* [PATCH v2 1/3] mfd: twl-core: Add a clock subdevice for the TWL6030
2024-10-02 11:07 [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
@ 2024-10-02 11:07 ` Andreas Kemnade
2024-10-02 11:07 ` [PATCH v2 2/3] clk: twl: remove is_prepared Andreas Kemnade
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Andreas Kemnade @ 2024-10-02 11:07 UTC (permalink / raw)
To: Stephen Boyd, Tony Lindgren, Aaro Koskinen, Kevin Hilman,
linux-clk, linux-kernel, Lee Jones, linux-omap, Roger Quadros,
Michael Turquette
Cc: Andreas Kemnade
Also the TWL6030 has some clocks, so add a subdevice for that.
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Reviewed-by: Roger Quadros <rogerq@kernel.org>
---
drivers/mfd/twl-core.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index c130ffef182f..c981922f62d5 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -711,6 +711,10 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
{ /* sentinel */ },
};
+static const struct mfd_cell twl6030_cells[] = {
+ { .name = "twl6030-clk" },
+};
+
static const struct mfd_cell twl6032_cells[] = {
{ .name = "twl6032-clk" },
};
@@ -861,17 +865,25 @@ twl_probe(struct i2c_client *client)
TWL4030_DCDC_GLOBAL_CFG);
}
- if (id->driver_data == (TWL6030_CLASS | TWL6032_SUBCLASS)) {
- status = devm_mfd_add_devices(&client->dev,
- PLATFORM_DEVID_NONE,
- twl6032_cells,
- ARRAY_SIZE(twl6032_cells),
- NULL, 0, NULL);
- if (status < 0)
- goto free;
- }
-
if (twl_class_is_6030()) {
+ if (id->driver_data & TWL6032_SUBCLASS) {
+ status = devm_mfd_add_devices(&client->dev,
+ PLATFORM_DEVID_NONE,
+ twl6032_cells,
+ ARRAY_SIZE(twl6032_cells),
+ NULL, 0, NULL);
+ if (status < 0)
+ goto free;
+ } else {
+ status = devm_mfd_add_devices(&client->dev,
+ PLATFORM_DEVID_NONE,
+ twl6030_cells,
+ ARRAY_SIZE(twl6030_cells),
+ NULL, 0, NULL);
+ if (status < 0)
+ goto free;
+ }
+
if (of_device_is_system_power_controller(node)) {
if (!pm_power_off)
pm_power_off = twl6030_power_off;
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/3] clk: twl: remove is_prepared
2024-10-02 11:07 [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
2024-10-02 11:07 ` [PATCH v2 1/3] mfd: twl-core: Add a clock subdevice for the TWL6030 Andreas Kemnade
@ 2024-10-02 11:07 ` Andreas Kemnade
2024-10-02 12:09 ` Roger Quadros
2024-10-02 11:07 ` [PATCH v2 3/3] clk: twl: add TWL6030 support Andreas Kemnade
2024-10-02 13:13 ` [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
3 siblings, 1 reply; 7+ messages in thread
From: Andreas Kemnade @ 2024-10-02 11:07 UTC (permalink / raw)
To: Stephen Boyd, Tony Lindgren, Aaro Koskinen, Kevin Hilman,
linux-clk, linux-kernel, Lee Jones, linux-omap, Roger Quadros,
Michael Turquette
Cc: Andreas Kemnade
Remave is_prepared to simplify adding of TWL6030 support.
The default implementation should be enough.
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
drivers/clk/clk-twl.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/drivers/clk/clk-twl.c b/drivers/clk/clk-twl.c
index eab9d3c8ed8a..1d684b358401 100644
--- a/drivers/clk/clk-twl.c
+++ b/drivers/clk/clk-twl.c
@@ -77,26 +77,9 @@ static void twl6032_clks_unprepare(struct clk_hw *hw)
dev_err(cinfo->dev, "clk unprepare failed\n");
}
-static int twl6032_clks_is_prepared(struct clk_hw *hw)
-{
- struct twl_clock_info *cinfo = to_twl_clks_info(hw);
- int val;
-
- val = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE);
- if (val < 0) {
- dev_err(cinfo->dev, "clk read failed\n");
- return val;
- }
-
- val &= TWL6030_CFG_STATE_MASK;
-
- return val == TWL6030_CFG_STATE_ON;
-}
-
static const struct clk_ops twl6032_clks_ops = {
.prepare = twl6032_clks_prepare,
.unprepare = twl6032_clks_unprepare,
- .is_prepared = twl6032_clks_is_prepared,
.recalc_rate = twl_clks_recalc_rate,
};
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 2/3] clk: twl: remove is_prepared
2024-10-02 11:07 ` [PATCH v2 2/3] clk: twl: remove is_prepared Andreas Kemnade
@ 2024-10-02 12:09 ` Roger Quadros
0 siblings, 0 replies; 7+ messages in thread
From: Roger Quadros @ 2024-10-02 12:09 UTC (permalink / raw)
To: Andreas Kemnade, Stephen Boyd, Tony Lindgren, Aaro Koskinen,
Kevin Hilman, linux-clk, linux-kernel, Lee Jones, linux-omap,
Michael Turquette
On 02/10/2024 14:07, Andreas Kemnade wrote:
> Remave is_prepared to simplify adding of TWL6030 support.
Remave/Remove
> The default implementation should be enough.
>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Reviewed-by: Roger Quadros <rogerq@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] clk: twl: add TWL6030 support
2024-10-02 11:07 [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
2024-10-02 11:07 ` [PATCH v2 1/3] mfd: twl-core: Add a clock subdevice for the TWL6030 Andreas Kemnade
2024-10-02 11:07 ` [PATCH v2 2/3] clk: twl: remove is_prepared Andreas Kemnade
@ 2024-10-02 11:07 ` Andreas Kemnade
2024-10-02 12:22 ` Roger Quadros
2024-10-02 13:13 ` [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
3 siblings, 1 reply; 7+ messages in thread
From: Andreas Kemnade @ 2024-10-02 11:07 UTC (permalink / raw)
To: Stephen Boyd, Tony Lindgren, Aaro Koskinen, Kevin Hilman,
linux-clk, linux-kernel, Lee Jones, linux-omap, Roger Quadros,
Michael Turquette
Cc: Andreas Kemnade
The TWL6030 has similar clocks, so add support for it. Take care of the
resource grouping handling needed.
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
drivers/clk/Kconfig | 2 +-
drivers/clk/clk-twl.c | 54 +++++++++++++++++++++++++++++++++----------
2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 299bc678ed1b..82ec12f9b82c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -291,7 +291,7 @@ config CLK_TWL
help
Enable support for controlling the clock resources on TWL family
PMICs. These devices have some 32K clock outputs which can be
- controlled by software. For now, only the TWL6032 clocks are
+ controlled by software. For now, the TWL6032 and TWL6030 clocks are
supported.
config CLK_TWL6040
diff --git a/drivers/clk/clk-twl.c b/drivers/clk/clk-twl.c
index 1d684b358401..f3a52f568887 100644
--- a/drivers/clk/clk-twl.c
+++ b/drivers/clk/clk-twl.c
@@ -11,13 +11,26 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
-#define VREG_STATE 2
+#define VREG_STATE 2
+#define VREG_GRP 0
#define TWL6030_CFG_STATE_OFF 0x00
#define TWL6030_CFG_STATE_ON 0x01
#define TWL6030_CFG_STATE_MASK 0x03
+#define TWL6030_CFG_STATE_GRP_SHIFT 5
+#define TWL6030_CFG_STATE_APP_SHIFT 2
+#define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
+#define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
+ TWL6030_CFG_STATE_APP_SHIFT)
+#define P1_GRP BIT(0) /* processor power group */
+#define P2_GRP BIT(1)
+#define P3_GRP BIT(2)
+#define ALL_GRP (P1_GRP | P2_GRP | P3_GRP)
+
+#define DRIVER_DATA_TWL6030 0
+#define DRIVER_DATA_TWL6032 1
struct twl_clock_info {
- struct device *dev;
+ struct platform_device *pdev;
u8 base;
struct clk_hw hw;
};
@@ -56,14 +69,21 @@ static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
static int twl6032_clks_prepare(struct clk_hw *hw)
{
struct twl_clock_info *cinfo = to_twl_clks_info(hw);
- int ret;
- ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
- TWL6030_CFG_STATE_ON);
- if (ret < 0)
- dev_err(cinfo->dev, "clk prepare failed\n");
+ if (platform_get_device_id(cinfo->pdev)->driver_data == DRIVER_DATA_TWL6030) {
+ int grp;
- return ret;
+ grp = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+ grp << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_ON);
+ }
+
+ return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+ TWL6030_CFG_STATE_ON);
}
static void twl6032_clks_unprepare(struct clk_hw *hw)
@@ -71,10 +91,16 @@ static void twl6032_clks_unprepare(struct clk_hw *hw)
struct twl_clock_info *cinfo = to_twl_clks_info(hw);
int ret;
- ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
- TWL6030_CFG_STATE_OFF);
+ if (platform_get_device_id(cinfo->pdev)->driver_data == DRIVER_DATA_TWL6030)
+ ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+ ALL_GRP << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_OFF);
+ else
+ ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+ TWL6030_CFG_STATE_OFF);
+
if (ret < 0)
- dev_err(cinfo->dev, "clk unprepare failed\n");
+ dev_err(&cinfo->pdev->dev, "clk unprepare failed\n");
}
static const struct clk_ops twl6032_clks_ops = {
@@ -137,7 +163,7 @@ static int twl_clks_probe(struct platform_device *pdev)
for (i = 0; i < count; i++) {
cinfo[i].base = hw_data[i].base;
- cinfo[i].dev = &pdev->dev;
+ cinfo[i].pdev = pdev;
cinfo[i].hw.init = &hw_data[i].init;
ret = devm_clk_hw_register(&pdev->dev, &cinfo[i].hw);
if (ret) {
@@ -159,7 +185,11 @@ static int twl_clks_probe(struct platform_device *pdev)
static const struct platform_device_id twl_clks_id[] = {
{
+ .name = "twl6030-clk",
+ .driver_data = DRIVER_DATA_TWL6030,
+ }, {
.name = "twl6032-clk",
+ .driver_data = DRIVER_DATA_TWL6032,
}, {
/* sentinel */
}
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 3/3] clk: twl: add TWL6030 support
2024-10-02 11:07 ` [PATCH v2 3/3] clk: twl: add TWL6030 support Andreas Kemnade
@ 2024-10-02 12:22 ` Roger Quadros
0 siblings, 0 replies; 7+ messages in thread
From: Roger Quadros @ 2024-10-02 12:22 UTC (permalink / raw)
To: Andreas Kemnade, Stephen Boyd, Tony Lindgren, Aaro Koskinen,
Kevin Hilman, linux-clk, linux-kernel, Lee Jones, linux-omap,
Michael Turquette
On 02/10/2024 14:07, Andreas Kemnade wrote:
> The TWL6030 has similar clocks, so add support for it. Take care of the
> resource grouping handling needed.
>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> ---
> drivers/clk/Kconfig | 2 +-
> drivers/clk/clk-twl.c | 54 +++++++++++++++++++++++++++++++++----------
> 2 files changed, 43 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 299bc678ed1b..82ec12f9b82c 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -291,7 +291,7 @@ config CLK_TWL
> help
> Enable support for controlling the clock resources on TWL family
> PMICs. These devices have some 32K clock outputs which can be
> - controlled by software. For now, only the TWL6032 clocks are
> + controlled by software. For now, the TWL6032 and TWL6030 clocks are
> supported.
>
> config CLK_TWL6040
> diff --git a/drivers/clk/clk-twl.c b/drivers/clk/clk-twl.c
> index 1d684b358401..f3a52f568887 100644
> --- a/drivers/clk/clk-twl.c
> +++ b/drivers/clk/clk-twl.c
> @@ -11,13 +11,26 @@
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>
> -#define VREG_STATE 2
> +#define VREG_STATE 2
> +#define VREG_GRP 0
> #define TWL6030_CFG_STATE_OFF 0x00
> #define TWL6030_CFG_STATE_ON 0x01
> #define TWL6030_CFG_STATE_MASK 0x03
> +#define TWL6030_CFG_STATE_GRP_SHIFT 5
> +#define TWL6030_CFG_STATE_APP_SHIFT 2
> +#define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
> +#define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
> + TWL6030_CFG_STATE_APP_SHIFT)
> +#define P1_GRP BIT(0) /* processor power group */
> +#define P2_GRP BIT(1)
> +#define P3_GRP BIT(2)
> +#define ALL_GRP (P1_GRP | P2_GRP | P3_GRP)
> +
> +#define DRIVER_DATA_TWL6030 0
> +#define DRIVER_DATA_TWL6032 1
how about using enum here?
enum twl_type {
TWL_TYPE_6030,
TWL_TYPE_6032,
};
>
> struct twl_clock_info {
> - struct device *dev;
> + struct platform_device *pdev;
I wouldn't change this.
Instead, you can add twl_type member here and initialize it in probe.
enum twl_type type;
> u8 base;
> struct clk_hw hw;
> };
> @@ -56,14 +69,21 @@ static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
> static int twl6032_clks_prepare(struct clk_hw *hw)
> {
> struct twl_clock_info *cinfo = to_twl_clks_info(hw);
> - int ret;
>
> - ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> - TWL6030_CFG_STATE_ON);
> - if (ret < 0)
> - dev_err(cinfo->dev, "clk prepare failed\n");
> + if (platform_get_device_id(cinfo->pdev)->driver_data == DRIVER_DATA_TWL6030) {
this changes to
if (cinfo->type == TWL_TYPE_6030)
> + int grp;
>
> - return ret;
> + grp = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_GRP);
> + if (grp < 0)
> + return grp;
> +
> + return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> + grp << TWL6030_CFG_STATE_GRP_SHIFT |
> + TWL6030_CFG_STATE_ON);
> + }
> +
> + return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> + TWL6030_CFG_STATE_ON);
> }
>
> static void twl6032_clks_unprepare(struct clk_hw *hw)
> @@ -71,10 +91,16 @@ static void twl6032_clks_unprepare(struct clk_hw *hw)
> struct twl_clock_info *cinfo = to_twl_clks_info(hw);
> int ret;
>
> - ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> - TWL6030_CFG_STATE_OFF);
> + if (platform_get_device_id(cinfo->pdev)->driver_data == DRIVER_DATA_TWL6030)
here too.
> + ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> + ALL_GRP << TWL6030_CFG_STATE_GRP_SHIFT |
> + TWL6030_CFG_STATE_OFF);
> + else
> + ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
> + TWL6030_CFG_STATE_OFF);
> +
> if (ret < 0)
> - dev_err(cinfo->dev, "clk unprepare failed\n");
> + dev_err(&cinfo->pdev->dev, "clk unprepare failed\n");
> }
>
> static const struct clk_ops twl6032_clks_ops = {
> @@ -137,7 +163,7 @@ static int twl_clks_probe(struct platform_device *pdev)
>
> for (i = 0; i < count; i++) {
> cinfo[i].base = hw_data[i].base;
> - cinfo[i].dev = &pdev->dev;
> + cinfo[i].pdev = pdev;
here we can initialize twl type like so.
cinfo[i].type = platform_get_device_id(pdev)->driver_data;
> cinfo[i].hw.init = &hw_data[i].init;
> ret = devm_clk_hw_register(&pdev->dev, &cinfo[i].hw);
> if (ret) {
> @@ -159,7 +185,11 @@ static int twl_clks_probe(struct platform_device *pdev)
>
> static const struct platform_device_id twl_clks_id[] = {
> {
> + .name = "twl6030-clk",
> + .driver_data = DRIVER_DATA_TWL6030,
TWL_TYPE_6030
> + }, {
> .name = "twl6032-clk",
> + .driver_data = DRIVER_DATA_TWL6032,
TWL_TYPE_6032
> }, {
> /* sentinel */
> }
--
cheers,
-roger
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/3] mfd: twl: Add clock for TWL6030
2024-10-02 11:07 [PATCH v2 0/3] mfd: twl: Add clock for TWL6030 Andreas Kemnade
` (2 preceding siblings ...)
2024-10-02 11:07 ` [PATCH v2 3/3] clk: twl: add TWL6030 support Andreas Kemnade
@ 2024-10-02 13:13 ` Andreas Kemnade
3 siblings, 0 replies; 7+ messages in thread
From: Andreas Kemnade @ 2024-10-02 13:13 UTC (permalink / raw)
To: Stephen Boyd, Tony Lindgren, Aaro Koskinen, Kevin Hilman,
linux-clk, linux-kernel, Lee Jones, linux-omap, Roger Quadros,
Michael Turquette
Am Wed, 2 Oct 2024 13:07:15 +0200
schrieb Andreas Kemnade <andreas@kemnade.info>:
> Previously the clock support for only implemented for TWL6032 so add
> it also for the TWL6030. There are devices out there where especially
> WLAN only works if these clocks are enabled by some patched U-Boot.
> This allows to explicitly specify the clock requirements.
>
oh, forgotten the changelog:
Changes in V2:
- cleanup some defines
- no separate ops for 6030
- remove is_prepared()
- update Kconfig
Regards,
Andreas
^ permalink raw reply [flat|nested] 7+ messages in thread