]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'devprop-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jul 2017 22:23:45 +0000 (15:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jul 2017 22:23:45 +0000 (15:23 -0700)
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()

1  2 
drivers/acpi/device_pm.c
drivers/acpi/internal.h
drivers/acpi/scan.c
drivers/of/property.c
include/linux/acpi.h
include/linux/of.h

diff --combined drivers/acpi/device_pm.c
index 28938b5a334e1297cfe230a8290b5cfb38a7f9e9,e565ed329f11db0307ba47cb19d0f25d9a936b37..2ed6935d4483bb0139e1ed9cc4cf27854c328c0d
@@@ -24,7 -24,6 +24,7 @@@
  #include <linux/pm_qos.h>
  #include <linux/pm_domain.h>
  #include <linux/pm_runtime.h>
 +#include <linux/suspend.h>
  
  #include "internal.h"
  
@@@ -262,8 -261,10 +262,10 @@@ int acpi_bus_init_power(struct acpi_dev
                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)
@@@ -386,12 -387,6 +388,12 @@@ EXPORT_SYMBOL(acpi_bus_power_manageable
  #ifdef CONFIG_PM
  static DEFINE_MUTEX(acpi_pm_notifier_lock);
  
 +void acpi_pm_wakeup_event(struct device *dev)
 +{
 +      pm_wakeup_dev_event(dev, 0, acpi_s2idle_wakeup());
 +}
 +EXPORT_SYMBOL_GPL(acpi_pm_wakeup_event);
 +
  static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
  {
        struct acpi_device *adev;
        mutex_lock(&acpi_pm_notifier_lock);
  
        if (adev->wakeup.flags.notifier_present) {
 -              __pm_wakeup_event(adev->wakeup.ws, 0);
 -              if (adev->wakeup.context.work.func)
 -                      queue_pm_work(&adev->wakeup.context.work);
 +              pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup());
 +              if (adev->wakeup.context.func)
 +                      adev->wakeup.context.func(&adev->wakeup.context);
        }
  
        mutex_unlock(&acpi_pm_notifier_lock);
   * acpi_add_pm_notifier - Register PM notify handler for given ACPI device.
   * @adev: ACPI device to add the notify handler for.
   * @dev: Device to generate a wakeup event for while handling the notification.
 - * @work_func: Work function to execute when handling the notification.
 + * @func: Work function to execute when handling the notification.
   *
   * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
   * PM wakeup events.  For example, wakeup events may be generated for bridges
   * bridge itself doesn't have a wakeup GPE associated with it.
   */
  acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
 -                               void (*work_func)(struct work_struct *work))
 +                      void (*func)(struct acpi_device_wakeup_context *context))
  {
        acpi_status status = AE_ALREADY_EXISTS;
  
 -      if (!dev && !work_func)
 +      if (!dev && !func)
                return AE_BAD_PARAMETER;
  
        mutex_lock(&acpi_pm_notifier_lock);
  
        adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev));
        adev->wakeup.context.dev = dev;
 -      if (work_func)
 -              INIT_WORK(&adev->wakeup.context.work, work_func);
 +      adev->wakeup.context.func = func;
  
        status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY,
                                             acpi_pm_notify_handler, NULL);
