mbox series

[v2,0/7] Introduce intel_skl_int3472 driver

Message ID 20210118003428.568892-1-djrscally@gmail.com
Headers show
Series Introduce intel_skl_int3472 driver | expand

Message

Daniel Scally Jan. 18, 2021, 12:34 a.m. UTC
Hello all

v1 for this series was originally 14-18 of this series:
https://lore.kernel.org/linux-media/20201130133129.1024662-1-djrscally@gmail.com/T/#m91934e12e3d033da2e768e952ea3b4a125ee3e67

At the moment in the kernel the ACPI _HID INT3472 is taken by the tps68470
MFD driver, but that driver can only handle some of the cases of that _HID
that we see. There are at least these three possibilities:

1. INT3472 devices that provide GPIOs through the usual framework and run
   power and clocks through an operation region; this is the situation that
   the current module handles and is seen on ChromeOS devices
2. INT3472 devices that provide GPIOs, plus clocks and regulators that are
   meant to be driven through the usual frameworks, usually seen on devices
   designed to run Windows
3. INT3472 devices that don't actually represent a physical tps68470, but
   are being used as a convenient way of grouping a bunch of system GPIO
   lines that are intended to enable power and clocks for sensors which
   are called out as dependent on them. Also seen on devices designed to
   run Windows.

This series introduces a new module which registers:

1. An i2c driver that determines which scenario (#1 or #2) applies to the
   machine and registers platform devices to be bound to GPIO, OpRegion,
   clock and regulator drivers as appropriate.
2. A platform driver that binds to the dummy INT3472 devices described in
   #3

The platform driver for the dummy device registers the GPIO lines that
enable the clocks and regulators to the sensors via those frameworks so
that sensor drivers can consume them in the usual fashion. The existing
GPIO and OpRegion tps68470 drivers will work with the i2c driver that's
registered. Clock and regulator drivers are currently in the works.

The existing mfd/tps68470.c driver being thus superseded, it is removed.

This has been tested on a number of devices; but currently **not** on a
ChromeOS, which we ideally need to do to ensure no regression caused by
replacing the tps68470 MFD driver.

Thanks
Dan

Daniel Scally (7):
  acpi: utils: move acpi_lpss_dep() to utils
  acpi: utils: Add function to fetch dependent acpi_devices
  i2c: i2c-core-base: Use format macro in i2c_dev_set_name()
  i2c: i2c-core-acpi: Add i2c_acpi_dev_name()
  gpio: gpiolib-acpi: Export acpi_get_gpiod()
  platform: x86: Add intel_skl_int3472 driver
  mfd: Remove tps68470 MFD driver

 MAINTAINERS                                   |   5 +
 drivers/acpi/acpi_lpss.c                      |  24 -
 drivers/acpi/internal.h                       |   1 +
 drivers/acpi/pmic/Kconfig                     |   1 -
 drivers/acpi/utils.c                          |  58 ++
 drivers/gpio/Kconfig                          |   1 -
 drivers/gpio/gpiolib-acpi.c                   |   3 +-
 drivers/i2c/i2c-core-acpi.c                   |  16 +
 drivers/i2c/i2c-core-base.c                   |   4 +-
 drivers/mfd/Kconfig                           |  18 -
 drivers/mfd/Makefile                          |   1 -
 drivers/mfd/tps68470.c                        |  97 ----
 drivers/platform/x86/Kconfig                  |  25 +
 drivers/platform/x86/Makefile                 |   4 +
 .../platform/x86/intel_skl_int3472_common.c   | 100 ++++
 .../platform/x86/intel_skl_int3472_common.h   | 100 ++++
 .../platform/x86/intel_skl_int3472_discrete.c | 496 ++++++++++++++++++
 .../platform/x86/intel_skl_int3472_tps68470.c | 145 +++++
 include/acpi/acpi_bus.h                       |   2 +
 include/linux/acpi.h                          |   5 +
 include/linux/i2c.h                           |   8 +
 21 files changed, 969 insertions(+), 145 deletions(-)
 delete mode 100644 drivers/mfd/tps68470.c
 create mode 100644 drivers/platform/x86/intel_skl_int3472_common.c
 create mode 100644 drivers/platform/x86/intel_skl_int3472_common.h
 create mode 100644 drivers/platform/x86/intel_skl_int3472_discrete.c
 create mode 100644 drivers/platform/x86/intel_skl_int3472_tps68470.c

Comments

Laurent Pinchart Jan. 18, 2021, 7:34 a.m. UTC | #1
Hi Daniel,

Thank you for the patch.

On Mon, Jan 18, 2021 at 12:34:23AM +0000, Daniel Scally wrote:
> In some ACPI tables we encounter, devices use the _DEP method to assert
> a dependence on other ACPI devices as opposed to the OpRegions that the
> specification intends. We need to be able to find those devices "from"
> the dependee, so add a function to parse all ACPI Devices and check if
> the include the handle of the dependee device in their _DEP buffer.
> 
> Signed-off-by: Daniel Scally <djrscally@gmail.com>
> ---
> Changes in v2:
> 	- Used acpi_lpss_dep() as Andy suggested.
> 
>  drivers/acpi/utils.c    | 34 ++++++++++++++++++++++++++++++++++
>  include/acpi/acpi_bus.h |  2 ++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
> index 78b38775f18b..ec6a2406a886 100644
> --- a/drivers/acpi/utils.c
> +++ b/drivers/acpi/utils.c
> @@ -831,6 +831,18 @@ bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
>  	return false;
>  }
>  
> +static int acpi_dev_match_by_dep(struct device *dev, const void *data)
> +{
> +	struct acpi_device *adev = to_acpi_device(dev);
> +	const struct acpi_device *dependee = data;
> +	acpi_handle handle = dependee->handle;
> +
> +	if (acpi_lpss_dep(adev, handle))
> +		return 1;
> +
> +	return 0;
> +}
> +

I think I'd move this just before acpi_dev_get_next_dep_dev() to keep
the two together.

>  /**
>   * acpi_dev_present - Detect that a given ACPI device is present
>   * @hid: Hardware ID of the device.
> @@ -866,6 +878,28 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
>  }
>  EXPORT_SYMBOL(acpi_dev_present);
>  
> +/**
> + * acpi_dev_get_next_dep_dev - Return next ACPI device dependent on input dev

Maybe acpi_dev_get_next_dependent_dev() ? "dep" could mean either
dependent or dependency.

> + * @adev: Pointer to the dependee device
> + * @prev: Pointer to the previous dependent device (or NULL for first match)
> + *
> + * Return the next ACPI device which declares itself dependent on @adev in
> + * the _DEP buffer.
> + *
> + * The caller is responsible to call put_device() on the returned device.
> + */
> +struct acpi_device *acpi_dev_get_next_dep_dev(struct acpi_device *adev,
> +					      struct acpi_device *prev)
> +{
> +	struct device *start = prev ? &prev->dev : NULL;
> +	struct device *dev;
> +
> +	dev = bus_find_device(&acpi_bus_type, start, adev, acpi_dev_match_by_dep);

Having to loop over all ACPI devices is quite inefficient, but if we
need a reverse lookup, we don't really have a choice. We could create a
reverse map, but I don't think it's worth it.

> +
> +	return dev ? to_acpi_device(dev) : NULL;
> +}
> +EXPORT_SYMBOL(acpi_dev_get_next_dep_dev);

