All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data
@ 2021-10-08 16:21 Hans de Goede
  2021-10-08 16:21 ` [PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function Hans de Goede
                   ` (11 more replies)
  0 siblings, 12 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

Hi All,

This patch series is a rework/rewrite of Daniel Scally's earlier
attempts at adding support for camera sensor connected to a
TPS68470 PMIC on x86/ACPI devices.

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node, but on ACPI this info is missing.

This series worksaround this by providing platform_data with the info to
the TPS68470 clk/regulator MFD cells.

Patches 1 - 3 deal with a probe-ordering problem this introduces, since the
lookups are only registered when the provider-driver binds, trying to get
these clks/regulators before then results in a -ENOENT error for clks and
a dummy regulator for regulators. See the patches for more details.

Patch 4 adds a header file which adds tps68470_clk_platform_data and
tps68470_regulator_platform_data structs. The futher patches depend on
this new header file.

Patch 5 + 6 add the TPS68470 clk and regulator drivers

Patches 7 - 12 Modify the INT3472 driver which instantiates the MFD cells to
provide the necessary platform-data.

Assuming this series is acceptable to everyone, we need to talk about how
to merge this.

Rafael, can you provide an immutable branch with
"[PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function"
on there? Then the media subsys-maintaines can merge that and then
merge patch 2 + 3 on top.

For "[PATCH 04/12] platform_data: Add linux/platform_data/tps68470.h file",
which all further patches depend on I plan to provide an immutable branch
myself (once it has been reviewed), which the clk / regulator maintainers
can then merge before merging the clk / regulator driver which depends on
this.

Regards,

Hans


Daniel Scally (1):
  platform/x86: int3472: Enable I2c daisy chain

Hans de Goede (11):
  ACPI: Add has_unmet_acpi_deps() helper function
  media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  media: i2c: ov5693: Add an has_unmet_acpi_deps() check
  platform_data: Add linux/platform_data/tps68470.h file
  regulator: Introduce tps68470-regulator driver
  clk: Introduce clk-tps68470 driver
  platform/x86: int3472: Split into 2 drivers
  platform/x86: int3472: Add get_sensor_adev_and_name() helper
  platform/x86: int3472: Pass tps68470_clk_platform_data to the
    tps68470-regulator MFD-cell
  platform/x86: int3472: Pass tps68470_regulator_platform_data to the
    tps68470-regulator MFD-cell
  platform/x86: int3472: Call acpi_dev_clear_dependencies() on
    successful probe

 drivers/clk/Kconfig                           |   6 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-tps68470.c                    | 257 ++++++++++++++++++
 drivers/media/i2c/ov5693.c                    |   3 +
 drivers/media/i2c/ov8865.c                    |   3 +
 drivers/platform/x86/intel/int3472/Makefile   |   9 +-
 ...lk_and_regulator.c => clk_and_regulator.c} |   2 +-
 drivers/platform/x86/intel/int3472/common.c   |  82 ++++++
 .../{intel_skl_int3472_common.h => common.h}  |   6 +-
 ...ntel_skl_int3472_discrete.c => discrete.c} |  51 ++--
 .../intel/int3472/intel_skl_int3472_common.c  | 106 --------
 ...ntel_skl_int3472_tps68470.c => tps68470.c} |  88 +++++-
 drivers/platform/x86/intel/int3472/tps68470.h |  25 ++
 .../x86/intel/int3472/tps68470_board_data.c   | 118 ++++++++
 drivers/regulator/Kconfig                     |   9 +
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/tps68470-regulator.c        | 194 +++++++++++++
 include/linux/acpi.h                          |  12 +
 include/linux/mfd/tps68470.h                  |  11 +
 include/linux/platform_data/tps68470.h        |  35 +++
 20 files changed, 873 insertions(+), 146 deletions(-)
 create mode 100644 drivers/clk/clk-tps68470.c
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_clk_and_regulator.c => clk_and_regulator.c} (99%)
 create mode 100644 drivers/platform/x86/intel/int3472/common.c
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_common.h => common.h} (94%)
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_discrete.c => discrete.c} (91%)
 delete mode 100644 drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_tps68470.c => tps68470.c} (58%)
 create mode 100644 drivers/platform/x86/intel/int3472/tps68470.h
 create mode 100644 drivers/platform/x86/intel/int3472/tps68470_board_data.c
 create mode 100644 drivers/regulator/tps68470-regulator.c
 create mode 100644 include/linux/platform_data/tps68470.h

-- 
2.31.1


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check Hans de Goede
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.

To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.

This causes problems with the probe ordering wrt drivers for consumers
of these clks/regulators. Since the lookups are only registered when the
provider-driver binds, trying to get these clks/regulators before then
results in a -ENOENT error for clks and a dummy regulator for regulators.

ACPI-devices may have dependencies at the ACPI level (_DEP method), these
are tracked by the ACPI core, but ACPI devices will be instantiated during
boot even if they have unmet ACPI-dependencies because the _DEPs may never
get fully resolved (under Linux).

These ACPI-dependencies may be useful to solve the probe ordeing, for
example on laptops which use MIPI camera sensors connected to an Intel IPU3
for there cameras, a TI TPS68470 PMIC may be used to provide a clk +
regulators for the sensors. This TPS68470 PMIC is described using an
ACPI-device with a HID of INT3472 and the sensors have a _DEP pointing to
the INT3472 device which describes their PMIC.

The sensor drivers can use the ACPI core dependency tracking to delay
binding (return -EPROBE_DEFER) until the Linux INT3472 driver has bound
and registered the clks + regulator including lookup info, thus solving
the probe ordering issue.

Add a has_unmet_acpi_deps() which drivers can use to check if all
dependencies requested enumerated by the _DEP method have been met.

Note this relies on all drivers for devices listed in _DEP (for a
device which driver uses has_unmet_acpi_deps()) to call
acpi_dev_clear_dependencies() at the end of their probe() function.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/linux/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 974d497a897d..7ff35d483d04 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -86,6 +86,13 @@ static inline bool has_acpi_companion(struct device *dev)
 	return is_acpi_device_node(dev->fwnode);
 }
 
+static inline bool has_unmet_acpi_deps(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	return adev ? adev->dep_unmet : false;
+}
+
 static inline void acpi_preset_companion(struct device *dev,
 					 struct acpi_device *parent, u64 addr)
 {
@@ -802,6 +809,11 @@ static inline bool has_acpi_companion(struct device *dev)
 	return false;
 }
 