@@@ -475,7 -471,10 +477,7 @@@ acpi_status acpi_remove_pm_notifier(str
        if (ACPI_FAILURE(status))
                goto out;
  
 -      if (adev->wakeup.context.work.func) {
 -              cancel_work_sync(&adev->wakeup.context.work);
 -              adev->wakeup.context.work.func = NULL;
 -      }
 +      adev->wakeup.context.func = NULL;
        adev->wakeup.context.dev = NULL;
        wakeup_source_unregister(adev->wakeup.ws);
  
@@@ -496,13 -495,6 +498,13 @@@ bool acpi_bus_can_wakeup(acpi_handle ha
  }
  EXPORT_SYMBOL(acpi_bus_can_wakeup);
  
 +bool acpi_pm_device_can_wakeup(struct device *dev)
 +{
 +      struct acpi_device *adev = ACPI_COMPANION(dev);
 +
 +      return adev ? acpi_device_can_wakeup(adev) : false;
 +}
 +
  /**
   * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
   * @dev: Device whose preferred target power state to return.
@@@ -668,15 -660,16 +670,15 @@@ EXPORT_SYMBOL(acpi_pm_device_sleep_stat
  
  /**
   * acpi_pm_notify_work_func - ACPI devices wakeup notification work function.
 - * @work: Work item to handle.
 + * @context: Device wakeup context.
   */
 -static void acpi_pm_notify_work_func(struct work_struct *work)
 +static void acpi_pm_notify_work_func(struct acpi_device_wakeup_context *context)
  {
 -      struct device *dev;
 +      struct device *dev = context->dev;
  
 -      dev = container_of(work, struct acpi_device_wakeup_context, work)->dev;
        if (dev) {
                pm_wakeup_event(dev, 0);
 -              pm_runtime_resume(dev);
 +              pm_request_resume(dev);
        }
  }
  
@@@ -702,53 -695,80 +704,53 @@@ static int acpi_device_wakeup(struct ac
                acpi_status res;
                int error;
  
 +              if (adev->wakeup.flags.enabled)
 +                      return 0;
 +
                error = acpi_enable_wakeup_device_power(adev, target_state);
                if (error)
                        return error;
  
 -              if (adev->wakeup.flags.enabled)
 -                      return 0;
 -
                res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
 -              if (ACPI_SUCCESS(res)) {
 -                      adev->wakeup.flags.enabled = 1;
 -              } else {
 +              if (ACPI_FAILURE(res)) {
                        acpi_disable_wakeup_device_power(adev);
                        return -EIO;
                }
 -      } else {
 -              if (adev->wakeup.flags.enabled) {
 -                      acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
 -                      adev->wakeup.flags.enabled = 0;
 -              }
 +              adev->wakeup.flags.enabled = 1;
 +      } else if (adev->wakeup.flags.enabled) {
 +              acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
                acpi_disable_wakeup_device_power(adev);
 +              adev->wakeup.flags.enabled = 0;
        }
        return 0;
  }
  
  /**
 - * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
 - * @dev: Device to enable/disable the platform to wake up.
 + * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device.
 + * @dev: Device to enable/disable to generate wakeup events.
   * @enable: Whether to enable or disable the wakeup functionality.
   */
 -int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
 -{
 -      struct acpi_device *adev;
 -
 -      if (!device_run_wake(phys_dev))
 -              return -EINVAL;
 -
 -      adev = ACPI_COMPANION(phys_dev);
 -      if (!adev) {
 -              dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
 -              return -ENODEV;
 -      }
 -
 -      return acpi_device_wakeup(adev, ACPI_STATE_S0, enable);
 -}
 -EXPORT_SYMBOL(acpi_pm_device_run_wake);
 -
 -#ifdef CONFIG_PM_SLEEP
 -/**
 - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
 - * @dev: Device to enable/desible to wake up the system from sleep states.
 - * @enable: Whether to enable or disable @dev to wake up the system.
 - */
 -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 +int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
  {
        struct acpi_device *adev;
        int error;
  
 -      if (!device_can_wakeup(dev))
 -              return -EINVAL;
 -
        adev = ACPI_COMPANION(dev);
        if (!adev) {
                dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
                return -ENODEV;
        }
  
 +      if (!acpi_device_can_wakeup(adev))
 +              return -EINVAL;
 +
        error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
        if (!error)
 -              dev_info(dev, "System wakeup %s by ACPI\n",
 -                              enable ? "enabled" : "disabled");
 +              dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
  
        return error;
  }
 -#endif /* CONFIG_PM_SLEEP */
 +EXPORT_SYMBOL(acpi_pm_set_device_wakeup);
  
  /**
   * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
diff --combined drivers/acpi/internal.h
index be79f7db1850c10168dff094bb2e1030808bd257,73002402c461c0b26b98d1ed97fc058bd9c71c27..9531d3276f652a14e5eb39d9e0cb8a0325353f72
@@@ -111,7 -111,7 +111,7 @@@ int acpi_device_setup_files(struct acpi
  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);
@@@ -198,12 -198,8 +198,12 @@@ void acpi_ec_remove_query_handler(struc
                                    Suspend/Resume
    -------------------------------------------------------------------------- */
  #ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT
 +extern bool acpi_s2idle_wakeup(void);
 +extern bool acpi_sleep_no_ec_events(void);
  extern int acpi_sleep_init(void);
  #else
 +static inline bool acpi_s2idle_wakeup(void) { return false; }
 +static inline bool acpi_sleep_no_ec_events(void) { return true; }
  static inline int acpi_sleep_init(void) { return -ENXIO; }
  #endif
  
diff --combined drivers/acpi/scan.c
index 59ebbd5f7b835b1aa5d119930c65f34b57a0dedc,bc2a525c495f792aa78d8051d4b1db3db8abf858..33897298f03e3ed680272ba6f4109077d434a0d8
@@@ -404,6 -404,10 +404,6 @@@ void acpi_device_hotplug(struct acpi_de
                error = dock_notify(adev, src);
        } else if (adev->flags.hotplug_notify) {
                error = acpi_generic_hotplug_event(adev, src);
 -              if (error == -EPERM) {
 -                      ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
 -                      goto err_out;
 -              }
        } else {
                int (*notify)(struct acpi_device *, u32);
  
                else
                        goto out;
        }
 -      if (!error)
 +      switch (error) {
 +      case 0:
                ost_code = ACPI_OST_SC_SUCCESS;
 +              break;
 +      case -EPERM:
 +              ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
 +              break;
 +      case -EBUSY:
 +              ost_code = ACPI_OST_SC_DEVICE_BUSY;
 +              break;
 +      default:
 +              ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
 +              break;
 +      }
  
   err_out:
        acpi_evaluate_ost(adev->handle, src, ost_code, NULL);
@@@ -843,7 -835,7 +843,7 @@@ static int acpi_bus_extract_wakeup_devi
        return err;
  }
  
 -static void acpi_wakeup_gpe_init(struct acpi_device *device)
 +static bool acpi_wakeup_gpe_init(struct acpi_device *device)
  {
        static const struct acpi_device_id button_device_ids[] = {
                {"PNP0C0C", 0},
        };
        struct acpi_device_wakeup *wakeup = &device->wakeup;
        acpi_status status;
 -      acpi_event_status event_status;
  
        wakeup->flags.notifier_present = 0;
  
        /* Power button, Lid switch always enable wakeup */
        if (!acpi_match_device_ids(device, button_device_ids)) {
 -              wakeup->flags.run_wake = 1;
                if (!acpi_match_device_ids(device, &button_device_ids[1])) {
                        /* Do not use Lid/sleep button for S5 wakeup */
                        if (wakeup->sleep_state == ACPI_STATE_S5)
                }
                acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
                device_set_wakeup_capable(&device->dev, true);
 -              return;
 +              return true;
        }
  
 -      acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
 -                              wakeup->gpe_number);
 -      status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
 -                                   &event_status);
 -      if (ACPI_FAILURE(status))
 -              return;
 -
 -      wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER);
 +      status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
 +                                       wakeup->gpe_number);
 +      return ACPI_SUCCESS(status);
  }
  
  static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
                return;
        }
  
 -      device->wakeup.flags.valid = 1;
 +      device->wakeup.flags.valid = acpi_wakeup_gpe_init(device);
        device->wakeup.prepare_count = 0;
 -      acpi_wakeup_gpe_init(device);
 -      /* Call _PSW/_DSW object to disable its ability to wake the sleeping
 +      /*
 +       * Call _PSW/_DSW object to disable its ability to wake the sleeping
         * system for the ACPI device with the _PRW object.
         * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
         * So it is necessary to call _DSW object first. Only when it is not
@@@ -1429,37 -1428,6 +1429,37 @@@ static void acpi_init_coherency(struct 
        adev->flags.coherent_dma = cca;
  }
  
 +static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
 +{
 +      bool *is_spi_i2c_slave_p = data;
 +
 +      if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
 +              return 1;
 +
 +      /*
 +       * devices that are connected to UART still need to be enumerated to
 +       * platform bus
 +       */
 +      if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
 +              *is_spi_i2c_slave_p = true;
 +
 +       /* no need to do more checking */
 +      return -1;
 +}
 +
 +static bool acpi_is_spi_i2c_slave(struct acpi_device *device)
 +{
 +      struct list_head resource_list;
 +      bool is_spi_i2c_slave = false;
 +
 +      INIT_LIST_HEAD(&resource_list);
 +      acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
 +                             &is_spi_i2c_slave);
 +      acpi_dev_free_resource_list(&resource_list);
 +
 +      return is_spi_i2c_slave;
 +}
 +
  void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
                             int type, unsigned long long sta)
  {
        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);
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
        device->flags.initialized = true;
 +      device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device);
        acpi_device_clear_enumerated(device);
        device_initialize(&device->dev);
        dev_set_uevent_suppress(&device->dev, true);
