aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-07 15:16:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-07 15:16:27 -0500
commit2d51daaa615e4724f24e43fa01e705c40551080a (patch)
tree3596123890aae2645a189a75bdf45789e89ae2d9
parentfbce1c234feedb5270468aa4b1770c1cab58a960 (diff)
parente583685e998e52ebbf31fadf7d8470ae69951660 (diff)
Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6
spi changes queued up for v3.3 merge window * tag 'spi-for-linus-20120104' of git://git.secretlab.ca/git/linux-2.6: spi: Fix device unregistration when unregistering the bus master spi-topcliff-pch: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor spi-topcliff-pch: Support new device LAPIS Semiconductor ML7831 IOH spi/omap: Correct the error path spi/omap: call pm_runtime_disable in error path and remove spi/omap: Use a workqueue per omap2_mcspi controller
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--drivers/spi/spi-omap2-mcspi.c51
-rw-r--r--drivers/spi/spi-topcliff-pch.c13
-rw-r--r--drivers/spi/spi.c2
4 files changed, 44 insertions, 28 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8ba4510a9519..7587796224c8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -346,14 +346,14 @@ config SPI_TI_SSP
346 serial port. 346 serial port.
347 347
348config SPI_TOPCLIFF_PCH 348config SPI_TOPCLIFF_PCH
349 tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH SPI controller" 349 tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI"
350 depends on PCI 350 depends on PCI
351 help 351 help
352 SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus 352 SPI driver for the Topcliff PCH (Platform Controller Hub) SPI bus
353 used in some x86 embedded processors. 353 used in some x86 embedded processors.
354 354
355 This driver also supports the ML7213, a companion chip for the 355 This driver also supports the ML7213/ML7223/ML7831, a companion chip
356 Atom E6xx series and compatible with the Intel EG20T PCH. 356 for the Atom E6xx series and compatible with the Intel EG20T PCH.
357 357
358config SPI_TXX9 358config SPI_TXX9
359 tristate "Toshiba TXx9 SPI controller" 359 tristate "Toshiba TXx9 SPI controller"
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 322be7aea8b4..0b0dfb71c640 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -121,6 +121,7 @@ struct omap2_mcspi {
121 /* SPI1 has 4 channels, while SPI2 has 2 */ 121 /* SPI1 has 4 channels, while SPI2 has 2 */
122 struct omap2_mcspi_dma *dma_channels; 122 struct omap2_mcspi_dma *dma_channels;
123 struct device *dev; 123 struct device *dev;
124 struct workqueue_struct *wq;
124}; 125};
125 126
126struct omap2_mcspi_cs { 127struct omap2_mcspi_cs {
@@ -143,8 +144,6 @@ struct omap2_mcspi_regs {
143 144
144static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; 145static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
145 146
146static struct workqueue_struct *omap2_mcspi_wq;
147
148#define MOD_REG_BIT(val, mask, set) do { \ 147#define MOD_REG_BIT(val, mask, set) do { \
149 if (set) \ 148 if (set) \
150 val |= mask; \ 149 val |= mask; \
@@ -1043,7 +1042,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
1043 1042
1044 spin_lock_irqsave(&mcspi->lock, flags); 1043 spin_lock_irqsave(&mcspi->lock, flags);
1045 list_add_tail(&m->queue, &mcspi->msg_queue); 1044 list_add_tail(&m->queue, &mcspi->msg_queue);
1046 queue_work(omap2_mcspi_wq, &mcspi->work); 1045 queue_work(mcspi->wq, &mcspi->work);
1047 spin_unlock_irqrestore(&mcspi->lock, flags); 1046 spin_unlock_irqrestore(&mcspi->lock, flags);
1048 1047
1049 return 0; 1048 return 0;
@@ -1088,6 +1087,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1088 struct omap2_mcspi *mcspi; 1087 struct omap2_mcspi *mcspi;
1089 struct resource *r; 1088 struct resource *r;
1090 int status = 0, i; 1089 int status = 0, i;
1090 char wq_name[20];
1091 1091
1092 master = spi_alloc_master(&pdev->dev, sizeof *mcspi); 1092 master = spi_alloc_master(&pdev->dev, sizeof *mcspi);
1093 if (master == NULL) { 1093 if (master == NULL) {
@@ -1111,10 +1111,17 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1111 mcspi = spi_master_get_devdata(master); 1111 mcspi = spi_master_get_devdata(master);
1112 mcspi->master = master; 1112 mcspi->master = master;
1113 1113
1114 sprintf(wq_name, "omap2_mcspi/%d", master->bus_num);
1115 mcspi->wq = alloc_workqueue(wq_name, WQ_MEM_RECLAIM, 1);
1116 if (mcspi->wq == NULL) {
1117 status = -ENOMEM;
1118 goto free_master;
1119 }
1120
1114 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1121 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1115 if (r == NULL) { 1122 if (r == NULL) {
1116 status = -ENODEV; 1123 status = -ENODEV;
1117 goto err1; 1124 goto free_master;
1118 } 1125 }
1119 1126
1120 r->start += pdata->regs_offset; 1127 r->start += pdata->regs_offset;
@@ -1123,14 +1130,14 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1123 if (!request_mem_region(r->start, resource_size(r), 1130 if (!request_mem_region(r->start, resource_size(r),
1124 dev_name(&pdev->dev))) { 1131 dev_name(&pdev->dev))) {
1125 status = -EBUSY; 1132 status = -EBUSY;
1126 goto err1; 1133 goto free_master;
1127 } 1134 }
1128 1135
1129 mcspi->base = ioremap(r->start, resource_size(r)); 1136 mcspi->base = ioremap(r->start, resource_size(r));
1130 if (!mcspi->base) { 1137 if (!mcspi->base) {
1131 dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); 1138 dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
1132 status = -ENOMEM; 1139 status = -ENOMEM;
1133 goto err2; 1140 goto release_region;
1134 } 1141 }
1135 1142
1136 mcspi->dev = &pdev->dev; 1143 mcspi->dev = &pdev->dev;
@@ -1145,7 +1152,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1145 GFP_KERNEL); 1152 GFP_KERNEL);
1146 1153
1147 if (mcspi->dma_channels == NULL) 1154 if (mcspi->dma_channels == NULL)
1148 goto err2; 1155 goto unmap_io;
1149 1156
1150 for (i = 0; i < master->num_chipselect; i++) { 1157 for (i = 0; i < master->num_chipselect; i++) {
1151 char dma_ch_name[14]; 1158 char dma_ch_name[14];
@@ -1175,25 +1182,33 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
1175 mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; 1182 mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
1176 } 1183 }
1177 1184
1185 if (status < 0)
1186 goto dma_chnl_free;
1187
1178 pm_runtime_enable(&pdev->dev); 1188 pm_runtime_enable(&pdev->dev);
1179 1189
1180 if (status || omap2_mcspi_master_setup(mcspi) < 0) 1190 if (status || omap2_mcspi_master_setup(mcspi) < 0)
1181 goto err3; 1191 goto disable_pm;
1182 1192
1183 status = spi_register_master(master); 1193 status = spi_register_master(master);
1184 if (status < 0) 1194 if (status < 0)
1185 goto err4; 1195 goto err_spi_register;
1186 1196
1187 return status; 1197 return status;
1188 1198
1189err4: 1199err_spi_register:
1190 spi_master_put(master); 1200 spi_master_put(master);
1191err3: 1201disable_pm:
1202 pm_runtime_disable(&pdev->dev);
1203dma_chnl_free:
1192 kfree(mcspi->dma_channels); 1204 kfree(mcspi->dma_channels);
1193err2: 1205unmap_io:
1194 release_mem_region(r->start, resource_size(r));
1195 iounmap(mcspi->base); 1206 iounmap(mcspi->base);
1196err1: 1207release_region:
1208 release_mem_region(r->start, resource_size(r));
1209free_master:
1210 kfree(master);
1211 platform_set_drvdata(pdev, NULL);
1197 return status; 1212 return status;
1198} 1213}
1199 1214
@@ -1210,6 +1225,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
1210 dma_channels = mcspi->dma_channels; 1225 dma_channels = mcspi->dma_channels;
1211 1226
1212 omap2_mcspi_disable_clocks(mcspi); 1227 omap2_mcspi_disable_clocks(mcspi);
1228 pm_runtime_disable(&pdev->dev);
1213 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1229 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1214 release_mem_region(r->start, resource_size(r)); 1230 release_mem_region(r->start, resource_size(r));
1215 1231
@@ -1217,6 +1233,8 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
1217 spi_unregister_master(master); 1233 spi_unregister_master(master);
1218 iounmap(base); 1234 iounmap(base);
1219 kfree(dma_channels); 1235 kfree(dma_channels);
1236 destroy_workqueue(mcspi->wq);
1237 platform_set_drvdata(pdev, NULL);
1220 1238
1221 return 0; 1239 return 0;
1222} 1240}
@@ -1275,10 +1293,6 @@ static struct platform_driver omap2_mcspi_driver = {
1275 1293
1276static int __init omap2_mcspi_init(void) 1294static int __init omap2_mcspi_init(void)
1277{ 1295{
1278 omap2_mcspi_wq = create_singlethread_workqueue(
1279 omap2_mcspi_driver.driver.name);
1280 if (omap2_mcspi_wq == NULL)
1281 return -1;
1282 return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe); 1296 return platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe);
1283} 1297}
1284subsys_initcall(omap2_mcspi_init); 1298subsys_initcall(omap2_mcspi_init);
@@ -1287,7 +1301,6 @@ static void __exit omap2_mcspi_exit(void)
1287{ 1301{
1288 platform_driver_unregister(&omap2_mcspi_driver); 1302 platform_driver_unregister(&omap2_mcspi_driver);
1289 1303
1290 destroy_workqueue(omap2_mcspi_wq);
1291} 1304}
1292module_exit(omap2_mcspi_exit); 1305module_exit(omap2_mcspi_exit);
1293 1306
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 6a80749391db..7086583b9107 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SPI bus driver for the Topcliff PCH used by Intel SoCs 2 * SPI bus driver for the Topcliff PCH used by Intel SoCs
3 * 3 *
4 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. 4 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -95,16 +95,18 @@
95#define PCH_CLOCK_HZ 50000000 95#define PCH_CLOCK_HZ 50000000
96#define PCH_MAX_SPBR 1023 96#define PCH_MAX_SPBR 1023
97 97
98/* Definition for ML7213 by OKI SEMICONDUCTOR */ 98/* Definition for ML7213/ML7223/ML7831 by LAPIS Semiconductor */
99#define PCI_VENDOR_ID_ROHM 0x10DB 99#define PCI_VENDOR_ID_ROHM 0x10DB
100#define PCI_DEVICE_ID_ML7213_SPI 0x802c 100#define PCI_DEVICE_ID_ML7213_SPI 0x802c
101#define PCI_DEVICE_ID_ML7223_SPI 0x800F 101#define PCI_DEVICE_ID_ML7223_SPI 0x800F
102#define PCI_DEVICE_ID_ML7831_SPI 0x8816
102 103
103/* 104/*
104 * Set the number of SPI instance max 105 * Set the number of SPI instance max
105 * Intel EG20T PCH : 1ch 106 * Intel EG20T PCH : 1ch
106 * OKI SEMICONDUCTOR ML7213 IOH : 2ch 107 * LAPIS Semiconductor ML7213 IOH : 2ch
107 * OKI SEMICONDUCTOR ML7223 IOH : 1ch 108 * LAPIS Semiconductor ML7223 IOH : 1ch
109 * LAPIS Semiconductor ML7831 IOH : 1ch
108*/ 110*/
109#define PCH_SPI_MAX_DEV 2 111#define PCH_SPI_MAX_DEV 2
110 112
@@ -218,6 +220,7 @@ static struct pci_device_id pch_spi_pcidev_id[] = {
218 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, }, 220 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, },
219 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, }, 221 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
220 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, 222 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, },
223 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_SPI), 1, },
221 { } 224 { }
222}; 225};
223 226
@@ -1753,4 +1756,4 @@ MODULE_PARM_DESC(use_dma,
1753 "to use DMA for data transfers pass 1 else 0; default 1"); 1756 "to use DMA for data transfers pass 1 else 0; default 1");
1754 1757
1755MODULE_LICENSE("GPL"); 1758MODULE_LICENSE("GPL");
1756MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7xxx IOH SPI Driver"); 1759MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor ML7xxx IOH SPI Driver");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 77eae99af11c..b2ccdea30cb9 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -319,7 +319,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)
319 } 319 }
320 320
321 spi->master = master; 321 spi->master = master;
322 spi->dev.parent = dev; 322 spi->dev.parent = &master->dev;
323 spi->dev.bus = &spi_bus_type; 323 spi->dev.bus = &spi_bus_type;
324 spi->dev.release = spidev_release; 324 spi->dev.release = spidev_release;
325 device_initialize(&spi->dev); 325 device_initialize(&spi->dev);