Immutable branch from LEDs due for the v6.3 merge window
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmPUBkUACgkQUa+KL4f8 d2GlDA//XebKIyCc+3pexfTQ31gW+jMbJ085iKbhhgPAPsTiJ8qu6zQt2KA8+f88 v+vREQQ6mkngCeL4XS4KyiCr79hXF9WMwte4R58XVuzc9MTYeEpKkJDLIMobBnwI caoeRfROf6rYcXaWKhjc7Iq6btCZi4JVGSflQ/vHDOiuyRi2UrLxC61QbK6j6bNB 2WEyM2wibOUPnLXt96DAEyje3U+5p+wc4MGO9qZf2sKmCwNWW5SMjrQzgD1HpUMH RrhA8QQ8D6I+5Gr0Znrw8h99ueIGGLR7vFxZDLw/6DOqexyeNoSL4PR+oSBG3chK 9C+q0rHSQGsHu2LB8D3OJaME/3mgCsRPnzDosfjE+M8rGILuYD90+UK4usriv92n aSgjKTuq7qv0HSqGQxsBkZk7LEN2xnSZmB1Ro+J4hc6/XFlMEln4Nnq2KAi9J+7c nWWMFFC3g/ILLcFgdxNSpDZMOklOigsLAfny+bCKosnhX5SCv93BIrzwfL5NJPpv DdKEOxemVGz/JyeHRVrnN5sAheFAN3CeNESX/Gi5wybfDDjdbRwlXtyePRATaX7Y 8Y2yMU/XndKDREflLt4woT7kKwlPomp1yWKehYBuO+oUeZc0SpIydU298hP3QHCM Ae8eCBum6YKfyBpK8iXSAGngHbY0QdJ/dgQHrENuIperk1QJsJg= =LTfM -----END PGP SIGNATURE----- Merge tag 'ib-leds-led_get-v6.3' into HEAD Immutable branch from LEDs due for the v6.3 merge window
This commit is contained in:
commit
39f0932050
|
@ -23,6 +23,8 @@
|
|||
#include "leds.h"
|
||||
|
||||
static struct class *leds_class;
|
||||
static DEFINE_MUTEX(leds_lookup_lock);
|
||||
static LIST_HEAD(leds_lookup_list);
|
||||
|
||||
static ssize_t brightness_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
|
@ -215,6 +217,23 @@ static int led_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
|
||||
|
||||
static struct led_classdev *led_module_get(struct device *led_dev)
|
||||
{
|
||||
struct led_classdev *led_cdev;
|
||||
|
||||
if (!led_dev)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
led_cdev = dev_get_drvdata(led_dev);
|
||||
|
||||
if (!try_module_get(led_cdev->dev->parent->driver->owner)) {
|
||||
put_device(led_cdev->dev);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
return led_cdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_led_get() - request a LED device via the LED framework
|
||||
* @np: device node to get the LED device from
|
||||
|
@ -226,7 +245,6 @@ static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
|
|||
struct led_classdev *of_led_get(struct device_node *np, int index)
|
||||
{
|
||||
struct device *led_dev;
|
||||
struct led_classdev *led_cdev;
|
||||
struct device_node *led_node;
|
||||
|
||||
led_node = of_parse_phandle(np, "leds", index);
|
||||
|
@ -236,15 +254,7 @@ struct led_classdev *of_led_get(struct device_node *np, int index)
|
|||
led_dev = class_find_device_by_of_node(leds_class, led_node);
|
||||
of_node_put(led_node);
|
||||
|
||||
if (!led_dev)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
led_cdev = dev_get_drvdata(led_dev);
|
||||
|
||||
if (!try_module_get(led_cdev->dev->parent->driver->owner))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return led_cdev;
|
||||
return led_module_get(led_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_led_get);
|
||||
|
||||
|
@ -255,6 +265,7 @@ EXPORT_SYMBOL_GPL(of_led_get);
|
|||
void led_put(struct led_classdev *led_cdev)
|
||||
{
|
||||
module_put(led_cdev->dev->parent->driver->owner);
|
||||
put_device(led_cdev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_put);
|
||||
|
||||
|
@ -265,6 +276,22 @@ static void devm_led_release(struct device *dev, void *res)
|
|||
led_put(*p);
|
||||
}
|
||||
|
||||
static struct led_classdev *__devm_led_get(struct device *dev, struct led_classdev *led)
|
||||
{
|
||||
struct led_classdev **dr;
|
||||
|
||||
dr = devres_alloc(devm_led_release, sizeof(struct led_classdev *), GFP_KERNEL);
|
||||
if (!dr) {
|
||||
led_put(led);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
*dr = led;
|
||||
devres_add(dev, dr);
|
||||
|
||||
return led;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_of_led_get - Resource-managed request of a LED device
|
||||
* @dev: LED consumer
|
||||
|
@ -280,7 +307,6 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev,
|
|||
int index)
|
||||
{
|
||||
struct led_classdev *led;
|
||||
struct led_classdev **dr;
|
||||
|
||||
if (!dev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -289,20 +315,92 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev,
|
|||
if (IS_ERR(led))
|
||||
return led;
|
||||
|
||||
dr = devres_alloc(devm_led_release, sizeof(struct led_classdev *),
|
||||
GFP_KERNEL);
|
||||
if (!dr) {
|
||||
led_put(led);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
*dr = led;
|
||||
devres_add(dev, dr);
|
||||
|
||||
return led;
|
||||
return __devm_led_get(dev, led);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_of_led_get);
|
||||
|
||||
/**
|
||||
* led_get() - request a LED device via the LED framework
|
||||
* @dev: device for which to get the LED device
|
||||
* @con_id: name of the LED from the device's point of view
|
||||
*
|
||||
* @return a pointer to a LED device or ERR_PTR(errno) on failure.
|
||||
*/
|
||||
struct led_classdev *led_get(struct device *dev, char *con_id)
|
||||
{
|
||||
struct led_lookup_data *lookup;
|
||||
const char *provider = NULL;
|
||||
struct device *led_dev;
|
||||
|
||||
mutex_lock(&leds_lookup_lock);
|
||||
list_for_each_entry(lookup, &leds_lookup_list, list) {
|
||||
if (!strcmp(lookup->dev_id, dev_name(dev)) &&
|
||||
!strcmp(lookup->con_id, con_id)) {
|
||||
provider = kstrdup_const(lookup->provider, GFP_KERNEL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&leds_lookup_lock);
|
||||
|
||||
if (!provider)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
led_dev = class_find_device_by_name(leds_class, provider);
|
||||
kfree_const(provider);
|
||||
|
||||
return led_module_get(led_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_get);
|
||||
|
||||
/**
|
||||
* devm_led_get() - request a LED device via the LED framework
|
||||
* @dev: device for which to get the LED device
|
||||
* @con_id: name of the LED from the device's point of view
|
||||
*
|
||||
* The LED device returned from this function is automatically released
|
||||
* on driver detach.
|
||||
*
|
||||
* @return a pointer to a LED device or ERR_PTR(errno) on failure.
|
||||
*/
|
||||
struct led_classdev *devm_led_get(struct device *dev, char *con_id)
|
||||
{
|
||||
struct led_classdev *led;
|
||||
|
||||
led = led_get(dev, con_id);
|
||||
if (IS_ERR(led))
|
||||
return led;
|
||||
|
||||
return __devm_led_get(dev, led);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_led_get);
|
||||
|
||||
/**
|
||||
* led_add_lookup() - Add a LED lookup table entry
|
||||
* @led_lookup: the lookup table entry to add
|
||||
*
|
||||
* Add a LED lookup table entry. On systems without devicetree the lookup table
|
||||
* is used by led_get() to find LEDs.
|
||||
*/
|
||||
void led_add_lookup(struct led_lookup_data *led_lookup)
|
||||
{
|
||||
mutex_lock(&leds_lookup_lock);
|
||||
list_add_tail(&led_lookup->list, &leds_lookup_list);
|
||||
mutex_unlock(&leds_lookup_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_add_lookup);
|
||||
|
||||
/**
|
||||
* led_remove_lookup() - Remove a LED lookup table entry
|
||||
* @led_lookup: the lookup table entry to remove
|
||||
*/
|
||||
void led_remove_lookup(struct led_lookup_data *led_lookup)
|
||||
{
|
||||
mutex_lock(&leds_lookup_lock);
|
||||
list_del(&led_lookup->list);
|
||||
mutex_unlock(&leds_lookup_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_remove_lookup);
|
||||
|
||||
static int led_classdev_next_name(const char *init_name, char *name,
|
||||
size_t len)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,21 @@ enum led_default_state {
|
|||
LEDS_DEFSTATE_KEEP = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct led_lookup_data - represents a single LED lookup entry
|
||||
*
|
||||
* @list: internal list of all LED lookup entries
|
||||
* @provider: name of led_classdev providing the LED
|
||||
* @dev_id: name of the device associated with this LED
|
||||
* @con_id: name of the LED from the device's point of view
|
||||
*/
|
||||
struct led_lookup_data {
|
||||
struct list_head list;
|
||||
const char *provider;
|
||||
const char *dev_id;
|
||||
const char *con_id;
|
||||
};
|
||||
|
||||
struct led_init_data {
|
||||
/* device fwnode handle */
|
||||
struct fwnode_handle *fwnode;
|
||||
|
@ -211,6 +226,12 @@ void devm_led_classdev_unregister(struct device *parent,
|
|||
void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
|
||||
void led_add_lookup(struct led_lookup_data *led_lookup);
|
||||
void led_remove_lookup(struct led_lookup_data *led_lookup);
|
||||
|
||||
struct led_classdev *__must_check led_get(struct device *dev, char *con_id);
|
||||
struct led_classdev *__must_check devm_led_get(struct device *dev, char *con_id);
|
||||
|
||||
extern struct led_classdev *of_led_get(struct device_node *np, int index);
|
||||
extern void led_put(struct led_classdev *led_cdev);
|
||||
struct led_classdev *__must_check devm_of_led_get(struct device *dev,
|
||||
|
|
Loading…
Reference in New Issue