diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-08 01:00:49 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-08 19:58:35 (GMT) |
commit | 47d2261a3fa71cde24263559a4219a25e50d8c89 (patch) | |
tree | 28774d5b330ccf1b777a3af222d8356918328013 /drivers/spi | |
parent | fb7f27080adc65cd5f341bdf56a1d0c14f316c1b (diff) | |
parent | 5fb9d37f27351e42f002e372074249f92cbdf815 (diff) | |
download | linux-fsl-qoriq-47d2261a3fa71cde24263559a4219a25e50d8c89.tar.xz |
Merge branch 'merge' into sdk-v1.6.x
This reverts v3.13-rc3+ (78fd82238d0e5716) to v3.12, except for
commits which I noticed which appear relevant to the SDK.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Conflicts:
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_interrupts.S
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/sysdev/fsl_soc.h
drivers/Kconfig
drivers/cpufreq/ppc-corenet-cpufreq.c
drivers/dma/fsldma.c
drivers/dma/s3c24xx-dma.c
drivers/misc/Makefile
drivers/mmc/host/sdhci-of-esdhc.c
drivers/mtd/devices/m25p80.c
drivers/net/ethernet/freescale/gianfar.h
drivers/platform/Kconfig
drivers/platform/Makefile
drivers/spi/spi-fsl-espi.c
include/crypto/algapi.h
include/linux/netdev_features.h
include/linux/skbuff.h
include/net/ip.h
net/core/ethtool.c
Diffstat (limited to 'drivers/spi')
56 files changed, 727 insertions, 1126 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index eb1f1ef..b9c53cc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -264,7 +264,6 @@ 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. @@ -370,7 +369,7 @@ config SPI_PXA2XX_PCI config SPI_RSPI tristate "Renesas RSPI controller" - depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE + depends on SUPERH && SH_DMAE_BASE help SPI driver for Renesas RSPI blocks. @@ -394,7 +393,7 @@ config SPI_S3C24XX_FIQ config SPI_S3C64XX tristate "Samsung S3C64XX series type SPI" - depends on PLAT_SAMSUNG + depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS) 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 595b62c..9a64c3f 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 = master; + hw->bitbang.master = spi_master_get(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 821bf7a..37bad95 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 = master; + sp->bitbang.master = spi_master_get(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 273db0b..d4ac60b 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,11 +1546,9 @@ static int atmel_spi_probe(struct platform_device *pdev) INIT_LIST_HEAD(&as->queue); as->pdev = pdev; - as->regs = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(as->regs)) { - ret = PTR_ERR(as->regs); + as->regs = ioremap(regs->start, resource_size(regs)); + if (!as->regs) goto out_free_buffer; - } as->phybase = regs->start; as->irq = irq; as->clk = clk; @@ -1619,6 +1617,7 @@ out_free_dma: out_free_irq: free_irq(irq, master); out_unmap_regs: + iounmap(as->regs); out_free_buffer: if (!as->use_pdc) tasklet_kill(&as->tasklet); @@ -1670,36 +1669,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_SLEEP -static int atmel_spi_suspend(struct device *dev) +#ifdef CONFIG_PM + +static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_master *master = platform_get_drvdata(pdev); struct atmel_spi *as = spi_master_get_devdata(master); clk_disable_unprepare(as->clk); return 0; } -static int atmel_spi_resume(struct device *dev) +static int atmel_spi_resume(struct platform_device *pdev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_master *master = platform_get_drvdata(pdev); struct atmel_spi *as = spi_master_get_devdata(master); - clk_prepare_enable(as->clk); + return 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_PM_OPS NULL +#define atmel_spi_suspend NULL +#define atmel_spi_resume NULL #endif #if defined(CONFIG_OF) @@ -1715,9 +1714,10 @@ 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 c4141c9..1d00d9b3 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 = master; + hw->master = spi_master_get(master); hw->pdata = dev_get_platdata(&pdev->dev); hw->dev = &pdev->dev; @@ -985,7 +985,6 @@ 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", @@ -1005,7 +1004,7 @@ static int __init au1550_spi_init(void) printk(KERN_ERR "au1550-spi: cannot add memory" "dbdma device\n"); } - return platform_driver_register(&au1550_spi_drv); + return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); } module_init(au1550_spi_init); diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 9025edd..52c8148 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -217,7 +217,7 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, cs |= spi->chip_select; } - reinit_completion(&bs->done); + INIT_COMPLETION(bs->done); bs->tx_buf = tfr->tx_buf; bs->rx_buf = tfr->rx_buf; bs->len = tfr->len; @@ -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 = devm_spi_register_master(&pdev->dev, master); + err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); goto out_free_irq; @@ -377,16 +377,18 @@ out_master_put: static int bcm2835_spi_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(pdev); + struct spi_master *master = spi_master_get(platform_get_drvdata(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 469ecd8..536b0e3 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 = devm_spi_register_master(dev, master); + ret = spi_register_master(master); if (ret) { dev_err(dev, "spi register failed\n"); goto out_clk_disable; @@ -435,9 +435,11 @@ out: static int bcm63xx_spi_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(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); @@ -445,6 +447,8 @@ 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 38941e5..91921b5 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\n"); + dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields"); goto error; } chip->cs_chg_udelay = chip_info->cs_chg_udelay; @@ -879,10 +879,11 @@ static int bfin_sport_spi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int bfin_sport_spi_suspend(struct device *dev) +#ifdef CONFIG_PM +static int +bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) { - struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev); + struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); int status; status = bfin_sport_spi_stop_queue(drv_data); @@ -895,9 +896,10 @@ static int bfin_sport_spi_suspend(struct device *dev) return status; } -static int bfin_sport_spi_resume(struct device *dev) +static int +bfin_sport_spi_resume(struct platform_device *pdev) { - struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev); + struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); int status; /* Enable the SPI interface */ @@ -910,22 +912,19 @@ static int bfin_sport_spi_resume(struct device *dev) 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_PM_OPS NULL +# define bfin_sport_spi_suspend NULL +# define bfin_sport_spi_resume NULL #endif static struct platform_driver bfin_sport_spi_driver = { .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = BFIN_SPORT_SPI_PM_OPS, + .name = DRV_NAME, + .owner = THIS_MODULE, }, .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 8f85988..f4bf813 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 = devm_spi_register_master(dev, master); + ret = spi_register_master(master); if (ret) { dev_err(dev, "can not register spi master\n"); goto err_free_peripheral; @@ -898,6 +898,7 @@ 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 f0f195a..45bdf73 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\n"); + dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF"); break; } else cpu_relax(); @@ -913,9 +913,8 @@ 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); @@ -1014,8 +1013,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 @@ -1051,17 +1050,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\n"); + dev_warn(&spi->dev, "Warning: SPI CPHA not set:" + " Slave Select not under software control!\n" + " See Documentation/blackfin/bfin-spi-notes.txt"); 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; } /* @@ -1411,10 +1410,10 @@ static int bfin_spi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int bfin_spi_suspend(struct device *dev) +#ifdef CONFIG_PM +static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state) { - struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev); + struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); int status = 0; status = bfin_spi_stop_queue(drv_data); @@ -1433,9 +1432,9 @@ static int bfin_spi_suspend(struct device *dev) return 0; } -static int bfin_spi_resume(struct device *dev) +static int bfin_spi_resume(struct platform_device *pdev) { - struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev); + struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev); int status = 0; bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg); @@ -1444,34 +1443,31 @@ static int bfin_spi_resume(struct device *dev) /* Start the queue running */ status = bfin_spi_start_queue(drv_data); if (status != 0) { - dev_err(dev, "problem starting queue (%d)\n", status); + dev_err(&pdev->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_PM_OPS NULL -#endif +#define bfin_spi_suspend NULL +#define bfin_spi_resume NULL +#endif /* CONFIG_PM */ MODULE_ALIAS("platform:bfin-spi"); static struct platform_driver bfin_spi_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, - .pm = BFIN_SPI_PM_OPS, }, - .probe = bfin_spi_probe, + .suspend = bfin_spi_suspend, + .resume = bfin_spi_resume, .remove = bfin_spi_remove, }; static int __init bfin_spi_init(void) { - return platform_driver_register(&bfin_spi_driver); + return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe); } subsys_initcall(bfin_spi_init); diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index bd222f6..8c11355 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,8 +349,7 @@ 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 */ @@ -379,7 +378,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); @@ -415,16 +414,10 @@ 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; @@ -456,11 +449,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) /* driver may get busy before register() returns, especially * if someone registered boardinfo for devices */ - ret = spi_register_master(spi_master_get(master)); - if (ret) - spi_master_put(master); - - return 0; + return spi_register_master(master); } EXPORT_SYMBOL_GPL(spi_bitbang_start); diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 8081f96..5ed08e5 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c @@ -147,8 +147,8 @@ static void butterfly_chipselect(struct spi_device *spi, int value) /* we only needed to implement one mode here, and choose SPI_MODE_0 */ -#define spidelay(X) do { } while (0) -/* #define spidelay ndelay */ +#define spidelay(X) do{}while(0) +//#define spidelay ndelay #include "spi-bitbang-txrx.h" @@ -171,15 +171,15 @@ static struct mtd_partition partitions[] = { { /* sector 0 = 8 pages * 264 bytes/page (1 block) * sector 1 = 248 pages * 264 bytes/page */ - .name = "bookkeeping", /* 66 KB */ + .name = "bookkeeping", // 66 KB .offset = 0, .size = (8 + 248) * 264, - /* .mask_flags = MTD_WRITEABLE, */ +// .mask_flags = MTD_WRITEABLE, }, { /* sector 2 = 256 pages * 264 bytes/page * sectors 3-5 = 512 pages * 264 bytes/page */ - .name = "filesystem", /* 462 KB */ + .name = "filesystem", // 462 KB .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, } }; @@ -209,7 +209,7 @@ static void butterfly_attach(struct parport *p) * and no way to be selective about what it binds to. */ - master = spi_alloc_master(dev, sizeof(*pp)); + master = spi_alloc_master(dev, sizeof *pp); if (!master) { status = -ENOMEM; goto done; @@ -225,7 +225,7 @@ static void butterfly_attach(struct parport *p) master->bus_num = 42; master->num_chipselect = 2; - pp->bitbang.master = master; + pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = butterfly_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; @@ -289,6 +289,7 @@ static void butterfly_attach(struct parport *p) pr_debug("%s: dataflash at %s\n", p->name, dev_name(&pp->dataflash->dev)); + // dev_info(_what?_, ...) pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; return; diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 6f03d7e..6416798 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -105,7 +105,7 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH)); - reinit_completion(&hw->done); + INIT_COMPLETION(hw->done); hw->count = 0; hw->len = xfer->len; @@ -226,10 +226,10 @@ static int spi_clps711x_probe(struct platform_device *pdev) dev_name(&pdev->dev), hw); if (ret) { dev_err(&pdev->dev, "Can't request IRQ\n"); - goto err_out; + goto clk_out; } - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (!ret) { dev_info(&pdev->dev, "SPI bus driver initialized. Master clock %u Hz\n", @@ -239,6 +239,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to register master\n"); +clk_out: err_out: while (--i >= 0) if (gpio_is_valid(hw->chipselect[i])) @@ -259,6 +260,8 @@ static int spi_clps711x_remove(struct platform_device *pdev) if (gpio_is_valid(hw->chipselect[i])) gpio_free(hw->chipselect[i]); + spi_unregister_master(master); + return 0; } diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 50b2d88..8fbfe24 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -279,8 +279,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, struct davinci_spi *dspi; struct davinci_spi_config *spicfg; u8 bits_per_word = 0; - u32 hz = 0, spifmt = 0; - int prescale; + u32 hz = 0, spifmt = 0, prescale = 0; dspi = spi_master_get_devdata(spi->master); spicfg = (struct davinci_spi_config *)spi->controller_data; @@ -554,7 +553,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK); set_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); - reinit_completion(&dspi->done); + INIT_COMPLETION(dspi->done); if (spicfg->io_type == SPI_IO_TYPE_INTR) set_io_bits(dspi->base + SPIINT, SPIINT_MASKINT); @@ -917,7 +916,7 @@ static int davinci_spi_probe(struct platform_device *pdev) if (ret) goto unmap_io; - dspi->bitbang.master = master; + dspi->bitbang.master = spi_master_get(master); if (dspi->bitbang.master == NULL) { ret = -ENODEV; goto irq_free; @@ -926,7 +925,7 @@ static int davinci_spi_probe(struct platform_device *pdev) dspi->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dspi->clk)) { ret = -ENODEV; - goto irq_free; + goto put_master; } clk_prepare_enable(dspi->clk); @@ -1016,6 +1015,8 @@ free_dma: free_clk: clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); +put_master: + spi_master_put(master); irq_free: free_irq(dspi->irq, dspi); unmap_io: @@ -1023,7 +1024,7 @@ unmap_io: release_region: release_mem_region(dspi->pbase, resource_size(r)); free_master: - spi_master_put(master); + kfree(master); err: return ret; } @@ -1050,11 +1051,11 @@ static int davinci_spi_remove(struct platform_device *pdev) clk_disable_unprepare(dspi->clk); clk_put(dspi->clk); + spi_master_put(master); free_irq(dspi->irq, dspi); iounmap(dspi->base); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(dspi->pbase, resource_size(r)); - spi_master_put(master); return 0; } diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 6d207af..b9f0192 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -150,7 +150,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) &dws->tx_sgl, 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT); + DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); txdesc->callback = dw_spi_dma_done; txdesc->callback_param = dws; @@ -173,7 +173,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) &dws->rx_sgl, 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT); + DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); rxdesc->callback = dw_spi_dma_done; rxdesc->callback_param = dws; diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 168c620..4aa8be8 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -74,7 +74,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) dwsmmio->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dwsmmio->clk)) { ret = PTR_ERR(dwsmmio->clk); - goto err_unmap; + goto err_irq; } clk_enable(dwsmmio->clk); @@ -94,6 +94,8 @@ err_clk: clk_disable(dwsmmio->clk); clk_put(dwsmmio->clk); dwsmmio->clk = NULL; +err_irq: + free_irq(dws->irq, dws); err_unmap: iounmap(dws->regs); err_release_reg: @@ -113,6 +115,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) clk_put(dwsmmio->clk); dwsmmio->clk = NULL; + free_irq(dwsmmio->dws.irq, &dwsmmio->dws); dw_spi_remove_host(&dwsmmio->dws); iounmap(dwsmmio->dws.regs); kfree(dwsmmio); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 66fa995..6055c8d 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -40,7 +40,7 @@ static int spi_pci_probe(struct pci_dev *pdev, int pci_bar = 0; int ret; - dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n", + printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n", pdev->vendor, pdev->device); ret = pci_enable_device(pdev); @@ -109,6 +109,7 @@ static void spi_pci_remove(struct pci_dev *pdev) { struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); + pci_set_drvdata(pdev, NULL); dw_spi_remove_host(&dwpci->dws); iounmap(dwpci->dws.regs); pci_release_region(pdev, 0); diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index b897c4ad..79c958e 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -870,8 +870,8 @@ void dw_spi_remove_host(struct dw_spi *dws) /* Remove the queue */ status = destroy_queue(dws); if (status != 0) - dev_err(&dws->master->dev, - "dw_spi_remove: workqueue will not complete, message memory not freed\n"); + dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " + "complete, message memory not freed\n"); if (dws->dma_ops && dws->dma_ops->dma_exit) dws->dma_ops->dma_exit(dws); diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index d4d3cc5..7d84418 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -280,6 +280,10 @@ static irqreturn_t efm32_spi_txirq(int irq, void *data) return IRQ_HANDLED; } +static const struct efm32_spi_pdata efm32_spi_pdata_default = { + .location = 1, +}; + static u32 efm32_spi_get_configured_location(struct efm32_spi_ddata *ddata) { u32 reg = efm32_spi_read32(ddata, REG_ROUTE); @@ -343,7 +347,7 @@ static int efm32_spi_probe(struct platform_device *pdev) ddata = spi_master_get_devdata(master); - ddata->bitbang.master = master; + ddata->bitbang.master = spi_master_get(master); ddata->bitbang.chipselect = efm32_spi_chipselect; ddata->bitbang.setup_transfer = efm32_spi_setup_transfer; ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; @@ -383,7 +387,7 @@ static int efm32_spi_probe(struct platform_device *pdev) goto err; } - if (resource_size(res) < 0x60) { + if (resource_size(res) < 60) { ret = -EINVAL; dev_err(&pdev->dev, "memory resource too small\n"); goto err; @@ -463,6 +467,7 @@ err_disable_clk: clk_disable_unprepare(ddata->clk); err: spi_master_put(master); + kfree(master); } return ret; @@ -473,14 +478,13 @@ static int efm32_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct efm32_spi_ddata *ddata = spi_master_get_devdata(master); - spi_bitbang_stop(&ddata->bitbang); - efm32_spi_write32(ddata, 0, REG_IEN); free_irq(ddata->txirq, ddata); free_irq(ddata->rxirq, ddata); clk_disable_unprepare(ddata->clk); spi_master_put(master); + kfree(master); return 0; } diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 1bfaed6..d22c00a 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -330,7 +330,7 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", chip->spi->mode, div_cpsr, div_scr, dss); - dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); + dev_dbg(&espi->pdev->dev, "setup: cr0 %#x", cr0); ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); ep93xx_spi_write_u16(espi, SSPCR0, cr0); @@ -509,7 +509,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) } if (WARN_ON(len)) { - dev_warn(&espi->pdev->dev, "len = %zu expected 0!\n", len); + dev_warn(&espi->pdev->dev, "len = %zu expected 0!", len); return ERR_PTR(-EINVAL); } @@ -942,7 +942,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) /* make sure that the hardware is disabled */ ep93xx_spi_write_u8(espi, SSPCR1, 0); - error = devm_spi_register_master(&pdev->dev, master); + error = spi_register_master(master); if (error) { dev_err(&pdev->dev, "failed to register SPI master\n"); goto fail_free_dma; @@ -968,6 +968,7 @@ static int ep93xx_spi_remove(struct platform_device *pdev) ep93xx_spi_release_dma(espi); + spi_unregister_master(master); return 0; } diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 54b0637..07971e3 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -20,7 +20,6 @@ #include <linux/spi/spi.h> #include <linux/fsl_devices.h> #include <linux/dma-mapping.h> -#include <linux/of_address.h> #include <asm/cpm.h> #include <asm/qe.h> @@ -300,7 +299,7 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi) switch (mspi->subblock) { default: - dev_warn(dev, "cell-index unspecified, assuming SPI1\n"); + dev_warn(dev, "cell-index unspecified, assuming SPI1"); /* fall through */ case 0: mspi->subblock = QE_CR_SUBBLOCK_SPI1; diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 8641b03..4e44575 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -108,7 +108,7 @@ struct fsl_dspi { struct spi_bitbang bitbang; struct platform_device *pdev; - void __iomem *base; + void *base; int irq; struct clk *clk; @@ -165,7 +165,7 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, } } - pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\ + pr_warn("Can not find valid buad rate,speed_hz is %d,clkrate is %ld\ ,we use the max prescaler value.\n", speed_hz, clkrate); *pbr = ARRAY_SIZE(pbr_tbl) - 1; *br = ARRAY_SIZE(brs) - 1; @@ -450,7 +450,7 @@ static int dspi_probe(struct platform_device *pdev) dspi = spi_master_get_devdata(master); dspi->pdev = pdev; - dspi->bitbang.master = master; + dspi->bitbang.master = spi_master_get(master); dspi->bitbang.chipselect = dspi_chipselect; dspi->bitbang.setup_transfer = dspi_setup_transfer; dspi->bitbang.txrx_bufs = dspi_txrx_transfer; @@ -520,6 +520,7 @@ out_clk_put: clk_disable_unprepare(dspi->clk); out_master_put: spi_master_put(master); + platform_set_drvdata(pdev, NULL); return ret; } @@ -530,7 +531,6 @@ static int dspi_remove(struct platform_device *pdev) /* Disconnect from the SPI framework */ spi_bitbang_stop(&dspi->bitbang); - clk_disable_unprepare(dspi->clk); spi_master_put(dspi->bitbang.master); return 0; @@ -547,5 +547,5 @@ static struct platform_driver fsl_dspi_driver = { module_platform_driver(fsl_dspi_driver); MODULE_DESCRIPTION("Freescale DSPI Controller Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 428dc7a..50c2040 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -16,8 +16,6 @@ #include <linux/fsl_devices.h> #include <linux/mm.h> #include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/interrupt.h> #include <linux/err.h> @@ -232,7 +230,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) mpc8xxx_spi->tx = t->tx_buf; mpc8xxx_spi->rx = t->rx_buf; - reinit_completion(&mpc8xxx_spi->done); + INIT_COMPLETION(mpc8xxx_spi->done); /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ if ((t->len - 1) > SPCOM_TRANLEN_MAX) { @@ -291,8 +289,8 @@ static void fsl_espi_do_trans(struct spi_message *m, if ((first->bits_per_word != t->bits_per_word) || (first->speed_hz != t->speed_hz)) { espi_trans->status = -EINVAL; - dev_err(mspi->dev, - "bits_per_word/speed_hz should be same for the same SPI transfer\n"); + dev_err(mspi->dev, "bits_per_word/speed_hz should be" + " same for the same SPI transfer\n"); return; } @@ -689,7 +687,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) struct device_node *np = ofdev->dev.of_node; struct spi_master *master; struct resource mem; - unsigned int irq; + struct resource irq; int ret = -ENOMEM; ret = of_mpc8xxx_spi_probe(ofdev); @@ -704,13 +702,13 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) if (ret) goto err; - irq = irq_of_parse_and_map(np, 0); - if (!irq) { + ret = of_irq_to_resource(np, 0, &irq); + if (!ret) { ret = -EINVAL; goto err; } - master = fsl_espi_probe(dev, &mem, irq); + master = fsl_espi_probe(dev, &mem, irq.start); if (IS_ERR(master)) { ret = PTR_ERR(master); goto err; diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 119f7af..2129fcd 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -339,7 +339,7 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, mpc8xxx_spi->tx = t->tx_buf; mpc8xxx_spi->rx = t->rx_buf; - reinit_completion(&mpc8xxx_spi->done); + INIT_COMPLETION(mpc8xxx_spi->done); if (mpc8xxx_spi->flags & SPI_CPM_MODE) ret = fsl_spi_cpm_bufs(mpc8xxx_spi, t, is_dma_mapped); diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 3fb09f9..68b69fe 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/gpio.h> -#include <linux/of.h> #include <linux/of_device.h> #include <linux/of_gpio.h> @@ -468,7 +467,7 @@ static int spi_gpio_probe(struct platform_device *pdev) } #endif - spi_gpio->bitbang.master = master; + spi_gpio->bitbang.master = spi_master_get(master); spi_gpio->bitbang.chipselect = spi_gpio_chipselect; if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { @@ -487,6 +486,7 @@ static int spi_gpio_probe(struct platform_device *pdev) status = spi_bitbang_start(&spi_gpio->bitbang); if (status < 0) { + spi_master_put(spi_gpio->bitbang.master); gpio_free: if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) gpio_free(SPI_MISO_GPIO); @@ -510,13 +510,13 @@ static int spi_gpio_remove(struct platform_device *pdev) /* stop() unregisters child devices too */ status = spi_bitbang_stop(&spi_gpio->bitbang); + spi_master_put(spi_gpio->bitbang.master); if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) gpio_free(SPI_MISO_GPIO); if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) gpio_free(SPI_MOSI_GPIO); gpio_free(SPI_SCK_GPIO); - spi_master_put(spi_gpio->bitbang.master); return status; } diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index b80f2f7..15323d8 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -749,35 +749,6 @@ static void spi_imx_cleanup(struct spi_device *spi) { } -static int -spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg) -{ - struct spi_imx_data *spi_imx = spi_master_get_devdata(master); - int ret; - - ret = clk_enable(spi_imx->clk_per); - if (ret) - return ret; - - ret = clk_enable(spi_imx->clk_ipg); - if (ret) { - clk_disable(spi_imx->clk_per); - return ret; - } - - return 0; -} - -static int -spi_imx_unprepare_message(struct spi_master *master, struct spi_message *msg) -{ - struct spi_imx_data *spi_imx = spi_master_get_devdata(master); - - clk_disable(spi_imx->clk_ipg); - clk_disable(spi_imx->clk_per); - return 0; -} - static int spi_imx_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -815,7 +786,7 @@ static int spi_imx_probe(struct platform_device *pdev) master->num_chipselect = num_cs; spi_imx = spi_master_get_devdata(master); - spi_imx->bitbang.master = master; + spi_imx->bitbang.master = spi_master_get(master); for (i = 0; i < master->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); @@ -839,8 +810,6 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.txrx_bufs = spi_imx_transfer; spi_imx->bitbang.master->setup = spi_imx_setup; spi_imx->bitbang.master->cleanup = spi_imx_cleanup; - spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; - spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; init_completion(&spi_imx->xfer_done); @@ -903,8 +872,6 @@ static int spi_imx_probe(struct platform_device *pdev) dev_info(&pdev->dev, "probed\n"); - clk_disable(spi_imx->clk_ipg); - clk_disable(spi_imx->clk_per); return ret; out_clk_put: diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 41c5765..0759b5d 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c @@ -222,7 +222,7 @@ static void spi_lm70llp_attach(struct parport *p) /* * SPI and bitbang hookup. */ - pp->bitbang.master = master; + pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = lm70_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx; pp->bitbang.flags = SPI_3WIRE; diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 8767658..6adf4e3 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -20,7 +20,6 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/completion.h> #include <linux/io.h> @@ -167,7 +166,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, } /* have the ISR trigger when the TX FIFO is empty */ - reinit_completion(&mps->txisrdone); + INIT_COMPLETION(mps->txisrdone); out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY); out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY); wait_for_completion(&mps->txisrdone); @@ -537,7 +536,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, if (ret < 0) goto free_clock; - ret = devm_spi_register_master(dev, master); + ret = spi_register_master(master); if (ret < 0) goto free_clock; @@ -557,13 +556,15 @@ free_master: static int mpc512x_psc_spi_do_remove(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); + spi_unregister_master(master); clk_disable_unprepare(mps->clk_mclk); free_irq(mps->irq, mps); if (mps->psc) iounmap(mps->psc); + spi_master_put(master); return 0; } diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index 00ba910..6e925dc 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c @@ -383,8 +383,8 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, mps->irq = irq; if (pdata == NULL) { - dev_warn(dev, - "probe called without platform data, no cs_control function will be called\n"); + dev_warn(dev, "probe called without platform data, no " + "cs_control function will be called\n"); mps->cs_control = NULL; mps->sysclk = 0; master->bus_num = bus_num; diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 3adebfa..de7b114 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -57,53 +57,34 @@ #define SG_MAXLEN 0xff00 -/* - * Flags for txrx functions. More efficient that using an argument register for - * each one. - */ -#define TXRX_WRITE (1<<0) /* This is a write */ -#define TXRX_DEASSERT_CS (1<<1) /* De-assert CS at end of txrx */ - struct mxs_spi { struct mxs_ssp ssp; struct completion c; - unsigned int sck; /* Rate requested (vs actual) */ }; static int mxs_spi_setup_transfer(struct spi_device *dev, - const struct spi_transfer *t) + struct spi_transfer *t) { struct mxs_spi *spi = spi_master_get_devdata(dev->master); struct mxs_ssp *ssp = &spi->ssp; - const unsigned int hz = min(dev->max_speed_hz, t->speed_hz); + uint32_t hz = 0; + hz = dev->max_speed_hz; + if (t && t->speed_hz) + hz = min(hz, t->speed_hz); if (hz == 0) { - dev_err(&dev->dev, "SPI clock rate of zero not allowed\n"); + dev_err(&dev->dev, "Cannot continue with zero clock\n"); return -EINVAL; } - if (hz != spi->sck) { - mxs_ssp_set_clk_rate(ssp, hz); - /* - * Save requested rate, hz, rather than the actual rate, - * ssp->clk_rate. Otherwise we would set the rate every trasfer - * when the actual rate is not quite the same as requested rate. - */ - spi->sck = hz; - /* - * Perhaps we should return an error if the actual clock is - * nowhere close to what was requested? - */ - } - - writel(BM_SSP_CTRL0_LOCK_CS, - ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); + mxs_ssp_set_clk_rate(ssp, hz); writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) | - BF_SSP_CTRL1_WORD_LENGTH(BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | - ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | - ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), - ssp->base + HW_SSP_CTRL1(ssp)); + BF_SSP_CTRL1_WORD_LENGTH + (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | + ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | + ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), + ssp->base + HW_SSP_CTRL1(ssp)); writel(0x0, ssp->base + HW_SSP_CMD0); writel(0x0, ssp->base + HW_SSP_CMD1); @@ -113,15 +94,26 @@ static int mxs_spi_setup_transfer(struct spi_device *dev, static int mxs_spi_setup(struct spi_device *dev) { + int err = 0; + if (!dev->bits_per_word) dev->bits_per_word = 8; - return 0; + if (dev->mode & ~(SPI_CPOL | SPI_CPHA)) + return -EINVAL; + + err = mxs_spi_setup_transfer(dev, NULL); + if (err) { + dev_err(&dev->dev, + "Failed to setup transfer, error = %d\n", err); + } + + return err; } -static u32 mxs_spi_cs_to_reg(unsigned cs) +static uint32_t mxs_spi_cs_to_reg(unsigned cs) { - u32 select = 0; + uint32_t select = 0; /* * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0 @@ -139,11 +131,43 @@ static u32 mxs_spi_cs_to_reg(unsigned cs) return select; } +static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs) +{ + const uint32_t mask = + BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ; + uint32_t select; + struct mxs_ssp *ssp = &spi->ssp; + + writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); + select = mxs_spi_cs_to_reg(cs); + writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); +} + +static inline void mxs_spi_enable(struct mxs_spi *spi) +{ + struct mxs_ssp *ssp = &spi->ssp; + + writel(BM_SSP_CTRL0_LOCK_CS, + ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); + writel(BM_SSP_CTRL0_IGNORE_CRC, + ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); +} + +static inline void mxs_spi_disable(struct mxs_spi *spi) +{ + struct mxs_ssp *ssp = &spi->ssp; + + writel(BM_SSP_CTRL0_LOCK_CS, + ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); + writel(BM_SSP_CTRL0_IGNORE_CRC, + ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); +} + static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set) { const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT); struct mxs_ssp *ssp = &spi->ssp; - u32 reg; + uint32_t reg; do { reg = readl_relaxed(ssp->base + offset); @@ -176,9 +200,9 @@ static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int mxs_spi_txrx_dma(struct mxs_spi *spi, +static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, unsigned char *buf, int len, - unsigned int flags) + int *first, int *last, int write) { struct mxs_ssp *ssp = &spi->ssp; struct dma_async_tx_descriptor *desc = NULL; @@ -187,11 +211,11 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, const int sgs = DIV_ROUND_UP(len, desc_len); int sg_count; int min, ret; - u32 ctrl0; + uint32_t ctrl0; struct page *vm_page; void *sg_buf; struct { - u32 pio[4]; + uint32_t pio[4]; struct scatterlist sg; } *dma_xfer; @@ -202,27 +226,23 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, if (!dma_xfer) return -ENOMEM; - reinit_completion(&spi->c); + INIT_COMPLETION(spi->c); - /* Chip select was already programmed into CTRL0 */ ctrl0 = readl(ssp->base + HW_SSP_CTRL0); - ctrl0 &= ~(BM_SSP_CTRL0_XFER_COUNT | BM_SSP_CTRL0_IGNORE_CRC | - BM_SSP_CTRL0_READ); - ctrl0 |= BM_SSP_CTRL0_DATA_XFER; + ctrl0 &= ~BM_SSP_CTRL0_XFER_COUNT; + ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs); - if (!(flags & TXRX_WRITE)) + if (*first) + ctrl0 |= BM_SSP_CTRL0_LOCK_CS; + if (!write) ctrl0 |= BM_SSP_CTRL0_READ; /* Queue the DMA data transfer. */ for (sg_count = 0; sg_count < sgs; sg_count++) { - /* Prepare the transfer descriptor. */ min = min(len, desc_len); - /* - * De-assert CS on last segment if flag is set (i.e., no more - * transfers will follow) - */ - if ((sg_count + 1 == sgs) && (flags & TXRX_DEASSERT_CS)) + /* Prepare the transfer descriptor. */ + if ((sg_count + 1 == sgs) && *last) ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC; if (ssp->devid == IMX23_SSP) { @@ -247,7 +267,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min); ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, - (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); len -= min; buf += min; @@ -267,7 +287,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, desc = dmaengine_prep_slave_sg(ssp->dmach, &dma_xfer[sg_count].sg, 1, - (flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, + write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { @@ -304,7 +324,7 @@ err_vmalloc: while (--sg_count >= 0) { err_mapped: dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, - (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } kfree(dma_xfer); @@ -312,19 +332,20 @@ err_mapped: return ret; } -static int mxs_spi_txrx_pio(struct mxs_spi *spi, +static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, unsigned char *buf, int len, - unsigned int flags) + int *first, int *last, int write) { struct mxs_ssp *ssp = &spi->ssp; - writel(BM_SSP_CTRL0_IGNORE_CRC, - ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); + if (*first) + mxs_spi_enable(spi); + + mxs_spi_set_cs(spi, cs); while (len--) { - if (len == 0 && (flags & TXRX_DEASSERT_CS)) - writel(BM_SSP_CTRL0_IGNORE_CRC, - ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); + if (*last && len == 0) + mxs_spi_disable(spi); if (ssp->devid == IMX23_SSP) { writel(BM_SSP_CTRL0_XFER_COUNT, @@ -335,7 +356,7 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, writel(1, ssp->base + HW_SSP_XFER_SIZE); } - if (flags & TXRX_WRITE) + if (write) writel(BM_SSP_CTRL0_READ, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); else @@ -348,13 +369,13 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1)) return -ETIMEDOUT; - if (flags & TXRX_WRITE) + if (write) writel(*buf, ssp->base + HW_SSP_DATA(ssp)); writel(BM_SSP_CTRL0_DATA_XFER, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); - if (!(flags & TXRX_WRITE)) { + if (!write) { if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp), BM_SSP_STATUS_FIFO_EMPTY, 0)) return -ETIMEDOUT; @@ -379,15 +400,14 @@ static int mxs_spi_transfer_one(struct spi_master *master, { struct mxs_spi *spi = spi_master_get_devdata(master); struct mxs_ssp *ssp = &spi->ssp; + int first, last; struct spi_transfer *t, *tmp_t; - unsigned int flag; int status = 0; + int cs; + + first = last = 0; - /* Program CS register bits here, it will be used for all transfers. */ - writel(BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ, - ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); - writel(mxs_spi_cs_to_reg(m->spi->chip_select), - ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); + cs = m->spi->chip_select; list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { @@ -395,9 +415,16 @@ static int mxs_spi_transfer_one(struct spi_master *master, if (status) break; - /* De-assert on last transfer, inverted by cs_change flag */ - flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ? - TXRX_DEASSERT_CS : 0; + if (&t->transfer_list == m->transfers.next) + first = 1; + if (&t->transfer_list == m->transfers.prev) + last = 1; + if ((t->rx_buf && t->tx_buf) || (t->rx_dma && t->tx_dma)) { + dev_err(ssp->dev, + "Cannot send and receive simultaneously\n"); + status = -EINVAL; + break; + } /* * Small blocks can be transfered via PIO. @@ -414,26 +441,26 @@ static int mxs_spi_transfer_one(struct spi_master *master, STMP_OFFSET_REG_CLR); if (t->tx_buf) - status = mxs_spi_txrx_pio(spi, + status = mxs_spi_txrx_pio(spi, cs, (void *)t->tx_buf, - t->len, flag | TXRX_WRITE); + t->len, &first, &last, 1); if (t->rx_buf) - status = mxs_spi_txrx_pio(spi, + status = mxs_spi_txrx_pio(spi, cs, t->rx_buf, t->len, - flag); + &first, &last, 0); } else { writel(BM_SSP_CTRL1_DMA_ENABLE, ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET); if (t->tx_buf) - status = mxs_spi_txrx_dma(spi, + status = mxs_spi_txrx_dma(spi, cs, (void *)t->tx_buf, t->len, - flag | TXRX_WRITE); + &first, &last, 1); if (t->rx_buf) - status = mxs_spi_txrx_dma(spi, + status = mxs_spi_txrx_dma(spi, cs, t->rx_buf, t->len, - flag); + &first, &last, 0); } if (status) { @@ -442,6 +469,7 @@ static int mxs_spi_transfer_one(struct spi_master *master, } m->actual_length += t->len; + first = last = 0; } m->status = status; @@ -535,6 +563,7 @@ static int mxs_spi_probe(struct platform_device *pdev) goto out_dma_release; clk_set_rate(ssp->clk, clk_freq); + ssp->clk_rate = clk_get_rate(ssp->clk) / 1000; ret = stmp_reset_block(ssp->base); if (ret) @@ -542,7 +571,7 @@ static int mxs_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret); goto out_disable_clk; @@ -565,12 +594,14 @@ static int mxs_spi_remove(struct platform_device *pdev) struct mxs_spi *spi; struct mxs_ssp *ssp; - master = platform_get_drvdata(pdev); + master = spi_master_get(platform_get_drvdata(pdev)); spi = spi_master_get_devdata(master); ssp = &spi->ssp; + spi_unregister_master(master); clk_disable_unprepare(ssp->clk); dma_release_channel(ssp->dmach); + spi_master_put(master); return 0; } diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index e0c32bc..47a68b4 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -349,7 +349,7 @@ static int nuc900_spi_probe(struct platform_device *pdev) } hw = spi_master_get_devdata(master); - hw->master = master; + hw->master = spi_master_get(master); hw->pdata = dev_get_platdata(&pdev->dev); hw->dev = &pdev->dev; @@ -435,6 +435,7 @@ err_iomap: kfree(hw->ioarea); err_pdata: spi_master_put(hw->master); + err_nomem: return err; } diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 91c6685..333cb1b 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -306,7 +306,7 @@ static int tiny_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); /* setup the state for the bitbang driver */ - hw->bitbang.master = master; + hw->bitbang.master = spi_master_get(master); if (!hw->bitbang.master) return err; hw->bitbang.setup_transfer = tiny_spi_setup_transfer; diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index 67249a4..5f28ddb 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -272,7 +272,7 @@ static int octeon_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_MASK(8); master->dev.of_node = pdev->dev.of_node; - err = devm_spi_register_master(&pdev->dev, master); + err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "register master failed: %d\n", err); goto fail; @@ -292,6 +292,8 @@ static int octeon_spi_remove(struct platform_device *pdev) struct octeon_spi *p = spi_master_get_devdata(master); u64 register_base = p->register_base; + spi_unregister_master(master); + /* Clear the CSENA* and put everything in a known state. */ cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0); diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index b6ed82b..69ecf05 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -457,7 +457,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev) goto err; } - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status < 0) goto err; @@ -485,6 +485,8 @@ static int omap1_spi100k_remove(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + spi_unregister_master(master); + return 0; } diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 9313fd3..a6a8f09 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -557,8 +557,7 @@ static struct platform_driver uwire_driver = { .name = "omap_uwire", .owner = THIS_MODULE, }, - .probe = uwire_probe, - .remove = uwire_remove, + .remove = uwire_remove, // suspend ... unuse ck // resume ... use ck }; @@ -580,7 +579,7 @@ static int __init omap_uwire_init(void) omap_writel(val | 0x00AAA000, OMAP7XX_IO_CONF_9); } - return platform_driver_register(&uwire_driver); + return platform_driver_probe(&uwire_driver, uwire_probe); } static void __exit omap_uwire_exit(void) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 443df39..ed4af47 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -276,7 +276,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, struct omap2_mcspi_cs *cs = spi->controller_state; struct omap2_mcspi *mcspi; unsigned int wcnt; - int max_fifo_depth, fifo_depth, bytes_per_word; + int fifo_depth, bytes_per_word; u32 chconf, xferlevel; mcspi = spi_master_get_devdata(master); @@ -287,12 +287,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, if (t->len % bytes_per_word != 0) goto disable_fifo; - if (t->rx_buf != NULL && t->tx_buf != NULL) - max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH / 2; - else - max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH; - - fifo_depth = gcd(t->len, max_fifo_depth); + fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH); if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0) goto disable_fifo; @@ -304,8 +299,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, if (t->rx_buf != NULL) { chconf |= OMAP2_MCSPI_CHCONF_FFER; xferlevel |= (fifo_depth - 1) << 8; - } - if (t->tx_buf != NULL) { + } else { chconf |= OMAP2_MCSPI_CHCONF_FFET; xferlevel |= fifo_depth - 1; } @@ -504,7 +498,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, ((u32 *)xfer->rx_buf)[elements++] = w; } else { int bytes_per_word = mcspi_bytes_per_word(word_len); - dev_err(&spi->dev, "DMA RX penultimate word empty\n"); + dev_err(&spi->dev, "DMA RX penultimate word empty"); count -= (bytes_per_word << 1); omap2_mcspi_set_enable(spi, 1); return count; @@ -522,7 +516,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, else /* word_len <= 32 */ ((u32 *)xfer->rx_buf)[elements] = w; } else { - dev_err(&spi->dev, "DMA RX last word empty\n"); + dev_err(&spi->dev, "DMA RX last word empty"); count -= mcspi_bytes_per_word(word_len); } omap2_mcspi_set_enable(spi, 1); @@ -1413,7 +1407,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) if (status < 0) goto disable_pm; - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status < 0) goto disable_pm; @@ -1441,6 +1435,7 @@ static int omap2_mcspi_remove(struct platform_device *pdev) pm_runtime_put_sync(mcspi->dev); pm_runtime_disable(&pdev->dev); + spi_unregister_master(master); kfree(dma_channels); return 0; diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 744841e..1d1d321 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -84,8 +84,8 @@ static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size) orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG, ORION_SPI_IF_8_16_BIT_MODE); } else { - pr_debug("Bad bits per word value %d (only 8 or 16 are allowed).\n", - size); + pr_debug("Bad bits per word value %d (only 8 or 16 are " + "allowed).\n", size); return -EINVAL; } @@ -407,7 +407,7 @@ static int orion_spi_probe(struct platform_device *pdev) const u32 *iprop; int size; - master = spi_alloc_master(&pdev->dev, sizeof(*spi)); + master = spi_alloc_master(&pdev->dev, sizeof *spi); if (master == NULL) { dev_dbg(&pdev->dev, "master allocation failed\n"); return -ENOMEM; @@ -457,7 +457,7 @@ static int orion_spi_probe(struct platform_device *pdev) goto out_rel_clk; master->dev.of_node = pdev->dev.of_node; - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status < 0) goto out_rel_clk; @@ -483,6 +483,8 @@ static int orion_spi_remove(struct platform_device *pdev) clk_disable_unprepare(spi->clk); clk_put(spi->clk); + spi_unregister_master(master); + return 0; } diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 2789b45..9c511a9 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1619,6 +1619,7 @@ static int verify_controller_parameters(struct pl022 *pl022, dev_err(&pl022->adev->dev, "RX FIFO Trigger Level is configured incorrectly\n"); return -EINVAL; + break; } switch (chip_info->tx_lev_trig) { case SSP_TX_1_OR_MORE_EMPTY_LOC: @@ -1644,6 +1645,7 @@ static int verify_controller_parameters(struct pl022 *pl022, dev_err(&pl022->adev->dev, "TX FIFO Trigger Level is configured incorrectly\n"); return -EINVAL; + break; } if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) { if ((chip_info->ctrl_len < SSP_BITS_4) @@ -2173,8 +2175,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) status = -ENOMEM; goto err_no_ioremap; } - dev_info(&adev->dev, "mapped registers from %pa to %p\n", - &adev->res.start, pl022->virtbase); + printk(KERN_INFO "pl022: mapped registers from %pa to %p\n", + &adev->res.start, pl022->virtbase); pl022->clk = devm_clk_get(&adev->dev, NULL); if (IS_ERR(pl022->clk)) { @@ -2225,7 +2227,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) /* Register with the SPI framework */ amba_set_drvdata(adev, pl022); - status = devm_spi_register_master(&adev->dev, master); + status = spi_register_master(master); if (status != 0) { dev_err(&adev->dev, "probe - problem registering spi master\n"); @@ -2285,6 +2287,8 @@ pl022_remove(struct amba_device *adev) clk_unprepare(pl022->clk); amba_release_regions(adev); tasklet_disable(&pl022->pump_transfers); + spi_unregister_master(pl022->master); + amba_set_drvdata(adev, NULL); return 0; } diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 5ee5672..0ee53c2 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -29,8 +29,6 @@ #include <linux/slab.h> #include <linux/errno.h> #include <linux/wait.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <linux/interrupt.h> @@ -398,7 +396,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) master->dev.of_node = np; platform_set_drvdata(op, master); hw = spi_master_get_devdata(master); - hw->master = master; + hw->master = spi_master_get(master); hw->dev = dev; init_completion(&hw->done); @@ -560,7 +558,6 @@ static int spi_ppc4xx_of_remove(struct platform_device *op) free_irq(hw->irqnum, hw); iounmap(hw->regs); free_gpios(hw); - spi_master_put(master); return 0; } diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 7765b19..c1a5067 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -573,8 +573,8 @@ static irqreturn_t ssp_int(int irq, void *dev_id) write_SSTO(0, reg); write_SSSR_CS(drv_data, drv_data->clear_sr); - dev_err(&drv_data->pdev->dev, - "bad message state in interrupt handler\n"); + dev_err(&drv_data->pdev->dev, "bad message state " + "in interrupt handler\n"); /* Never fail */ return IRQ_HANDLED; @@ -651,8 +651,8 @@ static void pump_transfers(unsigned long data) if (message->is_dma_mapped || transfer->rx_dma || transfer->tx_dma) { dev_err(&drv_data->pdev->dev, - "pump_transfers: mapped transfer length of " - "%u is greater than %d\n", + "pump_transfers: mapped transfer length " + "of %u is greater than %d\n", transfer->len, MAX_DMA_LEN); message->status = -EINVAL; giveback(drv_data); @@ -660,10 +660,11 @@ static void pump_transfers(unsigned long data) } /* warn ... we force this to PIO mode */ - dev_warn_ratelimited(&message->spi->dev, - "pump_transfers: DMA disabled for transfer length %ld " - "greater than %d\n", - (long)drv_data->len, MAX_DMA_LEN); + if (printk_ratelimit()) + dev_warn(&message->spi->dev, "pump_transfers: " + "DMA disabled for transfer length %ld " + "greater than %d\n", + (long)drv_data->len, MAX_DMA_LEN); } /* Setup the transfer state based on the type of transfer */ @@ -725,8 +726,11 @@ static void pump_transfers(unsigned long data) message->spi, bits, &dma_burst, &dma_thresh)) - dev_warn_ratelimited(&message->spi->dev, - "pump_transfers: DMA burst size reduced to match bits_per_word\n"); + if (printk_ratelimit()) + dev_warn(&message->spi->dev, + "pump_transfers: " + "DMA burst size reduced to " + "match bits_per_word\n"); } cr0 = clk_div @@ -850,8 +854,8 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, if (gpio_is_valid(chip_info->gpio_cs)) { err = gpio_request(chip_info->gpio_cs, "SPI_CS"); if (err) { - dev_err(&spi->dev, "failed to request chip select GPIO%d\n", - chip_info->gpio_cs); + dev_err(&spi->dev, "failed to request chip select " + "GPIO%d\n", chip_info->gpio_cs); return err; } @@ -895,8 +899,8 @@ static int setup(struct spi_device *spi) if (drv_data->ssp_type == CE4100_SSP) { if (spi->chip_select > 4) { - dev_err(&spi->dev, - "failed setup: cs number must not be > 4.\n"); + dev_err(&spi->dev, "failed setup: " + "cs number must not be > 4.\n"); kfree(chip); return -EINVAL; } @@ -952,8 +956,8 @@ static int setup(struct spi_device *spi) spi->bits_per_word, &chip->dma_burst_size, &chip->dma_threshold)) { - dev_warn(&spi->dev, - "in setup: DMA burst size reduced to match bits_per_word\n"); + dev_warn(&spi->dev, "in setup: DMA burst size reduced " + "to match bits_per_word\n"); } } @@ -1073,8 +1077,6 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) static struct acpi_device_id pxa2xx_spi_acpi_match[] = { { "INT33C0", 0 }, { "INT33C1", 0 }, - { "INT3430", 0 }, - { "INT3431", 0 }, { "80860F0E", 0 }, { }, }; @@ -1203,7 +1205,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) /* Register with the SPI framework */ platform_set_drvdata(pdev, drv_data); - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status != 0) { dev_err(&pdev->dev, "problem registering spi master\n"); goto out_error_clock_enabled; @@ -1255,6 +1257,9 @@ static int pxa2xx_spi_remove(struct platform_device *pdev) /* Release SSP */ pxa_ssp_free(ssp); + /* Disconnect from the SPI framework */ + spi_unregister_master(drv_data->master); + return 0; } @@ -1293,9 +1298,6 @@ static int pxa2xx_spi_resume(struct device *dev) /* Enable the SSP clock */ clk_prepare_enable(ssp->clk); - /* Restore LPSS private register bits */ - lpss_ssp_setup(drv_data); - /* Start the queue running */ status = spi_master_resume(drv_data->master); if (status != 0) { diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 9e829ce..8719206 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -59,14 +59,6 @@ #define RSPI_SPCMD6 0x1c #define RSPI_SPCMD7 0x1e -/*qspi only */ -#define QSPI_SPBFCR 0x18 -#define QSPI_SPBDCR 0x1a -#define QSPI_SPBMUL0 0x1c -#define QSPI_SPBMUL1 0x20 -#define QSPI_SPBMUL2 0x24 -#define QSPI_SPBMUL3 0x28 - /* SPCR */ #define SPCR_SPRIE 0x80 #define SPCR_SPE 0x40 @@ -134,8 +126,6 @@ #define SPCMD_LSBF 0x1000 #define SPCMD_SPB_MASK 0x0f00 #define SPCMD_SPB_8_TO_16(bit) (((bit - 1) << 8) & SPCMD_SPB_MASK) -#define SPCMD_SPB_8BIT 0x0000 /* qspi only */ -#define SPCMD_SPB_16BIT 0x0100 #define SPCMD_SPB_20BIT 0x0000 #define SPCMD_SPB_24BIT 0x0100 #define SPCMD_SPB_32BIT 0x0200 @@ -145,10 +135,6 @@ #define SPCMD_CPOL 0x0002 #define SPCMD_CPHA 0x0001 -/* SPBFCR */ -#define SPBFCR_TXRST 0x80 /* qspi only */ -#define SPBFCR_RXRST 0x40 /* qspi only */ - struct rspi_data { void __iomem *addr; u32 max_speed_hz; @@ -159,7 +145,6 @@ struct rspi_data { spinlock_t lock; struct clk *clk; unsigned char spsr; - const struct spi_ops *ops; /* for dmaengine */ struct dma_chan *chan_tx; @@ -180,11 +165,6 @@ static void rspi_write16(struct rspi_data *rspi, u16 data, u16 offset) iowrite16(data, rspi->addr + offset); } -static void rspi_write32(struct rspi_data *rspi, u32 data, u16 offset) -{ - iowrite32(data, rspi->addr + offset); -} - static u8 rspi_read8(struct rspi_data *rspi, u16 offset) { return ioread8(rspi->addr + offset); @@ -195,103 +175,17 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset) return ioread16(rspi->addr + offset); } -/* optional functions */ -struct spi_ops { - int (*set_config_register)(struct rspi_data *rspi, int access_size); - int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg, - struct spi_transfer *t); - int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg, - struct spi_transfer *t); - -}; - -/* - * functions for RSPI - */ -static int rspi_set_config_register(struct rspi_data *rspi, int access_size) -{ - int spbr; - - /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ - rspi_write8(rspi, 0x00, RSPI_SPPCR); - - /* Sets transfer bit rate */ - spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; - rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); - - /* Sets number of frames to be used: 1 frame */ - rspi_write8(rspi, 0x00, RSPI_SPDCR); - - /* Sets RSPCK, SSL, next-access delay value */ - rspi_write8(rspi, 0x00, RSPI_SPCKD); - rspi_write8(rspi, 0x00, RSPI_SSLND); - rspi_write8(rspi, 0x00, RSPI_SPND); - - /* Sets parity, interrupt mask */ - rspi_write8(rspi, 0x00, RSPI_SPCR2); - - /* Sets SPCMD */ - rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, - RSPI_SPCMD0); - - /* Sets RSPI mode */ - rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); - - return 0; -} - -/* - * functions for QSPI - */ -static int qspi_set_config_register(struct rspi_data *rspi, int access_size) +static unsigned char rspi_calc_spbr(struct rspi_data *rspi) { - u16 spcmd; - int spbr; - - /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ - rspi_write8(rspi, 0x00, RSPI_SPPCR); - - /* Sets transfer bit rate */ - spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz); - rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); - - /* Sets number of frames to be used: 1 frame */ - rspi_write8(rspi, 0x00, RSPI_SPDCR); - - /* Sets RSPCK, SSL, next-access delay value */ - rspi_write8(rspi, 0x00, RSPI_SPCKD); - rspi_write8(rspi, 0x00, RSPI_SSLND); - rspi_write8(rspi, 0x00, RSPI_SPND); - - /* Data Length Setting */ - if (access_size == 8) - spcmd = SPCMD_SPB_8BIT; - else if (access_size == 16) - spcmd = SPCMD_SPB_16BIT; - else if (access_size == 32) - spcmd = SPCMD_SPB_32BIT; - - spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SSLKP | SPCMD_SPNDEN; - - /* Resets transfer data length */ - rspi_write32(rspi, 0, QSPI_SPBMUL0); - - /* Resets transmit and receive buffer */ - rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); - /* Sets buffer to allow normal operation */ - rspi_write8(rspi, 0x00, QSPI_SPBFCR); - - /* Sets SPCMD */ - rspi_write16(rspi, spcmd, RSPI_SPCMD0); + int tmp; + unsigned char spbr; - /* Enables SPI function in a master mode */ - rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR); + tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; + spbr = clamp(tmp, 0, 255); - return 0; + return spbr; } -#define set_config_register(spi, n) spi->ops->set_config_register(spi, n) - static void rspi_enable_irq(struct rspi_data *rspi, u8 enable) { rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR); @@ -326,60 +220,54 @@ static void rspi_negate_ssl(struct rspi_data *rspi) rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); } -static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, - struct spi_transfer *t) +static int rspi_set_config_register(struct rspi_data *rspi, int access_size) { - int remain = t->len; - u8 *data; + /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ + rspi_write8(rspi, 0x00, RSPI_SPPCR); - data = (u8 *)t->tx_buf; - while (remain > 0) { - rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, - RSPI_SPCR); + /* Sets transfer bit rate */ + rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR); - if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { - dev_err(&rspi->master->dev, - "%s: tx empty timeout\n", __func__); - return -ETIMEDOUT; - } + /* Sets number of frames to be used: 1 frame */ + rspi_write8(rspi, 0x00, RSPI_SPDCR); - rspi_write16(rspi, *data, RSPI_SPDR); - data++; - remain--; - } + /* Sets RSPCK, SSL, next-access delay value */ + rspi_write8(rspi, 0x00, RSPI_SPCKD); + rspi_write8(rspi, 0x00, RSPI_SSLND); + rspi_write8(rspi, 0x00, RSPI_SPND); - /* Waiting for the last transmition */ - rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); + /* Sets parity, interrupt mask */ + rspi_write8(rspi, 0x00, RSPI_SPCR2); + + /* Sets SPCMD */ + rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, + RSPI_SPCMD0); + + /* Sets RSPI mode */ + rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); return 0; } -static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, +static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, struct spi_transfer *t) { int remain = t->len; u8 *data; - rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); - rspi_write8(rspi, 0x00, QSPI_SPBFCR); - data = (u8 *)t->tx_buf; while (remain > 0) { + rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, + RSPI_SPCR); if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { dev_err(&rspi->master->dev, "%s: tx empty timeout\n", __func__); return -ETIMEDOUT; } - rspi_write8(rspi, *data++, RSPI_SPDR); - - if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { - dev_err(&rspi->master->dev, - "%s: receive timeout\n", __func__); - return -ETIMEDOUT; - } - rspi_read8(rspi, RSPI_SPDR); + rspi_write16(rspi, *data, RSPI_SPDR); + data++; remain--; } @@ -389,8 +277,6 @@ static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, return 0; } -#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t) - static void rspi_dma_complete(void *arg) { struct rspi_data *rspi = arg; @@ -556,51 +442,6 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, return 0; } -static void qspi_receive_init(struct rspi_data *rspi) -{ - unsigned char spsr; - - spsr = rspi_read8(rspi, RSPI_SPSR); - if (spsr & SPSR_SPRF) - rspi_read8(rspi, RSPI_SPDR); /* dummy read */ - rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); - rspi_write8(rspi, 0x00, QSPI_SPBFCR); -} - -static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, - struct spi_transfer *t) -{ - int remain = t->len; - u8 *data; - - qspi_receive_init(rspi); - - data = (u8 *)t->rx_buf; - while (remain > 0) { - - if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { - dev_err(&rspi->master->dev, - "%s: tx empty timeout\n", __func__); - return -ETIMEDOUT; - } - /* dummy write for generate clock */ - rspi_write8(rspi, 0x00, RSPI_SPDR); - - if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { - dev_err(&rspi->master->dev, - "%s: receive timeout\n", __func__); - return -ETIMEDOUT; - } - /* SPDR allows 8, 16 or 32-bit access */ - *data++ = rspi_read8(rspi, RSPI_SPDR); - remain--; - } - - return 0; -} - -#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t) - static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) { struct scatterlist sg, sg_dummy; @@ -740,7 +581,7 @@ static void rspi_work(struct work_struct *work) if (rspi_is_dma(rspi, t)) ret = rspi_send_dma(rspi, t); else - ret = send_pio(rspi, mesg, t); + ret = rspi_send_pio(rspi, mesg, t); if (ret < 0) goto error; } @@ -748,7 +589,7 @@ static void rspi_work(struct work_struct *work) if (rspi_is_dma(rspi, t)) ret = rspi_receive_dma(rspi, t); else - ret = receive_pio(rspi, mesg, t); + ret = rspi_receive_pio(rspi, mesg, t); if (ret < 0) goto error; } @@ -775,7 +616,7 @@ static int rspi_setup(struct spi_device *spi) spi->bits_per_word = 8; rspi->max_speed_hz = spi->max_speed_hz; - set_config_register(rspi, 8); + rspi_set_config_register(rspi, 8); return 0; } @@ -885,13 +726,14 @@ static void rspi_release_dma(struct rspi_data *rspi) static int rspi_remove(struct platform_device *pdev) { - struct rspi_data *rspi = platform_get_drvdata(pdev); + struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev)); spi_unregister_master(rspi->master); rspi_release_dma(rspi); free_irq(platform_get_irq(pdev, 0), rspi); clk_put(rspi->clk); iounmap(rspi->addr); + spi_master_put(rspi->master); return 0; } @@ -903,16 +745,7 @@ static int rspi_probe(struct platform_device *pdev) struct rspi_data *rspi; int ret, irq; char clk_name[16]; - struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; - const struct spi_ops *ops; - const struct platform_device_id *id_entry = pdev->id_entry; - - ops = (struct spi_ops *)id_entry->driver_data; - /* ops parameter check */ - if (!ops->set_config_register) { - dev_err(&pdev->dev, "there is no set_config_register\n"); - return -ENODEV; - } + /* get base addr */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(res == NULL)) { @@ -934,7 +767,7 @@ static int rspi_probe(struct platform_device *pdev) rspi = spi_master_get_devdata(master); platform_set_drvdata(pdev, rspi); - rspi->ops = ops; + rspi->master = master; rspi->addr = ioremap(res->start, resource_size(res)); if (rspi->addr == NULL) { @@ -943,7 +776,7 @@ static int rspi_probe(struct platform_device *pdev) goto error1; } - snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id); + snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id); rspi->clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(rspi->clk)) { dev_err(&pdev->dev, "cannot get clock\n"); @@ -957,10 +790,7 @@ static int rspi_probe(struct platform_device *pdev) INIT_WORK(&rspi->ws, rspi_work); init_waitqueue_head(&rspi->wait); - master->num_chipselect = rspi_pd->num_chipselect; - if (!master->num_chipselect) - master->num_chipselect = 2; /* default */ - + master->num_chipselect = 2; master->bus_num = pdev->id; master->setup = rspi_setup; master->transfer = rspi_transfer; @@ -1002,32 +832,11 @@ error1: return ret; } -static struct spi_ops rspi_ops = { - .set_config_register = rspi_set_config_register, - .send_pio = rspi_send_pio, - .receive_pio = rspi_receive_pio, -}; - -static struct spi_ops qspi_ops = { - .set_config_register = qspi_set_config_register, - .send_pio = qspi_send_pio, - .receive_pio = qspi_receive_pio, -}; - -static struct platform_device_id spi_driver_ids[] = { - { "rspi", (kernel_ulong_t)&rspi_ops }, - { "qspi", (kernel_ulong_t)&qspi_ops }, - {}, -}; - -MODULE_DEVICE_TABLE(platform, spi_driver_ids); - static struct platform_driver rspi_driver = { .probe = rspi_probe, .remove = rspi_remove, - .id_table = spi_driver_ids, .driver = { - .name = "renesas_spi", + .name = "rspi", .owner = THIS_MODULE, }, }; diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index 0dc32a1..ce318d9 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -280,7 +280,7 @@ static inline u32 ack_bit(unsigned int irq) * so the caller does not need to do anything more than start the transfer * as normal, since the IRQ will have been re-routed to the FIQ handler. */ -static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) +void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) { struct pt_regs regs; enum spi_fiq_mode mode; @@ -524,7 +524,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) hw = spi_master_get_devdata(master); memset(hw, 0, sizeof(struct s3c24xx_spi)); - hw->master = master; + hw->master = spi_master_get(master); hw->pdata = pdata = dev_get_platdata(&pdev->dev); hw->dev = &pdev->dev; diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 4c4b0a1..a80376d 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -205,6 +205,7 @@ struct s3c64xx_spi_driver_data { #endif struct s3c64xx_spi_port_config *port_conf; unsigned int port_id; + unsigned long gpios[4]; bool cs_gpio; }; @@ -558,18 +559,25 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, struct spi_device *spi) { + struct s3c64xx_spi_csinfo *cs; + if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ /* Deselect the last toggled device */ - if (spi->cs_gpio >= 0) - gpio_set_value(spi->cs_gpio, + cs = sdd->tgl_spi->controller_data; + if (sdd->cs_gpio) + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); } sdd->tgl_spi = NULL; } - if (spi->cs_gpio >= 0) - gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 1 : 0); + cs = spi->controller_data; + if (sdd->cs_gpio) + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); + + /* Start the signals */ + writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); } static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, @@ -694,11 +702,16 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, struct spi_device *spi) { + struct s3c64xx_spi_csinfo *cs = spi->controller_data; + if (sdd->tgl_spi == spi) sdd->tgl_spi = NULL; - if (spi->cs_gpio >= 0) - gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); + if (sdd->cs_gpio) + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); + + /* Quiese the signals */ + writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); } static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) @@ -849,12 +862,16 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, } } -static int s3c64xx_spi_prepare_message(struct spi_master *master, - struct spi_message *msg) +static int s3c64xx_spi_transfer_one_message(struct spi_master *master, + struct spi_message *msg) { struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; struct s3c64xx_spi_csinfo *cs = spi->controller_data; + struct spi_transfer *xfer; + int status = 0, cs_toggle = 0; + u32 speed; + u8 bpw; /* If Master's(controller) state differs from that needed by Slave */ if (sdd->cur_speed != spi->max_speed_hz @@ -870,99 +887,107 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master, if (s3c64xx_spi_map_mssg(sdd, msg)) { dev_err(&spi->dev, "Xfer: Unable to map message buffers!\n"); - return -ENOMEM; + status = -ENOMEM; + goto out; } /* Configure feedback delay */ writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); - return 0; -} + list_for_each_entry(xfer, &msg->transfers, transfer_list) { -static int s3c64xx_spi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *xfer) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - int status; - u32 speed; - u8 bpw; - unsigned long flags; - int use_dma; + unsigned long flags; + int use_dma; - reinit_completion(&sdd->xfer_completion); + INIT_COMPLETION(sdd->xfer_completion); - /* Only BPW and Speed may change across transfers */ - bpw = xfer->bits_per_word; - speed = xfer->speed_hz ? : spi->max_speed_hz; + /* Only BPW and Speed may change across transfers */ + bpw = xfer->bits_per_word; + speed = xfer->speed_hz ? : spi->max_speed_hz; - if (xfer->len % (bpw / 8)) { - dev_err(&spi->dev, - "Xfer length(%u) not a multiple of word size(%u)\n", - xfer->len, bpw / 8); - return -EIO; - } + if (xfer->len % (bpw / 8)) { + dev_err(&spi->dev, + "Xfer length(%u) not a multiple of word size(%u)\n", + xfer->len, bpw / 8); + status = -EIO; + goto out; + } - if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { - sdd->cur_bpw = bpw; - sdd->cur_speed = speed; - s3c64xx_spi_config(sdd); - } + if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { + sdd->cur_bpw = bpw; + sdd->cur_speed = speed; + s3c64xx_spi_config(sdd); + } - /* Polling method for xfers not bigger than FIFO capacity */ - use_dma = 0; - if (!is_polling(sdd) && - (sdd->rx_dma.ch && sdd->tx_dma.ch && - (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) - use_dma = 1; + /* Polling method for xfers not bigger than FIFO capacity */ + use_dma = 0; + if (!is_polling(sdd) && + (sdd->rx_dma.ch && sdd->tx_dma.ch && + (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) + use_dma = 1; - spin_lock_irqsave(&sdd->lock, flags); + spin_lock_irqsave(&sdd->lock, flags); + + /* Pending only which is to be done */ + sdd->state &= ~RXBUSY; + sdd->state &= ~TXBUSY; - /* Pending only which is to be done */ - sdd->state &= ~RXBUSY; - sdd->state &= ~TXBUSY; + enable_datapath(sdd, spi, xfer, use_dma); - enable_datapath(sdd, spi, xfer, use_dma); + /* Slave Select */ + enable_cs(sdd, spi); - /* Start the signals */ - writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); + spin_unlock_irqrestore(&sdd->lock, flags); - /* Start the signals */ - writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); + status = wait_for_xfer(sdd, xfer, use_dma); - spin_unlock_irqrestore(&sdd->lock, flags); + if (status) { + dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", + xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, + (sdd->state & RXBUSY) ? 'f' : 'p', + (sdd->state & TXBUSY) ? 'f' : 'p', + xfer->len); - status = wait_for_xfer(sdd, xfer, use_dma); - - if (status) { - dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", - xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, - (sdd->state & RXBUSY) ? 'f' : 'p', - (sdd->state & TXBUSY) ? 'f' : 'p', - xfer->len); - - if (use_dma) { - if (xfer->tx_buf != NULL - && (sdd->state & TXBUSY)) - s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); - if (xfer->rx_buf != NULL - && (sdd->state & RXBUSY)) - s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); + if (use_dma) { + if (xfer->tx_buf != NULL + && (sdd->state & TXBUSY)) + s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); + if (xfer->rx_buf != NULL + && (sdd->state & RXBUSY)) + s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); + } + + goto out; } - } else { + + if (xfer->delay_usecs) + udelay(xfer->delay_usecs); + + if (xfer->cs_change) { + /* Hint that the next mssg is gonna be + for the same device */ + if (list_is_last(&xfer->transfer_list, + &msg->transfers)) + cs_toggle = 1; + } + + msg->actual_length += xfer->len; + flush_fifo(sdd); } - return status; -} - -static int s3c64xx_spi_unprepare_message(struct spi_master *master, - struct spi_message *msg) -{ - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); +out: + if (!cs_toggle || status) + disable_cs(sdd, spi); + else + sdd->tgl_spi = spi; s3c64xx_spi_unmap_mssg(sdd, msg); + msg->status = status; + + spi_finalize_current_message(master); + return 0; } @@ -1046,8 +1071,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) cs->line, err); goto err_gpio_req; } - - spi->cs_gpio = cs->line; } spi_set_ctldata(spi, cs); @@ -1094,14 +1117,11 @@ static int s3c64xx_spi_setup(struct spi_device *spi) } pm_runtime_put(&sdd->pdev->dev); - writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); disable_cs(sdd, spi); return 0; setup_exit: - pm_runtime_put(&sdd->pdev->dev); /* setup() returns with device de-selected */ - writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); disable_cs(sdd, spi); gpio_free(cs->line); @@ -1120,8 +1140,8 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi) struct s3c64xx_spi_driver_data *sdd; sdd = spi_master_get_devdata(spi->master); - if (spi->cs_gpio) { - gpio_free(spi->cs_gpio); + if (cs && sdd->cs_gpio) { + gpio_free(cs->line); if (spi->dev.of_node) kfree(cs); } @@ -1339,9 +1359,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) master->setup = s3c64xx_spi_setup; master->cleanup = s3c64xx_spi_cleanup; master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; - master->prepare_message = s3c64xx_spi_prepare_message; - master->transfer_one = s3c64xx_spi_transfer_one; - master->unprepare_message = s3c64xx_spi_unprepare_message; + master->transfer_one_message = s3c64xx_spi_transfer_one_message; master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; master->num_chipselect = sci->num_cs; master->dma_alignment = 8; @@ -1410,12 +1428,11 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, sdd->regs + S3C64XX_SPI_INT_EN); - pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = devm_spi_register_master(&pdev->dev, master); - if (ret != 0) { - dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret); + if (spi_register_master(master)) { + dev_err(&pdev->dev, "cannot register SPI master\n"); + ret = -EBUSY; goto err3; } @@ -1444,12 +1461,16 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); + spi_unregister_master(master); + writel(0, sdd->regs + S3C64XX_SPI_INT_EN); clk_disable_unprepare(sdd->src_clk); clk_disable_unprepare(sdd->clk); + spi_master_put(master); + return 0; } @@ -1459,14 +1480,11 @@ static int s3c64xx_spi_suspend(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - int ret = spi_master_suspend(master); - if (ret) - return ret; + spi_master_suspend(master); - if (!pm_runtime_suspended(dev)) { - clk_disable_unprepare(sdd->clk); - clk_disable_unprepare(sdd->src_clk); - } + /* Disable the clock */ + clk_disable_unprepare(sdd->src_clk); + clk_disable_unprepare(sdd->clk); sdd->cur_speed = 0; /* Output Clock is stopped */ @@ -1482,14 +1500,15 @@ static int s3c64xx_spi_resume(struct device *dev) if (sci->cfg_gpio) sci->cfg_gpio(); - if (!pm_runtime_suspended(dev)) { - clk_prepare_enable(sdd->src_clk); - clk_prepare_enable(sdd->clk); - } + /* Enable the clock */ + clk_prepare_enable(sdd->src_clk); + clk_prepare_enable(sdd->clk); s3c64xx_spi_hwinit(sdd, sdd->port_id); - return spi_master_resume(master); + spi_master_resume(master); + + return 0; } #endif /* CONFIG_PM_SLEEP */ @@ -1509,17 +1528,9 @@ static int s3c64xx_spi_runtime_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - int ret; - ret = clk_prepare_enable(sdd->src_clk); - if (ret != 0) - return ret; - - ret = clk_prepare_enable(sdd->clk); - if (ret != 0) { - clk_disable_unprepare(sdd->src_clk); - return ret; - } + clk_prepare_enable(sdd->src_clk); + clk_prepare_enable(sdd->clk); return 0; } @@ -1605,18 +1616,6 @@ static struct platform_device_id s3c64xx_spi_driver_ids[] = { }; static const struct of_device_id s3c64xx_spi_dt_match[] = { - { .compatible = "samsung,s3c2443-spi", - .data = (void *)&s3c2443_spi_port_config, - }, - { .compatible = "samsung,s3c6410-spi", - .data = (void *)&s3c6410_spi_port_config, - }, - { .compatible = "samsung,s5pc100-spi", - .data = (void *)&s5pc100_spi_port_config, - }, - { .compatible = "samsung,s5pv210-spi", - .data = (void *)&s5pv210_spi_port_config, - }, { .compatible = "samsung,exynos4210-spi", .data = (void *)&exynos4_spi_port_config, }, @@ -1634,13 +1633,22 @@ static struct platform_driver s3c64xx_spi_driver = { .pm = &s3c64xx_spi_pm, .of_match_table = of_match_ptr(s3c64xx_spi_dt_match), }, - .probe = s3c64xx_spi_probe, .remove = s3c64xx_spi_remove, .id_table = s3c64xx_spi_driver_ids, }; MODULE_ALIAS("platform:s3c64xx-spi"); -module_platform_driver(s3c64xx_spi_driver); +static int __init s3c64xx_spi_init(void) +{ + return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); +} +subsys_initcall(s3c64xx_spi_init); + +static void __exit s3c64xx_spi_exit(void) +{ + platform_driver_unregister(&s3c64xx_spi_driver); +} +module_exit(s3c64xx_spi_exit); MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 292567a..e488a90 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -137,7 +137,7 @@ static void hspi_hw_setup(struct hspi_priv *hspi, rate /= 16; /* CLKCx calculation */ - rate /= (((idiv_clk & 0x1F) + 1) * 2); + rate /= (((idiv_clk & 0x1F) + 1) * 2) ; /* save best settings */ tmp = abs(target_rate - rate); @@ -303,10 +303,9 @@ static int hspi_probe(struct platform_device *pdev) master->setup = hspi_setup; master->cleanup = hspi_cleanup; master->mode_bits = SPI_CPOL | SPI_CPHA; - master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; master->transfer_one_message = hspi_transfer_one_message; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(&pdev->dev, "spi_register_master error.\n"); goto error1; @@ -329,23 +328,17 @@ static int hspi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); clk_put(hspi->clk); + spi_unregister_master(hspi->master); return 0; } -static struct of_device_id hspi_of_match[] = { - { .compatible = "renesas,hspi", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, hspi_of_match); - static struct platform_driver hspi_driver = { .probe = hspi_probe, .remove = hspi_remove, .driver = { .name = "sh-hspi", .owner = THIS_MODULE, - .of_match_table = hspi_of_match, }, }; module_platform_driver(hspi_driver); diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index c74298c..2a95435 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -465,7 +465,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TXE); /* start by setting frame bit */ - reinit_completion(&p->done); + INIT_COMPLETION(p->done); ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE); if (ret) { dev_err(&p->pdev->dev, "failed to start hardware\n"); diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index 38eb24d..8eefeb6 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -133,7 +133,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) sp->info = dev_get_platdata(&dev->dev); /* setup spi bitbang adaptor */ - sp->bitbang.master = master; + sp->bitbang.master = spi_master_get(master); sp->bitbang.master->bus_num = sp->info->bus_num; sp->bitbang.master->num_chipselect = sp->info->num_chipselect; sp->bitbang.chipselect = sh_sci_spi_chipselect; diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index ed5e501..a1f21b7 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -305,8 +305,8 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t) sspi->tx = t->tx_buf ? t->tx_buf : sspi->dummypage; sspi->rx = t->rx_buf ? t->rx_buf : sspi->dummypage; sspi->left_tx_word = sspi->left_rx_word = t->len / sspi->word_width; - reinit_completion(&sspi->rx_done); - reinit_completion(&sspi->tx_done); + INIT_COMPLETION(sspi->rx_done); + INIT_COMPLETION(sspi->tx_done); writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS); @@ -632,7 +632,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) if (ret) goto free_master; - sspi->bitbang.master = master; + sspi->bitbang.master = spi_master_get(master); sspi->bitbang.chipselect = spi_sirfsoc_chipselect; sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer; sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index aaecfb3..145dd43 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -182,7 +182,6 @@ struct tegra_spi_data { u32 cur_speed; struct spi_device *cur_spi; - struct spi_device *cs_control; unsigned cur_pos; unsigned cur_len; unsigned words_per_32bit; @@ -268,7 +267,7 @@ static unsigned tegra_spi_calculate_curr_xfer_param( unsigned max_len; unsigned total_fifo_words; - tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8); + tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1; if (bits_per_word == 8 || bits_per_word == 16) { tspi->is_packed = 1; @@ -451,7 +450,7 @@ static void tegra_spi_dma_complete(void *args) static int tegra_spi_start_tx_dma(struct tegra_spi_data *tspi, int len) { - reinit_completion(&tspi->tx_dma_complete); + INIT_COMPLETION(tspi->tx_dma_complete); tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan, tspi->tx_dma_phys, len, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -470,7 +469,7 @@ static int tegra_spi_start_tx_dma(struct tegra_spi_data *tspi, int len) static int tegra_spi_start_rx_dma(struct tegra_spi_data *tspi, int len) { - reinit_completion(&tspi->rx_dma_complete); + INIT_COMPLETION(tspi->rx_dma_complete); tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan, tspi->rx_dma_phys, len, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -677,12 +676,15 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi, dma_release_channel(dma_chan); } -static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi, - struct spi_transfer *t, bool is_first_of_msg) +static int tegra_spi_start_transfer_one(struct spi_device *spi, + struct spi_transfer *t, bool is_first_of_msg, + bool is_single_xfer) { struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); u32 speed = t->speed_hz; u8 bits_per_word = t->bits_per_word; + unsigned total_fifo_words; + int ret; unsigned long command1; int req_mode; @@ -696,6 +698,7 @@ static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi, tspi->cur_rx_pos = 0; tspi->cur_tx_pos = 0; tspi->curr_xfer = t; + total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t); if (is_first_of_msg) { tegra_spi_clear_status(tspi); @@ -714,12 +717,7 @@ static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi, else if (req_mode == SPI_MODE_3) command1 |= SPI_CONTROL_MODE_3; - if (tspi->cs_control) { - if (tspi->cs_control != spi) - tegra_spi_writel(tspi, command1, SPI_COMMAND1); - tspi->cs_control = NULL; - } else - tegra_spi_writel(tspi, command1, SPI_COMMAND1); + tegra_spi_writel(tspi, command1, SPI_COMMAND1); command1 |= SPI_CS_SW_HW; if (spi->mode & SPI_CS_HIGH) @@ -734,18 +732,6 @@ static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi, command1 |= SPI_BIT_LENGTH(bits_per_word - 1); } - return command1; -} - -static int tegra_spi_start_transfer_one(struct spi_device *spi, - struct spi_transfer *t, unsigned long command1) -{ - struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); - unsigned total_fifo_words; - int ret; - - total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t); - if (tspi->is_packed) command1 |= SPI_PACKED; @@ -817,50 +803,29 @@ static int tegra_spi_setup(struct spi_device *spi) return 0; } -static void tegra_spi_transfer_delay(int delay) -{ - if (!delay) - return; - - if (delay >= 1000) - mdelay(delay / 1000); - - udelay(delay % 1000); -} - static int tegra_spi_transfer_one_message(struct spi_master *master, struct spi_message *msg) { bool is_first_msg = true; + int single_xfer; struct tegra_spi_data *tspi = spi_master_get_devdata(master); struct spi_transfer *xfer; struct spi_device *spi = msg->spi; int ret; - bool skip = false; msg->status = 0; msg->actual_length = 0; + single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { - unsigned long cmd1; - - reinit_completion(&tspi->xfer_completion); - - cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg); - - if (!xfer->len) { - ret = 0; - skip = true; - goto complete_xfer; - } - - ret = tegra_spi_start_transfer_one(spi, xfer, cmd1); + INIT_COMPLETION(tspi->xfer_completion); + ret = tegra_spi_start_transfer_one(spi, xfer, + is_first_msg, single_xfer); if (ret < 0) { dev_err(tspi->dev, "spi can not start transfer, err %d\n", ret); - goto complete_xfer; + goto exit; } - is_first_msg = false; ret = wait_for_completion_timeout(&tspi->xfer_completion, SPI_DMA_TIMEOUT); @@ -868,40 +833,24 @@ static int tegra_spi_transfer_one_message(struct spi_master *master, dev_err(tspi->dev, "spi trasfer timeout, err %d\n", ret); ret = -EIO; - goto complete_xfer; + goto exit; } if (tspi->tx_status || tspi->rx_status) { dev_err(tspi->dev, "Error in Transfer\n"); ret = -EIO; - goto complete_xfer; + goto exit; } msg->actual_length += xfer->len; - -complete_xfer: - if (ret < 0 || skip) { + if (xfer->cs_change && xfer->delay_usecs) { tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); - tegra_spi_transfer_delay(xfer->delay_usecs); - goto exit; - } else if (msg->transfers.prev == &xfer->transfer_list) { - /* This is the last transfer in message */ - if (xfer->cs_change) - tspi->cs_control = spi; - else { - tegra_spi_writel(tspi, tspi->def_command1_reg, - SPI_COMMAND1); - tegra_spi_transfer_delay(xfer->delay_usecs); - } - } else if (xfer->cs_change) { - tegra_spi_writel(tspi, tspi->def_command1_reg, - SPI_COMMAND1); - tegra_spi_transfer_delay(xfer->delay_usecs); + udelay(xfer->delay_usecs); } - } ret = 0; exit: + tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); msg->status = ret; spi_finalize_current_message(master); return ret; @@ -1166,7 +1115,7 @@ static int tegra_spi_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); goto exit_pm_disable; @@ -1193,6 +1142,7 @@ static int tegra_spi_remove(struct platform_device *pdev) struct tegra_spi_data *tspi = spi_master_get_devdata(master); free_irq(tspi->irq, tspi); + spi_unregister_master(master); if (tspi->tx_dma_chan) tegra_spi_deinit_dma_param(tspi, false); diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 4dc8e81..1d814dc 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -173,7 +173,7 @@ static unsigned tegra_sflash_calculate_curr_xfer_param( unsigned remain_len = t->len - tsd->cur_pos; unsigned max_word; - tsd->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8); + tsd->bytes_per_word = (t->bits_per_word - 1) / 8 + 1; max_word = remain_len / tsd->bytes_per_word; if (max_word > SPI_FIFO_DEPTH) max_word = SPI_FIFO_DEPTH; @@ -339,7 +339,7 @@ static int tegra_sflash_transfer_one_message(struct spi_master *master, msg->actual_length = 0; single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { - reinit_completion(&tsd->xfer_completion); + INIT_COMPLETION(tsd->xfer_completion); ret = tegra_sflash_start_transfer_one(spi, xfer, is_first_msg, single_xfer); if (ret < 0) { @@ -529,7 +529,7 @@ static int tegra_sflash_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); goto exit_pm_disable; @@ -553,6 +553,7 @@ static int tegra_sflash_remove(struct platform_device *pdev) struct tegra_sflash_data *tsd = spi_master_get_devdata(master); free_irq(tsd->irq, tsd); + spi_unregister_master(master); pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index e66715b..c703536 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -278,12 +278,12 @@ static unsigned tegra_slink_calculate_curr_xfer_param( { unsigned remain_len = t->len - tspi->cur_pos; unsigned max_word; - unsigned bits_per_word; + unsigned bits_per_word ; unsigned max_len; unsigned total_fifo_words; bits_per_word = t->bits_per_word; - tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8); + tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1; if (bits_per_word == 8 || bits_per_word == 16) { tspi->is_packed = 1; @@ -462,7 +462,7 @@ static void tegra_slink_dma_complete(void *args) static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len) { - reinit_completion(&tspi->tx_dma_complete); + INIT_COMPLETION(tspi->tx_dma_complete); tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan, tspi->tx_dma_phys, len, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -481,7 +481,7 @@ static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len) static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len) { - reinit_completion(&tspi->rx_dma_complete); + INIT_COMPLETION(tspi->rx_dma_complete); tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan, tspi->rx_dma_phys, len, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -707,7 +707,8 @@ static void tegra_slink_deinit_dma_param(struct tegra_slink_data *tspi, } static int tegra_slink_start_transfer_one(struct spi_device *spi, - struct spi_transfer *t) + struct spi_transfer *t, bool is_first_of_msg, + bool is_single_xfer) { struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); u32 speed; @@ -731,12 +732,32 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, tspi->curr_xfer = t; total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t); - command = tspi->command_reg; - command &= ~SLINK_BIT_LENGTH(~0); - command |= SLINK_BIT_LENGTH(bits_per_word - 1); + if (is_first_of_msg) { + tegra_slink_clear_status(tspi); - command2 = tspi->command2_reg; - command2 &= ~(SLINK_RXEN | SLINK_TXEN); + command = tspi->def_command_reg; + command |= SLINK_BIT_LENGTH(bits_per_word - 1); + command |= SLINK_CS_SW | SLINK_CS_VALUE; + + command2 = tspi->def_command2_reg; + command2 |= SLINK_SS_EN_CS(spi->chip_select); + + command &= ~SLINK_MODES; + if (spi->mode & SPI_CPHA) + command |= SLINK_CK_SDA; + + if (spi->mode & SPI_CPOL) + command |= SLINK_IDLE_SCLK_DRIVE_HIGH; + else + command |= SLINK_IDLE_SCLK_DRIVE_LOW; + } else { + command = tspi->command_reg; + command &= ~SLINK_BIT_LENGTH(~0); + command |= SLINK_BIT_LENGTH(bits_per_word - 1); + + command2 = tspi->command2_reg; + command2 &= ~(SLINK_RXEN | SLINK_TXEN); + } tegra_slink_writel(tspi, command, SLINK_COMMAND); tspi->command_reg = command; @@ -803,72 +824,58 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } -static int tegra_slink_prepare_message(struct spi_master *master, - struct spi_message *msg) +static int tegra_slink_transfer_one_message(struct spi_master *master, + struct spi_message *msg) { + bool is_first_msg = true; + int single_xfer; struct tegra_slink_data *tspi = spi_master_get_devdata(master); + struct spi_transfer *xfer; struct spi_device *spi = msg->spi; - - tegra_slink_clear_status(tspi); - - tspi->command_reg = tspi->def_command_reg; - tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE; - - tspi->command2_reg = tspi->def_command2_reg; - tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select); - - tspi->command_reg &= ~SLINK_MODES; - if (spi->mode & SPI_CPHA) - tspi->command_reg |= SLINK_CK_SDA; - - if (spi->mode & SPI_CPOL) - tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_HIGH; - else - tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_LOW; - - return 0; -} - -static int tegra_slink_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *xfer) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); int ret; - reinit_completion(&tspi->xfer_completion); - ret = tegra_slink_start_transfer_one(spi, xfer); - if (ret < 0) { - dev_err(tspi->dev, - "spi can not start transfer, err %d\n", ret); - return ret; - } + msg->status = 0; + msg->actual_length = 0; - ret = wait_for_completion_timeout(&tspi->xfer_completion, - SLINK_DMA_TIMEOUT); - if (WARN_ON(ret == 0)) { - dev_err(tspi->dev, - "spi trasfer timeout, err %d\n", ret); - return -EIO; - } - - if (tspi->tx_status) - return tspi->tx_status; - if (tspi->rx_status) - return tspi->rx_status; - - return 0; -} - -static int tegra_slink_unprepare_message(struct spi_master *master, - struct spi_message *msg) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); + single_xfer = list_is_singular(&msg->transfers); + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + INIT_COMPLETION(tspi->xfer_completion); + ret = tegra_slink_start_transfer_one(spi, xfer, + is_first_msg, single_xfer); + if (ret < 0) { + dev_err(tspi->dev, + "spi can not start transfer, err %d\n", ret); + goto exit; + } + is_first_msg = false; + ret = wait_for_completion_timeout(&tspi->xfer_completion, + SLINK_DMA_TIMEOUT); + if (WARN_ON(ret == 0)) { + dev_err(tspi->dev, + "spi trasfer timeout, err %d\n", ret); + ret = -EIO; + goto exit; + } + if (tspi->tx_status || tspi->rx_status) { + dev_err(tspi->dev, "Error in Transfer\n"); + ret = -EIO; + goto exit; + } + msg->actual_length += xfer->len; + if (xfer->cs_change && xfer->delay_usecs) { + tegra_slink_writel(tspi, tspi->def_command_reg, + SLINK_COMMAND); + udelay(xfer->delay_usecs); + } + } + ret = 0; +exit: tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); - - return 0; + msg->status = ret; + spi_finalize_current_message(master); + return ret; } static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) @@ -1071,9 +1078,7 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; - master->prepare_message = tegra_slink_prepare_message; - master->transfer_one = tegra_slink_transfer_one; - master->unprepare_message = tegra_slink_unprepare_message; + master->transfer_one_message = tegra_slink_transfer_one_message; master->auto_runtime_pm = true; master->num_chipselect = MAX_CHIP_SELECT; master->bus_num = -1; @@ -1159,7 +1164,7 @@ static int tegra_slink_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); goto exit_pm_disable; @@ -1186,6 +1191,7 @@ static int tegra_slink_remove(struct platform_device *pdev) struct tegra_slink_data *tspi = spi_master_get_devdata(master); free_irq(tspi->irq, tspi); + spi_unregister_master(master); if (tspi->tx_dma_chan) tegra_slink_deinit_dma_param(tspi, false); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 4396bd4..e12d962 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -41,6 +41,9 @@ struct ti_qspi_regs { struct ti_qspi { struct completion transfer_complete; + /* IRQ synchronization */ + spinlock_t lock; + /* list synchronization */ struct mutex list_lock; @@ -54,6 +57,7 @@ struct ti_qspi { u32 spi_max_frequency; u32 cmd; u32 dc; + u32 stat; }; #define QSPI_PID (0x0) @@ -161,7 +165,7 @@ static int ti_qspi_setup(struct spi_device *spi) qspi->spi_max_frequency, clk_div); ret = pm_runtime_get_sync(qspi->dev); - if (ret < 0) { + if (ret) { dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); return ret; } @@ -393,12 +397,13 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id) { struct ti_qspi *qspi = dev_id; u16 int_stat; - u32 stat; irqreturn_t ret = IRQ_HANDLED; + spin_lock(&qspi->lock); + int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); - stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); + qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); if (!int_stat) { dev_dbg(qspi->dev, "No IRQ triggered\n"); @@ -406,14 +411,35 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id) goto out; } + ret = IRQ_WAKE_THREAD; + + ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_STATUS_ENABLED_CLEAR); - if (stat & WC) - complete(&qspi->transfer_complete); + out: + spin_unlock(&qspi->lock); + return ret; } +static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id) +{ + struct ti_qspi *qspi = dev_id; + unsigned long flags; + + spin_lock_irqsave(&qspi->lock, flags); + + if (qspi->stat & WC) + complete(&qspi->transfer_complete); + + spin_unlock_irqrestore(&qspi->lock, flags); + + ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); + + return IRQ_HANDLED; +} + static int ti_qspi_runtime_resume(struct device *dev) { struct ti_qspi *qspi; @@ -446,7 +472,7 @@ static int ti_qspi_probe(struct platform_device *pdev) if (!master) return -ENOMEM; - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD; + master->mode_bits = SPI_CPOL | SPI_CPHA; master->bus_num = -1; master->flags = SPI_MASTER_HALF_DUPLEX; @@ -459,10 +485,11 @@ static int ti_qspi_probe(struct platform_device *pdev) if (!of_property_read_u32(np, "num-cs", &num_cs)) master->num_chipselect = num_cs; + platform_set_drvdata(pdev, master); + qspi = spi_master_get_devdata(master); qspi->master = master; qspi->dev = &pdev->dev; - platform_set_drvdata(pdev, qspi); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -472,6 +499,7 @@ static int ti_qspi_probe(struct platform_device *pdev) return irq; } + spin_lock_init(&qspi->lock); mutex_init(&qspi->list_lock); qspi->base = devm_ioremap_resource(&pdev->dev, r); @@ -480,7 +508,8 @@ static int ti_qspi_probe(struct platform_device *pdev) goto free_master; } - ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, + ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr, + ti_qspi_threaded_isr, 0, dev_name(&pdev->dev), qspi); if (ret < 0) { dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", @@ -503,7 +532,7 @@ static int ti_qspi_probe(struct platform_device *pdev) if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) qspi->spi_max_frequency = max_freq; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret) goto free_master; @@ -516,25 +545,9 @@ free_master: static int ti_qspi_remove(struct platform_device *pdev) { - struct spi_master *master; - struct ti_qspi *qspi; - int ret; - - master = platform_get_drvdata(pdev); - qspi = spi_master_get_devdata(master); - - ret = pm_runtime_get_sync(qspi->dev); - if (ret < 0) { - dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); - return ret; - } - - ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); - - pm_runtime_put(qspi->dev); - pm_runtime_disable(&pdev->dev); + struct ti_qspi *qspi = platform_get_drvdata(pdev); - spi_unregister_master(master); + spi_unregister_master(qspi->master); return 0; } @@ -545,7 +558,7 @@ static const struct dev_pm_ops ti_qspi_pm_ops = { static struct platform_driver ti_qspi_driver = { .probe = ti_qspi_probe, - .remove = ti_qspi_remove, + .remove = ti_qspi_remove, .driver = { .name = "ti,dra7xxx-qspi", .owner = THIS_MODULE, diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 4461313..eaeeed5 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -506,8 +506,8 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg) goto err_out; } - dev_dbg(&pspi->dev, - "%s Transfer List not empty. Transfer Speed is set.\n", __func__); + dev_dbg(&pspi->dev, "%s Transfer List not empty. " + "Transfer Speed is set.\n", __func__); spin_lock_irqsave(&data->lock, flags); /* validate Tx/Rx buffers and Transfer length */ @@ -526,9 +526,8 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg) goto err_return_spinlock; } - dev_dbg(&pspi->dev, - "%s Tx/Rx buffer valid. Transfer length valid\n", - __func__); + dev_dbg(&pspi->dev, "%s Tx/Rx buffer valid. Transfer length" + " valid\n", __func__); /* if baud rate has been specified validate the same */ if (transfer->speed_hz > PCH_MAX_BAUDRATE) @@ -1182,8 +1181,8 @@ static void pch_spi_process_messages(struct work_struct *pwork) spin_lock(&data->lock); /* check if suspend has been initiated;if yes flush queue */ if (data->board_dat->suspend_sts || (data->status == STATUS_EXITING)) { - dev_dbg(&data->master->dev, - "%s suspend/remove initiated, flushing queue\n", __func__); + dev_dbg(&data->master->dev, "%s suspend/remove initiated," + "flushing queue\n", __func__); list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) { pmsg->status = -EIO; @@ -1411,13 +1410,13 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev) /* baseaddress + address offset) */ data->io_base_addr = pci_resource_start(board_dat->pdev, 1) + PCH_ADDRESS_SIZE * plat_dev->id; - data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0); + data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0) + + PCH_ADDRESS_SIZE * plat_dev->id; if (!data->io_remap_addr) { dev_err(&plat_dev->dev, "%s pci_iomap failed\n", __func__); ret = -ENOMEM; goto err_pci_iomap; } - data->io_remap_addr += PCH_ADDRESS_SIZE * plat_dev->id; dev_dbg(&plat_dev->dev, "[ch%d] remap_addr=%p\n", plat_dev->id, data->io_remap_addr); diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 18c9bb2..7c6d157 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -177,7 +177,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m) | 0x08, TXx9_SPCR0); - list_for_each_entry(t, &m->transfers, transfer_list) { + list_for_each_entry (t, &m->transfers, transfer_list) { const void *txbuf = t->tx_buf; void *rxbuf = t->rx_buf; u32 data; @@ -308,7 +308,7 @@ static int txx9spi_transfer(struct spi_device *spi, struct spi_message *m) m->actual_length = 0; /* check each transfer's parameters */ - list_for_each_entry(t, &m->transfers, transfer_list) { + list_for_each_entry (t, &m->transfers, transfer_list) { u32 speed_hz = t->speed_hz ? : spi->max_speed_hz; u8 bits_per_word = t->bits_per_word; @@ -406,7 +406,7 @@ static int txx9spi_probe(struct platform_device *dev) master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */ master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); - ret = devm_spi_register_master(&dev->dev, master); + ret = spi_register_master(master); if (ret) goto exit; return 0; @@ -425,12 +425,14 @@ exit: static int txx9spi_remove(struct platform_device *dev) { - struct spi_master *master = platform_get_drvdata(dev); + struct spi_master *master = spi_master_get(platform_get_drvdata(dev)); struct txx9spi *c = spi_master_get_devdata(master); + spi_unregister_master(master); destroy_workqueue(c->workqueue); clk_disable(c->clk); clk_put(c->clk); + spi_master_put(master); return 0; } @@ -438,7 +440,6 @@ static int txx9spi_remove(struct platform_device *dev) MODULE_ALIAS("platform:spi_txx9"); static struct platform_driver txx9spi_driver = { - .probe = txx9spi_probe, .remove = txx9spi_remove, .driver = { .name = "spi_txx9", @@ -448,7 +449,7 @@ static struct platform_driver txx9spi_driver = { static int __init txx9spi_init(void) { - return platform_driver_register(&txx9spi_driver); + return platform_driver_probe(&txx9spi_driver, txx9spi_probe); } subsys_initcall(txx9spi_init); diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 6d4ce46..0bf1b2c 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -258,7 +258,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) xspi->tx_ptr = t->tx_buf; xspi->rx_ptr = t->rx_buf; xspi->remaining_bytes = t->len; - reinit_completion(&xspi->done); + INIT_COMPLETION(xspi->done); /* Enable the transmit empty interrupt, which we use to determine @@ -372,7 +372,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) master->mode_bits = SPI_CPOL | SPI_CPHA; xspi = spi_master_get_devdata(master); - xspi->bitbang.master = master; + xspi->bitbang.master = spi_master_get(master); xspi->bitbang.chipselect = xilinx_spi_chipselect; xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 349ebba..9e039c6 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -39,9 +39,6 @@ #include <linux/ioport.h> #include <linux/acpi.h> -#define CREATE_TRACE_POINTS -#include <trace/events/spi.h> - static void spidev_release(struct device *dev) { struct spi_device *spi = to_spi_device(dev); @@ -61,13 +58,11 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); } -static DEVICE_ATTR_RO(modalias); -static struct attribute *spi_dev_attrs[] = { - &dev_attr_modalias.attr, - NULL, +static struct device_attribute spi_dev_attrs[] = { + __ATTR_RO(modalias), + __ATTR_NULL, }; -ATTRIBUTE_GROUPS(spi_dev); /* modalias support makes "modprobe $MODALIAS" new-style hotplug work, * and the sysfs version makes coldplug work too. @@ -234,7 +229,7 @@ static const struct dev_pm_ops spi_pm = { struct bus_type spi_bus_type = { .name = "spi", - .dev_groups = spi_dev_groups, + .dev_attrs = spi_dev_attrs, .match = spi_match_device, .uevent = spi_uevent, .pm = &spi_pm, @@ -245,27 +240,15 @@ EXPORT_SYMBOL_GPL(spi_bus_type); static int spi_drv_probe(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); - struct spi_device *spi = to_spi_device(dev); - int ret; - - acpi_dev_pm_attach(&spi->dev, true); - ret = sdrv->probe(spi); - if (ret) - acpi_dev_pm_detach(&spi->dev, true); - return ret; + return sdrv->probe(to_spi_device(dev)); } static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); - struct spi_device *spi = to_spi_device(dev); - int ret; - - ret = sdrv->remove(spi); - acpi_dev_pm_detach(&spi->dev, true); - return ret; + return sdrv->remove(to_spi_device(dev)); } static void spi_drv_shutdown(struct device *dev) @@ -340,7 +323,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master) if (!spi_master_get(master)) return NULL; - spi = kzalloc(sizeof(*spi), GFP_KERNEL); + spi = kzalloc(sizeof *spi, GFP_KERNEL); if (!spi) { dev_err(dev, "cannot alloc spi_device\n"); spi_master_put(master); @@ -357,19 +340,6 @@ struct spi_device *spi_alloc_device(struct spi_master *master) } EXPORT_SYMBOL_GPL(spi_alloc_device); -static void spi_dev_set_name(struct spi_device *spi) -{ - struct acpi_device *adev = ACPI_COMPANION(&spi->dev); - - if (adev) { - dev_set_name(&spi->dev, "spi-%s", acpi_dev_name(adev)); - return; - } - - dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev), - spi->chip_select); -} - /** * spi_add_device - Add spi_device allocated with spi_alloc_device * @spi: spi_device to register @@ -396,7 +366,9 @@ int spi_add_device(struct spi_device *spi) } /* Set the bus ID string */ - spi_dev_set_name(spi); + dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev), + spi->chip_select); + /* We need to make sure there's no other device with this * chipselect **BEFORE** we call setup(), else we'll trash @@ -551,95 +523,6 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) /*-------------------------------------------------------------------------*/ -static void spi_set_cs(struct spi_device *spi, bool enable) -{ - if (spi->mode & SPI_CS_HIGH) - enable = !enable; - - if (spi->cs_gpio >= 0) - gpio_set_value(spi->cs_gpio, !enable); - else if (spi->master->set_cs) - spi->master->set_cs(spi, !enable); -} - -/* - * spi_transfer_one_message - Default implementation of transfer_one_message() - * - * This is a standard implementation of transfer_one_message() for - * drivers which impelment a transfer_one() operation. It provides - * standard handling of delays and chip select management. - */ -static int spi_transfer_one_message(struct spi_master *master, - struct spi_message *msg) -{ - struct spi_transfer *xfer; - bool cur_cs = true; - bool keep_cs = false; - int ret = 0; - - spi_set_cs(msg->spi, true); - - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - trace_spi_transfer_start(msg, xfer); - - reinit_completion(&master->xfer_completion); - - ret = master->transfer_one(master, msg->spi, xfer); - if (ret < 0) { - dev_err(&msg->spi->dev, - "SPI transfer failed: %d\n", ret); - goto out; - } - - if (ret > 0) - wait_for_completion(&master->xfer_completion); - - trace_spi_transfer_stop(msg, xfer); - - if (msg->status != -EINPROGRESS) - goto out; - - if (xfer->delay_usecs) - udelay(xfer->delay_usecs); - - if (xfer->cs_change) { - if (list_is_last(&xfer->transfer_list, - &msg->transfers)) { - keep_cs = true; - } else { - cur_cs = !cur_cs; - spi_set_cs(msg->spi, cur_cs); - } - } - - msg->actual_length += xfer->len; - } - -out: - if (ret != 0 || !keep_cs) - spi_set_cs(msg->spi, false); - - if (msg->status == -EINPROGRESS) - msg->status = ret; - - spi_finalize_current_message(master); - - return ret; -} - -/** - * spi_finalize_current_transfer - report completion of a transfer - * - * Called by SPI drivers using the core transfer_one_message() - * implementation to notify it that the current interrupt driven - * transfer has finised and the next one may be scheduled. - */ -void spi_finalize_current_transfer(struct spi_master *master) -{ - complete(&master->xfer_completion); -} -EXPORT_SYMBOL_GPL(spi_finalize_current_transfer); - /** * spi_pump_messages - kthread work function which processes spi message queue * @work: pointer to kthread work struct contained in the master struct @@ -674,7 +557,6 @@ static void spi_pump_messages(struct kthread_work *work) pm_runtime_mark_last_busy(master->dev.parent); pm_runtime_put_autosuspend(master->dev.parent); } - trace_spi_master_idle(master); return; } @@ -703,9 +585,6 @@ static void spi_pump_messages(struct kthread_work *work) } } - if (!was_busy) - trace_spi_master_busy(master); - if (!was_busy && master->prepare_transfer_hardware) { ret = master->prepare_transfer_hardware(master); if (ret) { @@ -718,20 +597,6 @@ static void spi_pump_messages(struct kthread_work *work) } } - trace_spi_message_start(master->cur_msg); - - if (master->prepare_message) { - ret = master->prepare_message(master, master->cur_msg); - if (ret) { - dev_err(&master->dev, - "failed to prepare message: %d\n", ret); - master->cur_msg->status = ret; - spi_finalize_current_message(master); - return; - } - master->cur_msg_prepared = true; - } - ret = master->transfer_one_message(master, master->cur_msg); if (ret) { dev_err(&master->dev, @@ -813,7 +678,6 @@ void spi_finalize_current_message(struct spi_master *master) { struct spi_message *mesg; unsigned long flags; - int ret; spin_lock_irqsave(&master->queue_lock, flags); mesg = master->cur_msg; @@ -822,20 +686,9 @@ void spi_finalize_current_message(struct spi_master *master) queue_kthread_work(&master->kworker, &master->pump_messages); spin_unlock_irqrestore(&master->queue_lock, flags); - if (master->cur_msg_prepared && master->unprepare_message) { - ret = master->unprepare_message(master, mesg); - if (ret) { - dev_err(&master->dev, - "failed to unprepare message: %d\n", ret); - } - } - master->cur_msg_prepared = false; - mesg->state = NULL; if (mesg->complete) mesg->complete(mesg->context); - - trace_spi_message_done(mesg); } EXPORT_SYMBOL_GPL(spi_finalize_current_message); @@ -950,8 +803,6 @@ static int spi_master_initialize_queue(struct spi_master *master) master->queued = true; master->transfer = spi_queued_transfer; - if (!master->transfer_one_message) - master->transfer_one_message = spi_transfer_one_message; /* Initialize and start queue */ ret = spi_init_queue(master); @@ -987,8 +838,10 @@ static void of_register_spi_devices(struct spi_master *master) { struct spi_device *spi; struct device_node *nc; + const __be32 *prop; + char modalias[SPI_NAME_SIZE + 4]; int rc; - u32 value; + int len; if (!master->dev.of_node) return; @@ -1013,14 +866,14 @@ static void of_register_spi_devices(struct spi_master *master) } /* Device address */ - rc = of_property_read_u32(nc, "reg", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", - nc->full_name, rc); + prop = of_get_property(nc, "reg", &len); + if (!prop || len < sizeof(*prop)) { + dev_err(&master->dev, "%s has no 'reg' property\n", + nc->full_name); spi_dev_put(spi); continue; } - spi->chip_select = value; + spi->chip_select = be32_to_cpup(prop); /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) @@ -1033,53 +886,55 @@ static void of_register_spi_devices(struct spi_master *master) spi->mode |= SPI_3WIRE; /* Device DUAL/QUAD mode */ - if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { - switch (value) { - case 1: + prop = of_get_property(nc, "spi-tx-bus-width", &len); + if (prop && len == sizeof(*prop)) { + switch (be32_to_cpup(prop)) { + case SPI_NBITS_SINGLE: break; - case 2: + case SPI_NBITS_DUAL: spi->mode |= SPI_TX_DUAL; break; - case 4: + case SPI_NBITS_QUAD: spi->mode |= SPI_TX_QUAD; break; default: dev_err(&master->dev, "spi-tx-bus-width %d not supported\n", - value); + be32_to_cpup(prop)); spi_dev_put(spi); continue; } } - if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { - switch (value) { - case 1: + prop = of_get_property(nc, "spi-rx-bus-width", &len); + if (prop && len == sizeof(*prop)) { + switch (be32_to_cpup(prop)) { + case SPI_NBITS_SINGLE: break; - case 2: + case SPI_NBITS_DUAL: spi->mode |= SPI_RX_DUAL; break; - case 4: + case SPI_NBITS_QUAD: spi->mode |= SPI_RX_QUAD; break; default: dev_err(&master->dev, "spi-rx-bus-width %d not supported\n", - value); + be32_to_cpup(prop)); spi_dev_put(spi); continue; } } /* Device speed */ - rc = of_property_read_u32(nc, "spi-max-frequency", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", - nc->full_name, rc); + prop = of_get_property(nc, "spi-max-frequency", &len); + if (!prop || len < sizeof(*prop)) { + dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n", + nc->full_name); spi_dev_put(spi); continue; } - spi->max_speed_hz = value; + spi->max_speed_hz = be32_to_cpup(prop); /* IRQ */ spi->irq = irq_of_parse_and_map(nc, 0); @@ -1089,7 +944,9 @@ static void of_register_spi_devices(struct spi_master *master) spi->dev.of_node = nc; /* Register the new device */ - request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias); + snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX, + spi->modalias); + request_module(modalias); rc = spi_add_device(spi); if (rc) { dev_err(&master->dev, "spi_device register error %s\n", @@ -1155,7 +1012,7 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, return AE_NO_MEMORY; } - ACPI_COMPANION_SET(&spi->dev, adev); + ACPI_HANDLE_SET(&spi->dev, handle); spi->irq = -1; INIT_LIST_HEAD(&resource_list); @@ -1168,10 +1025,8 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, return AE_OK; } - adev->power.flags.ignore_parent = true; - strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias)); + strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias)); if (spi_add_device(spi)) { - adev->power.flags.ignore_parent = false; dev_err(&master->dev, "failed to add SPI device %s from ACPI\n", dev_name(&adev->dev)); spi_dev_put(spi); @@ -1242,7 +1097,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) if (!dev) return NULL; - master = kzalloc(size + sizeof(*master), GFP_KERNEL); + master = kzalloc(size + sizeof *master, GFP_KERNEL); if (!master) return NULL; @@ -1267,7 +1122,7 @@ static int of_spi_register_master(struct spi_master *master) return 0; nb = of_gpio_named_count(np, "cs-gpios"); - master->num_chipselect = max_t(int, nb, master->num_chipselect); + master->num_chipselect = max(nb, (int)master->num_chipselect); /* Return error only for an incorrectly formed cs-gpios property */ if (nb == 0 || nb == -ENOENT) @@ -1354,7 +1209,6 @@ int spi_register_master(struct spi_master *master) spin_lock_init(&master->bus_lock_spinlock); mutex_init(&master->bus_lock_mutex); master->bus_lock_flag = 0; - init_completion(&master->xfer_completion); /* register the device, then userspace will see it. * registration fails if the bus ID is in use. @@ -1391,41 +1245,6 @@ done: } EXPORT_SYMBOL_GPL(spi_register_master); -static void devm_spi_unregister(struct device *dev, void *res) -{ - spi_unregister_master(*(struct spi_master **)res); -} - -/** - * dev_spi_register_master - register managed SPI master controller - * @dev: device managing SPI master - * @master: initialized master, originally from spi_alloc_master() - * Context: can sleep - * - * Register a SPI device as with spi_register_master() which will - * automatically be unregister - */ -int devm_spi_register_master(struct device *dev, struct spi_master *master) -{ - struct spi_master **ptr; - int ret; - - ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return -ENOMEM; - - ret = spi_register_master(master); - if (!ret) { - *ptr = master; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return ret; -} -EXPORT_SYMBOL_GPL(devm_spi_register_master); - static int __unregister(struct device *dev, void *null) { spi_unregister_device(to_spi_device(dev)); @@ -1583,7 +1402,8 @@ int spi_setup(struct spi_device *spi) if (spi->master->setup) status = spi->master->setup(spi); - dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n", + dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s" + "%u bits/w, %u Hz max --> %d\n", (int) (spi->mode & (SPI_CPOL | SPI_CPHA)), (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "", (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "", @@ -1601,10 +1421,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) struct spi_master *master = spi->master; struct spi_transfer *xfer; - message->spi = spi; - - trace_spi_message_submit(message); - if (list_empty(&message->transfers)) return -EINVAL; if (!message->complete) @@ -1704,6 +1520,7 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) } } + message->spi = spi; message->status = -EINPROGRESS; return master->transfer(spi, message); } @@ -1945,7 +1762,7 @@ int spi_bus_unlock(struct spi_master *master) EXPORT_SYMBOL_GPL(spi_bus_unlock); /* portable code must never pass more than 32 bytes */ -#define SPI_BUFSIZ max(32, SMP_CACHE_BYTES) +#define SPI_BUFSIZ max(32,SMP_CACHE_BYTES) static u8 *buf; @@ -1994,7 +1811,7 @@ int spi_write_then_read(struct spi_device *spi, } spi_message_init(&message); - memset(x, 0, sizeof(x)); + memset(x, 0, sizeof x); if (n_tx) { x[0].len = n_tx; spi_message_add_tail(&x[0], &message); diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index d7c6e36..ca5bcfe 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -37,7 +37,7 @@ #include <linux/spi/spi.h> #include <linux/spi/spidev.h> -#include <linux/uaccess.h> +#include <asm/uaccess.h> /* @@ -206,9 +206,9 @@ spidev_write(struct file *filp, const char __user *buf, mutex_lock(&spidev->buf_lock); missing = copy_from_user(spidev->buffer, buf, count); - if (missing == 0) + if (missing == 0) { status = spidev_sync_write(spidev, count); - else + } else status = -EFAULT; mutex_unlock(&spidev->buf_lock); @@ -629,6 +629,7 @@ static int spidev_remove(struct spi_device *spi) /* make sure ops on existing fds can abort cleanly */ spin_lock_irq(&spidev->spi_lock); spidev->spi = NULL; + spi_set_drvdata(spi, NULL); spin_unlock_irq(&spidev->spi_lock); /* prevent new opens */ |