public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] lis3: various fixes and enhancements
@ 2011-07-25 15:14 Éric Piel
  2011-07-25 15:16 ` [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked Éric Piel
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:14 UTC (permalink / raw)
  To: Andrew Morton, Matthew Garrett
  Cc: Christian Lamparter, LKML, platform-driver-x86, Malte Starostik,
	Ilkka Koskinen, Thadeu Lima de Souza Cascardo

Hello,

Here are a couple of patches from my backlog for the lis3. Since the 
move out of hwmon, I'm not entirely sure to who I should send the 
patches for the part which lies in driver/misc. Maybe Andrew can pick 
them, or should I send them directly to Linus?

Patch 1 avoids crashes with a buggy hardware (which is actually seen in 
the wild). Patch 7 fixes a missing free(). The rest of the patches are 
more enhancements. Iilka had actually sent another patch, coming as 
number 11, to allow multiple devices at the same time. But Cascardo 
noticed that it can cause problems with the misc device, so I'm not 
including it. Iilka, maybe have you found a solution since then?

Cheers,
Éric


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
@ 2011-07-25 15:16 ` Éric Piel
  2011-08-01 20:29   ` Andrew Morton
  2011-07-25 15:17 ` [PATCH 02/10] lis3: update maintainer information Éric Piel
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:16 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: Christian Lamparter, LKML, platform-driver-x86

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:[<ffffffffa014b427>]  [<ffffffffa014b427>]
		 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:
 [<ffffffffa014bcc1>] lis3lv02d_init_device+0x1ce/0x496 [lis3lv02d]
 [<ffffffffa01522ff>] lis3lv02d_add+0x10f/0x17c [hp_accel]
 [<ffffffff81233e11>] 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 <f7> f9 89 c7 e8 93 82 ef e0 48 83 7b 30 00 74 2d 45
31 e4 80 7b=20
RIP  [<ffffffffa014b427>] lis3lv02d_poweron+0x4e/0x94 [lis3lv02d]
 RSP <ffff8801d6407cf8>

>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 <chunkeey@googlemail.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/misc/lis3lv02d/lis3lv02d.c |   36 ++++++++++++++++++++++++++++++------
 drivers/misc/lis3lv02d/lis3lv02d.h |    2 +-
 drivers/platform/x86/hp_accel.c    |    3 +--
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index b928bc1..a9ee5f7 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -206,6 +206,18 @@ static int lis3lv02d_get_odr(void)
 	return lis3_dev.odrs[(ctrl >> shift)];
 }
 
+static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
+{
+	int div = lis3lv02d_get_odr();
+
+	if (WARN_ONCE(div == 0, "device returned spurious data"))
+		return -ENXIO;
+
+	/* LIS3 power on delay is quite long */
+	msleep(lis3->pwron_delay / div);
+	return 0;
+}
+
 static int lis3lv02d_set_odr(int rate)
 {
 	u8 ctrl;
@@ -266,7 +278,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 
 	lis3->read(lis3, ctlreg, &reg);
 	lis3->write(lis3, ctlreg, (reg | selftest));
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+	ret = lis3lv02d_get_pwron_wait(lis3);
+	if (ret)
+		goto fail;
 
 	/* Read directly to avoid axis remap */
 	x = lis3->read_data(lis3, OUTX);
@@ -275,7 +289,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 
 	/* back to normal settings */
 	lis3->write(lis3, ctlreg, reg);
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+	ret = lis3lv02d_get_pwron_wait(lis3);
+	if (ret)
+		goto fail;
 
 	results[0] = x - lis3->read_data(lis3, OUTX);
 	results[1] = y - lis3->read_data(lis3, OUTY);
@@ -363,8 +379,9 @@ void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
-void lis3lv02d_poweron(struct lis3lv02d *lis3)
+int lis3lv02d_poweron(struct lis3lv02d *lis3)
 {
+	int err;
 	u8 reg;
 
 	lis3->init(lis3);
@@ -382,11 +399,14 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 		reg |= CTRL2_BOOT_8B;
 	lis3->write(lis3, CTRL_REG2, reg);
 
-	/* LIS3 power on delay is quite long */
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+	err = lis3lv02d_get_pwron_wait(lis3);
+	if (err)
+		return err;
 
 	if (lis3->reg_ctrl)
 		lis3_context_restore(lis3);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -926,7 +946,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	atomic_set(&dev->wake_thread, 0);
 
 	lis3lv02d_add_fs(dev);
-	lis3lv02d_poweron(dev);
+	err = lis3lv02d_poweron(dev);
+	if (err) {
+		lis3lv02d_remove_fs(dev);
+		return err;
+	}
 
 	if (dev->pm_dev) {
 		pm_runtime_set_active(dev->pm_dev);
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h
index a193958..57c64bb 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.h
+++ b/drivers/misc/lis3lv02d/lis3lv02d.h
@@ -285,7 +285,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3);
 int lis3lv02d_joystick_enable(void);
 void lis3lv02d_joystick_disable(void);
 void lis3lv02d_poweroff(struct lis3lv02d *lis3);
-void lis3lv02d_poweron(struct lis3lv02d *lis3);
+int lis3lv02d_poweron(struct lis3lv02d *lis3);
 int lis3lv02d_remove_fs(struct lis3lv02d *lis3);
 
 extern struct lis3lv02d lis3_dev;
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 1b52d00..891e71f 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
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 02/10] lis3: update maintainer information
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
  2011-07-25 15:16 ` [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked Éric Piel
@ 2011-07-25 15:17 ` Éric Piel
  2011-07-25 15:18 ` [PATCH 03/10] lis3: add support for HP EliteBook 2730p Éric Piel
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:17 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: LKML, platform-driver-x86

In the move of the lis3 driver, the hp_accel.c file got dropped from the
MAINTAINER file. Make it explicit again that this file is tied to lis3
again.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 MAINTAINERS |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 187282d..00f7325 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3937,6 +3937,7 @@ M:	Eric Piel <eric.piel@tremplin-utc.net>
 S:	Maintained
 F:	Documentation/misc-devices/lis3lv02d
 F:	drivers/misc/lis3lv02d/
+F:	drivers/platform/x86/hp_accel.c
 
 LLC (802.2)
 M:	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 03/10] lis3: add support for HP EliteBook 2730p
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
  2011-07-25 15:16 ` [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked Éric Piel
  2011-07-25 15:17 ` [PATCH 02/10] lis3: update maintainer information Éric Piel
@ 2011-07-25 15:18 ` Éric Piel
  2011-07-25 15:19 ` [PATCH 04/10] lis3: add support for HP EliteBook 8540w Éric Piel
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:18 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: LKML, platform-driver-x86, Witold Pilat

Add axis correction for HP EliteBook 2730p.

Tested-by: Witold Pilat <witold.pilat@gmail.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/platform/x86/hp_accel.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 891e71f..76b24e6 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",
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 04/10] lis3: add support for HP EliteBook 8540w
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (2 preceding siblings ...)
  2011-07-25 15:18 ` [PATCH 03/10] lis3: add support for HP EliteBook 2730p Éric Piel
@ 2011-07-25 15:19 ` Éric Piel
  2011-07-25 15:19 ` [PATCH 05/10] hp_accel: Add HP ProBook 655x Éric Piel
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:19 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: LKML, platform-driver-x86, Lyall Pearce

Add axis correction for HP EliteBook 8540w.

Reported-by: Lyall Pearce <lyall.pearce@hp.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/platform/x86/hp_accel.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 76b24e6..626b162 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",
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 05/10] hp_accel: Add HP ProBook 655x
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (3 preceding siblings ...)
  2011-07-25 15:19 ` [PATCH 04/10] lis3: add support for HP EliteBook 8540w Éric Piel
@ 2011-07-25 15:19 ` Éric Piel
  2011-07-25 15:20 ` [PATCH 06/10] CONFIG_HP_ACCEL: Fix help text Éric Piel
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:19 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: Malte Starostik, LKML, platform-driver-x86

Add axis correction for HP ProBook 6555b.

Signed-off-by: Malte Starostik <m-starostik@versanet.de>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/platform/x86/hp_accel.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 626b162..89c5cb5 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):
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 06/10] CONFIG_HP_ACCEL: Fix help text
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (4 preceding siblings ...)
  2011-07-25 15:19 ` [PATCH 05/10] hp_accel: Add HP ProBook 655x Éric Piel
@ 2011-07-25 15:20 ` Éric Piel
  2011-07-25 15:21 ` [PATCH 07/10] lis3: Free regulators if probe() fails Éric Piel
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:20 UTC (permalink / raw)
  To: Matthew Garrett; +Cc: Malte Starostik, LKML, platform-driver-x86

Adapt the help text for CONFIG_HP_ACCEL to the move of
Documentation/hwmon/lis3lv02d to Documentation/misc-devices/ in
ff606677f6a47c63329cf8e6c7cf978c29f2d736

Signed-off-by: Malte Starostik <m-starostik@versanet.de>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/platform/x86/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 45e0191..d25f486 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -164,7 +164,7 @@ config HP_ACCEL
 
 	  Support for a led indicating disk protection will be provided as
 	  hp::hddprotect. For more information on the feature, refer to
-	  Documentation/hwmon/lis3lv02d.
+	  Documentation/misc-devices/lis3lv02d.
 
 	  To compile this driver as a module, choose M here: the module will
 	  be called hp_accel.
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 07/10] lis3: Free regulators if probe() fails.
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (5 preceding siblings ...)
  2011-07-25 15:20 ` [PATCH 06/10] CONFIG_HP_ACCEL: Fix help text Éric Piel
@ 2011-07-25 15:21 ` Éric Piel
  2011-07-25 15:22 ` [PATCH 08/10] lis3: Change naming to consistent Éric Piel
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:21 UTC (permalink / raw)
  Cc: Ilkka Koskinen, LKML, Andrew Morton

Signed-off-by: Ilkka Koskinen <ilkka.koskinen@nokia.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/misc/lis3lv02d/lis3lv02d_i2c.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
index b20dfb4..ea9159c 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
@@ -161,8 +161,13 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	if (lis3_dev.reg_ctrl)
 		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
 
-	if (ret == 0)
-		return 0;
+	if (ret)
+		goto fail2;
+	return 0;
+
+fail2:
+	regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators),
+				lis3_dev.regulators);
 fail:
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 08/10] lis3: Change naming to consistent
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (6 preceding siblings ...)
  2011-07-25 15:21 ` [PATCH 07/10] lis3: Free regulators if probe() fails Éric Piel
