]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'spi/for-next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:37:27 +0000 (14:37 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:37:27 +0000 (14:37 +0200)
Conflicts:
drivers/spi/spi.c

61 files changed:
Documentation/driver-model/devres.txt
drivers/hwmon/adt7310.c
drivers/spi/Kconfig
drivers/spi/spi-altera.c
drivers/spi/spi-ath79.c
drivers/spi/spi-atmel.c
drivers/spi/spi-au1550.c
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-bfin-sport.c
drivers/spi/spi-bfin-v3.c
drivers/spi/spi-bfin5xx.c
drivers/spi/spi-bitbang.c
drivers/spi/spi-butterfly.c
drivers/spi/spi-clps711x.c
drivers/spi/spi-davinci.c
drivers/spi/spi-dw-mmio.c
drivers/spi/spi-dw-pci.c
drivers/spi/spi-dw.c
drivers/spi/spi-efm32.c
drivers/spi/spi-ep93xx.c
drivers/spi/spi-fsl-cpm.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-fsl-espi.c
drivers/spi/spi-gpio.c
drivers/spi/spi-imx.c
drivers/spi/spi-lm70llp.c
drivers/spi/spi-mpc512x-psc.c
drivers/spi/spi-mpc52xx-psc.c
drivers/spi/spi-mxs.c
drivers/spi/spi-nuc900.c
drivers/spi/spi-oc-tiny.c
drivers/spi/spi-octeon.c
drivers/spi/spi-omap-100k.c
drivers/spi/spi-omap-uwire.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-orion.c
drivers/spi/spi-pl022.c
drivers/spi/spi-ppc4xx.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-rspi.c
drivers/spi/spi-s3c24xx.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sh-hspi.c
drivers/spi/spi-sh-sci.c
drivers/spi/spi-sirf.c
drivers/spi/spi-tegra114.c
drivers/spi/spi-tegra20-sflash.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-txx9.c
drivers/spi/spi-xilinx.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/staging/iio/meter/ade7753.c
drivers/staging/iio/meter/ade7754.c
drivers/staging/iio/meter/ade7759.c
include/linux/spi/rspi.h
include/linux/spi/spi.h
include/trace/events/spi.h [new file with mode: 0644]

index 3d9c2a766230a5d7d24164675a4bee3b4e67dd67..5bdc8cb5fc2855047004cf673d735fa23c561fb8 100644 (file)
@@ -303,3 +303,6 @@ PHY
 
 SLAVE DMA ENGINE
   devm_acpi_dma_controller_register()
+
+SPI
+  devm_spi_register_master()
index da5f0789fb97b937b2ad7f23ec8c9474bf41fa80..5994cf68e0a4225813f165f6c3160277c191352b 100644 (file)
@@ -42,13 +42,8 @@ static const u8 adt7310_reg_table[] = {
 static int adt7310_spi_read_word(struct device *dev, u8 reg)
 {
        struct spi_device *spi = to_spi_device(dev);
-       int ret;
 
-       ret = spi_w8r16(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
-       if (ret < 0)
-               return ret;
-
-       return be16_to_cpu((__force __be16)ret);
+       return spi_w8r16be(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
 }
 
 static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data)
index b9c53cc40e1fa487dd3d73cd9c83d713a3334e6a..eb1f1ef5fa2eb69db729b6061b2d96c85aaf968b 100644 (file)
@@ -264,6 +264,7 @@ config SPI_FSL_SPI
 config SPI_FSL_DSPI
        tristate "Freescale DSPI controller"
        select SPI_BITBANG
+       depends on SOC_VF610 || COMPILE_TEST
        help
          This enables support for the Freescale DSPI controller in master
          mode. VF610 platform uses the controller.
@@ -369,7 +370,7 @@ config SPI_PXA2XX_PCI
 
 config SPI_RSPI
        tristate "Renesas RSPI controller"
-       depends on SUPERH && SH_DMAE_BASE
+       depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE
        help
          SPI driver for Renesas RSPI blocks.
 
@@ -393,7 +394,7 @@ config SPI_S3C24XX_FIQ
 
 config SPI_S3C64XX
        tristate "Samsung S3C64XX series type SPI"
-       depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS)
+       depends on PLAT_SAMSUNG
        select S3C64XX_DMA if ARCH_S3C64XX
        help
          SPI driver for Samsung S3C64XX and newer SoCs.
index 9a64c3fee218b152cb40365ea7f6bf1b4f7e39e7..595b62cb545d9f804a6fe64bc07c20a6a892892d 100644 (file)
@@ -219,7 +219,7 @@ static int altera_spi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, hw);
 
        /* setup the state for the bitbang driver */
-       hw->bitbang.master = spi_master_get(master);
+       hw->bitbang.master = master;
        if (!hw->bitbang.master)
                return err;
        hw->bitbang.chipselect = altera_spi_chipsel;
index 37bad952ab38a649ea86eedc52ac6e3df1b9a133..821bf7ac218d965411027e3ce7efe16ed8e3e567 100644 (file)
@@ -231,7 +231,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
                master->num_chipselect = pdata->num_chipselect;
        }
 
-       sp->bitbang.master = spi_master_get(master);
+       sp->bitbang.master = master;
        sp->bitbang.chipselect = ath79_spi_chipselect;
        sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
        sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
index d4ac60b4a56e8a6f4615fcac50015a06cccd53fc..273db0beb2b88ffeb588307ce08b2cb40120c790 100644 (file)
 /* Bit manipulation macros */
 #define SPI_BIT(name) \
        (1 << SPI_##name##_OFFSET)
-#define SPI_BF(name,value) \
+#define SPI_BF(name, value) \
        (((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET)
-#define SPI_BFEXT(name,value) \
+#define SPI_BFEXT(name, value) \
        (((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1))
-#define SPI_BFINS(name,value,old) \
-       ( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
-         | SPI_BF(name,value))
+#define SPI_BFINS(name, value, old) \
+       (((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
+         | SPI_BF(name, value))
 
 /* Register access macros */
-#define spi_readl(port,reg) \
+#define spi_readl(port, reg) \
        __raw_readl((port)->regs + SPI_##reg)
-#define spi_writel(port,reg,value) \
+#define spi_writel(port, reg, value) \
        __raw_writel((value), (port)->regs + SPI_##reg)
 
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
@@ -1401,8 +1401,8 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
                        asd = spi->controller_state;
                        bits = (asd->csr >> 4) & 0xf;
                        if (bits != xfer->bits_per_word - 8) {
-                               dev_dbg(&spi->dev, "you can't yet change "
-                                        "bits_per_word in transfers\n");
+                               dev_dbg(&spi->dev,
+                                       "you can't yet change bits_per_word in transfers\n");
                                return -ENOPROTOOPT;
                        }
                }
@@ -1516,7 +1516,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
 
        /* setup spi core then atmel-specific driver state */
        ret = -ENOMEM;
-       master = spi_alloc_master(&pdev->dev, sizeof *as);
+       master = spi_alloc_master(&pdev->dev, sizeof(*as));
        if (!master)
                goto out_free;
 
@@ -1546,9 +1546,11 @@ static int atmel_spi_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&as->queue);
 
        as->pdev = pdev;
-       as->regs = ioremap(regs->start, resource_size(regs));
-       if (!as->regs)
+       as->regs = devm_ioremap_resource(&pdev->dev, regs);
+       if (IS_ERR(as->regs)) {
+               ret = PTR_ERR(as->regs);
                goto out_free_buffer;
+       }
        as->phybase = regs->start;
        as->irq = irq;
        as->clk = clk;
@@ -1617,7 +1619,6 @@ 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);
@@ -1669,36 +1670,36 @@ static int atmel_spi_remove(struct platform_device *pdev)
        clk_disable_unprepare(as->clk);
        clk_put(as->clk);
        free_irq(as->irq, master);
-       iounmap(as->regs);
 
        spi_unregister_master(master);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-
-static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int atmel_spi_suspend(struct device *dev)
 {
-       struct spi_master       *master = platform_get_drvdata(pdev);
+       struct spi_master       *master = dev_get_drvdata(dev);
        struct atmel_spi        *as = spi_master_get_devdata(master);
 
        clk_disable_unprepare(as->clk);
        return 0;
 }
 
-static int atmel_spi_resume(struct platform_device *pdev)
+static int atmel_spi_resume(struct device *dev)
 {
-       struct spi_master       *master = platform_get_drvdata(pdev);
+       struct spi_master       *master = dev_get_drvdata(dev);
        struct atmel_spi        *as = spi_master_get_devdata(master);
 
-       return clk_prepare_enable(as->clk);
+       clk_prepare_enable(as->clk);
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume);
+
+#define ATMEL_SPI_PM_OPS       (&atmel_spi_pm_ops)
 #else
-#define        atmel_spi_suspend       NULL
-#define        atmel_spi_resume        NULL
+#define ATMEL_SPI_PM_OPS       NULL
 #endif
 
 #if defined(CONFIG_OF)
@@ -1714,10 +1715,9 @@ static struct platform_driver atmel_spi_driver = {
        .driver         = {
                .name   = "atmel_spi",
                .owner  = THIS_MODULE,
+               .pm     = ATMEL_SPI_PM_OPS,
                .of_match_table = of_match_ptr(atmel_spi_dt_ids),
        },
-       .suspend        = atmel_spi_suspend,
-       .resume         = atmel_spi_resume,
        .probe          = atmel_spi_probe,
        .remove         = atmel_spi_remove,
 };
index 1d00d9b397dde39dc585c2c99d7be47cbb50607e..c4141c92bcff5734c4f228e94c5ce38a665c0d94 100644 (file)
@@ -775,7 +775,7 @@ static int au1550_spi_probe(struct platform_device *pdev)
 
        hw = spi_master_get_devdata(master);
 
-       hw->master = spi_master_get(master);
+       hw->master = master;
        hw->pdata = dev_get_platdata(&pdev->dev);
        hw->dev = &pdev->dev;
 
@@ -985,6 +985,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
 MODULE_ALIAS("platform:au1550-spi");
 
 static struct platform_driver au1550_spi_drv = {
+       .probe = au1550_spi_probe,
        .remove = au1550_spi_remove,
        .driver = {
                .name = "au1550-spi",
@@ -1004,7 +1005,7 @@ static int __init au1550_spi_init(void)
                        printk(KERN_ERR "au1550-spi: cannot add memory"
                                        "dbdma device\n");
        }
-       return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
+       return platform_driver_register(&au1550_spi_drv);
 }
 module_init(au1550_spi_init);
 
index 52c81481c5c77408e90e22bbf2580e8041cf4a2c..4c332143a3100c52d916fc9887ffd11d96356892 100644 (file)
@@ -358,7 +358,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
        bcm2835_wr(bs, BCM2835_SPI_CS,
                   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 
-       err = spi_register_master(master);
+       err = devm_spi_register_master(&pdev->dev, master);
        if (err) {
                dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
                goto out_free_irq;
@@ -381,14 +381,12 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
 
        free_irq(bs->irq, master);
-       spi_unregister_master(master);
 
        /* Clear FIFOs, and disable the HW block */
        bcm2835_wr(bs, BCM2835_SPI_CS,
                   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 
        clk_disable_unprepare(bs->clk);
-       spi_master_put(master);
 
        return 0;
 }
index 536b0e363826164f3421765f21e32913c071ec8f..80d56b214eb51af96ceb9e9d55ffea6bbb2d7302 100644 (file)
@@ -412,7 +412,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 
        /* register and we are done */
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(dev, master);
        if (ret) {
                dev_err(dev, "spi register failed\n");
                goto out_clk_disable;
@@ -438,8 +438,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
        struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 
-       spi_unregister_master(master);
-
        /* reset spi block */
        bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 
@@ -447,8 +445,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
        clk_disable_unprepare(bs->clk);
        clk_put(bs->clk);
 
-       spi_master_put(master);
-
        return 0;
 }
 
index 91921b5f58171fcd8de5faf0d33099f8fc490f2f..38941e5920b50fe2bb9455cc9392fe6803db6355 100644 (file)
@@ -592,7 +592,7 @@ bfin_sport_spi_setup(struct spi_device *spi)
                         */
                        if (chip_info->ctl_reg || chip_info->enable_dma) {
                                ret = -EINVAL;
-                               dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields");
+                               dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields\n");
                                goto error;
                        }
                        chip->cs_chg_udelay = chip_info->cs_chg_udelay;
@@ -879,11 +879,10 @@ static int bfin_sport_spi_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int
-bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int bfin_sport_spi_suspend(struct device *dev)
 {
-       struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+       struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
        int status;
 
        status = bfin_sport_spi_stop_queue(drv_data);
@@ -896,10 +895,9 @@ bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
        return status;
 }
 
-static int
-bfin_sport_spi_resume(struct platform_device *pdev)
+static int bfin_sport_spi_resume(struct device *dev)
 {
-       struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+       struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
        int status;
 
        /* Enable the SPI interface */
@@ -912,19 +910,22 @@ bfin_sport_spi_resume(struct platform_device *pdev)
 
        return status;
 }
+
+static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend,
+                       bfin_sport_spi_resume);
+
+#define BFIN_SPORT_SPI_PM_OPS          (&bfin_sport_spi_pm_ops)
 #else
-# define bfin_sport_spi_suspend NULL
-# define bfin_sport_spi_resume  NULL
+#define BFIN_SPORT_SPI_PM_OPS          NULL
 #endif
 
 static struct platform_driver bfin_sport_spi_driver = {
        .driver = {
-               .name = DRV_NAME,
-               .owner = THIS_MODULE,
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+               .pm     = BFIN_SPORT_SPI_PM_OPS,
        },
        .probe   = bfin_sport_spi_probe,
        .remove  = bfin_sport_spi_remove,
-       .suspend = bfin_sport_spi_suspend,
-       .resume  = bfin_sport_spi_resume,
 };
 module_platform_driver(bfin_sport_spi_driver);
index f4bf81347d68fd60d6f0a4d01f8702d412a70d20..8f8598834b30d0831ed08e6711a3528994f6df58 100644 (file)
@@ -867,7 +867,7 @@ static int bfin_spi_probe(struct platform_device *pdev)
        tasklet_init(&drv_data->pump_transfers,
                        bfin_spi_pump_transfers, (unsigned long)drv_data);
        /* register with the SPI framework */
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(dev, master);
        if (ret) {
                dev_err(dev, "can not  register spi master\n");
                goto err_free_peripheral;
@@ -898,7 +898,6 @@ static int bfin_spi_remove(struct platform_device *pdev)
        free_dma(drv_data->rx_dma);
        free_dma(drv_data->tx_dma);
 
-       spi_unregister_master(drv_data->master);
        return 0;
 }
 
index 45bdf73d6868e62d0efd5c16296d359400d05b17..f0f195af75d4d67815e6d550d54c5cf990d6813f 100644 (file)
@@ -524,7 +524,7 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)
        timeout = jiffies + HZ;
        while (!(bfin_read(&drv_data->regs->stat) & BIT_STAT_SPIF))
                if (!time_before(jiffies, timeout)) {
-                       dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF");
+                       dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF\n");
                        break;
                } else
                        cpu_relax();
@@ -913,8 +913,9 @@ static void bfin_spi_pump_messages(struct work_struct *work)
        drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
                                            struct spi_transfer, transfer_list);
 
-       dev_dbg(&drv_data->pdev->dev, "got a message to pump, "
-               "state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
+       dev_dbg(&drv_data->pdev->dev,
+               "got a message to pump, state is set to: baud "
+               "%d, flag 0x%x, ctl 0x%x\n",
                drv_data->cur_chip->baud, drv_data->cur_chip->flag,
                drv_data->cur_chip->ctl_reg);
 
@@ -1013,8 +1014,8 @@ static int bfin_spi_setup(struct spi_device *spi)
                 * but let's assume (for now) they do.
                 */
                if (chip_info->ctl_reg & ~bfin_ctl_reg) {
-                       dev_err(&spi->dev, "do not set bits in ctl_reg "
-                               "that the SPI framework manages\n");
+                       dev_err(&spi->dev,
+                               "do not set bits in ctl_reg that the SPI framework manages\n");
                        goto error;
                }
                chip->enable_dma = chip_info->enable_dma != 0
@@ -1050,17 +1051,17 @@ static int bfin_spi_setup(struct spi_device *spi)
        chip->chip_select_num = spi->chip_select;
        if (chip->chip_select_num < MAX_CTRL_CS) {
                if (!(spi->mode & SPI_CPHA))
-                       dev_warn(&spi->dev, "Warning: SPI CPHA not set:"
-                               " Slave Select not under software control!\n"
-                               " See Documentation/blackfin/bfin-spi-notes.txt");
+                       dev_warn(&spi->dev,
+                               "Warning: SPI CPHA not set: Slave Select not under software control!\n"
+                               "See Documentation/blackfin/bfin-spi-notes.txt\n");
 
                chip->flag = (1 << spi->chip_select) << 8;
        } else
                chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS;
 
        if (chip->enable_dma && chip->pio_interrupt) {
-               dev_err(&spi->dev, "enable_dma is set, "
-                               "do not set pio_interrupt\n");
+               dev_err(&spi->dev,
+                       "enable_dma is set, do not set pio_interrupt\n");
                goto error;
        }
        /*
@@ -1410,10 +1411,10 @@ static int bfin_spi_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int bfin_spi_suspend(struct device *dev)
 {
-       struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev);
+       struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);
        int status = 0;
 
        status = bfin_spi_stop_queue(drv_data);
@@ -1432,9 +1433,9 @@ static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)
        return 0;
 }
 
-static int bfin_spi_resume(struct platform_device *pdev)
+static int bfin_spi_resume(struct device *dev)
 {
-       struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev);
+       struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);
        int status = 0;
 
        bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg);
@@ -1443,31 +1444,34 @@ static int bfin_spi_resume(struct platform_device *pdev)
        /* Start the queue running */
        status = bfin_spi_start_queue(drv_data);
        if (status != 0) {
-               dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
+               dev_err(dev, "problem starting queue (%d)\n", status);
                return status;
        }
 
        return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(bfin_spi_pm_ops, bfin_spi_suspend, bfin_spi_resume);
+
+#define BFIN_SPI_PM_OPS                (&bfin_spi_pm_ops)
 #else
-#define bfin_spi_suspend NULL
-#define bfin_spi_resume NULL
-#endif                         /* CONFIG_PM */
+#define BFIN_SPI_PM_OPS                NULL
+#endif
 
 MODULE_ALIAS("platform:bfin-spi");
 static struct platform_driver bfin_spi_driver = {
        .driver = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
+               .pm     = BFIN_SPI_PM_OPS,
        },
-       .suspend        = bfin_spi_suspend,
-       .resume         = bfin_spi_resume,
+       .probe          = bfin_spi_probe,
        .remove         = bfin_spi_remove,
 };
 
 static int __init bfin_spi_init(void)
 {
-       return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe);
+       return platform_driver_register(&bfin_spi_driver);
 }
 subsys_initcall(bfin_spi_init);
 
index 8c11355dec233595a04a33877f832084af933168..bd222f6b677d0c775dbd608a66356554adefa660 100644 (file)
@@ -191,7 +191,7 @@ int spi_bitbang_setup(struct spi_device *spi)
        bitbang = spi_master_get_devdata(spi->master);
 
        if (!cs) {
-               cs = kzalloc(sizeof *cs, GFP_KERNEL);
+               cs = kzalloc(sizeof(*cs), GFP_KERNEL);
                if (!cs)
                        return -ENOMEM;
                spi->controller_state = cs;
@@ -258,7 +258,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
 
 static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 {
-       struct spi_bitbang      *bitbang;
+       struct spi_bitbang      *bitbang;
        unsigned long           flags;
 
        bitbang = spi_master_get_devdata(spi);
@@ -273,7 +273,7 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 static int spi_bitbang_transfer_one(struct spi_master *master,
                                    struct spi_message *m)
 {
-       struct spi_bitbang      *bitbang;
+       struct spi_bitbang      *bitbang;
        unsigned                nsecs;
        struct spi_transfer     *t = NULL;
        unsigned                cs_change;
@@ -292,7 +292,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
        cs_change = 1;
        status = 0;
 
-       list_for_each_entry (t, &m->transfers, transfer_list) {
+       list_for_each_entry(t, &m->transfers, transfer_list) {
 
                /* override speed or wordsize? */
                if (t->speed_hz || t->bits_per_word)
@@ -349,7 +349,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
                if (t->delay_usecs)
                        udelay(t->delay_usecs);
 
-               if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) {
+               if (cs_change &&
+                   !list_is_last(&t->transfer_list, &m->transfers)) {
                        /* sometimes a short mid-message deselect of the chip
                         * may be needed to terminate a mode or command
                         */
@@ -378,7 +379,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
 static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 {
-       struct spi_bitbang      *bitbang;
+       struct spi_bitbang      *bitbang;
        unsigned long           flags;
 
        bitbang = spi_master_get_devdata(spi);
@@ -414,10 +415,16 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
  * This routine registers the spi_master, which will process requests in a
  * dedicated task, keeping IRQs unblocked most of the time.  To stop
  * processing those requests, call spi_bitbang_stop().
+ *
+ * On success, this routine will take a reference to master. The caller is
+ * responsible for calling spi_bitbang_stop() to decrement the reference and
+ * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory
+ * leak.
  */
 int spi_bitbang_start(struct spi_bitbang *bitbang)
 {
        struct spi_master *master = bitbang->master;
+       int ret;
 
        if (!master || !bitbang->chipselect)
                return -EINVAL;
@@ -449,7 +456,11 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
        /* driver may get busy before register() returns, especially
         * if someone registered boardinfo for devices
         */
-       return spi_register_master(master);
+       ret = spi_register_master(spi_master_get(master));
+       if (ret)
+               spi_master_put(master);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(spi_bitbang_start);
 
index 5ed08e5374335e2fcefe76a73bf5d2718d621ce4..8081f96bd1d5add797eb482446f55850cbc248f1 100644 (file)
@@ -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 = spi_master_get(master);
+       pp->bitbang.master = master;
        pp->bitbang.chipselect = butterfly_chipselect;
        pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
 
@@ -289,7 +289,6 @@ 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;
index 6416798828e72bc9f5194282f55cf49a37f6809c..e2a5a426b2efc57038503ed7b64d00237e190b14 100644 (file)
@@ -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 clk_out;
+               goto err_out;
        }
 
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (!ret) {
                dev_info(&pdev->dev,
                         "SPI bus driver initialized. Master clock %u Hz\n",
@@ -239,7 +239,6 @@ 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]))
@@ -260,8 +259,6 @@ 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;
 }
 
index 8fbfe2483ffdd12c20683e50194877c1a1ac85ca..dd72445ba2ea2d14f6afd7fb53c5317c1aee81af 100644 (file)
@@ -279,7 +279,8 @@ 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, prescale = 0;
+       u32 hz = 0, spifmt = 0;
+       int prescale;
 
        dspi = spi_master_get_devdata(spi->master);
        spicfg = (struct davinci_spi_config *)spi->controller_data;
@@ -916,7 +917,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
        if (ret)
                goto unmap_io;
 
-       dspi->bitbang.master = spi_master_get(master);
+       dspi->bitbang.master = master;
        if (dspi->bitbang.master == NULL) {
                ret = -ENODEV;
                goto irq_free;
@@ -925,7 +926,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 put_master;
+               goto irq_free;
        }
        clk_prepare_enable(dspi->clk);
 
@@ -1015,8 +1016,6 @@ 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:
@@ -1024,7 +1023,7 @@ unmap_io:
 release_region:
        release_mem_region(dspi->pbase, resource_size(r));
 free_master:
-       kfree(master);
+       spi_master_put(master);
 err:
        return ret;
 }
@@ -1051,11 +1050,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;
 }
index 4aa8be865cc06ae81d1145161086a89c9846723e..168c620947f4b515bd3307fc84a9dcd3f06073f7 100644 (file)
@@ -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_irq;
+               goto err_unmap;
        }
        clk_enable(dwsmmio->clk);
 
@@ -94,8 +94,6 @@ 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:
@@ -115,7 +113,6 @@ 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);
index 6055c8d9fdd7a44622d9c5c1b27f68ffd4dec50c..66fa9955ea148e5c10c3cfda9b3b90da65902ef0 100644 (file)
@@ -40,7 +40,7 @@ static int spi_pci_probe(struct pci_dev *pdev,
        int pci_bar = 0;
        int ret;
 
-       printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n",
+       dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
                pdev->vendor, pdev->device);
 
        ret = pci_enable_device(pdev);
@@ -109,7 +109,6 @@ 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);
index 79c958e49f6110a33385d99b3116245028c6c264..b897c4adb39deda5f7e293d86216e74458ce912d 100644 (file)
@@ -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);
index 7d84418a01d8c0fece0e4d6e73fbafe559f9b2e3..d4d3cc534792ad024d9680f8e52025460f26e7b3 100644 (file)
@@ -280,10 +280,6 @@ 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);
@@ -347,7 +343,7 @@ static int efm32_spi_probe(struct platform_device *pdev)
 
        ddata = spi_master_get_devdata(master);
 
-       ddata->bitbang.master = spi_master_get(master);
+       ddata->bitbang.master = master;
        ddata->bitbang.chipselect = efm32_spi_chipselect;
        ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;
        ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;
@@ -387,7 +383,7 @@ static int efm32_spi_probe(struct platform_device *pdev)
                goto err;
        }
 
