Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
39f09320
Commit
39f09320
authored
Feb 03, 2023
by
Hans de Goede
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'ib-leds-led_get-v6.3' into HEAD
Immutable branch from LEDs due for the v6.3 merge window
parents
391bb17d
abc3100f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
139 additions
and
20 deletions
+139
-20
drivers/leds/led-class.c
drivers/leds/led-class.c
+118
-20
include/linux/leds.h
include/linux/leds.h
+21
-0
No files found.
drivers/leds/led-class.c
View file @
39f09320
...
...
@@ -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,19 +315,91 @@ 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
);
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
);
*
dr
=
led
;
devres_add
(
dev
,
dr
);
if
(
!
provider
)
return
ERR_PTR
(
-
ENOENT
);
return
led
;
led_dev
=
class_find_device_by_name
(
leds_class
,
provider
);
kfree_const
(
provider
);
return
led_module_get
(
led_dev
);
}
EXPORT_SYMBOL_GPL
(
devm_of_led_get
);
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
)
...
...
include/linux/leds.h
View file @
39f09320
...
...
@@ -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
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment