Skip to content

Commit

Permalink
Merge tag 'devprop-4.13-rc1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/rafael/linux-pm

Pull device properties framework updates from Rafael Wysocki:
 "These mostly rearrange the device properties core code and add a few
  helper functions to it as a foundation for future work.

  Specifics:

   - Rearrange the core device properties code by moving the code
     specific to each supported platform configuration framework (ACPI,
     DT and build-in) into a separate file (Sakari Ailus).

   - Add helper functions for accessing device properties in a
     firmware-agnostic way (Sakari Ailus, Kieran Bingham)"

* tag 'devprop-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  device property: Add fwnode_graph_get_port_parent
  device property: Add FW type agnostic fwnode_graph_get_remote_node
  device property: Introduce fwnode_device_is_available()
  device property: Move fwnode graph ops to firmware specific locations
  device property: Move FW type specific functionality to FW specific files
  ACPI: Constify argument to acpi_device_is_present()
  • Loading branch information
torvalds committed Jul 10, 2017
2 parents 3226186 + 6a71d8d commit 548aa0e
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 207 deletions.
4 changes: 3 additions & 1 deletion drivers/acpi/device_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,10 @@ int acpi_bus_init_power(struct acpi_device *device)
return -EINVAL;

device->power.state = ACPI_STATE_UNKNOWN;
if (!acpi_device_is_present(device))
if (!acpi_device_is_present(device)) {
device->flags.initialized = false;
return -ENXIO;
}

result = acpi_device_get_power(device, &state);
if (result)
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ int acpi_device_setup_files(struct acpi_device *dev);
void acpi_device_remove_files(struct acpi_device *dev);
void acpi_device_add_finalize(struct acpi_device *device);
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
bool acpi_device_is_present(struct acpi_device *adev);
bool acpi_device_is_present(const struct acpi_device *adev);
bool acpi_device_is_battery(struct acpi_device *adev);
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
const struct device *dev);
Expand Down
117 changes: 117 additions & 0 deletions drivers/acpi/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,

dn->name = link->package.elements[0].string.pointer;
dn->fwnode.type = FWNODE_ACPI_DATA;
dn->fwnode.ops = &acpi_fwnode_ops;
dn->parent = parent;
INIT_LIST_HEAD(&dn->data.subnodes);

Expand Down Expand Up @@ -1119,3 +1120,119 @@ int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode,

return 0;
}

static bool acpi_fwnode_device_is_available(struct fwnode_handle *fwnode)
{
if (!is_acpi_device_node(fwnode))
return false;

return acpi_device_is_present(to_acpi_device_node(fwnode));
}

static bool acpi_fwnode_property_present(struct fwnode_handle *fwnode,
const char *propname)
{
return !acpi_node_prop_get(fwnode, propname, NULL);
}

static int acpi_fwnode_property_read_int_array(struct fwnode_handle *fwnode,
const char *propname,
unsigned int elem_size,
void *val, size_t nval)
{
enum dev_prop_type type;

switch (elem_size) {
case sizeof(u8):
type = DEV_PROP_U8;
break;
case sizeof(u16):
type = DEV_PROP_U16;
break;
case sizeof(u32):
type = DEV_PROP_U32;
break;
case sizeof(u64):
type = DEV_PROP_U64;
break;
default:
return -ENXIO;
}

return acpi_node_prop_read(fwnode, propname, type, val, nval);
}

static int acpi_fwnode_property_read_string_array(struct fwnode_handle *fwnode,
const char *propname,
const char **val, size_t nval)
{
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
val, nval);
}

static struct fwnode_handle *
acpi_fwnode_get_named_child_node(struct fwnode_handle *fwnode,
const char *childname)
{
struct fwnode_handle *child;

/*
* Find first matching named child node of this fwnode.
* For ACPI this will be a data only sub-node.
*/
fwnode_for_each_child_node(fwnode, child)
if (acpi_data_node_match(child, childname))
return child;

return NULL;
}

static struct fwnode_handle *
acpi_fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
struct fwnode_handle *prev)
{
struct fwnode_handle *endpoint;

endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
if (IS_ERR(endpoint))
return NULL;

return endpoint;
}

static struct fwnode_handle *
acpi_fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
{
struct fwnode_handle *endpoint = NULL;

acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, &endpoint);

return endpoint;
}

static int acpi_fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint)
{
struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode);

endpoint->local_fwnode = fwnode;

fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);

return 0;
}

const struct fwnode_operations acpi_fwnode_ops = {
.device_is_available = acpi_fwnode_device_is_available,
.property_present = acpi_fwnode_property_present,
.property_read_int_array = acpi_fwnode_property_read_int_array,
.property_read_string_array = acpi_fwnode_property_read_string_array,
.get_parent = acpi_node_get_parent,
.get_next_child_node = acpi_get_next_subnode,
.get_named_child_node = acpi_fwnode_get_named_child_node,
.graph_get_next_endpoint = acpi_fwnode_graph_get_next_endpoint,
.graph_get_remote_endpoint = acpi_fwnode_graph_get_remote_endpoint,
.graph_get_port_parent = acpi_node_get_parent,
.graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint,
};
10 changes: 4 additions & 6 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
device->handle = handle;
device->parent = acpi_bus_get_parent(handle);
device->fwnode.type = FWNODE_ACPI;
device->fwnode.ops = &acpi_fwnode_ops;
acpi_set_device_status(device, sta);
acpi_device_get_busid(device);
acpi_set_pnp_ids(handle, &device->pnp, type);
Expand Down Expand Up @@ -1600,13 +1601,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
return 0;
}

bool acpi_device_is_present(struct acpi_device *adev)
bool acpi_device_is_present(const struct acpi_device *adev)
{
if (adev->status.present || adev->status.functional)
return true;

adev->flags.initialized = false;
return false;
return adev->status.present || adev->status.functional;
}

static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
Expand Down Expand Up @@ -1839,6 +1836,7 @@ static void acpi_bus_attach(struct acpi_device *device)
acpi_bus_get_status(device);
/* Skip devices that are not present. */
if (!acpi_device_is_present(device)) {
device->flags.initialized = false;
acpi_device_clear_enumerated(device);
device->flags.power_manageable = 0;
return;
Expand Down
Loading

0 comments on commit 548aa0e

Please sign in to comment.