+static inline bool has_unmet_acpi_deps(struct device *dev)
+{
+	return false;
+}
+
 static inline void acpi_preset_companion(struct device *dev,
 					 struct acpi_device *parent, u64 addr)
 {
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
  2021-10-08 16:21 ` [PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 18:41   ` Laurent Pinchart
  2021-10-08 16:21 ` [PATCH 03/12] media: i2c: ov5693: " Hans de Goede
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.

To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.

This causes problems with the probe ordering of the ov8865 driver vs the
drivers for these clks/regulators. Since the lookups are only registered
when the provider-driver binds, trying to get these clks/regulators before
then results in a -ENOENT error for clks and a dummy regulator for regs.

On ACPI/x86 where this is a problem, the ov8865 ACPI fw-nodes have a _DEP
dependency on the INT3472 ACPI fw-node which describes the hardware which
provides the clks/regulators.

The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
_DEP has been "met" when all the clks/regulators have been setup.

Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
and return -EPROBE_DEFER if this returns true, so that we wait for
the clk/regulator setup to be done before continuing with probing.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/media/i2c/ov8865.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index ce4e0ae2c4d3..fd18d1256f78 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2978,6 +2978,9 @@ static int ov8865_probe(struct i2c_client *client)
 	unsigned int i;
 	int ret;
 
+	if (has_unmet_acpi_deps(dev))
+		return -EPROBE_DEFER;
+
 	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
 	if (!sensor)
 		return -ENOMEM;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 03/12] media: i2c: ov5693: Add an has_unmet_acpi_deps() check
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
  2021-10-08 16:21 ` [PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function Hans de Goede
  2021-10-08 16:21 ` [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 04/12] platform_data: Add linux/platform_data/tps68470.h file Hans de Goede
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.

To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the clks/regulators
when registering these.

This causes problems with the probe ordering of the ov5693 driver vs the
drivers for these clks/regulators. Since the lookups are only registered
when the provider-driver binds, trying to get these clks/regulators before
then results in a -ENOENT error for clks and a dummy regulator for regs.

On ACPI/x86 where this is a problem, the ov5693 ACPI fw-nodes have a _DEP
dependency on the INT3472 ACPI fw-node which describes the hardware which
provides the clks/regulators.

The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
_DEP has been "met" when all the clks/regulators have been setup.

Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
and return -EPROBE_DEFER if this returns true, so that we wait for
the clk/regulator setup to be done before continuing with probing.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/media/i2c/ov5693.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
index 1320063c6747..886649670efb 100644
--- a/drivers/media/i2c/ov5693.c
+++ b/drivers/media/i2c/ov5693.c
@@ -1415,6 +1415,9 @@ static int ov5693_probe(struct i2c_client *client)
 	if (!endpoint)
 		return -EPROBE_DEFER;
 
+	if (has_unmet_acpi_deps(&client->dev))
+		return -EPROBE_DEFER;
+
 	ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
 	if (!ov5693)
 		return -ENOMEM;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 04/12] platform_data: Add linux/platform_data/tps68470.h file
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (2 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 03/12] media: i2c: ov5693: " Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 05/12] regulator: Introduce tps68470-regulator driver Hans de Goede
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.

To work around cases where this info is not present in the firmware tables,
which is often the case on x86/ACPI devices, both frameworks allow the
provider-driver to attach info about consumers to the provider-device
during probe/registration of the provider device.

The TI TPS68470 PMIC is used x86/ACPI devices with the consumer-info
missing from the ACPI tables. Thus the tps68470-clk and tps68470-regulator
drivers must provide the consumer-info at probe time.

Define tps68470_clk_platform_data and tps68470_regulator_platform_data
structs to allow the x86 platform code to pass the necessary consumer info
to these drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/linux/platform_data/tps68470.h | 35 ++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 include/linux/platform_data/tps68470.h

diff --git a/include/linux/platform_data/tps68470.h b/include/linux/platform_data/tps68470.h
new file mode 100644
index 000000000000..126d082c3f2e
--- /dev/null
+++ b/include/linux/platform_data/tps68470.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#ifndef __PDATA_TPS68470_H
+#define __PDATA_TPS68470_H
+
+enum tps68470_regulators {
+	TPS68470_CORE,
+	TPS68470_ANA,
+	TPS68470_VCM,
+	TPS68470_VIO,
+	TPS68470_VSIO,
+	TPS68470_AUX1,
+	TPS68470_AUX2,
+	TPS68470_NUM_REGULATORS
+};
+
+struct regulator_init_data;
+
+struct tps68470_regulator_platform_data {
+	const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
+};
+
+struct tps68470_clk_platform_data {
+	const char *consumer_dev_name;
+	const char *consumer_con_id;
+};
+
+#endif
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (3 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 04/12] platform_data: Add linux/platform_data/tps68470.h file Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-11 10:42   ` Mark Brown
  2021-10-08 16:21 ` [PATCH 06/12] clk: Introduce clk-tps68470 driver Hans de Goede
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The TPS68470 PMIC provides Clocks, GPIOs and Regulators. At present in
the kernel the Regulators and Clocks are controlled by an OpRegion
driver designed to work with power control methods defined in ACPI, but
some platforms lack those methods, meaning drivers need to be able to
consume the resources of these chips through the usual frameworks.

This commit adds a driver for the regulators provided by the tps68470,
and is designed to bind to the platform_device registered by the
intel_skl_int3472 module.

This is based on this out of tree driver written by Intel:
https://github.com/intel/linux-intel-lts/blob/4.14/base/drivers/regulator/tps68470-regulator.c
with various cleanups added.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/regulator/Kconfig              |   9 ++
 drivers/regulator/Makefile             |   1 +
 drivers/regulator/tps68470-regulator.c | 194 +++++++++++++++++++++++++
 3 files changed, 204 insertions(+)
 create mode 100644 drivers/regulator/tps68470-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4fd13b06231f..d107af5bff6c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1339,6 +1339,15 @@ config REGULATOR_TPS65912
 	help
 	    This driver supports TPS65912 voltage regulator chip.
 
+config REGULATOR_TPS68470
+	tristate "TI TPS68370 PMIC Regulators Driver"
+	depends on INTEL_SKL_INT3472
+	help
+	  This driver adds support for the TPS68470 PMIC to register
+	  regulators against the usual framework.
+
+	  The module will be called "tps68470-regulator"
+
 config REGULATOR_TPS80031
 	tristate "TI TPS80031/TPS80032 power regulator driver"
 	depends on MFD_TPS80031
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 9e382b50a5ef..03c318110986 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -158,6 +158,7 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
+obj-$(CONFIG_REGULATOR_TPS68470) += tps68470-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
diff --git a/drivers/regulator/tps68470-regulator.c b/drivers/regulator/tps68470-regulator.c
new file mode 100644
index 000000000000..82c4b1211c6f
--- /dev/null
+++ b/drivers/regulator/tps68470-regulator.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Regulator driver for TPS68470 PMIC
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Authors:
+ *	Zaikuo Wang <zaikuo.wang@intel.com>
+ *	Tianshu Qiu <tian.shu.qiu@intel.com>
+ *	Jian Xu Zheng <jian.xu.zheng@intel.com>
+ *	Yuning Pu <yuning.pu@intel.com>
+ *	Rajmohan Mani <rajmohan.mani@intel.com>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps68470.h>
+#include <linux/module.h>
+#include <linux/platform_data/tps68470.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#define TPS68470_REGULATOR(_name, _id, _ops, _n, _vr,			\
+			   _vm, _er, _em, _t, _lr, _nlr)		\
+	[TPS68470_ ## _name] = {					\
+		.name			= # _name,			\
+		.id			= _id,				\
+		.ops			= &_ops,			\
+		.n_voltages		= _n,				\
+		.type			= REGULATOR_VOLTAGE,		\
+		.owner			= THIS_MODULE,			\
+		.vsel_reg		= _vr,				\
+		.vsel_mask		= _vm,				\
+		.enable_reg		= _er,				\
+		.enable_mask		= _em,				\
+		.volt_table		= _t,				\
+		.linear_ranges		= _lr,				\
+		.n_linear_ranges	= _nlr,				\
+	}
+
+static const struct linear_range tps68470_ldo_ranges[] = {
+	REGULATOR_LINEAR_RANGE(875000, 0, 125, 17800),
+};
+
+static const struct linear_range tps68470_core_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000, 0, 42, 25000),
+};
+
+/* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */
+static struct regulator_ops tps68470_regulator_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_desc regulators[] = {
+	TPS68470_REGULATOR(CORE, TPS68470_CORE,
+			   tps68470_regulator_ops, 43, TPS68470_REG_VDVAL,
+			   TPS68470_VDVAL_DVOLT_MASK, TPS68470_REG_VDCTL,
+			   TPS68470_VDCTL_EN_MASK,
+			   NULL, tps68470_core_ranges,
+			   ARRAY_SIZE(tps68470_core_ranges)),
+	TPS68470_REGULATOR(ANA, TPS68470_ANA,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VAVAL,
+			   TPS68470_VAVAL_AVOLT_MASK, TPS68470_REG_VACTL,
+			   TPS68470_VACTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+	TPS68470_REGULATOR(VCM, TPS68470_VCM,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VCMVAL,
+			   TPS68470_VCMVAL_VCVOLT_MASK, TPS68470_REG_VCMCTL,
+			   TPS68470_VCMCTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+	TPS68470_REGULATOR(VIO, TPS68470_VIO,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VIOVAL,
+			   TPS68470_VIOVAL_IOVOLT_MASK, TPS68470_REG_S_I2C_CTL,
+			   TPS68470_S_I2C_CTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+
+/*
+ * (1) This register must have same setting as VIOVAL if S_IO LDO is used to
+ *     power daisy chained IOs in the receive side.
+ * (2) If there is no I2C daisy chain it can be set freely.
+ *
+ */
+	TPS68470_REGULATOR(VSIO, TPS68470_VSIO,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VSIOVAL,
+			   TPS68470_VSIOVAL_IOVOLT_MASK, TPS68470_REG_S_I2C_CTL,
+			   TPS68470_S_I2C_CTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+	TPS68470_REGULATOR(AUX1, TPS68470_AUX1,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VAUX1VAL,
+			   TPS68470_VAUX1VAL_AUX1VOLT_MASK,
+			   TPS68470_REG_VAUX1CTL,
+			   TPS68470_VAUX1CTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+	TPS68470_REGULATOR(AUX2, TPS68470_AUX2,
+			   tps68470_regulator_ops, 126, TPS68470_REG_VAUX2VAL,
+			   TPS68470_VAUX2VAL_AUX2VOLT_MASK,
+			   TPS68470_REG_VAUX2CTL,
+			   TPS68470_VAUX2CTL_EN_MASK,
+			   NULL, tps68470_ldo_ranges,
+			   ARRAY_SIZE(tps68470_ldo_ranges)),
+};
+
+#define TPS68470_REG_INIT_DATA(_name, _min_uV, _max_uV)			\
+	[TPS68470_ ## _name] = {					\
+		.constraints = {					\
+			.name = # _name,				\
+			.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |	\
+					  REGULATOR_CHANGE_STATUS,	\
+			.min_uV = _min_uV,				\
+			.max_uV = _max_uV,				\
+		},							\
+	}
+
+struct regulator_init_data tps68470_init[] = {
+	TPS68470_REG_INIT_DATA(CORE, 900000, 1950000),
+	TPS68470_REG_INIT_DATA(ANA, 875000, 3100000),
+	TPS68470_REG_INIT_DATA(VCM, 875000, 3100000),
+	TPS68470_REG_INIT_DATA(VIO, 875000, 3100000),
+	TPS68470_REG_INIT_DATA(VSIO, 875000, 3100000),
+	TPS68470_REG_INIT_DATA(AUX1, 875000, 3100000),
+	TPS68470_REG_INIT_DATA(AUX2, 875000, 3100000),
+};
+
+static int tps68470_regulator_probe(struct platform_device *pdev)
+{
+	struct tps68470_regulator_platform_data *pdata = pdev->dev.platform_data;
+	struct regulator_config config = { };
+	struct regmap *tps68470_regmap;
+	struct regulator_dev *rdev;
+	int i;
+
+	tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
+
+	for (i = 0; i < TPS68470_NUM_REGULATORS; i++) {
+		config.dev = pdev->dev.parent;
+		config.regmap = tps68470_regmap;
+		if (pdata && pdata->reg_init_data[i])
+			config.init_data = pdata->reg_init_data[i];
+		else
+			config.init_data = &tps68470_init[i];
+
+		rdev = devm_regulator_register(&pdev->dev, &regulators[i], &config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "failed to register %s regulator\n",
+				regulators[i].name);
+			return PTR_ERR(rdev);
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver tps68470_regulator_driver = {
+	.driver = {
+		.name = "tps68470-regulator",
+	},
+	.probe = tps68470_regulator_probe,
+};
+
+/*
+ * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
+ * being registered before the MFD cells are created (the MFD driver calls
+ * acpi_dev_clear_dependencies() after the cell creation).
+ * subsys_initcall() ensures this when the drivers are builtin.
+ */
+static int __init tps68470_regulator_init(void)
+{
+	return platform_driver_register(&tps68470_regulator_driver);
+}
+subsys_initcall(tps68470_regulator_init);
+
+static void __exit tps68470_regulator_exit(void)
+{
+	platform_driver_unregister(&tps68470_regulator_driver);
+}
+module_exit(tps68470_regulator_exit);
+
+MODULE_ALIAS("platform:tps68470-regulator");
+MODULE_DESCRIPTION("TPS68470 voltage regulator driver");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 06/12] clk: Introduce clk-tps68470 driver
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (4 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 05/12] regulator: Introduce tps68470-regulator driver Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 07/12] platform/x86: int3472: Enable I2c daisy chain Hans de Goede
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The TPS68470 PMIC provides Clocks, GPIOs and Regulators. At present in
the kernel the Regulators and Clocks are controlled by an OpRegion
driver designed to work with power control methods defined in ACPI, but
some platforms lack those methods, meaning drivers need to be able to
consume the resources of these chips through the usual frameworks.

This commit adds a driver for the clocks provided by the tps68470,
and is designed to bind to the platform_device registered by the
intel_skl_int3472 module.

This is based on this out of tree driver written by Intel:
https://github.com/intel/linux-intel-lts/blob/4.14/base/drivers/clk/clk-tps68470.c
with various cleanups added.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/clk/Kconfig          |   6 +
 drivers/clk/Makefile         |   1 +
 drivers/clk/clk-tps68470.c   | 257 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/tps68470.h |  11 ++
 4 files changed, 275 insertions(+)
 create mode 100644 drivers/clk/clk-tps68470.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c5b3dc97396a..7dffecac83d1 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -169,6 +169,12 @@ config COMMON_CLK_CDCE706
 	help
 	  This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
 
+config COMMON_CLK_TPS68470
+	tristate "Clock Driver for TI TPS68470 PMIC"
+	depends on I2C && REGMAP_I2C && INTEL_SKL_INT3472
+	help
+	 This driver supports the clocks provided by TPS68470
+
 config COMMON_CLK_CDCE925
 	tristate "Clock driver for TI CDCE913/925/937/949 devices"
 	depends on I2C
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121e51..6b6a88ae1425 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_COMMON_CLK_SI570)		+= clk-si570.o
 obj-$(CONFIG_COMMON_CLK_STM32F)		+= clk-stm32f4.o
 obj-$(CONFIG_COMMON_CLK_STM32H7)	+= clk-stm32h7.o
 obj-$(CONFIG_COMMON_CLK_STM32MP157)	+= clk-stm32mp1.o
+obj-$(CONFIG_COMMON_CLK_TPS68470)      += clk-tps68470.o
 obj-$(CONFIG_CLK_TWL6040)		+= clk-twl6040.o
 obj-$(CONFIG_ARCH_VT8500)		+= clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_VC5)		+= clk-versaclock5.o
diff --git a/drivers/clk/clk-tps68470.c b/drivers/clk/clk-tps68470.c
new file mode 100644
index 000000000000..3cf7e6151033
--- /dev/null
+++ b/drivers/clk/clk-tps68470.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TPS68470 PMIC
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Authors:
+ *	Zaikuo Wang <zaikuo.wang@intel.com>
+ *	Tianshu Qiu <tian.shu.qiu@intel.com>
+ *	Jian Xu Zheng <jian.xu.zheng@intel.com>
+ *	Yuning Pu <yuning.pu@intel.com>
+ *	Antti Laakso <antti.laakso@intel.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps68470.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tps68470.h>
+#include <linux/regmap.h>
+
+#define TPS68470_CLK_NAME "tps68470-clk"
+
+#define to_tps68470_clkdata(clkd) \
+	container_of(clkd, struct tps68470_clkdata, clkout_hw)
+
+struct tps68470_clkout_freqs {
+	unsigned long freq;
+	unsigned int xtaldiv;
+	unsigned int plldiv;
+	unsigned int postdiv;
+	unsigned int buckdiv;
+	unsigned int boostdiv;
+} clk_freqs[] = {
+/*
+ *  The PLL is used to multiply the crystal oscillator
+ *  frequency range of 3 MHz to 27 MHz by a programmable
+ *  factor of F = (M/N)*(1/P) such that the output
+ *  available at the HCLK_A or HCLK_B pins are in the range
+ *  of 4 MHz to 64 MHz in increments of 0.1 MHz
+ *
+ * hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv)
+ *
+ * PLL_REF_CLK should be as close as possible to 100kHz
+ * PLL_REF_CLK = input clk / XTALDIV[7:0] + 30)
+ *
+ * PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320))
+ *
+ * BOOST should be as close as possible to 2Mhz
+ * BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) *
+ *
+ * BUCK should be as close as possible to 5.2Mhz
+ * BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5)
+ *
+ * osc_in   xtaldiv  plldiv   postdiv   hclk_#
+ * 20Mhz    170      32       1         19.2Mhz
+ * 20Mhz    170      40       1         20Mhz
+ * 20Mhz    170      80       1         24Mhz
+ *
+ */
+	{ 19200000, 170, 32, 1, 2, 3 },
+	{ 20000000, 170, 40, 1, 3, 4 },
+	{ 24000000, 170, 80, 1, 4, 8 },
+};
+
+struct tps68470_clkdata {
+	struct clk_hw clkout_hw;
+	struct regmap *regmap;
+	struct clk *clk;
+	int clk_cfg_idx;
+};
+
+static int tps68470_clk_is_prepared(struct clk_hw *hw)
+{
+	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+	int val;
+
+	if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val))
+		return 0;
+
+	return val & TPS68470_PLL_EN_MASK;
+}
+
+static int tps68470_clk_prepare(struct clk_hw *hw)
+{
+	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+	int idx = clkdata->clk_cfg_idx;
+
+	regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT);
+	regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv);
+	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA);
+
+	regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL, 
+		     TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT |
+		     TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT);
+
+	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1,
+			   (TPS68470_PLL_OUTPUT_ENABLE <<
+			   TPS68470_OUTPUT_A_SHIFT) |
+			   (TPS68470_PLL_OUTPUT_ENABLE <<
+			   TPS68470_OUTPUT_B_SHIFT));
+
+	regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL,
+			   TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK);
+
+	return 0;
+}
+
+static void tps68470_clk_unprepare(struct clk_hw *hw)
+{
+	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+
+	/* disable clock first*/
+	regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0);
+
+	/* write hw defaults */
+	regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, 0);
+	regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0);
+}
+
+static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+
+	return clk_freqs[clkdata->clk_cfg_idx].freq;
+}
+
+static int tps68470_clk_cfg_lookup(unsigned long rate)
+{
+	long diff, best_diff = LONG_MAX;
+	int i, best_idx = 0;
+
+	for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) {
+		diff = clk_freqs[i].freq - rate;
+		if (diff == 0)
+			return i;
+
+		diff = abs(diff);
+		if (diff < best_diff) {
+			best_diff = diff;
+			best_idx = i;
+		}
+	}
+
+	return best_idx;
+}
+
+static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	int idx = tps68470_clk_cfg_lookup(rate);
+
+	return clk_freqs[idx].freq;
+}
+
+static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long parent_rate)
+{
+	struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+	int idx = tps68470_clk_cfg_lookup(rate);
+
+	if (rate != clk_freqs[idx].freq)
+		return -EINVAL;
+
+	clkdata->clk_cfg_idx = idx;
+	return 0;
+}
+
+static const struct clk_ops tps68470_clk_ops = {
+	.is_prepared = tps68470_clk_is_prepared,
+	.prepare = tps68470_clk_prepare,
+	.unprepare = tps68470_clk_unprepare,
+	.recalc_rate = tps68470_clk_recalc_rate,
+	.round_rate = tps68470_clk_round_rate,
+	.set_rate = tps68470_clk_set_rate,
+};
+
+static struct clk_init_data tps68470_clk_initdata = {
+	.name = TPS68470_CLK_NAME,
+	.ops = &tps68470_clk_ops,
+};
+
+static int tps68470_clk_probe(struct platform_device *pdev)
+{
+	struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data;
+	struct tps68470_clkdata *tps68470_clkdata;
+	int ret;
+
+	tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
+					GFP_KERNEL);
+	if (!tps68470_clkdata)
+		return -ENOMEM;
+
+	tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent);
+	tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata;
+	tps68470_clkdata->clk = devm_clk_register(&pdev->dev, &tps68470_clkdata->clkout_hw);
+	if (IS_ERR(tps68470_clkdata->clk))
+		return PTR_ERR(tps68470_clkdata->clk);
+
+	ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw,
+					  TPS68470_CLK_NAME, NULL);
+	if (ret)
+		return ret;
+
+	if (pdata) {
+		ret = devm_clk_hw_register_clkdev(&pdev->dev,
+						  &tps68470_clkdata->clkout_hw,
+						  pdata->consumer_con_id,
+						  pdata->consumer_dev_name);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver tps68470_clk_driver = {
+	.driver = {
+		.name = TPS68470_CLK_NAME,
+	},
+	.probe = tps68470_clk_probe,
+};
+
+/*
+ * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
+ * being registered before the MFD cells are created (the MFD driver calls
+ * acpi_dev_clear_dependencies() after the cell creation).
+ * subsys_initcall() ensures this when the drivers are builtin.
+ */
+static int __init tps68470_clk_init(void)
+{
+	return platform_driver_register(&tps68470_clk_driver);
+}
+subsys_initcall(tps68470_clk_init);
+
+static void __exit tps68470_clk_exit(void)
+{
+	platform_driver_unregister(&tps68470_clk_driver);
+}
+module_exit(tps68470_clk_exit);
+
+MODULE_ALIAS("platform:tps68470-clk");
+MODULE_DESCRIPTION("clock driver for TPS68470 pmic");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h
index ffe81127d91c..7807fa329db0 100644
--- a/include/linux/mfd/tps68470.h
+++ b/include/linux/mfd/tps68470.h
@@ -75,6 +75,17 @@
 #define TPS68470_CLKCFG1_MODE_A_MASK	GENMASK(1, 0)
 #define TPS68470_CLKCFG1_MODE_B_MASK	GENMASK(3, 2)
 
+#define TPS68470_CLKCFG2_DRV_STR_2MA	0x05
+#define TPS68470_PLL_OUTPUT_ENABLE	0x02
+#define TPS68470_CLK_SRC_XTAL		BIT(0)
+#define TPS68470_PLLSWR_DEFAULT		GENMASK(1, 0)
+#define TPS68470_OSC_EXT_CAP_DEFAULT	0x05
+
+#define TPS68470_OUTPUT_A_SHIFT		0x00
+#define TPS68470_OUTPUT_B_SHIFT		0x02
+#define TPS68470_CLK_SRC_SHIFT		GENMASK(2, 0)
+#define TPS68470_OSC_EXT_CAP_SHIFT	BIT(2)
+
 #define TPS68470_GPIO_CTL_REG_A(x)	(TPS68470_REG_GPCTL0A + (x) * 2)
 #define TPS68470_GPIO_CTL_REG_B(x)	(TPS68470_REG_GPCTL0B + (x) * 2)
 #define TPS68470_GPIO_MODE_MASK		GENMASK(1, 0)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 07/12] platform/x86: int3472: Enable I2c daisy chain
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (5 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 06/12] clk: Introduce clk-tps68470 driver Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 08/12] platform/x86: int3472: Split into 2 drivers Hans de Goede
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

From: Daniel Scally <djrscally@gmail.com>

The TPS68470 PMIC has an I2C passthrough mode through which I2C traffic
can be forwarded to a device connected to the PMIC as though it were
connected directly to the system bus. Enable this mode when the chip
is initialised.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
 .../x86/intel/int3472/intel_skl_int3472_tps68470.c         | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
index c05b4cf502fe..42e688f4cad4 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
+++ b/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
@@ -45,6 +45,13 @@ static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
 		return ret;
 	}
 
+	/* Enable I2C daisy chain */
+	ret = regmap_write(regmap, TPS68470_REG_S_I2C_CTL, 0x03);
+	if (ret) {
+		dev_err(dev, "Failed to enable i2c daisy chain\n");
+		return ret;
+	}
+
 	dev_info(dev, "TPS68470 REVID: 0x%02x\n", version);
 
 	return 0;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 08/12] platform/x86: int3472: Split into 2 drivers
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (6 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 07/12] platform/x86: int3472: Enable I2c daisy chain Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 09/12] platform/x86: int3472: Add get_sensor_adev_and_name() helper Hans de Goede
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The intel_skl_int3472.ko module contains 2 separate drivers,
the int3472_discrete platform driver and the int3472_tps68470
i2c-driver.

These 2 drivers contain very little shared code, only
skl_int3472_get_acpi_buffer() and skl_int3472_fill_cldb() are
shared.

Split the module into 2 drivers, linking the little shared code
directly into both.

This will allow us to add soft-module dependencies for the
tps68470 clk, gpio and regulator drivers to the new
intel_skl_int3472_tps68470.ko to help with probe ordering issues
without causing these modules to get loaded on boards which only
use the int3472_discrete platform driver.

While at it also rename the .c and .h files to remove the
cumbersome intel_skl_int3472_ prefix.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Note git rename detection is failing for the new common.c but this is
just the old intel_skl_int3472_common.c with the driver registering
bits removed.
---
 drivers/platform/x86/intel/int3472/Makefile   |   9 +-
 ...lk_and_regulator.c => clk_and_regulator.c} |   2 +-
 drivers/platform/x86/intel/int3472/common.c   |  54 +++++++++
 .../{intel_skl_int3472_common.h => common.h}  |   3 -
 ...ntel_skl_int3472_discrete.c => discrete.c} |  28 ++++-
 .../intel/int3472/intel_skl_int3472_common.c  | 106 ------------------
 ...ntel_skl_int3472_tps68470.c => tps68470.c} |  23 +++-
 7 files changed, 105 insertions(+), 120 deletions(-)
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_clk_and_regulator.c => clk_and_regulator.c} (99%)
 create mode 100644 drivers/platform/x86/intel/int3472/common.c
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_common.h => common.h} (94%)
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_discrete.c => discrete.c} (93%)
 delete mode 100644 drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
 rename drivers/platform/x86/intel/int3472/{intel_skl_int3472_tps68470.c => tps68470.c} (86%)

diff --git a/drivers/platform/x86/intel/int3472/Makefile b/drivers/platform/x86/intel/int3472/Makefile
index 2362e04db18d..771e720528a0 100644
--- a/drivers/platform/x86/intel/int3472/Makefile
+++ b/drivers/platform/x86/intel/int3472/Makefile
@@ -1,5 +1,4 @@
-obj-$(CONFIG_INTEL_SKL_INT3472)		+= intel_skl_int3472.o
-intel_skl_int3472-y			:= intel_skl_int3472_common.o \
-					   intel_skl_int3472_discrete.o \
-					   intel_skl_int3472_tps68470.o \
-					   intel_skl_int3472_clk_and_regulator.o
+obj-$(CONFIG_INTEL_SKL_INT3472)		+= intel_skl_int3472_discrete.o \
+					   intel_skl_int3472_tps68470.o
+intel_skl_int3472_discrete-y		:= discrete.o clk_and_regulator.o common.o
+intel_skl_int3472_tps68470-y		:= tps68470.o common.o
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
similarity index 99%
rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c
rename to drivers/platform/x86/intel/int3472/clk_and_regulator.c
index 1700e7557a82..1cf958983e86 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c
+++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
@@ -9,7 +9,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/slab.h>
 
-#include "intel_skl_int3472_common.h"
+#include "common.h"
 
 /*
  * The regulators have to have .ops to be valid, but the only ops we actually
diff --git a/drivers/platform/x86/intel/int3472/common.c b/drivers/platform/x86/intel/int3472/common.c
new file mode 100644
index 000000000000..350655a9515b
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/common.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Author: Dan Scally <djrscally@gmail.com> */
+
+#include <linux/acpi.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_handle handle = adev->handle;
+	union acpi_object *obj;
+	acpi_status status;
+
+	status = acpi_evaluate_object(handle, id, NULL, &buffer);
+	if (ACPI_FAILURE(status))
+		return ERR_PTR(-ENODEV);
+
+	obj = buffer.pointer;
+	if (!obj)
+		return ERR_PTR(-ENODEV);
+
+	if (obj->type != ACPI_TYPE_BUFFER) {
+		acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
+		kfree(obj);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return obj;
+}
+
+int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
+{
+	union acpi_object *obj;
+	int ret;
+
+	obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	if (obj->buffer.length > sizeof(*cldb)) {
+		acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
+		ret = -EINVAL;
+		goto out_free_obj;
+	}
+
+	memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
+	ret = 0;
+
+out_free_obj:
+	kfree(obj);
+	return ret;
+}
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel/int3472/common.h
similarity index 94%
rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h
rename to drivers/platform/x86/intel/int3472/common.h
index 714fde73b524..d14944ee8586 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h
+++ b/drivers/platform/x86/intel/int3472/common.h
@@ -105,9 +105,6 @@ struct int3472_discrete_device {
 	struct gpiod_lookup_table gpios;
 };
 
-int skl_int3472_discrete_probe(struct platform_device *pdev);
-int skl_int3472_discrete_remove(struct platform_device *pdev);
-int skl_int3472_tps68470_probe(struct i2c_client *client);
 union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
 					       char *id);
 int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
similarity index 93%
rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
rename to drivers/platform/x86/intel/int3472/discrete.c
index 9fe0a2527e1c..d62d81cde6ef 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -14,7 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/uuid.h>
 
-#include "intel_skl_int3472_common.h"
+#include "common.h"
 
 /*
  * 79234640-9e10-4fea-a5c1-b5aa8b19756f
@@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
 	return 0;
 }
 
-int skl_int3472_discrete_probe(struct platform_device *pdev)
+static int skl_int3472_discrete_remove(struct platform_device *pdev);
+
+static int skl_int3472_discrete_probe(struct platform_device *pdev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
 	struct int3472_discrete_device *int3472;
@@ -395,7 +397,7 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
 	return ret;
 }
 
-int skl_int3472_discrete_remove(struct platform_device *pdev)
+static int skl_int3472_discrete_remove(struct platform_device *pdev)
 {
 	struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
 
@@ -411,3 +413,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
 
 	return 0;
 }
+
+static const struct acpi_device_id int3472_device_id[] = {
+	{ "INT3472", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, int3472_device_id);
+
+static struct platform_driver int3472_discrete = {
+	.driver = {
+		.name = "int3472-discrete",
+		.acpi_match_table = int3472_device_id,
+	},
+	.probe = skl_int3472_discrete_probe,
+	.remove = skl_int3472_discrete_remove,
+};
+module_platform_driver(int3472_discrete);
+
+MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
+MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c b/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
deleted file mode 100644
index 497e74fba75f..000000000000
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Author: Dan Scally <djrscally@gmail.com> */
-
-#include <linux/acpi.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "intel_skl_int3472_common.h"
-
-union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
-{
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	acpi_handle handle = adev->handle;
-	union acpi_object *obj;
-	acpi_status status;
-
-	status = acpi_evaluate_object(handle, id, NULL, &buffer);
-	if (ACPI_FAILURE(status))
-		return ERR_PTR(-ENODEV);
-
-	obj = buffer.pointer;
-	if (!obj)
-		return ERR_PTR(-ENODEV);
-
-	if (obj->type != ACPI_TYPE_BUFFER) {
-		acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
-		kfree(obj);
-		return ERR_PTR(-EINVAL);
-	}
-
-	return obj;
-}
-
-int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
-{
-	union acpi_object *obj;
-	int ret;
-
-	obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
-	if (obj->buffer.length > sizeof(*cldb)) {
-		acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
-		ret = -EINVAL;
-		goto out_free_obj;
-	}
-
-	memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
-	ret = 0;
-
-out_free_obj:
-	kfree(obj);
-	return ret;
-}
-
-static const struct acpi_device_id int3472_device_id[] = {
-	{ "INT3472", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(acpi, int3472_device_id);
-
-static struct platform_driver int3472_discrete = {
-	.driver = {
-		.name = "int3472-discrete",
-		.acpi_match_table = int3472_device_id,
-	},
-	.probe = skl_int3472_discrete_probe,
-	.remove = skl_int3472_discrete_remove,
-};
-
-static struct i2c_driver int3472_tps68470 = {
-	.driver = {
-		.name = "int3472-tps68470",
-		.acpi_match_table = int3472_device_id,
-	},
-	.probe_new = skl_int3472_tps68470_probe,
-};
-
-static int skl_int3472_init(void)
-{
-	int ret;
-
-	ret = platform_driver_register(&int3472_discrete);
-	if (ret)
-		return ret;
-
-	ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
-	if (ret)
-		platform_driver_unregister(&int3472_discrete);
-
-	return ret;
-}
-module_init(skl_int3472_init);
-
-static void skl_int3472_exit(void)
-{
-	platform_driver_unregister(&int3472_discrete);
-	i2c_del_driver(&int3472_tps68470);
-}
-module_exit(skl_int3472_exit);
-
-MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
-MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
similarity index 86%
rename from drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
rename to drivers/platform/x86/intel/int3472/tps68470.c
index 42e688f4cad4..e95b0f50b384 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
+++ b/drivers/platform/x86/intel/int3472/tps68470.c
@@ -7,7 +7,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#include "intel_skl_int3472_common.h"
+#include "common.h"
 
 #define DESIGNED_FOR_CHROMEOS		1
 #define DESIGNED_FOR_WINDOWS		2
@@ -102,7 +102,7 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
 	return DESIGNED_FOR_WINDOWS;
 }
 
-int skl_int3472_tps68470_probe(struct i2c_client *client)
+static int skl_int3472_tps68470_probe(struct i2c_client *client)
 {
 	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
 	struct regmap *regmap;
@@ -142,3 +142,22 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
 
 	return ret;
 }
+
+static const struct acpi_device_id int3472_device_id[] = {
+	{ "INT3472", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, int3472_device_id);
+
+static struct i2c_driver int3472_tps68470 = {
+	.driver = {
+		.name = "int3472-tps68470",
+		.acpi_match_table = int3472_device_id,
+	},
+	.probe_new = skl_int3472_tps68470_probe,
+};
+module_i2c_driver(int3472_tps68470);
+
+MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
+MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 09/12] platform/x86: int3472: Add get_sensor_adev_and_name() helper
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (7 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 08/12] platform/x86: int3472: Split into 2 drivers Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 10/12] platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator MFD-cell Hans de Goede
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The discrete.c code is not the only code which needs to lookup the
acpi_device and device-name for the sensor for which the INT3472
ACPI-device is a GPIO/clk/regulator provider.

The tps68470.c code also needs this functionality, so factor this
out into a new get_sensor_adev_and_name() helper.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/intel/int3472/common.c   | 28 +++++++++++++++++++
 drivers/platform/x86/intel/int3472/common.h   |  3 ++
 drivers/platform/x86/intel/int3472/discrete.c | 22 +++------------
 3 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/drivers/platform/x86/intel/int3472/common.c b/drivers/platform/x86/intel/int3472/common.c
index 350655a9515b..77cf058e4168 100644
--- a/drivers/platform/x86/intel/int3472/common.c
+++ b/drivers/platform/x86/intel/int3472/common.c
@@ -52,3 +52,31 @@ int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
 	kfree(obj);
 	return ret;
 }
+
+/* sensor_adev_ret may be NULL, name_ret must not be NULL */
+int skl_int3472_get_sensor_adev_and_name(struct device *dev,
+					 struct acpi_device **sensor_adev_ret,
+					 const char **name_ret)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct acpi_device *sensor;
+	int ret = 0;
+
+	sensor = acpi_dev_get_first_consumer_dev(adev);
+	if (!sensor) {
+		dev_err(dev, "INT3472 seems to have no dependents.\n");
+		return -ENODEV;
+	}
+
+	*name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
+				   acpi_dev_name(sensor));
+	if (!*name_ret)
+		ret = -ENOMEM;
+
+	if (ret == 0 && sensor_adev_ret)
+		*sensor_adev_ret = sensor;
+	else
+		acpi_dev_put(sensor);
+
+	return ret;
+}
diff --git a/drivers/platform/x86/intel/int3472/common.h b/drivers/platform/x86/intel/int3472/common.h
index d14944ee8586..53270d19c73a 100644
--- a/drivers/platform/x86/intel/int3472/common.h
+++ b/drivers/platform/x86/intel/int3472/common.h
@@ -108,6 +108,9 @@ struct int3472_discrete_device {
 union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
 					       char *id);
 int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
+int skl_int3472_get_sensor_adev_and_name(struct device *dev,
+					 struct acpi_device **sensor_adev_ret,
+					 const char **name_ret);
 
 int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
 void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index d62d81cde6ef..fefe12850777 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -363,19 +363,10 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev)
 	int3472->dev = &pdev->dev;
 	platform_set_drvdata(pdev, int3472);
 
-	int3472->sensor = acpi_dev_get_first_consumer_dev(adev);
-	if (!int3472->sensor) {
-		dev_err(&pdev->dev, "INT3472 seems to have no dependents.\n");
-		return -ENODEV;
-	}
-
-	int3472->sensor_name = devm_kasprintf(int3472->dev, GFP_KERNEL,
-					      I2C_DEV_NAME_FORMAT,
-					      acpi_dev_name(int3472->sensor));
-	if (!int3472->sensor_name) {
-		ret = -ENOMEM;
-		goto err_put_sensor;
-	}
+	ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
+						   &int3472->sensor_name);
+	if (ret)
+		return ret;
 
 	/*
 	 * Initialising this list means we can call gpiod_remove_lookup_table()
@@ -390,11 +381,6 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev)
 	}
 
 	return 0;
-
-err_put_sensor:
-	acpi_dev_put(int3472->sensor);
-
-	return ret;
 }
 
 static int skl_int3472_discrete_remove(struct platform_device *pdev)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 10/12] platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator MFD-cell
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (8 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 09/12] platform/x86: int3472: Add get_sensor_adev_and_name() helper Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 11/12] platform/x86: int3472: Pass tps68470_regulator_platform_data " Hans de Goede
  2021-10-08 16:21 ` [PATCH 12/12] platform/x86: int3472: Call acpi_dev_clear_dependencies() on successful probe Hans de Goede
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

Pass tps68470_clk_platform_data to the tps68470-clk MFD-cell,
so that sensors which use the TPS68470 can find their clock.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/intel/int3472/tps68470.c | 28 +++++++++++++------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
index e95b0f50b384..bd01acb177c4 100644
--- a/drivers/platform/x86/intel/int3472/tps68470.c
+++ b/drivers/platform/x86/intel/int3472/tps68470.c
@@ -5,6 +5,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps68470.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/tps68470.h>
 #include <linux/regmap.h>
 
 #include "common.h"
@@ -17,12 +18,6 @@ static const struct mfd_cell tps68470_cros[] = {
 	{ .name = "tps68470_pmic_opregion" },
 };
 
-static const struct mfd_cell tps68470_win[] = {
-	{ .name = "tps68470-gpio" },
-	{ .name = "tps68470-clk" },
-	{ .name = "tps68470-regulator" },
-};
-
 static const struct regmap_config tps68470_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -105,10 +100,17 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
 static int skl_int3472_tps68470_probe(struct i2c_client *client)
 {
 	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+	struct tps68470_clk_platform_data clk_pdata = {};
+	struct mfd_cell *cells;
 	struct regmap *regmap;
 	int device_type;
 	int ret;
 
+	ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
+						   &clk_pdata.consumer_dev_name);
+	if (ret)
+		return ret;
+
 	regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
 	if (IS_ERR(regmap)) {
 		dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
@@ -126,9 +128,19 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
 	device_type = skl_int3472_tps68470_calc_type(adev);
 	switch (device_type) {
 	case DESIGNED_FOR_WINDOWS:
-		ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
-					   tps68470_win, ARRAY_SIZE(tps68470_win),
+		cells = kcalloc(3, sizeof(*cells), GFP_KERNEL);
+		if (!cells)
+			return -ENOMEM;
+
+		cells[0].name = "tps68470-gpio";
+		cells[1].name = "tps68470-clk";
+		cells[1].platform_data = &clk_pdata;
+		cells[1].pdata_size = sizeof(clk_pdata);
+		cells[2].name = "tps68470-regulator";
+
+		ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, cells, 3,
 					   NULL, 0, NULL);
+		kfree(cells);
 		break;
 	case DESIGNED_FOR_CHROMEOS:
 		ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 11/12] platform/x86: int3472: Pass tps68470_regulator_platform_data to the tps68470-regulator MFD-cell
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (9 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 10/12] platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator MFD-cell Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  2021-10-08 16:21 ` [PATCH 12/12] platform/x86: int3472: Call acpi_dev_clear_dependencies() on successful probe Hans de Goede
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

Pass tps68470_regulator_platform_data to the tps68470-regulator
MFD-cell, specifying the voltages of the various regulators and
tying the regulators to the sensor supplies so that sensors which use
the TPS68470 can find their regulators.

Since the voltages and supply connections are board-specific, this
introduces a DMI matches int3472_tps68470_board_data struct which
contains the necessary per-board info.

This per-board info also includes GPIO lookup information for the
sensor GPIOs which may be connected to the tps68470 gpios.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/intel/int3472/Makefile   |   2 +-
 drivers/platform/x86/intel/int3472/tps68470.c |  26 ++++
 drivers/platform/x86/intel/int3472/tps68470.h |  25 ++++
 .../x86/intel/int3472/tps68470_board_data.c   | 118 ++++++++++++++++++
 4 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 drivers/platform/x86/intel/int3472/tps68470.h
 create mode 100644 drivers/platform/x86/intel/int3472/tps68470_board_data.c

diff --git a/drivers/platform/x86/intel/int3472/Makefile b/drivers/platform/x86/intel/int3472/Makefile
index 771e720528a0..cfec7784c5c9 100644
--- a/drivers/platform/x86/intel/int3472/Makefile
+++ b/drivers/platform/x86/intel/int3472/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_INTEL_SKL_INT3472)		+= intel_skl_int3472_discrete.o \
 					   intel_skl_int3472_tps68470.o
 intel_skl_int3472_discrete-y		:= discrete.o clk_and_regulator.o common.o
-intel_skl_int3472_tps68470-y		:= tps68470.o common.o
+intel_skl_int3472_tps68470-y		:= tps68470.o tps68470_board_data.o common.o
diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
index bd01acb177c4..36b657888fe2 100644
--- a/drivers/platform/x86/intel/int3472/tps68470.c
+++ b/drivers/platform/x86/intel/int3472/tps68470.c
@@ -9,6 +9,7 @@
 #include <linux/regmap.h>
 
 #include "common.h"
+#include "tps68470.h"
 
 #define DESIGNED_FOR_CHROMEOS		1
 #define DESIGNED_FOR_WINDOWS		2
@@ -100,6 +101,7 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
 static int skl_int3472_tps68470_probe(struct i2c_client *client)
 {
 	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+	const struct int3472_tps68470_board_data *board_data;
 	struct tps68470_clk_platform_data clk_pdata = {};
 	struct mfd_cell *cells;
 	struct regmap *regmap;
@@ -128,6 +130,12 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
 	device_type = skl_int3472_tps68470_calc_type(adev);
 	switch (device_type) {
 	case DESIGNED_FOR_WINDOWS:
+		board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
+		if (!board_data) {
+			dev_err(&client->dev, "No board-data found for this laptop/tablet model\n");
+			return -ENODEV;
+		}
+
 		cells = kcalloc(3, sizeof(*cells), GFP_KERNEL);
 		if (!cells)
 			return -ENOMEM;
@@ -137,10 +145,16 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
 		cells[1].platform_data = &clk_pdata;
 		cells[1].pdata_size = sizeof(clk_pdata);
 		cells[2].name = "tps68470-regulator";
+		cells[2].platform_data = (void *)board_data->tps68470_regulator_pdata;
+		cells[2].pdata_size = sizeof(struct tps68470_regulator_platform_data);
 
 		ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, cells, 3,
 					   NULL, 0, NULL);
 		kfree(cells);
+
+		if (ret == 0)
+			gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
+
 		break;
 	case DESIGNED_FOR_CHROMEOS:
 		ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
@@ -155,6 +169,17 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
 	return ret;
 }
 
+static int skl_int3472_tps68470_remove(struct i2c_client *client)
+{
+	const struct int3472_tps68470_board_data *board_data;
+
+	board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
+	if (board_data)
+		gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
+
+	return 0;
+}
+
 static const struct acpi_device_id int3472_device_id[] = {
 	{ "INT3472", 0 },
 	{ }
@@ -167,6 +192,7 @@ static struct i2c_driver int3472_tps68470 = {
 		.acpi_match_table = int3472_device_id,
 	},
 	.probe_new = skl_int3472_tps68470_probe,
+	.remove = skl_int3472_tps68470_remove,
 };
 module_i2c_driver(int3472_tps68470);
 
diff --git a/drivers/platform/x86/intel/int3472/tps68470.h b/drivers/platform/x86/intel/int3472/tps68470.h
new file mode 100644
index 000000000000..cfd33eb62740
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/tps68470.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#ifndef _INTEL_SKL_INT3472_TPS68470_H
+#define _INTEL_SKL_INT3472_TPS68470_H
+
+struct gpiod_lookup_table;
+struct tps68470_regulator_platform_data;
+
+struct int3472_tps68470_board_data {
+	const char *dev_name;
+	struct gpiod_lookup_table *tps68470_gpio_lookup_table;
+	const struct tps68470_regulator_platform_data *tps68470_regulator_pdata;
+};
+
+const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name);
+
+#endif
diff --git a/drivers/platform/x86/intel/int3472/tps68470_board_data.c b/drivers/platform/x86/intel/int3472/tps68470_board_data.c
new file mode 100644
index 000000000000..96954a789bb8
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/tps68470_board_data.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Dan Scally <djrscally@gmail.com>
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/dmi.h>
+#include <linux/gpio/machine.h>
+#include <linux/platform_data/tps68470.h>
+#include <linux/regulator/machine.h>
+#include "tps68470.h"
+
+static struct regulator_consumer_supply int347a_core_consumer_supplies[] = {
+	REGULATOR_SUPPLY("dvdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_consumer_supply int347a_ana_consumer_supplies[] = {
+	REGULATOR_SUPPLY("avdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_consumer_supply int347a_vsio_consumer_supplies[] = {
+	REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
+};
+
+static const struct regulator_init_data surface_go_tps68470_core_reg_init_data = {
+	.constraints = {
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(int347a_core_consumer_supplies),
+	.consumer_supplies = int347a_core_consumer_supplies,
+};
+
+static const struct regulator_init_data surface_go_tps68470_ana_reg_init_data = {
+	.constraints = {
+		.min_uV = 2815200,
+		.max_uV = 2815200,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(int347a_ana_consumer_supplies),
+	.consumer_supplies = int347a_ana_consumer_supplies,
+};
+
+static const struct regulator_init_data surface_go_tps68470_vsio_reg_init_data = {
+	.constraints = {
+		.min_uV = 1800600,
+		.max_uV = 1800600,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(int347a_vsio_consumer_supplies),
+	.consumer_supplies = int347a_vsio_consumer_supplies,
+};
+
+static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = {
+	.reg_init_data = {
+		[TPS68470_CORE] = &surface_go_tps68470_core_reg_init_data,
+		[TPS68470_ANA]  = &surface_go_tps68470_ana_reg_init_data,
+		[TPS68470_VSIO] = &surface_go_tps68470_vsio_reg_init_data,
+	},
+};
+
+static struct gpiod_lookup_table surface_go_tps68470_gpios = {
+	.dev_id = "i2c-INT347A:00",
+	.table = {
+		GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
+	}
+};
+
+static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
+	.dev_name = "i2c-INT3472:05",
+	.tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
+	.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
+};
+
+static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go"),
+		},
+		.driver_data = (void *)&surface_go_tps68470_board_data,
+	},
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go 2"),
+		},
+		.driver_data = (void *)&surface_go_tps68470_board_data,
+	},
+	{ }
+};
+
+const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name)
+{
+	const struct int3472_tps68470_board_data *board_data;
+	const struct dmi_system_id *match;
+
+	match = dmi_first_match(int3472_tps68470_board_data_table);
+	while (match) {
+		board_data = match->driver_data;
+		if (strcmp(board_data->dev_name, dev_name) == 0)
+			return board_data;
+
+		dmi_first_match(++match);
+	}
+
+	return NULL;
+}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 12/12] platform/x86: int3472: Call acpi_dev_clear_dependencies() on successful probe
  2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
                   ` (10 preceding siblings ...)
  2021-10-08 16:21 ` [PATCH 11/12] platform/x86: int3472: Pass tps68470_regulator_platform_data " Hans de Goede
@ 2021-10-08 16:21 ` Hans de Goede
  11 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 16:21 UTC (permalink / raw)
  To: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Mark Brown, Michael Turquette, Stephen Boyd
  Cc: Hans de Goede, Len Brown, linux-acpi, platform-driver-x86,
	linux-kernel, Sakari Ailus, Kate Hsuan, linux-media, linux-clk

The clk and regulator frameworks expect clk/regulator consumer-devices
to have info about the consumed clks/regulators described in the device's
fw_node.

To work around this info missing from the ACPI tables on devices where
the int3472 driver is used, the int3472 MFD-cell drivers attach info about
consumers to the clks/regulators when registering these.

This causes problems with the probe ordering wrt drivers for consumers
of these clks/regulators. Since the lookups are only registered when the
provider-driver binds, trying to get these clks/regulators before then
results in a -ENOENT error for clks and a dummy regulator for regulators.

All the sensor ACPI fw-nodes have a _DEP dependency on the INT3472 ACPI
fw-node, so to work around these probe ordering issues the sensor drivers
call the has_unmet_acpi_deps() helper and return -EPROBE_DEFER if this
returns true.

Add MODULE_SOFTDEP dependencies for the gpio/clk/regulator drivers for
the instantiated MFD-cells so that these are loaded before us and so
that they bind immediately when the platform-devs are instantiated;
and call acpi_dev_clear_dependencies() on successful probe.

This way we ensure that the gpio/clk/regulators are registered before
we call acpi_dev_clear_dependencies() and the sensor drivers can then
use has_unmet_acpi_deps() helper to wait for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/intel/int3472/discrete.c | 1 +
 drivers/platform/x86/intel/int3472/tps68470.c | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index fefe12850777..e23a45b985dc 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -380,6 +380,7 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	acpi_dev_clear_dependencies(adev);
 	return 0;
 }
 
diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
index 36b657888fe2..781ce6ead720 100644
--- a/drivers/platform/x86/intel/int3472/tps68470.c
+++ b/drivers/platform/x86/intel/int3472/tps68470.c
@@ -166,6 +166,9 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
 		return device_type;
 	}
 
