Merge tag 'tegra-for-4.8-i2c' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra...
authorWolfram Sang <wsa@the-dreams.de>
Tue, 11 Oct 2016 21:26:13 +0000 (23:26 +0200)
committerWolfram Sang <wsa@the-dreams.de>
Tue, 11 Oct 2016 21:37:26 +0000 (23:37 +0200)
[wsa: fell through the cracks, applied to 4.9 now]

Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
i2c: 'i2c-bus' node support for v4.8-rc1

This includes the device tree binding and I2C core changes to support
the i2c-bus subnode that I2C masters can use to describe their slaves
in a separate namespace and therefore avoid clashing with potentially
other subnodes.

1  2 
Documentation/devicetree/bindings/i2c/i2c.txt
drivers/i2c/i2c-core.c

@@@ -32,6 -32,14 +32,14 @@@ wants to support one of the below featu
  - clock-frequency
        frequency of bus clock in Hz.
  
+ - i2c-bus
+       For I2C adapters that have child nodes that are a mixture of both I2C
+       devices and non-I2C devices, the 'i2c-bus' subnode can be used for
+       populating I2C devices. If the 'i2c-bus' subnode is present, only
+       subnodes of this will be considered as I2C slaves. The properties,
+       '#address-cells' and '#size-cells' must be defined under this subnode
+       if present.
  - i2c-scl-falling-time-ns
        Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
        specification.
  - wakeup-source
        device can be used as a wakeup source.
  
 +- reg
 +      I2C slave addresses
 +
 +- reg-names
 +      Names of map programmable addresses.
 +      It can contain any map needing another address than default one.
 +
  Binding may contain optional "interrupts" property, describing interrupts
  used by the device. I2C core will assign "irq" interrupt (or the very first
  interrupt if not using interrupt names) as primary interrupt for the slave.
diff --combined drivers/i2c/i2c-core.c
@@@ -27,8 -27,6 +27,8 @@@
     I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com>
   */
  
 +#define pr_fmt(fmt) "i2c-core: " fmt
 +
  #include <dt-bindings/i2c/i2c.h>
  #include <asm/uaccess.h>
  #include <linux/acpi.h>