-       if (resource_size(res) < 60) {
+       if (resource_size(res) < 0x60) {
                ret = -EINVAL;
                dev_err(&pdev->dev, "memory resource too small\n");
                goto err;
@@ -467,7 +463,6 @@ err_disable_clk:
                clk_disable_unprepare(ddata->clk);
 err:
                spi_master_put(master);
-               kfree(master);
        }
 
        return ret;
@@ -478,13 +473,14 @@ 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;
 }
index d22c00a227b683ea22b404d680575ae4a27efc9e..1bfaed6e4073cb3d536a9d1baf5be2227324a555 100644 (file)
@@ -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", cr0);
+       dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", 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!", len);
+               dev_warn(&espi->pdev->dev, "len = %zu expected 0!\n", 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 = spi_register_master(master);
+       error = devm_spi_register_master(&pdev->dev, master);
        if (error) {
                dev_err(&pdev->dev, "failed to register SPI master\n");
                goto fail_free_dma;
@@ -968,7 +968,6 @@ static int ep93xx_spi_remove(struct platform_device *pdev)
 
        ep93xx_spi_release_dma(espi);
 
-       spi_unregister_master(master);
        return 0;
 }
 
index bd5aaf42719ce0d735e02d62dfe1372558becaa0..54b06376f03c9e34b3d5863ffa814263455d904c 100644 (file)
@@ -300,7 +300,7 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
 
                switch (mspi->subblock) {
                default:
-                       dev_warn(dev, "cell-index unspecified, assuming SPI1");
+                       dev_warn(dev, "cell-index unspecified, assuming SPI1\n");
                        /* fall through */
                case 0:
                        mspi->subblock = QE_CR_SUBBLOCK_SPI1;
index 4e44575bd87a9674c72338cafe25c1b5006ef529..8641b03bdd7a26f6057914a05e2095c4a9d22d0c 100644 (file)
@@ -108,7 +108,7 @@ struct fsl_dspi {
        struct spi_bitbang      bitbang;
        struct platform_device  *pdev;
 
-       void                    *base;
+       void __iomem            *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 buad rate,speed_hz is %d,clkrate is %ld\
+       pr_warn("Can not find valid baud 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 = spi_master_get(master);
+       dspi->bitbang.master = master;
        dspi->bitbang.chipselect = dspi_chipselect;
        dspi->bitbang.setup_transfer = dspi_setup_transfer;
        dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
@@ -520,7 +520,6 @@ out_clk_put:
        clk_disable_unprepare(dspi->clk);
 out_master_put:
        spi_master_put(master);
-       platform_set_drvdata(pdev, NULL);
 
        return ret;
 }
@@ -531,6 +530,7 @@ 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 v2");
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRIVER_NAME);
index c1c936cf0ed4ec28f3f9ff7322805ebd6da6617b..aa40296f7d96c16101ae68c87e47e4fb2763fb45 100644 (file)
@@ -291,8 +291,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;
                }
 
index 68b69fec13a911cc2ec859ab3b40e5f0ff3f27a6..3fb09f981980aedb23a760dd0b14d604c843661b 100644 (file)
@@ -22,6 +22,7 @@
 #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>
 
@@ -467,7 +468,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
        }
 #endif
 
-       spi_gpio->bitbang.master = spi_master_get(master);
+       spi_gpio->bitbang.master = master;
        spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
 
        if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
@@ -486,7 +487,6 @@ 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;
 }
index 15323d8bd9cfa4237c34069a76e3700dd6873c15..b80f2f70fef7c22174df30a97c311f2aa9693e5c 100644 (file)
@@ -749,6 +749,35 @@ 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;
@@ -786,7 +815,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 = spi_master_get(master);
+       spi_imx->bitbang.master = master;
 
        for (i = 0; i < master->num_chipselect; i++) {
                int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
@@ -810,6 +839,8 @@ 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);
@@ -872,6 +903,8 @@ 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:
index 0759b5db98830ff05d2e1f58d2c4fe953f066967..41c5765be7469de4283ed1c2d9d47802abe17e48 100644 (file)
@@ -222,7 +222,7 @@ static void spi_lm70llp_attach(struct parport *p)
        /*
         * SPI and bitbang hookup.
         */
-       pp->bitbang.master = spi_master_get(master);
+       pp->bitbang.master = master;
        pp->bitbang.chipselect = lm70_chipselect;
        pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;
        pp->bitbang.flags = SPI_3WIRE;
index 8dcc1432f1f51fba2505bad2c6d5ab6690182faf..58d5ee0e4443e24442cb4cbeb51b2e80ac637d3b 100644 (file)
@@ -537,7 +537,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
        if (ret < 0)
                goto free_clock;
 
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(dev, master);
        if (ret < 0)
                goto free_clock;
 
@@ -560,12 +560,10 @@ static int mpc512x_psc_spi_do_remove(struct device *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;
 }
index 6e925dc3439682344def5508f53d2ec6ec9175d6..00ba910ab3023a2587bc54a700e25e9f4a561438 100644 (file)
@@ -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;
index de7b1141b90f5b741f3fc7fcbcdfc197fce5260b..de333059a9a7ec0f55c134f15161c55bd414648c 100644 (file)
 
 #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,
-                               struct spi_transfer *t)
+                                 const struct spi_transfer *t)
 {
        struct mxs_spi *spi = spi_master_get_devdata(dev->master);
        struct mxs_ssp *ssp = &spi->ssp;
-       uint32_t hz = 0;
+       const unsigned int hz = min(dev->max_speed_hz, t->speed_hz);
 
-       hz = dev->max_speed_hz;
-       if (t && t->speed_hz)
-               hz = min(hz, t->speed_hz);
        if (hz == 0) {
-               dev_err(&dev->dev, "Cannot continue with zero clock\n");
+               dev_err(&dev->dev, "SPI clock rate of zero not allowed\n");
                return -EINVAL;
        }
 
-       mxs_ssp_set_clk_rate(ssp, hz);
+       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);
 
        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);
@@ -94,26 +113,15 @@ 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;
 
-       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;
+       return 0;
 }
 
-static uint32_t mxs_spi_cs_to_reg(unsigned cs)
+static u32 mxs_spi_cs_to_reg(unsigned cs)
 {
-       uint32_t select = 0;
+       u32 select = 0;
 
        /*
         * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0
@@ -131,43 +139,11 @@ static uint32_t 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;
-       uint32_t reg;
+       u32 reg;
 
        do {
                reg = readl_relaxed(ssp->base + offset);
@@ -200,9 +176,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, int cs,
+static int mxs_spi_txrx_dma(struct mxs_spi *spi,
                            unsigned char *buf, int len,
-                           int *first, int *last, int write)
+                           unsigned int flags)
 {
        struct mxs_ssp *ssp = &spi->ssp;
        struct dma_async_tx_descriptor *desc = NULL;
@@ -211,11 +187,11 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
        const int sgs = DIV_ROUND_UP(len, desc_len);
        int sg_count;
        int min, ret;
-       uint32_t ctrl0;
+       u32 ctrl0;
        struct page *vm_page;
        void *sg_buf;
        struct {
-               uint32_t                pio[4];
+               u32                     pio[4];
                struct scatterlist      sg;
        } *dma_xfer;
 
@@ -228,21 +204,25 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
        INIT_COMPLETION(spi->c);
 
+       /* Chip select was already programmed into CTRL0 */
        ctrl0 = readl(ssp->base + HW_SSP_CTRL0);
-       ctrl0 &= ~BM_SSP_CTRL0_XFER_COUNT;
-       ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs);
+       ctrl0 &= ~(BM_SSP_CTRL0_XFER_COUNT | BM_SSP_CTRL0_IGNORE_CRC |
+                BM_SSP_CTRL0_READ);
+       ctrl0 |= BM_SSP_CTRL0_DATA_XFER;
 
-       if (*first)
-               ctrl0 |= BM_SSP_CTRL0_LOCK_CS;
-       if (!write)
+       if (!(flags & TXRX_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);
 
-               /* Prepare the transfer descriptor. */
-               if ((sg_count + 1 == sgs) && *last)
+               /*
+                * 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))
                        ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC;
 
                if (ssp->devid == IMX23_SSP) {
@@ -267,7 +247,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
                sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);
                ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
-                       write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+                       (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
                len -= min;
                buf += min;
@@ -287,7 +267,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
                desc = dmaengine_prep_slave_sg(ssp->dmach,
                                &dma_xfer[sg_count].sg, 1,
-                               write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+                               (flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
                if (!desc) {
@@ -324,7 +304,7 @@ err_vmalloc:
        while (--sg_count >= 0) {
 err_mapped:
                dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
-                       write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+                       (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
        }
 
        kfree(dma_xfer);
@@ -332,20 +312,19 @@ err_mapped:
        return ret;
 }
 
-static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
+static int mxs_spi_txrx_pio(struct mxs_spi *spi,
                            unsigned char *buf, int len,
-                           int *first, int *last, int write)
+                           unsigned int flags)
 {
        struct mxs_ssp *ssp = &spi->ssp;
 
-       if (*first)
-               mxs_spi_enable(spi);
-
-       mxs_spi_set_cs(spi, cs);
+       writel(BM_SSP_CTRL0_IGNORE_CRC,
+              ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
 
        while (len--) {
-               if (*last && len == 0)
-                       mxs_spi_disable(spi);
+               if (len == 0 && (flags & TXRX_DEASSERT_CS))
+                       writel(BM_SSP_CTRL0_IGNORE_CRC,
+                              ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 
                if (ssp->devid == IMX23_SSP) {
                        writel(BM_SSP_CTRL0_XFER_COUNT,
@@ -356,7 +335,7 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
                        writel(1, ssp->base + HW_SSP_XFER_SIZE);
                }
 
-               if (write)
+               if (flags & TXRX_WRITE)
                        writel(BM_SSP_CTRL0_READ,
                                ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
                else
@@ -369,13 +348,13 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
                if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1))
                        return -ETIMEDOUT;
 
-               if (write)
+               if (flags & TXRX_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 (!write) {
+               if (!(flags & TXRX_WRITE)) {
                        if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp),
                                                BM_SSP_STATUS_FIFO_EMPTY, 0))
                                return -ETIMEDOUT;
@@ -400,14 +379,15 @@ 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;
 
-       cs = m->spi->chip_select;
+       /* 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);
 
        list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) {
 
@@ -415,16 +395,9 @@ static int mxs_spi_transfer_one(struct spi_master *master,
                if (status)
                        break;
 
-               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;
-               }
+               /* De-assert on last transfer, inverted by cs_change flag */
+               flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ?
+                      TXRX_DEASSERT_CS : 0;
 
                /*
                 * Small blocks can be transfered via PIO.
@@ -441,26 +414,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, cs,
+                               status = mxs_spi_txrx_pio(spi,
                                                (void *)t->tx_buf,
-                                               t->len, &first, &last, 1);
+                                               t->len, flag | TXRX_WRITE);
                        if (t->rx_buf)
-                               status = mxs_spi_txrx_pio(spi, cs,
+                               status = mxs_spi_txrx_pio(spi,
                                                t->rx_buf, t->len,
-                                               &first, &last, 0);
+                                               flag);
                } 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, cs,
+                               status = mxs_spi_txrx_dma(spi,
                                                (void *)t->tx_buf, t->len,
-                                               &first, &last, 1);
+                                               flag | TXRX_WRITE);
                        if (t->rx_buf)
-                               status = mxs_spi_txrx_dma(spi, cs,
+                               status = mxs_spi_txrx_dma(spi,
                                                t->rx_buf, t->len,
-                                               &first, &last, 0);
+                                               flag);
                }
 
                if (status) {
@@ -469,7 +442,6 @@ static int mxs_spi_transfer_one(struct spi_master *master,
                }
 
                m->actual_length += t->len;
-               first = last = 0;
        }
 
        m->status = status;
@@ -563,7 +535,6 @@ 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)
@@ -571,7 +542,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, master);
 
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret) {
                dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
                goto out_disable_clk;
@@ -598,10 +569,8 @@ static int mxs_spi_remove(struct platform_device *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;
 }
index 47a68b43bcd5057f3fec2ffda5d2fe9c1dda0a9c..e0c32bc69ee2553d137e28d0ea2c70cdd58a2050 100644 (file)
@@ -349,7 +349,7 @@ static int nuc900_spi_probe(struct platform_device *pdev)
        }
 
        hw = spi_master_get_devdata(master);
-       hw->master = spi_master_get(master);
+       hw->master = master;
        hw->pdata  = dev_get_platdata(&pdev->dev);
        hw->dev = &pdev->dev;
 
@@ -435,7 +435,6 @@ err_iomap:
        kfree(hw->ioarea);
 err_pdata:
        spi_master_put(hw->master);
-
 err_nomem:
        return err;
 }
index 333cb1badcd73be1da1656196139040cce133096..91c66859620232a024827df02f846c0a6f08798d 100644 (file)
@@ -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 = spi_master_get(master);
+       hw->bitbang.master = master;
        if (!hw->bitbang.master)
                return err;
        hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
index 5f28ddbe4f7e9cf5b5d5716c55e88c8fe7f346f7..67249a48b391b601a7e069ff566015e5a3872773 100644 (file)
@@ -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 = spi_register_master(master);
+       err = devm_spi_register_master(&pdev->dev, master);
        if (err) {
                dev_err(&pdev->dev, "register master failed: %d\n", err);
                goto fail;
@@ -292,8 +292,6 @@ 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);
 
index 69ecf05757dda6d5f8fc42f7718f7754af43f03c..b6ed82beb01dc651d687f374ce5536ce289d440c 100644 (file)
@@ -457,7 +457,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
                goto err;
        }
 
-       status = spi_register_master(master);
+       status = devm_spi_register_master(&pdev->dev, master);
        if (status < 0)
                goto err;
 
@@ -485,8 +485,6 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       spi_unregister_master(master);
-
        return 0;
 }
 
index a6a8f09617508aeaf5a4ac3631d8914d26f38807..9313fd3b413dfd6eed5e1d8e14dc42a0e32f1e3d 100644 (file)
@@ -557,7 +557,8 @@ static struct platform_driver uwire_driver = {
                .name           = "omap_uwire",
                .owner          = THIS_MODULE,
        },
-       .remove         = uwire_remove,
+       .probe = uwire_probe,
+       .remove = uwire_remove,
        // suspend ... unuse ck
        // resume ... use ck
 };
@@ -579,7 +580,7 @@ static int __init omap_uwire_init(void)
                omap_writel(val | 0x00AAA000, OMAP7XX_IO_CONF_9);
        }
 
-       return platform_driver_probe(&uwire_driver, uwire_probe);
+       return platform_driver_register(&uwire_driver);
 }
 
 static void __exit omap_uwire_exit(void)
index ed4af4708d9aa2374c444915aa81345b9684b518..443df39840bc899fb3525dcb141ed82da87d72f4 100644 (file)
@@ -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 fifo_depth, bytes_per_word;
+       int max_fifo_depth, fifo_depth, bytes_per_word;
        u32 chconf, xferlevel;
 
        mcspi = spi_master_get_devdata(master);
@@ -287,7 +287,12 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
                if (t->len % bytes_per_word != 0)
                        goto disable_fifo;
 
-               fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH);
+               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);
                if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
                        goto disable_fifo;
 
@@ -299,7 +304,8 @@ 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;
-               } else {
+               }
+               if (t->tx_buf != NULL) {
                        chconf |= OMAP2_MCSPI_CHCONF_FFET;
                        xferlevel |= fifo_depth - 1;
                }
@@ -498,7 +504,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");
+                       dev_err(&spi->dev, "DMA RX penultimate word empty\n");
                        count -= (bytes_per_word << 1);
                        omap2_mcspi_set_enable(spi, 1);
                        return count;
@@ -516,7 +522,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");
+               dev_err(&spi->dev, "DMA RX last word empty\n");
                count -= mcspi_bytes_per_word(word_len);
        }
        omap2_mcspi_set_enable(spi, 1);
@@ -1407,7 +1413,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
        if (status < 0)
                goto disable_pm;
 
-       status = spi_register_master(master);
+       status = devm_spi_register_master(&pdev->dev, master);
        if (status < 0)
                goto disable_pm;
 
@@ -1435,7 +1441,6 @@ 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;
index 1d1d321d90c458b9e3b6afe7f61172453a25d627..744841e095e4be7d4a8b7e6f057b2bed2915cf9a 100644 (file)
@@ -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 = spi_register_master(master);
+       status = devm_spi_register_master(&pdev->dev, master);
        if (status < 0)
                goto out_rel_clk;
 
@@ -483,8 +483,6 @@ static int orion_spi_remove(struct platform_device *pdev)
        clk_disable_unprepare(spi->clk);
        clk_put(spi->clk);
 
-       spi_unregister_master(master);
-
        return 0;
 }
 
index 9c511a954d213cfec829ebcc0431b80cf93541f9..2789b452e71159a86164ff752ef2c1e06a6da411 100644 (file)
@@ -1619,7 +1619,6 @@ 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:
@@ -1645,7 +1644,6 @@ 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)
@@ -2175,8 +2173,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
                status = -ENOMEM;
                goto err_no_ioremap;
        }
-       printk(KERN_INFO "pl022: mapped registers from %pa to %p\n",
-              &adev->res.start, pl022->virtbase);
+       dev_info(&adev->dev, "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)) {
@@ -2227,7 +2225,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 = spi_register_master(master);
+       status = devm_spi_register_master(&adev->dev, master);
        if (status != 0) {
                dev_err(&adev->dev,
                        "probe - problem registering spi master\n");
@@ -2287,8 +2285,6 @@ 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;
 }
 
index 0ee53c25ba58b5d772633e4736f5c2bbbaf72ab4..c57740bb70d30815f2a30ee342af6a2b782ce1a1 100644 (file)
@@ -396,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 = spi_master_get(master);
+       hw->master = master;
        hw->dev = dev;
 
        init_completion(&hw->done);
@@ -558,6 +558,7 @@ 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;
 }
 
index c1a50674c1e359deb3e83fc2a04c9acf2324f58d..cb0e1f1137adb65384188ce31651171cb3f5f311 100644 (file)
@@ -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,11 +660,10 @@ static void pump_transfers(unsigned long data)
                }
 
                /* warn ... we force this to PIO mode */
-               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);
+               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);
        }
 
        /* Setup the transfer state based on the type of transfer */