+	if (ret == 0)
+		acpi_dev_clear_dependencies(adev);
+
 	return ret;
 }
 
@@ -199,3 +202,4 @@ module_i2c_driver(int3472_tps68470);
 MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
 MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
 MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: gpio-tps68470 clk-tps68470 tps68470-regulator");
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  2021-10-08 16:21 ` [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check Hans de Goede
@ 2021-10-08 18:41   ` Laurent Pinchart
  2021-10-08 18:48     ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Laurent Pinchart @ 2021-10-08 18:41 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi Hans,

Thank you for the patch.

On Fri, Oct 08, 2021 at 06:21:11PM +0200, Hans de Goede wrote:
> The clk and regulator frameworks expect clk/regulator consumer-devices
> to have info about the consumed clks/regulators described in the device's
> fw_node.
> 
> To work around cases where this info is not present in the firmware tables,
> which is often the case on x86/ACPI devices, both frameworks allow the
> provider-driver to attach info about consumers to the clks/regulators
> when registering these.
> 
> This causes problems with the probe ordering of the ov8865 driver vs the
> drivers for these clks/regulators. Since the lookups are only registered
> when the provider-driver binds, trying to get these clks/regulators before
> then results in a -ENOENT error for clks and a dummy regulator for regs.
> 
> On ACPI/x86 where this is a problem, the ov8865 ACPI fw-nodes have a _DEP
> dependency on the INT3472 ACPI fw-node which describes the hardware which
> provides the clks/regulators.
> 
> The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
> fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
> _DEP has been "met" when all the clks/regulators have been setup.
> 
> Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
> and return -EPROBE_DEFER if this returns true, so that we wait for
> the clk/regulator setup to be done before continuing with probing.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/media/i2c/ov8865.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
> index ce4e0ae2c4d3..fd18d1256f78 100644
> --- a/drivers/media/i2c/ov8865.c
> +++ b/drivers/media/i2c/ov8865.c
> @@ -2978,6 +2978,9 @@ static int ov8865_probe(struct i2c_client *client)
>  	unsigned int i;
>  	int ret;
>  
> +	if (has_unmet_acpi_deps(dev))
> +		return -EPROBE_DEFER;
> +