I would have used EXPORT_SYMBOL_GPL. I'm not sure what the policy is in
the ACPI subsystem, and it's also a personal choice.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +
>  /**
>   * acpi_dev_get_next_match_dev - Return the next match of ACPI device
>   * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 02a716a0af5d..33deb22294f2 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -683,6 +683,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
>  
>  bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
>  
> +struct acpi_device *
> +acpi_dev_get_next_dep_dev(struct acpi_device *adev, struct acpi_device *prev);
>  struct acpi_device *
>  acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
>  struct acpi_device *
Laurent Pinchart Jan. 18, 2021, 7:42 a.m. UTC | #2
Hi Daniel,

Thank you for the patch.

On Mon, Jan 18, 2021 at 12:34:28AM +0000, Daniel Scally wrote:
> This driver only covered one scenario in which ACPI devices with _HID
> INT3472 are found, and its functionality has been taken over by the
> intel-skl-int3472 module, so remove it.
> 
> Signed-off-by: Daniel Scally <djrscally@gmail.com>
> ---
> Changes in v2:
> 
> 	- Introduced
> 
>  drivers/acpi/pmic/Kconfig |  1 -
>  drivers/gpio/Kconfig      |  1 -
>  drivers/mfd/Kconfig       | 18 --------
>  drivers/mfd/Makefile      |  1 -
>  drivers/mfd/tps68470.c    | 97 ---------------------------------------
>  5 files changed, 118 deletions(-)
>  delete mode 100644 drivers/mfd/tps68470.c
> 
> diff --git a/drivers/acpi/pmic/Kconfig b/drivers/acpi/pmic/Kconfig
> index 56bbcb2ce61b..e27d8ef3a32c 100644
> --- a/drivers/acpi/pmic/Kconfig
> +++ b/drivers/acpi/pmic/Kconfig
> @@ -52,7 +52,6 @@ endif	# PMIC_OPREGION
>  
>  config TPS68470_PMIC_OPREGION
>  	bool "ACPI operation region support for TPS68470 PMIC"
> -	depends on MFD_TPS68470

Should this now depend on INTEL_SKL_INT3472 ?

>  	help
>  	  This config adds ACPI operation region support for TI TPS68470 PMIC.
>  	  TPS68470 device is an advanced power management unit that powers
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index c70f46e80a3b..07ff8f24b0d9 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1343,7 +1343,6 @@ config GPIO_TPS65912
>  
>  config GPIO_TPS68470
>  	bool "TPS68470 GPIO"
> -	depends on MFD_TPS68470

Same here.

This won't deal with the case where th TPS68470 is instantiated through
DT, but that's not supported yet, so it can be dealt with it later when
the need arises.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>  	help
>  	  Select this option to enable GPIO driver for the TPS68470
>  	  chip family.
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index bdfce7b15621..9a1f648efde0 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1520,24 +1520,6 @@ config MFD_TPS65217
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called tps65217.
>  
> -config MFD_TPS68470
> -	bool "TI TPS68470 Power Management / LED chips"
> -	depends on ACPI && PCI && I2C=y
> -	depends on I2C_DESIGNWARE_PLATFORM=y
> -	select MFD_CORE
> -	select REGMAP_I2C
> -	help
> -	  If you say yes here you get support for the TPS68470 series of
> -	  Power Management / LED chips.
> -
> -	  These include voltage regulators, LEDs and other features
> -	  that are often used in portable devices.
> -
> -	  This option is a bool as it provides an ACPI operation
> -	  region, which must be available before any of the devices
> -	  using this are probed. This option also configures the
> -	  designware-i2c driver to be built-in, for the same reason.
> -
>  config MFD_TI_LP873X
>  	tristate "TI LP873X Power Management IC"
>  	depends on I2C
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 14fdb188af02..5994e812f479 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -105,7 +105,6 @@ obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
>  obj-$(CONFIG_MFD_TPS65912)	+= tps65912-core.o
>  obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
>  obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
> -obj-$(CONFIG_MFD_TPS68470)	+= tps68470.o
>  obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
>  obj-$(CONFIG_MENELAUS)		+= menelaus.o
>  
> diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c
> deleted file mode 100644
> index 4a4df4ffd18c..000000000000
> --- a/drivers/mfd/tps68470.c
> +++ /dev/null
> @@ -1,97 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * TPS68470 chip Parent driver
> - *
> - * Copyright (C) 2017 Intel Corporation
> - *
> - * Authors:
> - *	Rajmohan Mani <rajmohan.mani@intel.com>
> - *	Tianshu Qiu <tian.shu.qiu@intel.com>
> - *	Jian Xu Zheng <jian.xu.zheng@intel.com>
> - *	Yuning Pu <yuning.pu@intel.com>
> - */
> -
> -#include <linux/acpi.h>
> -#include <linux/delay.h>
> -#include <linux/i2c.h>
> -#include <linux/init.h>
> -#include <linux/mfd/core.h>
> -#include <linux/mfd/tps68470.h>
> -#include <linux/regmap.h>
> -
> -static const struct mfd_cell tps68470s[] = {
> -	{ .name = "tps68470-gpio" },
> -	{ .name = "tps68470_pmic_opregion" },
> -};
> -
> -static const struct regmap_config tps68470_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = TPS68470_REG_MAX,
> -};
> -
> -static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
> -{
> -	unsigned int version;
> -	int ret;
> -
> -	/* Force software reset */
> -	ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
> -	if (ret)
> -		return ret;
> -
> -	ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
> -	if (ret) {
> -		dev_err(dev, "Failed to read revision register: %d\n", ret);
> -		return ret;
> -	}
> -
> -	dev_info(dev, "TPS68470 REVID: 0x%x\n", version);
> -
> -	return 0;
> -}
> -
> -static int tps68470_probe(struct i2c_client *client)
> -{
> -	struct device *dev = &client->dev;
> -	struct regmap *regmap;
> -	int ret;
> -
> -	regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
> -	if (IS_ERR(regmap)) {
> -		dev_err(dev, "devm_regmap_init_i2c Error %ld\n",
> -			PTR_ERR(regmap));
> -		return PTR_ERR(regmap);
> -	}
> -
> -	i2c_set_clientdata(client, regmap);
> -
> -	ret = tps68470_chip_init(dev, regmap);
> -	if (ret < 0) {
> -		dev_err(dev, "TPS68470 Init Error %d\n", ret);
> -		return ret;
> -	}
> -
> -	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, tps68470s,
> -			      ARRAY_SIZE(tps68470s), NULL, 0, NULL);
> -	if (ret < 0) {
> -		dev_err(dev, "devm_mfd_add_devices failed: %d\n", ret);
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static const struct acpi_device_id tps68470_acpi_ids[] = {
> -	{"INT3472"},
> -	{},
> -};
> -
> -static struct i2c_driver tps68470_driver = {
> -	.driver = {
> -		   .name = "tps68470",
> -		   .acpi_match_table = tps68470_acpi_ids,
> -	},
> -	.probe_new = tps68470_probe,
> -};
> -builtin_i2c_driver(tps68470_driver);
Daniel Scally Jan. 18, 2021, 8:37 a.m. UTC | #3
Morning Laurent

On 18/01/2021 07:34, Laurent Pinchart wrote:
> Hi Daniel,
>
> Thank you for the patch.
>
> On Mon, Jan 18, 2021 at 12:34:23AM +0000, Daniel Scally wrote:
>> In some ACPI tables we encounter, devices use the _DEP method to assert
>> a dependence on other ACPI devices as opposed to the OpRegions that the
>> specification intends. We need to be able to find those devices "from"
>> the dependee, so add a function to parse all ACPI Devices and check if
>> the include the handle of the dependee device in their _DEP buffer.
>>
>> Signed-off-by: Daniel Scally <djrscally@gmail.com>
>> ---
>> Changes in v2:
>> 	- Used acpi_lpss_dep() as Andy suggested.
>>
>>  drivers/acpi/utils.c    | 34 ++++++++++++++++++++++++++++++++++
>>  include/acpi/acpi_bus.h |  2 ++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
>> index 78b38775f18b..ec6a2406a886 100644
>> --- a/drivers/acpi/utils.c
>> +++ b/drivers/acpi/utils.c
>> @@ -831,6 +831,18 @@ bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
>>  	return false;
>>  }
>>  
>> +static int acpi_dev_match_by_dep(struct device *dev, const void *data)
>> +{
>> +	struct acpi_device *adev = to_acpi_device(dev);
>> +	const struct acpi_device *dependee = data;
>> +	acpi_handle handle = dependee->handle;
>> +
>> +	if (acpi_lpss_dep(adev, handle))
>> +		return 1;
>> +
>> +	return 0;
>> +}
>> +
> I think I'd move this just before acpi_dev_get_next_dep_dev() to keep
> the two together.


Will do