@ 2011-07-25 15:22 ` Éric Piel
  2011-07-25 15:23 ` [PATCH 09/10] lis3: Change exported function to use given Éric Piel
  2011-07-25 15:24 ` [PATCH 10/10] lis3: Remove the references to the global variable in core driver Éric Piel
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:22 UTC (permalink / raw)
  To: Andrew Morton, Thadeu Lima de Souza Cascardo; +Cc: Ilkka Koskinen, LKML

Signed-off-by: Ilkka Koskinen <ilkka.koskinen@nokia.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/misc/lis3lv02d/lis3lv02d.c |  120 ++++++++++++++++++------------------
 1 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index a9ee5f7..3ab8389 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -831,23 +831,23 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
 
-static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
+static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
 				struct lis3lv02d_platform_data *p)
 {
 	int err;
 	int ctrl2 = p->hipass_ctrl;
 
 	if (p->click_flags) {
-		dev->write(dev, CLICK_CFG, p->click_flags);
-		dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit);
-		dev->write(dev, CLICK_LATENCY, p->click_latency);
-		dev->write(dev, CLICK_WINDOW, p->click_window);
-		dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf);
-		dev->write(dev, CLICK_THSY_X,
+		lis3->write(lis3, CLICK_CFG, p->click_flags);
+		lis3->write(lis3, CLICK_TIMELIMIT, p->click_time_limit);
+		lis3->write(lis3, CLICK_LATENCY, p->click_latency);
+		lis3->write(lis3, CLICK_WINDOW, p->click_window);
+		lis3->write(lis3, CLICK_THSZ, p->click_thresh_z & 0xf);
+		lis3->write(lis3, CLICK_THSY_X,
 			(p->click_thresh_x & 0xf) |
 			(p->click_thresh_y << 4));
 
-		if (dev->idev) {
+		if (lis3->idev) {
 			struct input_dev *input_dev = lis3_dev.idev->input;
 			input_set_capability(input_dev, EV_KEY, BTN_X);
 			input_set_capability(input_dev, EV_KEY, BTN_Y);
@@ -856,22 +856,22 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
 	}
 
 	if (p->wakeup_flags) {
-		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
-		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
+		lis3->write(lis3, FF_WU_CFG_1, p->wakeup_flags);
+		lis3->write(lis3, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
 		/* pdata value + 1 to keep this backward compatible*/
-		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
+		lis3->write(lis3, FF_WU_DURATION_1, p->duration1 + 1);
 		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
 	}
 
 	if (p->wakeup_flags2) {
-		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
-		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
+		lis3->write(lis3, FF_WU_CFG_2, p->wakeup_flags2);
+		lis3->write(lis3, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
 		/* pdata value + 1 to keep this backward compatible*/
-		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
+		lis3->write(lis3, FF_WU_DURATION_2, p->duration2 + 1);
 		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
 	}
 	/* Configure hipass filters */
-	dev->write(dev, CTRL_REG2, ctrl2);
+	lis3->write(lis3, CTRL_REG2, ctrl2);
 
 	if (p->irq2) {
 		err = request_threaded_irq(p->irq2,
@@ -889,72 +889,72 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
  * Initialise the accelerometer and the various subsystems.
  * Should be rather independent of the bus system.
  */
-int lis3lv02d_init_device(struct lis3lv02d *dev)
+int lis3lv02d_init_device(struct lis3lv02d *lis3)
 {
 	int err;
 	irq_handler_t thread_fn;
 	int irq_flags = 0;
 
-	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
+	lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I);
 
-	switch (dev->whoami) {
+	switch (lis3->whoami) {
 	case WAI_12B:
 		pr_info("12 bits sensor found\n");
-		dev->read_data = lis3lv02d_read_12;
-		dev->mdps_max_val = 2048;
-		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
-		dev->odrs = lis3_12_rates;
-		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
-		dev->scale = LIS3_SENSITIVITY_12B;
-		dev->regs = lis3_wai12_regs;
-		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
+		lis3->read_data = lis3lv02d_read_12;
+		lis3->mdps_max_val = 2048;
+		lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
+		lis3->odrs = lis3_12_rates;
+		lis3->odr_mask = CTRL1_DF0 | CTRL1_DF1;
+		lis3->scale = LIS3_SENSITIVITY_12B;
+		lis3->regs = lis3_wai12_regs;
+		lis3->regs_size = ARRAY_SIZE(lis3_wai12_regs);
 		break;
 	case WAI_8B:
 		pr_info("8 bits sensor found\n");
-		dev->read_data = lis3lv02d_read_8;
-		dev->mdps_max_val = 128;
-		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
-		dev->odrs = lis3_8_rates;
-		dev->odr_mask = CTRL1_DR;
-		dev->scale = LIS3_SENSITIVITY_8B;
-		dev->regs = lis3_wai8_regs;
-		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
+		lis3->read_data = lis3lv02d_read_8;
+		lis3->mdps_max_val = 128;
+		lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
+		lis3->odrs = lis3_8_rates;
+		lis3->odr_mask = CTRL1_DR;
+		lis3->scale = LIS3_SENSITIVITY_8B;
+		lis3->regs = lis3_wai8_regs;
+		lis3->regs_size = ARRAY_SIZE(lis3_wai8_regs);
 		break;
 	case WAI_3DC:
 		pr_info("8 bits 3DC sensor found\n");
-		dev->read_data = lis3lv02d_read_8;
-		dev->mdps_max_val = 128;
-		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
-		dev->odrs = lis3_3dc_rates;
-		dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
-		dev->scale = LIS3_SENSITIVITY_8B;
+		lis3->read_data = lis3lv02d_read_8;
+		lis3->mdps_max_val = 128;
+		lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
+		lis3->odrs = lis3_3dc_rates;
+		lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
+		lis3->scale = LIS3_SENSITIVITY_8B;
 		break;
 	default:
-		pr_err("unknown sensor type 0x%X\n", dev->whoami);
+		pr_err("unknown sensor type 0x%X\n", lis3->whoami);
 		return -EINVAL;
 	}
 
-	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
+	lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
 				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
 
-	if (dev->reg_cache == NULL) {
+	if (lis3->reg_cache == NULL) {
 		printk(KERN_ERR DRIVER_NAME "out of memory\n");
 		return -ENOMEM;
 	}
 
-	mutex_init(&dev->mutex);
-	atomic_set(&dev->wake_thread, 0);
+	mutex_init(&lis3->mutex);
+	atomic_set(&lis3->wake_thread, 0);
 
-	lis3lv02d_add_fs(dev);
-	err = lis3lv02d_poweron(dev);
+	lis3lv02d_add_fs(lis3);
+	err = lis3lv02d_poweron(lis3);
 	if (err) {
-		lis3lv02d_remove_fs(dev);
+		lis3lv02d_remove_fs(lis3);
 		return err;
 	}
 
-	if (dev->pm_dev) {
-		pm_runtime_set_active(dev->pm_dev);
-		pm_runtime_enable(dev->pm_dev);
+	if (lis3->pm_dev) {
+		pm_runtime_set_active(lis3->pm_dev);
+		pm_runtime_enable(lis3->pm_dev);
 	}
 
 	if (lis3lv02d_joystick_enable())
@@ -962,24 +962,24 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 
 	/* passing in platform specific data is purely optional and only
 	 * used by the SPI transport layer at the moment */
-	if (dev->pdata) {
-		struct lis3lv02d_platform_data *p = dev->pdata;
+	if (lis3->pdata) {
+		struct lis3lv02d_platform_data *p = lis3->pdata;
 
-		if (dev->whoami == WAI_8B)
-			lis3lv02d_8b_configure(dev, p);
+		if (lis3->whoami == WAI_8B)
+			lis3lv02d_8b_configure(lis3, p);
 
 		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
 
-		dev->irq_cfg = p->irq_cfg;
+		lis3->irq_cfg = p->irq_cfg;
 		if (p->irq_cfg)
-			dev->write(dev, CTRL_REG3, p->irq_cfg);
+			lis3->write(lis3, CTRL_REG3, p->irq_cfg);
 
 		if (p->default_rate)
 			lis3lv02d_set_odr(p->default_rate);
 	}
 
 	/* bail if we did not get an IRQ from the bus layer */
-	if (!dev->irq) {
+	if (!lis3->irq) {
 		pr_debug("No IRQ. Disabling /dev/freefall\n");
 		goto out;
 	}
@@ -995,12 +995,12 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	 * io-apic is not configurable (and generates a warning) but I keep it
 	 * in case of support for other hardware.
 	 */
-	if (dev->pdata && dev->whoami == WAI_8B)
+	if (lis3->pdata && lis3->whoami == WAI_8B)
 		thread_fn = lis302dl_interrupt_thread1_8b;
 	else
 		thread_fn = NULL;
 
-	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
+	err = request_threaded_irq(lis3->irq, lis302dl_interrupt,
 				thread_fn,
 				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
 				irq_flags,
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 09/10] lis3: Change exported function to use given
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (7 preceding siblings ...)
  2011-07-25 15:22 ` [PATCH 08/10] lis3: Change naming to consistent Éric Piel