We've worked hard to avoid adding ACPI-specific code such as this in
sensor drivers, as it would then spread like crazy, and also open the
door to more ACPI-specific support. I don't want to open this pandora's
box, I'd like to see this handled in another layer (the I2C core could
be a condidate for instance, but bonus points if it can be handled in
the ACPI subsystem itself).

>  	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
>  	if (!sensor)
>  		return -ENOMEM;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  2021-10-08 18:41   ` Laurent Pinchart
@ 2021-10-08 18:48     ` Hans de Goede
  2021-10-08 18:58       ` Laurent Pinchart
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-08 18:48 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi Laurent,

On 10/8/21 8:41 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Fri, Oct 08, 2021 at 06:21:11PM +0200, Hans de Goede wrote:
>> The clk and regulator frameworks expect clk/regulator consumer-devices
>> to have info about the consumed clks/regulators described in the device's
>> fw_node.
>>
>> To work around cases where this info is not present in the firmware tables,
>> which is often the case on x86/ACPI devices, both frameworks allow the
>> provider-driver to attach info about consumers to the clks/regulators
>> when registering these.
>>
>> This causes problems with the probe ordering of the ov8865 driver vs the
>> drivers for these clks/regulators. Since the lookups are only registered
>> when the provider-driver binds, trying to get these clks/regulators before
>> then results in a -ENOENT error for clks and a dummy regulator for regs.
>>
>> On ACPI/x86 where this is a problem, the ov8865 ACPI fw-nodes have a _DEP
>> dependency on the INT3472 ACPI fw-node which describes the hardware which
>> provides the clks/regulators.
>>
>> The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
>> fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
>> _DEP has been "met" when all the clks/regulators have been setup.
>>
>> Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
>> and return -EPROBE_DEFER if this returns true, so that we wait for
>> the clk/regulator setup to be done before continuing with probing.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/media/i2c/ov8865.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
>> index ce4e0ae2c4d3..fd18d1256f78 100644
>> --- a/drivers/media/i2c/ov8865.c
>> +++ b/drivers/media/i2c/ov8865.c
>> @@ -2978,6 +2978,9 @@ static int ov8865_probe(struct i2c_client *client)
>>  	unsigned int i;
>>  	int ret;
>>  
>> +	if (has_unmet_acpi_deps(dev))
>> +		return -EPROBE_DEFER;
>> +
> 
> We've worked hard to avoid adding ACPI-specific code such as this in
> sensor drivers, as it would then spread like crazy, and also open the
> door to more ACPI-specific support. I don't want to open this pandora's
> box, I'd like to see this handled in another layer (the I2C core could
> be a condidate for instance, but bonus points if it can be handled in
> the ACPI subsystem itself).

The problem is that we do NOT want this check for all i2c devices, so doing
it in any place other then the drivers means having some list of APCI-ids
to which to apply this someplace else. And then for every sensor driver
which needs this we need to update this list.

This is wht I've chosen to just put this check directly in the sensor
drivers. It is only 2 lines, it is a no-op on kernels where ACPI
is not enabled (without need a #ifdef) and it is a no-op if the
sensor i2c-client is not instantiated through APCI even when ACPI
support is enabled in the kernel.

I understand that you don't want a lot of ACPI specific code inside
the drivers, which is why I've come up with this fix which consists
of only 2 lines.  My previous attempts (which I never posted)
where much worse then this.

Regards,

Hans



> 
>>  	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
>>  	if (!sensor)
>>  		return -ENOMEM;
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  2021-10-08 18:48     ` Hans de Goede
@ 2021-10-08 18:58       ` Laurent Pinchart
  2021-10-09 15:31         ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Laurent Pinchart @ 2021-10-08 18:58 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi Hans,

On Fri, Oct 08, 2021 at 08:48:18PM +0200, Hans de Goede wrote:
> On 10/8/21 8:41 PM, Laurent Pinchart wrote:
> > On Fri, Oct 08, 2021 at 06:21:11PM +0200, Hans de Goede wrote:
> >> The clk and regulator frameworks expect clk/regulator consumer-devices
> >> to have info about the consumed clks/regulators described in the device's
> >> fw_node.
> >>
> >> To work around cases where this info is not present in the firmware tables,
> >> which is often the case on x86/ACPI devices, both frameworks allow the
> >> provider-driver to attach info about consumers to the clks/regulators
> >> when registering these.
> >>
> >> This causes problems with the probe ordering of the ov8865 driver vs the
> >> drivers for these clks/regulators. Since the lookups are only registered
> >> when the provider-driver binds, trying to get these clks/regulators before
> >> then results in a -ENOENT error for clks and a dummy regulator for regs.
> >>
> >> On ACPI/x86 where this is a problem, the ov8865 ACPI fw-nodes have a _DEP
> >> dependency on the INT3472 ACPI fw-node which describes the hardware which
> >> provides the clks/regulators.
> >>
> >> The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
> >> fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
> >> _DEP has been "met" when all the clks/regulators have been setup.
> >>
> >> Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
> >> and return -EPROBE_DEFER if this returns true, so that we wait for
> >> the clk/regulator setup to be done before continuing with probing.
> >>
> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >> ---
> >>  drivers/media/i2c/ov8865.c | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
> >> index ce4e0ae2c4d3..fd18d1256f78 100644
> >> --- a/drivers/media/i2c/ov8865.c
> >> +++ b/drivers/media/i2c/ov8865.c
> >> @@ -2978,6 +2978,9 @@ static int ov8865_probe(struct i2c_client *client)
> >>  	unsigned int i;
> >>  	int ret;
> >>  
> >> +	if (has_unmet_acpi_deps(dev))
> >> +		return -EPROBE_DEFER;
> >> +
> > 
> > We've worked hard to avoid adding ACPI-specific code such as this in
> > sensor drivers, as it would then spread like crazy, and also open the
> > door to more ACPI-specific support. I don't want to open this pandora's
> > box, I'd like to see this handled in another layer (the I2C core could
> > be a condidate for instance, but bonus points if it can be handled in
> > the ACPI subsystem itself).
> 
> The problem is that we do NOT want this check for all i2c devices,

Any of these sensors can be used on non-ACPI-based platforms, or on
ACPI-based platforms where integration has been done right. If it causes
an issue to call this function on those platforms, then this driver
won't work. If it causes no issue, why can't we call it in the I2C core
(or somewhere else) ?

> so doing
> it in any place other then the drivers means having some list of APCI-ids
> to which to apply this someplace else. And then for every sensor driver
> which needs this we need to update this list.
> 
> This is wht I've chosen to just put this check directly in the sensor
> drivers. It is only 2 lines, it is a no-op on kernels where ACPI
> is not enabled (without need a #ifdef) and it is a no-op if the
> sensor i2c-client is not instantiated through APCI even when ACPI
> support is enabled in the kernel.
> 
> I understand that you don't want a lot of ACPI specific code inside
> the drivers, which is why I've come up with this fix which consists
> of only 2 lines.  My previous attempts (which I never posted)
> where much worse then this.

So we only need to take one more step to remove just two lines :-)

This is all caused by Intel messing up their ACPI design badly. It's too
late to point and shame, it won't fix the problem, but I don't want this
to spread through drivers, neither for just those two lines (there are
dozens of sensors that would need the same treatment), nor for what the
next steps would be when someone else will want to add ACPI-specific
code and use this as a precedent. That's why we tried hard with Dan
Scally to isolate all the necessary quirks in a single place instead of
spreading them through drivers, which would have been easier to
implement.

I'd like to hear what Sakari thinks about this.

> >>  	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
> >>  	if (!sensor)
> >>  		return -ENOMEM;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check
  2021-10-08 18:58       ` Laurent Pinchart
