2017-04-24 13:33:46

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 00/10] fujitsu-laptop: use device-specific data instead of module-wide globals

fujitsu-laptop registers two ACPI drivers. Whenever an ACPI device with
a matching identifier is found by the ACPI bus, a new instance of the
relevant driver is bound to that ACPI device. However, both ACPI
drivers registered by fujitsu-laptop access module-wide global data
structures, assuming neither ACPI driver will ever be instantiated more
than once. While there are currently no indications of such issues
happening in the wild, it is theoretically possible for multiple
FUJ02B1/FUJ02E3 ACPI devices to be present in the firmware, which would
cause two instances of the relevant driver to simultaneously access
module-wide globals without any locking in place. Also, modern Fujitsu
laptops ship without the FUJ02B1 ACPI device present in firmware,
causing memory to be needlessly allocated inside fujitsu_init().

To future-proof the module and lay the groundwork for separating the two
aforementioned ACPI drivers into separate modules, move away from
module-wide global data structures by using device-specific data
instead.

This patch series was tested on a Lifebook S7020 and a Lifebook E744.

I found it challenging to adhere to the "one logical change per patch"
rule while touching code commonly used by almost all other module code.
If the changes introduced are illegible, I will be happy to further
explain and/or improve the series. Please also note that while the diff
stats for this series may seem daunting at first, using --color-words
should hopefully make reviewing much more manageable.

drivers/platform/x86/fujitsu-laptop.c | 460 +++++++++++++++++-----------------
1 file changed, 236 insertions(+), 224 deletions(-)

--
2.12.2


2017-04-24 13:34:37

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 06/10] platform/x86: fujitsu-laptop: allocate struct fujitsu_bl in acpi_fujitsu_bl_add()

Only allocate memory for struct fujitsu_bl when the FUJ02B1 ACPI device
is present. Use devm_kzalloc() for allocating memory to simplify
cleanup.

Until all backlight-related code is modified to only use device-specific
data, the pointer to the allocated memory still has to be stored in a
module-wide variable.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 536b601c7067..780e11b43d27 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -417,6 +417,7 @@ static int fujitsu_backlight_register(struct acpi_device *device)

static int acpi_fujitsu_bl_add(struct acpi_device *device)
{
+ struct fujitsu_bl *priv;
int state = 0;
int error;

@@ -426,10 +427,15 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
if (!device)
return -EINVAL;

+ priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ fujitsu_bl = priv;
fujitsu_bl->handle = device->handle;
sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_BL_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
- device->driver_data = fujitsu_bl;
+ device->driver_data = priv;

error = acpi_fujitsu_bl_input_setup(device);
if (error)
@@ -1018,13 +1024,9 @@ static int __init fujitsu_init(void)
if (acpi_disabled)
return -ENODEV;

- fujitsu_bl = kzalloc(sizeof(struct fujitsu_bl), GFP_KERNEL);
- if (!fujitsu_bl)
- return -ENOMEM;
-
ret = acpi_bus_register_driver(&acpi_fujitsu_bl_driver);
if (ret)
- goto err_free_fujitsu_bl;
+ return ret;

/* Register platform stuff */

@@ -1054,8 +1056,6 @@ static int __init fujitsu_init(void)
platform_driver_unregister(&fujitsu_pf_driver);
err_unregister_acpi:
acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver);
-err_free_fujitsu_bl:
- kfree(fujitsu_bl);

return ret;
}
@@ -1070,8 +1070,6 @@ static void __exit fujitsu_cleanup(void)

acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver);

- kfree(fujitsu_bl);
-
pr_info("driver unloaded\n");
}

--
2.12.2

2017-04-24 13:35:36

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 10/10] platform/x86: fujitsu-laptop: use device-specific data in remaining module code

To prevent using module-wide data in remaining module code, employ
acpi_driver_data() and dev_get_drvdata() to fetch device-specific data
to work on in each function. This makes the input local variables in
hotkey-related callbacks redundant, so remove them. Remove the
module-wide struct fujitsu_laptop as it is now redundant. Adjust
whitespace to make checkpatch happy.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 133 +++++++++++++++++-----------------
1 file changed, 66 insertions(+), 67 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 77082e35f26a..9275f3c829a2 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -154,8 +154,6 @@ struct fujitsu_laptop {
int flags_state;
};

-static struct fujitsu_laptop *fujitsu_laptop;
-
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
static u32 dbg_level = 0x03;
#endif
@@ -313,9 +311,11 @@ static const struct backlight_ops fujitsu_bl_ops = {
static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- if (!(fujitsu_laptop->flags_supported & FLAG_LID))
+ struct fujitsu_laptop *priv = dev_get_drvdata(dev);
+
+ if (!(priv->flags_supported & FLAG_LID))
return sprintf(buf, "unknown\n");
- if (fujitsu_laptop->flags_state & FLAG_LID)
+ if (priv->flags_state & FLAG_LID)
return sprintf(buf, "open\n");
else
return sprintf(buf, "closed\n");
@@ -324,9 +324,11 @@ static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- if (!(fujitsu_laptop->flags_supported & FLAG_DOCK))
+ struct fujitsu_laptop *priv = dev_get_drvdata(dev);
+
+ if (!(priv->flags_supported & FLAG_DOCK))
return sprintf(buf, "unknown\n");
- if (fujitsu_laptop->flags_state & FLAG_DOCK)
+ if (priv->flags_state & FLAG_DOCK)
return sprintf(buf, "docked\n");
else
return sprintf(buf, "undocked\n");
@@ -335,9 +337,11 @@ static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
static ssize_t radios_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- if (!(fujitsu_laptop->flags_supported & FLAG_RFKILL))
+ struct fujitsu_laptop *priv = dev_get_drvdata(dev);
+
+ if (!(priv->flags_supported & FLAG_RFKILL))
return sprintf(buf, "unknown\n");
- if (fujitsu_laptop->flags_state & FLAG_RFKILL)
+ if (priv->flags_state & FLAG_RFKILL)
return sprintf(buf, "on\n");
else
return sprintf(buf, "killed\n");
@@ -598,19 +602,22 @@ static int acpi_fujitsu_laptop_input_setup(struct acpi_device *device)
return input_register_device(priv->input);
}