>
>>  /**
>>   * acpi_dev_present - Detect that a given ACPI device is present
>>   * @hid: Hardware ID of the device.
>> @@ -866,6 +878,28 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
>>  }
>>  EXPORT_SYMBOL(acpi_dev_present);
>>  
>> +/**
>> + * acpi_dev_get_next_dep_dev - Return next ACPI device dependent on input dev
> Maybe acpi_dev_get_next_dependent_dev() ? "dep" could mean either
> dependent or dependency.


Yes, good point, I agree.

>
>> + * @adev: Pointer to the dependee device
>> + * @prev: Pointer to the previous dependent device (or NULL for first match)
>> + *
>> + * Return the next ACPI device which declares itself dependent on @adev in
>> + * the _DEP buffer.
>> + *
>> + * The caller is responsible to call put_device() on the returned device.
>> + */
>> +struct acpi_device *acpi_dev_get_next_dep_dev(struct acpi_device *adev,
>> +					      struct acpi_device *prev)
>> +{
>> +	struct device *start = prev ? &prev->dev : NULL;
>> +	struct device *dev;
>> +
>> +	dev = bus_find_device(&acpi_bus_type, start, adev, acpi_dev_match_by_dep);
> Having to loop over all ACPI devices is quite inefficient, but if we
> need a reverse lookup, we don't really have a choice. We could create a
> reverse map, but I don't think it's worth it.
>
>> +
>> +	return dev ? to_acpi_device(dev) : NULL;
>> +}
>> +EXPORT_SYMBOL(acpi_dev_get_next_dep_dev);
> I would have used EXPORT_SYMBOL_GPL. I'm not sure what the policy is in
> the ACPI subsystem, and it's also a personal choice.
EXPORT_SYMBOL_GPL would be my usual choice, but the other functions in
the file all use EXPORT_SYMBOL, so I assumed there was some policy that
that be used (since basically everywhere else I've touched in the kernel
so far defaults to the GPL version)
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Thanks!

>
>> +
>>  /**
>>   * acpi_dev_get_next_match_dev - Return the next match of ACPI device
>>   * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index 02a716a0af5d..33deb22294f2 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -683,6 +683,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
>>  
>>  bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
>>  
>> +struct acpi_device *
>> +acpi_dev_get_next_dep_dev(struct acpi_device *adev, struct acpi_device *prev);
>>  struct acpi_device *
>>  acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
>>  struct acpi_device *
Laurent Pinchart Jan. 18, 2021, 9:18 a.m. UTC | #4
Hi Daniel,

Thank you for the patch.

On Mon, Jan 18, 2021 at 12:34:25AM +0000, Daniel Scally wrote:
> We want to refer to an i2c device by name before it has been

s/i2c device/acpi i2c device/ ?

> created by the kernel; add a function that constructs the name
> from the acpi device instead.
> 
> Signed-off-by: Daniel Scally <djrscally@gmail.com>
> ---
> Changes in v2:
> 
> 	- Stopped using devm_kasprintf()
> 
>  drivers/i2c/i2c-core-acpi.c | 16 ++++++++++++++++
>  include/linux/i2c.h         |  5 +++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> index 37c510d9347a..98c3ba9a2350 100644
> --- a/drivers/i2c/i2c-core-acpi.c
> +++ b/drivers/i2c/i2c-core-acpi.c
> @@ -497,6 +497,22 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
>  }
>  EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
>  
> +/**
> + * i2c_acpi_dev_name - Construct i2c device name for devs sourced from ACPI
> + * @adev:     ACPI device to construct the name for
> + *
> + * Constructs the name of an i2c device matching the format used by
> + * i2c_dev_set_name() to allow users to refer to an i2c device by name even
> + * before they have been instantiated.
> + *
> + * The caller is responsible for freeing the returned pointer.
> + */
> +char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> +	return kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));

There's a real danger of a memory leak, as the function name sounds very
similar to dev_name() or acpi_dev_name() and those don't allocate
memory. I'm not sure what a better name would be, but given that this
function is only used in patch 6/7 and not in the I2C subsystem itself,
I wonder if we should inline this kasprintf() call in the caller and
drop this patch.

