drivers core: Prepare support for multiple platform notifications
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>
Fri, 9 Nov 2018 14:21:34 +0000 (17:21 +0300)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Nov 2018 17:19:11 +0000 (18:19 +0100)
Since it should be possible to support several hardware
description models at the same time (at least in theory),
for example ACPI and devicetree on a running system, the
platform notifications need to be handled differently.

For now a single "platform_notify" callback function was
used to notify the underlying base system which is in charge
of the hardware description when a new device entry was
added to the system, but that callback is available to only
a single base system at the time. This will add a function
device_platform_notify() and replace all direct
platform_notify() calls with it.

device_platform_notify() will first simply call the
platform_notify() callback, so this commit has no functional
affect, however, the idea is that individual base systems
will put their direct notification calls there instead of
using the platform_notify function pointer.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/core.c

index 04bbcd7..3972ef3 100644 (file)
@@ -728,6 +728,16 @@ static inline int device_is_not_partition(struct device *dev)
 }
 #endif
 
+static int
+device_platform_notify(struct device *dev, enum kobject_action action)
+{
+       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: struct device to get the name of
@@ -1883,8 +1893,9 @@ int device_add(struct device *dev)
        }
 
        /* notify platform of device entry */
-       if (platform_notify)
-               platform_notify(dev);
+       error = device_platform_notify(dev, KOBJ_ADD);
+       if (error)
+               goto platform_error;
 
        error = device_create_file(dev, &dev_attr_uevent);
        if (error)
@@ -1960,6 +1971,8 @@ done:
  SymlinkError:
        device_remove_file(dev, &dev_attr_uevent);
  attrError:
+       device_platform_notify(dev, KOBJ_REMOVE);
+platform_error:
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        glue_dir = get_glue_dir(dev);
        kobject_del(&dev->kobj);
@@ -2077,14 +2090,10 @@ void device_del(struct device *dev)
        bus_remove_device(dev);
        device_pm_remove(dev);
        driver_deferred_probe_del(dev);
+       device_platform_notify(dev, KOBJ_REMOVE);
        device_remove_properties(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)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_REMOVED_DEVICE, dev);