-static int fujitsu_laptop_platform_add(void)
+static int fujitsu_laptop_platform_add(struct acpi_device *device)
{
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
int ret;

- fujitsu_laptop->pf_device = platform_device_alloc("fujitsu-laptop", -1);
- if (!fujitsu_laptop->pf_device)
+ priv->pf_device = platform_device_alloc("fujitsu-laptop", -1);
+ if (!priv->pf_device)
return -ENOMEM;

- ret = platform_device_add(fujitsu_laptop->pf_device);
+ platform_set_drvdata(priv->pf_device, priv);
+
+ ret = platform_device_add(priv->pf_device);
if (ret)
goto err_put_platform_device;

- ret = sysfs_create_group(&fujitsu_laptop->pf_device->dev.kobj,
+ ret = sysfs_create_group(&priv->pf_device->dev.kobj,
&fujitsu_pf_attribute_group);
if (ret)
goto err_del_platform_device;
@@ -618,18 +625,20 @@ static int fujitsu_laptop_platform_add(void)
return 0;

err_del_platform_device:
- platform_device_del(fujitsu_laptop->pf_device);
+ platform_device_del(priv->pf_device);
err_put_platform_device:
- platform_device_put(fujitsu_laptop->pf_device);
+ platform_device_put(priv->pf_device);

return ret;
}

-static void fujitsu_laptop_platform_remove(void)
+static void fujitsu_laptop_platform_remove(struct acpi_device *device)
{
- sysfs_remove_group(&fujitsu_laptop->pf_device->dev.kobj,
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
+
+ sysfs_remove_group(&priv->pf_device->dev.kobj,
&fujitsu_pf_attribute_group);
- platform_device_unregister(fujitsu_laptop->pf_device);
+ platform_device_unregister(priv->pf_device);
}

static int logolamp_set(struct led_classdev *cdev,
@@ -813,17 +822,16 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
if (!priv)
return -ENOMEM;

- fujitsu_laptop = priv;
- fujitsu_laptop->handle = device->handle;
+ priv->handle = device->handle;
sprintf(acpi_device_name(device), "%s",
ACPI_FUJITSU_LAPTOP_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = priv;

/* kfifo */
- spin_lock_init(&fujitsu_laptop->fifo_lock);
- error = kfifo_alloc(&fujitsu_laptop->fifo, RINGBUFFERSIZE * sizeof(int),
- GFP_KERNEL);
+ spin_lock_init(&priv->fifo_lock);
+ error = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int),
+ GFP_KERNEL);
if (error) {
pr_err("kfifo_alloc failed\n");
goto err_stop;
@@ -833,7 +841,7 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
if (error)
goto err_free_fifo;

- error = acpi_bus_update_power(fujitsu_laptop->handle, &state);
+ error = acpi_bus_update_power(priv->handle, &state);
if (error) {
pr_err("Error reading power state\n");
goto err_free_fifo;
@@ -843,50 +851,47 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off");

- fujitsu_laptop->dev = device;
+ priv->dev = device;

- if (acpi_has_method(device->handle, METHOD_NAME__INI)) {
+ if (acpi_has_method(priv->handle, METHOD_NAME__INI)) {
vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
if (ACPI_FAILURE
(acpi_evaluate_object
- (device->handle, METHOD_NAME__INI, NULL, NULL)))
+ (priv->handle, METHOD_NAME__INI, NULL, NULL)))
pr_err("_INI Method failed\n");
}

i = 0;
- while (fext_buttons(fujitsu_laptop->handle, 0x1, 0x0, 0x0) != 0 &&
+ while (fext_buttons(priv->handle, 0x1, 0x0, 0x0) != 0 &&
i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
; /* No action, result is discarded */
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);

- fujitsu_laptop->flags_supported = fext_flags(fujitsu_laptop->handle,
- 0x0, 0x0, 0x0);
+ priv->flags_supported = fext_flags(priv->handle, 0x0, 0x0, 0x0);

/* Make sure our bitmask of supported functions is cleared if the
RFKILL function block is not implemented, like on the S7020. */
- if (fujitsu_laptop->flags_supported == UNSUPPORTED_CMD)
- fujitsu_laptop->flags_supported = 0;
+ if (priv->flags_supported == UNSUPPORTED_CMD)
+ priv->flags_supported = 0;

- if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state = fext_flags(fujitsu_laptop->handle,
- 0x4, 0x0, 0x0);
+ if (priv->flags_supported)
+ priv->flags_state = fext_flags(priv->handle, 0x4, 0x0, 0x0);

/* Suspect this is a keymap of the application panel, print it */
- pr_info("BTNI: [0x%x]\n", fext_buttons(fujitsu_laptop->handle,
- 0x0, 0x0, 0x0));
+ pr_info("BTNI: [0x%x]\n", fext_buttons(priv->handle, 0x0, 0x0, 0x0));

error = acpi_fujitsu_laptop_leds_register(device);
if (error)
goto err_free_fifo;

- error = fujitsu_laptop_platform_add();
+ error = fujitsu_laptop_platform_add(device);
if (error)
goto err_free_fifo;

return 0;

err_free_fifo:
- kfifo_free(&fujitsu_laptop->fifo);
+ kfifo_free(&priv->fifo);
err_stop:
return error;
}
@@ -895,44 +900,42 @@ static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
{
struct fujitsu_laptop *priv = acpi_driver_data(device);

- fujitsu_laptop_platform_remove();
+ fujitsu_laptop_platform_remove(device);

kfifo_free(&priv->fifo);

return 0;
}

-static void acpi_fujitsu_laptop_press(int scancode)
+static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)
{
- struct input_dev *input = fujitsu_laptop->input;
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
int status;

- status = kfifo_in_locked(&fujitsu_laptop->fifo,
- (unsigned char *)&scancode, sizeof(scancode),
- &fujitsu_laptop->fifo_lock);
+ status = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode,
+ sizeof(scancode), &priv->fifo_lock);
if (status != sizeof(scancode)) {
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Could not push scancode [0x%x]\n", scancode);
return;
}
- sparse_keymap_report_event(input, scancode, 1, false);
+ sparse_keymap_report_event(priv->input, scancode, 1, false);
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"Push scancode into ringbuffer [0x%x]\n", scancode);
}

-static void acpi_fujitsu_laptop_release(void)
+static void acpi_fujitsu_laptop_release(struct acpi_device *device)
{
- struct input_dev *input = fujitsu_laptop->input;
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
int scancode, status;

while (true) {
- status = kfifo_out_locked(&fujitsu_laptop->fifo,
+ status = kfifo_out_locked(&priv->fifo,
(unsigned char *)&scancode,
- sizeof(scancode),
- &fujitsu_laptop->fifo_lock);
+ sizeof(scancode), &priv->fifo_lock);
if (status != sizeof(scancode))
return;
- sparse_keymap_report_event(input, scancode, 0, false);
+ sparse_keymap_report_event(priv->input, scancode, 0, false);
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"Pop scancode from ringbuffer [0x%x]\n", scancode);
}
@@ -940,31 +943,27 @@ static void acpi_fujitsu_laptop_release(void)

static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
{
- struct input_dev *input;
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
int scancode, i = 0;
unsigned int irb;

- input = fujitsu_laptop->input;
-
if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Unsupported event [0x%x]\n", event);
- sparse_keymap_report_event(input, -1, 1, true);
+ sparse_keymap_report_event(priv->input, -1, 1, true);
return;
}

- if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state = fext_flags(fujitsu_laptop->handle,
- 0x4, 0x0, 0x0);
+ if (priv->flags_supported)
+ priv->flags_state = fext_flags(priv->handle, 0x4, 0x0, 0x0);

- while ((irb = fext_buttons(fujitsu_laptop->handle,
- 0x1, 0x0, 0x0)) != 0 &&
+ while ((irb = fext_buttons(priv->handle, 0x1, 0x0, 0x0)) != 0 &&
i++ < MAX_HOTKEY_RINGBUFFER_SIZE) {
scancode = irb & 0x4ff;
- if (sparse_keymap_entry_from_scancode(input, scancode))
- acpi_fujitsu_laptop_press(scancode);
+ if (sparse_keymap_entry_from_scancode(priv->input, scancode))
+ acpi_fujitsu_laptop_press(device, scancode);
else if (scancode == 0)
- acpi_fujitsu_laptop_release();
+ acpi_fujitsu_laptop_release(device);
else
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Unknown GIRB result [%x]\n", irb);
@@ -974,9 +973,9 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
* E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
* handled in software; its state is queried using FUNC_FLAGS
*/
- if ((fujitsu_laptop->flags_supported & BIT(26)) &&
- (fext_flags(fujitsu_laptop->handle, 0x1, 0x0, 0x0) & BIT(26)))
- sparse_keymap_report_event(input, BIT(26), 1, true);
+ if ((priv->flags_supported & BIT(26)) &&
+ (fext_flags(priv->handle, 0x1, 0x0, 0x0) & BIT(26)))
+ sparse_keymap_report_event(priv->input, BIT(26), 1, true);
}

/* Initialization */
--
2.12.2

2017-04-24 13:35:57

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 08/10] platform/x86: fujitsu-laptop: allocate struct fujitsu_laptop in acpi_fujitsu_laptop_add()

Only allocate memory for struct fujitsu_laptop when the FUJ02E3 ACPI
device is present. Use devm_kzalloc() for allocating memory to simplify
cleanup.

Until all remaining module code is modified to only use device-specific
data, the pointer to the allocated memory still has to be stored in a
module-wide variable.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index fb46652250c7..f26abc41266e 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -808,6 +808,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)

