Skip to content

Commit 43cf369

Browse files
djrscallyrafaeljw
authored andcommitted
platform/x86: int3472: Support multiple clock consumers
At present, the tps68470.c only supports a single clock consumer when passing platform data to the clock driver. In some devices multiple sensors depend on the clock provided by a single TPS68470 and so all need to be able to acquire the clock. Support passing multiple consumers as platform data. Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Daniel Scally <[email protected]> Reviewed-by: Stephen Boyd <[email protected]> Acked-by: Stephen Boyd <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 62c8bc0 commit 43cf369

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

drivers/clk/clk-tps68470.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ static int tps68470_clk_probe(struct platform_device *pdev)
200200
.flags = CLK_SET_RATE_GATE,
201201
};
202202
struct tps68470_clkdata *tps68470_clkdata;
203+
struct tps68470_clk_consumer *consumer;
203204
int ret;
205+
int i;
204206

205207
tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
206208
GFP_KERNEL);
@@ -223,10 +225,13 @@ static int tps68470_clk_probe(struct platform_device *pdev)
223225
return ret;
224226

225227
if (pdata) {
226-
ret = devm_clk_hw_register_clkdev(&pdev->dev,
227-
&tps68470_clkdata->clkout_hw,
228-
pdata->consumer_con_id,
229-
pdata->consumer_dev_name);
228+
for (i = 0; i < pdata->n_consumers; i++) {
229+
consumer = &pdata->consumers[i];
230+
ret = devm_clk_hw_register_clkdev(&pdev->dev,
231+
&tps68470_clkdata->clkout_hw,
232+
consumer->consumer_con_id,
233+
consumer->consumer_dev_name);
234+
}
230235
}
231236

232237
return ret;

drivers/platform/x86/intel/int3472/tps68470.c

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/* Author: Dan Scally <[email protected]> */
33

4+
#include <linux/acpi.h>
45
#include <linux/i2c.h>
56
#include <linux/kernel.h>
67
#include <linux/mfd/core.h>
@@ -95,20 +96,64 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
9596
return DESIGNED_FOR_WINDOWS;
9697
}
9798

99+
/*
100+
* Return the size of the flexible array member, because we'll need that later
101+
* on to pass .pdata_size to cells.
102+
*/
103+
static int
104+
skl_int3472_fill_clk_pdata(struct device *dev, struct tps68470_clk_platform_data **clk_pdata)
105+
{
106+
struct acpi_device *adev = ACPI_COMPANION(dev);
107+
struct acpi_device *consumer;
108+
unsigned int n_consumers = 0;
109+
const char *sensor_name;
110+
unsigned int i = 0;
111+
112+
for_each_acpi_consumer_dev(adev, consumer)
113+
n_consumers++;
114+
115+
if (!n_consumers) {
116+
dev_err(dev, "INT3472 seems to have no dependents\n");
117+
return -ENODEV;
118+
}
119+
120+
*clk_pdata = devm_kzalloc(dev, struct_size(*clk_pdata, consumers, n_consumers),
121+
GFP_KERNEL);
122+
if (!*clk_pdata)
123+
return -ENOMEM;
124+
125+
(*clk_pdata)->n_consumers = n_consumers;
126+
i = 0;
127+
128+
for_each_acpi_consumer_dev(adev, consumer) {
129+
sensor_name = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
130+
acpi_dev_name(consumer));
131+
if (!sensor_name)
132+
return -ENOMEM;
133+
134+
(*clk_pdata)->consumers[i].consumer_dev_name = sensor_name;
135+
i++;
136+
}
137+
138+
acpi_dev_put(consumer);
139+
140+
return n_consumers;
141+
}
142+
98143
static int skl_int3472_tps68470_probe(struct i2c_client *client)
99144
{
100145
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
101146
const struct int3472_tps68470_board_data *board_data;
102-
struct tps68470_clk_platform_data clk_pdata = {};
147+
struct tps68470_clk_platform_data *clk_pdata;
103148
struct mfd_cell *cells;
104149
struct regmap *regmap;
150+
int n_consumers;
105151
int device_type;
106152
int ret;
107153

108-
ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
109-
&clk_pdata.consumer_dev_name);
110-
if (ret)
111-
return ret;
154+
n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata);
155+
if (n_consumers < 0)
156+
return n_consumers;
112157

113158
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
114159
if (IS_ERR(regmap)) {
@@ -142,8 +187,8 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
142187
* the clk + regulators must be ready when this happens.
143188
*/
144189
cells[0].name = "tps68470-clk";
145-
cells[0].platform_data = &clk_pdata;
146-
cells[0].pdata_size = sizeof(clk_pdata);
190+
cells[0].platform_data = clk_pdata;
191+
cells[0].pdata_size = struct_size(clk_pdata, consumers, n_consumers);
147192
cells[1].name = "tps68470-regulator";
148193
cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
149194
cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);

include/linux/platform_data/tps68470.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ struct tps68470_regulator_platform_data {
2727
const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
2828
};
2929

30-
struct tps68470_clk_platform_data {
30+
struct tps68470_clk_consumer {
3131
const char *consumer_dev_name;
3232
const char *consumer_con_id;
3333
};
3434

35+
struct tps68470_clk_platform_data {
36+
unsigned int n_consumers;
37+
struct tps68470_clk_consumer consumers[];
38+
};
39+
3540
#endif

0 commit comments

Comments
 (0)