Skip to content

Commit

Permalink
leds: gpio trigger: simplifications from core changes
Browse files Browse the repository at this point in the history
The trigger core learned error handling for the activate callback and
to handle device attributes. Also make use of the module_led_trigger()
helper to simplify trigger registration.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
  • Loading branch information
Uwe Kleine-König authored and Jacek Anaszewski committed Jul 5, 2018
1 parent e4786ba commit 9bfd7d9
Showing 1 changed file with 25 additions and 62 deletions.
87 changes: 25 additions & 62 deletions drivers/leds/trigger/ledtrig-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct gpio_trig_data {
static irqreturn_t gpio_trig_irq(int irq, void *_led)
{
struct led_classdev *led = _led;
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_get_trigger_data(led);
int tmp;

tmp = gpio_get_value_cansleep(gpio_data->gpio);
Expand All @@ -51,17 +51,15 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)
static ssize_t gpio_trig_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);

return sprintf(buf, "%u\n", gpio_data->desired_brightness);
}

static ssize_t gpio_trig_brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t n)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
unsigned desired_brightness;
int ret;

Expand All @@ -81,17 +79,16 @@ static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
static ssize_t gpio_trig_inverted_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);

return sprintf(buf, "%u\n", gpio_data->inverted);
}

static ssize_t gpio_trig_inverted_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t n)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct led_classdev *led = led_trigger_get_led(dev);
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
unsigned long inverted;
int ret;

Expand All @@ -115,17 +112,16 @@ static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
static ssize_t gpio_trig_gpio_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);

return sprintf(buf, "%u\n", gpio_data->gpio);
}

static ssize_t gpio_trig_gpio_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t n)
{
struct led_classdev *led = dev_get_drvdata(dev);
struct gpio_trig_data *gpio_data = led->trigger_data;
struct led_classdev *led = led_trigger_get_led(dev);
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
unsigned gpio;
int ret;

Expand Down Expand Up @@ -162,77 +158,44 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
}
static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);

static struct attribute *gpio_trig_attrs[] = {
&dev_attr_desired_brightness.attr,
&dev_attr_inverted.attr,
&dev_attr_gpio.attr,
NULL
};
ATTRIBUTE_GROUPS(gpio_trig);

static int gpio_trig_activate(struct led_classdev *led)
{
struct gpio_trig_data *gpio_data;
int ret;

gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
if (!gpio_data)
return 0;

ret = device_create_file(led->dev, &dev_attr_gpio);
if (ret)
goto err_gpio;

ret = device_create_file(led->dev, &dev_attr_inverted);
if (ret)
goto err_inverted;

ret = device_create_file(led->dev, &dev_attr_desired_brightness);
if (ret)
goto err_brightness;
return -ENOMEM;

gpio_data->led = led;
led->trigger_data = gpio_data;
led->activated = true;

return 0;

err_brightness:
device_remove_file(led->dev, &dev_attr_inverted);

err_inverted:
device_remove_file(led->dev, &dev_attr_gpio);

err_gpio:
kfree(gpio_data);
led_set_trigger_data(led, gpio_data);

return 0;
}

static void gpio_trig_deactivate(struct led_classdev *led)
{
struct gpio_trig_data *gpio_data = led->trigger_data;
struct gpio_trig_data *gpio_data = led_get_trigger_data(led);

if (led->activated) {
device_remove_file(led->dev, &dev_attr_gpio);
device_remove_file(led->dev, &dev_attr_inverted);
device_remove_file(led->dev, &dev_attr_desired_brightness);
if (gpio_data->gpio != 0)
free_irq(gpio_to_irq(gpio_data->gpio), led);
kfree(gpio_data);
led->activated = false;
}
if (gpio_data->gpio != 0)
free_irq(gpio_to_irq(gpio_data->gpio), led);
kfree(gpio_data);
}

static struct led_trigger gpio_led_trigger = {
.name = "gpio",
.activate = gpio_trig_activate,
.deactivate = gpio_trig_deactivate,
.groups = gpio_trig_groups,
};

static int __init gpio_trig_init(void)
{
return led_trigger_register(&gpio_led_trigger);
}
module_init(gpio_trig_init);

static void __exit gpio_trig_exit(void)
{
led_trigger_unregister(&gpio_led_trigger);
}
module_exit(gpio_trig_exit);
module_led_trigger(gpio_led_trigger);

MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
MODULE_DESCRIPTION("GPIO LED trigger");
Expand Down

0 comments on commit 9bfd7d9

Please sign in to comment.