@ 2021-10-09 15:31         ` Hans de Goede
  0 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-09 15:31 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Mauro Carvalho Chehab, Liam Girdwood, Mark Brown,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/8/21 8:58 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Fri, Oct 08, 2021 at 08:48:18PM +0200, Hans de Goede wrote:
>> On 10/8/21 8:41 PM, Laurent Pinchart wrote:
>>> On Fri, Oct 08, 2021 at 06:21:11PM +0200, Hans de Goede wrote:
>>>> The clk and regulator frameworks expect clk/regulator consumer-devices
>>>> to have info about the consumed clks/regulators described in the device's
>>>> fw_node.
>>>>
>>>> To work around cases where this info is not present in the firmware tables,
>>>> which is often the case on x86/ACPI devices, both frameworks allow the
>>>> provider-driver to attach info about consumers to the clks/regulators
>>>> when registering these.
>>>>
>>>> This causes problems with the probe ordering of the ov8865 driver vs the
>>>> drivers for these clks/regulators. Since the lookups are only registered
>>>> when the provider-driver binds, trying to get these clks/regulators before
>>>> then results in a -ENOENT error for clks and a dummy regulator for regs.
>>>>
>>>> On ACPI/x86 where this is a problem, the ov8865 ACPI fw-nodes have a _DEP
>>>> dependency on the INT3472 ACPI fw-node which describes the hardware which
>>>> provides the clks/regulators.
>>>>
>>>> The drivers/platform/x86/intel/int3472/ code dealing with these ACPI
>>>> fw-nodes will call acpi_dev_clear_dependencies() to indicate that this
>>>> _DEP has been "met" when all the clks/regulators have been setup.
>>>>
>>>> Call the has_unmet_acpi_deps() helper to check for unmet _DEPs
>>>> and return -EPROBE_DEFER if this returns true, so that we wait for
>>>> the clk/regulator setup to be done before continuing with probing.
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>> ---
>>>>  drivers/media/i2c/ov8865.c | 3 +++
>>>>  1 file changed, 3 insertions(+)
>>>>
>>>> diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
>>>> index ce4e0ae2c4d3..fd18d1256f78 100644
>>>> --- a/drivers/media/i2c/ov8865.c
>>>> +++ b/drivers/media/i2c/ov8865.c
>>>> @@ -2978,6 +2978,9 @@ static int ov8865_probe(struct i2c_client *client)
>>>>  	unsigned int i;
>>>>  	int ret;
>>>>  
>>>> +	if (has_unmet_acpi_deps(dev))
>>>> +		return -EPROBE_DEFER;
>>>> +
>>>
>>> We've worked hard to avoid adding ACPI-specific code such as this in
>>> sensor drivers, as it would then spread like crazy, and also open the
>>> door to more ACPI-specific support. I don't want to open this pandora's
>>> box, I'd like to see this handled in another layer (the I2C core could
>>> be a condidate for instance, but bonus points if it can be handled in
>>> the ACPI subsystem itself).
>>
>> The problem is that we do NOT want this check for all i2c devices,
> 
> Any of these sensors can be used on non-ACPI-based platforms, or on
> ACPI-based platforms where integration has been done right. If it causes
> an issue to call this function on those platforms, then this driver
> won't work. If it causes no issue, why can't we call it in the I2C core
> (or somewhere else) ?

This call checks the ACPI-core's count which keep track of all 
dependencies listed in the _DEP method have been marked as
"ready/available" by the driver for the Linux-device for those
dependencies having called acpi_dev_clear_dependencies().

The ACPI core code could delay instantiating devices for ACPI described
devices based on this itself, but it is deliberately not doing this.

This is deliberately not done because the _DEP method
may point to pretty much any random ACPI object and Linux does
not necessarily have a driver for all ACPI objects the driver
points too, which would lead to the devices never getting instantiated.

>> so doing
>> it in any place other then the drivers means having some list of APCI-ids
>> to which to apply this someplace else. And then for every sensor driver
>> which needs this we need to update this list.
>>
>> This is wht I've chosen to just put this check directly in the sensor
>> drivers. It is only 2 lines, it is a no-op on kernels where ACPI
>> is not enabled (without need a #ifdef) and it is a no-op if the
>> sensor i2c-client is not instantiated through APCI even when ACPI
>> support is enabled in the kernel.
>>
>> I understand that you don't want a lot of ACPI specific code inside
>> the drivers, which is why I've come up with this fix which consists
>> of only 2 lines.  My previous attempts (which I never posted)
>> where much worse then this.
> 
> So we only need to take one more step to remove just two lines :-)
> 
> This is all caused by Intel messing up their ACPI design badly. It's too
> late to point and shame, it won't fix the problem, but I don't want this
> to spread through drivers, neither for just those two lines (there are
> dozens of sensors that would need the same treatment), nor for what the
> next steps would be when someone else will want to add ACPI-specific
> code and use this as a precedent. That's why we tried hard with Dan
> Scally to isolate all the necessary quirks in a single place instead of
> spreading them through drivers, which would have been easier to
> implement.

Ok, so I've come up with a way to deal with this in the ACPI code
which does not require sensor-driver code modifications.

What I've done is make the ACPI core honor _DEP dependencies for
a device (instead of mostly ignore them) when one of those _DEPs
is for a device with a HID of INT3472 (the camera PMIC / discrete
clk/regulator ACPI device/node). This way the ACPI core can make
this decision without it having to keep an ever growing list of
sensor HIDs for which it should honor _DEP-s.

I'm about to send out a v2 of this series with this change,
see patch 1 + 2 of the v2 series.

I hope that Rafael is ok with the ACPI changes in there,
we will see...

Regards,

Hans


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-08 16:21 ` [PATCH 05/12] regulator: Introduce tps68470-regulator driver Hans de Goede
@ 2021-10-11 10:42   ` Mark Brown
  2021-10-11 11:43     ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-11 10:42 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]

On Fri, Oct 08, 2021 at 06:21:14PM +0200, Hans de Goede wrote:

> +++ b/drivers/regulator/tps68470-regulator.c
> @@ -0,0 +1,194 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Regulator driver for TPS68470 PMIC
> + *

Please make the entire comment a C++ one so things look more
intentional.

> +
> +/*
> + * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
> + * being registered before the MFD cells are created (the MFD driver calls
> + * acpi_dev_clear_dependencies() after the cell creation).
> + * subsys_initcall() ensures this when the drivers are builtin.
> + */
> +static int __init tps68470_regulator_init(void)
> +{
> +	return platform_driver_register(&tps68470_regulator_driver);
> +}
> +subsys_initcall(tps68470_regulator_init);

If this is actually required then the driver is broken for modular use
which frankly is just generally broken.  I don't understand why this
driver would require this when other drivers don't, or what the actual
requirement is here - what does the call do and why is the ordering
important?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-11 10:42   ` Mark Brown
@ 2021-10-11 11:43     ` Hans de Goede
  2021-10-15 16:46       ` Mark Brown
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-11 11:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/11/21 12:42 PM, Mark Brown wrote:
> On Fri, Oct 08, 2021 at 06:21:14PM +0200, Hans de Goede wrote:
> 
>> +++ b/drivers/regulator/tps68470-regulator.c
>> @@ -0,0 +1,194 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Regulator driver for TPS68470 PMIC
>> + *
> 
> Please make the entire comment a C++ one so things look more
> intentional.