@@ -726,11 +725,8 @@ static void pump_transfers(unsigned long data)
                                                        message->spi,
                                                        bits, &dma_burst,
                                                        &dma_thresh))
-                               if (printk_ratelimit())
-                                       dev_warn(&message->spi->dev,
-                                               "pump_transfers: "
-                                               "DMA burst size reduced to "
-                                               "match bits_per_word\n");
+                               dev_warn_ratelimited(&message->spi->dev,
+                                                    "pump_transfers: DMA burst size reduced to match bits_per_word\n");
                }
 
                cr0 = clk_div
@@ -854,8 +850,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;
                }
 
@@ -899,8 +895,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;
                        }
@@ -956,8 +952,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");
                }
        }
 
@@ -1205,7 +1201,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 
        /* Register with the SPI framework */
        platform_set_drvdata(pdev, drv_data);
-       status = spi_register_master(master);
+       status = devm_spi_register_master(&pdev->dev, master);
        if (status != 0) {
                dev_err(&pdev->dev, "problem registering spi master\n");
                goto out_error_clock_enabled;
@@ -1257,9 +1253,6 @@ 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;
 }
 
index 8719206a03a00e59a7dea523afe7f6c841745d50..58449ad4ad0d3a83eb273b49f292909078519ca1 100644 (file)
 #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
 #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
 #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;
@@ -145,6 +159,7 @@ struct rspi_data {
        spinlock_t lock;
        struct clk *clk;
        unsigned char spsr;
+       const struct spi_ops *ops;
 
        /* for dmaengine */
        struct dma_chan *chan_tx;
@@ -165,6 +180,11 @@ 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);
@@ -175,17 +195,103 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset)
        return ioread16(rspi->addr + offset);
 }
 
-static unsigned char rspi_calc_spbr(struct rspi_data *rspi)
+/* 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)
 {
-       int tmp;
-       unsigned char spbr;
+       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);
 
-       tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
-       spbr = clamp(tmp, 0, 255);
+       /* Enables SPI function in a master mode */
+       rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 
-       return spbr;
+       return 0;
 }
 
+#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);
@@ -220,54 +326,60 @@ static void rspi_negate_ssl(struct rspi_data *rspi)
        rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
 }
 
-static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
+static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
+                        struct spi_transfer *t)
 {
-       /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-       rspi_write8(rspi, 0x00, RSPI_SPPCR);
-
-       /* Sets transfer bit rate */
-       rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR);
-
-       /* Sets number of frames to be used: 1 frame */
-       rspi_write8(rspi, 0x00, RSPI_SPDCR);
+       int remain = t->len;
+       u8 *data;
 
-       /* 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 = (u8 *)t->tx_buf;
+       while (remain > 0) {
+               rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
+                           RSPI_SPCR);
 
-       /* Sets parity, interrupt mask */
-       rspi_write8(rspi, 0x00, RSPI_SPCR2);
+               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 SPCMD */
-       rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
-                    RSPI_SPCMD0);
+               rspi_write16(rspi, *data, RSPI_SPDR);
+               data++;
+               remain--;
+       }
 
-       /* Sets RSPI mode */
-       rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+       /* Waiting for the last transmition */
+       rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
 
        return 0;
 }
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
+static int qspi_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--;
        }
 
@@ -277,6 +389,8 @@ static int rspi_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;
@@ -442,6 +556,51 @@ 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;
@@ -581,7 +740,7 @@ static void rspi_work(struct work_struct *work)
                                if (rspi_is_dma(rspi, t))
                                        ret = rspi_send_dma(rspi, t);
                                else
-                                       ret = rspi_send_pio(rspi, mesg, t);
+                                       ret = send_pio(rspi, mesg, t);
                                if (ret < 0)
                                        goto error;
                        }
@@ -589,7 +748,7 @@ static void rspi_work(struct work_struct *work)
                                if (rspi_is_dma(rspi, t))
                                        ret = rspi_receive_dma(rspi, t);
                                else
-                                       ret = rspi_receive_pio(rspi, mesg, t);
+                                       ret = receive_pio(rspi, mesg, t);
                                if (ret < 0)
                                        goto error;
                        }
@@ -616,7 +775,7 @@ static int rspi_setup(struct spi_device *spi)
                spi->bits_per_word = 8;
        rspi->max_speed_hz = spi->max_speed_hz;
 
-       rspi_set_config_register(rspi, 8);
+       set_config_register(rspi, 8);
 
        return 0;
 }
@@ -745,7 +904,16 @@ 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)) {
@@ -767,7 +935,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) {
@@ -776,7 +944,7 @@ static int rspi_probe(struct platform_device *pdev)
                goto error1;
        }
 
-       snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id);
+       snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
        rspi->clk = clk_get(&pdev->dev, clk_name);
        if (IS_ERR(rspi->clk)) {
                dev_err(&pdev->dev, "cannot get clock\n");
@@ -790,7 +958,10 @@ static int rspi_probe(struct platform_device *pdev)
        INIT_WORK(&rspi->ws, rspi_work);
        init_waitqueue_head(&rspi->wait);
 
-       master->num_chipselect = 2;
+       master->num_chipselect = rspi_pd->num_chipselect;
+       if (!master->num_chipselect)
+               master->num_chipselect = 2; /* default */
+
        master->bus_num = pdev->id;
        master->setup = rspi_setup;
        master->transfer = rspi_transfer;
@@ -832,11 +1003,32 @@ 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 = "rspi",
+               .name = "renesas_spi",
                .owner  = THIS_MODULE,
        },
 };
index ce318d95a6ee8cb619d80f4a74ede5c377b024f4..0dc32a11bd3cd9ac657f9330858e29398876d96e 100644 (file)
@@ -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.
 */
-void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
+static 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 = spi_master_get(master);
+       hw->master = master;
        hw->pdata = pdata = dev_get_platdata(&pdev->dev);
        hw->dev = &pdev->dev;
 
index a80376dc3a102d04684f27934a42412be3e851d7..9e2020df9e0f7e5c473cf500b82c611d4625686f 100644 (file)
@@ -205,7 +205,6 @@ struct s3c64xx_spi_driver_data {
 #endif
        struct s3c64xx_spi_port_config  *port_conf;
        unsigned int                    port_id;
-       unsigned long                   gpios[4];
        bool                            cs_gpio;
 };
 
@@ -559,25 +558,18 @@ 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 */
-                       cs = sdd->tgl_spi->controller_data;
-                       if (sdd->cs_gpio)
-                               gpio_set_value(cs->line,
+                       if (spi->cs_gpio >= 0)
+                               gpio_set_value(spi->cs_gpio,
                                        spi->mode & SPI_CS_HIGH ? 0 : 1);
                }
                sdd->tgl_spi = NULL;
        }
 
-       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);
+       if (spi->cs_gpio >= 0)
+               gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 1 : 0);
 }
 
 static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
@@ -702,16 +694,11 @@ 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 (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);
+       if (spi->cs_gpio >= 0)
+               gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
 }
 
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
@@ -862,16 +849,12 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
        }
 }
 
-static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
-                                           struct spi_message *msg)
+static int s3c64xx_spi_prepare_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
@@ -887,106 +870,98 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
        if (s3c64xx_spi_map_mssg(sdd, msg)) {
                dev_err(&spi->dev,
                        "Xfer: Unable to map message buffers!\n");
-               status = -ENOMEM;
-               goto out;
+               return -ENOMEM;
        }
 
        /* Configure feedback delay */
        writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
 
-       list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-
-               unsigned long flags;
-               int use_dma;
-
-               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;
-
-               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;
-               }
+       return 0;
+}
 
-               if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
-                       sdd->cur_bpw = bpw;
-                       sdd->cur_speed = speed;
-                       s3c64xx_spi_config(sdd);
-               }
+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;
 
-               /* 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;
+       INIT_COMPLETION(sdd->xfer_completion);
 
-               spin_lock_irqsave(&sdd->lock, flags);
+       /* Only BPW and Speed may change across transfers */
+       bpw = xfer->bits_per_word;
+       speed = xfer->speed_hz ? : spi->max_speed_hz;
 
-               /* Pending only which is to be done */
-               sdd->state &= ~RXBUSY;
-               sdd->state &= ~TXBUSY;
+       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;
+       }
 
-               enable_datapath(sdd, spi, xfer, use_dma);
+       if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
+               sdd->cur_bpw = bpw;
+               sdd->cur_speed = speed;
+               s3c64xx_spi_config(sdd);
+       }
 
