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
5293fea2
Commit
5293fea2
authored
Nov 02, 2015
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'device-properties' into acpi-pci
parents
02715e86
205ad97f
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
760 additions
and
194 deletions
+760
-194
drivers/acpi/device_sysfs.c
drivers/acpi/device_sysfs.c
+108
-12
drivers/acpi/property.c
drivers/acpi/property.c
+358
-69
drivers/acpi/scan.c
drivers/acpi/scan.c
+0
-20
drivers/base/property.c
drivers/base/property.c
+76
-12
drivers/dma/acpi-dma.c
drivers/dma/acpi-dma.c
+17
-8
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib-acpi.c
+109
-44
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.c
+1
-2
drivers/gpio/gpiolib.h
drivers/gpio/gpiolib.h
+9
-1
include/acpi/acpi_bus.h
include/acpi/acpi_bus.h
+31
-2
include/linux/acpi.h
include/linux/acpi.h
+46
-24
include/linux/fwnode.h
include/linux/fwnode.h
+1
-0
include/linux/property.h
include/linux/property.h
+4
-0
No files found.
drivers/acpi/device_sysfs.c
View file @
5293fea2
...
@@ -26,6 +26,106 @@
...
@@ -26,6 +26,106 @@
#include "internal.h"
#include "internal.h"
static
ssize_t
acpi_object_path
(
acpi_handle
handle
,
char
*
buf
)
{
struct
acpi_buffer
path
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
int
result
;
result
=
acpi_get_name
(
handle
,
ACPI_FULL_PATHNAME
,
&
path
);
if
(
result
)
return
result
;
result
=
sprintf
(
buf
,
"%s
\n
"
,
(
char
*
)
path
.
pointer
);
kfree
(
path
.
pointer
);
return
result
;
}
struct
acpi_data_node_attr
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
acpi_data_node
*
,
char
*
);
ssize_t
(
*
store
)(
struct
acpi_data_node
*
,
const
char
*
,
size_t
count
);
};
#define DATA_NODE_ATTR(_name) \
static struct acpi_data_node_attr data_node_##_name = \
__ATTR(_name, 0444, data_node_show_##_name, NULL)
static
ssize_t
data_node_show_path
(
struct
acpi_data_node
*
dn
,
char
*
buf
)
{
return
acpi_object_path
(
dn
->
handle
,
buf
);
}
DATA_NODE_ATTR
(
path
);
static
struct
attribute
*
acpi_data_node_default_attrs
[]
=
{
&
data_node_path
.
attr
,
NULL
};
#define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
#define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
static
ssize_t
acpi_data_node_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
acpi_data_node
*
dn
=
to_data_node
(
kobj
);
struct
acpi_data_node_attr
*
dn_attr
=
to_attr
(
attr
);
return
dn_attr
->
show
?
dn_attr
->
show
(
dn
,
buf
)
:
-
ENXIO
;
}
static
const
struct
sysfs_ops
acpi_data_node_sysfs_ops
=
{
.
show
=
acpi_data_node_attr_show
,
};
static
void
acpi_data_node_release
(
struct
kobject
*
kobj
)
{
struct
acpi_data_node
*
dn
=
to_data_node
(
kobj
);
complete
(
&
dn
->
kobj_done
);
}
static
struct
kobj_type
acpi_data_node_ktype
=
{
.
sysfs_ops
=
&
acpi_data_node_sysfs_ops
,
.
default_attrs
=
acpi_data_node_default_attrs
,
.
release
=
acpi_data_node_release
,
};
static
void
acpi_expose_nondev_subnodes
(
struct
kobject
*
kobj
,
struct
acpi_device_data
*
data
)
{
struct
list_head
*
list
=
&
data
->
subnodes
;
struct
acpi_data_node
*
dn
;
if
(
list_empty
(
list
))
return
;
list_for_each_entry
(
dn
,
list
,
sibling
)
{
int
ret
;
init_completion
(
&
dn
->
kobj_done
);
ret
=
kobject_init_and_add
(
&
dn
->
kobj
,
&
acpi_data_node_ktype
,
kobj
,
dn
->
name
);
if
(
ret
)
acpi_handle_err
(
dn
->
handle
,
"Failed to expose (%d)
\n
"
,
ret
);
else
acpi_expose_nondev_subnodes
(
&
dn
->
kobj
,
&
dn
->
data
);
}
}
static
void
acpi_hide_nondev_subnodes
(
struct
acpi_device_data
*
data
)
{
struct
list_head
*
list
=
&
data
->
subnodes
;
struct
acpi_data_node
*
dn
;
if
(
list_empty
(
list
))
return
;
list_for_each_entry_reverse
(
dn
,
list
,
sibling
)
{
acpi_hide_nondev_subnodes
(
&
dn
->
data
);
kobject_put
(
&
dn
->
kobj
);
}
}
/**
/**
* create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
* create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
* @acpi_dev: ACPI device object.
* @acpi_dev: ACPI device object.
...
@@ -323,20 +423,12 @@ static ssize_t acpi_device_adr_show(struct device *dev,
...
@@ -323,20 +423,12 @@ static ssize_t acpi_device_adr_show(struct device *dev,
}
}
static
DEVICE_ATTR
(
adr
,
0444
,
acpi_device_adr_show
,
NULL
);
static
DEVICE_ATTR
(
adr
,
0444
,
acpi_device_adr_show
,
NULL
);
static
ssize_t
static
ssize_t
acpi_device_path_show
(
struct
device
*
dev
,
acpi_device_path_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
acpi_device
*
acpi_dev
=
to_acpi_device
(
dev
);
struct
acpi_device
*
acpi_dev
=
to_acpi_device
(
dev
);
struct
acpi_buffer
path
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
int
result
;
result
=
acpi_get_name
(
acpi_dev
->
handle
,
ACPI_FULL_PATHNAME
,
&
path
);
if
(
result
)
goto
end
;
result
=
sprintf
(
buf
,
"%s
\n
"
,
(
char
*
)
path
.
pointer
);
return
acpi_object_path
(
acpi_dev
->
handle
,
buf
);
kfree
(
path
.
pointer
);
end:
return
result
;
}
}
static
DEVICE_ATTR
(
path
,
0444
,
acpi_device_path_show
,
NULL
);
static
DEVICE_ATTR
(
path
,
0444
,
acpi_device_path_show
,
NULL
);
...
@@ -475,6 +567,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
...
@@ -475,6 +567,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
&
dev_attr_real_power_state
);
&
dev_attr_real_power_state
);
}
}
acpi_expose_nondev_subnodes
(
&
dev
->
dev
.
kobj
,
&
dev
->
data
);
end:
end:
return
result
;
return
result
;
}
}
...
@@ -485,6 +579,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
...
@@ -485,6 +579,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
*/
*/
void
acpi_device_remove_files
(
struct
acpi_device
*
dev
)
void
acpi_device_remove_files
(
struct
acpi_device
*
dev
)
{
{
acpi_hide_nondev_subnodes
(
&
dev
->
data
);
if
(
dev
->
flags
.
power_manageable
)
{
if
(
dev
->
flags
.
power_manageable
)
{
device_remove_file
(
&
dev
->
dev
,
&
dev_attr_power_state
);
device_remove_file
(
&
dev
->
dev
,
&
dev_attr_power_state
);
if
(
dev
->
power
.
flags
.
power_resources
)
if
(
dev
->
power
.
flags
.
power_resources
)
...
...
drivers/acpi/property.c
View file @
5293fea2
This diff is collapsed.
Click to expand it.
drivers/acpi/scan.c
View file @
5293fea2
...
@@ -695,26 +695,6 @@ int acpi_device_add(struct acpi_device *device,
...
@@ -695,26 +695,6 @@ int acpi_device_add(struct acpi_device *device,
return
result
;
return
result
;
}
}
struct
acpi_device
*
acpi_get_next_child
(
struct
device
*
dev
,
struct
acpi_device
*
child
)
{
struct
acpi_device
*
adev
=
ACPI_COMPANION
(
dev
);
struct
list_head
*
head
,
*
next
;
if
(
!
adev
)
return
NULL
;
head
=
&
adev
->
children
;
if
(
list_empty
(
head
))
return
NULL
;
if
(
!
child
)
return
list_first_entry
(
head
,
struct
acpi_device
,
node
);
next
=
child
->
node
.
next
;
return
next
==
head
?
NULL
:
list_entry
(
next
,
struct
acpi_device
,
node
);
}
/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
Device Enumeration
Device Enumeration
-------------------------------------------------------------------------- */
-------------------------------------------------------------------------- */
...
...
drivers/base/property.c
View file @
5293fea2
...
@@ -134,7 +134,7 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
...
@@ -134,7 +134,7 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
if
(
is_of_node
(
fwnode
))
if
(
is_of_node
(
fwnode
))
return
of_property_read_bool
(
to_of_node
(
fwnode
),
propname
);
return
of_property_read_bool
(
to_of_node
(
fwnode
),
propname
);
else
if
(
is_acpi_node
(
fwnode
))
else
if
(
is_acpi_node
(
fwnode
))
return
!
acpi_
dev_prop_get
(
to_acpi_node
(
fwnode
)
,
propname
,
NULL
);
return
!
acpi_
node_prop_get
(
fwnode
,
propname
,
NULL
);
return
!!
pset_prop_get
(
to_pset
(
fwnode
),
propname
);
return
!!
pset_prop_get
(
to_pset
(
fwnode
),
propname
);
}
}
...
@@ -287,6 +287,28 @@ int device_property_read_string(struct device *dev, const char *propname,
...
@@ -287,6 +287,28 @@ int device_property_read_string(struct device *dev, const char *propname,
}
}
EXPORT_SYMBOL_GPL
(
device_property_read_string
);
EXPORT_SYMBOL_GPL
(
device_property_read_string
);
/**
* device_property_match_string - find a string in an array and return index
* @dev: Device to get the property of
* @propname: Name of the property holding the array
* @string: String to look for
*
* Find a given string in a string array and if it is found return the
* index back.
*
* Return: %0 if the property was found (success),
* %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of strings,
* %-ENXIO if no suitable firmware interface is present.
*/
int
device_property_match_string
(
struct
device
*
dev
,
const
char
*
propname
,
const
char
*
string
)
{
return
fwnode_property_match_string
(
dev_fwnode
(
dev
),
propname
,
string
);
}
EXPORT_SYMBOL_GPL
(
device_property_match_string
);
#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
: of_property_count_elems_of_size((node), (propname), sizeof(type))
: of_property_count_elems_of_size((node), (propname), sizeof(type))
...
@@ -298,8 +320,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
...
@@ -298,8 +320,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
_type_, _val_, _nval_); \
_type_, _val_, _nval_); \
else if (is_acpi_node(_fwnode_)) \
else if (is_acpi_node(_fwnode_)) \
_ret_ = acpi_
dev_prop_read(to_acpi_node(_fwnode_), _propnam
e_, \
_ret_ = acpi_
node_prop_read(_fwnode_, _propname_, _proptyp
e_, \
_proptype_,
_val_, _nval_); \
_val_, _nval_); \
else if (is_pset(_fwnode_)) \
else if (is_pset(_fwnode_)) \
_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
_proptype_, _val_, _nval_); \
_proptype_, _val_, _nval_); \
...
@@ -440,8 +462,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
...
@@ -440,8 +462,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
propname
,
val
,
nval
)
:
propname
,
val
,
nval
)
:
of_property_count_strings
(
to_of_node
(
fwnode
),
propname
);
of_property_count_strings
(
to_of_node
(
fwnode
),
propname
);
else
if
(
is_acpi_node
(
fwnode
))
else
if
(
is_acpi_node
(
fwnode
))
return
acpi_
dev_prop_read
(
to_acpi_node
(
fwnode
),
propname
,
return
acpi_
node_prop_read
(
fwnode
,
propname
,
DEV_PROP_STRING
,
DEV_PROP_STRING
,
val
,
nval
);
val
,
nval
);
else
if
(
is_pset
(
fwnode
))
else
if
(
is_pset
(
fwnode
))
return
pset_prop_read_array
(
to_pset
(
fwnode
),
propname
,
return
pset_prop_read_array
(
to_pset
(
fwnode
),
propname
,
DEV_PROP_STRING
,
val
,
nval
);
DEV_PROP_STRING
,
val
,
nval
);
...
@@ -470,14 +492,60 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
...
@@ -470,14 +492,60 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
if
(
is_of_node
(
fwnode
))
if
(
is_of_node
(
fwnode
))
return
of_property_read_string
(
to_of_node
(
fwnode
),
propname
,
val
);
return
of_property_read_string
(
to_of_node
(
fwnode
),
propname
,
val
);
else
if
(
is_acpi_node
(
fwnode
))
else
if
(
is_acpi_node
(
fwnode
))
return
acpi_
dev_prop_read
(
to_acpi_node
(
fwnode
),
propname
,
return
acpi_
node_prop_read
(
fwnode
,
propname
,
DEV_PROP_STRING
,
DEV_PROP_STRING
,
val
,
1
);
val
,
1
);
return
pset_prop_read_array
(
to_pset
(
fwnode
),
propname
,
return
pset_prop_read_array
(
to_pset
(
fwnode
),
propname
,
DEV_PROP_STRING
,
val
,
1
);
DEV_PROP_STRING
,
val
,
1
);
}
}
EXPORT_SYMBOL_GPL
(
fwnode_property_read_string
);
EXPORT_SYMBOL_GPL
(
fwnode_property_read_string
);
/**
* fwnode_property_match_string - find a string in an array and return index
* @fwnode: Firmware node to get the property of
* @propname: Name of the property holding the array
* @string: String to look for
*
* Find a given string in a string array and if it is found return the
* index back.
*
* Return: %0 if the property was found (success),
* %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of strings,
* %-ENXIO if no suitable firmware interface is present.
*/
int
fwnode_property_match_string
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
const
char
*
string
)
{
const
char
**
values
;
int
nval
,
ret
,
i
;
nval
=
fwnode_property_read_string_array
(
fwnode
,
propname
,
NULL
,
0
);
if
(
nval
<
0
)
return
nval
;
values
=
kcalloc
(
nval
,
sizeof
(
*
values
),
GFP_KERNEL
);
if
(
!
values
)
return
-
ENOMEM
;
ret
=
fwnode_property_read_string_array
(
fwnode
,
propname
,
values
,
nval
);
if
(
ret
<
0
)
goto
out
;
ret
=
-
ENODATA
;
for
(
i
=
0
;
i
<
nval
;
i
++
)
{
if
(
!
strcmp
(
values
[
i
],
string
))
{
ret
=
i
;
break
;
}
}
out:
kfree
(
values
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
fwnode_property_match_string
);
/**
/**
* device_get_next_child_node - Return the next child node handle for a device
* device_get_next_child_node - Return the next child node handle for a device
* @dev: Device to find the next child node for.
* @dev: Device to find the next child node for.
...
@@ -493,11 +561,7 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
...
@@ -493,11 +561,7 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
if
(
node
)
if
(
node
)
return
&
node
->
fwnode
;
return
&
node
->
fwnode
;
}
else
if
(
IS_ENABLED
(
CONFIG_ACPI
))
{
}
else
if
(
IS_ENABLED
(
CONFIG_ACPI
))
{
struct
acpi_device
*
node
;
return
acpi_get_next_subnode
(
dev
,
child
);
node
=
acpi_get_next_child
(
dev
,
to_acpi_node
(
child
));
if
(
node
)
return
acpi_fwnode_handle
(
node
);
}
}
return
NULL
;
return
NULL
;
}
}
...
...
drivers/dma/acpi-dma.c
View file @
5293fea2
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/acpi_dma.h>
#include <linux/acpi_dma.h>
#include <linux/property.h>
static
LIST_HEAD
(
acpi_dma_list
);
static
LIST_HEAD
(
acpi_dma_list
);
static
DEFINE_MUTEX
(
acpi_dma_lock
);
static
DEFINE_MUTEX
(
acpi_dma_lock
);
...
@@ -413,21 +414,29 @@ EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
...
@@ -413,21 +414,29 @@ EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
* translate the names "tx" and "rx" here based on the most common case where
* translate the names "tx" and "rx" here based on the most common case where
* the first FixedDMA descriptor is TX and second is RX.
* the first FixedDMA descriptor is TX and second is RX.
*
*
* If the device has "dma-names" property the FixedDMA descriptor indices
* are retrieved based on those. Otherwise the function falls back using
* hardcoded indices.
*
* Return:
* Return:
* Pointer to appropriate dma channel on success or an error pointer.
* Pointer to appropriate dma channel on success or an error pointer.
*/
*/
struct
dma_chan
*
acpi_dma_request_slave_chan_by_name
(
struct
device
*
dev
,
struct
dma_chan
*
acpi_dma_request_slave_chan_by_name
(
struct
device
*
dev
,
const
char
*
name
)
const
char
*
name
)
{
{
size_t
index
;
int
index
;
if
(
!
strcmp
(
name
,
"tx"
))
index
=
device_property_match_string
(
dev
,
"dma-names"
,
name
);
index
=
0
;
if
(
index
<
0
)
{
else
if
(
!
strcmp
(
name
,
"rx"
))
if
(
!
strcmp
(
name
,
"tx"
))
index
=
1
;
index
=
0
;
else
else
if
(
!
strcmp
(
name
,
"rx"
))
return
ERR_PTR
(
-
ENODEV
);
index
=
1
;
else
return
ERR_PTR
(
-
ENODEV
);
}
dev_dbg
(
dev
,
"found DMA channel
\"
%s
\"
at index %d
\n
"
,
name
,
index
);
return
acpi_dma_request_slave_chan_by_index
(
dev
,
index
);
return
acpi_dma_request_slave_chan_by_index
(
dev
,
index
);
}
}
EXPORT_SYMBOL_GPL
(
acpi_dma_request_slave_chan_by_name
);
EXPORT_SYMBOL_GPL
(
acpi_dma_request_slave_chan_by_name
);
...
...
drivers/gpio/gpiolib-acpi.c
View file @
5293fea2
...
@@ -389,6 +389,8 @@ struct acpi_gpio_lookup {
...
@@ -389,6 +389,8 @@ struct acpi_gpio_lookup {
struct
acpi_gpio_info
info
;
struct
acpi_gpio_info
info
;
int
index
;
int
index
;
int
pin_index
;
int
pin_index
;
bool
active_low
;
struct
acpi_device
*
adev
;
struct
gpio_desc
*
desc
;
struct
gpio_desc
*
desc
;
int
n
;
int
n
;
};
};
...
@@ -425,6 +427,65 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
...
@@ -425,6 +427,65 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
return
1
;
return
1
;
}
}
static
int
acpi_gpio_resource_lookup
(
struct
acpi_gpio_lookup
*
lookup
,
struct
acpi_gpio_info
*
info
)
{
struct
list_head
res_list
;
int
ret
;
INIT_LIST_HEAD
(
&
res_list
);
ret
=
acpi_dev_get_resources
(
lookup
->
adev
,
&
res_list
,
acpi_find_gpio
,
lookup
);
if
(
ret
<
0
)
return
ret
;
acpi_dev_free_resource_list
(
&
res_list
);
if
(
!
lookup
->
desc
)
return
-
ENOENT
;
if
(
info
)
{
*
info
=
lookup
->
info
;
if
(
lookup
->
active_low
)
info
->
active_low
=
lookup
->
active_low
;
}
return
0
;
}
static
int
acpi_gpio_property_lookup
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
int
index
,
struct
acpi_gpio_lookup
*
lookup
)
{
struct
acpi_reference_args
args
;
int
ret
;
memset
(
&
args
,
0
,
sizeof
(
args
));
ret
=
acpi_node_get_property_reference
(
fwnode
,
propname
,
index
,
&
args
);
if
(
ret
)
{
struct
acpi_device
*
adev
=
to_acpi_device_node
(
fwnode
);
if
(
!
adev
)
return
ret
;
if
(
!
acpi_get_driver_gpio_data
(
adev
,
propname
,
index
,
&
args
))
return
ret
;
}
/*
* The property was found and resolved, so need to lookup the GPIO based
* on returned args.
*/
lookup
->
adev
=
args
.
adev
;
if
(
args
.
nargs
>=
2
)
{
lookup
->
index
=
args
.
args
[
0
];
lookup
->
pin_index
=
args
.
args
[
1
];
/* 3rd argument, if present is used to specify active_low. */
if
(
args
.
nargs
>=
3
)
lookup
->
active_low
=
!!
args
.
args
[
2
];
}
return
0
;
}
/**
/**
* acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
* acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
* @adev: pointer to a ACPI device to get GPIO from
* @adev: pointer to a ACPI device to get GPIO from
...
@@ -452,8 +513,6 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
...
@@ -452,8 +513,6 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
struct
acpi_gpio_info
*
info
)
struct
acpi_gpio_info
*
info
)
{
{
struct
acpi_gpio_lookup
lookup
;
struct
acpi_gpio_lookup
lookup
;
struct
list_head
resource_list
;
bool
active_low
=
false
;
int
ret
;
int
ret
;
if
(
!
adev
)
if
(
!
adev
)
...
@@ -463,58 +522,64 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
...
@@ -463,58 +522,64 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
lookup
.
index
=
index
;
lookup
.
index
=
index
;
if
(
propname
)
{
if
(
propname
)
{
struct
acpi_reference_args
args
;
dev_dbg
(
&
adev
->
dev
,
"GPIO: looking up %s
\n
"
,
propname
);
dev_dbg
(
&
adev
->
dev
,
"GPIO: looking up %s
\n
"
,
propname
);
memset
(
&
args
,
0
,
sizeof
(
args
));
ret
=
acpi_gpio_property_lookup
(
acpi_fwnode_handle
(
adev
),
ret
=
acpi_dev_get_property_reference
(
adev
,
propname
,
propname
,
index
,
&
lookup
);
index
,
&
args
);
if
(
ret
)
if
(
ret
)
{
return
ERR_PTR
(
ret
);
bool
found
=
acpi_get_driver_gpio_data
(
adev
,
propname
,
index
,
&
args
);
if
(
!
found
)
return
ERR_PTR
(
ret
);
}
/*
dev_dbg
(
&
adev
->
dev
,
"GPIO: _DSD returned %s %d %d %u
\n
"
,
* The property was found and resolved so need to
dev_name
(
&
lookup
.
adev
->
dev
),
lookup
.
index
,
* lookup the GPIO based on returned args instead.
lookup
.
pin_index
,
lookup
.
active_low
);
*/
adev
=
args
.
adev
;
if
(
args
.
nargs
>=
2
)
{
lookup
.
index
=
args
.
args
[
0
];
lookup
.
pin_index
=
args
.
args
[
1
];
/*
* 3rd argument, if present is used to
* specify active_low.
*/
if
(
args
.
nargs
>=
3
)
active_low
=
!!
args
.
args
[
2
];
}
dev_dbg
(
&
adev
->
dev
,
"GPIO: _DSD returned %s %zd %llu %llu %llu
\n
"
,
dev_name
(
&
adev
->
dev
),
args
.
nargs
,
args
.
args
[
0
],
args
.
args
[
1
],
args
.
args
[
2
]);
}
else
{
}
else
{
dev_dbg
(
&
adev
->
dev
,
"GPIO: looking up %d in _CRS
\n
"
,
index
);
dev_dbg
(
&
adev
->
dev
,
"GPIO: looking up %d in _CRS
\n
"
,
index
);
lookup
.
adev
=
adev
;
}
}
INIT_LIST_HEAD
(
&
resource_list
);
ret
=
acpi_gpio_resource_lookup
(
&
lookup
,
info
);
ret
=
acpi_dev_get_resources
(
adev
,
&
resource_list
,
acpi_find_gpio
,
return
ret
?
ERR_PTR
(
ret
)
:
lookup
.
desc
;
&
lookup
);
}
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
/**
* acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
* @fwnode: pointer to an ACPI firmware node to get the GPIO information from
* @propname: Property name of the GPIO
* @index: index of GpioIo/GpioInt resource (starting from %0)
* @info: info pointer to fill in (optional)
*
* If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it.
* Otherwise (ie. it is a data-only non-device object), use the property-based
* GPIO lookup to get to the GPIO resource with the relevant information and use
* that to obtain the GPIO descriptor to return.
*/
struct
gpio_desc
*
acpi_node_get_gpiod
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
int
index
,
struct
acpi_gpio_info
*
info
)
{
struct
acpi_gpio_lookup
lookup
;
struct
acpi_device
*
adev
;
int
ret
;
acpi_dev_free_resource_list
(
&
resource_list
);
adev
=
to_acpi_device_node
(
fwnode
);
if
(
adev
)
return
acpi_get_gpiod_by_index
(
adev
,
propname
,
index
,
info
);
if
(
lookup
.
desc
&&
info
)
{
if
(
!
is_acpi_data_node
(
fwnode
))
*
info
=
lookup
.
info
;
return
ERR_PTR
(
-
ENODEV
);
if
(
active_low
)
info
->
active_low
=
active_low
;
if
(
!
propname
)
}
return
ERR_PTR
(
-
EINVAL
);
memset
(
&
lookup
,
0
,
sizeof
(
lookup
));
lookup
.
index
=
index
;
ret
=
acpi_gpio_property_lookup
(
fwnode
,
propname
,
index
,
&
lookup
);
if
(
ret
)
return
ERR_PTR
(
ret
);
return
lookup
.
desc
?
lookup
.
desc
:
ERR_PTR
(
-
ENOENT
);
ret
=
acpi_gpio_resource_lookup
(
&
lookup
,
info
);
return
ret
?
ERR_PTR
(
ret
)
:
lookup
.
desc
;
}
}
/**
/**
...
...
drivers/gpio/gpiolib.c
View file @
5293fea2
...
@@ -2093,8 +2093,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
...
@@ -2093,8 +2093,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
}
else
if
(
is_acpi_node
(
fwnode
))
{
}
else
if
(
is_acpi_node
(
fwnode
))
{
struct
acpi_gpio_info
info
;
struct
acpi_gpio_info
info
;
desc
=
acpi_get_gpiod_by_index
(
to_acpi_node
(
fwnode
),
propname
,
0
,
desc
=
acpi_node_get_gpiod
(
fwnode
,
propname
,
0
,
&
info
);
&
info
);
if
(
!
IS_ERR
(
desc
))
if
(
!
IS_ERR
(
desc
))
active_low
=
info
.
active_low
;
active_low
=
info
.
active_low
;
}
}
...
...
drivers/gpio/gpiolib.h
View file @
5293fea2
...
@@ -42,6 +42,9 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
...
@@ -42,6 +42,9 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
struct
gpio_desc
*
acpi_get_gpiod_by_index
(
struct
acpi_device
*
adev
,
struct
gpio_desc
*
acpi_get_gpiod_by_index
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
int
index
,
const
char
*
propname
,
int
index
,
struct
acpi_gpio_info
*
info
);
struct
acpi_gpio_info
*
info
);
struct
gpio_desc
*
acpi_node_get_gpiod
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
int
index
,
struct
acpi_gpio_info
*
info
);
int
acpi_gpio_count
(
struct
device
*
dev
,
const
char
*
con_id
);
int
acpi_gpio_count
(
struct
device
*
dev
,
const
char
*
con_id
);
#else
#else
...
@@ -60,7 +63,12 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
...
@@ -60,7 +63,12 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
{
{
return
ERR_PTR
(
-
ENOSYS
);
return
ERR_PTR
(
-
ENOSYS
);
}
}
static
inline
struct
gpio_desc
*
acpi_node_get_gpiod
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
int
index
,
struct
acpi_gpio_info
*
info
)
{
return
ERR_PTR
(
-
ENXIO
);
}
static
inline
int
acpi_gpio_count
(
struct
device
*
dev
,
const
char
*
con_id
)
static
inline
int
acpi_gpio_count
(
struct
device
*
dev
,
const
char
*
con_id
)
{
{
return
-
ENODEV
;
return
-
ENODEV
;
...
...
include/acpi/acpi_bus.h
View file @
5293fea2
...
@@ -343,6 +343,7 @@ struct acpi_device_data {
...
@@ -343,6 +343,7 @@ struct acpi_device_data {
const
union
acpi_object
*
pointer
;
const
union
acpi_object
*
pointer
;
const
union
acpi_object
*
properties
;
const
union
acpi_object
*
properties
;
const
union
acpi_object
*
of_compatible
;
const
union
acpi_object
*
of_compatible
;
struct
list_head
subnodes
;
};
};
struct
acpi_gpio_mapping
;
struct
acpi_gpio_mapping
;
...
@@ -378,6 +379,17 @@ struct acpi_device {
...
@@ -378,6 +379,17 @@ struct acpi_device {
void
(
*
remove
)(
struct
acpi_device
*
);
void
(
*
remove
)(
struct
acpi_device
*
);
};
};
/* Non-device subnode */
struct
acpi_data_node
{
const
char
*
name
;
acpi_handle
handle
;
struct
fwnode_handle
fwnode
;
struct
acpi_device_data
data
;
struct
list_head
sibling
;
struct
kobject
kobj
;
struct
completion
kobj_done
;
};
static
inline
bool
acpi_check_dma
(
struct
acpi_device
*
adev
,
bool
*
coherent
)
static
inline
bool
acpi_check_dma
(
struct
acpi_device
*
adev
,
bool
*
coherent
)
{
{
bool
ret
=
false
;
bool
ret
=
false
;
...
@@ -412,16 +424,33 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
...
@@ -412,16 +424,33 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
}
}
static
inline
bool
is_acpi_node
(
struct
fwnode_handle
*
fwnode
)
static
inline
bool
is_acpi_node
(
struct
fwnode_handle
*
fwnode
)
{
return
fwnode
&&
(
fwnode
->
type
==
FWNODE_ACPI
||
fwnode
->
type
==
FWNODE_ACPI_DATA
);
}
static
inline
bool
is_acpi_device_node
(
struct
fwnode_handle
*
fwnode
)
{
{
return
fwnode
&&
fwnode
->
type
==
FWNODE_ACPI
;
return
fwnode
&&
fwnode
->
type
==
FWNODE_ACPI
;
}
}
static
inline
struct
acpi_device
*
to_acpi_node
(
struct
fwnode_handle
*
fwnode
)
static
inline
struct
acpi_device
*
to_acpi_
device_
node
(
struct
fwnode_handle
*
fwnode
)
{
{
return
is_acpi_node
(
fwnode
)
?
return
is_acpi_
device_
node
(
fwnode
)
?
container_of
(
fwnode
,
struct
acpi_device
,
fwnode
)
:
NULL
;
container_of
(
fwnode
,
struct
acpi_device
,
fwnode
)
:
NULL
;
}
}
static
inline
bool
is_acpi_data_node
(
struct
fwnode_handle
*
fwnode
)
{
return
fwnode
&&
fwnode
->
type
==
FWNODE_ACPI_DATA
;
}
static
inline
struct
acpi_data_node
*
to_acpi_data_node
(
struct
fwnode_handle
*
fwnode
)
{
return
is_acpi_data_node
(
fwnode
)
?
container_of
(
fwnode
,
struct
acpi_data_node
,
fwnode
)
:
NULL
;
}
static
inline
struct
fwnode_handle
*
acpi_fwnode_handle
(
struct
acpi_device
*
adev
)
static
inline
struct
fwnode_handle
*
acpi_fwnode_handle
(
struct
acpi_device
*
adev
)
{
{
return
&
adev
->
fwnode
;
return
&
adev
->
fwnode
;
...
...
include/linux/acpi.h
View file @
5293fea2
...
@@ -49,7 +49,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
...
@@ -49,7 +49,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
return
adev
?
adev
->
handle
:
NULL
;
return
adev
?
adev
->
handle
:
NULL
;
}
}
#define ACPI_COMPANION(dev) to_acpi_node((dev)->fwnode)
#define ACPI_COMPANION(dev) to_acpi_
device_
node((dev)->fwnode)
#define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \
#define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \
acpi_fwnode_handle(adev) : NULL)
acpi_fwnode_handle(adev) : NULL)
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
...
@@ -69,7 +69,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
...
@@ -69,7 +69,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
static
inline
bool
has_acpi_companion
(
struct
device
*
dev
)
static
inline
bool
has_acpi_companion
(
struct
device
*
dev
)
{
{
return
is_acpi_node
(
dev
->
fwnode
);
return
is_acpi_
device_
node
(
dev
->
fwnode
);
}
}
static
inline
void
acpi_preset_companion
(
struct
device
*
dev
,
static
inline
void
acpi_preset_companion
(
struct
device
*
dev
,
...
@@ -462,7 +462,22 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode)
...
@@ -462,7 +462,22 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode)
return
false
;
return
false
;
}
}
static
inline
struct
acpi_device
*
to_acpi_node
(
struct
fwnode_handle
*
fwnode
)
static
inline
bool
is_acpi_device_node
(
struct
fwnode_handle
*
fwnode
)
{
return
false
;
}
static
inline
struct
acpi_device
*
to_acpi_device_node
(
struct
fwnode_handle
*
fwnode
)
{
return
NULL
;
}
static
inline
bool
is_acpi_data_node
(
struct
fwnode_handle
*
fwnode
)
{
return
false
;
}
static
inline
struct
acpi_data_node
*
to_acpi_data_node
(
struct
fwnode_handle
*
fwnode
)
{
{
return
NULL
;
return
NULL
;
}
}
...
@@ -744,22 +759,21 @@ struct acpi_reference_args {
...
@@ -744,22 +759,21 @@ struct acpi_reference_args {
#ifdef CONFIG_ACPI
#ifdef CONFIG_ACPI
int
acpi_dev_get_property
(
struct
acpi_device
*
adev
,
const
char
*
name
,
int
acpi_dev_get_property
(
struct
acpi_device
*
adev
,
const
char
*
name
,
acpi_object_type
type
,
const
union
acpi_object
**
obj
);
acpi_object_type
type
,
const
union
acpi_object
**
obj
);
int
acpi_dev_get_property_array
(
struct
acpi_device
*
adev
,
const
char
*
name
,
int
acpi_node_get_property_reference
(
struct
fwnode_handle
*
fwnode
,
acpi_object_type
type
,
const
char
*
name
,
size_t
index
,
const
union
acpi_object
**
obj
);
struct
acpi_reference_args
*
args
);
int
acpi_dev_get_property_reference
(
struct
acpi_device
*
adev
,
const
char
*
name
,
size_t
index
,
int
acpi_node_prop_get
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
struct
acpi_reference_args
*
args
);
void
**
valptr
);
int
acpi_dev_prop_get
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
void
**
valptr
);
int
acpi_dev_prop_read_single
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
int
acpi_dev_prop_read_single
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
enum
dev_prop_type
proptype
,
void
*
val
);
enum
dev_prop_type
proptype
,
void
*
val
);
int
acpi_node_prop_read
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
enum
dev_prop_type
proptype
,
void
*
val
,
size_t
nval
);
int
acpi_dev_prop_read
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
int
acpi_dev_prop_read
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
enum
dev_prop_type
proptype
,
void
*
val
,
size_t
nval
);
enum
dev_prop_type
proptype
,
void
*
val
,
size_t
nval
);
struct
acpi_device
*
acpi_get_next_child
(
struct
device
*
dev
,
struct
fwnode_handle
*
acpi_get_next_subnode
(
struct
device
*
dev
,
struct
acpi_device
*
child
);
struct
fwnode_handle
*
subnode
);
#else
#else
static
inline
int
acpi_dev_get_property
(
struct
acpi_device
*
adev
,
static
inline
int
acpi_dev_get_property
(
struct
acpi_device
*
adev
,
const
char
*
name
,
acpi_object_type
type
,
const
char
*
name
,
acpi_object_type
type
,
...
@@ -767,16 +781,17 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
...
@@ -767,16 +781,17 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
{
{
return
-
ENXIO
;
return
-
ENXIO
;
}
}
static
inline
int
acpi_dev_get_property_array
(
struct
acpi_device
*
adev
,
const
char
*
nam
e
,
static
inline
int
acpi_node_get_property_reference
(
struct
fwnode_handle
*
fwnod
e
,
acpi_object_type
typ
e
,
const
char
*
name
,
const
char
*
cells_nam
e
,
const
union
acpi_object
**
obj
)
size_t
index
,
struct
acpi_reference_args
*
args
)
{
{
return
-
ENXIO
;
return
-
ENXIO
;
}
}
static
inline
int
acpi_dev_get_property_reference
(
struct
acpi_device
*
adev
,
const
char
*
name
,
const
char
*
cells_name
,
static
inline
int
acpi_node_prop_get
(
struct
fwnode_handle
*
fwnode
,
size_t
index
,
struct
acpi_reference_args
*
args
)
const
char
*
propname
,
void
**
valptr
)
{
{
return
-
ENXIO
;
return
-
ENXIO
;
}
}
...
@@ -796,6 +811,14 @@ static inline int acpi_dev_prop_read_single(struct acpi_device *adev,
...
@@ -796,6 +811,14 @@ static inline int acpi_dev_prop_read_single(struct acpi_device *adev,
return
-
ENXIO
;
return
-
ENXIO
;
}
}
static
inline
int
acpi_node_prop_read
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
enum
dev_prop_type
proptype
,
void
*
val
,
size_t
nval
)
{
return
-
ENXIO
;
}
static
inline
int
acpi_dev_prop_read
(
struct
acpi_device
*
adev
,
static
inline
int
acpi_dev_prop_read
(
struct
acpi_device
*
adev
,
const
char
*
propname
,
const
char
*
propname
,
enum
dev_prop_type
proptype
,
enum
dev_prop_type
proptype
,
...
@@ -804,12 +827,11 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev,
...
@@ -804,12 +827,11 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev,
return
-
ENXIO
;
return
-
ENXIO
;
}
}
static
inline
struct
acpi_device
*
acpi_get_next_child
(
struct
device
*
dev
,
static
inline
struct
fwnode_handle
*
acpi_get_next_subnode
(
struct
device
*
dev
,
struct
acpi_device
*
child
)
struct
fwnode_handle
*
subnode
)
{
{
return
NULL
;
return
NULL
;
}
}
#endif
#endif
#endif
/*_LINUX_ACPI_H*/
#endif
/*_LINUX_ACPI_H*/
include/linux/fwnode.h
View file @
5293fea2
...
@@ -16,6 +16,7 @@ enum fwnode_type {
...
@@ -16,6 +16,7 @@ enum fwnode_type {
FWNODE_INVALID
=
0
,
FWNODE_INVALID
=
0
,
FWNODE_OF
,
FWNODE_OF
,
FWNODE_ACPI
,
FWNODE_ACPI
,
FWNODE_ACPI_DATA
,
FWNODE_PDATA
,
FWNODE_PDATA
,
};
};
...
...
include/linux/property.h
View file @
5293fea2
...
@@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname,
...
@@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname,
const
char
**
val
,
size_t
nval
);
const
char
**
val
,
size_t
nval
);
int
device_property_read_string
(
struct
device
*
dev
,
const
char
*
propname
,
int
device_property_read_string
(
struct
device
*
dev
,
const
char
*
propname
,
const
char
**
val
);
const
char
**
val
);
int
device_property_match_string
(
struct
device
*
dev
,
const
char
*
propname
,
const
char
*
string
);
bool
fwnode_property_present
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
);
bool
fwnode_property_present
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
);
int
fwnode_property_read_u8_array
(
struct
fwnode_handle
*
fwnode
,
int
fwnode_property_read_u8_array
(
struct
fwnode_handle
*
fwnode
,
...
@@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
...
@@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
size_t
nval
);
size_t
nval
);
int
fwnode_property_read_string
(
struct
fwnode_handle
*
fwnode
,
int
fwnode_property_read_string
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
const
char
**
val
);
const
char
*
propname
,
const
char
**
val
);
int
fwnode_property_match_string
(
struct
fwnode_handle
*
fwnode
,
const
char
*
propname
,
const
char
*
string
);
struct
fwnode_handle
*
device_get_next_child_node
(
struct
device
*
dev
,
struct
fwnode_handle
*
device_get_next_child_node
(
struct
device
*
dev
,
struct
fwnode_handle
*
child
);
struct
fwnode_handle
*
child
);
...
...
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