Ok, will do so for the next version.


>> +
>> +/*
>> + * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
>> + * being registered before the MFD cells are created (the MFD driver calls
>> + * acpi_dev_clear_dependencies() after the cell creation).
>> + * subsys_initcall() ensures this when the drivers are builtin.
>> + */
>> +static int __init tps68470_regulator_init(void)
>> +{
>> +	return platform_driver_register(&tps68470_regulator_driver);
>> +}
>> +subsys_initcall(tps68470_regulator_init);
> 
> If this is actually required then the driver is broken for modular use
> which frankly is just generally broken.  I don't understand why this
> driver would require this when other drivers don't, or what the actual
> requirement is here - what does the call do and why is the ordering
> important?

For the camera-sensor which is a consumer of this devices to be able
to get the regulators (and not end up with a dummy regulator) the
consumer info added through the constraints passed as platform data
must be available to the regulator framework before the sensor-driver's
probe() method tries to get the regulators.

The ACPI fwnode describing the sensor has an ACPI _DEP dependency on
the ACPI fwnode describing the PMIC. To ensure that the PMIC driver
binds first patches 1 + 2 of this series make the ACPI code use this
dependency to not instantiate the i2c-client for the sensor until
the PMIC driver has bound.

The PMIC driver is a MFD driver creating GPIO, clk and regulator
MFD cells. So in order for the ACPI code delaying the instantiation
to help, the regulator constraints / consumer info must be registered
when the MFD driver is done binding. This means that the regulator
driver for the regulator MFD cells must be registered before the
platform_dev-s for the cell is instantiated, so that the driver
binds immediately (during instantiation) and thus the regulator
consumer info is available before the PMIC-MFD-driver's probe()
method is done.

