Skip to content
Snippets Groups Projects
spi-atmel.c 27.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	clk_put(clk);
    	spi_master_put(master);
    	return ret;
    }
    
    static int __exit atmel_spi_remove(struct platform_device *pdev)
    {
    	struct spi_master	*master = platform_get_drvdata(pdev);
    	struct atmel_spi	*as = spi_master_get_devdata(master);
    	struct spi_message	*msg;
    
    	/* reset the hardware and block queue progress */
    	spin_lock_irq(&as->lock);
    	as->stopping = 1;
    	spi_writel(as, CR, SPI_BIT(SWRST));
    
    	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
    
    	spi_readl(as, SR);
    	spin_unlock_irq(&as->lock);
    
    	/* Terminate remaining queued transfers */
    	list_for_each_entry(msg, &as->queue, queue) {
    		/* REVISIT unmapping the dma is a NOP on ARM and AVR32
    		 * but we shouldn't depend on that...
    		 */
    		msg->status = -ESHUTDOWN;
    		msg->complete(msg->context);
    	}
    
    	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
    			as->buffer_dma);
    
    	clk_disable(as->clk);
    	clk_put(as->clk);
    	free_irq(as->irq, master);
    	iounmap(as->regs);
    
    	spi_unregister_master(master);
    
    	return 0;
    }
    
    #ifdef	CONFIG_PM
    
    static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
    {
    	struct spi_master	*master = platform_get_drvdata(pdev);
    	struct atmel_spi	*as = spi_master_get_devdata(master);
    
    	clk_disable(as->clk);
    	return 0;
    }
    
    static int atmel_spi_resume(struct platform_device *pdev)
    {
    	struct spi_master	*master = platform_get_drvdata(pdev);
    	struct atmel_spi	*as = spi_master_get_devdata(master);
    
    	clk_enable(as->clk);
    	return 0;
    }
    
    #else
    #define	atmel_spi_suspend	NULL
    #define	atmel_spi_resume	NULL
    #endif
    
    
    static struct platform_driver atmel_spi_driver = {
    	.driver		= {
    		.name	= "atmel_spi",
    		.owner	= THIS_MODULE,
    	},
    	.suspend	= atmel_spi_suspend,
    	.resume		= atmel_spi_resume,
    	.remove		= __exit_p(atmel_spi_remove),
    };
    
    static int __init atmel_spi_init(void)
    {
    	return platform_driver_probe(&atmel_spi_driver, atmel_spi_probe);
    }
    module_init(atmel_spi_init);
    
    static void __exit atmel_spi_exit(void)
    {
    	platform_driver_unregister(&atmel_spi_driver);
    }
    module_exit(atmel_spi_exit);
    
    MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
    
    MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
    
    MODULE_LICENSE("GPL");
    
    MODULE_ALIAS("platform:atmel_spi");