@ 2011-07-25 15:23 ` Éric Piel
  2011-07-25 15:24 ` [PATCH 10/10] lis3: Remove the references to the global variable in core driver Éric Piel
  9 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:23 UTC (permalink / raw)
  To: Andrew Morton, Thadeu Lima de Souza Cascardo; +Cc: Ilkka Koskinen, LKML

Change exported functions to use the device given as parameter
instead of the global one.

Signed-off-by: Ilkka Koskinen <ilkka.koskinen@nokia.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 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(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 3ab8389..83ff7b4 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -629,7 +629,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;
@@ -687,7 +687,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);
@@ -957,7 +957,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 57c64bb..b94e723 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 ea9159c..6cdc38f 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 c1f8a8f..b2c1be1 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 89c5cb5..f93a47b 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);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 10/10] lis3: Remove the references to the global variable in core driver
  2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
                   ` (8 preceding siblings ...)
  2011-07-25 15:23 ` [PATCH 09/10] lis3: Change exported function to use given Éric Piel
@ 2011-07-25 15:24 ` Éric Piel
  2011-08-03 13:47   ` [PATCH 10/10 v2] " Éric Piel
  9 siblings, 1 reply; 16+ messages in thread
From: Éric Piel @ 2011-07-25 15:24 UTC (permalink / raw)
  To: Andrew Morton, Thadeu Lima de Souza Cascardo; +Cc: Ilkka Koskinen, LKML