The use of a subsys_initcall() here ensures that when builtin
the regulator driver is registered before the PMIC-MFD-driver
is registered (the PMIC driver uses a normal device_initcall).

To make this work when everything is build as a module patch 12/12
adds the following to the PMIC-MFD-driver:

MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");

This will make modprobe load the clk and regulator drivers
before it loads the main/MFD tps68470 driver.

I've tested this with everything built as module (the typical
setup for standard x86 setups) and without the MODULE_SOFTDEP
the sensor driver ends up with a dummy regulator (illustrating
the problem) and with the SOFTDEP in place everything works
as it should.

I hope this helps explain things.

Regards,

Hans


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-11 11:43     ` Hans de Goede
@ 2021-10-15 16:46       ` Mark Brown
  2021-10-15 18:50         ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-15 16:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

On Mon, Oct 11, 2021 at 01:43:40PM +0200, Hans de Goede wrote:

> To make this work when everything is build as a module patch 12/12
> adds the following to the PMIC-MFD-driver:

> MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");

> This will make modprobe load the clk and regulator drivers
> before it loads the main/MFD tps68470 driver.

I feel nervous about this being reliable with all userspaces - IIRC
there was an alternative implementation of the modules stuff in
userspace and someone could always be doing insmod.  OTOH without better
in kernel dependency management and/or more standards based firmware
interfaces I guess we're stuck with this.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 484 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 16:46       ` Mark Brown
@ 2021-10-15 18:50         ` Hans de Goede
  2021-10-15 18:58           ` Mark Brown
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-15 18:50 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/15/21 6:46 PM, Mark Brown wrote:
> On Mon, Oct 11, 2021 at 01:43:40PM +0200, Hans de Goede wrote:
> 
>> To make this work when everything is build as a module patch 12/12
>> adds the following to the PMIC-MFD-driver:
> 
>> MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");
> 
>> This will make modprobe load the clk and regulator drivers
>> before it loads the main/MFD tps68470 driver.
> 
> I feel nervous about this being reliable with all userspaces - IIRC
> there was an alternative implementation of the modules stuff in
> userspace and someone could always be doing insmod.  OTOH without better
> in kernel dependency management and/or more standards based firmware
> interfaces I guess we're stuck with this.

Right, this is all less then ideak, but I believe that this is the
best we can do for now.

Are you happy with the platform_data for this driver as defined in
patch 4/12 ? :

https://lore.kernel.org/platform-driver-x86/20211008162121.6628-1-hdegoede@redhat.com/T/#m745cc1191f531a57ae7998f5c8817ba9a46f0fed

And are you ok with me doing an immutable-branch based on
5.15-rc1 with just the patch adding the platform_data
in there ?  The platform_data is used/shared by most patches
in this series. So the idea is to have an immutable branch
which can be shared/merged by all subsystems which have
patches in this patch series.

Regards,

Hans


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 18:50         ` Hans de Goede
@ 2021-10-15 18:58           ` Mark Brown
  2021-10-15 19:27             ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-15 18:58 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 608 bytes --]

On Fri, Oct 15, 2021 at 08:50:13PM +0200, Hans de Goede wrote:

> Are you happy with the platform_data for this driver as defined in
> patch 4/12 ? :

Some of the other review comments lead me to believe that you'd be
sending out a new version at some point?

> https://lore.kernel.org/platform-driver-x86/20211008162121.6628-1-hdegoede@redhat.com/T/#m745cc1191f531a57ae7998f5c8817ba9a46f0fed

I am very confused about why it's in the driver without a DMI quirk
and/or clear comments about why and saying that this is a terrible
example to copy.  I'd also expect to get compile test coverage for the
driver.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 18:58           ` Mark Brown
@ 2021-10-15 19:27             ` Hans de Goede
  2021-10-15 19:40               ` Mark Brown
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-15 19:27 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/15/21 8:58 PM, Mark Brown wrote:
> On Fri, Oct 15, 2021 at 08:50:13PM +0200, Hans de Goede wrote:
> 
>> Are you happy with the platform_data for this driver as defined in
>> patch 4/12 ? :
> 
> Some of the other review comments lead me to believe that you'd be
> sending out a new version at some point?

That is correct.

> 
>> https://lore.kernel.org/platform-driver-x86/20211008162121.6628-1-hdegoede@redhat.com/T/#m745cc1191f531a57ae7998f5c8817ba9a46f0fed
> 
> I am very confused about why it's in the driver without a DMI quirk
> and/or clear comments about why and saying that this is a terrible
> example to copy.

The DMI quirks live in the ACPI glue code under drivers/platform/x86,
that code instantiates the MFD cell and sets the platform-data
as part of the cell.

> I'd also expect to get compile test coverage for the driver.

Ack, Stephen made the same remark for the clk driver. I'll fix
this for the next version.

Regards,

Hans



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 19:27             ` Hans de Goede
@ 2021-10-15 19:40               ` Mark Brown
  2021-10-15 19:48                 ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-15 19:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 739 bytes --]

On Fri, Oct 15, 2021 at 09:27:50PM +0200, Hans de Goede wrote:
> On 10/15/21 8:58 PM, Mark Brown wrote:

> > I am very confused about why it's in the driver without a DMI quirk
> > and/or clear comments about why and saying that this is a terrible
> > example to copy.

> The DMI quirks live in the ACPI glue code under drivers/platform/x86,
> that code instantiates the MFD cell and sets the platform-data
> as part of the cell.

I can't see how the quirking gets propagated through into the driver and
I'd really expect that in a situation like this the platform data would
be passed through as platform data from the code doing the quirks, this
just looks wrong and it'll go badly wrong if the same part shows up in
some other machine.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 19:40               ` Mark Brown
@ 2021-10-15 19:48                 ` Hans de Goede
  2021-10-15 19:59                   ` Mark Brown
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-15 19:48 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/15/21 9:40 PM, Mark Brown wrote:
> On Fri, Oct 15, 2021 at 09:27:50PM +0200, Hans de Goede wrote:
>> On 10/15/21 8:58 PM, Mark Brown wrote:
> 
>>> I am very confused about why it's in the driver without a DMI quirk
>>> and/or clear comments about why and saying that this is a terrible
>>> example to copy.
> 
>> The DMI quirks live in the ACPI glue code under drivers/platform/x86,
>> that code instantiates the MFD cell and sets the platform-data
>> as part of the cell.
> 
> I can't see how the quirking gets propagated through into the driver and
> I'd really expect that in a situation like this the platform data would
> be passed through as platform data from the code doing the quirks,

That is exactly what is happening here. The platform_data in this
case is just an array of regulator_init_data pointers (one per
regulator in the PMIC):

struct tps68470_regulator_platform_data {
        const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
};

This struct gets filled by platform specific code under drivers/platform/x86
(in later patches in the series).

And the regulator code in this patch consumes this like this:

                if (pdata && pdata->reg_init_data[i])
                        config.init_data = pdata->reg_init_data[i];
                else
                        config.init_data = &tps68470_init[i];

                rdev = devm_regulator_register(&pdev->dev, &regulators[i], &config);

So we have the code doing the quirks determining the regulator_init_data
and passing this through platform_data, which AFAICT is exactly what
you want?

Regards,

Hans


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 19:48                 ` Hans de Goede
@ 2021-10-15 19:59                   ` Mark Brown
  2021-10-15 20:14                     ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-15 19:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 1501 bytes --]

On Fri, Oct 15, 2021 at 09:48:24PM +0200, Hans de Goede wrote:
> On 10/15/21 9:40 PM, Mark Brown wrote:

> > I can't see how the quirking gets propagated through into the driver and
> > I'd really expect that in a situation like this the platform data would
> > be passed through as platform data from the code doing the quirks,

> That is exactly what is happening here. The platform_data in this
> case is just an array of regulator_init_data pointers (one per
> regulator in the PMIC):

No, it's not.  What normally happens is that whatever registers the
device will when registering the device supply platform data that the
device later picks up from the struct device during probe.  What you're
saying is that the idea here is that driver unconditionally declares
platform data and then other code scribbles over that before the driver
instantiates.  This is cleaner in that it keeps the platform
configuration together and safer since the device can't exist before
it's configuration is provided.

> So we have the code doing the quirks determining the regulator_init_data
> and passing this through platform_data, which AFAICT is exactly what
> you want?

No.  There should be no sign of the platform data getting allocated or
initialised in the driver consuming the platform data.  It should purely
be reading the data it gets passed by the platform initialisation code.

Please make the use of platform data look like normal platform data use
rather than going and inventing some new scheme.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 19:59                   ` Mark Brown
@ 2021-10-15 20:14                     ` Hans de Goede
  2021-10-15 22:29                       ` Mark Brown
  0 siblings, 1 reply; 29+ messages in thread
From: Hans de Goede @ 2021-10-15 20:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi,

On 10/15/21 9:59 PM, Mark Brown wrote:
> On Fri, Oct 15, 2021 at 09:48:24PM +0200, Hans de Goede wrote:
>> On 10/15/21 9:40 PM, Mark Brown wrote:
> 
>>> I can't see how the quirking gets propagated through into the driver and
>>> I'd really expect that in a situation like this the platform data would
>>> be passed through as platform data from the code doing the quirks,
> 
>> That is exactly what is happening here. The platform_data in this
>> case is just an array of regulator_init_data pointers (one per
>> regulator in the PMIC):
> 
> No, it's not.  What normally happens is that whatever registers the
> device will when registering the device supply platform data that the
> device later picks up from the struct device during probe.  What you're
> saying is that the idea here is that driver unconditionally declares
> platform data and then other code scribbles over that before the driver
> instantiates.  This is cleaner in that it keeps the platform
> configuration together and safer since the device can't exist before
> it's configuration is provided.

Right, this is the standard device-tree model. Unfortunately the
information about which supplies are needed and the constraints
for those supplies is missing from the ACPI description for the
devices which we are dealing with here.

Daniel Scally tried to solve this by allowing specifying this
in software-firmware-nodes. Which you nacked because those need
separate parsing code in the regulator core.

During that discussion you said that instead we should sinmply
directly pass the regulator_init_data, rather then first
encoding this in device-properties in a swnode and then
decoding those again in the regulator core.

And passing the regulator_init_data is exactly what we are doing
now; and now again this is not what we should be doing ?

Also note that the current solution is exactly what I suggested
we should do during the discussion with Daniel and I even provided
example code and you said absolutely nothing about this!

>> So we have the code doing the quirks determining the regulator_init_data
>> and passing this through platform_data, which AFAICT is exactly what
>> you want?
> 
> No.  There should be no sign of the platform data getting allocated or
> initialised in the driver consuming the platform data.  It should purely
> be reading the data it gets passed by the platform initialisation code.
> 
> Please make the use of platform data look like normal platform data use
> rather than going and inventing some new scheme.

I'm sorry but I no longer have any clue what it is what you want us to do /
how you want us to solve this.

AFAIK what the current code is doing is exactly what you requested during
the discussion with Daniel.

If this is not to your looking please provide some pseudo code explaining
how you want us to solve this problem instead of the current solution.

And please keep in mind that we *cannot* change the ACPI firmware interfaces
and that whether we like it or not things simply work different in the ACPI
world.

Frankly I'm quit unhappy, angry even about how you are blocking progress
here. You don't like APCI we get it, can we get over that now please?

So far all you seem to be doing is shooting down solutions, then first
being quiet about suggested alternative solutions and then once the
alternative solutions are implemented shoot them down again...

And all that without adding anything constructive. All you have
told us is how things should not be done (according to you).

So fine everything we come up is wrong, please tell us how we should
solve this instead then!

Regards,

Hans



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 20:14                     ` Hans de Goede
@ 2021-10-15 22:29                       ` Mark Brown
  2021-10-16 10:18                         ` Hans de Goede
  0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2021-10-15 22:29 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