static int acpi_fujitsu_laptop_add(struct acpi_device *device)
{
+ struct fujitsu_laptop *priv;
int state = 0;
int error;
int i;
@@ -815,11 +816,16 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
if (!device)
return -EINVAL;

+ priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ fujitsu_laptop = priv;
fujitsu_laptop->handle = device->handle;
sprintf(acpi_device_name(device), "%s",
ACPI_FUJITSU_LAPTOP_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
- device->driver_data = fujitsu_laptop;
+ device->driver_data = priv;

/* kfifo */
spin_lock_init(&fujitsu_laptop->fifo_lock);
@@ -1039,22 +1045,14 @@ static int __init fujitsu_init(void)

/* Register laptop driver */

- fujitsu_laptop = kzalloc(sizeof(struct fujitsu_laptop), GFP_KERNEL);
- if (!fujitsu_laptop) {
- ret = -ENOMEM;
- goto err_unregister_platform_driver;
- }
-
ret = acpi_bus_register_driver(&acpi_fujitsu_laptop_driver);
if (ret)
- goto err_free_fujitsu_laptop;
+ goto err_unregister_platform_driver;

pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n");

return 0;

-err_free_fujitsu_laptop:
- kfree(fujitsu_laptop);
err_unregister_platform_driver:
platform_driver_unregister(&fujitsu_pf_driver);
err_unregister_acpi:
@@ -1067,8 +1065,6 @@ static void __exit fujitsu_cleanup(void)
{
acpi_bus_unregister_driver(&acpi_fujitsu_laptop_driver);

- kfree(fujitsu_laptop);
-
platform_driver_unregister(&fujitsu_pf_driver);

acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver);
--
2.12.2

2017-04-24 13:36:17

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 02/10] platform/x86: fujitsu-laptop: shorten names of acpi_handle fields

As both struct fujitsu_bl and struct fujitsu_laptop represent data
associated with ACPI devices, drop the "acpi_" prefix from the names of
the relevant fields of these structures to save some horizontal space.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 3f232967af04..3695e8075aa6 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -130,7 +130,7 @@

/* Device controlling the backlight and associated keys */
struct fujitsu_bl {
- acpi_handle acpi_handle;
+ acpi_handle handle;
struct input_dev *input;
char phys[32];
struct backlight_device *bl_device;
@@ -144,7 +144,7 @@ static bool disable_brightness_adjust;

/* Device used to access hotkeys and other features on the laptop */
struct fujitsu_laptop {
- acpi_handle acpi_handle;
+ acpi_handle handle;
struct acpi_device *dev;
struct input_dev *input;
char phys[32];
@@ -175,7 +175,7 @@ static int call_fext_func(int func, int op, int feature, int state)
unsigned long long value;
acpi_status status;

- status = acpi_evaluate_integer(fujitsu_laptop->acpi_handle, "FUNC",
+ status = acpi_evaluate_integer(fujitsu_laptop->handle, "FUNC",
&arg_list, &value);
if (ACPI_FAILURE(status)) {
vdbg_printk(FUJLAPTOP_DBG_ERROR, "Failed to evaluate FUNC\n");
@@ -216,7 +216,7 @@ static int set_lcd_level(int level)

switch (use_alt_lcd_levels) {
case -1:
- if (acpi_has_method(fujitsu_bl->acpi_handle, "SBL2"))
+ if (acpi_has_method(fujitsu_bl->handle, "SBL2"))
method = "SBL2";
else
method = "SBLL";
@@ -235,8 +235,7 @@ static int set_lcd_level(int level)
if (level < 0 || level >= fujitsu_bl->max_brightness)
return -EINVAL;

- status = acpi_execute_simple_method(fujitsu_bl->acpi_handle, method,
- level);
+ status = acpi_execute_simple_method(fujitsu_bl->handle, method, level);
if (ACPI_FAILURE(status)) {
vdbg_printk(FUJLAPTOP_DBG_ERROR, "Failed to evaluate %s\n",
method);
@@ -255,7 +254,7 @@ static int get_lcd_level(void)

vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");

- status = acpi_evaluate_integer(fujitsu_bl->acpi_handle, "GBLL", NULL,
+ status = acpi_evaluate_integer(fujitsu_bl->handle, "GBLL", NULL,
&state);
if (ACPI_FAILURE(status))
return 0;
@@ -272,7 +271,7 @@ static int get_max_brightness(void)

vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");

- status = acpi_evaluate_integer(fujitsu_bl->acpi_handle, "RBLL", NULL,
+ status = acpi_evaluate_integer(fujitsu_bl->handle, "RBLL", NULL,
&state);
if (ACPI_FAILURE(status))
return -1;
@@ -421,7 +420,7 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
if (!device)
return -EINVAL;

- fujitsu_bl->acpi_handle = device->handle;
+ fujitsu_bl->handle = device->handle;
sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_BL_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = fujitsu_bl;
@@ -430,7 +429,7 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
if (error)
return error;

- error = acpi_bus_update_power(fujitsu_bl->acpi_handle, &state);
+ error = acpi_bus_update_power(fujitsu_bl->handle, &state);
if (error) {
pr_err("Error reading power state\n");
return error;
@@ -791,7 +790,7 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
if (!device)
return -EINVAL;

- fujitsu_laptop->acpi_handle = device->handle;
+ fujitsu_laptop->handle = device->handle;
sprintf(acpi_device_name(device), "%s",
ACPI_FUJITSU_LAPTOP_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
@@ -810,7 +809,7 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
if (error)
goto err_free_fifo;

- error = acpi_bus_update_power(fujitsu_laptop->acpi_handle, &state);
+ error = acpi_bus_update_power(fujitsu_laptop->handle, &state);
if (error) {
pr_err("Error reading power state\n");
goto err_free_fifo;
--
2.12.2

2017-04-24 13:34:18

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 05/10] platform/x86: fujitsu-laptop: distinguish current uses of device-specific data

In portions of the driver which use device-specific data, rename local
variables from fujitsu_bl and fujitsu_laptop to priv in order to clearly
distinguish these parts from code that uses module-wide data.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 48 +++++++++++++++++------------------
1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 5f6b34a97348..536b601c7067 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -369,26 +369,26 @@ static const struct key_entry keymap_backlight[] = {

static int acpi_fujitsu_bl_input_setup(struct acpi_device *device)
{
- struct fujitsu_bl *fujitsu_bl = acpi_driver_data(device);
+ struct fujitsu_bl *priv = acpi_driver_data(device);
int ret;

- fujitsu_bl->input = devm_input_allocate_device(&device->dev);
- if (!fujitsu_bl->input)
+ priv->input = devm_input_allocate_device(&device->dev);
+ if (!priv->input)
return -ENOMEM;

- snprintf(fujitsu_bl->phys, sizeof(fujitsu_bl->phys),
- "%s/video/input0", acpi_device_hid(device));
+ snprintf(priv->phys, sizeof(priv->phys), "%s/video/input0",
+ acpi_device_hid(device));

- fujitsu_bl->input->name = acpi_device_name(device);
- fujitsu_bl->input->phys = fujitsu_bl->phys;
- fujitsu_bl->input->id.bustype = BUS_HOST;
- fujitsu_bl->input->id.product = 0x06;
+ priv->input->name = acpi_device_name(device);
+ priv->input->phys = priv->phys;
+ priv->input->id.bustype = BUS_HOST;
+ priv->input->id.product = 0x06;

- ret = sparse_keymap_setup(fujitsu_bl->input, keymap_backlight, NULL);
+ ret = sparse_keymap_setup(priv->input, keymap_backlight, NULL);
if (ret)
return ret;

- return input_register_device(fujitsu_bl->input);
+ return input_register_device(priv->input);
}

static int fujitsu_backlight_register(struct acpi_device *device)
@@ -566,27 +566,27 @@ static const struct dmi_system_id fujitsu_laptop_dmi_table[] = {

static int acpi_fujitsu_laptop_input_setup(struct acpi_device *device)
{
- struct fujitsu_laptop *fujitsu_laptop = acpi_driver_data(device);
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
int ret;

- fujitsu_laptop->input = devm_input_allocate_device(&device->dev);
- if (!fujitsu_laptop->input)
+ priv->input = devm_input_allocate_device(&device->dev);
+ if (!priv->input)
return -ENOMEM;

- snprintf(fujitsu_laptop->phys, sizeof(fujitsu_laptop->phys),
- "%s/video/input0", acpi_device_hid(device));
+ snprintf(priv->phys, sizeof(priv->phys), "%s/video/input0",
+ acpi_device_hid(device));

- fujitsu_laptop->input->name = acpi_device_name(device);
- fujitsu_laptop->input->phys = fujitsu_laptop->phys;
- fujitsu_laptop->input->id.bustype = BUS_HOST;
- fujitsu_laptop->input->id.product = 0x06;
+ priv->input->name = acpi_device_name(device);
+ priv->input->phys = priv->phys;
+ priv->input->id.bustype = BUS_HOST;
+ priv->input->id.product = 0x06;

dmi_check_system(fujitsu_laptop_dmi_table);
- ret = sparse_keymap_setup(fujitsu_laptop->input, keymap, NULL);
+ ret = sparse_keymap_setup(priv->input, keymap, NULL);
if (ret)
return ret;

- return input_register_device(fujitsu_laptop->input);
+ return input_register_device(priv->input);
}

static int fujitsu_laptop_platform_add(void)
@@ -885,11 +885,11 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)

static int acpi_fujitsu_laptop_remove(struct acpi_device *device)
{
- struct fujitsu_laptop *fujitsu_laptop = acpi_driver_data(device);
+ struct fujitsu_laptop *priv = acpi_driver_data(device);

fujitsu_laptop_platform_remove();

- kfifo_free(&fujitsu_laptop->fifo);
+ kfifo_free(&priv->fifo);

return 0;
}
--
2.12.2

2017-04-24 13:36:08

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 07/10] platform/x86: fujitsu-laptop: use device-specific data in backlight code

To prevent using module-wide data in backlight-related code, employ
acpi_driver_data() and bl_get_data() to fetch device-specific data to
work on in each function. This makes the input local variable in
acpi_fujitsu_bl_notify() redundant, so remove it. Remove the
module-wide struct fujitsu_bl as it is now redundant.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 89 ++++++++++++++++++-----------------
1 file changed, 46 insertions(+), 43 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 780e11b43d27..fb46652250c7 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -138,7 +138,6 @@ struct fujitsu_bl {
unsigned int brightness_level;
};

-static struct fujitsu_bl *fujitsu_bl;
static int use_alt_lcd_levels = -1;
static bool disable_brightness_adjust;

@@ -209,14 +208,15 @@ static int fext_leds(acpi_handle handle, int op, int feature, int state)

/* Hardware access for LCD brightness control */

-static int set_lcd_level(int level)
+static int set_lcd_level(struct acpi_device *device, int level)
{
+ struct fujitsu_bl *priv = acpi_driver_data(device);
acpi_status status;
char *method;

switch (use_alt_lcd_levels) {
case -1:
- if (acpi_has_method(fujitsu_bl->handle, "SBL2"))
+ if (acpi_has_method(priv->handle, "SBL2"))
method = "SBL2";
else
method = "SBLL";
@@ -232,72 +232,77 @@ static int set_lcd_level(int level)
vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via %s [%d]\n",
method, level);

- if (level < 0 || level >= fujitsu_bl->max_brightness)
+ if (level < 0 || level >= priv->max_brightness)
return -EINVAL;

- status = acpi_execute_simple_method(fujitsu_bl->handle, method, level);
+ status = acpi_execute_simple_method(priv->handle, method, level);
if (ACPI_FAILURE(status)) {
vdbg_printk(FUJLAPTOP_DBG_ERROR, "Failed to evaluate %s\n",
method);
return -ENODEV;
}

- fujitsu_bl->brightness_level = level;
+ priv->brightness_level = level;

return 0;
}

-static int get_lcd_level(void)
+static int get_lcd_level(struct acpi_device *device)
{
+ struct fujitsu_bl *priv = acpi_driver_data(device);
unsigned long long state = 0;
acpi_status status = AE_OK;

vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");

- status = acpi_evaluate_integer(fujitsu_bl->handle, "GBLL", NULL,
- &state);
+ status = acpi_evaluate_integer(priv->handle, "GBLL", NULL, &state);
if (ACPI_FAILURE(status))
return 0;

- fujitsu_bl->brightness_level = state & 0x0fffffff;
+ priv->brightness_level = state & 0x0fffffff;

- return fujitsu_bl->brightness_level;
+ return priv->brightness_level;
}

-static int get_max_brightness(void)
+static int get_max_brightness(struct acpi_device *device)
{
+ struct fujitsu_bl *priv = acpi_driver_data(device);
unsigned long long state = 0;
acpi_status status = AE_OK;

vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");

- status = acpi_evaluate_integer(fujitsu_bl->handle, "RBLL", NULL,
- &state);
+ status = acpi_evaluate_integer(priv->handle, "RBLL", NULL, &state);
if (ACPI_FAILURE(status))
return -1;

- fujitsu_bl->max_brightness = state;
+ priv->max_brightness = state;

- return fujitsu_bl->max_brightness;
+ return priv->max_brightness;
}

/* Backlight device stuff */

static int bl_get_brightness(struct backlight_device *b)
{
- return b->props.power == FB_BLANK_POWERDOWN ? 0 : get_lcd_level();
+ struct acpi_device *device = bl_get_data(b);
+
+ return b->props.power == FB_BLANK_POWERDOWN ? 0 : get_lcd_level(device);
}

static int bl_update_status(struct backlight_device *b)
{
- if (fujitsu_bl->fext_handle) {
+ struct acpi_device *device = bl_get_data(b);
+ struct fujitsu_bl *priv = acpi_driver_data(device);
+
+ if (priv->fext_handle) {
if (b->props.power == FB_BLANK_POWERDOWN)
- fext_backlight(fujitsu_bl->fext_handle, 0x1, 0x4, 0x3);
+ fext_backlight(priv->fext_handle, 0x1, 0x4, 0x3);
else
- fext_backlight(fujitsu_bl->fext_handle, 0x1, 0x4, 0x0);
+ fext_backlight(priv->fext_handle, 0x1, 0x4, 0x0);
}

- return set_lcd_level(b->props.brightness);
+ return set_lcd_level(device, b->props.brightness);
}

static const struct backlight_ops fujitsu_bl_ops = {
@@ -393,23 +398,24 @@ static int acpi_fujitsu_bl_input_setup(struct acpi_device *device)

static int fujitsu_backlight_register(struct acpi_device *device)
{
+ struct fujitsu_bl *priv = acpi_driver_data(device);
const struct backlight_properties props = {
- .brightness = fujitsu_bl->brightness_level,
- .max_brightness = fujitsu_bl->max_brightness - 1,
+ .brightness = priv->brightness_level,
+ .max_brightness = priv->max_brightness - 1,
.type = BACKLIGHT_PLATFORM
};
struct backlight_device *bd;
acpi_status status;

bd = devm_backlight_device_register(&device->dev, "fujitsu-laptop",
- &device->dev, NULL,
+ &device->dev, device,
&fujitsu_bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);

- status = acpi_get_handle(NULL, "\\_SB.FEXT", &fujitsu_bl->fext_handle);
+ status = acpi_get_handle(NULL, "\\_SB.FEXT", &priv->fext_handle);
if (ACPI_SUCCESS(status) &&
- fext_backlight(fujitsu_bl->fext_handle, 0x2, 0x4, 0x0) == 3)
+ fext_backlight(priv->fext_handle, 0x2, 0x4, 0x0) == 3)
bd->props.power = FB_BLANK_POWERDOWN;

return 0;
@@ -431,8 +437,7 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
if (!priv)
return -ENOMEM;

- fujitsu_bl = priv;
- fujitsu_bl->handle = device->handle;
+ priv->handle = device->handle;
sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_BL_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = priv;
@@ -441,7 +446,7 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
if (error)
return error;

- error = acpi_bus_update_power(fujitsu_bl->handle, &state);
+ error = acpi_bus_update_power(priv->handle, &state);
if (error) {
pr_err("Error reading power state\n");
return error;
@@ -451,17 +456,17 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)
acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off");

- if (acpi_has_method(device->handle, METHOD_NAME__INI)) {
+ if (acpi_has_method(priv->handle, METHOD_NAME__INI)) {
vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
if (ACPI_FAILURE
(acpi_evaluate_object
- (device->handle, METHOD_NAME__INI, NULL, NULL)))
+ (priv->handle, METHOD_NAME__INI, NULL, NULL)))
pr_err("_INI Method failed\n");
}

- if (get_max_brightness() <= 0)
- fujitsu_bl->max_brightness = FUJITSU_LCD_N_LEVELS;
- get_lcd_level();
+ if (get_max_brightness(device) <= 0)
+ priv->max_brightness = FUJITSU_LCD_N_LEVELS;
+ get_lcd_level(device);

error = fujitsu_backlight_register(device);
if (error)
@@ -474,21 +479,19 @@ static int acpi_fujitsu_bl_add(struct acpi_device *device)

static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
{
- struct input_dev *input;
+ struct fujitsu_bl *priv = acpi_driver_data(device);
int oldb, newb;

- input = fujitsu_bl->input;
-
if (event != ACPI_FUJITSU_NOTIFY_CODE1) {
vdbg_printk(FUJLAPTOP_DBG_WARN,
"unsupported event [0x%x]\n", event);
- sparse_keymap_report_event(input, -1, 1, true);
+ sparse_keymap_report_event(priv->input, -1, 1, true);
return;
}

- oldb = fujitsu_bl->brightness_level;
- get_lcd_level();
- newb = fujitsu_bl->brightness_level;
+ oldb = priv->brightness_level;
+ get_lcd_level(device);
+ newb = priv->brightness_level;

vdbg_printk(FUJLAPTOP_DBG_TRACE, "brightness button event [%i -> %i]\n",
oldb, newb);
@@ -497,9 +500,9 @@ static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
return;

if (!disable_brightness_adjust)
- set_lcd_level(newb);
+ set_lcd_level(device, newb);

- sparse_keymap_report_event(input, oldb < newb, 1, true);
+ sparse_keymap_report_event(priv->input, oldb < newb, 1, true);
}

/* ACPI device for hotkey handling */
--
2.12.2

2017-04-24 13:36:26

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 01/10] platform/x86: fujitsu-laptop: introduce fext_*() helper functions

Stop invoking call_fext_func() directly to improve code clarity and save
some horizontal space. Adjust whitespace to make checkpatch happy.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 90 ++++++++++++++++++++---------------
1 file changed, 51 insertions(+), 39 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 7f49d92914c9..3f232967af04 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -187,6 +187,26 @@ static int call_fext_func(int func, int op, int feature, int state)
return value;
}

+static int fext_backlight(int op, int feature, int state)
+{
+ return call_fext_func(FUNC_BACKLIGHT, op, feature, state);
+}
+
+static int fext_buttons(int op, int feature, int state)
+{
+ return call_fext_func(FUNC_BUTTONS, op, feature, state);
+}
+
+static int fext_flags(int op, int feature, int state)
+{
+ return call_fext_func(FUNC_FLAGS, op, feature, state);
+}
+
+static int fext_leds(int op, int feature, int state)
+{
+ return call_fext_func(FUNC_LEDS, op, feature, state);
+}
+
/* Hardware access for LCD brightness control */

static int set_lcd_level(int level)
@@ -272,9 +292,9 @@ static int bl_get_brightness(struct backlight_device *b)
static int bl_update_status(struct backlight_device *b)
{
if (b->props.power == FB_BLANK_POWERDOWN)
- call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x3);
+ fext_backlight(0x1, 0x4, 0x3);
else
- call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x0);
+ fext_backlight(0x1, 0x4, 0x0);

return set_lcd_level(b->props.brightness);
}
@@ -610,22 +630,22 @@ static int logolamp_set(struct led_classdev *cdev,
if (brightness < LED_FULL)
always = FUNC_LED_OFF;

- ret = call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
+ ret = fext_leds(0x1, LOGOLAMP_POWERON, poweron);
if (ret < 0)
return ret;

- return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
+ return fext_leds(0x1, LOGOLAMP_ALWAYS, always);
}

static enum led_brightness logolamp_get(struct led_classdev *cdev)
{
int ret;

- ret = call_fext_func(FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
+ ret = fext_leds(0x2, LOGOLAMP_ALWAYS, 0x0);
if (ret == FUNC_LED_ON)
return LED_FULL;

- ret = call_fext_func(FUNC_LEDS, 0x2, LOGOLAMP_POWERON, 0x0);
+ ret = fext_leds(0x2, LOGOLAMP_POWERON, 0x0);
if (ret == FUNC_LED_ON)
return LED_HALF;

@@ -642,18 +662,16 @@ static int kblamps_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
- FUNC_LED_ON);
+ return fext_leds(0x1, KEYBOARD_LAMPS, FUNC_LED_ON);
else
- return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
- FUNC_LED_OFF);
+ return fext_leds(0x1, KEYBOARD_LAMPS, FUNC_LED_OFF);
}

static enum led_brightness kblamps_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (call_fext_func(FUNC_LEDS, 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
+ if (fext_leds(0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -669,17 +687,16 @@ static int radio_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- return call_fext_func(FUNC_FLAGS, 0x5, RADIO_LED_ON,
- RADIO_LED_ON);
+ return fext_flags(0x5, RADIO_LED_ON, RADIO_LED_ON);
else
- return call_fext_func(FUNC_FLAGS, 0x5, RADIO_LED_ON, 0x0);
+ return fext_flags(0x5, RADIO_LED_ON, 0x0);
}

static enum led_brightness radio_led_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0) & RADIO_LED_ON)
+ if (fext_flags(0x4, 0x0, 0x0) & RADIO_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -697,20 +714,18 @@ static int eco_led_set(struct led_classdev *cdev,
{
int curr;

- curr = call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0);
+ curr = fext_leds(0x2, ECO_LED, 0x0);
if (brightness >= LED_FULL)
- return call_fext_func(FUNC_LEDS, 0x1, ECO_LED,
- curr | ECO_LED_ON);
+ return fext_leds(0x1, ECO_LED, curr | ECO_LED_ON);
else
- return call_fext_func(FUNC_LEDS, 0x1, ECO_LED,
- curr & ~ECO_LED_ON);
+ return fext_leds(0x1, ECO_LED, curr & ~ECO_LED_ON);
}

static enum led_brightness eco_led_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0) & ECO_LED_ON)
+ if (fext_leds(0x2, ECO_LED, 0x0) & ECO_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -726,15 +741,15 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
{
int result;

- if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
+ if (fext_leds(0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
result = devm_led_classdev_register(&device->dev,
&logolamp_led);
if (result)
return result;
}

- if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
- (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) == 0x0)) {
+ if ((fext_leds(0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
+ (fext_buttons(0x0, 0x0, 0x0) == 0x0)) {
result = devm_led_classdev_register(&device->dev, &kblamps_led);
if (result)
return result;
@@ -746,7 +761,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* to also have an RF LED. Therefore use bit 24 as an indicator
* that an RF LED is present.
*/
- if (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) & BIT(24)) {
+ if (fext_buttons(0x0, 0x0, 0x0) & BIT(24)) {
result = devm_led_classdev_register(&device->dev, &radio_led);
if (result)
return result;
@@ -757,8 +772,8 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* bit 14 seems to indicate presence of said led as well.
* Confirm by testing the status.
*/
- if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & BIT(14)) &&
- (call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
+ if ((fext_leds(0x0, 0x0, 0x0) & BIT(14)) &&
+ (fext_leds(0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
result = devm_led_classdev_register(&device->dev, &eco_led);
if (result)
return result;
@@ -816,13 +831,12 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
}

i = 0;
- while (call_fext_func(FUNC_BUTTONS, 0x1, 0x0, 0x0) != 0
- && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE)
+ while (fext_buttons(0x1, 0x0, 0x0) != 0 &&
+ i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
; /* No action, result is discarded */
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);

- fujitsu_laptop->flags_supported =
- call_fext_func(FUNC_FLAGS, 0x0, 0x0, 0x0);
+ fujitsu_laptop->flags_supported = fext_flags(0x0, 0x0, 0x0);

/* Make sure our bitmask of supported functions is cleared if the
RFKILL function block is not implemented, like on the S7020. */
@@ -830,16 +844,15 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
fujitsu_laptop->flags_supported = 0;

if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state =
- call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0);
+ fujitsu_laptop->flags_state = fext_flags(0x4, 0x0, 0x0);

/* Suspect this is a keymap of the application panel, print it */
- pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0));
+ pr_info("BTNI: [0x%x]\n", fext_buttons(0x0, 0x0, 0x0));

/* Sync backlight power status */
if (fujitsu_bl->bl_device &&
acpi_video_get_backlight_type() == acpi_backlight_vendor) {
- if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3)
+ if (fext_backlight(0x2, 0x4, 0x0) == 3)
fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
else
fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
@@ -924,10 +937,9 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
}

if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state =
- call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0);
+ fujitsu_laptop->flags_state = fext_flags(0x4, 0x0, 0x0);

- while ((irb = call_fext_func(FUNC_BUTTONS, 0x1, 0x0, 0x0)) != 0 &&
+ while ((irb = fext_buttons(0x1, 0x0, 0x0)) != 0 &&
i++ < MAX_HOTKEY_RINGBUFFER_SIZE) {
scancode = irb & 0x4ff;
if (sparse_keymap_entry_from_scancode(input, scancode))
@@ -944,7 +956,7 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
* handled in software; its state is queried using FUNC_FLAGS
*/
if ((fujitsu_laptop->flags_supported & BIT(26)) &&
- (call_fext_func(FUNC_FLAGS, 0x1, 0x0, 0x0) & BIT(26)))
+ (fext_flags(0x1, 0x0, 0x0) & BIT(26)))
sparse_keymap_report_event(input, BIT(26), 1, true);
}

--
2.12.2

2017-04-24 13:35:46

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 09/10] platform/x86: fujitsu-laptop: use device-specific data in LED-related code

In order to perform their duties, all LED callbacks need a handle to the
FUJ02E3 ACPI device. If that handle is to be fetched without accessing
module-wide data, it needs to be extracted from data that gets passed to
the LED callbacks as arguments. However, LED core does not currently
support supplying driver-specific pointers to struct led_classdev
callbacks, so the latter will have to be implemented a bit differently
than backlight device callbacks and platform device attribute callbacks.

As the FUJ02E3 ACPI device is the parent device of all LED class devices
registered by fujitsu-laptop, we can get to the struct acpi_device
representing the former by following the parent link present inside the
struct device belonging to the struct led_classdev passed as an argument
to each LED callback. Note that acpi_driver_data() is not used to
retrieve the ACPI handle. Doing that would break cleanup upon module
removal, because the managed LED class device release callback,
devm_led_classdev_release(), would be called after the bus-level device
removal callback, acpi_device_remove(), which sets the driver_data
member of struct acpi_device to NULL and as devm_led_classdev_release()
calls led_classdev_unregister(), which in turn resets the LED's
brightness to LED_OFF, LED callbacks would not be able to retrieve the
ACPI handle needed to perform that operation. To work around this, the
handle is retrieved directly from struct acpi_device as the latter is
guaranteed to be available upon brightness reset because parent device's
reference count is only decremented once brightness gets reset.

To get rid of module-wide structures defining LED class devices,
allocate them dynamically using devm_kzalloc() and initialize them in
acpi_fujitsu_laptop_leds_register().

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 113 ++++++++++++++++------------------
1 file changed, 53 insertions(+), 60 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index f26abc41266e..77082e35f26a 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -635,6 +635,7 @@ static void fujitsu_laptop_platform_remove(void)
static int logolamp_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
int poweron = FUNC_LED_ON, always = FUNC_LED_ON;
int ret;

@@ -644,136 +645,120 @@ static int logolamp_set(struct led_classdev *cdev,
if (brightness < LED_FULL)
always = FUNC_LED_OFF;

- ret = fext_leds(fujitsu_laptop->handle, 0x1, LOGOLAMP_POWERON, poweron);
+ ret = fext_leds(handle, 0x1, LOGOLAMP_POWERON, poweron);
if (ret < 0)
return ret;

- return fext_leds(fujitsu_laptop->handle, 0x1, LOGOLAMP_ALWAYS, always);
+ return fext_leds(handle, 0x1, LOGOLAMP_ALWAYS, always);
}

static enum led_brightness logolamp_get(struct led_classdev *cdev)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
int ret;

- ret = fext_leds(fujitsu_laptop->handle, 0x2, LOGOLAMP_ALWAYS, 0x0);
+ ret = fext_leds(handle, 0x2, LOGOLAMP_ALWAYS, 0x0);
if (ret == FUNC_LED_ON)
return LED_FULL;

- ret = fext_leds(fujitsu_laptop->handle, 0x2, LOGOLAMP_POWERON, 0x0);
+ ret = fext_leds(handle, 0x2, LOGOLAMP_POWERON, 0x0);
if (ret == FUNC_LED_ON)
return LED_HALF;

return LED_OFF;
}

-static struct led_classdev logolamp_led = {
- .name = "fujitsu::logolamp",
- .brightness_set_blocking = logolamp_set,
- .brightness_get = logolamp_get
-};
-
static int kblamps_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
+
if (brightness >= LED_FULL)
- return fext_leds(fujitsu_laptop->handle, 0x1, KEYBOARD_LAMPS,
- FUNC_LED_ON);
+ return fext_leds(handle, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON);
else
- return fext_leds(fujitsu_laptop->handle, 0x1, KEYBOARD_LAMPS,
- FUNC_LED_OFF);
+ return fext_leds(handle, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF);
}

static enum led_brightness kblamps_get(struct led_classdev *cdev)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
enum led_brightness brightness = LED_OFF;

- if (fext_leds(fujitsu_laptop->handle,
- 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
+ if (fext_leds(handle, 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
brightness = LED_FULL;

return brightness;
}

-static struct led_classdev kblamps_led = {
- .name = "fujitsu::kblamps",
- .brightness_set_blocking = kblamps_set,
- .brightness_get = kblamps_get
-};
-
static int radio_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
+
if (brightness >= LED_FULL)
- return fext_flags(fujitsu_laptop->handle, 0x5, RADIO_LED_ON,
- RADIO_LED_ON);
+ return fext_flags(handle, 0x5, RADIO_LED_ON, RADIO_LED_ON);
else
- return fext_flags(fujitsu_laptop->handle, 0x5, RADIO_LED_ON,
- 0x0);
+ return fext_flags(handle, 0x5, RADIO_LED_ON, 0x0);
}

static enum led_brightness radio_led_get(struct led_classdev *cdev)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
enum led_brightness brightness = LED_OFF;

- if (fext_flags(fujitsu_laptop->handle, 0x4, 0x0, 0x0) & RADIO_LED_ON)
+ if (fext_flags(handle, 0x4, 0x0, 0x0) & RADIO_LED_ON)
brightness = LED_FULL;

return brightness;
}

-static struct led_classdev radio_led = {
- .name = "fujitsu::radio_led",
- .brightness_set_blocking = radio_led_set,
- .brightness_get = radio_led_get,
- .default_trigger = "rfkill-any"
-};
-
static int eco_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
int curr;

- curr = fext_leds(fujitsu_laptop->handle, 0x2, ECO_LED, 0x0);
+ curr = fext_leds(handle, 0x2, ECO_LED, 0x0);
if (brightness >= LED_FULL)
- return fext_leds(fujitsu_laptop->handle, 0x1, ECO_LED,
- curr | ECO_LED_ON);
+ return fext_leds(handle, 0x1, ECO_LED, curr | ECO_LED_ON);
else
- return fext_leds(fujitsu_laptop->handle, 0x1, ECO_LED,
- curr & ~ECO_LED_ON);
+ return fext_leds(handle, 0x1, ECO_LED, curr & ~ECO_LED_ON);
}

static enum led_brightness eco_led_get(struct led_classdev *cdev)
{
+ acpi_handle handle = to_acpi_device(cdev->dev->parent)->handle;
enum led_brightness brightness = LED_OFF;

- if (fext_leds(fujitsu_laptop->handle, 0x2, ECO_LED, 0x0) & ECO_LED_ON)
+ if (fext_leds(handle, 0x2, ECO_LED, 0x0) & ECO_LED_ON)
brightness = LED_FULL;

return brightness;
}

-static struct led_classdev eco_led = {
- .name = "fujitsu::eco_led",
- .brightness_set_blocking = eco_led_set,
- .brightness_get = eco_led_get
-};
-
static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
{
+ struct fujitsu_laptop *priv = acpi_driver_data(device);
+ struct led_classdev *led;
int result;

- if (fext_leds(fujitsu_laptop->handle,
- 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
- result = devm_led_classdev_register(&device->dev,
- &logolamp_led);
+ if (fext_leds(priv->handle, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
+ led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
+ led->name = "fujitsu::logolamp";
+ led->brightness_set_blocking = logolamp_set;
+ led->brightness_get = logolamp_get;
+ result = devm_led_classdev_register(&device->dev, led);
if (result)
return result;
}

- if ((fext_leds(fujitsu_laptop->handle,
- 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
- (fext_buttons(fujitsu_laptop->handle, 0x0, 0x0, 0x0) == 0x0)) {
- result = devm_led_classdev_register(&device->dev, &kblamps_led);
+ if ((fext_leds(priv->handle, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
+ (fext_buttons(priv->handle, 0x0, 0x0, 0x0) == 0x0)) {
+ led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
+ led->name = "fujitsu::kblamps";
+ led->brightness_set_blocking = kblamps_set;
+ led->brightness_get = kblamps_get;
+ result = devm_led_classdev_register(&device->dev, led);
if (result)
return result;
}
@@ -784,8 +769,13 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* to also have an RF LED. Therefore use bit 24 as an indicator
* that an RF LED is present.
*/
- if (fext_buttons(fujitsu_laptop->handle, 0x0, 0x0, 0x0) & BIT(24)) {
- result = devm_led_classdev_register(&device->dev, &radio_led);
+ if (fext_buttons(priv->handle, 0x0, 0x0, 0x0) & BIT(24)) {
+ led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
+ led->name = "fujitsu::radio_led";
+ led->brightness_set_blocking = radio_led_set;
+ led->brightness_get = radio_led_get;
+ led->default_trigger = "rfkill-any";
+ result = devm_led_classdev_register(&device->dev, led);
if (result)
return result;
}
@@ -795,10 +785,13 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* bit 14 seems to indicate presence of said led as well.
* Confirm by testing the status.
*/
- if ((fext_leds(fujitsu_laptop->handle, 0x0, 0x0, 0x0) & BIT(14)) &&
- (fext_leds(fujitsu_laptop->handle,
- 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
- result = devm_led_classdev_register(&device->dev, &eco_led);
+ if ((fext_leds(priv->handle, 0x0, 0x0, 0x0) & BIT(14)) &&
+ (fext_leds(priv->handle, 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
+ led = devm_kzalloc(&device->dev, sizeof(*led), GFP_KERNEL);
+ led->name = "fujitsu::eco_led";
+ led->brightness_set_blocking = eco_led_set;
+ led->brightness_get = eco_led_get;
+ result = devm_led_classdev_register(&device->dev, led);
if (result)
return result;
}
--
2.12.2

2017-04-24 13:33:57

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 04/10] platform/x86: fujitsu-laptop: rework backlight power synchronization

fujitsu-laptop registers two ACPI drivers: one for ACPI device FUJ02B1
enabling backlight control and another for ACPI device FUJ02E3 which
handles various other stuff (hotkeys, LEDs, etc.) So far, these two
drivers have been entangled by calls to fext_backlight() (previously
known as call_fext_func()) in the backlight part of the module which use
module-wide data managed by the other part of the module and accesses to
the backlight device from within acpi_fujitsu_laptop_add(). This
entaglement can be solved by storing an independently fetched ACPI
handle to the FUJ02E3 device inside the data structure managed by the
backlight part of the module.

Add a field to struct fujitsu_bl for storing a handle to the FUJ02E3
ACPI device. Make fext_backlight() calls use that handle instead of the
one from struct fujitsu_laptop. Move backlight power synchronization
from acpi_fujitsu_laptop_add() to fujitsu_backlight_register().

This makes the bl_device field of struct fujitsu_bl redundant, so remove
it.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index ea3210ee83ec..5f6b34a97348 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -131,9 +131,9 @@
/* Device controlling the backlight and associated keys */
struct fujitsu_bl {
acpi_handle handle;
+ acpi_handle fext_handle;
struct input_dev *input;
char phys[32];
- struct backlight_device *bl_device;
unsigned int max_brightness;
unsigned int brightness_level;
};
@@ -290,10 +290,12 @@ static int bl_get_brightness(struct backlight_device *b)

static int bl_update_status(struct backlight_device *b)
{
- if (b->props.power == FB_BLANK_POWERDOWN)
- fext_backlight(fujitsu_laptop->handle, 0x1, 0x4, 0x3);
- else
- fext_backlight(fujitsu_laptop->handle, 0x1, 0x4, 0x0);
+ if (fujitsu_bl->fext_handle) {
+ if (b->props.power == FB_BLANK_POWERDOWN)
+ fext_backlight(fujitsu_bl->fext_handle, 0x1, 0x4, 0x3);
+ else
+ fext_backlight(fujitsu_bl->fext_handle, 0x1, 0x4, 0x0);
+ }

return set_lcd_level(b->props.brightness);
}
@@ -397,6 +399,7 @@ static int fujitsu_backlight_register(struct acpi_device *device)
.type = BACKLIGHT_PLATFORM
};
struct backlight_device *bd;
+ acpi_status status;

bd = devm_backlight_device_register(&device->dev, "fujitsu-laptop",
&device->dev, NULL,
@@ -404,7 +407,10 @@ static int fujitsu_backlight_register(struct acpi_device *device)
if (IS_ERR(bd))
return PTR_ERR(bd);

- fujitsu_bl->bl_device = bd;
+ status = acpi_get_handle(NULL, "\\_SB.FEXT", &fujitsu_bl->fext_handle);
+ if (ACPI_SUCCESS(status) &&
+ fext_backlight(fujitsu_bl->fext_handle, 0x2, 0x4, 0x0) == 3)
+ bd->props.power = FB_BLANK_POWERDOWN;

return 0;
}
@@ -861,15 +867,6 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
pr_info("BTNI: [0x%x]\n", fext_buttons(fujitsu_laptop->handle,
0x0, 0x0, 0x0));

- /* Sync backlight power status */
- if (fujitsu_bl->bl_device &&
- acpi_video_get_backlight_type() == acpi_backlight_vendor) {
- if (fext_backlight(fujitsu_laptop->handle, 0x2, 0x4, 0x0) == 3)
- fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
- else
- fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
- }
-
error = acpi_fujitsu_laptop_leds_register(device);
if (error)
goto err_free_fifo;
--
2.12.2

2017-04-24 13:34:07

by Michał Kępień

[permalink] [raw]
Subject: [PATCH 03/10] platform/x86: fujitsu-laptop: explicitly pass ACPI handle to call_fext_func()

Prepare for not using module-wide data in call_fext_func() by explicitly
passing it an ACPI handle to the FUJ02E3 device while still using the
module-wide handle in each call to fext_*() helper functions.

Signed-off-by: Michał Kępień <[email protected]>
---
drivers/platform/x86/fujitsu-laptop.c | 97 ++++++++++++++++++++---------------
1 file changed, 56 insertions(+), 41 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 3695e8075aa6..ea3210ee83ec 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -163,7 +163,8 @@ static u32 dbg_level = 0x03;

/* Fujitsu ACPI interface function */

-static int call_fext_func(int func, int op, int feature, int state)
+static int call_fext_func(acpi_handle handle,
+ int func, int op, int feature, int state)
{
union acpi_object params[4] = {
{ .integer.type = ACPI_TYPE_INTEGER, .integer.value = func },
@@ -175,8 +176,7 @@ static int call_fext_func(int func, int op, int feature, int state)
unsigned long long value;
acpi_status status;

- status = acpi_evaluate_integer(fujitsu_laptop->handle, "FUNC",
- &arg_list, &value);
+ status = acpi_evaluate_integer(handle, "FUNC", &arg_list, &value);
if (ACPI_FAILURE(status)) {
vdbg_printk(FUJLAPTOP_DBG_ERROR, "Failed to evaluate FUNC\n");
return -ENODEV;
@@ -187,24 +187,24 @@ static int call_fext_func(int func, int op, int feature, int state)
return value;
}

-static int fext_backlight(int op, int feature, int state)
+static int fext_backlight(acpi_handle handle, int op, int feature, int state)
{
- return call_fext_func(FUNC_BACKLIGHT, op, feature, state);
+ return call_fext_func(handle, FUNC_BACKLIGHT, op, feature, state);
}

-static int fext_buttons(int op, int feature, int state)
+static int fext_buttons(acpi_handle handle, int op, int feature, int state)
{
- return call_fext_func(FUNC_BUTTONS, op, feature, state);
+ return call_fext_func(handle, FUNC_BUTTONS, op, feature, state);
}

-static int fext_flags(int op, int feature, int state)
+static int fext_flags(acpi_handle handle, int op, int feature, int state)
{
- return call_fext_func(FUNC_FLAGS, op, feature, state);
+ return call_fext_func(handle, FUNC_FLAGS, op, feature, state);
}

-static int fext_leds(int op, int feature, int state)
+static int fext_leds(acpi_handle handle, int op, int feature, int state)
{
- return call_fext_func(FUNC_LEDS, op, feature, state);
+ return call_fext_func(handle, FUNC_LEDS, op, feature, state);
}

/* Hardware access for LCD brightness control */
@@ -291,9 +291,9 @@ static int bl_get_brightness(struct backlight_device *b)
static int bl_update_status(struct backlight_device *b)
{
if (b->props.power == FB_BLANK_POWERDOWN)
- fext_backlight(0x1, 0x4, 0x3);
+ fext_backlight(fujitsu_laptop->handle, 0x1, 0x4, 0x3);
else
- fext_backlight(0x1, 0x4, 0x0);
+ fext_backlight(fujitsu_laptop->handle, 0x1, 0x4, 0x0);

return set_lcd_level(b->props.brightness);
}
@@ -629,22 +629,22 @@ static int logolamp_set(struct led_classdev *cdev,
if (brightness < LED_FULL)
always = FUNC_LED_OFF;

- ret = fext_leds(0x1, LOGOLAMP_POWERON, poweron);
+ ret = fext_leds(fujitsu_laptop->handle, 0x1, LOGOLAMP_POWERON, poweron);
if (ret < 0)
return ret;

- return fext_leds(0x1, LOGOLAMP_ALWAYS, always);
+ return fext_leds(fujitsu_laptop->handle, 0x1, LOGOLAMP_ALWAYS, always);
}

static enum led_brightness logolamp_get(struct led_classdev *cdev)
{
int ret;

- ret = fext_leds(0x2, LOGOLAMP_ALWAYS, 0x0);
+ ret = fext_leds(fujitsu_laptop->handle, 0x2, LOGOLAMP_ALWAYS, 0x0);
if (ret == FUNC_LED_ON)
return LED_FULL;

- ret = fext_leds(0x2, LOGOLAMP_POWERON, 0x0);
+ ret = fext_leds(fujitsu_laptop->handle, 0x2, LOGOLAMP_POWERON, 0x0);
if (ret == FUNC_LED_ON)
return LED_HALF;

@@ -661,16 +661,19 @@ static int kblamps_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- return fext_leds(0x1, KEYBOARD_LAMPS, FUNC_LED_ON);
+ return fext_leds(fujitsu_laptop->handle, 0x1, KEYBOARD_LAMPS,
+ FUNC_LED_ON);
else
- return fext_leds(0x1, KEYBOARD_LAMPS, FUNC_LED_OFF);
+ return fext_leds(fujitsu_laptop->handle, 0x1, KEYBOARD_LAMPS,
+ FUNC_LED_OFF);
}

static enum led_brightness kblamps_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (fext_leds(0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
+ if (fext_leds(fujitsu_laptop->handle,
+ 0x2, KEYBOARD_LAMPS, 0x0) == FUNC_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -686,16 +689,18 @@ static int radio_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- return fext_flags(0x5, RADIO_LED_ON, RADIO_LED_ON);
+ return fext_flags(fujitsu_laptop->handle, 0x5, RADIO_LED_ON,
+ RADIO_LED_ON);
else
- return fext_flags(0x5, RADIO_LED_ON, 0x0);
+ return fext_flags(fujitsu_laptop->handle, 0x5, RADIO_LED_ON,
+ 0x0);
}

static enum led_brightness radio_led_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (fext_flags(0x4, 0x0, 0x0) & RADIO_LED_ON)
+ if (fext_flags(fujitsu_laptop->handle, 0x4, 0x0, 0x0) & RADIO_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -713,18 +718,20 @@ static int eco_led_set(struct led_classdev *cdev,
{
int curr;

- curr = fext_leds(0x2, ECO_LED, 0x0);
+ curr = fext_leds(fujitsu_laptop->handle, 0x2, ECO_LED, 0x0);
if (brightness >= LED_FULL)
- return fext_leds(0x1, ECO_LED, curr | ECO_LED_ON);
+ return fext_leds(fujitsu_laptop->handle, 0x1, ECO_LED,
+ curr | ECO_LED_ON);
else
- return fext_leds(0x1, ECO_LED, curr & ~ECO_LED_ON);
+ return fext_leds(fujitsu_laptop->handle, 0x1, ECO_LED,
+ curr & ~ECO_LED_ON);
}

static enum led_brightness eco_led_get(struct led_classdev *cdev)
{
enum led_brightness brightness = LED_OFF;

- if (fext_leds(0x2, ECO_LED, 0x0) & ECO_LED_ON)
+ if (fext_leds(fujitsu_laptop->handle, 0x2, ECO_LED, 0x0) & ECO_LED_ON)
brightness = LED_FULL;

return brightness;
@@ -740,15 +747,17 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
{
int result;

- if (fext_leds(0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
+ if (fext_leds(fujitsu_laptop->handle,
+ 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
result = devm_led_classdev_register(&device->dev,
&logolamp_led);
if (result)
return result;
}

- if ((fext_leds(0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
- (fext_buttons(0x0, 0x0, 0x0) == 0x0)) {
+ if ((fext_leds(fujitsu_laptop->handle,
+ 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) &&
+ (fext_buttons(fujitsu_laptop->handle, 0x0, 0x0, 0x0) == 0x0)) {
result = devm_led_classdev_register(&device->dev, &kblamps_led);
if (result)
return result;
@@ -760,7 +769,7 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* to also have an RF LED. Therefore use bit 24 as an indicator
* that an RF LED is present.
*/
- if (fext_buttons(0x0, 0x0, 0x0) & BIT(24)) {
+ if (fext_buttons(fujitsu_laptop->handle, 0x0, 0x0, 0x0) & BIT(24)) {
result = devm_led_classdev_register(&device->dev, &radio_led);
if (result)
return result;
@@ -771,8 +780,9 @@ static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
* bit 14 seems to indicate presence of said led as well.
* Confirm by testing the status.
*/
- if ((fext_leds(0x0, 0x0, 0x0) & BIT(14)) &&
- (fext_leds(0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
+ if ((fext_leds(fujitsu_laptop->handle, 0x0, 0x0, 0x0) & BIT(14)) &&
+ (fext_leds(fujitsu_laptop->handle,
+ 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) {
result = devm_led_classdev_register(&device->dev, &eco_led);
if (result)
return result;
@@ -830,12 +840,13 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
}

i = 0;
- while (fext_buttons(0x1, 0x0, 0x0) != 0 &&
+ while (fext_buttons(fujitsu_laptop->handle, 0x1, 0x0, 0x0) != 0 &&
i++ < MAX_HOTKEY_RINGBUFFER_SIZE)
; /* No action, result is discarded */
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);

- fujitsu_laptop->flags_supported = fext_flags(0x0, 0x0, 0x0);
+ fujitsu_laptop->flags_supported = fext_flags(fujitsu_laptop->handle,
+ 0x0, 0x0, 0x0);

/* Make sure our bitmask of supported functions is cleared if the
RFKILL function block is not implemented, like on the S7020. */
@@ -843,15 +854,17 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device)
fujitsu_laptop->flags_supported = 0;

if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state = fext_flags(0x4, 0x0, 0x0);
+ fujitsu_laptop->flags_state = fext_flags(fujitsu_laptop->handle,
+ 0x4, 0x0, 0x0);

/* Suspect this is a keymap of the application panel, print it */
- pr_info("BTNI: [0x%x]\n", fext_buttons(0x0, 0x0, 0x0));
+ pr_info("BTNI: [0x%x]\n", fext_buttons(fujitsu_laptop->handle,
+ 0x0, 0x0, 0x0));

/* Sync backlight power status */
if (fujitsu_bl->bl_device &&
acpi_video_get_backlight_type() == acpi_backlight_vendor) {
- if (fext_backlight(0x2, 0x4, 0x0) == 3)
+ if (fext_backlight(fujitsu_laptop->handle, 0x2, 0x4, 0x0) == 3)
fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN;
else
fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK;
@@ -936,9 +949,11 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
}

if (fujitsu_laptop->flags_supported)
- fujitsu_laptop->flags_state = fext_flags(0x4, 0x0, 0x0);
+ fujitsu_laptop->flags_state = fext_flags(fujitsu_laptop->handle,
+ 0x4, 0x0, 0x0);

- while ((irb = fext_buttons(0x1, 0x0, 0x0)) != 0 &&
+ while ((irb = fext_buttons(fujitsu_laptop->handle,
+ 0x1, 0x0, 0x0)) != 0 &&
i++ < MAX_HOTKEY_RINGBUFFER_SIZE) {
scancode = irb & 0x4ff;
if (sparse_keymap_entry_from_scancode(input, scancode))
@@ -955,7 +970,7 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
* handled in software; its state is queried using FUNC_FLAGS
*/
if ((fujitsu_laptop->flags_supported & BIT(26)) &&
- (fext_flags(0x1, 0x0, 0x0) & BIT(26)))
+ (fext_flags(fujitsu_laptop->handle, 0x1, 0x0, 0x0) & BIT(26)))
sparse_keymap_report_event(input, BIT(26), 1, true);
}

--
2.12.2