@@@ -1600,13 -1568,9 +1601,9 @@@ static int acpi_bus_type_and_status(acp
        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,
@@@ -1760,13 -1724,38 +1757,13 @@@ static acpi_status acpi_bus_check_add(a
        return AE_OK;
  }
  
 -static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data)
 -{
 -      bool *is_spi_i2c_slave_p = data;
 -
 -      if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
 -              return 1;
 -
 -      /*
 -       * devices that are connected to UART still need to be enumerated to
 -       * platform bus
 -       */
 -      if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
 -              *is_spi_i2c_slave_p = true;
 -
 -       /* no need to do more checking */
 -      return -1;
 -}
 -
  static void acpi_default_enumeration(struct acpi_device *device)
  {
 -      struct list_head resource_list;
 -      bool is_spi_i2c_slave = false;
 -
        /*
         * Do not enumerate SPI/I2C slaves as they will be enumerated by their
         * respective parents.
         */
 -      INIT_LIST_HEAD(&resource_list);
 -      acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave,
 -                             &is_spi_i2c_slave);
 -      acpi_dev_free_resource_list(&resource_list);
 -      if (!is_spi_i2c_slave) {
 +      if (!device->flags.spi_i2c_slave) {
                acpi_create_platform_device(device, NULL);
                acpi_device_set_enumerated(device);
        } else {
@@@ -1839,6 -1828,7 +1836,7 @@@ static void acpi_bus_attach(struct acpi
        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;
                return;
  
        device->flags.match_driver = true;
 -      if (ret > 0) {
 +      if (ret > 0 && !device->flags.spi_i2c_slave) {
                acpi_device_set_enumerated(device);
                goto ok;
        }
        if (ret < 0)
                return;
  
 -      if (device->pnp.type.platform_id)
 -              acpi_default_enumeration(device);
 -      else
 +      if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave)
                acpi_device_set_enumerated(device);
 +      else
 +              acpi_default_enumeration(device);
  
   ok:
        list_for_each_entry(child, &device->children, node)
diff --combined drivers/of/property.c
index 07c7c36c5ca8a0d23eafbbc65909242b52585fe8,c96389b7c6b32c64ee4a16270c8c87d9fadb1883..eda50b4be9349d26c5600a19426cdc1d7f7fe92b
@@@ -683,41 -683,6 +683,41 @@@ struct device_node *of_graph_get_endpoi
  }
  EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
  
 +/**
 + * of_graph_get_remote_endpoint() - get remote endpoint node
 + * @node: pointer to a local endpoint device_node
 + *
 + * Return: Remote endpoint node associated with remote endpoint node linked
 + *       to @node. Use of_node_put() on it when done.
 + */
 +struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
 +{
 +      /* Get remote endpoint node. */
 +      return of_parse_phandle(node, "remote-endpoint", 0);
 +}
 +EXPORT_SYMBOL(of_graph_get_remote_endpoint);
 +
 +/**
 + * of_graph_get_port_parent() - get port's parent node
 + * @node: pointer to a local endpoint device_node
 + *
 + * Return: device node associated with endpoint node linked
 + *       to @node. Use of_node_put() on it when done.
 + */
 +struct device_node *of_graph_get_port_parent(struct device_node *node)
 +{
 +      unsigned int depth;
 +
 +      /* Walk 3 levels up only if there is 'ports' node. */
 +      for (depth = 3; depth && node; depth--) {
 +              node = of_get_next_parent(node);
 +              if (depth == 2 && of_node_cmp(node->name, "ports"))
 +                      break;
 +      }
 +      return node;
 +}
 +EXPORT_SYMBOL(of_graph_get_port_parent);
 +
  /**
   * of_graph_get_remote_port_parent() - get remote port's parent node
   * @node: pointer to a local endpoint device_node
@@@ -729,11 -694,18 +729,11 @@@ struct device_node *of_graph_get_remote
                               const struct device_node *node)
  {
        struct device_node *np;
 -      unsigned int depth;
  
        /* Get remote endpoint node. */
 -      np = of_parse_phandle(node, "remote-endpoint", 0);
 +      np = of_graph_get_remote_endpoint(node);
  
 -      /* Walk 3 levels up only if there is 'ports' node. */
 -      for (depth = 3; depth && np; depth--) {
 -              np = of_get_next_parent(np);
 -              if (depth == 2 && of_node_cmp(np->name, "ports"))
 -                      break;
 -      }
 -      return np;
 +      return of_graph_get_port_parent(np);
  }
  EXPORT_SYMBOL(of_graph_get_remote_port_parent);
  
@@@ -749,25 -721,13 +749,25 @@@ struct device_node *of_graph_get_remote
        struct device_node *np;
  
        /* Get remote endpoint node. */
 -      np = of_parse_phandle(node, "remote-endpoint", 0);
 +      np = of_graph_get_remote_endpoint(node);
        if (!np)
                return NULL;
        return of_get_next_parent(np);
  }
  EXPORT_SYMBOL(of_graph_get_remote_port);
  
 +int of_graph_get_endpoint_count(const struct device_node *np)
 +{
 +      struct device_node *endpoint;
 +      int num = 0;
 +
 +      for_each_endpoint_of_node(np, endpoint)
 +              num++;
 +
 +      return num;
 +}
 +EXPORT_SYMBOL(of_graph_get_endpoint_count);
 +
  /**
   * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
   * @node: pointer to parent device_node containing graph port/endpoint
@@@ -804,3 -764,151 +804,151 @@@ struct device_node *of_graph_get_remote
        return remote;
  }
  EXPORT_SYMBOL(of_graph_get_remote_node);
+ static void of_fwnode_get(struct fwnode_handle *fwnode)
+ {
+       of_node_get(to_of_node(fwnode));
+ }
+ static void of_fwnode_put(struct fwnode_handle *fwnode)
+ {
+       of_node_put(to_of_node(fwnode));
+ }
+ static bool of_fwnode_device_is_available(struct fwnode_handle *fwnode)
+ {
+       return of_device_is_available(to_of_node(fwnode));
+ }
+ static bool of_fwnode_property_present(struct fwnode_handle *fwnode,
+                                      const char *propname)
+ {
+       return of_property_read_bool(to_of_node(fwnode), propname);
+ }
+ static int of_fwnode_property_read_int_array(struct fwnode_handle *fwnode,
+                                            const char *propname,
+                                            unsigned int elem_size, void *val,
+                                            size_t nval)
+ {
+       struct device_node *node = to_of_node(fwnode);
+       if (!val)
+               return of_property_count_elems_of_size(node, propname,
+                                                      elem_size);
+       switch (elem_size) {
+       case sizeof(u8):
+               return of_property_read_u8_array(node, propname, val, nval);
+       case sizeof(u16):
+               return of_property_read_u16_array(node, propname, val, nval);
+       case sizeof(u32):
+               return of_property_read_u32_array(node, propname, val, nval);
+       case sizeof(u64):
+               return of_property_read_u64_array(node, propname, val, nval);
+       }
+       return -ENXIO;
+ }
+ static int of_fwnode_property_read_string_array(struct fwnode_handle *fwnode,
+                                               const char *propname,
+                                               const char **val, size_t nval)
+ {
+       struct device_node *node = to_of_node(fwnode);
+       return val ?
+               of_property_read_string_array(node, propname, val, nval) :
+               of_property_count_strings(node, propname);
+ }
+ static struct fwnode_handle *of_fwnode_get_parent(struct fwnode_handle *fwnode)
+ {
+       return of_fwnode_handle(of_get_parent(to_of_node(fwnode)));
+ }
+ static struct fwnode_handle *
+ of_fwnode_get_next_child_node(struct fwnode_handle *fwnode,
+                             struct fwnode_handle *child)
+ {
+       return of_fwnode_handle(of_get_next_available_child(to_of_node(fwnode),
+                                                           to_of_node(child)));
+ }
+ static struct fwnode_handle *
+ of_fwnode_get_named_child_node(struct fwnode_handle *fwnode,
+                              const char *childname)
+ {
+       struct device_node *node = to_of_node(fwnode);
+       struct device_node *child;
+       for_each_available_child_of_node(node, child)
+               if (!of_node_cmp(child->name, childname))
+                       return of_fwnode_handle(child);
+       return NULL;
+ }
+ static struct fwnode_handle *
+ of_fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
+                                 struct fwnode_handle *prev)
+ {
+       return of_fwnode_handle(of_graph_get_next_endpoint(to_of_node(fwnode),
+                                                          to_of_node(prev)));
+ }
+ static struct fwnode_handle *
+ of_fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
+ {
+       return of_fwnode_handle(of_parse_phandle(to_of_node(fwnode),
+                                                "remote-endpoint", 0));
+ }
+ static struct fwnode_handle *
+ of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode)
+ {
+       struct device_node *np;
+       /* Get the parent of the port */
+       np = of_get_next_parent(to_of_node(fwnode));
+       if (!np)
+               return NULL;
+       /* Is this the "ports" node? If not, it's the port parent. */
+       if (of_node_cmp(np->name, "ports"))
+               return of_fwnode_handle(np);
+       return of_fwnode_handle(of_get_next_parent(np));
+ }
+ static int of_fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
+                                         struct fwnode_endpoint *endpoint)
+ {
+       struct device_node *node = to_of_node(fwnode);
+       struct device_node *port_node = of_get_parent(node);
+       endpoint->local_fwnode = fwnode;
+       of_property_read_u32(port_node, "reg", &endpoint->port);
+       of_property_read_u32(node, "reg", &endpoint->id);
+       of_node_put(port_node);
+       return 0;
+ }
+ const struct fwnode_operations of_fwnode_ops = {
+       .get = of_fwnode_get,
+       .put = of_fwnode_put,
+       .device_is_available = of_fwnode_device_is_available,
+       .property_present = of_fwnode_property_present,
+       .property_read_int_array = of_fwnode_property_read_int_array,
+       .property_read_string_array = of_fwnode_property_read_string_array,
+       .get_parent = of_fwnode_get_parent,
+       .get_next_child_node = of_fwnode_get_next_child_node,
+       .get_named_child_node = of_fwnode_get_named_child_node,
+       .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
+       .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
+       .graph_get_port_parent = of_fwnode_graph_get_port_parent,
+       .graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
+ };
diff --combined include/linux/acpi.h
index 99f96df83dd8db2b09bad8735b29d2900f824e44,b8f23c521b6732432c390290c85c5df1ef410dbf..c749eef1daa1557910ec81c5f296dc907f5ccab2
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/resource_ext.h>
  #include <linux/device.h>
  #include <linux/property.h>
 +#include <linux/uuid.h>
  
  #ifndef _LINUX
  #define _LINUX
