From 07d2390e36ee5b3265e9cc8305f2a106c8721e16 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 4 Apr 2016 14:54:59 +0900 Subject: [PATCH 1/3] iio: ak8975: Fix NULL pointer exception on early interrupt In certain probe conditions the interrupt came right after registering the handler causing a NULL pointer exception because of uninitialized waitqueue: $ udevadm trigger i2c-gpio i2c-gpio-1: using pins 143 (SDA) and 144 (SCL) i2c-gpio i2c-gpio-3: using pins 53 (SDA) and 52 (SCL) Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = e8b38000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: snd_soc_i2s(+) i2c_gpio(+) snd_soc_idma snd_soc_s3c_dma snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer snd soundcore ac97_bus spi_s3c64xx pwm_samsung dwc2 exynos_adc phy_exynos_usb2 exynosdrm exynos_rng rng_core rtc_s3c CPU: 0 PID: 717 Comm: data-provider-m Not tainted 4.6.0-rc1-next-20160401-00011-g1b8d87473b9e-dirty #101 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) (...) (__wake_up_common) from [] (__wake_up+0x38/0x4c) (__wake_up) from [] (ak8975_irq_handler+0x28/0x30) (ak8975_irq_handler) from [] (handle_irq_event_percpu+0x88/0x140) (handle_irq_event_percpu) from [] (handle_irq_event+0x44/0x68) (handle_irq_event) from [] (handle_edge_irq+0xf0/0x19c) (handle_edge_irq) from [] (generic_handle_irq+0x24/0x34) (generic_handle_irq) from [] (exynos_eint_gpio_irq+0x50/0x68) (exynos_eint_gpio_irq) from [] (handle_irq_event_percpu+0x88/0x140) (handle_irq_event_percpu) from [] (handle_irq_event+0x44/0x68) (handle_irq_event) from [] (handle_fasteoi_irq+0xb4/0x194) (handle_fasteoi_irq) from [] (generic_handle_irq+0x24/0x34) (generic_handle_irq) from [] (__handle_domain_irq+0x5c/0xb4) (__handle_domain_irq) from [] (gic_handle_irq+0x54/0x94) (gic_handle_irq) from [] (__irq_usr+0x50/0x80) The bug was reproduced on exynos4412-trats2 (with a max77693 device also using i2c-gpio) after building max77693 as a module. Cc: Fixes: 94a6d5cf7caa ("iio:ak8975 Implement data ready interrupt handling") Signed-off-by: Krzysztof Kozlowski Tested-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 9c5c9ef3f1da..3b23a850c930 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -462,6 +462,8 @@ static int ak8975_setup_irq(struct ak8975_data *data) int rc; int irq; + init_waitqueue_head(&data->data_ready_queue); + clear_bit(0, &data->flags); if (client->irq) irq = client->irq; else @@ -477,8 +479,6 @@ static int ak8975_setup_irq(struct ak8975_data *data) return rc; } - init_waitqueue_head(&data->data_ready_queue); - clear_bit(0, &data->flags); data->eoc_irq = irq; return rc; From 05be8d4101d960bad271d32b4f6096af1ccb1534 Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Tue, 5 Apr 2016 15:03:48 +0200 Subject: [PATCH 2/3] iio: ak8975: fix maybe-uninitialized warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If i2c_device_id *id is NULL and acpi_match_device returns NULL too, then chipset may be unitialized when accessing &ak_def_array[chipset] in ak8975_probe. Therefore initialize chipset to AK_MAX_TYPE, which will return an error when not changed. This patch fixes the following maybe-uninitialized warning: drivers/iio/magnetometer/ak8975.c: In function ‘ak8975_probe’: drivers/iio/magnetometer/ak8975.c:788:14: warning: ‘chipset’ may be used uninitialized in this function [-Wmaybe-uninitialized] data->def = &ak_def_array[chipset]; Signed-off-by: Richard Leitner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 3b23a850c930..0e931a9a1669 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -732,7 +732,7 @@ static int ak8975_probe(struct i2c_client *client, int eoc_gpio; int err; const char *name = NULL; - enum asahi_compass_chipset chipset; + enum asahi_compass_chipset chipset = AK_MAX_TYPE; /* Grab and set up the supplied GPIO. */ if (client->dev.platform_data) From 8e6cb470bac6b1e7afa4642a40a71f9bcd066242 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 18 Apr 2016 18:30:05 +0200 Subject: [PATCH 3/3] iio:adc:at91-sama5d2: Repair crash on module removal The driver never calls platform_set_drvdata() , so platform_get_drvdata() in .remove returns NULL and thus $indio_dev variable in .remove is NULL. Then it's only a matter of dereferencing the indio_dev variable to make the kernel blow as seen below. This patch adds the platform_set_drvdata() call to fix the problem. root@armhf:~# rmmod at91-sama5d2_adc Unable to handle kernel NULL pointer dereference at virtual address 000001d4 pgd = dd57c000 [000001d4] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: at91_sama5d2_adc(-) CPU: 0 PID: 1334 Comm: rmmod Not tainted 4.6.0-rc3-next-20160418+ #3 Hardware name: Atmel SAMA5 task: dd4fcc40 ti: de910000 task.ti: de910000 PC is at mutex_lock+0x4/0x24 LR is at iio_device_unregister+0x14/0x6c pc : [] lr : [] psr: a00d0013 sp : de911f00 ip : 00000000 fp : be898bd8 r10: 00000000 r9 : de910000 r8 : c0107724 r7 : 00000081 r6 : bf001048 r5 : 000001d4 r4 : 00000000 r3 : bf000000 r2 : 00000000 r1 : 00000004 r0 : 000001d4 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c53c7d Table: 3d57c059 DAC: 00000051 Process rmmod (pid: 1334, stack limit = 0xde910208) Stack: (0xde911f00 to 0xde912000) 1f00: bf000000 00000000 df5c7e10 bf000010 bf000000 df5c7e10 df5c7e10 c0351ca8 1f20: c0351c84 df5c7e10 bf001048 c0350734 bf001048 df5c7e10 df5c7e44 c035087c 1f40: bf001048 7f62dd4c 00000800 c034fb30 bf0010c0 c0158ee8 de910000 31397461 1f60: 6d61735f 32643561 6364615f 00000000 de911f90 de910000 de910000 00000000 1f80: de911fb0 10c53c7d de911f9c c05f33d8 de911fa0 00910000 be898ecb 7f62dd10 1fa0: 00000000 c0107560 be898ecb 7f62dd10 7f62dd4c 00000800 6f844800 6f844800 1fc0: be898ecb 7f62dd10 00000000 00000081 00000000 7f62dd10 be898bd8 be898bd8 1fe0: b6eedab1 be898b6c 7f61056b b6eedab6 000d0030 7f62dd4c 00000000 00000000 [] (mutex_lock) from [] (iio_device_unregister+0x14/0x6c) [] (iio_device_unregister) from [] (at91_adc_remove+0x10/0x3c [at91_sama5d2_adc]) [] (at91_adc_remove [at91_sama5d2_adc]) from [] (platform_drv_remove+0x24/0x3c) [] (platform_drv_remove) from [] (__device_release_driver+0x84/0x110) [] (__device_release_driver) from [] (driver_detach+0x8c/0x90) [] (driver_detach) from [] (bus_remove_driver+0x4c/0xa0) [] (bus_remove_driver) from [] (SyS_delete_module+0x110/0x1d0) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x3c) Code: e3520001 1affffd5 eafffff4 f5d0f000 (e1902f9f) ---[ end trace 86914d7ad3696fca ]--- Signed-off-by: Marek Vasut Cc: Ludovic Desroches Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index dbee13ad33a3..2e154cb51685 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -451,6 +451,8 @@ static int at91_adc_probe(struct platform_device *pdev) if (ret) goto vref_disable; + platform_set_drvdata(pdev, indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) goto per_clk_disable_unprepare;