aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-omap2-mcspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r--drivers/spi/spi-omap2-mcspi.c51
1 files changed, 32 insertions, 19 deletions
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