@@@ -57,6 -56,9 +57,9 @@@ static inline acpi_handle acpi_device_h
        acpi_fwnode_handle(adev) : NULL)
  #define ACPI_HANDLE(dev)              acpi_device_handle(ACPI_COMPANION(dev))
  
+ extern const struct fwnode_operations acpi_fwnode_ops;
  static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
  {
        struct fwnode_handle *fwnode;
@@@ -66,6 -68,7 +69,7 @@@
                return NULL;
  
        fwnode->type = FWNODE_ACPI_STATIC;
+       fwnode->ops = &acpi_fwnode_ops;
  
        return fwnode;
  }
@@@ -458,6 -461,7 +462,6 @@@ struct acpi_osc_context 
        struct acpi_buffer ret;         /* free by caller if success */
  };
  
 -acpi_status acpi_str_to_uuid(char *str, u8 *uuid);
  acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
  
  /* Indexes into _OSC Capabilities Buffer (DWORDs 2 & 3 are device-specific) */
@@@ -741,7 -745,7 +745,7 @@@ static inline bool acpi_driver_match_de
  }
  
  static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
 -                                                 const u8 *uuid,
 +                                                 const guid_t *guid,
                                                   int rev, int func,
                                                   union acpi_object *argv4)
  {
@@@ -964,8 -968,6 +968,8 @@@ int devm_acpi_dev_add_driver_gpios(stru
                                   const struct acpi_gpio_mapping *gpios);
  void devm_acpi_dev_remove_driver_gpios(struct device *dev);
  
 +bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
 +                              struct acpi_resource_gpio **agpio);
  int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
  #else
  static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