Signed-off-by: Ilkka Koskinen <ilkka.koskinen@nokia.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/misc/lis3lv02d/lis3lv02d.c |  233 ++++++++++++++++++++----------------
 drivers/misc/lis3lv02d/lis3lv02d.h |    3 +
 2 files changed, 133 insertions(+), 103 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 83ff7b4..e67dcea 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -163,7 +163,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 	int i;
 
 	if (lis3->blkread) {
-		if (lis3_dev.whoami == WAI_12B) {
+		if (lis3->whoami == WAI_12B) {
 			u16 data[3];
 			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
 			for (i = 0; i < 3; i++)
@@ -195,20 +195,20 @@ static int lis3_8_rates[2] = {100, 400};
 static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
 
 /* ODR is Output Data Rate */
-static int lis3lv02d_get_odr(void)
+static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
 {
 	u8 ctrl;
 	int shift;
 
-	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
-	ctrl &= lis3_dev.odr_mask;
-	shift = ffs(lis3_dev.odr_mask) - 1;
-	return lis3_dev.odrs[(ctrl >> shift)];
+	lis3->read(&lis3, CTRL_REG1, &ctrl);
+	ctrl &= lis3->odr_mask;
+	shift = ffs(lis3->odr_mask) - 1;
+	return lis3->odrs[(ctrl >> shift)];
 }
 
 static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
 {
-	int div = lis3lv02d_get_odr();
+	int div = lis3lv02d_get_odr(lis3);
 
 	if (WARN_ONCE(div == 0, "device returned spurious data"))
 		return -ENXIO;
@@ -218,7 +218,7 @@ static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
 	return 0;
 }
 
-static int lis3lv02d_set_odr(int rate)
+static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate)
 {
 	u8 ctrl;
 	int i, len, shift;
@@ -226,14 +226,14 @@ static int lis3lv02d_set_odr(int rate)
 	if (!rate)
 		return -EINVAL;
 
-	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
-	ctrl &= ~lis3_dev.odr_mask;
-	len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
-	shift = ffs(lis3_dev.odr_mask) - 1;
+	lis3->read(lis3, CTRL_REG1, &ctrl);
+	ctrl &= ~lis3->odr_mask;
+	len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */
+	shift = ffs(lis3->odr_mask) - 1;
 
 	for (i = 0; i < len; i++)
-		if (lis3_dev.odrs[i] == rate) {
-			lis3_dev.write(&lis3_dev, CTRL_REG1,
+		if (lis3->odrs[i] == rate) {
+			lis3->write(lis3, CTRL_REG1,
 					ctrl | (i << shift));
 			return 0;
 		}
@@ -252,12 +252,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	mutex_lock(&lis3->mutex);
 
 	irq_cfg = lis3->irq_cfg;
-	if (lis3_dev.whoami == WAI_8B) {
+	if (lis3->whoami == WAI_8B) {
 		lis3->data_ready_count[IRQ_LINE0] = 0;
 		lis3->data_ready_count[IRQ_LINE1] = 0;
 
 		/* Change interrupt cfg to data ready for selftest */
-		atomic_inc(&lis3_dev.wake_thread);
+		atomic_inc(&lis3->wake_thread);
 		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
 		lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
 		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
@@ -265,12 +265,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
 	}
 
-	if (lis3_dev.whoami == WAI_3DC) {
+	if (lis3->whoami == WAI_3DC) {
 		ctlreg = CTRL_REG4;
 		selftest = CTRL4_ST0;
 	} else {
 		ctlreg = CTRL_REG1;
-		if (lis3_dev.whoami == WAI_12B)
+		if (lis3->whoami == WAI_12B)
 			selftest = CTRL1_ST;
 		else
 			selftest = CTRL1_STP;
@@ -299,9 +299,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 
 	ret = 0;
 
-	if (lis3_dev.whoami == WAI_8B) {
+	if (lis3->whoami == WAI_8B) {
 		/* Restore original interrupt configuration */
-		atomic_dec(&lis3_dev.wake_thread);
+		atomic_dec(&lis3->wake_thread);
 		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
 		lis3->irq_cfg = irq_cfg;
 
@@ -413,24 +413,27 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
 static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
 {
+	struct lis3lv02d *lis3 = pidev->private;
 	int x, y, z;
 
-	mutex_lock(&lis3_dev.mutex);
-	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+	mutex_lock(&lis3->mutex);
+	lis3lv02d_get_xyz(lis3, &x, &y, &z);
 	input_report_abs(pidev->input, ABS_X, x);
 	input_report_abs(pidev->input, ABS_Y, y);
 	input_report_abs(pidev->input, ABS_Z, z);
 	input_sync(pidev->input);
-	mutex_unlock(&lis3_dev.mutex);
+	mutex_unlock(&lis3->mutex);
 }
 
 static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 {
-	if (lis3_dev.pm_dev)
-		pm_runtime_get_sync(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = pidev->private;
 
-	if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
-		atomic_set(&lis3_dev.wake_thread, 1);
+	if (lis3->pm_dev)
+		pm_runtime_get_sync(lis3->pm_dev);
+
+	if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev)
+		atomic_set(&lis3->wake_thread, 1);
 	/*
 	 * Update coordinates for the case where poll interval is 0 and
 	 * the chip in running purely under interrupt control
@@ -440,14 +443,18 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
 {
-	atomic_set(&lis3_dev.wake_thread, 0);
-	if (lis3_dev.pm_dev)
-		pm_runtime_put(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = pidev->private;
+
+	atomic_set(&lis3->wake_thread, 0);
+	if (lis3->pm_dev)
+		pm_runtime_put(lis3->pm_dev);
 }
 
-static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
+static irqreturn_t lis302dl_interrupt(int irq, void *data)
 {
-	if (!test_bit(0, &lis3_dev.misc_opened))
+	struct lis3lv02d *lis3 = data;
+
+	if (!test_bit(0, &lis3->misc_opened))
 		goto out;
 
 	/*
@@ -455,12 +462,12 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 	 * the lid is closed. This leads to interrupts as soon as a little move
 	 * is done.
 	 */
-	atomic_inc(&lis3_dev.count);
+	atomic_inc(&lis3->count);
 
-	wake_up_interruptible(&lis3_dev.misc_wait);
-	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
+	wake_up_interruptible(&lis3->misc_wait);
+	kill_fasync(&lis3->async_queue, SIGIO, POLL_IN);
 out:
-	if (atomic_read(&lis3_dev.wake_thread))
+	if (atomic_read(&lis3->wake_thread))
 		return IRQ_WAKE_THREAD;
 	return IRQ_HANDLED;
 }
@@ -532,28 +539,37 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 
 static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
 {
-	if (test_and_set_bit(0, &lis3_dev.misc_opened))
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	if (test_and_set_bit(0, &lis3->misc_opened))
 		return -EBUSY; /* already open */
 
-	if (lis3_dev.pm_dev)
-		pm_runtime_get_sync(lis3_dev.pm_dev);
+	if (lis3->pm_dev)
+		pm_runtime_get_sync(lis3->pm_dev);
 
-	atomic_set(&lis3_dev.count, 0);
+	atomic_set(&lis3->count, 0);
 	return 0;
 }
 
 static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
-	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
-	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
-	if (lis3_dev.pm_dev)
-		pm_runtime_put(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	fasync_helper(-1, file, 0, &lis3->async_queue);
+	clear_bit(0, &lis3->misc_opened); /* release the device */
+	if (lis3->pm_dev)
+		pm_runtime_put(lis3->pm_dev);
 	return 0;
 }
 
 static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 				size_t count, loff_t *pos)
 {
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
 	DECLARE_WAITQUEUE(wait, current);
 	u32 data;
 	unsigned char byte_data;
@@ -562,10 +578,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 	if (count < 1)
 		return -EINVAL;
 
-	add_wait_queue(&lis3_dev.misc_wait, &wait);
+	add_wait_queue(&lis3->misc_wait, &wait);
 	while (true) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		data = atomic_xchg(&lis3_dev.count, 0);
+		data = atomic_xchg(&lis3->count, 0);
 		if (data)
 			break;
 
@@ -595,22 +611,28 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 
 out:
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&lis3_dev.misc_wait, &wait);
+	remove_wait_queue(&lis3->misc_wait, &wait);
 
 	return retval;
 }
 
 static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
 {
-	poll_wait(file, &lis3_dev.misc_wait, wait);
-	if (atomic_read(&lis3_dev.count))
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	poll_wait(file, &lis3->misc_wait, wait);
+	if (atomic_read(&lis3->count))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
 
 static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
 {
-	return fasync_helper(fd, file, on, &lis3_dev.async_queue);
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	return fasync_helper(fd, file, on, &lis3->async_queue);
 }
 
 static const struct file_operations lis3lv02d_misc_fops = {
@@ -623,12 +645,6 @@ static const struct file_operations lis3lv02d_misc_fops = {
 	.fasync  = lis3lv02d_misc_fasync,
 };
 
-static struct miscdevice lis3lv02d_misc_device = {
-	.minor   = MISC_DYNAMIC_MINOR,
-	.name    = "freefall",
-	.fops    = &lis3lv02d_misc_fops,
-};
-
 int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
 {
 	struct input_dev *input_dev;
@@ -636,51 +652,52 @@ int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
 	int max_val, fuzz, flat;
 	int btns[] = {BTN_X, BTN_Y, BTN_Z};
 
-	if (lis3_dev.idev)
+	if (lis3->idev)
 		return -EINVAL;
 
-	lis3_dev.idev = input_allocate_polled_device();
-	if (!lis3_dev.idev)
+	lis3->idev = input_allocate_polled_device();
+	if (!lis3->idev)
 		return -ENOMEM;
 
-	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
-	lis3_dev.idev->open = lis3lv02d_joystick_open;
-	lis3_dev.idev->close = lis3lv02d_joystick_close;
-	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
-	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
-	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
-	input_dev = lis3_dev.idev->input;
+	lis3->idev->poll = lis3lv02d_joystick_poll;
+	lis3->idev->open = lis3lv02d_joystick_open;
+	lis3->idev->close = lis3lv02d_joystick_close;
+	lis3->idev->poll_interval = MDPS_POLL_INTERVAL;
+	lis3->idev->poll_interval_min = MDPS_POLL_MIN;
+	lis3->idev->poll_interval_max = MDPS_POLL_MAX;
+	lis3->idev->private = lis3;
+	input_dev = lis3->idev->input;
 
 	input_dev->name       = "ST LIS3LV02DL Accelerometer";
 	input_dev->phys       = DRIVER_NAME "/input0";
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor  = 0;
-	input_dev->dev.parent = &lis3_dev.pdev->dev;
+	input_dev->dev.parent = &lis3->pdev->dev;
 
 	set_bit(EV_ABS, input_dev->evbit);
-	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
-	if (lis3_dev.whoami == WAI_12B) {
+	max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY;
+	if (lis3->whoami == WAI_12B) {
 		fuzz = LIS3_DEFAULT_FUZZ_12B;
 		flat = LIS3_DEFAULT_FLAT_12B;
 	} else {
 		fuzz = LIS3_DEFAULT_FUZZ_8B;
 		flat = LIS3_DEFAULT_FLAT_8B;
 	}
-	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
-	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
+	fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY;
+	flat = (flat * lis3->scale) / LIS3_ACCURACY;
 
 	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
 
-	lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns);
-	lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns);
-	lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns);
+	lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns);
+	lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns);
+	lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns);
 
-	err = input_register_polled_device(lis3_dev.idev);
+	err = input_register_polled_device(lis3->idev);
 	if (err) {
-		input_free_polled_device(lis3_dev.idev);
-		lis3_dev.idev = NULL;
+		input_free_polled_device(lis3->idev);
+		lis3->idev = NULL;
 	}
 
 	return err;
@@ -689,19 +706,19 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
 
 void lis3lv02d_joystick_disable(struct lis3lv02d *lis3)
 {
-	if (lis3_dev.irq)
-		free_irq(lis3_dev.irq, &lis3_dev);
-	if (lis3_dev.pdata && lis3_dev.pdata->irq2)
-		free_irq(lis3_dev.pdata->irq2, &lis3_dev);
+	if (lis3->irq)
+		free_irq(lis3->irq, lis3);
+	if (lis3->pdata && lis3->pdata->irq2)
+		free_irq(lis3->pdata->irq2, lis3);
 
-	if (!lis3_dev.idev)
+	if (!lis3->idev)
 		return;
 
-	if (lis3_dev.irq)
-		misc_deregister(&lis3lv02d_misc_device);
-	input_unregister_polled_device(lis3_dev.idev);
-	input_free_polled_device(lis3_dev.idev);
-	lis3_dev.idev = NULL;
+	if (lis3->irq)
+		misc_deregister(&lis3->miscdev);
+	input_unregister_polled_device(lis3->idev);
+	input_free_polled_device(lis3->idev);
+	lis3->idev = NULL;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
@@ -726,6 +743,7 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	s16 values[3];
 
 	static const char ok[] = "OK";
@@ -733,8 +751,8 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev,
 	static const char irq[] = "FAIL_IRQ";
 	const char *res;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	switch (lis3lv02d_selftest(&lis3_dev, values)) {
+	lis3lv02d_sysfs_poweron(lis3);
+	switch (lis3lv02d_selftest(lis3, values)) {
 	case SELFTEST_FAIL:
 		res = fail;
 		break;
@@ -753,33 +771,37 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev,
 static ssize_t lis3lv02d_position_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	int x, y, z;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	mutex_lock(&lis3_dev.mutex);
-	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
-	mutex_unlock(&lis3_dev.mutex);
+	lis3lv02d_sysfs_poweron(lis3);
+	mutex_lock(&lis3->mutex);
+	lis3lv02d_get_xyz(lis3, &x, &y, &z);
+	mutex_unlock(&lis3->mutex);
 	return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
 }
 
 static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
+
+	lis3lv02d_sysfs_poweron(lis3);
+	return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
 }
 
 static ssize_t lis3lv02d_rate_set(struct device *dev,
 				struct device_attribute *attr, const char *buf,
 				size_t count)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	unsigned long rate;
 
 	if (strict_strtoul(buf, 0, &rate))
 		return -EINVAL;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	if (lis3lv02d_set_odr(rate))
+	lis3lv02d_sysfs_poweron(lis3);
+	if (lis3lv02d_set_odr(lis3, rate))
 		return -EINVAL;
 
 	return count;
@@ -808,6 +830,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
 	if (IS_ERR(lis3->pdev))
 		return PTR_ERR(lis3->pdev);
 
+	platform_set_drvdata(lis3->pdev, lis3);
 	return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
 }
 
@@ -821,7 +844,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 
 		/* SYSFS may have left chip running. Turn off if necessary */
 		if (!pm_runtime_suspended(lis3->pm_dev))
-			lis3lv02d_poweroff(&lis3_dev);
+			lis3lv02d_poweroff(lis3);
 
 		pm_runtime_disable(lis3->pm_dev);
 		pm_runtime_set_suspended(lis3->pm_dev);
@@ -848,7 +871,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
 			(p->click_thresh_y << 4));
 
 		if (lis3->idev) {
-			struct input_dev *input_dev = lis3_dev.idev->input;
+			struct input_dev *input_dev = lis3->idev->input;
 			input_set_capability(input_dev, EV_KEY, BTN_X);
 			input_set_capability(input_dev, EV_KEY, BTN_Y);
 			input_set_capability(input_dev, EV_KEY, BTN_Z);
@@ -879,7 +902,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
 					lis302dl_interrupt_thread2_8b,
 					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
 					(p->irq_flags2 & IRQF_TRIGGER_MASK),
-					DRIVER_NAME, &lis3_dev);
+					DRIVER_NAME, lis3);
 		if (err < 0)
 			pr_err("No second IRQ. Limited functionality\n");
 	}
@@ -975,7 +998,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 			lis3->write(lis3, CTRL_REG3, p->irq_cfg);
 
 		if (p->default_rate)
-			lis3lv02d_set_odr(p->default_rate);
+			lis3lv02d_set_odr(lis3, p->default_rate);
 	}
 
 	/* bail if we did not get an IRQ from the bus layer */
@@ -1004,14 +1027,18 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 				thread_fn,
 				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
 				irq_flags,
-				DRIVER_NAME, &lis3_dev);
+				DRIVER_NAME, lis3);
 
 	if (err < 0) {
 		pr_err("Cannot get IRQ\n");
 		goto out;
 	}
 
