diff options
Diffstat (limited to 'drivers/spi')
53 files changed, 1053 insertions, 701 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b9c53cc40e1..eb1f1ef5fa2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -264,6 +264,7 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" select SPI_BITBANG + depends on SOC_VF610 || COMPILE_TEST help This enables support for the Freescale DSPI controller in master mode. VF610 platform uses the controller. @@ -369,7 +370,7 @@ config SPI_PXA2XX_PCI config SPI_RSPI tristate "Renesas RSPI controller" - depends on SUPERH && SH_DMAE_BASE + depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE help SPI driver for Renesas RSPI blocks. @@ -393,7 +394,7 @@ config SPI_S3C24XX_FIQ config SPI_S3C64XX tristate "Samsung S3C64XX series type SPI" - depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS) + depends on PLAT_SAMSUNG select S3C64XX_DMA if ARCH_S3C64XX help SPI driver for Samsung S3C64XX and newer SoCs. diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 9a64c3fee21..595b62cb545 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c @@ -219,7 +219,7 @@ static int altera_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); /* setup the state for the bitbang driver */ - hw->bitbang.master = spi_master_get(master); + hw->bitbang.master = master; if (!hw->bitbang.master) return err; hw->bitbang.chipselect = altera_spi_chipsel; diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 37bad952ab3..821bf7ac218 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -231,7 +231,7 @@ static int ath79_spi_probe(struct platform_device *pdev) master->num_chipselect = pdata->num_chipselect; } - sp->bitbang.master = spi_master_get(master); + sp->bitbang.master = master; sp->bitbang.chipselect = ath79_spi_chipselect; sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0; sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index fd7cc566095..273db0beb2b 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -170,18 +170,18 @@ /* Bit manipulation macros */ #define SPI_BIT(name) \ (1 << SPI_##name##_OFFSET) -#define SPI_BF(name,value) \ +#define SPI_BF(name, value) \ (((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET) -#define SPI_BFEXT(name,value) \ +#define SPI_BFEXT(name, value) \ (((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1)) -#define SPI_BFINS(name,value,old) \ - ( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \ - | SPI_BF(name,value)) +#define SPI_BFINS(name, value, old) \ + (((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \ + | SPI_BF(name, value)) /* Register access macros */ -#define spi_readl(port,reg) \ +#define spi_readl(port, reg) \ __raw_readl((port)->regs + SPI_##reg) -#define spi_writel(port,reg,value) \ +#define spi_writel(port, reg, value) \ __raw_writel((value), (port)->regs + SPI_##reg) /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -1401,8 +1401,8 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) asd = spi->controller_state; bits = (asd->csr >> 4) & 0xf; if (bits != xfer->bits_per_word - 8) { - dev_dbg(&spi->dev, "you can't yet change " - "bits_per_word in transfers\n"); + dev_dbg(&spi->dev, + "you can't yet change bits_per_word in transfers\n"); return -ENOPROTOOPT; } } @@ -1516,7 +1516,7 @@ static int atmel_spi_probe(struct platform_device *pdev) /* setup spi core then atmel-specific driver state */ ret = -ENOMEM; - master = spi_alloc_master(&pdev->dev, sizeof *as); + master = spi_alloc_master(&pdev->dev, sizeof(*as)); if (!master) goto out_free; @@ -1546,9 +1546,11 @@ static int atmel_spi_probe(struct platform_device *pdev) INIT_LIST_HEAD(&as->queue); as->pdev = pdev; - as->regs = ioremap(regs->start, resource_size(regs)); - if (!as->regs) + as->regs = devm_ioremap_resource(&pdev->dev, regs); + if (IS_ERR(as->regs)) { + ret = PTR_ERR(as->regs); goto out_free_buffer; + } as->phybase = regs->start; as->irq = irq; as->clk = clk; @@ -1583,7 +1585,7 @@ static int atmel_spi_probe(struct platform_device *pdev) /* Initialize the hardware */ ret = clk_prepare_enable(clk); if (ret) - goto out_unmap_regs; + goto out_free_irq; spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ if (as->caps.has_wdrbt) { @@ -1614,9 +1616,9 @@ out_free_dma: spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ clk_disable_unprepare(clk); +out_free_irq: free_irq(irq, master); out_unmap_regs: - iounmap(as->regs); out_free_buffer: if (!as->use_pdc) tasklet_kill(&as->tasklet); @@ -1668,36 +1670,36 @@ static int atmel_spi_remove(struct platform_device *pdev) clk_disable_unprepare(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) +#ifdef CONFIG_PM_SLEEP +static int atmel_spi_suspend(struct device *dev) { - struct spi_master *master = platform_get_drvdata(pdev); + struct spi_master *master = dev_get_drvdata(dev); struct atmel_spi *as = spi_master_get_devdata(master); clk_disable_unprepare(as->clk); return 0; } -static int atmel_spi_resume(struct platform_device *pdev) +static int atmel_spi_resume(struct device *dev) { - struct spi_master *master = platform_get_drvdata(pdev); + struct spi_master *master = dev_get_drvdata(dev); struct atmel_spi *as = spi_master_get_devdata(master); - return clk_prepare_enable(as->clk); + clk_prepare_enable(as->clk); return 0; } +static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume); + +#define ATMEL_SPI_PM_OPS (&atmel_spi_pm_ops) #else -#define atmel_spi_suspend NULL -#define atmel_spi_resume NULL +#define ATMEL_SPI_PM_OPS NULL #endif #if defined(CONFIG_OF) @@ -1713,10 +1715,9 @@ static struct platform_driver atmel_spi_driver = { .driver = { .name = "atmel_spi", .owner = THIS_MODULE, + .pm = ATMEL_SPI_PM_OPS, .of_match_table = of_match_ptr(atmel_spi_dt_ids), }, - .suspend = atmel_spi_suspend, - .resume = atmel_spi_resume, .probe = atmel_spi_probe, .remove = atmel_spi_remove, }; diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 1d00d9b397d..c4141c92bcf 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -775,7 +775,7 @@ static int au1550_spi_probe(struct platform_device *pdev) hw = spi_master_get_devdata(master); - hw->master = spi_master_get(master); + hw->master = master; hw->pdata = dev_get_platdata(&pdev->dev); hw->dev = &pdev->dev; @@ -985,6 +985,7 @@ static int au1550_spi_remove(struct platform_device *pdev) MODULE_ALIAS("platform:au1550-spi"); static struct platform_driver au1550_spi_drv = { + .probe = au1550_spi_probe, .remove = au1550_spi_remove, .driver = { .name = "au1550-spi", @@ -1004,7 +1005,7 @@ static int __init au1550_spi_init(void) printk(KERN_ERR "au1550-spi: cannot add memory" "dbdma device\n"); } - return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); + return platform_driver_register(&au1550_spi_drv); } module_init(au1550_spi_init); diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 52c81481c5c..4c332143a31 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -358,7 +358,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - err = spi_register_master(master); + err = devm_spi_register_master(&pdev->dev, master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); goto out_free_irq; @@ -381,14 +381,12 @@ static int bcm2835_spi_remove(struct platform_device *pdev) struct bcm2835_spi *bs = spi_master_get_devdata(master); free_irq(bs->irq, master); - spi_unregister_master(master); /* Clear FIFOs, and disable the HW block */ bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); clk_disable_unprepare(bs->clk); - spi_master_put(master); return 0; } diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 536b0e36382..80d56b214eb 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -412,7 +412,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); /* register and we are done */ - ret = spi_register_master(master); + ret = devm_spi_register_master(dev, master); if (ret) { dev_err(dev, "spi register failed\n"); goto out_clk_disable; @@ -438,8 +438,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev) struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); struct bcm63xx_spi *bs = spi_master_get_devdata(master); - spi_unregister_master(master); - /* reset spi block */ bcm_spi_writeb(bs, 0, SPI_INT_MASK); @@ -447,8 +445,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev) clk_disable_unprepare(bs->clk); clk_put(bs->clk); - spi_master_put(master); - return 0; } diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index 91921b5f581..38941e5920b 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -592,7 +592,7 @@ bfin_sport_spi_setup(struct spi_device *spi) */ if (chip_info->ctl_reg || chip_info->enable_dma) { ret = -EINVAL; - dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields"); + dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields\n"); goto error; } chip->cs_chg_udelay = chip_info->cs_chg_udelay; @@ -879,11 +879,10 @@ static int bfin_sport_spi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int -bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int bfin_sport_spi_suspend(struct device *dev) { - struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); + struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev); int status; status = bfin_sport_spi_stop_queue(drv_data); @@ -896,10 +895,9 @@ bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) return status; } -static int -bfin_sport_spi_resume(struct platform_device *pdev) +static int bfin_sport_spi_resume(struct device *dev) { - struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); + struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev); int status; /* Enable the SPI interface */ @@ -912,19 +910,22 @@ bfin_sport_spi_resume(struct platform_device *pdev) return status; } + +static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend, + bfin_sport_spi_resume); + +#define BFIN_SPORT_SPI_PM_OPS (&bfin_sport_spi_pm_ops) #else -# define bfin_sport_spi_suspend NULL -# define bfin_sport_spi_resume NULL +#define BFIN_SPORT_SPI_PM_OPS NULL #endif static struct platform_driver bfin_sport_spi_driver = { .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = BFIN_SPORT_SPI_PM_OPS, }, .probe = bfin_sport_spi_probe, .remove = bfin_sport_spi_remove, - .suspend = bfin_sport_spi_suspend, - .resume = bfin_sport_spi_resume, }; module_platform_driver(bfin_sport_spi_driver); diff --git a/drivers/spi/spi-bfin-v3.c b/drivers/spi/spi-bfin-v3.c index f4bf81347d6..8f8598834b3 100644 --- a/drivers/spi/spi-bfin-v3.c +++ b/drivers/spi/spi-bfin-v3.c @@ -867,7 +867,7 @@ static int bfin_spi_probe(struct platform_device *pdev) tasklet_init(&drv_data->pump_transfers, bfin_spi_pump_transfers, (unsigned long)drv_data); /* register with the SPI framework */ - ret = spi_register_master(master); + ret = devm_spi_register_master(dev, master); if (ret) { dev_err(dev, "can not register spi master\n"); goto err_free_peripheral; @@ -898,7 +898,6 @@ static int bfin_spi_remove(struct platform_device *pdev) free_dma(drv_data->rx_dma); free_dma(drv_data->tx_dma); - spi_unregister_master(drv_data->master); return 0; } diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 45bdf73d686..f0f195af75d 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -524,7 +524,7 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id) timeout = jiffies + HZ; while (!(bfin_read(&drv_data->regs->stat) & BIT_STAT_SPIF)) if (!time_before(jiffies, timeout)) { - dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF"); + dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF\n"); break; } else cpu_relax(); @@ -913,8 +913,9 @@ static void bfin_spi_pump_messages(struct work_struct *work) drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, struct spi_transfer, transfer_list); - dev_dbg(&drv_data->pdev->dev, "got a message to pump, " - "state is set to: baud %d, flag 0x%x, ctl 0x%x\n", + dev_dbg(&drv_data->pdev->dev, + "got a message to pump, state is set to: baud " + "%d, flag 0x%x, ctl 0x%x\n", drv_data->cur_chip->baud, drv_data->cur_chip->flag, drv_data->cur_chip->ctl_reg); @@ -1013,8 +1014,8 @@ static int bfin_spi_setup(struct spi_device *spi) * but let's assume (for now) they do. */ if (chip_info->ctl_reg & ~bfin_ctl_reg) { - dev_err(&spi->dev, "do not set bits in ctl_reg " - "that the SPI framework manages\n"); + dev_err(&spi->dev, + "do not set bits in ctl_reg that the SPI framework manages\n"); goto error; } chip->enable_dma = chip_info->enable_dma != 0 @@ -1050,17 +1051,17 @@ static int bfin_spi_setup(struct spi_device *spi) chip->chip_select_num = spi->chip_select; if (chip->chip_select_num < MAX_CTRL_CS) { if (!(spi->mode & SPI_CPHA)) - dev_warn(&spi->dev, "Warning: SPI CPHA not set:" - " Slave Select not under software control!\n" - " See Documentation/blackfin/bfin-spi-notes.txt"); + dev_warn(&spi->dev, + "Warning: SPI CPHA not set: Slave Select not under software control!\n" + "See Documentation/blackfin/bfin-spi-notes.txt\n"); chip->flag = (1 << spi->chip_select) << 8; } else chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS; if (chip->enable_dma && chip->pio_interrupt) { - dev_err(&spi->dev, "enable_dma is set, " - "do not set pio_interrupt\n"); + dev_err(&spi->dev, + "enable_dma is set, do not set pio_interrupt\n"); goto error; } /* @@ -1410,10 +1411,10 @@ static int bfin_spi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int bfin_spi_suspend(struct device *dev) { - struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); + struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev); int status = 0; status = bfin_spi_stop_queue(drv_data); @@ -1432,9 +1433,9 @@ static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int bfin_spi_resume(struct platform_device *pdev) +static int bfin_spi_resume(struct device *dev) { - struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); + struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev); int status = 0; bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg); @@ -1443,31 +1444,34 @@ static int bfin_spi_resume(struct platform_device *pdev) /* Start the queue running */ status = bfin_spi_start_queue(drv_data); if (status != 0) { - dev_err(&pdev->dev, "problem starting queue (%d)\n", status); + dev_err(dev, "problem starting queue (%d)\n", status); return status; } return 0; } + +static SIMPLE_DEV_PM_OPS(bfin_spi_pm_ops, bfin_spi_suspend, bfin_spi_resume); + +#define BFIN_SPI_PM_OPS (&bfin_spi_pm_ops) #else -#define bfin_spi_suspend NULL -#define bfin_spi_resume NULL -#endif /* CONFIG_PM */ +#define BFIN_SPI_PM_OPS NULL +#endif MODULE_ALIAS("platform:bfin-spi"); static struct platform_driver bfin_spi_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .pm = BFIN_SPI_PM_OPS, }, - .suspend = bfin_spi_suspend, - .resume = bfin_spi_resume, + .probe = bfin_spi_probe, .remove = bfin_spi_remove, }; static int __init bfin_spi_init(void) { - return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe); + return platform_driver_register(&bfin_spi_driver); } subsys_initcall(bfin_spi_init); diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 8c11355dec2..bd222f6b677 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -191,7 +191,7 @@ int spi_bitbang_setup(struct spi_device *spi) bitbang = spi_master_get_devdata(spi->master); if (!cs) { - cs = kzalloc(sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof(*cs), GFP_KERNEL); if (!cs) return -ENOMEM; spi->controller_state = cs; @@ -258,7 +258,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) static int spi_bitbang_prepare_hardware(struct spi_master *spi) { - struct spi_bitbang *bitbang; + struct spi_bitbang *bitbang; unsigned long flags; bitbang = spi_master_get_devdata(spi); @@ -273,7 +273,7 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi) static int spi_bitbang_transfer_one(struct spi_master *master, struct spi_message *m) { - struct spi_bitbang *bitbang; + struct spi_bitbang *bitbang; unsigned nsecs; struct spi_transfer *t = NULL; unsigned cs_change; @@ -292,7 +292,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master, cs_change = 1; status = 0; - list_for_each_entry (t, &m->transfers, transfer_list) { + list_for_each_entry(t, &m->transfers, transfer_list) { /* override speed or wordsize? */ if (t->speed_hz || t->bits_per_word) @@ -349,7 +349,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master, if (t->delay_usecs) udelay(t->delay_usecs); - if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { + if (cs_change && + !list_is_last(&t->transfer_list, &m->transfers)) { /* sometimes a short mid-message deselect of the chip * may be needed to terminate a mode or command */ @@ -378,7 +379,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master, static int spi_bitbang_unprepare_hardware(struct spi_master *spi) { - struct spi_bitbang *bitbang; + struct spi_bitbang *bitbang; unsigned long flags; bitbang = spi_master_get_devdata(spi); @@ -414,10 +415,16 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi) * This routine registers the spi_master, which will process requests in a * dedicated task, keeping IRQs unblocked most of the time. To stop * processing those requests, call spi_bitbang_stop(). + * + * On success, this routine will take a reference to master. The caller is + * responsible for calling spi_bitbang_stop() to decrement the reference and + * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory + * leak. */ int spi_bitbang_start(struct spi_bitbang *bitbang) { struct spi_master *master = bitbang->master; + int ret; if (!master || !bitbang->chipselect) return -EINVAL; @@ -449,7 +456,11 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) /* driver may get busy before register() returns, especially * if someone registered boardinfo for devices */ - return spi_register_master(master); + ret = spi_register_master(spi_master_get(master)); + if (ret) + spi_master_put(master); + |