-               /* Slave Select */
-               enable_cs(sdd, spi);
+       /* 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_unlock_irqrestore(&sdd->lock, flags);
+       spin_lock_irqsave(&sdd->lock, flags);
 
-               status = wait_for_xfer(sdd, xfer, use_dma);
+       /* Pending only which is to be done */
+       sdd->state &= ~RXBUSY;
+       sdd->state &= ~TXBUSY;
 
-               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);
+       enable_datapath(sdd, spi, xfer, use_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);
-                       }
+       /* Start the signals */
+       writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
-                       goto out;
-               }
+       /* Start the signals */
+       writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
-               if (xfer->delay_usecs)
-                       udelay(xfer->delay_usecs);
+       spin_unlock_irqrestore(&sdd->lock, flags);
 
-               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;
+       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);
                }
-
-               msg->actual_length += xfer->len;
-
+       } else {
                flush_fifo(sdd);
        }
 
-out:
-       if (!cs_toggle || status)
-               disable_cs(sdd, spi);
-       else
-               sdd->tgl_spi = spi;
-
-       s3c64xx_spi_unmap_mssg(sdd, msg);
+       return status;
+}
 
-       msg->status = 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);
 
-       spi_finalize_current_message(master);
+       s3c64xx_spi_unmap_mssg(sdd, msg);
 
        return 0;
 }
@@ -1071,6 +1046,8 @@ 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);
@@ -1117,11 +1094,14 @@ 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);
@@ -1140,8 +1120,8 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)
        struct s3c64xx_spi_driver_data *sdd;
 
        sdd = spi_master_get_devdata(spi->master);
-       if (cs && sdd->cs_gpio) {
-               gpio_free(cs->line);
+       if (spi->cs_gpio) {
+               gpio_free(spi->cs_gpio);
                if (spi->dev.of_node)
                        kfree(cs);
        }
@@ -1359,7 +1339,9 @@ 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->transfer_one_message = s3c64xx_spi_transfer_one_message;
+       master->prepare_message = s3c64xx_spi_prepare_message;
+       master->transfer_one = s3c64xx_spi_transfer_one;
+       master->unprepare_message = s3c64xx_spi_unprepare_message;
        master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
        master->num_chipselect = sci->num_cs;
        master->dma_alignment = 8;
@@ -1428,11 +1410,12 @@ 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);
 
-       if (spi_register_master(master)) {
-               dev_err(&pdev->dev, "cannot register SPI master\n");
-               ret = -EBUSY;
+       ret = devm_spi_register_master(&pdev->dev, master);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);
                goto err3;
        }
 
@@ -1461,16 +1444,12 @@ 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;
 }
 
@@ -1480,11 +1459,14 @@ 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);
 
-       spi_master_suspend(master);
+       int ret = spi_master_suspend(master);
+       if (ret)
+               return ret;
 
-       /* Disable the clock */
-       clk_disable_unprepare(sdd->src_clk);
-       clk_disable_unprepare(sdd->clk);
+       if (!pm_runtime_suspended(dev)) {
+               clk_disable_unprepare(sdd->clk);
+               clk_disable_unprepare(sdd->src_clk);
+       }
 
        sdd->cur_speed = 0; /* Output Clock is stopped */
 
@@ -1500,15 +1482,14 @@ static int s3c64xx_spi_resume(struct device *dev)
        if (sci->cfg_gpio)
                sci->cfg_gpio();
 
-       /* Enable the clock */
-       clk_prepare_enable(sdd->src_clk);
-       clk_prepare_enable(sdd->clk);
+       if (!pm_runtime_suspended(dev)) {
+               clk_prepare_enable(sdd->src_clk);
+               clk_prepare_enable(sdd->clk);
+       }
 
        s3c64xx_spi_hwinit(sdd, sdd->port_id);
 
-       spi_master_resume(master);
-
-       return 0;
+       return spi_master_resume(master);
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -1528,9 +1509,17 @@ 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;
 
-       clk_prepare_enable(sdd->src_clk);
-       clk_prepare_enable(sdd->clk);
+       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;
+       }
 
        return 0;
 }
@@ -1616,6 +1605,18 @@ 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,
        },
@@ -1633,22 +1634,13 @@ 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");
 
-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_platform_driver(s3c64xx_spi_driver);
 
 MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");
index e488a90a98b8acbfff5b1fd72dd92b54db2ae602..bc38aaf4e1f966e27b724b89844975e2726454b6 100644 (file)
@@ -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);
@@ -305,7 +305,7 @@ static int hspi_probe(struct platform_device *pdev)
        master->mode_bits       = SPI_CPOL | SPI_CPHA;
        master->auto_runtime_pm = true;
        master->transfer_one_message            = hspi_transfer_one_message;
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret < 0) {
                dev_err(&pdev->dev, "spi_register_master error.\n");
                goto error1;
@@ -328,7 +328,6 @@ static int hspi_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
 
        clk_put(hspi->clk);
-       spi_unregister_master(hspi->master);
 
        return 0;
 }
index 8eefeb6007dfef67f8bcb5f8c6ad87ed5b3c68c8..38eb24df796c58ebdef65d2c5ada2e90aff036d0 100644 (file)
@@ -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 = spi_master_get(master);
+       sp->bitbang.master = 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;
index a1f21b74773345b581bd63333a9d608f19c0de53..592b4aff651f674c39f5c136a7bab01f9b178898 100644 (file)
@@ -632,7 +632,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
        if (ret)
                goto free_master;
 
-       sspi->bitbang.master = spi_master_get(master);
+       sspi->bitbang.master = master;
        sspi->bitbang.chipselect = spi_sirfsoc_chipselect;
        sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer;
        sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer;
index 145dd435483b2d12e304ce3bb46f97a2f4baab4e..9146bb3c24895803904bf67281b38ce9bc9c8395 100644 (file)
@@ -182,6 +182,7 @@ 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;
@@ -267,7 +268,7 @@ static unsigned tegra_spi_calculate_curr_xfer_param(
        unsigned max_len;
        unsigned total_fifo_words;
 
-       tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1;
+       tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
 
        if (bits_per_word == 8 || bits_per_word == 16) {
                tspi->is_packed = 1;
@@ -676,15 +677,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
        dma_release_channel(dma_chan);
 }
 
-static int tegra_spi_start_transfer_one(struct spi_device *spi,
-               struct spi_transfer *t, bool is_first_of_msg,
-               bool is_single_xfer)
+static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi,
+               struct spi_transfer *t, bool is_first_of_msg)
 {
        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;
 
@@ -698,7 +696,6 @@ static int tegra_spi_start_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);
@@ -717,7 +714,12 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
                else if (req_mode == SPI_MODE_3)
                        command1 |= SPI_CONTROL_MODE_3;
 
-               tegra_spi_writel(tspi, command1, SPI_COMMAND1);
+               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);
 
                command1 |= SPI_CS_SW_HW;
                if (spi->mode & SPI_CS_HIGH)
@@ -732,6 +734,18 @@ static int tegra_spi_start_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;
 
@@ -803,29 +817,50 @@ 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;
+
                INIT_COMPLETION(tspi->xfer_completion);
-               ret = tegra_spi_start_transfer_one(spi, xfer,
-                                       is_first_msg, single_xfer);
+
+               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);
                if (ret < 0) {
                        dev_err(tspi->dev,
                                "spi can not start transfer, err %d\n", ret);
-                       goto exit;
+                       goto complete_xfer;
                }
+
                is_first_msg = false;
                ret = wait_for_completion_timeout(&tspi->xfer_completion,
                                                SPI_DMA_TIMEOUT);
@@ -833,24 +868,40 @@ 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 exit;
+                       goto complete_xfer;
                }
 
                if (tspi->tx_status ||  tspi->rx_status) {
                        dev_err(tspi->dev, "Error in Transfer\n");
                        ret = -EIO;
-                       goto exit;
+                       goto complete_xfer;
                }
                msg->actual_length += xfer->len;
-               if (xfer->cs_change && xfer->delay_usecs) {
+
+complete_xfer:
+               if (ret < 0 || skip) {
                        tegra_spi_writel(tspi, tspi->def_command1_reg,
                                        SPI_COMMAND1);
-                       udelay(xfer->delay_usecs);
+                       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);
                }
+
        }
        ret = 0;
 exit:
-       tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
        msg->status = ret;
        spi_finalize_current_message(master);
        return ret;
@@ -1115,7 +1166,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
        pm_runtime_put(&pdev->dev);
 
        master->dev.of_node = pdev->dev.of_node;
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret < 0) {
                dev_err(&pdev->dev, "can not register to master err %d\n", ret);
                goto exit_pm_disable;
@@ -1142,7 +1193,6 @@ 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);
index 1d814dc6e0000c7743b6844db332f46a6516389c..79be8ce6a9d11368389c97faa0047c8ab5b5d8e1 100644 (file)
@@ -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 = (t->bits_per_word - 1) / 8 + 1;
+       tsd->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);
        max_word = remain_len / tsd->bytes_per_word;
        if (max_word > SPI_FIFO_DEPTH)
                max_word = SPI_FIFO_DEPTH;
@@ -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 = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret < 0) {
                dev_err(&pdev->dev, "can not register to master err %d\n", ret);
                goto exit_pm_disable;
@@ -553,7 +553,6 @@ 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))
index c70353672a23df85234c5089c28af6a155d33a99..af0a67886ae8bee523c469af2d89d49aca9c2ec5 100644 (file)
@@ -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 = (bits_per_word - 1) / 8 + 1;
+       tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
 
        if (bits_per_word == 8 || bits_per_word == 16) {
                tspi->is_packed = 1;
@@ -707,8 +707,7 @@ 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, bool is_first_of_msg,
-               bool is_single_xfer)
+               struct spi_transfer *t)
 {
        struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
        u32 speed;
@@ -732,32 +731,12 @@ 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);
 
-       if (is_first_of_msg) {
-               tegra_slink_clear_status(tspi);
+       command = tspi->command_reg;
+       command &= ~SLINK_BIT_LENGTH(~0);
+       command |= SLINK_BIT_LENGTH(bits_per_word - 1);
 
-               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);
-       }
+       command2 = tspi->command2_reg;
+       command2 &= ~(SLINK_RXEN | SLINK_TXEN);
 
        tegra_slink_writel(tspi, command, SLINK_COMMAND);
        tspi->command_reg = command;
@@ -824,58 +803,72 @@ static int tegra_slink_setup(struct spi_device *spi)
        return 0;
 }
 