-	if (misc_register(&lis3lv02d_misc_device))
+	lis3->miscdev.minor	= MISC_DYNAMIC_MINOR;
+	lis3->miscdev.name	= "freefall";
+	lis3->miscdev.fops	= &lis3lv02d_misc_fops;
+
+	if (misc_register(&lis3->miscdev))
 		pr_err("misc_register failed\n");
 out:
 	return 0;
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h
index b94e723..2b1482a 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.h
+++ b/drivers/misc/lis3lv02d/lis3lv02d.h
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
 #include <linux/regulator/consumer.h>
+#include <linux/miscdevice.h>
 
 /*
  * This driver tries to support the "digital" accelerometer chips from
@@ -273,6 +274,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
+	struct miscdevice	miscdev;
+
 	int                     data_ready_count[2];
 	atomic_t		wake_thread;
 	unsigned char           irq_cfg;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked
  2011-07-25 15:16 ` [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked Éric Piel
@ 2011-08-01 20:29   ` Andrew Morton
  2011-08-01 21:11     ` Christian Lamparter
  0 siblings, 1 reply; 16+ messages in thread
From: Andrew Morton @ 2011-08-01 20:29 UTC (permalink / raw)
  To: Éric Piel
  Cc: Matthew Garrett, Christian Lamparter, LKML, platform-driver-x86

On Mon, 25 Jul 2011 17:16:23 +0200
__ric Piel <eric.piel@tremplin-utc.net> wrote:

> +static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
> +{
> +	int div = lis3lv02d_get_odr();
> +
> +	if (WARN_ONCE(div == 0, "device returned spurious data"))
> +		return -ENXIO;
> +
> +	/* LIS3 power on delay is quite long */
> +	msleep(lis3->pwron_delay / div);
> +	return 0;
> +}

The WARN_ONCE may not be very useful.  The user gets worried, might
report it (often to a distro, not to you!).  But we won't actually *do*
anything with the information?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked
  2011-08-01 20:29   ` Andrew Morton
@ 2011-08-01 21:11     ` Christian Lamparter
  2011-08-01 21:29       ` Andrew Morton
  0 siblings, 1 reply; 16+ messages in thread
From: Christian Lamparter @ 2011-08-01 21:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Éric Piel, Matthew Garrett, LKML, platform-driver-x86

On Monday, August 01, 2011 10:29:06 PM Andrew Morton wrote:
> On Mon, 25 Jul 2011 17:16:23 +0200
> __ric Piel <eric.piel@tremplin-utc.net> wrote:
> 
> > +static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
> > +{
> > +	int div = lis3lv02d_get_odr();
> > +
> > +	if (WARN_ONCE(div == 0, "device returned spurious data"))
> > +		return -ENXIO;
> > +
> > +	/* LIS3 power on delay is quite long */
> > +	msleep(lis3->pwron_delay / div);
> > +	return 0;
> > +}
> 
> The WARN_ONCE may not be very useful.  The user gets worried, might
> report it (often to a distro, not to you!).  But we won't actually *do*
> anything with the information?
The sensor is used to park the hdd in case of an "accident". However,
if the sensors is not working, the user should at least get a WARN
that something is very wrong, right?

Regards,
	Chr

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked
  2011-08-01 21:11     ` Christian Lamparter