[-- Attachment #1: Type: text/plain, Size: 5679 bytes --]

On Fri, Oct 15, 2021 at 10:14:30PM +0200, Hans de Goede wrote:
> On 10/15/21 9:59 PM, Mark Brown wrote:

> > No, it's not.  What normally happens is that whatever registers the
> > device will when registering the device supply platform data that the
> > device later picks up from the struct device during probe.  What you're
> > saying is that the idea here is that driver unconditionally declares
> > platform data and then other code scribbles over that before the driver
> > instantiates.  This is cleaner in that it keeps the platform

Actually, correction - there's no export of tps68470_init[] so I guess
that's just the data that gets used :/

> > configuration together and safer since the device can't exist before
> > it's configuration is provided.

> Right, this is the standard device-tree model. Unfortunately the
> information about which supplies are needed and the constraints
> for those supplies is missing from the ACPI description for the
> devices which we are dealing with here.

That's not just the standard device tree model, that's how systems with
board files work too.

> During that discussion you said that instead we should sinmply
> directly pass the regulator_init_data, rather then first
> encoding this in device-properties in a swnode and then
> decoding those again in the regulator core.

> And passing the regulator_init_data is exactly what we are doing
> now; and now again this is not what we should be doing ?

No, it is not what the driver doing now.  The driver will *optionally*
check for platform data, but if none is provided or if it doesn't
configure some of the regulators then the driver will provide some hard
coded regulator_init_data as a default.  These might be OK on the system
you're looking at but will also be used on any other system that happens
to instantiate the driver without platform data where there's no
guarantee that the information provided will be safe.  These defaults
that are being provided may use the same structure that gets used for
platform data but they aren't really platform data.

Yes, someone could use this on a system that does things in the standard
fashion where the platform data is getting passed in but if it's ever
run on any other system then it's going to assume this default platform
data with these constraints that have been embedded directly into the
driver without anything to ensure that they make sense on that system.

Indeed, now I go back and dig out the rest of the series it seems that
there's some drivers/platforms/x86 code added later which does in fact
do the right thing for some but not all of the regulators, it supplies
some platform data which overrides some but not all of this default
regulator_init_data using platform_data having identified the system
using DMI information (with configurations quite different to and much
more restricted than the defaults provided, exactly why defaults are an
issue).  I'm now even more confused about what the information that's
there is doing in the driver.  Either it's all unneeded even for your
system and should just be deleted, or if any of it is needed then it
should be moved to being initialised in the same place everything else
is so that it's only used on your system and not on any other system
that happens to end up running the driver.

In any case given that your platform does actually have code for
identifying it and supplying appropriate platform data the driver itself
can be fixed by just deleting the else case of

	if (pdata && pdata->reg_init_data[i])
		config.init_data = pdata->reg_init_data[i];
	else
		config.init_data = &tps68470_init[i];

and the data structure/macro it uses.  If no configuration is provided
by the platform then none should be provided to the core, this in turn
means that the regulator framework won't reconfigure the hardware if it
doesn't know it's safe to do so.

> Also note that the current solution is exactly what I suggested
> we should do during the discussion with Daniel and I even provided
> example code and you said absolutely nothing about this!

I had been under the impression that the platform data would look like
normal platform data and come along with the device registration,
providing default regulator_init_data hadn't really occurred to me.

> And please keep in mind that we *cannot* change the ACPI firmware interfaces
> and that whether we like it or not things simply work different in the ACPI
> world.

> Frankly I'm quit unhappy, angry even about how you are blocking progress
> here. You don't like APCI we get it, can we get over that now please?

ACPI is fine, we have a bunch of perfectly good ways to handle things
that need quirking on it safely - both platform_data and DMI quirks can
and do work well here.  The issue is that we should be using those
things rather than inventing new things unless those new things solve a
problem.

> So far all you seem to be doing is shooting down solutions, then first
> being quiet about suggested alternative solutions and then once the
> alternative solutions are implemented shoot them down again...

> And all that without adding anything constructive. All you have
> told us is how things should not be done (according to you).

> So fine everything we come up is wrong, please tell us how we should
> solve this instead then!

The important thing is to get rid of the hard coded defaults for the
regulator_init_data in the driver itself, if there is regulator_init_data
in the driver itself then it should be guarded with a DMI or similar
quirk.  Like I say above I think now I've gone back and dug through the
rest of the series once the default init_data is gone it's probably OK.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 05/12] regulator: Introduce tps68470-regulator driver
  2021-10-15 22:29                       ` Mark Brown
@ 2021-10-16 10:18                         ` Hans de Goede
  0 siblings, 0 replies; 29+ messages in thread
From: Hans de Goede @ 2021-10-16 10:18 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J . Wysocki, Mark Gross, Andy Shevchenko, Daniel Scally,
	Laurent Pinchart, Mauro Carvalho Chehab, Liam Girdwood,
	Michael Turquette, Stephen Boyd, Len Brown, linux-acpi,
	platform-driver-x86, linux-kernel, Sakari Ailus, Kate Hsuan,
	linux-media, linux-clk

Hi Mark,

On 10/16/21 12:29 AM, Mark Brown wrote:
> On Fri, Oct 15, 2021 at 10:14:30PM +0200, Hans de Goede wrote:
>> On 10/15/21 9:59 PM, Mark Brown wrote:

<snip>

>> During that discussion you said that instead we should sinmply
>> directly pass the regulator_init_data, rather then first
>> encoding this in device-properties in a swnode and then
>> decoding those again in the regulator core.
> 
>> And passing the regulator_init_data is exactly what we are doing
>> now; and now again this is not what we should be doing ?
> 
> No, it is not what the driver doing now.  The driver will *optionally*
> check for platform data, but if none is provided or if it doesn't
> configure some of the regulators then the driver will provide some hard
> coded regulator_init_data as a default.  These might be OK on the system
> you're looking at but will also be used on any other system that happens
> to instantiate the driver without platform data where there's no
> guarantee that the information provided will be safe.  These defaults
> that are being provided may use the same structure that gets used for
> platform data but they aren't really platform data.
> 
> Yes, someone could use this on a system that does things in the standard
> fashion where the platform data is getting passed in but if it's ever
> run on any other system then it's going to assume this default platform
> data with these constraints that have been embedded directly into the
> driver without anything to ensure that they make sense on that system.
> 
> Indeed, now I go back and dig out the rest of the series it seems that
> there's some drivers/platforms/x86 code added later which does in fact
> do the right thing for some but not all of the regulators, it supplies
> some platform data which overrides some but not all of this default
> regulator_init_data using platform_data having identified the system
> using DMI information (with configurations quite different to and much
> more restricted than the defaults provided, exactly why defaults are an
> issue).  I'm now even more confused about what the information that's
> there is doing in the driver.  Either it's all unneeded even for your
> system and should just be deleted, or if any of it is needed then it
> should be moved to being initialised in the same place everything else
> is so that it's only used on your system and not on any other system
> that happens to end up running the driver.
> 
> In any case given that your platform does actually have code for
> identifying it and supplying appropriate platform data the driver itself
> can be fixed by just deleting the else case of
> 
> 	if (pdata && pdata->reg_init_data[i])
> 		config.init_data = pdata->reg_init_data[i];
> 	else
> 		config.init_data = &tps68470_init[i];
> 
> and the data structure/macro it uses.  If no configuration is provided
> by the platform then none should be provided to the core, this in turn
> means that the regulator framework won't reconfigure the hardware if it
> doesn't know it's safe to do so.

Ah, ok. The default regulator_init_data in the tps68470_init[]
array was already there in the out of tree version of this driver
Daniel and I started with:

https://github.com/intel/linux-intel-lts/blob/4.14/base/drivers/regulator/tps68470-regulator.c

Now that you have pointed this out I would be more then happy to
delete it and I agree that providing this bogus data is not a
good idea.

<snip>

> The important thing is to get rid of the hard coded defaults for the
> regulator_init_data in the driver itself, if there is regulator_init_data
> in the driver itself then it should be guarded with a DMI or similar
> quirk.  Like I say above I think now I've gone back and dug through the
> rest of the series once the default init_data is gone it's probably OK.

Ok, for the next version of this patch-set I will:

1. Remove the default init_data
2. Change the toplevel comment to be all C++ style matching the SPDX line
3. Add a || COMPILE_TEST to the Kconfig so that this can be compile-tested
   without selecting the INTEL_SKL_INT3472 option

Thank you for taking the time to dive a bit deeper into the patch-set
and make it clear that your objection is the presence of the default
regulator_init_data; and sorry for loosing my cool a bit in my previous
email.

Regards,

Hans


^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2021-10-16 10:18 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-08 16:21 [PATCH 00/12] Add support for X86/ACPI camera sensor/PMIC setup with clk and regulator platform data Hans de Goede
2021-10-08 16:21 ` [PATCH 01/12] ACPI: Add has_unmet_acpi_deps() helper function Hans de Goede
2021-10-08 16:21 ` [PATCH 02/12] media: i2c: ov8865: Add an has_unmet_acpi_deps() check Hans de Goede
2021-10-08 18:41   ` Laurent Pinchart
2021-10-08 18:48     ` Hans de Goede
2021-10-08 18:58       ` Laurent Pinchart
2021-10-09 15:31         ` Hans de Goede
2021-10-08 16:21 ` [PATCH 03/12] media: i2c: ov5693: " Hans de Goede
2021-10-08 16:21 ` [PATCH 04/12] platform_data: Add linux/platform_data/tps68470.h file Hans de Goede
2021-10-08 16:21 ` [PATCH 05/12] regulator: Introduce tps68470-regulator driver Hans de Goede
2021-10-11 10:42   ` Mark Brown
2021-10-11 11:43     ` Hans de Goede
2021-10-15 16:46       ` Mark Brown
2021-10-15 18:50         ` Hans de Goede
2021-10-15 18:58           ` Mark Brown
2021-10-15 19:27             ` Hans de Goede
2021-10-15 19:40               ` Mark Brown
2021-10-15 19:48                 ` Hans de Goede
2021-10-15 19:59                   ` Mark Brown
2021-10-15 20:14                     ` Hans de Goede
2021-10-15 22:29                       ` Mark Brown
2021-10-16 10:18                         ` Hans de Goede
2021-10-08 16:21 ` [PATCH 06/12] clk: Introduce clk-tps68470 driver Hans de Goede
2021-10-08 16:21 ` [PATCH 07/12] platform/x86: int3472: Enable I2c daisy chain Hans de Goede
2021-10-08 16:21 ` [PATCH 08/12] platform/x86: int3472: Split into 2 drivers Hans de Goede
2021-10-08 16:21 ` [PATCH 09/12] platform/x86: int3472: Add get_sensor_adev_and_name() helper Hans de Goede
2021-10-08 16:21 ` [PATCH 10/12] platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator MFD-cell Hans de Goede
2021-10-08 16:21 ` [PATCH 11/12] platform/x86: int3472: Pass tps68470_regulator_platform_data " Hans de Goede
2021-10-08 16:21 ` [PATCH 12/12] platform/x86: int3472: Call acpi_dev_clear_dependencies() on successful probe Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.