> +}
> +EXPORT_SYMBOL_GPL(i2c_acpi_dev_name);
> +
>  #ifdef CONFIG_ACPI_I2C_OPREGION
>  static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
>  		u8 cmd, u8 *data, u8 data_len)
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 4d40a4b46810..b82aac05b17f 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -998,6 +998,7 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
>  u32 i2c_acpi_find_bus_speed(struct device *dev);
>  struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
>  				       struct i2c_board_info *info);
> +char *i2c_acpi_dev_name(struct acpi_device *adev);
>  struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
>  #else
>  static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
> @@ -1014,6 +1015,10 @@ static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
>  {
>  	return ERR_PTR(-ENODEV);
>  }
> +static inline char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> +	return NULL;
> +}
>  static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
>  {
>  	return NULL;
Andy Shevchenko Jan. 18, 2021, 1:39 p.m. UTC | #5
On Mon, Jan 18, 2021 at 12:34:25AM +0000, Daniel Scally wrote:
> We want to refer to an i2c device by name before it has been

I²C

> created by the kernel; add a function that constructs the name
> from the acpi device instead.

acpi -> ACPI

Prefix: "i2c: core: "

With above
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Signed-off-by: Daniel Scally <djrscally@gmail.com>
> ---
> Changes in v2:
> 
> 	- Stopped using devm_kasprintf()
> 
>  drivers/i2c/i2c-core-acpi.c | 16 ++++++++++++++++
>  include/linux/i2c.h         |  5 +++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> index 37c510d9347a..98c3ba9a2350 100644
> --- a/drivers/i2c/i2c-core-acpi.c
> +++ b/drivers/i2c/i2c-core-acpi.c
> @@ -497,6 +497,22 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
>  }
>  EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
>  
> +/**
> + * i2c_acpi_dev_name - Construct i2c device name for devs sourced from ACPI
> + * @adev:     ACPI device to construct the name for
> + *
> + * Constructs the name of an i2c device matching the format used by
> + * i2c_dev_set_name() to allow users to refer to an i2c device by name even
> + * before they have been instantiated.
> + *
> + * The caller is responsible for freeing the returned pointer.
> + */
> +char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> +	return kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
> +}
> +EXPORT_SYMBOL_GPL(i2c_acpi_dev_name);
> +
>  #ifdef CONFIG_ACPI_I2C_OPREGION
>  static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
>  		u8 cmd, u8 *data, u8 data_len)
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 4d40a4b46810..b82aac05b17f 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -998,6 +998,7 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
>  u32 i2c_acpi_find_bus_speed(struct device *dev);
>  struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
>  				       struct i2c_board_info *info);
> +char *i2c_acpi_dev_name(struct acpi_device *adev);
>  struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
>  #else
>  static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
> @@ -1014,6 +1015,10 @@ static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
>  {
>  	return ERR_PTR(-ENODEV);
>  }
> +static inline char *i2c_acpi_dev_name(struct acpi_device *adev)
> +{
> +	return NULL;
> +}
>  static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
>  {
>  	return NULL;
> -- 
> 2.25.1
>
Andy Shevchenko Jan. 18, 2021, 1:45 p.m. UTC | #6
On Mon, Jan 18, 2021 at 12:34:26AM +0000, Daniel Scally wrote:
> I need to be able to translate GPIO resources in an acpi_device's _CRS

ACPI device's

> into gpio_descs. Those are represented in _CRS as a pathname to a GPIO

into GPIO descriptor array

> device plus the pin's index number: this function is perfect for that
> purpose.

...

> diff --git a/include/linux/acpi.h b/include/linux/acpi.h

Wrong header. Please use gpio/consumer.h.
Andy Shevchenko Jan. 18, 2021, 1:53 p.m. UTC | #7
On Mon, Jan 18, 2021 at 12:34:28AM +0000, Daniel Scally wrote:
> This driver only covered one scenario in which ACPI devices with _HID
> INT3472 are found, and its functionality has been taken over by the
> intel-skl-int3472 module, so remove it.

Prefix: "mfd: tps68470: ". Rationale: easier to look for specific commits, by,
for example, running `git log --grep tps68470`.
Joe Perches Jan. 18, 2021, 6:43 p.m. UTC | #8
On Mon, 2021-01-18 at 15:39 +0200, Andy Shevchenko wrote:
> On Mon, Jan 18, 2021 at 12:34:25AM +0000, Daniel Scally wrote:
> > We want to refer to an i2c device by name before it has been
> 
> I²C

Andy, are you next going to suggest renaming all the files with i2c?

$ git ls-files | grep i2c | wc -l
953

Please do not use the pedantic I²C, 7 bit ascii is just fine here.

My keyboard does not have a superscripted 2 key, and yes, I know
how to use it with multiple keypresses but it's irrelevant.

> > created by the kernel; add a function that constructs the name
> > from the acpi device instead.
> 
> acpi -> ACPI

Same deal with acpi filenames.  Everyone already recognizes acpi is
actually ACPI and there isn't any confusion in anyone's mind.

$ git ls-files | grep acpi | wc -l
533

> Prefix: "i2c: core: "

Please stop being a pedant on these trivial things.
It's unimportant and has almost no value.
Andy Shevchenko Jan. 18, 2021, 7:01 p.m. UTC | #9
On Mon, Jan 18, 2021 at 08:56:44PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 18, 2021 at 10:43:14AM -0800, Joe Perches wrote:
> > On Mon, 2021-01-18 at 15:39 +0200, Andy Shevchenko wrote:
> > > On Mon, Jan 18, 2021 at 12:34:25AM +0000, Daniel Scally wrote:

...

> > > Prefix: "i2c: core: "
> > 
> > Please stop being a pedant on these trivial things.
> > It's unimportant and has almost no value.
> 
> This series is going to have a new version, that's why I did those comments.
> If it had been the only comments, I would have not posted them.

And actually to the rationale: it makes slightly easier to grep for patches
against same driver / group of drivers / subsystem.

I bet the `... --grep 'i2c: core:' will give different results to the
`... -- drivers/i2c/i2c-* include/i2c*` besides being shorter.
Joe Perches Jan. 18, 2021, 8:07 p.m. UTC | #10
On Mon, 2021-01-18 at 15:53 +0200, Andy Shevchenko wrote:
> On Mon, Jan 18, 2021 at 12:34:28AM +0000, Daniel Scally wrote:
> > This driver only covered one scenario in which ACPI devices with _HID
> > INT3472 are found, and its functionality has been taken over by the
> > intel-skl-int3472 module, so remove it.
> 
> Prefix: "mfd: tps68470: ". Rationale: easier to look for specific commits, by,
> for example, running `git log --grep tps68470`.

It's also reasonable to grep by path instead

$ git log --pretty=oneline --grep 'tps68470'
cf2e8c544cd3b33e9e403b7b72404c221bf888d1 Merge tag 'mfd-next-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
66265e719b4603ef9a1b8a6c876bcb542c021496 mfd: tps68470: Drop unused MODULE_DEVICE_TABLE
883cad5ba8cc2d9b740b4ad0a8a91063c99c75a3 Merge tag 'mfd-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
ca34b4f0bed802e1c8612ef08456b20992aeb02a gpio: tps68470: Update to SPDX license identifier

vs

$ git log --pretty=oneline -- '*tps68470*'
e42615ec233b30dfaf117b108d4cb49455b4df1d gpio: Use new GPIO_LINE_DIRECTION
66265e719b4603ef9a1b8a6c876bcb542c021496 mfd: tps68470: Drop unused MODULE_DEVICE_TABLE
36b835176fe014197639f335d9d35424b7805027 ACPI / PMIC: Sort headers alphabetically
37c089d1facaf03969f66a5469c169a2c73429f6 mfd: Update to SPDX license identifier
1b2951dd99af3970c1c1a8385a12b90236b837de Merge tag 'gpio-v4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
ca34b4f0bed802e1c8612ef08456b20992aeb02a gpio: tps68470: Update to SPDX license identifier
66444f460e68d641a63f0787627bac6c1ee340b5 ACPI / PMIC: Replace license boilerplate with SPDX license identifier
e13452ac379070f038c264618e35559434252175 ACPI / PMIC: Add TI PMIC TPS68470 operation region driver
968c61f7da3cf6d58a49587cfe00d899ca72c1ad Merge tag 'mfd-next-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
9bbf6a15ce19dd947b7fa6ad4095931ab3682da8 mfd: Add support for TPS68470 device
275b13a65547e2dc39c75d660d2e0f0fddde90f6 gpio: Add support for TPS68470 GPIOs
Daniel Scally Jan. 18, 2021, 8:51 p.m. UTC | #11
On 18/01/2021 16:14, Rafael J. Wysocki wrote:
> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
>> In some ACPI tables we encounter, devices use the _DEP method to assert
>> a dependence on other ACPI devices as opposed to the OpRegions that the
>> specification intends. We need to be able to find those devices "from"
>> the dependee, so add a function to parse all ACPI Devices and check if
>> the include the handle of the dependee device in their _DEP buffer.
> What exactly do you need this for?


So, in our DSDT we have devices with _HID INT3472, plus sensors which
refer to those INT3472's in their _DEP method. The driver binds to the
INT3472 device, we need to find the sensors dependent on them.


> Would it be practical to look up the suppliers in acpi_dep_list instead?
>
> Note that supplier drivers may remove entries from there, but does
> that matter for your use case?


Ah - that may work, yes. Thank you, let me test that.


>
>> Signed-off-by: Daniel Scally <djrscally@gmail.com>
>> ---
>> Changes in v2:
>>         - Used acpi_lpss_dep() as Andy suggested.
>>
>>  drivers/acpi/utils.c    | 34 ++++++++++++++++++++++++++++++++++
>>  include/acpi/acpi_bus.h |  2 ++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
>> index 78b38775f18b..ec6a2406a886 100644
>> --- a/drivers/acpi/utils.c
>> +++ b/drivers/acpi/utils.c
>> @@ -831,6 +831,18 @@ bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
>>         return false;
>>  }
>>
>> +static int acpi_dev_match_by_dep(struct device *dev, const void *data)
>> +{
>> +       struct acpi_device *adev = to_acpi_device(dev);
>> +       const struct acpi_device *dependee = data;
>> +       acpi_handle handle = dependee->handle;
>> +
>> +       if (acpi_lpss_dep(adev, handle))
>> +               return 1;
>> +
>> +       return 0;
>> +}
>> +
>>  /**
>>   * acpi_dev_present - Detect that a given ACPI device is present
>>   * @hid: Hardware ID of the device.
>> @@ -866,6 +878,28 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
>>  }
>>  EXPORT_SYMBOL(acpi_dev_present);
>>
>> +/**
>> + * acpi_dev_get_next_dep_dev - Return next ACPI device dependent on input dev
>> + * @adev: Pointer to the dependee device
>> + * @prev: Pointer to the previous dependent device (or NULL for first match)
>> + *
>> + * Return the next ACPI device which declares itself dependent on @adev in
>> + * the _DEP buffer.
>> + *
>> + * The caller is responsible to call put_device() on the returned device.
>> + */
>> +struct acpi_device *acpi_dev_get_next_dep_dev(struct acpi_device *adev,
>> +                                             struct acpi_device *prev)
>> +{
>> +       struct device *start = prev ? &prev->dev : NULL;
>> +       struct device *dev;
>> +
>> +       dev = bus_find_device(&acpi_bus_type, start, adev, acpi_dev_match_by_dep);
>> +
>> +       return dev ? to_acpi_device(dev) : NULL;
>> +}
>> +EXPORT_SYMBOL(acpi_dev_get_next_dep_dev);
>> +
>>  /**
>>   * acpi_dev_get_next_match_dev - Return the next match of ACPI device
>>   * @adev: Pointer to the previous acpi_device matching this @hid, @uid and @hrv
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index 02a716a0af5d..33deb22294f2 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -683,6 +683,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
>>
>>  bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
>>
>> +struct acpi_device *
>> +acpi_dev_get_next_dep_dev(struct acpi_device *adev, struct acpi_device *prev);
>>  struct acpi_device *
>>  acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
>>  struct acpi_device *
>> --
>> 2.25.1
>>
Daniel Scally Jan. 18, 2021, 9:32 p.m. UTC | #12
On 18/01/2021 13:45, Andy Shevchenko wrote:
> On Mon, Jan 18, 2021 at 12:34:26AM +0000, Daniel Scally wrote:
>> I need to be able to translate GPIO resources in an acpi_device's _CRS
> 
> ACPI device's
> 
>> into gpio_descs. Those are represented in _CRS as a pathname to a GPIO
> 
> into GPIO descriptor array
> 
>> device plus the pin's index number: this function is perfect for that
>> purpose.
> 
> ...
> 
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> 
> Wrong header. Please use gpio/consumer.h.
> 
Ack to all - thanks.
Rafael J. Wysocki Jan. 19, 2021, 1:15 p.m. UTC | #13
On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
>
> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
> > On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
> >> In some ACPI tables we encounter, devices use the _DEP method to assert
> >> a dependence on other ACPI devices as opposed to the OpRegions that the
> >> specification intends. We need to be able to find those devices "from"
> >> the dependee, so add a function to parse all ACPI Devices and check if
> >> the include the handle of the dependee device in their _DEP buffer.
> > What exactly do you need this for?
>
> So, in our DSDT we have devices with _HID INT3472, plus sensors which
> refer to those INT3472's in their _DEP method. The driver binds to the
> INT3472 device, we need to find the sensors dependent on them.
>

Well, this is an interesting concept. :-)

Why does _DEP need to be used for that?  Isn't there any other way to
look up the dependent sensors?

>
> > Would it be practical to look up the suppliers in acpi_dep_list instead?
> >
> > Note that supplier drivers may remove entries from there, but does
> > that matter for your use case?
>
> Ah - that may work, yes. Thank you, let me test that.

Even if that doesn't work right away, but it can be made work, I would
very much prefer that to the driver parsing _DEP for every device in
the namespace by itself.
Rafael J. Wysocki Jan. 19, 2021, 1:19 p.m. UTC | #14
On Mon, Jan 18, 2021 at 9:55 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Mon, Jan 18, 2021 at 12:34:25AM +0000, Daniel Scally wrote:
> > We want to refer to an i2c device by name before it has been
>
> s/i2c device/acpi i2c device/ ?
>
> > created by the kernel; add a function that constructs the name
> > from the acpi device instead.
> >
> > Signed-off-by: Daniel Scally <djrscally@gmail.com>
> > ---
> > Changes in v2:
> >
> >       - Stopped using devm_kasprintf()
> >
> >  drivers/i2c/i2c-core-acpi.c | 16 ++++++++++++++++
> >  include/linux/i2c.h         |  5 +++++
> >  2 files changed, 21 insertions(+)
> >
> > diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
> > index 37c510d9347a..98c3ba9a2350 100644
> > --- a/drivers/i2c/i2c-core-acpi.c
> > +++ b/drivers/i2c/i2c-core-acpi.c
> > @@ -497,6 +497,22 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
> >  }
> >  EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
> >
> > +/**
> > + * i2c_acpi_dev_name - Construct i2c device name for devs sourced from ACPI
> > + * @adev:     ACPI device to construct the name for
> > + *
> > + * Constructs the name of an i2c device matching the format used by
> > + * i2c_dev_set_name() to allow users to refer to an i2c device by name even
> > + * before they have been instantiated.
> > + *
> > + * The caller is responsible for freeing the returned pointer.
> > + */
> > +char *i2c_acpi_dev_name(struct acpi_device *adev)
> > +{
> > +     return kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
>
> There's a real danger of a memory leak, as the function name sounds very
> similar to dev_name() or acpi_dev_name() and those don't allocate
> memory. I'm not sure what a better name would be, but given that this
> function is only used in patch 6/7 and not in the I2C subsystem itself,
> I wonder if we should inline this kasprintf() call in the caller and
> drop this patch.

IMO if this is a one-off usage, it's better to open-code it.
Daniel Scally Jan. 19, 2021, 1:28 p.m. UTC | #15
On 19/01/2021 13:15, Rafael J. Wysocki wrote:
> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
>>>> specification intends. We need to be able to find those devices "from"
>>>> the dependee, so add a function to parse all ACPI Devices and check if
>>>> the include the handle of the dependee device in their _DEP buffer.
>>> What exactly do you need this for?
>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
>> refer to those INT3472's in their _DEP method. The driver binds to the
>> INT3472 device, we need to find the sensors dependent on them.
>>
> Well, this is an interesting concept. :-)
>
> Why does _DEP need to be used for that?  Isn't there any other way to
> look up the dependent sensors?


If there is, I'm not aware of it, I don't see a reference to the sensor
in the INT3472 device (named "PMI0", with the corresponding sensor being
"CAM0") in DSDT  [1]

>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
>>>
>>> Note that supplier drivers may remove entries from there, but does
>>> that matter for your use case?
>> Ah - that may work, yes. Thank you, let me test that.
> Even if that doesn't work right away, but it can be made work, I would
> very much prefer that to the driver parsing _DEP for every device in
> the namespace by itself.


Alright; I haven't looked too closely yet, but I think an iterator over
acpi_dep_list exported from the ACPI subsystem would also work in a
pretty similar way to the function introduced in this patch does,
without much work


[1]
https://gist.githubusercontent.com/djrscally/e64d112180517352fa3392878b0f4a7d/raw/88b90b3ea4204fd7845257b6666fdade47cc2981/dsdt.dsl
Daniel Scally Jan. 21, 2021, 9:47 a.m. UTC | #16
Hi Rafael

On 19/01/2021 13:15, Rafael J. Wysocki wrote:
> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
>>>> specification intends. We need to be able to find those devices "from"
>>>> the dependee, so add a function to parse all ACPI Devices and check if
>>>> the include the handle of the dependee device in their _DEP buffer.
>>> What exactly do you need this for?
>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
>> refer to those INT3472's in their _DEP method. The driver binds to the
>> INT3472 device, we need to find the sensors dependent on them.
>>
> Well, this is an interesting concept. :-)
>
> Why does _DEP need to be used for that?  Isn't there any other way to
> look up the dependent sensors?
>
>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
>>>
>>> Note that supplier drivers may remove entries from there, but does
>>> that matter for your use case?
>> Ah - that may work, yes. Thank you, let me test that.
> Even if that doesn't work right away, but it can be made work, I would
> very much prefer that to the driver parsing _DEP for every device in
> the namespace by itself.


This does work; do you prefer it in scan.c, or in utils.c (in which case
with acpi_dep_list declared as external var in internal.h)?
Daniel Scally Jan. 21, 2021, 12:04 p.m. UTC | #17
On 21/01/2021 11:58, Rafael J. Wysocki wrote:
> On Thu, Jan 21, 2021 at 10:47 AM Daniel Scally <djrscally@gmail.com> wrote:
>> Hi Rafael
>>
>> On 19/01/2021 13:15, Rafael J. Wysocki wrote:
>>> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
>>>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
>>>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
>>>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
>>>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
>>>>>> specification intends. We need to be able to find those devices "from"
>>>>>> the dependee, so add a function to parse all ACPI Devices and check if
>>>>>> the include the handle of the dependee device in their _DEP buffer.
>>>>> What exactly do you need this for?
>>>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
>>>> refer to those INT3472's in their _DEP method. The driver binds to the
>>>> INT3472 device, we need to find the sensors dependent on them.
>>>>
>>> Well, this is an interesting concept. :-)
>>>
>>> Why does _DEP need to be used for that?  Isn't there any other way to
>>> look up the dependent sensors?
>>>
>>>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
>>>>>
>>>>> Note that supplier drivers may remove entries from there, but does
>>>>> that matter for your use case?
>>>> Ah - that may work, yes. Thank you, let me test that.
>>> Even if that doesn't work right away, but it can be made work, I would
>>> very much prefer that to the driver parsing _DEP for every device in
>>> the namespace by itself.
>>
>> This does work; do you prefer it in scan.c, or in utils.c (in which case
>> with acpi_dep_list declared as external var in internal.h)?
> Let's put it in scan.c for now, because there is the lock protecting
> the list in there too.
>
> How do you want to implement this?  Something like "walk the list and
> run a callback for the matching entries" or do you have something else
> in mind?


Something like this (though with a mutex_lock()). It could be simplified
by dropping the prev stuff, but we have seen INT3472 devices with
multiple sensors declaring themselves dependent on the same device


struct acpi_device *
acpi_dev_get_next_dependent_dev(struct acpi_device *supplier,
                struct acpi_device *prev)
{
    struct acpi_dep_data *dep;
    struct acpi_device *adev;
    int ret;

    if (!supplier)
        return ERR_PTR(-EINVAL);

    if (prev) {
        /*
         * We need to find the previous device in the list, so we know
         * where to start iterating from.
         */
        list_for_each_entry(dep, &acpi_dep_list, node)
            if (dep->consumer == prev->handle &&
                dep->supplier == supplier->handle)
                break;

        dep = list_next_entry(dep, node);
    } else {
        dep = list_first_entry(&acpi_dep_list, struct acpi_dep_data,
                       node);
    }


    list_for_each_entry_from(dep, &acpi_dep_list, node) {
        if (dep->supplier == supplier->handle) {
            ret = acpi_bus_get_device(dep->consumer, &adev);
            if (ret)
                return ERR_PTR(ret);

            return adev;
        }
    }

    return NULL;
}
Rafael J. Wysocki Jan. 21, 2021, 2:39 p.m. UTC | #18
On Thu, Jan 21, 2021 at 1:04 PM Daniel Scally <djrscally@gmail.com> wrote:
>

>

> On 21/01/2021 11:58, Rafael J. Wysocki wrote:

> > On Thu, Jan 21, 2021 at 10:47 AM Daniel Scally <djrscally@gmail.com> wrote:

> >> Hi Rafael

> >>

> >> On 19/01/2021 13:15, Rafael J. Wysocki wrote:

> >>> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:

> >>>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:

> >>>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:

> >>>>>> In some ACPI tables we encounter, devices use the _DEP method to assert

> >>>>>> a dependence on other ACPI devices as opposed to the OpRegions that the

> >>>>>> specification intends. We need to be able to find those devices "from"

> >>>>>> the dependee, so add a function to parse all ACPI Devices and check if

> >>>>>> the include the handle of the dependee device in their _DEP buffer.

> >>>>> What exactly do you need this for?

> >>>> So, in our DSDT we have devices with _HID INT3472, plus sensors which

> >>>> refer to those INT3472's in their _DEP method. The driver binds to the

> >>>> INT3472 device, we need to find the sensors dependent on them.

> >>>>

> >>> Well, this is an interesting concept. :-)

> >>>

> >>> Why does _DEP need to be used for that?  Isn't there any other way to

> >>> look up the dependent sensors?

> >>>

> >>>>> Would it be practical to look up the suppliers in acpi_dep_list instead?

> >>>>>

> >>>>> Note that supplier drivers may remove entries from there, but does

> >>>>> that matter for your use case?

> >>>> Ah - that may work, yes. Thank you, let me test that.

> >>> Even if that doesn't work right away, but it can be made work, I would

> >>> very much prefer that to the driver parsing _DEP for every device in

> >>> the namespace by itself.

> >>

> >> This does work; do you prefer it in scan.c, or in utils.c (in which case

> >> with acpi_dep_list declared as external var in internal.h)?

> > Let's put it in scan.c for now, because there is the lock protecting

> > the list in there too.

> >

> > How do you want to implement this?  Something like "walk the list and

> > run a callback for the matching entries" or do you have something else

> > in mind?

>

>

> Something like this (though with a mutex_lock()). It could be simplified

> by dropping the prev stuff, but we have seen INT3472 devices with

> multiple sensors declaring themselves dependent on the same device

>

>

> struct acpi_device *

> acpi_dev_get_next_dependent_dev(struct acpi_device *supplier,

>                 struct acpi_device *prev)

> {

>     struct acpi_dep_data *dep;

>     struct acpi_device *adev;

>     int ret;

>

>     if (!supplier)

>         return ERR_PTR(-EINVAL);

>

>     if (prev) {

>         /*

>          * We need to find the previous device in the list, so we know

>          * where to start iterating from.

>          */

>         list_for_each_entry(dep, &acpi_dep_list, node)

>             if (dep->consumer == prev->handle &&

>                 dep->supplier == supplier->handle)

>                 break;

>

>         dep = list_next_entry(dep, node);

>     } else {

>         dep = list_first_entry(&acpi_dep_list, struct acpi_dep_data,

>                        node);

>     }

>

>

>     list_for_each_entry_from(dep, &acpi_dep_list, node) {

>         if (dep->supplier == supplier->handle) {

>             ret = acpi_bus_get_device(dep->consumer, &adev);

>             if (ret)

>                 return ERR_PTR(ret);

>

>             return adev;

>         }

>     }

>

>     return NULL;

> }


That would work I think, but would it be practical to modify
acpi_walk_dep_device_list() so that it runs a callback for every
consumer found instead of or in addition to the "delete from the list
and free the entry" operation?
Rafael J. Wysocki Jan. 21, 2021, 6:08 p.m. UTC | #19
On Thu, Jan 21, 2021 at 5:34 PM Daniel Scally <djrscally@gmail.com> wrote:
>
>
> On 21/01/2021 14:39, Rafael J. Wysocki wrote:
> > On Thu, Jan 21, 2021 at 1:04 PM Daniel Scally <djrscally@gmail.com> wrote:
> >>
> >> On 21/01/2021 11:58, Rafael J. Wysocki wrote:
> >>> On Thu, Jan 21, 2021 at 10:47 AM Daniel Scally <djrscally@gmail.com> wrote:
> >>>> Hi Rafael
> >>>>
> >>>> On 19/01/2021 13:15, Rafael J. Wysocki wrote:
> >>>>> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
> >>>>>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
> >>>>>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
> >>>>>>>> specification intends. We need to be able to find those devices "from"
> >>>>>>>> the dependee, so add a function to parse all ACPI Devices and check if
> >>>>>>>> the include the handle of the dependee device in their _DEP buffer.
> >>>>>>> What exactly do you need this for?
> >>>>>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
> >>>>>> refer to those INT3472's in their _DEP method. The driver binds to the
> >>>>>> INT3472 device, we need to find the sensors dependent on them.
> >>>>>>
> >>>>> Well, this is an interesting concept. :-)
> >>>>>
> >>>>> Why does _DEP need to be used for that?  Isn't there any other way to
> >>>>> look up the dependent sensors?
> >>>>>
> >>>>>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
> >>>>>>>
> >>>>>>> Note that supplier drivers may remove entries from there, but does
> >>>>>>> that matter for your use case?
> >>>>>> Ah - that may work, yes. Thank you, let me test that.
> >>>>> Even if that doesn't work right away, but it can be made work, I would
> >>>>> very much prefer that to the driver parsing _DEP for every device in
> >>>>> the namespace by itself.
> >>>> This does work; do you prefer it in scan.c, or in utils.c (in which case
> >>>> with acpi_dep_list declared as external var in internal.h)?
> >>> Let's put it in scan.c for now, because there is the lock protecting
> >>> the list in there too.
> >>>
> >>> How do you want to implement this?  Something like "walk the list and
> >>> run a callback for the matching entries" or do you have something else
> >>> in mind?
> >>
> >> Something like this (though with a mutex_lock()). It could be simplified
> >> by dropping the prev stuff, but we have seen INT3472 devices with
> >> multiple sensors declaring themselves dependent on the same device
> >>
> >>
> >> struct acpi_device *
> >> acpi_dev_get_next_dependent_dev(struct acpi_device *supplier,
> >>                 struct acpi_device *prev)
> >> {
> >>     struct acpi_dep_data *dep;
> >>     struct acpi_device *adev;
> >>     int ret;
> >>
> >>     if (!supplier)
> >>         return ERR_PTR(-EINVAL);
> >>
> >>     if (prev) {
> >>         /*
> >>          * We need to find the previous device in the list, so we know
> >>          * where to start iterating from.
> >>          */
> >>         list_for_each_entry(dep, &acpi_dep_list, node)
> >>             if (dep->consumer == prev->handle &&
> >>                 dep->supplier == supplier->handle)
> >>                 break;
> >>
> >>         dep = list_next_entry(dep, node);
> >>     } else {
> >>         dep = list_first_entry(&acpi_dep_list, struct acpi_dep_data,
> >>                        node);
> >>     }
> >>
> >>
> >>     list_for_each_entry_from(dep, &acpi_dep_list, node) {
> >>         if (dep->supplier == supplier->handle) {
> >>             ret = acpi_bus_get_device(dep->consumer, &adev);
> >>             if (ret)
> >>                 return ERR_PTR(ret);
> >>
> >>             return adev;
> >>         }
> >>     }
> >>
> >>     return NULL;
> >> }
> > That would work I think, but would it be practical to modify
> > acpi_walk_dep_device_list() so that it runs a callback for every
> > consumer found instead of or in addition to the "delete from the list
> > and free the entry" operation?
>
>
> I think that this would work fine, if that's the way you want to go.
> We'd just need to move everything inside the if (dep->supplier ==
> handle) block to a new callback, and for my purposes I think also add a
> way to stop parsing the list from the callback (so like have the
> callbacks return int and stop parsing on a non-zero return). Do you want
> to expose that ability to pass a callback outside of ACPI?

Yes.

> Or just export helpers to call each of the callbacks (one to fetch the next
> dependent device, one to decrement the unmet dependencies counter)

If you can run a callback for every matching entry, you don't really
need to have a callback to return the next matching entry.  You can do
stuff for all of them in one go (note that it probably is not a good
idea to run the callback under the lock, so the for loop currently in
there is not really suitable for that).

> Otherwise, I'd just need to update the 5 users of that function either
> to use the new helper or else to also pass the decrement dependencies
> callback.

Or have a wrapper around it passing the decrement dependencies
callback for the "typical" users.
Wolfram Sang Jan. 28, 2021, 9 a.m. UTC | #20
> > There's a real danger of a memory leak, as the function name sounds very

> > similar to dev_name() or acpi_dev_name() and those don't allocate

> > memory. I'm not sure what a better name would be, but given that this

> > function is only used in patch 6/7 and not in the I2C subsystem itself,

> > I wonder if we should inline this kasprintf() call in the caller and

> > drop this patch.

> 

> IMO if this is a one-off usage, it's better to open-code it.


Sounds reasonable to me, too.
Wolfram Sang Jan. 28, 2021, 9:17 a.m. UTC | #21
> Just to clarify; "open-code" meaning inline it in the caller like

> Laurent said, right?


Yes.
Daniel Scally Jan. 28, 2021, 9:22 a.m. UTC | #22
On 28/01/2021 09:17, Wolfram Sang wrote:
>> Just to clarify; "open-code" meaning inline it in the caller like

>> Laurent said, right?

> Yes.

>

Thanks - will do that and drop this one then
Daniel Scally Feb. 2, 2021, 9:58 a.m. UTC | #23
Hi Rafael

On 21/01/2021 21:06, Daniel Scally wrote:
> 
> On 21/01/2021 18:08, Rafael J. Wysocki wrote:
>> On Thu, Jan 21, 2021 at 5:34 PM Daniel Scally <djrscally@gmail.com> wrote:
>>>
>>> On 21/01/2021 14:39, Rafael J. Wysocki wrote:
>>>> On Thu, Jan 21, 2021 at 1:04 PM Daniel Scally <djrscally@gmail.com> wrote:
>>>>> On 21/01/2021 11:58, Rafael J. Wysocki wrote:
>>>>>> On Thu, Jan 21, 2021 at 10:47 AM Daniel Scally <djrscally@gmail.com> wrote:
>>>>>>> Hi Rafael
>>>>>>>
>>>>>>> On 19/01/2021 13:15, Rafael J. Wysocki wrote:
>>>>>>>> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
>>>>>>>>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
>>>>>>>>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
>>>>>>>>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
>>>>>>>>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
>>>>>>>>>>> specification intends. We need to be able to find those devices "from"
>>>>>>>>>>> the dependee, so add a function to parse all ACPI Devices and check if
>>>>>>>>>>> the include the handle of the dependee device in their _DEP buffer.
>>>>>>>>>> What exactly do you need this for?
>>>>>>>>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
>>>>>>>>> refer to those INT3472's in their _DEP method. The driver binds to the
>>>>>>>>> INT3472 device, we need to find the sensors dependent on them.
>>>>>>>>>
>>>>>>>> Well, this is an interesting concept. :-)
>>>>>>>>
>>>>>>>> Why does _DEP need to be used for that?  Isn't there any other way to
>>>>>>>> look up the dependent sensors?
>>>>>>>>
>>>>>>>>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
>>>>>>>>>>
>>>>>>>>>> Note that supplier drivers may remove entries from there, but does
>>>>>>>>>> that matter for your use case?
>>>>>>>>> Ah - that may work, yes. Thank you, let me test that.
>>>>>>>> Even if that doesn't work right away, but it can be made work, I would
>>>>>>>> very much prefer that to the driver parsing _DEP for every device in
>>>>>>>> the namespace by itself.
>>>>>>> This does work; do you prefer it in scan.c, or in utils.c (in which case
>>>>>>> with acpi_dep_list declared as external var in internal.h)?
>>>>>> Let's put it in scan.c for now, because there is the lock protecting
>>>>>> the list in there too.
>>>>>>
>>>>>> How do you want to implement this?  Something like "walk the list and
>>>>>> run a callback for the matching entries" or do you have something else
>>>>>> in mind?
>>>>> Something like this (though with a mutex_lock()). It could be simplified
>>>>> by dropping the prev stuff, but we have seen INT3472 devices with
>>>>> multiple sensors declaring themselves dependent on the same device
>>>>>
>>>>>
>>>>> struct acpi_device *
>>>>> acpi_dev_get_next_dependent_dev(struct acpi_device *supplier,
>>>>>                 struct acpi_device *prev)
>>>>> {
>>>>>     struct acpi_dep_data *dep;
>>>>>     struct acpi_device *adev;
>>>>>     int ret;
>>>>>
>>>>>     if (!supplier)
>>>>>         return ERR_PTR(-EINVAL);
>>>>>
>>>>>     if (prev) {
>>>>>         /*
>>>>>          * We need to find the previous device in the list, so we know
>>>>>          * where to start iterating from.
>>>>>          */
>>>>>         list_for_each_entry(dep, &acpi_dep_list, node)
>>>>>             if (dep->consumer == prev->handle &&
>>>>>                 dep->supplier == supplier->handle)
>>>>>                 break;
>>>>>
>>>>>         dep = list_next_entry(dep, node);
>>>>>     } else {
>>>>>         dep = list_first_entry(&acpi_dep_list, struct acpi_dep_data,
>>>>>                        node);
>>>>>     }
>>>>>
>>>>>
>>>>>     list_for_each_entry_from(dep, &acpi_dep_list, node) {
>>>>>         if (dep->supplier == supplier->handle) {
>>>>>             ret = acpi_bus_get_device(dep->consumer, &adev);
>>>>>             if (ret)
>>>>>                 return ERR_PTR(ret);
>>>>>
>>>>>             return adev;
>>>>>         }
>>>>>     }
>>>>>
>>>>>     return NULL;
>>>>> }
>>>> That would work I think, but would it be practical to modify
>>>> acpi_walk_dep_device_list() so that it runs a callback for every
>>>> consumer found instead of or in addition to the "delete from the list
>>>> and free the entry" operation?
>>>
>>> I think that this would work fine, if that's the way you want to go.
>>> We'd just need to move everything inside the if (dep->supplier ==
>>> handle) block to a new callback, and for my purposes I think also add a
>>> way to stop parsing the list from the callback (so like have the
>>> callbacks return int and stop parsing on a non-zero return). Do you want
>>> to expose that ability to pass a callback outside of ACPI?
>> Yes.
>>
>>> Or just export helpers to call each of the callbacks (one to fetch the next
>>> dependent device, one to decrement the unmet dependencies counter)
>> If you can run a callback for every matching entry, you don't really
>> need to have a callback to return the next matching entry.  You can do
>> stuff for all of them in one go
> 
> Well it my case it's more to return a pointer to the dep->consumer's
> acpi_device for a matching entry, so my idea was where there's multiple
> dependents you could use this as an iterator...but it could just be
> extended to that if needed later; I don't actually need to do it right now.
> 
> 
>> note that it probably is not a good
>> idea to run the callback under the lock, so the for loop currently in
>> there is not really suitable for that
> 
> No problem;  I'll tweak that then

Slightly walking back my "No problem" here; as I understand this there's
kinda two options:

1. Walk over the (locked) list, when a match is found unlock, run the
callback and re-lock.

The problem with that idea is unless I'm mistaken there's no guarantee
that the .next pointer is still valid then (even using the *_safe()
methods) because either the next or the next + 1 entry could have been
removed whilst the list was unlocked and the callback was being ran, so
this seems a little unsafe.

2. Walk over the (locked) list twice, the first time counting matching
entries and using that to allocate a temporary buffer, then walk again
to store the matching entries into the buffer. Finally, run the callback
for everything in the buffer, free it and return.

Obviously that's a lot less efficient than the current function, which
isn't particularly palatable.

Apologies if I've missed a better option that would work fine; but
failing that do you still want me to go ahead and change
acpi_walk_dep_device_list() to do this (I'd choose #2 of the above), or
fallback to using acpi_dev_get_next_dependent_dev() described above? If
the latter, does acpi_walk_dep_device_list() maybe need re-naming to
make clear it's not a generalised function?
Andy Shevchenko Feb. 2, 2021, 11:27 a.m. UTC | #24
On Tue, Feb 02, 2021 at 09:58:17AM +0000, Daniel Scally wrote:
> On 21/01/2021 21:06, Daniel Scally wrote:
> > On 21/01/2021 18:08, Rafael J. Wysocki wrote:

...

> > No problem;  I'll tweak that then
> 
> Slightly walking back my "No problem" here; as I understand this there's
> kinda two options:
> 
> 1. Walk over the (locked) list, when a match is found unlock, run the
> callback and re-lock.
> 
> The problem with that idea is unless I'm mistaken there's no guarantee
> that the .next pointer is still valid then (even using the *_safe()
> methods) because either the next or the next + 1 entry could have been
> removed whilst the list was unlocked and the callback was being ran, so
> this seems a little unsafe.

It's easy to solve.
See an example in deferred_probe_work_func().

https://elixir.bootlin.com/linux/latest/source/drivers/base/dd.c#L75

> 2. Walk over the (locked) list twice, the first time counting matching
> entries and using that to allocate a temporary buffer, then walk again
> to store the matching entries into the buffer. Finally, run the callback
> for everything in the buffer, free it and return.
> 
> Obviously that's a lot less efficient than the current function, which
> isn't particularly palatable.
> 
> Apologies if I've missed a better option that would work fine; but
> failing that do you still want me to go ahead and change
> acpi_walk_dep_device_list() to do this (I'd choose #2 of the above), or
> fallback to using acpi_dev_get_next_dependent_dev() described above? If
> the latter, does acpi_walk_dep_device_list() maybe need re-naming to
> make clear it's not a generalised function?
Rafael J. Wysocki Feb. 2, 2021, 2:02 p.m. UTC | #25
On Tue, Feb 2, 2021 at 10:58 AM Daniel Scally <djrscally@gmail.com> wrote:
>
> Hi Rafael
>
> On 21/01/2021 21:06, Daniel Scally wrote:
> >
> > On 21/01/2021 18:08, Rafael J. Wysocki wrote:
> >> On Thu, Jan 21, 2021 at 5:34 PM Daniel Scally <djrscally@gmail.com> wrote:
> >>>
> >>> On 21/01/2021 14:39, Rafael J. Wysocki wrote:
> >>>> On Thu, Jan 21, 2021 at 1:04 PM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>> On 21/01/2021 11:58, Rafael J. Wysocki wrote:
> >>>>>> On Thu, Jan 21, 2021 at 10:47 AM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>>>> Hi Rafael
> >>>>>>>
> >>>>>>> On 19/01/2021 13:15, Rafael J. Wysocki wrote:
> >>>>>>>> On Mon, Jan 18, 2021 at 9:51 PM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>>>>>> On 18/01/2021 16:14, Rafael J. Wysocki wrote:
> >>>>>>>>>> On Mon, Jan 18, 2021 at 1:37 AM Daniel Scally <djrscally@gmail.com> wrote:
> >>>>>>>>>>> In some ACPI tables we encounter, devices use the _DEP method to assert
> >>>>>>>>>>> a dependence on other ACPI devices as opposed to the OpRegions that the
> >>>>>>>>>>> specification intends. We need to be able to find those devices "from"
> >>>>>>>>>>> the dependee, so add a function to parse all ACPI Devices and check if
> >>>>>>>>>>> the include the handle of the dependee device in their _DEP buffer.
> >>>>>>>>>> What exactly do you need this for?
> >>>>>>>>> So, in our DSDT we have devices with _HID INT3472, plus sensors which
> >>>>>>>>> refer to those INT3472's in their _DEP method. The driver binds to the
> >>>>>>>>> INT3472 device, we need to find the sensors dependent on them.
> >>>>>>>>>
> >>>>>>>> Well, this is an interesting concept. :-)
> >>>>>>>>
> >>>>>>>> Why does _DEP need to be used for that?  Isn't there any other way to
> >>>>>>>> look up the dependent sensors?
> >>>>>>>>
> >>>>>>>>>> Would it be practical to look up the suppliers in acpi_dep_list instead?
> >>>>>>>>>>
> >>>>>>>>>> Note that supplier drivers may remove entries from there, but does
> >>>>>>>>>> that matter for your use case?
> >>>>>>>>> Ah - that may work, yes. Thank you, let me test that.
> >>>>>>>> Even if that doesn't work right away, but it can be made work, I would
> >>>>>>>> very much prefer that to the driver parsing _DEP for every device in
> >>>>>>>> the namespace by itself.
> >>>>>>> This does work; do you prefer it in scan.c, or in utils.c (in which case
> >>>>>>> with acpi_dep_list declared as external var in internal.h)?
> >>>>>> Let's put it in scan.c for now, because there is the lock protecting
> >>>>>> the list in there too.
> >>>>>>
> >>>>>> How do you want to implement this?  Something like "walk the list and
> >>>>>> run a callback for the matching entries" or do you have something else
> >>>>>> in mind?
> >>>>> Something like this (though with a mutex_lock()). It could be simplified
> >>>>> by dropping the prev stuff, but we have seen INT3472 devices with
> >>>>> multiple sensors declaring themselves dependent on the same device
> >>>>>
> >>>>>
> >>>>> struct acpi_device *
> >>>>> acpi_dev_get_next_dependent_dev(struct acpi_device *supplier,
> >>>>>                 struct acpi_device *prev)
> >>>>> {
> >>>>>     struct acpi_dep_data *dep;
> >>>>>     struct acpi_device *adev;
> >>>>>     int ret;
> >>>>>
> >>>>>     if (!supplier)
> >>>>>         return ERR_PTR(-EINVAL);
> >>>>>
> >>>>>     if (prev) {
> >>>>>         /*
> >>>>>          * We need to find the previous device in the list, so we know
> >>>>>          * where to start iterating from.
> >>>>>          */
> >>>>>         list_for_each_entry(dep, &acpi_dep_list, node)
> >>>>>             if (dep->consumer == prev->handle &&
> >>>>>                 dep->supplier == supplier->handle)
> >>>>>                 break;
> >>>>>
> >>>>>         dep = list_next_entry(dep, node);
> >>>>>     } else {
> >>>>>         dep = list_first_entry(&acpi_dep_list, struct acpi_dep_data,
> >>>>>                        node);
> >>>>>     }
> >>>>>
> >>>>>
> >>>>>     list_for_each_entry_from(dep, &acpi_dep_list, node) {
> >>>>>         if (dep->supplier == supplier->handle) {
> >>>>>             ret = acpi_bus_get_device(dep->consumer, &adev);
> >>>>>             if (ret)
> >>>>>                 return ERR_PTR(ret);
> >>>>>
> >>>>>             return adev;
> >>>>>         }
> >>>>>     }
> >>>>>
> >>>>>     return NULL;
> >>>>> }
> >>>> That would work I think, but would it be practical to modify
> >>>> acpi_walk_dep_device_list() so that it runs a callback for every
> >>>> consumer found instead of or in addition to the "delete from the list
> >>>> and free the entry" operation?
> >>>
> >>> I think that this would work fine, if that's the way you want to go.
> >>> We'd just need to move everything inside the if (dep->supplier ==
> >>> handle) block to a new callback, and for my purposes I think also add a
> >>> way to stop parsing the list from the callback (so like have the
> >>> callbacks return int and stop parsing on a non-zero return). Do you want
> >>> to expose that ability to pass a callback outside of ACPI?
> >> Yes.
> >>
> >>> Or just export helpers to call each of the callbacks (one to fetch the next
> >>> dependent device, one to decrement the unmet dependencies counter)
> >> If you can run a callback for every matching entry, you don't really
> >> need to have a callback to return the next matching entry.  You can do
> >> stuff for all of them in one go
> >
> > Well it my case it's more to return a pointer to the dep->consumer's
> > acpi_device for a matching entry, so my idea was where there's multiple
> > dependents you could use this as an iterator...but it could just be
> > extended to that if needed later; I don't actually need to do it right now.
> >
> >
> >> note that it probably is not a good
> >> idea to run the callback under the lock, so the for loop currently in
> >> there is not really suitable for that
> >
> > No problem;  I'll tweak that then
>
> Slightly walking back my "No problem" here; as I understand this there's
> kinda two options:
>
> 1. Walk over the (locked) list, when a match is found unlock, run the
> callback and re-lock.

That's what I was thinking about.

> The problem with that idea is unless I'm mistaken there's no guarantee
> that the .next pointer is still valid then (even using the *_safe()
> methods) because either the next or the next + 1 entry could have been
> removed whilst the list was unlocked and the callback was being ran, so
> this seems a little unsafe.

This can be addressed by rotating the list while walking it, but that
becomes problematic if there are concurrent walkers.

OK, I guess running the callback under the lock is not really a big
deal (and for the deletion case this is actually necessary), so let's
do that.