@ 2011-08-01 21:29       ` Andrew Morton
  2011-08-03 13:21         ` Éric Piel
  0 siblings, 1 reply; 16+ messages in thread
From: Andrew Morton @ 2011-08-01 21:29 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: Éric Piel, Matthew Garrett, LKML, platform-driver-x86

On Mon, 1 Aug 2011 23:11:17 +0200
Christian Lamparter <chunkeey@googlemail.com> wrote:

> On Monday, August 01, 2011 10:29:06 PM Andrew Morton wrote:
> > On Mon, 25 Jul 2011 17:16:23 +0200
> > __ric Piel <eric.piel@tremplin-utc.net> wrote:
> > 
> > > +static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
> > > +{
> > > +	int div = lis3lv02d_get_odr();
> > > +
> > > +	if (WARN_ONCE(div == 0, "device returned spurious data"))
> > > +		return -ENXIO;
> > > +
> > > +	/* LIS3 power on delay is quite long */
> > > +	msleep(lis3->pwron_delay / div);
> > > +	return 0;
> > > +}
> > 
> > The WARN_ONCE may not be very useful.  The user gets worried, might
> > report it (often to a distro, not to you!).  But we won't actually *do*
> > anything with the information?
> The sensor is used to park the hdd in case of an "accident". However,
> if the sensors is not working, the user should at least get a WARN
> that something is very wrong, right?

Well if we're doing this for the user's benefit (most WARNs are for developers)
then the message should be user-useful.  That one isn't, really.

Can we come up with some text which is more useful to the user/operator and
won't require him/her/it to send emails and raise bug reports?

Also, the stack trace which WARN emits is not useful in this application?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked
  2011-08-01 21:29       ` Andrew Morton
@ 2011-08-03 13:21         ` Éric Piel
  0 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-08-03 13:21 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Christian Lamparter, Matthew Garrett, LKML, platform-driver-x86

Op 01-08-11 23:29, Andrew Morton schreef:
> On Mon, 1 Aug 2011 23:11:17 +0200
> Christian Lamparter<chunkeey@googlemail.com>  wrote:
>
>> On Monday, August 01, 2011 10:29:06 PM Andrew Morton wrote:
>>> On Mon, 25 Jul 2011 17:16:23 +0200
>>> __ric Piel<eric.piel@tremplin-utc.net>  wrote:
>>>
>>>> +static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
>>>> +{
>>>> +	int div = lis3lv02d_get_odr();
>>>> +
>>>> +	if (WARN_ONCE(div == 0, "device returned spurious data"))
>>>> +		return -ENXIO;
>>>> +
>>>> +	/* LIS3 power on delay is quite long */
>>>> +	msleep(lis3->pwron_delay / div);
>>>> +	return 0;
>>>> +}
>>>
>>> The WARN_ONCE may not be very useful.  The user gets worried, might
>>> report it (often to a distro, not to you!).  But we won't actually *do*
>>> anything with the information?
>> The sensor is used to park the hdd in case of an "accident". However,
>> if the sensors is not working, the user should at least get a WARN
>> that something is very wrong, right?
>
> Well if we're doing this for the user's benefit (most WARNs are for developers)
> then the message should be user-useful.  That one isn't, really.
>
> Can we come up with some text which is more useful to the user/operator and
> won't require him/her/it to send emails and raise bug reports?
>
> Also, the stack trace which WARN emits is not useful in this application?
Thanks Andrew for pointing out this.
Indeed, a WARN with such a message seems not the best way to explain 
what's is going on. IIRC, Christian suspects the bug happens due to some 
weird things that the bios does. So do you think this code looks better?

if (div == 0) {
   pr_warn_once("device returned spurious data, it will not be used. "
	       "It might be a hardware or firmware bug. "
	       "Contact the driver's authors if you think it is not.");
   return -ENXIO;
}

If every one likes it, I'll update the patch and send you the new version.

See you,
Éric

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 10/10 v2] lis3: Remove the references to the global variable in core driver
  2011-07-25 15:24 ` [PATCH 10/10] lis3: Remove the references to the global variable in core driver Éric Piel
@ 2011-08-03 13:47   ` Éric Piel
  0 siblings, 0 replies; 16+ messages in thread
From: Éric Piel @ 2011-08-03 13:47 UTC (permalink / raw)
  To: Andrew Morton, Ilkka Koskinen; +Cc: Thadeu Lima de Souza Cascardo, LKML

Op 25-07-11 17:24, Éric Piel schreef:
> Signed-off-by: Ilkka Koskinen<ilkka.koskinen@nokia.com>
> Signed-off-by: Éric Piel<eric.piel@tremplin-utc.net>
> ---
>   drivers/misc/lis3lv02d/lis3lv02d.c |  233 ++++++++++++++++++++----------------
>   drivers/misc/lis3lv02d/lis3lv02d.h |    3 +
>   2 files changed, 133 insertions(+), 103 deletions(-)
I'm terribly sorry, this version of the patch had a bug from a
last minute fix, preventing to even compile the driver.

Please find here a corrected version.

Thanks,
Éric
8<-------------------------------------------------------

From: Ilkka Koskinen <ilkka.koskinen@nokia.com>