-static int tegra_slink_transfer_one_message(struct spi_master *master,
-                       struct spi_message *msg)
+static int tegra_slink_prepare_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;
-       int ret;
 
-       msg->status = 0;
-       msg->actual_length = 0;
+       tegra_slink_clear_status(tspi);
 
-       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;
-               }
+       tspi->command_reg = tspi->def_command_reg;
+       tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE;
 
-               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);
-               }
+       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;
+
+       INIT_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;
        }
-       ret = 0;
-exit:
+
+       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);
+
        tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND);
        tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2);
-       msg->status = ret;
-       spi_finalize_current_message(master);
-       return ret;
+
+       return 0;
 }
 
 static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
@@ -1078,7 +1071,9 @@ 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->transfer_one_message = tegra_slink_transfer_one_message;
+       master->prepare_message = tegra_slink_prepare_message;
+       master->transfer_one = tegra_slink_transfer_one;
+       master->unprepare_message = tegra_slink_unprepare_message;
        master->auto_runtime_pm = true;
        master->num_chipselect = MAX_CHIP_SELECT;
        master->bus_num = -1;
@@ -1164,7 +1159,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
        pm_runtime_put(&pdev->dev);
 
        master->dev.of_node = pdev->dev.of_node;
-       ret = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret < 0) {
                dev_err(&pdev->dev, "can not register to master err %d\n", ret);
                goto exit_pm_disable;
@@ -1191,7 +1186,6 @@ 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);
index e12d962a289f61823b673098fce9e49dc8da94f7..0b71270fbf67ba671dd43f116db48de30076514c 100644 (file)
@@ -41,9 +41,6 @@ struct ti_qspi_regs {
 struct ti_qspi {
        struct completion       transfer_complete;
 
-       /* IRQ synchronization */
-       spinlock_t              lock;
-
        /* list synchronization */
        struct mutex            list_lock;
 
@@ -57,7 +54,6 @@ struct ti_qspi {
        u32 spi_max_frequency;
        u32 cmd;
        u32 dc;
-       u32 stat;
 };
 
 #define QSPI_PID                       (0x0)
@@ -397,13 +393,12 @@ 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);
-       qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
+       stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
 
        if (!int_stat) {
                dev_dbg(qspi->dev, "No IRQ triggered\n");
@@ -411,35 +406,14 @@ 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;
@@ -472,7 +446,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
        if (!master)
                return -ENOMEM;
 
-       master->mode_bits = SPI_CPOL | SPI_CPHA;
+       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
 
        master->bus_num = -1;
        master->flags = SPI_MASTER_HALF_DUPLEX;
@@ -499,7 +473,6 @@ 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);
@@ -508,8 +481,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
                goto free_master;
        }
 
-       ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr,
-                       ti_qspi_threaded_isr, 0,
+       ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,
                        dev_name(&pdev->dev), qspi);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
@@ -532,7 +504,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 = spi_register_master(master);
+       ret = devm_spi_register_master(&pdev->dev, master);
        if (ret)
                goto free_master;
 
@@ -547,7 +519,7 @@ static int ti_qspi_remove(struct platform_device *pdev)
 {
        struct  ti_qspi *qspi = platform_get_drvdata(pdev);
 
-       spi_unregister_master(qspi->master);
+       ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
 
        return 0;
 }
@@ -558,7 +530,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,
index eaeeed51bbbfa1f6a315fd87a2cef72b5dd2c5d1..446131308acb26a1fac3ed8bfc1aad9e287404d5 100644 (file)
@@ -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,8 +526,9 @@ 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)
@@ -1181,8 +1182,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;
 
@@ -1410,13 +1411,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) +
-                                        PCH_ADDRESS_SIZE * plat_dev->id;
+       data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0);
        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);
index 7c6d15766c72539f9561cecddfd886666218b8d6..637cce2b8bdde8d3f37c8134a5f3aee7c4adead8 100644 (file)
@@ -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 = spi_register_master(master);
+       ret = devm_spi_register_master(&dev->dev, master);
        if (ret)
                goto exit;
        return 0;
@@ -428,11 +428,9 @@ static int txx9spi_remove(struct platform_device *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;
 }
 
@@ -440,6 +438,7 @@ 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",
@@ -449,7 +448,7 @@ static struct platform_driver txx9spi_driver = {
 
 static int __init txx9spi_init(void)
 {
-       return platform_driver_probe(&txx9spi_driver, txx9spi_probe);
+       return platform_driver_register(&txx9spi_driver);
 }
 subsys_initcall(txx9spi_init);
 
index 0bf1b2c457a1dc6b71cc69641216ac6bb8b4a87b..ec3a83f52ea2faead4cb43ab9908c087004469e9 100644 (file)
@@ -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 = spi_master_get(master);
+       xspi->bitbang.master = master;
        xspi->bitbang.chipselect = xilinx_spi_chipselect;
        xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
        xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
index 740f9ddda227d55f15042e1e7a8d2cadb58aae71..927998aa5e71e711177a3adbf7cfe94ed020a85b 100644 (file)
@@ -39,6 +39,9 @@
 #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);
@@ -58,11 +61,13 @@ 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 device_attribute spi_dev_attrs[] = {
-       __ATTR_RO(modalias),
-       __ATTR_NULL,
+static struct attribute *spi_dev_attrs[] = {
+       &dev_attr_modalias.attr,
+       NULL,
 };
+ATTRIBUTE_GROUPS(spi_dev);
 
 /* modalias support makes "modprobe $MODALIAS" new-style hotplug work,
  * and the sysfs version makes coldplug work too.
@@ -229,7 +234,7 @@ static const struct dev_pm_ops spi_pm = {
 
 struct bus_type spi_bus_type = {
        .name           = "spi",
-       .dev_attrs      = spi_dev_attrs,
+       .dev_groups     = spi_dev_groups,
        .match          = spi_match_device,
        .uevent         = spi_uevent,
        .pm             = &spi_pm,
@@ -335,7 +340,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);
@@ -535,6 +540,95 @@ 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);
+
+               INIT_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
@@ -569,6 +663,7 @@ 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;
        }
 
@@ -597,6 +692,9 @@ 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) {
@@ -609,6 +707,20 @@ 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,
@@ -690,6 +802,7 @@ 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;
@@ -698,9 +811,20 @@ 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);
 
@@ -815,6 +939,8 @@ 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);
@@ -850,10 +976,8 @@ 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;
-       int len;
+       u32 value;
 
        if (!master->dev.of_node)
                return;
@@ -878,14 +1002,14 @@ static void of_register_spi_devices(struct spi_master *master)
                }
 
                /* Device address */
-               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);
+               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);
                        spi_dev_put(spi);
                        continue;
                }
-               spi->chip_select = be32_to_cpup(prop);
+               spi->chip_select = value;
 
                /* Mode (clock phase/polarity/etc.) */
                if (of_find_property(nc, "spi-cpha", NULL))
@@ -898,55 +1022,53 @@ static void of_register_spi_devices(struct spi_master *master)
                        spi->mode |= SPI_3WIRE;
 
                /* Device DUAL/QUAD mode */
-               prop = of_get_property(nc, "spi-tx-bus-width", &len);
-               if (prop && len == sizeof(*prop)) {
-                       switch (be32_to_cpup(prop)) {
-                       case SPI_NBITS_SINGLE:
+               if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
+                       switch (value) {
+                       case 1:
                                break;
-                       case SPI_NBITS_DUAL:
+                       case 2:
                                spi->mode |= SPI_TX_DUAL;
                                break;
-                       case SPI_NBITS_QUAD:
+                       case 4:
                                spi->mode |= SPI_TX_QUAD;
                                break;
                        default:
                                dev_err(&master->dev,
                                        "spi-tx-bus-width %d not supported\n",
-                                       be32_to_cpup(prop));
+                                       value);
                                spi_dev_put(spi);
                                continue;
                        }
                }
 
-               prop = of_get_property(nc, "spi-rx-bus-width", &len);
-               if (prop && len == sizeof(*prop)) {
-                       switch (be32_to_cpup(prop)) {
-                       case SPI_NBITS_SINGLE:
+               if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) {
+                       switch (value) {
+                       case 1:
                                break;
-                       case SPI_NBITS_DUAL:
+                       case 2:
                                spi->mode |= SPI_RX_DUAL;
                                break;
-                       case SPI_NBITS_QUAD:
+                       case 4:
                                spi->mode |= SPI_RX_QUAD;
                                break;
                        default:
                                dev_err(&master->dev,
                                        "spi-rx-bus-width %d not supported\n",
-                                       be32_to_cpup(prop));
+                                       value);
                                spi_dev_put(spi);
                                continue;
                        }
                }
 
                /* Device speed */
-               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);
+               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);
                        spi_dev_put(spi);
                        continue;
                }
-               spi->max_speed_hz = be32_to_cpup(prop);
+               spi->max_speed_hz = value;
 
                /* IRQ */
                spi->irq = irq_of_parse_and_map(nc, 0);
@@ -956,9 +1078,7 @@ static void of_register_spi_devices(struct spi_master *master)
                spi->dev.of_node = nc;
 
                /* Register the new device */
-               snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX,
-                        spi->modalias);
-               request_module(modalias);
+               request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias);
                rc = spi_add_device(spi);
                if (rc) {
                        dev_err(&master->dev, "spi_device register error %s\n",
@@ -1038,7 +1158,7 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
        }
 
        adev->power.flags.ignore_parent = true;
-       strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
+       strlcpy(spi->modalias, acpi_device_hid(adev), 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",
@@ -1111,7 +1231,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;
 
@@ -1136,7 +1256,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(nb, (int)master->num_chipselect);
+       master->num_chipselect = max_t(int, nb, master->num_chipselect);
 
        /* Return error only for an incorrectly formed cs-gpios property */
        if (nb == 0 || nb == -ENOENT)
@@ -1223,6 +1343,7 @@ 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.
@@ -1259,6 +1380,41 @@ 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 != 0) {
+               *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));
@@ -1416,8 +1572,7 @@ 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, " : "",
@@ -1435,6 +1590,10 @@ 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)
@@ -1534,7 +1693,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
                }
        }
 
-       message->spi = spi;
        message->status = -EINPROGRESS;
        return master->transfer(spi, message);
 }
@@ -1776,7 +1934,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;
 
@@ -1825,7 +1983,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);
index ca5bcfe874d0afa3d01849c23b72a1c5d08846a2..d7c6e36021e884727f9bd0a7fc858d83824d441a 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spidev.h>
 
-#include <asm/uaccess.h>
+#include <linux/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,7 +629,6 @@ 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 */
index 74025fbae6794f3c5f6226efd1b137ef42ec450c..abfc8bd1794d03e4f89e75b1362b40a22d783f17 100644 (file)
@@ -86,7 +86,7 @@ static int ade7753_spi_read_reg_16(struct device *dev,
        struct ade7753_state *st = iio_priv(indio_dev);
        ssize_t ret;
 
-       ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address));
+       ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address));
        if (ret < 0) {
                dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
                        reg_address);
@@ -94,7 +94,6 @@ static int ade7753_spi_read_reg_16(struct device *dev,
        }
 
        *val = ret;
-       *val = be16_to_cpup(val);
 
        return 0;
 }
index f649ebe55a04d49da431c9c8ff5d45947d7e8ac7..3d1c02cd65384db7a9d6fa8e87eaa0542510e0db 100644 (file)
@@ -86,7 +86,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
        struct ade7754_state *st = iio_priv(indio_dev);
        int ret;
 
-       ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address));
+       ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address));
        if (ret < 0) {
                dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
                        reg_address);
@@ -94,7 +94,6 @@ static int ade7754_spi_read_reg_16(struct device *dev,
        }
 
        *val = ret;
-       *val = be16_to_cpup(val);
 
        return 0;
 }
index d214ac4932cbef428c4d414967146eb7c92cce4d..7467e51fd42497c4885a953b34e7e644358a5945 100644 (file)
@@ -86,7 +86,7 @@ static int ade7759_spi_read_reg_16(struct device *dev,
        struct ade7759_state *st = iio_priv(indio_dev);
        int ret;
 
-       ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address));
+       ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address));
        if (ret < 0) {
                dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
                        reg_address);
@@ -94,7 +94,6 @@ static int ade7759_spi_read_reg_16(struct device *dev,
        }
 
        *val = ret;
-       *val = be16_to_cpup(val);
 
        return 0;
 }
index 900f0e328235790d02f7a38147967b1cfc3631d2..a25bd6f65e7f7fd2a7d21bf4e909016aaeeac959 100644 (file)
@@ -26,6 +26,8 @@ struct rspi_plat_data {
        unsigned int dma_rx_id;
 
        unsigned dma_width_16bit:1;     /* DMAC read/write width = 16-bit */
+
+       u16 num_chipselect;
 };
 
 #endif
index 887116dbce2c8504fb7d56cf13565f47dd8c3c2a..8c62ba74dd91d9800439038d86298f2e2477f1fe 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/completion.h>
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -150,8 +151,7 @@ static inline void *spi_get_drvdata(struct spi_device *spi)
 }
 
 struct spi_message;
-
-
+struct spi_transfer;
 
 /**
  * struct spi_driver - Host side "protocol" driver
@@ -257,6 +257,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @queue_lock: spinlock to syncronise access to message queue
  * @queue: message queue
  * @cur_msg: the currently in-flight message
+ * @cur_msg_prepared: spi_prepare_message was called for the currently
+ *                    in-flight message
+ * @xfer_completion: used by core tranfer_one_message()
  * @busy: message pump is busy
  * @running: message pump is running
  * @rt: whether this queue is set to run as a realtime task
@@ -274,6 +277,16 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @unprepare_transfer_hardware: there are currently no more messages on the
  *     queue so the subsystem notifies the driver that it may relax the
  *     hardware by issuing this call
+ * @set_cs: assert or deassert chip select, true to assert.  May be called
+ *          from interrupt context.
+ * @prepare_message: set up the controller to transfer a single message,
+ *                   for example doing DMA mapping.  Called from threaded
+ *                   context.
+ * @transfer_one: transfer a single spi_transfer. When the
+ *               driver is finished with this transfer it must call
+ *               spi_finalize_current_transfer() so the subsystem can issue
+ *                the next transfer
+ * @unprepare_message: undo any work done by prepare_message().
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *     number. Any individual value may be -ENOENT for CS lines that
  *     are not GPIOs (driven by the SPI controller itself).
@@ -388,11 +401,25 @@ struct spi_master {
        bool                            running;
        bool                            rt;
        bool                            auto_runtime_pm;
+       bool                            cur_msg_prepared;
+       struct completion               xfer_completion;
 
        int (*prepare_transfer_hardware)(struct spi_master *master);
        int (*transfer_one_message)(struct spi_master *master,
                                    struct spi_message *mesg);
        int (*unprepare_transfer_hardware)(struct spi_master *master);
+       int (*prepare_message)(struct spi_master *master,
+                              struct spi_message *message);
+       int (*unprepare_message)(struct spi_master *master,
+                                struct spi_message *message);
+
+       /*
+        * These hooks are for drivers that use a generic implementation
+        * of transfer_one_message() provied by the core.
+        */
+       void (*set_cs)(struct spi_device *spi, bool enable);
+       int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
+                           struct spi_transfer *transfer);
 
        /* gpio chip select */
        int                     *cs_gpios;
@@ -428,12 +455,15 @@ extern int spi_master_resume(struct spi_master *master);
 /* Calls the driver make to interact with the message queue */
 extern struct spi_message *spi_get_next_queued_message(struct spi_master *master);
 extern void spi_finalize_current_message(struct spi_master *master);
+extern void spi_finalize_current_transfer(struct spi_master *master);
 
 /* the spi driver core manages memory for the spi_master classdev */
 extern struct spi_master *
 spi_alloc_master(struct device *host, unsigned size);
 
 extern int spi_register_master(struct spi_master *master);
+extern int devm_spi_register_master(struct device *dev,
+                                   struct spi_master *master);
 extern void spi_unregister_master(struct spi_master *master);
 
 extern struct spi_master *spi_busnum_to_master(u16 busnum);
@@ -823,6 +853,33 @@ static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)
        return (status < 0) ? status : result;
 }
 
+/**
+ * spi_w8r16be - SPI synchronous 8 bit write followed by 16 bit big-endian read
+ * @spi: device with which data will be exchanged
+ * @cmd: command to be written before data is read back
+ * Context: can sleep
+ *
+ * This returns the (unsigned) sixteen bit number returned by the device in cpu
+ * endianness, or else a negative error code. Callable only from contexts that
+ * can sleep.
+ *
+ * This function is similar to spi_w8r16, with the exception that it will
+ * convert the read 16 bit data word from big-endian to native endianness.
+ *
+ */
+static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd)
+
+{
+       ssize_t status;
+       __be16 result;
+
+       status = spi_write_then_read(spi, &cmd, 1, &result, 2);
+       if (status < 0)
+               return status;
+
+       return be16_to_cpu(result);
+}
+
 /*---------------------------------------------------------------------------*/
 
 /*
diff --git a/include/trace/events/spi.h b/include/trace/events/spi.h
new file mode 100644 (file)
index 0000000..7e02c98
--- /dev/null
@@ -0,0 +1,156 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spi
+
+#if !defined(_TRACE_SPI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPI_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(spi_master,
+
+       TP_PROTO(struct spi_master *master),
+
+       TP_ARGS(master),
+
+       TP_STRUCT__entry(
+               __field(        int,           bus_num             )
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = master->bus_num;
+       ),
+
+       TP_printk("spi%d", (int)__entry->bus_num)
+
+);
+
+DEFINE_EVENT(spi_master, spi_master_idle,
+
+       TP_PROTO(struct spi_master *master),
+
+       TP_ARGS(master)
+
+);
+
+DEFINE_EVENT(spi_master, spi_master_busy,
+
+       TP_PROTO(struct spi_master *master),
+
+       TP_ARGS(master)
+
+);
+
+DECLARE_EVENT_CLASS(spi_message,
+
+       TP_PROTO(struct spi_message *msg),
+
+       TP_ARGS(msg),
+
+       TP_STRUCT__entry(
+               __field(        int,            bus_num         )
+               __field(        int,            chip_select     )
+               __field(        struct spi_message *,   msg     )
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = msg->spi->master->bus_num;
+               __entry->chip_select = msg->spi->chip_select;
+               __entry->msg = msg;
+       ),
+
+        TP_printk("spi%d.%d %p", (int)__entry->bus_num,
+                 (int)__entry->chip_select,
+                 (struct spi_message *)__entry->msg)
+);
+
+DEFINE_EVENT(spi_message, spi_message_submit,
+
+       TP_PROTO(struct spi_message *msg),
+
+       TP_ARGS(msg)
+
+);
+
+DEFINE_EVENT(spi_message, spi_message_start,
+
+       TP_PROTO(struct spi_message *msg),
+
+       TP_ARGS(msg)
+
+);
+
+TRACE_EVENT(spi_message_done,
+
+       TP_PROTO(struct spi_message *msg),
+
+       TP_ARGS(msg),
+
+       TP_STRUCT__entry(
+               __field(        int,            bus_num         )
+               __field(        int,            chip_select     )
+               __field(        struct spi_message *,   msg     )
+               __field(        unsigned,       frame           )
+               __field(        unsigned,       actual          )
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = msg->spi->master->bus_num;
+               __entry->chip_select = msg->spi->chip_select;
+               __entry->msg = msg;
+               __entry->frame = msg->frame_length;
+               __entry->actual = msg->actual_length;
+       ),
+
+        TP_printk("spi%d.%d %p len=%u/%u", (int)__entry->bus_num,
+                 (int)__entry->chip_select,
+                 (struct spi_message *)__entry->msg,
+                  (unsigned)__entry->actual, (unsigned)__entry->frame)
+);
+
+DECLARE_EVENT_CLASS(spi_transfer,
+
+       TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+       TP_ARGS(msg, xfer),
+
+       TP_STRUCT__entry(
+               __field(        int,            bus_num         )
+               __field(        int,            chip_select     )
+               __field(        struct spi_transfer *,   xfer   )
+               __field(        int,            len             )
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = msg->spi->master->bus_num;
+               __entry->chip_select = msg->spi->chip_select;
+               __entry->xfer = xfer;
+               __entry->len = xfer->len;
+       ),
+
+        TP_printk("spi%d.%d %p len=%d", (int)__entry->bus_num,
+                 (int)__entry->chip_select,
+                 (struct spi_message *)__entry->xfer,
+                 (int)__entry->len)
+);
+
+DEFINE_EVENT(spi_transfer, spi_transfer_start,
+
+       TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+       TP_ARGS(msg, xfer)
+
+);
+
+DEFINE_EVENT(spi_transfer, spi_transfer_stop,
+
+       TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+       TP_ARGS(msg, xfer)
+
+);
+
+#endif /* _TRACE_POWER_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>