@@@ -88,7 -86,7 +88,7 @@@ void i2c_transfer_trace_unreg(void
  }
  
  #if defined(CONFIG_ACPI)
 -struct acpi_i2c_handler_data {
 +struct i2c_acpi_handler_data {
        struct acpi_connection_info info;
        struct i2c_adapter *adapter;
  };
@@@ -103,20 -101,18 +103,20 @@@ struct gsb_buffer 
        };
  } __packed;
  
 -struct acpi_i2c_lookup {
 +struct i2c_acpi_lookup {
        struct i2c_board_info *info;
        acpi_handle adapter_handle;
        acpi_handle device_handle;
 +      acpi_handle search_handle;
 +      u32 speed;
 +      u32 min_speed;
  };
  
 -static int acpi_i2c_find_address(struct acpi_resource *ares, void *data)
 +static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
  {
 -      struct acpi_i2c_lookup *lookup = data;
 +      struct i2c_acpi_lookup *lookup = data;
        struct i2c_board_info *info = lookup->info;
        struct acpi_resource_i2c_serialbus *sb;
 -      acpi_handle adapter_handle;
        acpi_status status;
  
        if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
        if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
                return 1;
  
 -      /*
 -       * Extract the ResourceSource and make sure that the handle matches
 -       * with the I2C adapter handle.
 -       */
        status = acpi_get_handle(lookup->device_handle,
                                 sb->resource_source.string_ptr,
 -                               &adapter_handle);
 -      if (ACPI_SUCCESS(status) && adapter_handle == lookup->adapter_handle) {
 -              info->addr = sb->slave_address;
 -              if (sb->access_mode == ACPI_I2C_10BIT_MODE)
 -                      info->flags |= I2C_CLIENT_TEN;
 -      }
 +                               &lookup->adapter_handle);
 +      if (!ACPI_SUCCESS(status))
 +              return 1;
 +
 +      info->addr = sb->slave_address;
 +      lookup->speed = sb->connection_speed;
 +      if (sb->access_mode == ACPI_I2C_10BIT_MODE)
 +              info->flags |= I2C_CLIENT_TEN;
  
        return 1;
  }
  
 -static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 -                                     void *data, void **return_value)
 +static int i2c_acpi_do_lookup(struct acpi_device *adev,
 +                            struct i2c_acpi_lookup *lookup)
  {
 -      struct i2c_adapter *adapter = data;
 +      struct i2c_board_info *info = lookup->info;
        struct list_head resource_list;
 -      struct acpi_i2c_lookup lookup;
 -      struct resource_entry *entry;
 -      struct i2c_board_info info;
 -      struct acpi_device *adev;
        int ret;
  
 -      if (acpi_bus_get_device(handle, &adev))
 -              return AE_OK;
 -      if (acpi_bus_get_status(adev) || !adev->status.present)
 -              return AE_OK;
 -
 -      memset(&info, 0, sizeof(info));
 -      info.fwnode = acpi_fwnode_handle(adev);
 +      if (acpi_bus_get_status(adev) || !adev->status.present ||
 +          acpi_device_enumerated(adev))
 +              return -EINVAL;
  
 -      memset(&lookup, 0, sizeof(lookup));
 -      lookup.adapter_handle = ACPI_HANDLE(&adapter->dev);
 -      lookup.device_handle = handle;
 -      lookup.info = &info;
 +      memset(info, 0, sizeof(*info));
 +      lookup->device_handle = acpi_device_handle(adev);
  
 -      /*
 -       * Look up for I2cSerialBus resource with ResourceSource that
 -       * matches with this adapter.
 -       */
 +      /* Look up for I2cSerialBus resource */
        INIT_LIST_HEAD(&resource_list);
        ret = acpi_dev_get_resources(adev, &resource_list,
 -                                   acpi_i2c_find_address, &lookup);
 +                                   i2c_acpi_fill_info, lookup);
        acpi_dev_free_resource_list(&resource_list);
  
 -      if (ret < 0 || !info.addr)
 -              return AE_OK;
 +      if (ret < 0 || !info->addr)
 +              return -EINVAL;
 +
 +      return 0;
 +}
 +
 +static int i2c_acpi_get_info(struct acpi_device *adev,
 +                           struct i2c_board_info *info,
 +                           struct i2c_adapter *adapter,
 +                           acpi_handle *adapter_handle)
 +{
 +      struct list_head resource_list;
 +      struct resource_entry *entry;
 +      struct i2c_acpi_lookup lookup;
 +      int ret;
 +
 +      memset(&lookup, 0, sizeof(lookup));
 +      lookup.info = info;
 +
 +      ret = i2c_acpi_do_lookup(adev, &lookup);
 +      if (ret)
 +              return ret;
 +
 +      if (adapter) {
 +              /* The adapter must match the one in I2cSerialBus() connector */
 +              if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle)
 +                      return -ENODEV;
 +      } else {
 +              struct acpi_device *adapter_adev;
 +
 +              /* The adapter must be present */
 +              if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev))
 +                      return -ENODEV;
 +              if (acpi_bus_get_status(adapter_adev) ||
 +                  !adapter_adev->status.present)
 +                      return -ENODEV;
 +      }
 +
 +      info->fwnode = acpi_fwnode_handle(adev);
 +      if (adapter_handle)
 +              *adapter_handle = lookup.adapter_handle;
  
        /* Then fill IRQ number if any */
 +      INIT_LIST_HEAD(&resource_list);
        ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
        if (ret < 0)
 -              return AE_OK;
 +              return -EINVAL;
  
        resource_list_for_each_entry(entry, &resource_list) {
                if (resource_type(entry->res) == IORESOURCE_IRQ) {
 -                      info.irq = entry->res->start;
 +                      info->irq = entry->res->start;
                        break;
                }
        }
  
        acpi_dev_free_resource_list(&resource_list);
  
 +      strlcpy(info->type, dev_name(&adev->dev), sizeof(info->type));
 +
 +      return 0;
 +}
 +
 +static void i2c_acpi_register_device(struct i2c_adapter *adapter,
 +                                   struct acpi_device *adev,
 +                                   struct i2c_board_info *info)
 +{
        adev->power.flags.ignore_parent = true;
 -      strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
 -      if (!i2c_new_device(adapter, &info)) {
 +      acpi_device_set_enumerated(adev);
 +
 +      if (!i2c_new_device(adapter, info)) {
                adev->power.flags.ignore_parent = false;
                dev_err(&adapter->dev,
                        "failed to add I2C device %s from ACPI\n",
                        dev_name(&adev->dev));
        }
 +}
 +
 +static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
 +                                     void *data, void **return_value)
 +{
 +      struct i2c_adapter *adapter = data;
 +      struct acpi_device *adev;
 +      struct i2c_board_info info;
 +
 +      if (acpi_bus_get_device(handle, &adev))
 +              return AE_OK;
 +
 +      if (i2c_acpi_get_info(adev, &info, adapter, NULL))
 +              return AE_OK;
 +
 +      i2c_acpi_register_device(adapter, adev, &info);
  
        return AE_OK;
  }
  
 -#define ACPI_I2C_MAX_SCAN_DEPTH 32
 +#define I2C_ACPI_MAX_SCAN_DEPTH 32
  
  /**
 - * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
 + * i2c_acpi_register_devices - enumerate I2C slave devices behind adapter
   * @adap: pointer to adapter
   *
   * Enumerate all I2C slave devices behind this adapter by walking the ACPI
   * namespace. When a device is found it will be added to the Linux device
   * model and bound to the corresponding ACPI handle.
   */
 -static void acpi_i2c_register_devices(struct i2c_adapter *adap)
 +static void i2c_acpi_register_devices(struct i2c_adapter *adap)
  {
        acpi_status status;
  
                return;
  
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 -                                   ACPI_I2C_MAX_SCAN_DEPTH,
 -                                   acpi_i2c_add_device, NULL,
 +                                   I2C_ACPI_MAX_SCAN_DEPTH,
 +                                   i2c_acpi_add_device, NULL,
                                     adap, NULL);
        if (ACPI_FAILURE(status))
                dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
  }
  
 +static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
 +                                         void *data, void **return_value)
 +{
 +      struct i2c_acpi_lookup *lookup = data;
 +      struct acpi_device *adev;
 +
 +      if (acpi_bus_get_device(handle, &adev))
 +              return AE_OK;
 +
 +      if (i2c_acpi_do_lookup(adev, lookup))
 +              return AE_OK;
 +
 +      if (lookup->search_handle != lookup->adapter_handle)
 +              return AE_OK;
 +
 +      if (lookup->speed <= lookup->min_speed)
 +              lookup->min_speed = lookup->speed;
 +
 +      return AE_OK;
 +}
 +
 +/**
 + * i2c_acpi_find_bus_speed - find I2C bus speed from ACPI
 + * @dev: The device owning the bus
 + *
 + * Find the I2C bus speed by walking the ACPI namespace for all I2C slaves
 + * devices connected to this bus and use the speed of slowest device.
 + *
 + * Returns the speed in Hz or zero
 + */
 +u32 i2c_acpi_find_bus_speed(struct device *dev)
 +{
 +      struct i2c_acpi_lookup lookup;
 +      struct i2c_board_info dummy;
 +      acpi_status status;
 +
 +      if (!has_acpi_companion(dev))
 +              return 0;
 +
 +      memset(&lookup, 0, sizeof(lookup));
 +      lookup.search_handle = ACPI_HANDLE(dev);
 +      lookup.min_speed = UINT_MAX;
 +      lookup.info = &dummy;
 +
 +      status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 +                                   I2C_ACPI_MAX_SCAN_DEPTH,
 +                                   i2c_acpi_lookup_speed, NULL,
 +                                   &lookup, NULL);
 +
 +      if (ACPI_FAILURE(status)) {
 +              dev_warn(dev, "unable to find I2C bus speed from ACPI\n");
 +              return 0;
 +      }
 +
 +      return lookup.min_speed != UINT_MAX ? lookup.min_speed : 0;
 +}
 +EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
 +
 +static int i2c_acpi_match_adapter(struct device *dev, void *data)
 +{
 +      struct i2c_adapter *adapter = i2c_verify_adapter(dev);
 +
 +      if (!adapter)
 +              return 0;
 +
 +      return ACPI_HANDLE(dev) == (acpi_handle)data;
 +}
 +
 +static int i2c_acpi_match_device(struct device *dev, void *data)
 +{
 +      return ACPI_COMPANION(dev) == data;
 +}
 +
 +static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
 +{
 +      struct device *dev;
 +
 +      dev = bus_find_device(&i2c_bus_type, NULL, handle,
 +                            i2c_acpi_match_adapter);
 +      return dev ? i2c_verify_adapter(dev) : NULL;
 +}
 +
 +static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
 +{
 +      struct device *dev;
 +
 +      dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device);
 +      return dev ? i2c_verify_client(dev) : NULL;
 +}
 +
 +static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
 +                         void *arg)
 +{
 +      struct acpi_device *adev = arg;
 +      struct i2c_board_info info;
 +      acpi_handle adapter_handle;
 +      struct i2c_adapter *adapter;
 +      struct i2c_client *client;
 +
 +      switch (value) {
 +      case ACPI_RECONFIG_DEVICE_ADD:
 +              if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle))
 +                      break;
 +
 +              adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
 +              if (!adapter)
 +                      break;
 +
 +              i2c_acpi_register_device(adapter, adev, &info);
 +              break;
 +      case ACPI_RECONFIG_DEVICE_REMOVE:
 +              if (!acpi_device_enumerated(adev))
 +                      break;
 +
 +              client = i2c_acpi_find_client_by_adev(adev);
 +              if (!client)
 +                      break;
 +
 +              i2c_unregister_device(client);
 +              put_device(&client->dev);
 +              break;
 +      }
 +
 +      return NOTIFY_OK;
 +}
 +
 +static struct notifier_block i2c_acpi_notifier = {
 +      .notifier_call = i2c_acpi_notify,
 +};
  #else /* CONFIG_ACPI */
 -static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) { }
 +static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
 +extern struct notifier_block i2c_acpi_notifier;
  #endif /* CONFIG_ACPI */
  
  #ifdef CONFIG_ACPI_I2C_OPREGION