Signed-off-by: Ilkka Koskinen <ilkka.koskinen@nokia.com>
Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
---
 drivers/misc/lis3lv02d/lis3lv02d.c |  233 ++++++++++++++++++++----------------
 drivers/misc/lis3lv02d/lis3lv02d.h |    3 +
 2 files changed, 133 insertions(+), 103 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 83ff7b4..e67dcea 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -163,7 +163,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 	int i;
 
 	if (lis3->blkread) {
-		if (lis3_dev.whoami == WAI_12B) {
+		if (lis3->whoami == WAI_12B) {
 			u16 data[3];
 			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
 			for (i = 0; i < 3; i++)
@@ -195,20 +195,20 @@ static int lis3_8_rates[2] = {100, 400};
 static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
 
 /* ODR is Output Data Rate */
-static int lis3lv02d_get_odr(void)
+static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
 {
 	u8 ctrl;
 	int shift;
 
-	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
-	ctrl &= lis3_dev.odr_mask;
-	shift = ffs(lis3_dev.odr_mask) - 1;
-	return lis3_dev.odrs[(ctrl >> shift)];
+	lis3->read(lis3, CTRL_REG1, &ctrl);
+	ctrl &= lis3->odr_mask;
+	shift = ffs(lis3->odr_mask) - 1;
+	return lis3->odrs[(ctrl >> shift)];
 }
 
 static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
 {
-	int div = lis3lv02d_get_odr();
+	int div = lis3lv02d_get_odr(lis3);
 
 	if (WARN_ONCE(div == 0, "device returned spurious data"))
 		return -ENXIO;
@@ -218,7 +218,7 @@ static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
 	return 0;
 }
 
-static int lis3lv02d_set_odr(int rate)
+static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate)
 {
 	u8 ctrl;
 	int i, len, shift;
@@ -226,14 +226,14 @@ static int lis3lv02d_set_odr(int rate)
 	if (!rate)
 		return -EINVAL;
 
-	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
-	ctrl &= ~lis3_dev.odr_mask;
-	len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
-	shift = ffs(lis3_dev.odr_mask) - 1;
+	lis3->read(lis3, CTRL_REG1, &ctrl);
+	ctrl &= ~lis3->odr_mask;
+	len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */
+	shift = ffs(lis3->odr_mask) - 1;
 
 	for (i = 0; i < len; i++)
-		if (lis3_dev.odrs[i] == rate) {
-			lis3_dev.write(&lis3_dev, CTRL_REG1,
+		if (lis3->odrs[i] == rate) {
+			lis3->write(lis3, CTRL_REG1,
 					ctrl | (i << shift));
 			return 0;
 		}
@@ -252,12 +252,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	mutex_lock(&lis3->mutex);
 
 	irq_cfg = lis3->irq_cfg;
-	if (lis3_dev.whoami == WAI_8B) {
+	if (lis3->whoami == WAI_8B) {
 		lis3->data_ready_count[IRQ_LINE0] = 0;
 		lis3->data_ready_count[IRQ_LINE1] = 0;
 
 		/* Change interrupt cfg to data ready for selftest */
-		atomic_inc(&lis3_dev.wake_thread);
+		atomic_inc(&lis3->wake_thread);
 		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
 		lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
 		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
@@ -265,12 +265,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
 	}
 
-	if (lis3_dev.whoami == WAI_3DC) {
+	if (lis3->whoami == WAI_3DC) {
 		ctlreg = CTRL_REG4;
 		selftest = CTRL4_ST0;
 	} else {
 		ctlreg = CTRL_REG1;
-		if (lis3_dev.whoami == WAI_12B)
+		if (lis3->whoami == WAI_12B)
 			selftest = CTRL1_ST;
 		else
 			selftest = CTRL1_STP;
@@ -299,9 +299,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 
 	ret = 0;
 
-	if (lis3_dev.whoami == WAI_8B) {
+	if (lis3->whoami == WAI_8B) {
 		/* Restore original interrupt configuration */
-		atomic_dec(&lis3_dev.wake_thread);
+		atomic_dec(&lis3->wake_thread);
 		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
 		lis3->irq_cfg = irq_cfg;
 
@@ -413,24 +413,27 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
 static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
 {
+	struct lis3lv02d *lis3 = pidev->private;
 	int x, y, z;
 
-	mutex_lock(&lis3_dev.mutex);
-	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+	mutex_lock(&lis3->mutex);
+	lis3lv02d_get_xyz(lis3, &x, &y, &z);
 	input_report_abs(pidev->input, ABS_X, x);
 	input_report_abs(pidev->input, ABS_Y, y);
 	input_report_abs(pidev->input, ABS_Z, z);
 	input_sync(pidev->input);
-	mutex_unlock(&lis3_dev.mutex);
+	mutex_unlock(&lis3->mutex);
 }
 
 static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 {
-	if (lis3_dev.pm_dev)
-		pm_runtime_get_sync(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = pidev->private;
 
-	if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
-		atomic_set(&lis3_dev.wake_thread, 1);
+	if (lis3->pm_dev)
+		pm_runtime_get_sync(lis3->pm_dev);
+
+	if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev)
+		atomic_set(&lis3->wake_thread, 1);
 	/*
 	 * Update coordinates for the case where poll interval is 0 and
 	 * the chip in running purely under interrupt control
@@ -440,14 +443,18 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
 {
-	atomic_set(&lis3_dev.wake_thread, 0);
-	if (lis3_dev.pm_dev)
-		pm_runtime_put(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = pidev->private;
+
+	atomic_set(&lis3->wake_thread, 0);
+	if (lis3->pm_dev)
+		pm_runtime_put(lis3->pm_dev);
 }
 
-static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
+static irqreturn_t lis302dl_interrupt(int irq, void *data)
 {
-	if (!test_bit(0, &lis3_dev.misc_opened))
+	struct lis3lv02d *lis3 = data;
+
+	if (!test_bit(0, &lis3->misc_opened))
 		goto out;
 
 	/*
@@ -455,12 +462,12 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 	 * the lid is closed. This leads to interrupts as soon as a little move
 	 * is done.
 	 */
-	atomic_inc(&lis3_dev.count);
+	atomic_inc(&lis3->count);
 
-	wake_up_interruptible(&lis3_dev.misc_wait);
-	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
+	wake_up_interruptible(&lis3->misc_wait);
+	kill_fasync(&lis3->async_queue, SIGIO, POLL_IN);
 out:
-	if (atomic_read(&lis3_dev.wake_thread))
+	if (atomic_read(&lis3->wake_thread))
 		return IRQ_WAKE_THREAD;
 	return IRQ_HANDLED;
 }
@@ -532,28 +539,37 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 
 static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
 {
-	if (test_and_set_bit(0, &lis3_dev.misc_opened))
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	if (test_and_set_bit(0, &lis3->misc_opened))
 		return -EBUSY; /* already open */
 
-	if (lis3_dev.pm_dev)
-		pm_runtime_get_sync(lis3_dev.pm_dev);
+	if (lis3->pm_dev)
+		pm_runtime_get_sync(lis3->pm_dev);
 
-	atomic_set(&lis3_dev.count, 0);
+	atomic_set(&lis3->count, 0);
 	return 0;
 }
 
 static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
-	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
-	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
-	if (lis3_dev.pm_dev)
-		pm_runtime_put(lis3_dev.pm_dev);
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	fasync_helper(-1, file, 0, &lis3->async_queue);
+	clear_bit(0, &lis3->misc_opened); /* release the device */
+	if (lis3->pm_dev)
+		pm_runtime_put(lis3->pm_dev);
 	return 0;
 }
 
 static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 				size_t count, loff_t *pos)
 {
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
 	DECLARE_WAITQUEUE(wait, current);
 	u32 data;
 	unsigned char byte_data;
@@ -562,10 +578,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 	if (count < 1)
 		return -EINVAL;
 
-	add_wait_queue(&lis3_dev.misc_wait, &wait);
+	add_wait_queue(&lis3->misc_wait, &wait);
 	while (true) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		data = atomic_xchg(&lis3_dev.count, 0);
+		data = atomic_xchg(&lis3->count, 0);
 		if (data)
 			break;
 
@@ -595,22 +611,28 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
 
 out:
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&lis3_dev.misc_wait, &wait);
+	remove_wait_queue(&lis3->misc_wait, &wait);
 
 	return retval;
 }
 
 static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
 {
-	poll_wait(file, &lis3_dev.misc_wait, wait);
-	if (atomic_read(&lis3_dev.count))
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	poll_wait(file, &lis3->misc_wait, wait);
+	if (atomic_read(&lis3->count))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
 
 static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
 {
-	return fasync_helper(fd, file, on, &lis3_dev.async_queue);
+	struct lis3lv02d *lis3 = container_of(file->private_data,
+					      struct lis3lv02d, miscdev);
+
+	return fasync_helper(fd, file, on, &lis3->async_queue);
 }
 
 static const struct file_operations lis3lv02d_misc_fops = {
@@ -623,12 +645,6 @@ static const struct file_operations lis3lv02d_misc_fops = {
 	.fasync  = lis3lv02d_misc_fasync,
 };
 
-static struct miscdevice lis3lv02d_misc_device = {
-	.minor   = MISC_DYNAMIC_MINOR,
-	.name    = "freefall",
-	.fops    = &lis3lv02d_misc_fops,
-};
-
 int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
 {
 	struct input_dev *input_dev;
@@ -636,51 +652,52 @@ int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
 	int max_val, fuzz, flat;
 	int btns[] = {BTN_X, BTN_Y, BTN_Z};
 
-	if (lis3_dev.idev)
+	if (lis3->idev)
 		return -EINVAL;
 
-	lis3_dev.idev = input_allocate_polled_device();
-	if (!lis3_dev.idev)
+	lis3->idev = input_allocate_polled_device();
+	if (!lis3->idev)
 		return -ENOMEM;
 
-	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
-	lis3_dev.idev->open = lis3lv02d_joystick_open;
-	lis3_dev.idev->close = lis3lv02d_joystick_close;
-	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
-	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
-	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
-	input_dev = lis3_dev.idev->input;
+	lis3->idev->poll = lis3lv02d_joystick_poll;
+	lis3->idev->open = lis3lv02d_joystick_open;
+	lis3->idev->close = lis3lv02d_joystick_close;
+	lis3->idev->poll_interval = MDPS_POLL_INTERVAL;
+	lis3->idev->poll_interval_min = MDPS_POLL_MIN;
+	lis3->idev->poll_interval_max = MDPS_POLL_MAX;
+	lis3->idev->private = lis3;
+	input_dev = lis3->idev->input;
 
 	input_dev->name       = "ST LIS3LV02DL Accelerometer";
 	input_dev->phys       = DRIVER_NAME "/input0";
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor  = 0;
-	input_dev->dev.parent = &lis3_dev.pdev->dev;
+	input_dev->dev.parent = &lis3->pdev->dev;
 
 	set_bit(EV_ABS, input_dev->evbit);
-	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
-	if (lis3_dev.whoami == WAI_12B) {
+	max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY;
+	if (lis3->whoami == WAI_12B) {
 		fuzz = LIS3_DEFAULT_FUZZ_12B;
 		flat = LIS3_DEFAULT_FLAT_12B;
 	} else {
 		fuzz = LIS3_DEFAULT_FUZZ_8B;
 		flat = LIS3_DEFAULT_FLAT_8B;
 	}
-	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
-	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
+	fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY;
+	flat = (flat * lis3->scale) / LIS3_ACCURACY;
 
 	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
 
-	lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns);
-	lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns);
-	lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns);
+	lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns);
+	lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns);
+	lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns);
 
-	err = input_register_polled_device(lis3_dev.idev);
+	err = input_register_polled_device(lis3->idev);
 	if (err) {
-		input_free_polled_device(lis3_dev.idev);
-		lis3_dev.idev = NULL;
+		input_free_polled_device(lis3->idev);
+		lis3->idev = NULL;
 	}
 
 	return err;
@@ -689,19 +706,19 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
 
 void lis3lv02d_joystick_disable(struct lis3lv02d *lis3)
 {
-	if (lis3_dev.irq)
-		free_irq(lis3_dev.irq, &lis3_dev);
-	if (lis3_dev.pdata && lis3_dev.pdata->irq2)
-		free_irq(lis3_dev.pdata->irq2, &lis3_dev);
+	if (lis3->irq)
+		free_irq(lis3->irq, lis3);
+	if (lis3->pdata && lis3->pdata->irq2)
+		free_irq(lis3->pdata->irq2, lis3);
 
-	if (!lis3_dev.idev)
+	if (!lis3->idev)
 		return;
 
-	if (lis3_dev.irq)
-		misc_deregister(&lis3lv02d_misc_device);
-	input_unregister_polled_device(lis3_dev.idev);
-	input_free_polled_device(lis3_dev.idev);
-	lis3_dev.idev = NULL;
+	if (lis3->irq)
+		misc_deregister(&lis3->miscdev);
+	input_unregister_polled_device(lis3->idev);
+	input_free_polled_device(lis3->idev);
+	lis3->idev = NULL;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
@@ -726,6 +743,7 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	s16 values[3];
 
 	static const char ok[] = "OK";
@@ -733,8 +751,8 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev,
 	static const char irq[] = "FAIL_IRQ";
 	const char *res;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	switch (lis3lv02d_selftest(&lis3_dev, values)) {
+	lis3lv02d_sysfs_poweron(lis3);
+	switch (lis3lv02d_selftest(lis3, values)) {
 	case SELFTEST_FAIL:
 		res = fail;
 		break;
@@ -753,33 +771,37 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev,
 static ssize_t lis3lv02d_position_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	int x, y, z;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	mutex_lock(&lis3_dev.mutex);
-	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
-	mutex_unlock(&lis3_dev.mutex);
+	lis3lv02d_sysfs_poweron(lis3);
+	mutex_lock(&lis3->mutex);
+	lis3lv02d_get_xyz(lis3, &x, &y, &z);
+	mutex_unlock(&lis3->mutex);
 	return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
 }
 
 static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
+
+	lis3lv02d_sysfs_poweron(lis3);
+	return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
 }
 
 static ssize_t lis3lv02d_rate_set(struct device *dev,
 				struct device_attribute *attr, const char *buf,
 				size_t count)
 {
+	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	unsigned long rate;
 
 	if (strict_strtoul(buf, 0, &rate))
 		return -EINVAL;
 
-	lis3lv02d_sysfs_poweron(&lis3_dev);
-	if (lis3lv02d_set_odr(rate))
+	lis3lv02d_sysfs_poweron(lis3);
+	if (lis3lv02d_set_odr(lis3, rate))
 		return -EINVAL;
 
 	return count;
@@ -808,6 +830,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
 	if (IS_ERR(lis3->pdev))
 		return PTR_ERR(lis3->pdev);
 
+	platform_set_drvdata(lis3->pdev, lis3);
 	return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
 }
 
@@ -821,7 +844,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 
 		/* SYSFS may have left chip running. Turn off if necessary */
 		if (!pm_runtime_suspended(lis3->pm_dev))
-			lis3lv02d_poweroff(&lis3_dev);
+			lis3lv02d_poweroff(lis3);
 
 		pm_runtime_disable(lis3->pm_dev);
 		pm_runtime_set_suspended(lis3->pm_dev);
@@ -848,7 +871,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
 			(p->click_thresh_y << 4));
 
 		if (lis3->idev) {
-			struct input_dev *input_dev = lis3_dev.idev->input;
+			struct input_dev *input_dev = lis3->idev->input;
 			input_set_capability(input_dev, EV_KEY, BTN_X);
 			input_set_capability(input_dev, EV_KEY, BTN_Y);
 			input_set_capability(input_dev, EV_KEY, BTN_Z);
@@ -879,7 +902,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
 					lis302dl_interrupt_thread2_8b,
 					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
 					(p->irq_flags2 & IRQF_TRIGGER_MASK),
-					DRIVER_NAME, &lis3_dev);
+					DRIVER_NAME, lis3);
 		if (err < 0)
 			pr_err("No second IRQ. Limited functionality\n");
 	}
@@ -975,7 +998,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 			lis3->write(lis3, CTRL_REG3, p->irq_cfg);
 
 		if (p->default_rate)
-			lis3lv02d_set_odr(p->default_rate);
+			lis3lv02d_set_odr(lis3, p->default_rate);
 	}
 
 	/* bail if we did not get an IRQ from the bus layer */
@@ -1004,14 +1027,18 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 				thread_fn,
 				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
 				irq_flags,
-				DRIVER_NAME, &lis3_dev);
+				DRIVER_NAME, lis3);
 
 	if (err < 0) {
 		pr_err("Cannot get IRQ\n");
 		goto out;
 	}
 
