platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator...
authorHans de Goede <hdegoede@redhat.com>
Fri, 3 Dec 2021 10:28:52 +0000 (11:28 +0100)
committerHans de Goede <hdegoede@redhat.com>
Mon, 13 Dec 2021 10:44:48 +0000 (11:44 +0100)
Pass tps68470_clk_platform_data to the tps68470-clk MFD-cell,
so that sensors which use the TPS68470 can find their clock.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20211203102857.44539-10-hdegoede@redhat.com
drivers/platform/x86/intel/int3472/tps68470.c

index fd3bef4..d0a3659 100644 (file)
@@ -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"
 #define DESIGNED_FOR_CHROMEOS          1
 #define DESIGNED_FOR_WINDOWS           2
 
+#define TPS68470_WIN_MFD_CELL_COUNT    3
+
 static const struct mfd_cell tps68470_cros[] = {
        { .name = "tps68470-gpio" },
        { .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,
@@ -98,10 +95,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));
@@ -119,9 +123,26 @@ 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:
+               cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
+               if (!cells)
+                       return -ENOMEM;
+
+               /*
+                * The order of the cells matters here! The clk must be first
+                * because the regulator depends on it. The gpios must be last,
+                * acpi_gpiochip_add() calls acpi_dev_clear_dependencies() and
+                * the clk + regulators must be ready when this happens.
+                */
+               cells[0].name = "tps68470-clk";
+               cells[0].platform_data = &clk_pdata;
+               cells[0].pdata_size = sizeof(clk_pdata);
+               cells[1].name = "tps68470-regulator";
+               cells[2].name = "tps68470-gpio";
+
                ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
-                                          tps68470_win, ARRAY_SIZE(tps68470_win),
+                                          cells, TPS68470_WIN_MFD_CELL_COUNT,
                                           NULL, 0, NULL);
+               kfree(cells);
                break;
        case DESIGNED_FOR_CHROMEOS:
                ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,