Commit d8924c0d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'devprop-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull device properties framework updates from Rafael Wysocki:
 "This introduces 'software nodes' that are analogous to the DT and ACPI
  firmware nodes except that they can be created by drivers themselves
  and do a couple of assorted cleanups.

  Specifics:

   - Introduce "software nodes", analogous to the DT and ACPI firmware
     nodes except that they can be created by kernel code, in order to
     complement fwnodes representing real firmware nodes when they are
     incomplete (for example missing device properties) and to supply
     the primary fwnode when the firmware lacks hardware description for
     a device completely, and replace the "property_set" struct
     fwnode_handle type with software nodes (Heikki Krogerus).

   - Clean up the just introduced software nodes support and fix a
     commet in the graph-handling code (Colin Ian King, Marco Felsch)"

* tag 'devprop-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  device property: fix fwnode_graph_get_next_endpoint() documentation
  drivers: base: swnode: remove need for a temporary string for the node name
  device property: Remove struct property_set
  device property: Move device_add_properties() to swnode.c
  drivers: base: Introducing software nodes to the firmware node framework
  ACPI / glue: Add acpi_platform_notify() function
  drivers core: Prepare support for multiple platform notifications
  driver core: platform: Remove duplicated device_remove_properties() call
parents 1fbb2dc6 f569da8c
What: /sys/devices/.../software_node/
Date: January 2019
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Description:
This directory contains the details about the device that are
assigned in kernel (i.e. software), as opposed to the
firmware_node directory which contains the details that are
assigned for the device in firmware. The main attributes in the
directory will show the properties the device has, and the
relationship it has to some of the other devices.
...@@ -1237,7 +1237,6 @@ static int __init acpi_init(void) ...@@ -1237,7 +1237,6 @@ static int __init acpi_init(void)
acpi_kobj = NULL; acpi_kobj = NULL;
} }
init_acpi_device_notify();
result = acpi_bus_init(); result = acpi_bus_init();
if (result) { if (result) {
disable_acpi(); disable_acpi();
......
...@@ -296,7 +296,7 @@ int acpi_unbind_one(struct device *dev) ...@@ -296,7 +296,7 @@ int acpi_unbind_one(struct device *dev)
} }
EXPORT_SYMBOL_GPL(acpi_unbind_one); EXPORT_SYMBOL_GPL(acpi_unbind_one);
static int acpi_platform_notify(struct device *dev) static int acpi_device_notify(struct device *dev)
{ {
struct acpi_bus_type *type = acpi_get_bus_type(dev); struct acpi_bus_type *type = acpi_get_bus_type(dev);
struct acpi_device *adev; struct acpi_device *adev;
...@@ -343,7 +343,7 @@ static int acpi_platform_notify(struct device *dev) ...@@ -343,7 +343,7 @@ static int acpi_platform_notify(struct device *dev)
return ret; return ret;
} }
static int acpi_platform_notify_remove(struct device *dev) static int acpi_device_notify_remove(struct device *dev)
{ {
struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_bus_type *type; struct acpi_bus_type *type;
...@@ -361,12 +361,17 @@ static int acpi_platform_notify_remove(struct device *dev) ...@@ -361,12 +361,17 @@ static int acpi_platform_notify_remove(struct device *dev)
return 0; return 0;
} }
void __init init_acpi_device_notify(void) int acpi_platform_notify(struct device *dev, enum kobject_action action)
{ {
if (platform_notify || platform_notify_remove) { switch (action) {
printk(KERN_ERR PREFIX "Can't use platform_notify\n"); case KOBJ_ADD:
return; acpi_device_notify(dev);
break;
case KOBJ_REMOVE:
acpi_device_notify_remove(dev);
break;
default:
break;
} }
platform_notify = acpi_platform_notify; return 0;
platform_notify_remove = acpi_platform_notify_remove;
} }
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
int early_acpi_osi_init(void); int early_acpi_osi_init(void);
int acpi_osi_init(void); int acpi_osi_init(void);
acpi_status acpi_os_initialize1(void); acpi_status acpi_os_initialize1(void);
void init_acpi_device_notify(void);
int acpi_scan_init(void); int acpi_scan_init(void);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
void acpi_pci_root_init(void); void acpi_pci_root_init(void);
......
...@@ -6,7 +6,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ ...@@ -6,7 +6,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
cpu.o firmware.o init.o map.o devres.o \ cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o \ attribute_container.o transport_class.o \
topology.o container.o property.o cacheinfo.o \ topology.o container.o property.o cacheinfo.o \
devcon.o devcon.o swnode.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/ obj-y += power/
obj-$(CONFIG_ISA_BUS_API) += isa.o obj-$(CONFIG_ISA_BUS_API) += isa.o
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (c) 2006 Novell, Inc. * Copyright (c) 2006 Novell, Inc.
*/ */
#include <linux/acpi.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/fwnode.h> #include <linux/fwnode.h>
...@@ -728,6 +729,26 @@ static inline int device_is_not_partition(struct device *dev) ...@@ -728,6 +729,26 @@ static inline int device_is_not_partition(struct device *dev)
} }
#endif #endif
static int
device_platform_notify(struct device *dev, enum kobject_action action)
{
int ret;
ret = acpi_platform_notify(dev, action);
if (ret)
return ret;
ret = software_node_notify(dev, action);
if (ret)
return ret;
if (platform_notify && action == KOBJ_ADD)
platform_notify(dev);
else if (platform_notify_remove && action == KOBJ_REMOVE)
platform_notify_remove(dev);
return 0;
}
/** /**
* dev_driver_string - Return a device's driver name, if at all possible * dev_driver_string - Return a device's driver name, if at all possible
* @dev: struct device to get the name of * @dev: struct device to get the name of
...@@ -1883,8 +1904,9 @@ int device_add(struct device *dev) ...@@ -1883,8 +1904,9 @@ int device_add(struct device *dev)
} }
/* notify platform of device entry */ /* notify platform of device entry */
if (platform_notify) error = device_platform_notify(dev, KOBJ_ADD);
platform_notify(dev); if (error)
goto platform_error;
error = device_create_file(dev, &dev_attr_uevent); error = device_create_file(dev, &dev_attr_uevent);
if (error) if (error)
...@@ -1960,6 +1982,8 @@ int device_add(struct device *dev) ...@@ -1960,6 +1982,8 @@ int device_add(struct device *dev)
SymlinkError: SymlinkError:
device_remove_file(dev, &dev_attr_uevent); device_remove_file(dev, &dev_attr_uevent);
attrError: attrError:
device_platform_notify(dev, KOBJ_REMOVE);
platform_error:
kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_uevent(&dev->kobj, KOBJ_REMOVE);
glue_dir = get_glue_dir(dev); glue_dir = get_glue_dir(dev);
kobject_del(&dev->kobj); kobject_del(&dev->kobj);
...@@ -2077,14 +2101,10 @@ void device_del(struct device *dev) ...@@ -2077,14 +2101,10 @@ void device_del(struct device *dev)
bus_remove_device(dev); bus_remove_device(dev);
device_pm_remove(dev); device_pm_remove(dev);
driver_deferred_probe_del(dev); driver_deferred_probe_del(dev);
device_platform_notify(dev, KOBJ_REMOVE);
device_remove_properties(dev); device_remove_properties(dev);
device_links_purge(dev); device_links_purge(dev);
/* Notify the platform of the removal, in case they
* need to do anything...
*/
if (platform_notify_remove)
platform_notify_remove(dev);
if (dev->bus) if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier, blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_REMOVED_DEVICE, dev); BUS_NOTIFY_REMOVED_DEVICE, dev);
......
...@@ -448,7 +448,6 @@ void platform_device_del(struct platform_device *pdev) ...@@ -448,7 +448,6 @@ void platform_device_del(struct platform_device *pdev)
int i; int i;
if (pdev) { if (pdev) {
device_remove_properties(&pdev->dev);
device_del(&pdev->dev); device_del(&pdev->dev);
if (pdev->id_auto) { if (pdev->id_auto) {
......
This diff is collapsed.
This diff is collapsed.
...@@ -1331,4 +1331,14 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) ...@@ -1331,4 +1331,14 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
} }
#endif #endif
#ifdef CONFIG_ACPI
extern int acpi_platform_notify(struct device *dev, enum kobject_action action);
#else
static inline int
acpi_platform_notify(struct device *dev, enum kobject_action action)
{
return 0;
}
#endif
#endif /*_LINUX_ACPI_H*/ #endif /*_LINUX_ACPI_H*/
...@@ -311,4 +311,16 @@ fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port, ...@@ -311,4 +311,16 @@ fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port,
int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint); struct fwnode_endpoint *endpoint);
/* -------------------------------------------------------------------------- */
/* Software fwnode support - when HW description is incomplete or missing */
bool is_software_node(const struct fwnode_handle *fwnode);
int software_node_notify(struct device *dev, unsigned long action);
struct fwnode_handle *
fwnode_create_software_node(const struct property_entry *properties,
const struct fwnode_handle *parent);
void fwnode_remove_software_node(struct fwnode_handle *fwnode);
#endif /* _LINUX_PROPERTY_H_ */ #endif /* _LINUX_PROPERTY_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment