From 2856ac13b8ab41a17b1c65e4eed51543e55f4bac Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Fri, 28 Oct 2011 17:14:17 +0530 Subject: spi/omap: Use a workqueue per omap2_mcspi controller Currently all the spi controllers share the work queue. This patch allocates a work queue per controller. Signed-off-by: Steve Wilkins Signed-off-by: Shubhrajyoti D Signed-off-by: Grant Likely --- drivers/spi/spi-omap2-mcspi.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 322be7aea8b..0192d1b79ca 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -121,6 +121,7 @@ struct omap2_mcspi { /* SPI1 has 4 channels, while SPI2 has 2 */ struct omap2_mcspi_dma *dma_channels; struct device *dev; + struct workqueue_struct *wq; }; struct omap2_mcspi_cs { @@ -143,8 +144,6 @@ struct omap2_mcspi_regs { static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; -static struct workqueue_struct *omap2_mcspi_wq; - #define MOD_REG_BIT(val, mask, set) do { \ if (set) \ val |= mask; \ @@ -1043,7 +1042,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) spin_lock_irqsave(&mcspi->lock, flags); list_add_tail(&m->queue, &mcspi->msg_queue); - queue_work(omap2_mcspi_wq, &mcspi->work); + queue_work(mcspi->wq, &mcspi->work); spin_unlock_irqrestore(&mcspi->lock, flags); return 0; @@ -1088,6 +1087,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) struct omap2_mcspi *mcspi; struct resource *r; int status = 0, i; + char wq_name[20]; master = spi_alloc_master(&pdev->dev, sizeof *mcspi); if (master == NULL) { @@ -1111,6 +1111,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) mcspi = spi_master_get_devdata(master); mcspi->master = master; + sprintf(wq_name, "omap2_mcspi/%d", master->bus_num); + mcspi->wq = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 1); + if (mcspi->wq == NULL) { + status = -ENOMEM; + goto err1; + } + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { status = -ENODEV; @@ -1217,6 +1224,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) spi_unregister_master(master); iounmap(base); kfree(dma_channels); + destroy_workqueue(mcspi->wq); return 0; } @@ -1275,10 +1283,6 @@ static struct platform_driver omap2_mcspi_driver = { static int __init omap2_mcspi_init(void) { - omap2_mcspi_wq = create_singlethread_workqueue( - omap2_mcspi_driver.driver.name); - if (omap2_mcspi_wq == NULL) - return -1; return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe); } subsys_initcall(omap2_mcspi_init); @@ -1287,7 +1291,6 @@ static void __exit omap2_mcspi_exit(void) { platform_driver_unregister(&omap2_mcspi_driver); - destroy_workqueue(omap2_mcspi_wq); } module_exit(omap2_mcspi_exit); -- cgit v1.2.3 From 751c925cbb3a270f9771e3945494cb44bd9e732a Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Fri, 28 Oct 2011 17:14:18 +0530 Subject: spi/omap: call pm_runtime_disable in error path and remove omap mcspi probe() doesnt call pm_runtime disable functions in case of failure. remove() doesnt call pm_runtime disable. This could lead to warnings as below on subsequent insmod. ~# insmod spi-omap2-mcspi.ko [ 255.383671] omap2_mcspi omap2_mcspi.1: Unbalanced pm_runtime_enable! ... This patch adds the pm_runtime disable() at appropriate stages. Signed-off-by: Hebbar, Gururaja Signed-off-by: Shubhrajyoti D Signed-off-by: Grant Likely --- drivers/spi/spi-omap2-mcspi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 0192d1b79ca..22e17264a20 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1196,6 +1196,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) err4: spi_master_put(master); err3: + pm_runtime_disable(&pdev->dev); kfree(mcspi->dma_channels); err2: release_mem_region(r->start, resource_size(r)); @@ -1217,6 +1218,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) dma_channels = mcspi->dma_channels; omap2_mcspi_disable_clocks(mcspi); + pm_runtime_disable(&pdev->dev); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(r->start, resource_size(r)); -- cgit v1.2.3 From 39f1b56593293a3d1d3b49b97a59337a19fef053 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Fri, 28 Oct 2011 17:14:19 +0530 Subject: spi/omap: Correct the error path Currently McSPI driver doesnt follow correct failure fallback steps attempting to correct the same. Also: - label names changed to give meaningful names. - Setting the driver data to NULL in remove Signed-off-by: Hebbar, Gururaja Signed-off-by: Shubhrajyoti D Signed-off-by: Grant Likely --- drivers/spi/spi-omap2-mcspi.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 22e17264a20..0b0dfb71c64 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1115,13 +1115,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) mcspi->wq = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 1); if (mcspi->wq == NULL) { status = -ENOMEM; - goto err1; + goto free_master; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { status = -ENODEV; - goto err1; + goto free_master; } r->start += pdata->regs_offset; @@ -1130,14 +1130,14 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) if (!request_mem_region(r->start, resource_size(r), dev_name(&pdev->dev))) { status = -EBUSY; - goto err1; + goto free_master; } mcspi->base = ioremap(r->start, resource_size(r)); if (!mcspi->base) { dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); status = -ENOMEM; - goto err2; + goto release_region; } mcspi->dev = &pdev->dev; @@ -1152,7 +1152,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) GFP_KERNEL); if (mcspi->dma_channels == NULL) - goto err2; + goto unmap_io; for (i = 0; i < master->num_chipselect; i++) { char dma_ch_name[14]; @@ -1182,26 +1182,33 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; } + if (status < 0) + goto dma_chnl_free; + pm_runtime_enable(&pdev->dev); if (status || omap2_mcspi_master_setup(mcspi) < 0) - goto err3; + goto disable_pm; status = spi_register_master(master); if (status < 0) - goto err4; + goto err_spi_register; return status; -err4: +err_spi_register: spi_master_put(master); -err3: +disable_pm: pm_runtime_disable(&pdev->dev); +dma_chnl_free: kfree(mcspi->dma_channels); -err2: - release_mem_region(r->start, resource_size(r)); +unmap_io: iounmap(mcspi->base); -err1: +release_region: + release_mem_region(r->start, resource_size(r)); +free_master: + kfree(master); + platform_set_drvdata(pdev, NULL); return status; } @@ -1227,6 +1234,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) iounmap(base); kfree(dma_channels); destroy_workqueue(mcspi->wq); + platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.2.3 From 92b3a5c1bc3c7da1ae4675d014124f4a97ddb632 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 28 Oct 2011 09:35:21 +0900 Subject: spi-topcliff-pch: Support new device LAPIS Semiconductor ML7831 IOH ML7831 is companion chip for Intel Atom E6xx series. Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/Kconfig | 6 +++--- drivers/spi/spi-topcliff-pch.c | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 52e2900d9d8..b02920a6e97 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -346,14 +346,14 @@ config SPI_TI_SSP serial port. config SPI_TOPCLIFF_PCH - tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH SPI controller" + tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" depends on PCI help SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus used in some x86 embedded processors. - This driver also supports the ML7213, a companion chip for the - Atom E6xx series and compatible with the Intel EG20T PCH. + This driver also supports the ML7213/ML7223/ML7831, a companion chip + for the Atom E6xx series and compatible with the Intel EG20T PCH. config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 6a80749391d..2b1e96643d7 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -95,16 +95,18 @@ #define PCH_CLOCK_HZ 50000000 #define PCH_MAX_SPBR 1023 -/* Definition for ML7213 by OKI SEMICONDUCTOR */ +/* Definition for ML7213/ML7831 by OKI SEMICONDUCTOR */ #define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_DEVICE_ID_ML7213_SPI 0x802c #define PCI_DEVICE_ID_ML7223_SPI 0x800F +#define PCI_DEVICE_ID_ML7831_SPI 0x8816 /* * Set the number of SPI instance max * Intel EG20T PCH : 1ch * OKI SEMICONDUCTOR ML7213 IOH : 2ch * OKI SEMICONDUCTOR ML7223 IOH : 1ch + * OKI SEMICONDUCTOR ML7831 IOH : 1ch */ #define PCH_SPI_MAX_DEV 2 @@ -218,6 +220,7 @@ static struct pci_device_id pch_spi_pcidev_id[] = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, + { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_SPI), 1, }, { } }; -- cgit v1.2.3 From 2b246283277862c4866a005852af5c70fd581824 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 28 Oct 2011 09:35:22 +0900 Subject: spi-topcliff-pch: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor On October 1 in 2011, OKI SEMICONDUCTOR Co., Ltd. changed the company name in to LAPIS Semiconductor Co., Ltd. Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 2b1e96643d7..7086583b910 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1,7 +1,7 @@ /* * SPI bus driver for the Topcliff PCH used by Intel SoCs * - * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -95,7 +95,7 @@ #define PCH_CLOCK_HZ 50000000 #define PCH_MAX_SPBR 1023 -/* Definition for ML7213/ML7831 by OKI SEMICONDUCTOR */ +/* Definition for ML7213/ML7223/ML7831 by LAPIS Semiconductor */ #define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_DEVICE_ID_ML7213_SPI 0x802c #define PCI_DEVICE_ID_ML7223_SPI 0x800F @@ -104,9 +104,9 @@ /* * Set the number of SPI instance max * Intel EG20T PCH : 1ch - * OKI SEMICONDUCTOR ML7213 IOH : 2ch - * OKI SEMICONDUCTOR ML7223 IOH : 1ch - * OKI SEMICONDUCTOR ML7831 IOH : 1ch + * LAPIS Semiconductor ML7213 IOH : 2ch + * LAPIS Semiconductor ML7223 IOH : 1ch + * LAPIS Semiconductor ML7831 IOH : 1ch */ #define PCH_SPI_MAX_DEV 2 @@ -1756,4 +1756,4 @@ MODULE_PARM_DESC(use_dma, "to use DMA for data transfers pass 1 else 0; default 1"); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7xxx IOH SPI Driver"); +MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor ML7xxx IOH SPI Driver"); -- cgit v1.2.3