return -ENODEV;
}
- vcc = regulator_get_exclusive(&pdev->dev, "vled");
+ vcc = devm_regulator_get_exclusive(&pdev->dev, "vled");
if (IS_ERR(vcc)) {
dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
return PTR_ERR(vcc);
}
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
- if (led == NULL) {
- ret = -ENOMEM;
- goto err_vcc;
- }
+ if (led == NULL)
+ return -ENOMEM;
led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
if (pdata->brightness > led->cdev.max_brightness) {
dev_err(&pdev->dev, "Invalid default brightness %d\n",
pdata->brightness);
- ret = -EINVAL;
- goto err_vcc;
+ return -EINVAL;
}
led->value = pdata->brightness;
ret = led_classdev_register(&pdev->dev, &led->cdev);
if (ret < 0) {
cancel_work_sync(&led->work);
- goto err_vcc;
+ return ret;
}
/* to expose the default value to userspace */
regulator_led_set_value(led);
return 0;
-
- err_vcc:
- regulator_put(vcc);
- return ret;
}
static int regulator_led_remove(struct platform_device *pdev)
led_classdev_unregister(&led->cdev);
cancel_work_sync(&led->work);
regulator_led_disable(led);
- regulator_put(led->vcc);
return 0;
}
static struct platform_driver regulator_led_driver = {
.driver = {
.name = "leds-regulator",
- .owner = THIS_MODULE,
},
.probe = regulator_led_probe,
.remove = regulator_led_remove,
#define __LINUX_LEDS_H_INCLUDED
#include <linux/list.h>
+ #include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#define LED_BLINK_ONESHOT (1 << 17)
#define LED_BLINK_ONESHOT_STOP (1 << 18)
#define LED_BLINK_INVERT (1 << 19)
+ #define LED_SYSFS_DISABLE (1 << 20)
+ #define SET_BRIGHTNESS_ASYNC (1 << 21)
+ #define SET_BRIGHTNESS_SYNC (1 << 22)
/* Set LED brightness level */
/* Must not sleep, use a workqueue if needed */
void (*brightness_set)(struct led_classdev *led_cdev,
enum led_brightness brightness);
+ /*
+ * Set LED brightness level immediately - it can block the caller for
+ * the time required for accessing a LED device register.
+ */
+ int (*brightness_set_sync)(struct led_classdev *led_cdev,
+ enum led_brightness brightness);
/* Get LED brightness level */
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
/* true if activated - deactivate routine uses it to do cleanup */
bool activated;
#endif
+
+ /* Ensures consistent access to the LED Flash Class device */
+ struct mutex led_access;
};
extern int led_classdev_register(struct device *parent,
*/
extern int led_update_brightness(struct led_classdev *led_cdev);
+ /**
+ * led_sysfs_disable - disable LED sysfs interface
+ * @led_cdev: the LED to set
+ *
+ * Disable the led_cdev's sysfs interface.
+ */
+ extern void led_sysfs_disable(struct led_classdev *led_cdev);
+
+ /**
+ * led_sysfs_enable - enable LED sysfs interface
+ * @led_cdev: the LED to set
+ *
+ * Enable the led_cdev's sysfs interface.
+ */
+ extern void led_sysfs_enable(struct led_classdev *led_cdev);
+
+ /**
+ * led_sysfs_is_disabled - check if LED sysfs interface is disabled
+ * @led_cdev: the LED to query
+ *
+ * Returns: true if the led_cdev's sysfs interface is disabled.
+ */
+ static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev)
+ {
+ return led_cdev->flags & LED_SYSFS_DISABLE;
+ }
+
/*
* LED Triggers
*/
unsigned retain_state_suspended : 1;
unsigned default_state : 2;
/* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */
+ struct gpio_desc *gpiod;
};
#define LEDS_GPIO_DEFSTATE_OFF 0
#define LEDS_GPIO_DEFSTATE_ON 1
#define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */
#define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */
#define GPIO_LED_BLINK 2 /* Please, blink */
- int (*gpio_blink_set)(unsigned gpio, int state,
+ int (*gpio_blink_set)(struct gpio_desc *desc, int state,
unsigned long *delay_on,
unsigned long *delay_off);
};