@@@ -476,12 -291,12 +476,12 @@@ static int acpi_gsb_i2c_write_bytes(str
  }
  
  static acpi_status
 -acpi_i2c_space_handler(u32 function, acpi_physical_address command,
 +i2c_acpi_space_handler(u32 function, acpi_physical_address command,
                        u32 bits, u64 *value64,
                        void *handler_context, void *region_context)
  {
        struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
 -      struct acpi_i2c_handler_data *data = handler_context;
 +      struct i2c_acpi_handler_data *data = handler_context;
        struct acpi_connection_info *info = &data->info;
        struct acpi_resource_i2c_serialbus *sb;
        struct i2c_adapter *adapter = data->adapter;
                break;
  
        default:
 -              pr_info("protocol(0x%02x) is not supported.\n", accessor_type);
 +              dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
 +                       accessor_type, client->addr);
                ret = AE_BAD_PARAMETER;
                goto err;
        }
  }
  
  
 -static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
 +static int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
  {
        acpi_handle handle;
 -      struct acpi_i2c_handler_data *data;
 +      struct i2c_acpi_handler_data *data;
        acpi_status status;
  
        if (!adapter->dev.parent)
        if (!handle)
                return -ENODEV;
  
 -      data = kzalloc(sizeof(struct acpi_i2c_handler_data),
 +      data = kzalloc(sizeof(struct i2c_acpi_handler_data),
                            GFP_KERNEL);
        if (!data)
                return -ENOMEM;
  
        status = acpi_install_address_space_handler(handle,
                                ACPI_ADR_SPACE_GSBUS,
 -                              &acpi_i2c_space_handler,
 +                              &i2c_acpi_space_handler,
                                NULL,
                                data);
        if (ACPI_FAILURE(status)) {
        return 0;
  }
  
 -static void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
 +static void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
  {
        acpi_handle handle;
 -      struct acpi_i2c_handler_data *data;
 +      struct i2c_acpi_handler_data *data;
        acpi_status status;
  
        if (!adapter->dev.parent)
  
        acpi_remove_address_space_handler(handle,
                                ACPI_ADR_SPACE_GSBUS,
 -                              &acpi_i2c_space_handler);
 +                              &i2c_acpi_space_handler);
  
        status = acpi_bus_get_private_data(handle, (void **)&data);
        if (ACPI_SUCCESS(status))
        acpi_bus_detach_private_data(handle);
  }
  #else /* CONFIG_ACPI_I2C_OPREGION */
 -static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
 +static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
  { }
  
 -static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
 +static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
  { return 0; }
  #endif /* CONFIG_ACPI_I2C_OPREGION */
  
@@@ -852,47 -666,6 +852,47 @@@ int i2c_recover_bus(struct i2c_adapter 
  }
  EXPORT_SYMBOL_GPL(i2c_recover_bus);
  
 +static void i2c_init_recovery(struct i2c_adapter *adap)
 +{
 +      struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
 +      char *err_str;
 +
 +      if (!bri)
 +              return;
 +
 +      if (!bri->recover_bus) {
 +              err_str = "no recover_bus() found";
 +              goto err;
 +      }
 +
 +      /* Generic GPIO recovery */
 +      if (bri->recover_bus == i2c_generic_gpio_recovery) {
 +              if (!gpio_is_valid(bri->scl_gpio)) {
 +                      err_str = "invalid SCL gpio";
 +                      goto err;
 +              }
 +
 +              if (gpio_is_valid(bri->sda_gpio))
 +                      bri->get_sda = get_sda_gpio_value;
 +              else
 +                      bri->get_sda = NULL;
 +
 +              bri->get_scl = get_scl_gpio_value;
 +              bri->set_scl = set_scl_gpio_value;
 +      } else if (bri->recover_bus == i2c_generic_scl_recovery) {
 +              /* Generic SCL recovery */
 +              if (!bri->set_scl || !bri->get_scl) {
 +                      err_str = "no {get|set}_scl() found";
 +                      goto err;
 +              }
 +      }
 +
 +      return;
 + err:
 +      dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
 +      adap->bus_recovery_info = NULL;
 +}
 +
  static int i2c_device_probe(struct device *dev)
  {
        struct i2c_client       *client = i2c_verify_client(dev);
                        status = 0;
  
                if (status)
 -                      dev_warn(&client->dev, "failed to set up wakeup irq");
 +                      dev_warn(&client->dev, "failed to set up wakeup irq\n");
        }
  
        dev_dbg(dev, "probe\n");
@@@ -1298,9 -1071,8 +1298,9 @@@ i2c_new_device(struct i2c_adapter *adap
        return client;
  
  out_err:
 -      dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
 -              "(%d)\n", client->name, client->addr, status);
 +      dev_err(&adap->dev,
 +              "Failed to register i2c client %s at 0x%02x (%d)\n",
 +              client->name, client->addr, status);
  out_err_silent:
        kfree(client);
        return NULL;
@@@ -1317,8 -1089,6 +1317,8 @@@ void i2c_unregister_device(struct i2c_c
  {
        if (client->dev.of_node)
                of_node_clear_flag(client->dev.of_node, OF_POPULATED);
 +      if (ACPI_COMPANION(&client->dev))
 +              acpi_device_clear_enumerated(ACPI_COMPANION(&client->dev));
        device_unregister(&client->dev);
  }
  EXPORT_SYMBOL_GPL(i2c_unregister_device);
@@@ -1375,47 -1145,6 +1375,47 @@@ struct i2c_client *i2c_new_dummy(struc
  }
  EXPORT_SYMBOL_GPL(i2c_new_dummy);
  
 +/**
 + * i2c_new_secondary_device - Helper to get the instantiated secondary address
 + * and create the associated device
 + * @client: Handle to the primary client
 + * @name: Handle to specify which secondary address to get
 + * @default_addr: Used as a fallback if no secondary address was specified
 + * Context: can sleep
 + *
 + * I2C clients can be composed of multiple I2C slaves bound together in a single
 + * component. The I2C client driver then binds to the master I2C slave and needs
 + * to create I2C dummy clients to communicate with all the other slaves.
 + *
 + * This function creates and returns an I2C dummy client whose I2C address is
 + * retrieved from the platform firmware based on the given slave name. If no
 + * address is specified by the firmware default_addr is used.
 + *
 + * On DT-based platforms the address is retrieved from the "reg" property entry
 + * cell whose "reg-names" value matches the slave name.
 + *
 + * This returns the new i2c client, which should be saved for later use with
 + * i2c_unregister_device(); or NULL to indicate an error.
 + */
 +struct i2c_client *i2c_new_secondary_device(struct i2c_client *client,
 +                                              const char *name,
 +                                              u16 default_addr)
 +{
 +      struct device_node *np = client->dev.of_node;
 +      u32 addr = default_addr;
 +      int i;
 +
 +      if (np) {
 +              i = of_property_match_string(np, "reg-names", name);
 +              if (i >= 0)
 +                      of_property_read_u32_index(np, "reg", i, &addr);
 +      }
 +
 +      dev_dbg(&client->adapter->dev, "Address for %s : 0x%x\n", name, addr);
 +      return i2c_new_dummy(client->adapter, addr);
 +}
 +EXPORT_SYMBOL_GPL(i2c_new_secondary_device);
 +
  /* ------------------------------------------------------------------------- */
  
  /* I2C bus adapters -- one roots each I2C or SMBUS segment */
@@@ -1426,19 -1155,21 +1426,19 @@@ static void i2c_adapter_dev_release(str
        complete(&adap->dev_released);
  }
  
 -/*
 - * This function is only needed for mutex_lock_nested, so it is never
 - * called unless locking correctness checking is enabled. Thus we
 - * make it inline to avoid a compiler warning. That's what gcc ends up
 - * doing anyway.
 - */
 -static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter)
 +unsigned int i2c_adapter_depth(struct i2c_adapter *adapter)
  {
        unsigned int depth = 0;
  
        while ((adapter = i2c_parent_is_i2c_adapter(adapter)))
                depth++;
  
 +      WARN_ONCE(depth >= MAX_LOCKDEP_SUBCLASSES,
 +                "adapter depth exceeds lockdep subclass limit\n");
 +
        return depth;
  }
 +EXPORT_SYMBOL_GPL(i2c_adapter_depth);
  
  /*
   * Let users instantiate I2C devices through sysfs. This can be used when
@@@ -1680,7 -1411,7 +1680,7 @@@ static struct i2c_client *of_i2c_regist
  
  static void of_i2c_register_devices(struct i2c_adapter *adap)
  {
-       struct device_node *node;
+       struct device_node *bus, *node;
  
        /* Only register child devices if the adapter has a node pointer set */
        if (!adap->dev.of_node)
  
        dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
  
-       for_each_available_child_of_node(adap->dev.of_node, node) {
+       bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
+       if (!bus)
+               bus = of_node_get(adap->dev.of_node);
+       for_each_available_child_of_node(bus, node) {
                if (of_node_test_and_set_flag(node, OF_POPULATED))
                        continue;
                of_i2c_register_device(adap, node);
        }
+       of_node_put(bus);
  }
  
  static int of_dev_node_match(struct device *dev, void *data)
@@@ -1767,8 -1504,8 +1773,8 @@@ static int i2c_do_add_adapter(struct i2
        if (driver->attach_adapter) {
                dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
                         driver->driver.name);
 -              dev_warn(&adap->dev, "Please use another way to instantiate "
 -                       "your i2c_client\n");
 +              dev_warn(&adap->dev,
 +                       "Please use another way to instantiate your i2c_client\n");
                /* We ignore the return code; if it fails, too bad */
                driver->attach_adapter(adap);
        }
@@@ -1780,15 -1517,9 +1786,15 @@@ static int __process_new_adapter(struc
        return i2c_do_add_adapter(to_i2c_driver(d), data);
  }
  
 +static const struct i2c_lock_operations i2c_adapter_lock_ops = {
 +      .lock_bus =    i2c_adapter_lock_bus,
 +      .trylock_bus = i2c_adapter_trylock_bus,
 +      .unlock_bus =  i2c_adapter_unlock_bus,
 +};
 +
  static int i2c_register_adapter(struct i2c_adapter *adap)
  {
 -      int res = 0;
 +      int res = -EINVAL;
  
        /* Can't register until after driver model init */
        if (WARN_ON(!is_registered)) {
        }
  
        /* Sanity checks */
 -      if (unlikely(adap->name[0] == '\0')) {
 -              pr_err("i2c-core: Attempt to register an adapter with "
 -                     "no name!\n");
 -              return -EINVAL;
 -      }
 -      if (unlikely(!adap->algo)) {
 -              pr_err("i2c-core: Attempt to register adapter '%s' with "
 -                     "no algo!\n", adap->name);
 -              return -EINVAL;
 -      }
 +      if (WARN(!adap->name[0], "i2c adapter has no name"))
 +              goto out_list;
  
 -      if (!adap->lock_bus) {
 -              adap->lock_bus = i2c_adapter_lock_bus;
 -              adap->trylock_bus = i2c_adapter_trylock_bus;
 -              adap->unlock_bus = i2c_adapter_unlock_bus;
 +      if (!adap->algo) {
 +              pr_err("adapter '%s': no algo supplied!\n", adap->name);
 +              goto out_list;
        }
  
 +      if (!adap->lock_ops)
 +              adap->lock_ops = &i2c_adapter_lock_ops;
 +
        rt_mutex_init(&adap->bus_lock);
        rt_mutex_init(&adap->mux_lock);
        mutex_init(&adap->userspace_clients_lock);
        adap->dev.bus = &i2c_bus_type;
        adap->dev.type = &i2c_adapter_type;
        res = device_register(&adap->dev);
 -      if (res)
 +      if (res) {
 +              pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
                goto out_list;
 +      }
  
        dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
  
                         "Failed to create compatibility class link\n");
  #endif
  
 -      /* bus recovery specific initialization */
 -      if (adap->bus_recovery_info) {
 -              struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
 +      i2c_init_recovery(adap);
  
 -              if (!bri->recover_bus) {
 -                      dev_err(&adap->dev, "No recover_bus() found, not using recovery\n");
 -                      adap->bus_recovery_info = NULL;
 -                      goto exit_recovery;
 -              }
 -
 -              /* Generic GPIO recovery */
 -              if (bri->recover_bus == i2c_generic_gpio_recovery) {
 -                      if (!gpio_is_valid(bri->scl_gpio)) {
 -                              dev_err(&adap->dev, "Invalid SCL gpio, not using recovery\n");
 -                              adap->bus_recovery_info = NULL;
 -                              goto exit_recovery;
 -                      }
 -
 -                      if (gpio_is_valid(bri->sda_gpio))
 -                              bri->get_sda = get_sda_gpio_value;
 -                      else
 -                              bri->get_sda = NULL;
 -
 -                      bri->get_scl = get_scl_gpio_value;
 -                      bri->set_scl = set_scl_gpio_value;
 -              } else if (bri->recover_bus == i2c_generic_scl_recovery) {
 -                      /* Generic SCL recovery */
 -                      if (!bri->set_scl || !bri->get_scl) {
 -                              dev_err(&adap->dev, "No {get|set}_scl() found, not using recovery\n");
 -                              adap->bus_recovery_info = NULL;
 -                      }
 -              }
 -      }
 -
 -exit_recovery:
        /* create pre-declared device nodes */
        of_i2c_register_devices(adap);
 -      acpi_i2c_register_devices(adap);
 -      acpi_i2c_install_space_handler(adap);
 +      i2c_acpi_register_devices(adap);
 +      i2c_acpi_install_space_handler(adap);
  
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
@@@ -1873,12 -1641,13 +1879,12 @@@ out_list
   */
  static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
  {
 -      int     id;
 +      int id;
  
        mutex_lock(&core_lock);
 -      id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
 -                     GFP_KERNEL);
 +      id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
        mutex_unlock(&core_lock);
 -      if (id < 0)
 +      if (WARN(id < 0, "couldn't get idr"))
                return id == -ENOSPC ? -EBUSY : id;
  
        return i2c_register_adapter(adap);
@@@ -1915,7 -1684,7 +1921,7 @@@ int i2c_add_adapter(struct i2c_adapter 
        id = idr_alloc(&i2c_adapter_idr, adapter,
                       __i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
        mutex_unlock(&core_lock);
 -      if (id < 0)
 +      if (WARN(id < 0, "couldn't get idr"))
                return id;
  
        adapter->nr = id;
@@@ -2013,11 -1782,12 +2019,11 @@@ void i2c_del_adapter(struct i2c_adapte
        found = idr_find(&i2c_adapter_idr, adap->nr);
        mutex_unlock(&core_lock);
        if (found != adap) {
 -              pr_debug("i2c-core: attempting to delete unregistered "
 -                       "adapter [%s]\n", adap->name);
 +              pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
                return;
        }
  
 -      acpi_i2c_remove_space_handler(adap);
 +      i2c_acpi_remove_space_handler(adap);
        /* Tell drivers about this removal */
        mutex_lock(&core_lock);
        bus_for_each_drv(&i2c_bus_type, NULL, adap,
@@@ -2173,7 -1943,7 +2179,7 @@@ int i2c_register_driver(struct module *
        if (res)
                return res;
  
 -      pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
 +      pr_debug("driver [%s] registered\n", driver->driver.name);
  
        INIT_LIST_HEAD(&driver->clients);
        /* Walk the adapters that are already present */
@@@ -2200,7 -1970,7 +2206,7 @@@ void i2c_del_driver(struct i2c_driver *
        i2c_for_each_dev(driver, __process_removed_driver);
  
        driver_unregister(&driver->driver);
 -      pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
 +      pr_debug("driver [%s] unregistered\n", driver->driver.name);
  }
  EXPORT_SYMBOL(i2c_del_driver);
  
@@@ -2291,8 -2061,8 +2297,8 @@@ static int of_i2c_notify(struct notifie
                put_device(&adap->dev);
  
                if (IS_ERR(client)) {
 -                      pr_err("%s: failed to create for '%s'\n",
 -                                      __func__, rd->dn->full_name);
 +                      dev_err(&adap->dev, "failed to create client for '%s'\n",
 +                               rd->dn->full_name);
                        return notifier_from_errno(PTR_ERR(client));
                }
                break;
@@@ -2353,8 -2123,6 +2359,8 @@@ static int __init i2c_init(void
  
        if (IS_ENABLED(CONFIG_OF_DYNAMIC))
                WARN_ON(of_reconfig_notifier_register(&i2c_of_notifier));
 +      if (IS_ENABLED(CONFIG_ACPI))
 +              WARN_ON(acpi_reconfig_notifier_register(&i2c_acpi_notifier));
  
        return 0;
  
@@@ -2370,8 -2138,6 +2376,8 @@@ bus_err
  
  static void __exit i2c_exit(void)
  {
 +      if (IS_ENABLED(CONFIG_ACPI))
 +              WARN_ON(acpi_reconfig_notifier_unregister(&i2c_acpi_notifier));
        if (IS_ENABLED(CONFIG_OF_DYNAMIC))
                WARN_ON(of_reconfig_notifier_unregister(&i2c_of_notifier));
        i2c_del_driver(&dummy_driver);
@@@ -2543,16 -2309,15 +2549,16 @@@ int i2c_transfer(struct i2c_adapter *ad
        if (adap->algo->master_xfer) {
  #ifdef DEBUG
                for (ret = 0; ret < num; ret++) {
 -                      dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
 -                              "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
 -                              ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
 +                      dev_dbg(&adap->dev,
 +                              "master_xfer[%d] %c, addr=0x%02x, len=%d%s\n",
 +                              ret, (msgs[ret].flags & I2C_M_RD) ? 'R' : 'W',
 +                              msgs[ret].addr, msgs[ret].len,
                                (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
                }
  #endif
  
                if (in_atomic() || irqs_disabled()) {
 -                      ret = adap->trylock_bus(adap, I2C_LOCK_SEGMENT);
 +                      ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT);
                        if (!ret)
                                /* I2C activity is ongoing. */
                                return -EAGAIN;
@@@ -2712,9 -2477,9 +2718,9 @@@ static int i2c_detect_address(struct i2
  
        /* Consistency check */
        if (info.type[0] == '\0') {
 -              dev_err(&adapter->dev, "%s detection function provided "
 -                      "no name for 0x%x\n", driver->driver.name,
 -                      addr);
 +              dev_err(&adapter->dev,
 +                      "%s detection function provided no name for 0x%x\n",
 +                      driver->driver.name, addr);
        } else {
                struct i2c_client *client;
  
@@@ -2752,8 -2517,9 +2758,8 @@@ static int i2c_detect(struct i2c_adapte
        /* Warn that the adapter lost class based instantiation */
        if (adapter->class == I2C_CLASS_DEPRECATED) {
                dev_dbg(&adapter->dev,
 -                      "This adapter dropped support for I2C classes and "
 -                      "won't auto-detect %s devices anymore. If you need it, check "
 -                      "'Documentation/i2c/instantiating-devices' for alternatives.\n",
 +                      "This adapter dropped support for I2C classes and won't auto-detect %s devices anymore. "
 +                      "If you need it, check 'Documentation/i2c/instantiating-devices' for alternatives.\n",
                        driver->driver.name);
                return 0;
        }
        temp_client->adapter = adapter;
  
        for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
 -              dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
 -                      "addr 0x%02x\n", adap_id, address_list[i]);
 +              dev_dbg(&adapter->dev,
 +                      "found normal entry for adapter %d, addr 0x%02x\n",
 +                      adap_id, address_list[i]);
                temp_client->addr = address_list[i];
                err = i2c_detect_address(temp_client, driver);
                if (unlikely(err))
@@@ -2803,16 -2568,15 +2809,16 @@@ i2c_new_probed_device(struct i2c_adapte
        for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
                /* Check address validity */
                if (i2c_check_7bit_addr_validity_strict(addr_list[i]) < 0) {
 -                      dev_warn(&adap->dev, "Invalid 7-bit address "
 -                               "0x%02x\n", addr_list[i]);
 +                      dev_warn(&adap->dev, "Invalid 7-bit address 0x%02x\n",
 +                               addr_list[i]);
                        continue;
                }
  
                /* Check address availability (7 bit, no need to encode flags) */
                if (i2c_check_addr_busy(adap, addr_list[i])) {
 -                      dev_dbg(&adap->dev, "Address 0x%02x already in "
 -                              "use, not probing\n", addr_list[i]);
 +                      dev_dbg(&adap->dev,
 +                              "Address 0x%02x already in use, not probing\n",
 +                              addr_list[i]);
                        continue;
                }
  
@@@ -2915,7 -2679,7 +2921,7 @@@ static int i2c_smbus_check_pec(u8 cpec
        cpec = i2c_smbus_msg_pec(cpec, msg);
  
        if (rpec != cpec) {
 -              pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
 +              pr_debug("Bad PEC 0x%02x vs. 0x%02x\n",
                        rpec, cpec);
                return -EBADMSG;
        }