aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
commit908cf4b925e419bc74f3297b2f0e51d6f8a81da2 (patch)
tree6c2da79366d4695a9c2560ab18259eca8a2a25b4 /drivers/spi
parent92c49890922d54cba4b1eadeb0b185773c2c9570 (diff)
parent14b395e35d1afdd8019d11b92e28041fad591b71 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/spi_imx.c54
-rw-r--r--drivers/spi/spidev.c179
3 files changed, 167 insertions, 68 deletions
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 681d62325d3d..604e5f0a2d95 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -17,7 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18 18
19#if defined(CONFIG_PPC_MERGE) 19#if defined(CONFIG_PPC_MERGE)
20#include <asm/of_platform.h> 20#include <linux/of_platform.h>
21#else 21#else
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#endif 23#endif
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index c730d05bfeb6..54ac7bea5f8c 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -29,6 +29,7 @@
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/clk.h>
32 33
33#include <asm/io.h> 34#include <asm/io.h>
34#include <asm/irq.h> 35#include <asm/irq.h>
@@ -250,6 +251,8 @@ struct driver_data {
250 int tx_dma_needs_unmap; 251 int tx_dma_needs_unmap;
251 size_t tx_map_len; 252 size_t tx_map_len;
252 u32 dummy_dma_buf ____cacheline_aligned; 253 u32 dummy_dma_buf ____cacheline_aligned;
254
255 struct clk *clk;
253}; 256};
254 257
255/* Runtime state */ 258/* Runtime state */
@@ -855,15 +858,15 @@ static irqreturn_t spi_int(int irq, void *dev_id)
855 return drv_data->transfer_handler(drv_data); 858 return drv_data->transfer_handler(drv_data);
856} 859}
857 860
858static inline u32 spi_speed_hz(u32 data_rate) 861static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate)
859{ 862{
860 return imx_get_perclk2() / (4 << ((data_rate) >> 13)); 863 return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13));
861} 864}
862 865
863static u32 spi_data_rate(u32 speed_hz) 866static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz)
864{ 867{
865 u32 div; 868 u32 div;
866 u32 quantized_hz = imx_get_perclk2() >> 2; 869 u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2;
867 870
868 for (div = SPI_PERCLK2_DIV_MIN; 871 for (div = SPI_PERCLK2_DIV_MIN;
869 div <= SPI_PERCLK2_DIV_MAX; 872 div <= SPI_PERCLK2_DIV_MAX;
@@ -947,7 +950,7 @@ static void pump_transfers(unsigned long data)
947 tmp = transfer->speed_hz; 950 tmp = transfer->speed_hz;
948 if (tmp == 0) 951 if (tmp == 0)
949 tmp = chip->max_speed_hz; 952 tmp = chip->max_speed_hz;
950 tmp = spi_data_rate(tmp); 953 tmp = spi_data_rate(drv_data, tmp);
951 u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); 954 u32_EDIT(control, SPI_CONTROL_DATARATE, tmp);
952 955
953 writel(control, regs + SPI_CONTROL); 956 writel(control, regs + SPI_CONTROL);
@@ -1109,7 +1112,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
1109 msg->actual_length = 0; 1112 msg->actual_length = 0;
1110 1113
1111 /* Per transfer setup check */ 1114 /* Per transfer setup check */
1112 min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN); 1115 min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN);
1113 max_speed_hz = spi->max_speed_hz; 1116 max_speed_hz = spi->max_speed_hz;
1114 list_for_each_entry(trans, &msg->transfers, transfer_list) { 1117 list_for_each_entry(trans, &msg->transfers, transfer_list) {
1115 tmp = trans->bits_per_word; 1118 tmp = trans->bits_per_word;
@@ -1176,6 +1179,7 @@ msg_rejected:
1176 applied and notified to the calling driver. */ 1179 applied and notified to the calling driver. */
1177static int setup(struct spi_device *spi) 1180static int setup(struct spi_device *spi)
1178{ 1181{
1182 struct driver_data *drv_data = spi_master_get_devdata(spi->master);
1179 struct spi_imx_chip *chip_info; 1183 struct spi_imx_chip *chip_info;
1180 struct chip_data *chip; 1184 struct chip_data *chip;
1181 int first_setup = 0; 1185 int first_setup = 0;
@@ -1304,14 +1308,14 @@ static int setup(struct spi_device *spi)
1304 chip->n_bytes = (tmp <= 8) ? 1 : 2; 1308 chip->n_bytes = (tmp <= 8) ? 1 : 2;
1305 1309
1306 /* SPI datarate */ 1310 /* SPI datarate */
1307 tmp = spi_data_rate(spi->max_speed_hz); 1311 tmp = spi_data_rate(drv_data, spi->max_speed_hz);
1308 if (tmp == SPI_CONTROL_DATARATE_BAD) { 1312 if (tmp == SPI_CONTROL_DATARATE_BAD) {
1309 status = -EINVAL; 1313 status = -EINVAL;
1310 dev_err(&spi->dev, 1314 dev_err(&spi->dev,
1311 "setup - " 1315 "setup - "
1312 "HW min speed (%d Hz) exceeds required " 1316 "HW min speed (%d Hz) exceeds required "
1313 "max speed (%d Hz)\n", 1317 "max speed (%d Hz)\n",
1314 spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1318 spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN),
1315 spi->max_speed_hz); 1319 spi->max_speed_hz);
1316 if (first_setup) 1320 if (first_setup)
1317 goto err_first_setup; 1321 goto err_first_setup;
@@ -1321,7 +1325,7 @@ static int setup(struct spi_device *spi)
1321 } else { 1325 } else {
1322 u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); 1326 u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp);
1323 /* Actual rounded max_speed_hz */ 1327 /* Actual rounded max_speed_hz */
1324 tmp = spi_speed_hz(tmp); 1328 tmp = spi_speed_hz(drv_data, tmp);
1325 spi->max_speed_hz = tmp; 1329 spi->max_speed_hz = tmp;
1326 chip->max_speed_hz = tmp; 1330 chip->max_speed_hz = tmp;
1327 } 1331 }
@@ -1352,7 +1356,7 @@ static int setup(struct spi_device *spi)
1352 chip->period & SPI_PERIOD_WAIT, 1356 chip->period & SPI_PERIOD_WAIT,
1353 spi->mode, 1357 spi->mode,
1354 spi->bits_per_word, 1358 spi->bits_per_word,
1355 spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1359 spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN),
1356 spi->max_speed_hz); 1360 spi->max_speed_hz);
1357 return status; 1361 return status;
1358 1362
@@ -1465,6 +1469,14 @@ static int __init spi_imx_probe(struct platform_device *pdev)
1465 goto err_no_pdata; 1469 goto err_no_pdata;
1466 } 1470 }
1467 1471
1472 drv_data->clk = clk_get(&pdev->dev, "perclk2");
1473 if (IS_ERR(drv_data->clk)) {
1474 dev_err(&pdev->dev, "probe - cannot get get\n");
1475 status = PTR_ERR(drv_data->clk);
1476 goto err_no_clk;
1477 }
1478 clk_enable(drv_data->clk);
1479
1468 /* Allocate master with space for drv_data */ 1480 /* Allocate master with space for drv_data */
1469 master = spi_alloc_master(dev, sizeof(struct driver_data)); 1481 master = spi_alloc_master(dev, sizeof(struct driver_data));
1470 if (!master) { 1482 if (!master) {
@@ -1526,24 +1538,24 @@ static int __init spi_imx_probe(struct platform_device *pdev)
1526 drv_data->rx_channel = -1; 1538 drv_data->rx_channel = -1;
1527 if (platform_info->enable_dma) { 1539 if (platform_info->enable_dma) {
1528 /* Get rx DMA channel */ 1540 /* Get rx DMA channel */
1529 status = imx_dma_request_by_prio(&drv_data->rx_channel, 1541 drv_data->rx_channel = imx_dma_request_by_prio("spi_imx_rx",
1530 "spi_imx_rx", DMA_PRIO_HIGH); 1542 DMA_PRIO_HIGH);
1531 if (status < 0) { 1543 if (drv_data->rx_channel < 0) {
1532 dev_err(dev, 1544 dev_err(dev,
1533 "probe - problem (%d) requesting rx channel\n", 1545 "probe - problem (%d) requesting rx channel\n",
1534 status); 1546 drv_data->rx_channel);
1535 goto err_no_rxdma; 1547 goto err_no_rxdma;
1536 } else 1548 } else
1537 imx_dma_setup_handlers(drv_data->rx_channel, NULL, 1549 imx_dma_setup_handlers(drv_data->rx_channel, NULL,
1538 dma_err_handler, drv_data); 1550 dma_err_handler, drv_data);
1539 1551
1540 /* Get tx DMA channel */ 1552 /* Get tx DMA channel */
1541 status = imx_dma_request_by_prio(&drv_data->tx_channel, 1553 drv_data->tx_channel = imx_dma_request_by_prio("spi_imx_tx",
1542 "spi_imx_tx", DMA_PRIO_MEDIUM); 1554 DMA_PRIO_MEDIUM);
1543 if (status < 0) { 1555 if (drv_data->tx_channel < 0) {
1544 dev_err(dev, 1556 dev_err(dev,
1545 "probe - problem (%d) requesting tx channel\n", 1557 "probe - problem (%d) requesting tx channel\n",
1546 status); 1558 drv_data->tx_channel);
1547 imx_dma_free(drv_data->rx_channel); 1559 imx_dma_free(drv_data->rx_channel);
1548 goto err_no_txdma; 1560 goto err_no_txdma;
1549 } else 1561 } else
@@ -1623,6 +1635,9 @@ err_no_iores:
1623 spi_master_put(master); 1635 spi_master_put(master);
1624 1636
1625err_no_pdata: 1637err_no_pdata:
1638 clk_disable(drv_data->clk);
1639 clk_put(drv_data->clk);
1640err_no_clk:
1626err_no_mem: 1641err_no_mem:
1627 return status; 1642 return status;
1628} 1643}
@@ -1662,6 +1677,9 @@ static int __exit spi_imx_remove(struct platform_device *pdev)
1662 if (irq >= 0) 1677 if (irq >= 0)
1663 free_irq(irq, drv_data); 1678 free_irq(irq, drv_data);
1664 1679
1680 clk_disable(drv_data->clk);
1681 clk_put(drv_data->clk);
1682
1665 /* Release map resources */ 1683 /* Release map resources */
1666 iounmap(drv_data->regs); 1684 iounmap(drv_data->regs);
1667 release_resource(drv_data->ioarea); 1685 release_resource(drv_data->ioarea);
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index b3518ca9f04e..ddbe1a5e970e 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -25,10 +25,12 @@
25#include <linux/ioctl.h> 25#include <linux/ioctl.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/err.h>
28#include <linux/list.h> 29#include <linux/list.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
30#include <linux/mutex.h> 31#include <linux/mutex.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/smp_lock.h>
32 34
33#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
34#include <linux/spi/spidev.h> 36#include <linux/spi/spidev.h>
@@ -67,10 +69,12 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG];
67 | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) 69 | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP)
68 70
69struct spidev_data { 71struct spidev_data {
70 struct device dev; 72 dev_t devt;
73 spinlock_t spi_lock;
71 struct spi_device *spi; 74 struct spi_device *spi;
72 struct list_head device_entry; 75 struct list_head device_entry;
73 76
77 /* buffer is NULL unless this device is open (users > 0) */
74 struct mutex buf_lock; 78 struct mutex buf_lock;
75 unsigned users; 79 unsigned users;
76 u8 *buffer; 80 u8 *buffer;
@@ -85,12 +89,75 @@ MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
85 89
86/*-------------------------------------------------------------------------*/ 90/*-------------------------------------------------------------------------*/
87 91
92/*
93 * We can't use the standard synchronous wrappers for file I/O; we
94 * need to protect against async removal of the underlying spi_device.
95 */
96static void spidev_complete(void *arg)
97{
98 complete(arg);
99}
100
101static ssize_t
102spidev_sync(struct spidev_data *spidev, struct spi_message *message)
103{
104 DECLARE_COMPLETION_ONSTACK(done);
105 int status;
106
107 message->complete = spidev_complete;
108 message->context = &done;
109
110 spin_lock_irq(&spidev->spi_lock);
111 if (spidev->spi == NULL)
112 status = -ESHUTDOWN;
113 else
114 status = spi_async(spidev->spi, message);
115 spin_unlock_irq(&spidev->spi_lock);
116
117 if (status == 0) {
118 wait_for_completion(&done);
119 status = message->status;
120 if (status == 0)
121 status = message->actual_length;
122 }
123 return status;
124}
125
126static inline ssize_t
127spidev_sync_write(struct spidev_data *spidev, size_t len)
128{
129 struct spi_transfer t = {
130 .tx_buf = spidev->buffer,
131 .len = len,
132 };
133 struct spi_message m;
134
135 spi_message_init(&m);
136 spi_message_add_tail(&t, &m);
137 return spidev_sync(spidev, &m);
138}
139
140static inline ssize_t
141spidev_sync_read(struct spidev_data *spidev, size_t len)
142{
143 struct spi_transfer t = {
144 .rx_buf = spidev->buffer,
145 .len = len,
146 };
147 struct spi_message m;
148
149 spi_message_init(&m);
150 spi_message_add_tail(&t, &m);
151 return spidev_sync(spidev, &m);
152}
153
154/*-------------------------------------------------------------------------*/
155
88/* Read-only message with current device setup */ 156/* Read-only message with current device setup */
89static ssize_t 157static ssize_t
90spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) 158spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
91{ 159{
92 struct spidev_data *spidev; 160 struct spidev_data *spidev;
93 struct spi_device *spi;
94 ssize_t status = 0; 161 ssize_t status = 0;
95 162
96 /* chipselect only toggles at start or end of operation */ 163 /* chipselect only toggles at start or end of operation */
@@ -98,18 +165,17 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
98 return -EMSGSIZE; 165 return -EMSGSIZE;
99 166
100 spidev = filp->private_data; 167 spidev = filp->private_data;
101 spi = spidev->spi;
102 168
103 mutex_lock(&spidev->buf_lock); 169 mutex_lock(&spidev->buf_lock);
104 status = spi_read(spi, spidev->buffer, count); 170 status = spidev_sync_read(spidev, count);
105 if (status == 0) { 171 if (status > 0) {
106 unsigned long missing; 172 unsigned long missing;
107 173
108 missing = copy_to_user(buf, spidev->buffer, count); 174 missing = copy_to_user(buf, spidev->buffer, status);
109 if (count && missing == count) 175 if (missing == status)
110 status = -EFAULT; 176 status = -EFAULT;
111 else 177 else
112 status = count - missing; 178 status = status - missing;
113 } 179 }
114 mutex_unlock(&spidev->buf_lock); 180 mutex_unlock(&spidev->buf_lock);
115 181
@@ -122,7 +188,6 @@ spidev_write(struct file *filp, const char __user *buf,
122 size_t count, loff_t *f_pos) 188 size_t count, loff_t *f_pos)
123{ 189{
124 struct spidev_data *spidev; 190 struct spidev_data *spidev;
125 struct spi_device *spi;
126 ssize_t status = 0; 191 ssize_t status = 0;
127 unsigned long missing; 192 unsigned long missing;
128 193
@@ -131,14 +196,11 @@ spidev_write(struct file *filp, const char __user *buf,
131 return -EMSGSIZE; 196 return -EMSGSIZE;
132 197
133 spidev = filp->private_data; 198 spidev = filp->private_data;
134 spi = spidev->spi;
135 199
136 mutex_lock(&spidev->buf_lock); 200 mutex_lock(&spidev->buf_lock);
137 missing = copy_from_user(spidev->buffer, buf, count); 201 missing = copy_from_user(spidev->buffer, buf, count);
138 if (missing == 0) { 202 if (missing == 0) {
139 status = spi_write(spi, spidev->buffer, count); 203 status = spidev_sync_write(spidev, count);
140 if (status == 0)
141 status = count;
142 } else 204 } else
143 status = -EFAULT; 205 status = -EFAULT;
144 mutex_unlock(&spidev->buf_lock); 206 mutex_unlock(&spidev->buf_lock);
@@ -153,7 +215,6 @@ static int spidev_message(struct spidev_data *spidev,
153 struct spi_transfer *k_xfers; 215 struct spi_transfer *k_xfers;
154 struct spi_transfer *k_tmp; 216 struct spi_transfer *k_tmp;
155 struct spi_ioc_transfer *u_tmp; 217 struct spi_ioc_transfer *u_tmp;
156 struct spi_device *spi = spidev->spi;
157 unsigned n, total; 218 unsigned n, total;
158 u8 *buf; 219 u8 *buf;
159 int status = -EFAULT; 220 int status = -EFAULT;
@@ -215,7 +276,7 @@ static int spidev_message(struct spidev_data *spidev,
215 spi_message_add_tail(k_tmp, &msg); 276 spi_message_add_tail(k_tmp, &msg);
216 } 277 }
217 278
218 status = spi_sync(spi, &msg); 279 status = spidev_sync(spidev, &msg);
219 if (status < 0) 280 if (status < 0)
220 goto done; 281 goto done;
221 282
@@ -269,8 +330,16 @@ spidev_ioctl(struct inode *inode, struct file *filp,
269 if (err) 330 if (err)
270 return -EFAULT; 331 return -EFAULT;
271 332
333 /* guard against device removal before, or while,
334 * we issue this ioctl.
335 */
272 spidev = filp->private_data; 336 spidev = filp->private_data;
273 spi = spidev->spi; 337 spin_lock_irq(&spidev->spi_lock);
338 spi = spi_dev_get(spidev->spi);
339 spin_unlock_irq(&spidev->spi_lock);
340
341 if (spi == NULL)
342 return -ESHUTDOWN;
274 343
275 switch (cmd) { 344 switch (cmd) {
276 /* read requests */ 345 /* read requests */
@@ -356,8 +425,10 @@ spidev_ioctl(struct inode *inode, struct file *filp,
356 default: 425 default:
357 /* segmented and/or full-duplex I/O request */ 426 /* segmented and/or full-duplex I/O request */
358 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) 427 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
359 || _IOC_DIR(cmd) != _IOC_WRITE) 428 || _IOC_DIR(cmd) != _IOC_WRITE) {
360 return -ENOTTY; 429 retval = -ENOTTY;
430 break;
431 }
361 432
362 tmp = _IOC_SIZE(cmd); 433 tmp = _IOC_SIZE(cmd);
363 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { 434 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
@@ -385,6 +456,7 @@ spidev_ioctl(struct inode *inode, struct file *filp,
385 kfree(ioc); 456 kfree(ioc);
386 break; 457 break;
387 } 458 }
459 spi_dev_put(spi);
388 return retval; 460 return retval;
389} 461}
390 462
@@ -393,10 +465,11 @@ static int spidev_open(struct inode *inode, struct file *filp)
393 struct spidev_data *spidev; 465 struct spidev_data *spidev;
394 int status = -ENXIO; 466 int status = -ENXIO;
395 467
468 lock_kernel();
396 mutex_lock(&device_list_lock); 469 mutex_lock(&device_list_lock);
397 470
398 list_for_each_entry(spidev, &device_list, device_entry) { 471 list_for_each_entry(spidev, &device_list, device_entry) {
399 if (spidev->dev.devt == inode->i_rdev) { 472 if (spidev->devt == inode->i_rdev) {
400 status = 0; 473 status = 0;
401 break; 474 break;
402 } 475 }
@@ -418,6 +491,7 @@ static int spidev_open(struct inode *inode, struct file *filp)
418 pr_debug("spidev: nothing for minor %d\n", iminor(inode)); 491 pr_debug("spidev: nothing for minor %d\n", iminor(inode));
419 492
420 mutex_unlock(&device_list_lock); 493 mutex_unlock(&device_list_lock);
494 unlock_kernel();
421 return status; 495 return status;
422} 496}
423 497
@@ -429,10 +503,22 @@ static int spidev_release(struct inode *inode, struct file *filp)
429 mutex_lock(&device_list_lock); 503 mutex_lock(&device_list_lock);
430 spidev = filp->private_data; 504 spidev = filp->private_data;
431 filp->private_data = NULL; 505 filp->private_data = NULL;
506
507 /* last close? */
432 spidev->users--; 508 spidev->users--;
433 if (!spidev->users) { 509 if (!spidev->users) {
510 int dofree;
511
434 kfree(spidev->buffer); 512 kfree(spidev->buffer);
435 spidev->buffer = NULL; 513 spidev->buffer = NULL;
514
515 /* ... after we unbound from the underlying device? */
516 spin_lock_irq(&spidev->spi_lock);
517 dofree = (spidev->spi == NULL);
518 spin_unlock_irq(&spidev->spi_lock);
519
520 if (dofree)
521 kfree(spidev);
436 } 522 }
437 mutex_unlock(&device_list_lock); 523 mutex_unlock(&device_list_lock);
438 524
@@ -459,19 +545,7 @@ static struct file_operations spidev_fops = {
459 * It also simplifies memory management. 545 * It also simplifies memory management.
460 */ 546 */
461 547
462static void spidev_classdev_release(struct device *dev) 548static struct class *spidev_class;
463{
464 struct spidev_data *spidev;
465
466 spidev = container_of(dev, struct spidev_data, dev);
467 kfree(spidev);
468}
469
470static struct class spidev_class = {
471 .name = "spidev",
472 .owner = THIS_MODULE,
473 .dev_release = spidev_classdev_release,
474};
475 549
476/*-------------------------------------------------------------------------*/ 550/*-------------------------------------------------------------------------*/
477 551
@@ -488,6 +562,7 @@ static int spidev_probe(struct spi_device *spi)
488 562
489 /* Initialize the driver data */ 563 /* Initialize the driver data */
490 spidev->spi = spi; 564 spidev->spi = spi;
565 spin_lock_init(&spidev->spi_lock);
491 mutex_init(&spidev->buf_lock); 566 mutex_init(&spidev->buf_lock);
492 567
493 INIT_LIST_HEAD(&spidev->device_entry); 568 INIT_LIST_HEAD(&spidev->device_entry);
@@ -498,20 +573,20 @@ static int spidev_probe(struct spi_device *spi)
498 mutex_lock(&device_list_lock); 573 mutex_lock(&device_list_lock);
499 minor = find_first_zero_bit(minors, N_SPI_MINORS); 574 minor = find_first_zero_bit(minors, N_SPI_MINORS);
500 if (minor < N_SPI_MINORS) { 575 if (minor < N_SPI_MINORS) {
501 spidev->dev.parent = &spi->dev; 576 struct device *dev;
502 spidev->dev.class = &spidev_class; 577
503 spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor); 578 spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
504 snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id, 579 dev = device_create(spidev_class, &spi->dev, spidev->devt,
505 "spidev%d.%d", 580 "spidev%d.%d",
506 spi->master->bus_num, spi->chip_select); 581 spi->master->bus_num, spi->chip_select);
507 status = device_register(&spidev->dev); 582 status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
508 } else { 583 } else {
509 dev_dbg(&spi->dev, "no minor number available!\n"); 584 dev_dbg(&spi->dev, "no minor number available!\n");
510 status = -ENODEV; 585 status = -ENODEV;
511 } 586 }
512 if (status == 0) { 587 if (status == 0) {
513 set_bit(minor, minors); 588 set_bit(minor, minors);
514 dev_set_drvdata(&spi->dev, spidev); 589 spi_set_drvdata(spi, spidev);
515 list_add(&spidev->device_entry, &device_list); 590 list_add(&spidev->device_entry, &device_list);
516 } 591 }
517 mutex_unlock(&device_list_lock); 592 mutex_unlock(&device_list_lock);
@@ -524,15 +599,21 @@ static int spidev_probe(struct spi_device *spi)
524 599
525static int spidev_remove(struct spi_device *spi) 600static int spidev_remove(struct spi_device *spi)
526{ 601{
527 struct spidev_data *spidev = dev_get_drvdata(&spi->dev); 602 struct spidev_data *spidev = spi_get_drvdata(spi);
528 603
529 mutex_lock(&device_list_lock); 604 /* make sure ops on existing fds can abort cleanly */
605 spin_lock_irq(&spidev->spi_lock);
606 spidev->spi = NULL;
607 spi_set_drvdata(spi, NULL);
608 spin_unlock_irq(&spidev->spi_lock);
530 609
610 /* prevent new opens */
611 mutex_lock(&device_list_lock);
531 list_del(&spidev->device_entry); 612 list_del(&spidev->device_entry);
532 dev_set_drvdata(&spi->dev, NULL); 613 device_destroy(spidev_class, spidev->devt);
533 clear_bit(MINOR(spidev->dev.devt), minors); 614 clear_bit(MINOR(spidev->devt), minors);
534 device_unregister(&spidev->dev); 615 if (spidev->users == 0)
535 616 kfree(spidev);
536 mutex_unlock(&device_list_lock); 617 mutex_unlock(&device_list_lock);
537 618
538 return 0; 619 return 0;
@@ -568,15 +649,15 @@ static int __init spidev_init(void)
568 if (status < 0) 649 if (status < 0)
569 return status; 650 return status;
570 651
571 status = class_register(&spidev_class); 652 spidev_class = class_create(THIS_MODULE, "spidev");
572 if (status < 0) { 653 if (IS_ERR(spidev_class)) {
573 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 654 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
574 return status; 655 return PTR_ERR(spidev_class);
575 } 656 }
576 657
577 status = spi_register_driver(&spidev_spi); 658 status = spi_register_driver(&spidev_spi);
578 if (status < 0) { 659 if (status < 0) {
579 class_unregister(&spidev_class); 660 class_destroy(spidev_class);
580 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 661 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
581 } 662 }
582 return status; 663 return status;
@@ -586,7 +667,7 @@ module_init(spidev_init);
586static void __exit spidev_exit(void) 667static void __exit spidev_exit(void)
587{ 668{
588 spi_unregister_driver(&spidev_spi); 669 spi_unregister_driver(&spidev_spi);
589 class_unregister(&spidev_class); 670 class_destroy(spidev_class);
590 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 671 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
591} 672}
592module_exit(spidev_exit); 673module_exit(spidev_exit);