@@@ -982,11 -984,6 +986,11 @@@ static inline int devm_acpi_dev_add_dri
  }
  static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {}
  
 +static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
 +                                            struct acpi_resource_gpio **agpio)
 +{
 +      return false;
 +}
  static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
  {
        return -ENXIO;
diff --combined include/linux/of.h
index fa089a2789a017f88adc95a49cafa18d161d2bc2,cdbfa88c32cfa91c9214352ad9f1268c6cbbce47..4a8a70916237ec1f9d1583d6cd69bf86f48102cc
@@@ -100,10 -100,12 +100,12 @@@ struct of_reconfig_data 
  
  /* initialize a node */
  extern struct kobj_type of_node_ktype;
+ extern const struct fwnode_operations of_fwnode_ops;
  static inline void of_node_init(struct device_node *node)
  {
        kobject_init(&node->kobj, &of_node_ktype);
        node->fwnode.type = FWNODE_OF;
+       node->fwnode.ops = &of_fwnode_ops;
  }
  
  /* true when node is initialized */
@@@ -637,12 -639,6 +639,12 @@@ static inline int of_device_is_compatib
        return 0;
  }
  
 +static inline  int of_device_compatible_match(struct device_node *device,
 +                                            const char *const *compat)
 +{
 +      return 0;
 +}
 +
  static inline bool of_device_is_available(const struct device_node *device)
  {
        return false;