-	if (misc_register(&lis3lv02d_misc_device))
+	lis3->miscdev.minor	= MISC_DYNAMIC_MINOR;
+	lis3->miscdev.name	= "freefall";
+	lis3->miscdev.fops	= &lis3lv02d_misc_fops;
+
+	if (misc_register(&lis3->miscdev))
 		pr_err("misc_register failed\n");
 out:
 	return 0;
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h
index b94e723..2b1482a 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.h
+++ b/drivers/misc/lis3lv02d/lis3lv02d.h
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
 #include <linux/regulator/consumer.h>
+#include <linux/miscdevice.h>
 
 /*
  * This driver tries to support the "digital" accelerometer chips from
@@ -273,6 +274,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
+	struct miscdevice	miscdev;
+
 	int                     data_ready_count[2];
 	atomic_t		wake_thread;
 	unsigned char           irq_cfg;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-08-03 13:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-25 15:14 [PATCH 00/10] lis3: various fixes and enhancements Éric Piel
2011-07-25 15:16 ` [PATCH 01/10] lis3lv02d: avoid divide by zero due to unchecked Éric Piel
2011-08-01 20:29   ` Andrew Morton
2011-08-01 21:11     ` Christian Lamparter
2011-08-01 21:29       ` Andrew Morton
2011-08-03 13:21         ` Éric Piel
2011-07-25 15:17 ` [PATCH 02/10] lis3: update maintainer information Éric Piel
2011-07-25 15:18 ` [PATCH 03/10] lis3: add support for HP EliteBook 2730p Éric Piel
2011-07-25 15:19 ` [PATCH 04/10] lis3: add support for HP EliteBook 8540w Éric Piel
2011-07-25 15:19 ` [PATCH 05/10] hp_accel: Add HP ProBook 655x Éric Piel
2011-07-25 15:20 ` [PATCH 06/10] CONFIG_HP_ACCEL: Fix help text Éric Piel
2011-07-25 15:21 ` [PATCH 07/10] lis3: Free regulators if probe() fails Éric Piel
2011-07-25 15:22 ` [PATCH 08/10] lis3: Change naming to consistent Éric Piel
2011-07-25 15:23 ` [PATCH 09/10] lis3: Change exported function to use given Éric Piel
2011-07-25 15:24 ` [PATCH 10/10] lis3: Remove the references to the global variable in core driver Éric Piel
2011-08-03 13:47   ` [PATCH 10/10 v2] " Éric Piel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox