From: Kyungmin Park Date: Fri, 17 Aug 2007 00:06:56 +0000 (+0900) Subject: Fix scheduling while atomic bug in tsc210x X-Git-Tag: v2.6.23-omap1~85 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=6e133407e7d9da42d230558bd3f1352a3838d54b;p=linux-2.6-omap-h63xx.git Fix scheduling while atomic bug in tsc210x Fix scheduling while atomic bug BUG: scheduling while atomic: swapper/0x00000002/1 [] (dump_stack+0x0/0x14) from [] (__schedule_bug+0x34/0x3c) [] (__schedule_bug+0x0/0x3c) from [] (schedule+0x74/0x384) [] (schedule+0x0/0x384) from [] (wait_for_completion+0xc8/0) [] (wait_for_completion+0x0/0x148) from [] (call_usermodehe) r8:c072bce0 r7:00000000 r6:00000000 r5:c02fd2d4 r4:c07536e0 [] (call_usermodehelper_exec+0x0/0x100) from [] (kobject_ue) r8:00000008 r7:c7c060ad r6:c7cccda0 r5:c074a9e0 r4:00000000 [] (kobject_uevent_env+0x0/0x498) from [] (kobject_uevent+0) [] (kobject_uevent+0x0/0x18) from [] (device_add+0x374/0x61) [] (device_add+0x0/0x618) from [] (platform_device_add+0xe8) [] (platform_device_add+0x0/0x164) from [] (platform_device) r7:c076a800 r6:c0752400 r5:c076a8a4 r4:c02f0958 [] (platform_device_register+0x0/0x28) from [] (tsc210x_pro) r4:00000004 [] (tsc210x_probe+0x0/0x54c) from [] (tsc2101_probe+0x14/0x) [] (tsc2101_probe+0x0/0x18) from [] (spi_drv_probe+0x24/0x2) [] (spi_drv_probe+0x0/0x28) from [] (driver_probe_device+0x) [] (driver_probe_device+0x0/0x180) from [] (__driver_attach) r8:c072a000 r7:c02f0648 r6:c02f0648 r5:c076a800 r4:c076a8c0 [] (__driver_attach+0x0/0xf8) from [] (bus_for_each_dev+0x4) r6:c019ca20 r5:c072bed8 r4:00000000 [] (bus_for_each_dev+0x0/0x84) from [] (driver_attach+0x24/) r7:c02f01e8 r6:c02f0650 r5:c02f0648 r4:00000000 [] (driver_attach+0x0/0x2c) from [] (bus_add_driver+0x7c/0x) [] (bus_add_driver+0x0/0x1d4) from [] (driver_register+0x84) [] (driver_register+0x0/0x8c) from [] (spi_register_driver+) r4:00000000 [] (spi_register_driver+0x0/0x64) from [] (tsc210x_init+0x3) [] (tsc210x_init+0x0/0x74) from [] (kernel_init+0xe0/0x290) r5:00000000 r4:00000000 [] (kernel_init+0x0/0x290) from [] (do_exit+0x0/0x878) Signed-off-by: Kyungmin Park Signed-off-by: Tony Lindgren --- diff --git a/drivers/spi/tsc210x.c b/drivers/spi/tsc210x.c index 8a2b406ba30..df8bcf91bf9 100644 --- a/drivers/spi/tsc210x.c +++ b/drivers/spi/tsc210x.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -107,7 +107,7 @@ struct tsc210x_dev { struct workqueue_struct *queue; struct delayed_work ts_worker; /* Poll-wait for PEN UP */ struct delayed_work sensor_worker; /* Scan the ADC inputs */ - spinlock_t queue_lock; + struct mutex queue_lock; struct completion data_avail; tsc210x_touch_t touch_cb; @@ -523,10 +523,10 @@ static void tsc210x_input_scan(struct work_struct *work) tsc210x_touchscreen_mode(dev); - spin_lock(&dev->queue_lock); + mutex_lock(&dev->queue_lock); if (!dev->flushing) tsc210x_queue_scan(dev); - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); } /* ADC has finished a new conversion for us. */ @@ -927,10 +927,10 @@ tsc210x_suspend(struct spi_device *spi, pm_message_t state) return -ENODEV; /* Stop the inputs scan loop */ - spin_lock(&dev->queue_lock); + mutex_lock(&dev->queue_lock); dev->flushing = 1; cancel_delayed_work(&dev->sensor_worker); - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); flush_workqueue(dev->queue); /* Wait until pen-up happens */ @@ -955,11 +955,11 @@ static int tsc210x_resume(struct spi_device *spi) if (!dev) return 0; - spin_lock(&dev->queue_lock); + mutex_lock(&dev->queue_lock); err = tsc210x_configure(dev); dev->flushing = 0; - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); return err; } @@ -1020,7 +1020,7 @@ static int tsc210x_probe(struct spi_device *spi, enum tsc_type type) goto err_queue; } - spin_lock_init(&dev->queue_lock); + mutex_init(&dev->queue_lock); init_completion(&dev->data_avail); /* Allocate enough struct spi_transfer's for all requests */ @@ -1099,7 +1099,7 @@ static int tsc210x_probe(struct spi_device *spi, enum tsc_type type) goto err_spi; /* We want no interrupts before configuration succeeds. */ - spin_lock(&dev->queue_lock); + mutex_lock(&dev->queue_lock); dev->flushing = 1; if (request_irq(spi->irq, tsc210x_handler, IRQF_SAMPLE_RANDOM | @@ -1130,7 +1130,7 @@ static int tsc210x_probe(struct spi_device *spi, enum tsc_type type) goto err_alsa; dev->flushing = 0; - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); return 0; err_alsa: @@ -1138,7 +1138,7 @@ err_alsa: err_hwmon: platform_device_unregister(&tsc210x_ts_device); err_irq: - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); err_spi: dev_set_drvdata(&spi->dev, NULL); clk_disable(dev->bclk_ck); @@ -1167,10 +1167,10 @@ static int tsc210x_remove(struct spi_device *spi) struct tsc210x_dev *dev = dev_get_drvdata(&spi->dev); /* Stop the inputs scan loop */ - spin_lock(&dev->queue_lock); + mutex_lock(&dev->queue_lock); dev->flushing = 1; cancel_delayed_work(&dev->sensor_worker); - spin_unlock(&dev->queue_lock); + mutex_unlock(&dev->queue_lock); flush_workqueue(dev->queue); /* Wait for pen-up */