mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:24:31 +01:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
141 lines
3.5 KiB
C
141 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* ledtrig-gio.c - LED Trigger Based on GPIO events
|
|
*
|
|
* Copyright 2009 Felipe Balbi <me@felipebalbi.com>
|
|
* Copyright 2023 Linus Walleij <linus.walleij@linaro.org>
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/gpio/consumer.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/leds.h>
|
|
#include <linux/slab.h>
|
|
#include "../leds.h"
|
|
|
|
struct gpio_trig_data {
|
|
struct led_classdev *led;
|
|
unsigned desired_brightness; /* desired brightness when led is on */
|
|
struct gpio_desc *gpiod; /* gpio that triggers the led */
|
|
};
|
|
|
|
static irqreturn_t gpio_trig_irq(int irq, void *_led)
|
|
{
|
|
struct led_classdev *led = _led;
|
|
struct gpio_trig_data *gpio_data = led_get_trigger_data(led);
|
|
int tmp;
|
|
|
|
tmp = gpiod_get_value_cansleep(gpio_data->gpiod);
|
|
if (tmp) {
|
|
if (gpio_data->desired_brightness)
|
|
led_set_brightness_nosleep(gpio_data->led,
|
|
gpio_data->desired_brightness);
|
|
else
|
|
led_set_brightness_nosleep(gpio_data->led, LED_FULL);
|
|
} else {
|
|
led_set_brightness_nosleep(gpio_data->led, LED_OFF);
|
|
}
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static ssize_t desired_brightness_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
|
|
|
|
return sysfs_emit(buf, "%u\n", gpio_data->desired_brightness);
|
|
}
|
|
|
|
static ssize_t desired_brightness_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t n)
|
|
{
|
|
struct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);
|
|
u8 desired_brightness;
|
|
int ret;
|
|
|
|
ret = kstrtou8(buf, 10, &desired_brightness);
|
|
if (ret)
|
|
return ret;
|
|
|
|
gpio_data->desired_brightness = desired_brightness;
|
|
|
|
return n;
|
|
}
|
|
static DEVICE_ATTR_RW(desired_brightness);
|
|
|
|
static struct attribute *gpio_trig_attrs[] = {
|
|
&dev_attr_desired_brightness.attr,
|
|
NULL
|
|
};
|
|
ATTRIBUTE_GROUPS(gpio_trig);
|
|
|
|
static int gpio_trig_activate(struct led_classdev *led)
|
|
{
|
|
struct gpio_trig_data *gpio_data;
|
|
struct device *dev = led->dev;
|
|
int ret;
|
|
|
|
gpio_data = kzalloc_obj(*gpio_data);
|
|
if (!gpio_data)
|
|
return -ENOMEM;
|
|
|
|
/*
|
|
* The generic property "trigger-sources" is followed,
|
|
* and we hope that this is a GPIO.
|
|
*/
|
|
gpio_data->gpiod = gpiod_get_optional(dev, "trigger-sources", GPIOD_IN);
|
|
if (IS_ERR(gpio_data->gpiod)) {
|
|
ret = PTR_ERR(gpio_data->gpiod);
|
|
kfree(gpio_data);
|
|
return ret;
|
|
}
|
|
if (!gpio_data->gpiod) {
|
|
dev_err(dev, "no valid GPIO for the trigger\n");
|
|
kfree(gpio_data);
|
|
return -EINVAL;
|
|
}
|
|
|
|
gpiod_set_consumer_name(gpio_data->gpiod, "led-trigger");
|
|
|
|
gpio_data->led = led;
|
|
led_set_trigger_data(led, gpio_data);
|
|
|
|
ret = request_threaded_irq(gpiod_to_irq(gpio_data->gpiod), NULL, gpio_trig_irq,
|
|
IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING
|
|
| IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
|
|
if (ret) {
|
|
dev_err(dev, "request_irq failed with error %d\n", ret);
|
|
gpiod_put(gpio_data->gpiod);
|
|
kfree(gpio_data);
|
|
return ret;
|
|
}
|
|
|
|
/* Finally update the LED to initial status */
|
|
gpio_trig_irq(0, led);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void gpio_trig_deactivate(struct led_classdev *led)
|
|
{
|
|
struct gpio_trig_data *gpio_data = led_get_trigger_data(led);
|
|
|
|
free_irq(gpiod_to_irq(gpio_data->gpiod), led);
|
|
gpiod_put(gpio_data->gpiod);
|
|
kfree(gpio_data);
|
|
}
|
|
|
|
static struct led_trigger gpio_led_trigger = {
|
|
.name = "gpio",
|
|
.activate = gpio_trig_activate,
|
|
.deactivate = gpio_trig_deactivate,
|
|
.groups = gpio_trig_groups,
|
|
};
|
|
module_led_trigger(gpio_led_trigger);
|
|
|
|
MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
|
|
MODULE_DESCRIPTION("GPIO LED trigger");
|
|
MODULE_LICENSE("GPL v2");
|