From 1510dd5954be5070e46b155eb32362dc73d9e9cb Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Mon, 31 Oct 2011 17:10:31 -0700 Subject: lis3lv02d: avoid divide by zero due to unchecked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After an "unexpected" reboot, I found this Oops in my logs: divide error: 0000 [#1] PREEMPT SMP=20 CPU 0=20 Modules linked in: lis3lv02d hp_wmi input_polldev [...] Pid: 390, comm: modprobe Tainted: G C 2.6.39-rc7-wl+=20 RIP: 0010:[] [] lis3lv02d_poweron+0x4e/0x94 [lis3lv02d] RSP: 0018:ffff8801d6407cf8 EFLAGS: 00010246 RAX: 0000000000000bb8 RBX: ffffffffa014e000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffea00066e4708 RDI: ffff8801df002700 RBP: ffff8801d6407d18 R08: ffffea00066c5a30 R09: ffffffff812498c9 R10: ffff8801d7bfcea0 R11: ffff8801d7bfce10 R12: 0000000000000bb8 R13: 00000000ffffffda R14: ffffffffa0154120 R15: ffffffffa0154030 =46S: 00007fc0705db700(0000) GS:ffff8801dfa00000(0000) knlGS:0 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007f33549174f0 CR3: 00000001d65c9000 CR4: 00000000000406f0 Process modprobe (pid: 390, threadinfo ffff8801d6406000, task ffff8801d6b40= 000) Stack: ffffffffa0154120 62ffffffa0154030 ffffffffa014e000 00000000ffffffea ffff8801d6407d58 ffffffffa014bcc1 0000000000000000 0000000000000048 ffff8801d8bae800 00000000ffffffea 00000000ffffffda ffffffffa0154120 Call Trace: [] lis3lv02d_init_device+0x1ce/0x496 [lis3lv02d] [] lis3lv02d_add+0x10f/0x17c [hp_accel] [] acpi_device_probe+0x49/0x117 [...] Code: 3a 75 06 80 4d ef 50 eb 04 80 4d ef 40 0f b6 55 ef be 21 00 00 00 48 89 df ff 53 18 44 8b 63 6c e8 3e fc ff ff 89 c1 44 89 e0 99 f9 89 c7 e8 93 82 ef e0 48 83 7b 30 00 74 2d 45 31 e4 80 7b=20 RIP [] lis3lv02d_poweron+0x4e/0x94 [lis3lv02d] RSP >From my POV, it looks like the hardware is not working as expected and returns a bogus data rate. The driver doesn't check the result and directly uses it as some sort of divisor in some places: msleep(lis3->pwron_delay / lis3lv02d_get_odr()); Under this circumstances, this could very well cause the "divide by zero" exception from above. For now, I fixed it the easiest and most obvious way: Check if the result is sane and if it isn't use a sane default instead. I went for "100" in the latter case, simply because /sys/devices/platform/lis3lv02d/rate returns it on a successful boot. Signed-off-by: Christian Lamparter Signed-off-by: Éric Piel Cc: Matthew Garrett Cc: Witold Pilat Cc: Lyall Pearce Cc: Malte Starostik Cc: Ilkka Koskinen Cc: Thadeu Lima de Souza Cascardo Cc: Christian Lamparter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/hp_accel.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 1b52d00e2f90..891e71f75f56 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -354,8 +354,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) static int lis3lv02d_resume(struct acpi_device *device) { - lis3lv02d_poweron(&lis3_dev); - return 0; + return lis3lv02d_poweron(&lis3_dev); } #else #define lis3lv02d_suspend NULL -- cgit v1.2.3 From a17b81beeb76a7cc3551fc17d7aa73b303dee52c Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Mon, 31 Oct 2011 17:10:43 -0700 Subject: lis3: add support for HP EliteBook 2730p MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add axis correction for HP EliteBook 2730p. Tested-by: Witold Pilat Signed-off-by: Éric Piel Cc: Matthew Garrett Cc: Lyall Pearce Cc: Malte Starostik Cc: Ilkka Koskinen Cc: Thadeu Lima de Souza Cascardo Cc: Christian Lamparter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/hp_accel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 891e71f75f56..76b24e6b6301 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -209,6 +209,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap), + AXIS_DMI_MATCH("NC273xx", "HP EliteBook 273", y_inverted), /* Intel-based HP Pavilion dv5 */ AXIS_DMI_MATCH2("HPDV5_I", PRODUCT_NAME, "HP Pavilion dv5", -- cgit v1.2.3 From cdeaf62255d171dd159f0bdc453efd7ff31c6916 Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Mon, 31 Oct 2011 17:10:46 -0700 Subject: lis3: add support for HP EliteBook 8540w MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add axis correction for HP EliteBook 8540w. Reported-by: Lyall Pearce Signed-off-by: Éric Piel Cc: Matthew Garrett Cc: Witold Pilat Cc: Malte Starostik Cc: Ilkka Koskinen Cc: Thadeu Lima de Souza Cascardo Cc: Christian Lamparter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/hp_accel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 76b24e6b6301..626b162168cc 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -209,6 +209,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap), + AXIS_DMI_MATCH("NC854xx", "HP EliteBook 854", y_inverted), AXIS_DMI_MATCH("NC273xx", "HP EliteBook 273", y_inverted), /* Intel-based HP Pavilion dv5 */ AXIS_DMI_MATCH2("HPDV5_I", -- cgit v1.2.3 From d0b6a971ed034054897df42f3e3000b4f57cccc5 Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Mon, 31 Oct 2011 17:10:50 -0700 Subject: hp_accel: add HP ProBook 655x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add axis correction for HP ProBook 6555b. Signed-off-by: Malte Starostik Signed-off-by: Éric Piel Cc: Matthew Garrett Cc: Witold Pilat Cc: Lyall Pearce Cc: Ilkka Koskinen Cc: Thadeu Lima de Souza Cascardo Cc: Christian Lamparter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/hp_accel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/platform') diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 626b162168cc..89c5cb586187 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -229,6 +229,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), + AXIS_DMI_MATCH("HPB655x", "HP ProBook 655", xy_swap_inverted), AXIS_DMI_MATCH("Mini510x", "HP Mini 510", xy_rotated_left_usd), { NULL, } /* Laptop models without axis info (yet): -- cgit v1.2.3 From e1e5687d75ef0ea5cbae63df48ff2fdcb5306f66 Mon Sep 17 00:00:00 2001 From: Éric Piel Date: Mon, 31 Oct 2011 17:11:02 -0700 Subject: lis3: change exported function to use passed parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change exported functions to use the device given as parameter instead of the global one. Signed-off-by: Ilkka Koskinen Signed-off-by: Éric Piel Cc: Matthew Garrett Cc: Witold Pilat Cc: Lyall Pearce Cc: Malte Starostik Cc: Thadeu Lima de Souza Cascardo Cc: Christian Lamparter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/lis3lv02d/lis3lv02d.c | 6 +++--- drivers/misc/lis3lv02d/lis3lv02d.h | 4 ++-- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 2 +- drivers/platform/x86/hp_accel.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/platform') diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index eaef96bbbdfd..57249a01e6e7 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -631,7 +631,7 @@ static struct miscdevice lis3lv02d_misc_device = { .fops = &lis3lv02d_misc_fops, }; -int lis3lv02d_joystick_enable(void) +int lis3lv02d_joystick_enable(struct lis3lv02d *lis3) { struct input_dev *input_dev; int err; @@ -689,7 +689,7 @@ int lis3lv02d_joystick_enable(void) } EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); -void lis3lv02d_joystick_disable(void) +void lis3lv02d_joystick_disable(struct lis3lv02d *lis3) { if (lis3_dev.irq) free_irq(lis3_dev.irq, &lis3_dev); @@ -959,7 +959,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3) pm_runtime_enable(lis3->pm_dev); } - if (lis3lv02d_joystick_enable()) + if (lis3lv02d_joystick_enable(lis3)) pr_err("joystick initialization failed\n"); /* passing in platform specific data is purely optional and only diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index 57c64bbcf5f7..b94e72374810 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h @@ -282,8 +282,8 @@ struct lis3lv02d { }; int lis3lv02d_init_device(struct lis3lv02d *lis3); -int lis3lv02d_joystick_enable(void); -void lis3lv02d_joystick_disable(void); +int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); +void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); void lis3lv02d_poweroff(struct lis3lv02d *lis3); int lis3lv02d_poweron(struct lis3lv02d *lis3); int lis3lv02d_remove_fs(struct lis3lv02d *lis3); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index ea9159c65b58..6cdc38f6a9a8 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -182,7 +182,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) if (pdata && pdata->release_resources) pdata->release_resources(); - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(lis3); lis3lv02d_remove_fs(&lis3_dev); if (lis3_dev.reg_ctrl) diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index c1f8a8fbf694..b2c1be12d16f 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -83,7 +83,7 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi) static int __devexit lis302dl_spi_remove(struct spi_device *spi) { struct lis3lv02d *lis3 = spi_get_drvdata(spi); - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(lis3); lis3lv02d_poweroff(lis3); return lis3lv02d_remove_fs(&lis3_dev); diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 89c5cb586187..f93a47b7136a 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -323,7 +323,7 @@ static int lis3lv02d_add(struct acpi_device *device) INIT_WORK(&hpled_led.work, delayed_set_status_worker); ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) { - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); return ret; @@ -337,7 +337,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) if (!device) return -EINVAL; - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); led_classdev_unregister(&hpled_led.led_classdev); -- cgit v1.2.3