[PATCH v2 7/8] platform/x86: fujitsu-laptop: use device-specific data in LED-related code

2017-05-19 Thread Michał Kępień
In order to perform their duties, all LED callbacks need a pointer to
the struct acpi_device representing the FUJ02E3 ACPI device.  To limit
the use of the module-wide pointer, the same pointer should be extracted
from data that gets passed to LED callbacks as arguments.  However, LED
core does not currently support supplying driver-specific pointers to
struct led_classdev callbacks, so the latter 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, struct acpi_device
representing the former can be extracted by following the parent link
present inside the struct device belonging to the struct led_classdev
passed as an argument to each LED callback.

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ń 
---
 drivers/platform/x86/fujitsu-laptop.c | 102 +-
 1 file changed, 52 insertions(+), 50 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c 
b/drivers/platform/x86/fujitsu-laptop.c
index b78c97ebfee4..3d33be9f88f6 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -608,6 +608,7 @@ static void fujitsu_laptop_platform_remove(void)
 static int logolamp_set(struct led_classdev *cdev,
enum led_brightness brightness)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
int poweron = FUNC_LED_ON, always = FUNC_LED_ON;
int ret;
 
@@ -617,136 +618,128 @@ static int logolamp_set(struct led_classdev *cdev,
if (brightness < LED_FULL)
always = FUNC_LED_OFF;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
+   ret = call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
if (ret < 0)
return ret;
 
-   return call_fext_func(fext, FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
+   return call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
 }
 
 static enum led_brightness logolamp_get(struct led_classdev *cdev)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
int ret;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
+   ret = call_fext_func(device, FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
if (ret == FUNC_LED_ON)
return LED_FULL;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x2, LOGOLAMP_POWERON, 0x0);
+   ret = call_fext_func(device, FUNC_LEDS, 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)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
+
if (brightness >= LED_FULL)
-   return call_fext_func(fext, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
+   return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
  FUNC_LED_ON);
else
-   return call_fext_func(fext, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
+   return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
  FUNC_LED_OFF);
 }
 
 static enum led_brightness kblamps_get(struct led_classdev *cdev)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
enum led_brightness brightness = LED_OFF;
 
-   if (call_fext_func(fext,
+   if (call_fext_func(device,
   FUNC_LEDS, 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)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
+
if (brightness >= LED_FULL)
-   return call_fext_func(fext, FUNC_FLAGS, 0x5, RADIO_LED_ON,
+   return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
  RADIO_LED_ON);
else
-   return call_fext_func(fext, FUNC_FLAGS, 0x5, RADIO_LED_ON,
+   return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
  0x0);
 }
 
 static enum led_brightness radio_led_get(struct led_classdev 

[PATCH v2 7/8] platform/x86: fujitsu-laptop: use device-specific data in LED-related code

2017-05-19 Thread Michał Kępień
In order to perform their duties, all LED callbacks need a pointer to
the struct acpi_device representing the FUJ02E3 ACPI device.  To limit
the use of the module-wide pointer, the same pointer should be extracted
from data that gets passed to LED callbacks as arguments.  However, LED
core does not currently support supplying driver-specific pointers to
struct led_classdev callbacks, so the latter 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, struct acpi_device
representing the former can be extracted by following the parent link
present inside the struct device belonging to the struct led_classdev
passed as an argument to each LED callback.

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ń 
---
 drivers/platform/x86/fujitsu-laptop.c | 102 +-
 1 file changed, 52 insertions(+), 50 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c 
b/drivers/platform/x86/fujitsu-laptop.c
index b78c97ebfee4..3d33be9f88f6 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -608,6 +608,7 @@ static void fujitsu_laptop_platform_remove(void)
 static int logolamp_set(struct led_classdev *cdev,
enum led_brightness brightness)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
int poweron = FUNC_LED_ON, always = FUNC_LED_ON;
int ret;
 
@@ -617,136 +618,128 @@ static int logolamp_set(struct led_classdev *cdev,
if (brightness < LED_FULL)
always = FUNC_LED_OFF;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
+   ret = call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_POWERON, poweron);
if (ret < 0)
return ret;
 
-   return call_fext_func(fext, FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
+   return call_fext_func(device, FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, always);
 }
 
 static enum led_brightness logolamp_get(struct led_classdev *cdev)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
int ret;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
+   ret = call_fext_func(device, FUNC_LEDS, 0x2, LOGOLAMP_ALWAYS, 0x0);
if (ret == FUNC_LED_ON)
return LED_FULL;
 
-   ret = call_fext_func(fext, FUNC_LEDS, 0x2, LOGOLAMP_POWERON, 0x0);
+   ret = call_fext_func(device, FUNC_LEDS, 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)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
+
if (brightness >= LED_FULL)
-   return call_fext_func(fext, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
+   return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
  FUNC_LED_ON);
else
-   return call_fext_func(fext, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
+   return call_fext_func(device, FUNC_LEDS, 0x1, KEYBOARD_LAMPS,
  FUNC_LED_OFF);
 }
 
 static enum led_brightness kblamps_get(struct led_classdev *cdev)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
enum led_brightness brightness = LED_OFF;
 
-   if (call_fext_func(fext,
+   if (call_fext_func(device,
   FUNC_LEDS, 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)
 {
+   struct acpi_device *device = to_acpi_device(cdev->dev->parent);
+
if (brightness >= LED_FULL)
-   return call_fext_func(fext, FUNC_FLAGS, 0x5, RADIO_LED_ON,
+   return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
  RADIO_LED_ON);
else
-   return call_fext_func(fext, FUNC_FLAGS, 0x5, RADIO_LED_ON,
+   return call_fext_func(device, FUNC_FLAGS, 0x5, RADIO_LED_ON,
  0x0);
 }
 
 static enum led_brightness radio_led_get(struct led_classdev *cdev)
 {
+