* [PATCH v4 0/2] add NXP LINFlexD UART clock support for S32G2/S32G3
@ 2024-11-11 11:29 Ciprian Costea
2024-11-11 11:29 ` [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions Ciprian Costea
2024-11-11 11:29 ` [PATCH v4 2/2] serial: fsl_linflexuart: add clock management Ciprian Costea
0 siblings, 2 replies; 6+ messages in thread
From: Ciprian Costea @ 2024-11-11 11:29 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin
Cc: linux-kernel, linux-serial, devicetree, imx, NXP S32 Linux,
Christophe Lizzi, Alberto Ruiz, Enric Balletbo,
Ciprian Marian Costea
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
LINFlexD driver was working on S32 based boards without clock management
because the downstream bootloaders (TF-A [1] and U-Boot [2]) were
performing the LINFlexD clock management.
LINFlexD driver from Linux Kernel should manage its clocks independently
and not rely on a previous bootloader configuration.
[1] https://github.com/nxp-auto-linux/arm-trusted-firmware
[2] https://github.com/nxp-auto-linux/u-boot
Changes in V4:
- Switched clock management to 'clk bulk' API usage
- Added more context for this patchset
Changes in V3:
- Fixed an error reported by 'dt_bindings_check'
Changes in V2:
- Updated bindings by adding more information related to
required LINFlexD clocks
Ciprian Marian Costea (2):
dt-bindings: serial: fsl-linflexuart: add clock definitions
serial: fsl_linflexuart: add clock management
.../bindings/serial/fsl,s32-linflexuart.yaml | 16 ++++
drivers/tty/serial/fsl_linflexuart.c | 82 +++++++++++++++----
2 files changed, 84 insertions(+), 14 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions
2024-11-11 11:29 [PATCH v4 0/2] add NXP LINFlexD UART clock support for S32G2/S32G3 Ciprian Costea
@ 2024-11-11 11:29 ` Ciprian Costea
2024-11-11 20:07 ` Conor Dooley
2024-11-11 11:29 ` [PATCH v4 2/2] serial: fsl_linflexuart: add clock management Ciprian Costea
1 sibling, 1 reply; 6+ messages in thread
From: Ciprian Costea @ 2024-11-11 11:29 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin
Cc: linux-kernel, linux-serial, devicetree, imx, NXP S32 Linux,
Christophe Lizzi, Alberto Ruiz, Enric Balletbo,
Ciprian Marian Costea
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Add clock definitions for NXP LINFlexD UART bindings.
The LINFlexD driver was working because the LINFlexD clocks were
configured and kept enabled by the downstream bootloader (TF-A [1]
and U-Boot [2]). This is not ideal since LINFlexD Linux driver should
manage its clocks independently and not rely on a previous bootloader
configuration.
[1] https://github.com/nxp-auto-linux/arm-trusted-firmware
[2] https://github.com/nxp-auto-linux/u-boot
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
.../bindings/serial/fsl,s32-linflexuart.yaml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
index 4171f524a928..ca3146d9b872 100644
--- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
+++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
@@ -34,10 +34,24 @@ properties:
interrupts:
maxItems: 1
+ clocks:
+ items:
+ - description:
+ ipg clock drives the access to the LINFlexD
+ iomapped registers
+ - description: lin is the frequency of the baud clock
+
+ clock-names:
+ items:
+ - const: ipg
+ - const: lin
+
required:
- compatible
- reg
- interrupts
+ - clocks
+ - clock-names
unevaluatedProperties: false
@@ -47,4 +61,6 @@ examples:
compatible = "fsl,s32v234-linflexuart";
reg = <0x40053000 0x1000>;
interrupts = <0 59 4>;
+ clocks = <&clks 132>, <&clks 131>;
+ clock-names = "ipg", "lin";
};
--
2.45.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/2] serial: fsl_linflexuart: add clock management
2024-11-11 11:29 [PATCH v4 0/2] add NXP LINFlexD UART clock support for S32G2/S32G3 Ciprian Costea
2024-11-11 11:29 ` [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions Ciprian Costea
@ 2024-11-11 11:29 ` Ciprian Costea
2024-11-11 21:57 ` Frank Li
1 sibling, 1 reply; 6+ messages in thread
From: Ciprian Costea @ 2024-11-11 11:29 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin
Cc: linux-kernel, linux-serial, devicetree, imx, NXP S32 Linux,
Christophe Lizzi, Alberto Ruiz, Enric Balletbo,
Ciprian Marian Costea
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Add optional clock 'ipg' and 'lin' support to NXP LINFlexD UART driver,
which is used by S32G2 and S32G3 SoCs.
LINFlex driver should perform clock management and not rely on a previous
bootloader configuration.
Clocking support is added as optional in order to not break existing
support for S32V234 SoC. Therefore, there should be no impact if not
providing LINFlexD clocks and continue to rely on a bootloader clock
configuration and enablement.
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
drivers/tty/serial/fsl_linflexuart.c | 82 +++++++++++++++++++++++-----
1 file changed, 68 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c
index e972df4b188d..66b822f36d06 100644
--- a/drivers/tty/serial/fsl_linflexuart.c
+++ b/drivers/tty/serial/fsl_linflexuart.c
@@ -3,9 +3,10 @@
* Freescale LINFlexD UART serial port driver
*
* Copyright 2012-2016 Freescale Semiconductor, Inc.
- * Copyright 2017-2019 NXP
+ * Copyright 2017-2019, 2024 NXP
*/
+#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -120,9 +121,29 @@
#define PREINIT_DELAY 2000 /* us */
+struct linflex_devtype_data {
+ const char * const *clks_names;
+ int n_clks;
+};
+
+struct linflex_port {
+ struct uart_port port;
+ struct clk_bulk_data *clks;
+ const struct linflex_devtype_data *devtype_data;
+};
+
+static const char * const s32v234_clk_names[] = {
+ "ipg", "lin",
+};
+
+static const struct linflex_devtype_data s32v234_data = {
+ .clks_names = s32v234_clk_names,
+ .n_clks = ARRAY_SIZE(s32v234_clk_names),
+};
+
static const struct of_device_id linflex_dt_ids[] = {
{
- .compatible = "fsl,s32v234-linflexuart",
+ .compatible = "fsl,s32v234-linflexuart", .data = &s32v234_data,
},
{ /* sentinel */ }
};
@@ -807,12 +828,13 @@ static struct uart_driver linflex_reg = {
static int linflex_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ struct linflex_port *lfport;
struct uart_port *sport;
struct resource *res;
- int ret;
+ int i, ret;
- sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
- if (!sport)
+ lfport = devm_kzalloc(&pdev->dev, sizeof(*lfport), GFP_KERNEL);
+ if (!lfport)
return -ENOMEM;
ret = of_alias_get_id(np, "serial");
@@ -826,8 +848,14 @@ static int linflex_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ sport = &lfport->port;
sport->line = ret;
+ lfport->devtype_data = of_device_get_match_data(&pdev->dev);
+ if (!lfport->devtype_data)
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Failed to get linflexuart driver data\n");
+
sport->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(sport->membase))
return PTR_ERR(sport->membase);
@@ -844,37 +872,63 @@ static int linflex_probe(struct platform_device *pdev)
sport->flags = UPF_BOOT_AUTOCONF;
sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE);
- linflex_ports[sport->line] = sport;
+ lfport->clks = devm_kmalloc_array(&pdev->dev, lfport->devtype_data->n_clks,
+ sizeof(*lfport->clks), GFP_KERNEL);
+ if (!lfport->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < lfport->devtype_data->n_clks; i++)
+ lfport->clks[i].id = lfport->devtype_data->clks_names[i];
+
+ ret = devm_clk_bulk_get_optional(&pdev->dev,
+ lfport->devtype_data->n_clks, lfport->clks);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to get linflexuart clocks\n");
+
+ ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
+ lfport->clks);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to enable linflexuart clocks\n");
- platform_set_drvdata(pdev, sport);
+ linflex_ports[sport->line] = sport;
+ platform_set_drvdata(pdev, lfport);
return uart_add_one_port(&linflex_reg, sport);
}
static void linflex_remove(struct platform_device *pdev)
{
- struct uart_port *sport = platform_get_drvdata(pdev);
+ struct linflex_port *lfport = platform_get_drvdata(pdev);
- uart_remove_one_port(&linflex_reg, sport);
+ uart_remove_one_port(&linflex_reg, &lfport->port);
}
#ifdef CONFIG_PM_SLEEP
static int linflex_suspend(struct device *dev)
{
- struct uart_port *sport = dev_get_drvdata(dev);
+ struct linflex_port *lfport = dev_get_drvdata(dev);
+
+ uart_suspend_port(&linflex_reg, &lfport->port);
- uart_suspend_port(&linflex_reg, sport);
+ clk_bulk_disable_unprepare(lfport->devtype_data->n_clks,
+ lfport->clks);
return 0;
}
static int linflex_resume(struct device *dev)
{
- struct uart_port *sport = dev_get_drvdata(dev);
+ struct linflex_port *lfport = dev_get_drvdata(dev);
+ int ret;
- uart_resume_port(&linflex_reg, sport);
+ ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
+ lfport->clks);
+ if (ret)
+ return ret;
- return 0;
+ return uart_resume_port(&linflex_reg, &lfport->port);
}
#endif
--
2.45.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions
2024-11-11 11:29 ` [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions Ciprian Costea
@ 2024-11-11 20:07 ` Conor Dooley
0 siblings, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2024-11-11 20:07 UTC (permalink / raw)
To: Ciprian Costea
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin, linux-kernel, linux-serial, devicetree,
imx, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
[-- Attachment #1: Type: text/plain, Size: 746 bytes --]
On Mon, Nov 11, 2024 at 01:29:20PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>
> Add clock definitions for NXP LINFlexD UART bindings.
>
> The LINFlexD driver was working because the LINFlexD clocks were
> configured and kept enabled by the downstream bootloader (TF-A [1]
> and U-Boot [2]). This is not ideal since LINFlexD Linux driver should
> manage its clocks independently and not rely on a previous bootloader
> configuration.
>
> [1] https://github.com/nxp-auto-linux/arm-trusted-firmware
> [2] https://github.com/nxp-auto-linux/u-boot
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] serial: fsl_linflexuart: add clock management
2024-11-11 11:29 ` [PATCH v4 2/2] serial: fsl_linflexuart: add clock management Ciprian Costea
@ 2024-11-11 21:57 ` Frank Li
2024-11-12 17:36 ` Ciprian Marian Costea
0 siblings, 1 reply; 6+ messages in thread
From: Frank Li @ 2024-11-11 21:57 UTC (permalink / raw)
To: Ciprian Costea
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin, linux-kernel, linux-serial, devicetree,
imx, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
On Mon, Nov 11, 2024 at 01:29:21PM +0200, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>
> Add optional clock 'ipg' and 'lin' support to NXP LINFlexD UART driver,
> which is used by S32G2 and S32G3 SoCs.
>
> LINFlex driver should perform clock management and not rely on a previous
> bootloader configuration.
>
> Clocking support is added as optional in order to not break existing
> support for S32V234 SoC. Therefore, there should be no impact if not
> providing LINFlexD clocks and continue to rely on a bootloader clock
> configuration and enablement.
>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
> ---
> drivers/tty/serial/fsl_linflexuart.c | 82 +++++++++++++++++++++++-----
> 1 file changed, 68 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c
> index e972df4b188d..66b822f36d06 100644
> --- a/drivers/tty/serial/fsl_linflexuart.c
> +++ b/drivers/tty/serial/fsl_linflexuart.c
> @@ -3,9 +3,10 @@
> * Freescale LINFlexD UART serial port driver
> *
> * Copyright 2012-2016 Freescale Semiconductor, Inc.
> - * Copyright 2017-2019 NXP
> + * Copyright 2017-2019, 2024 NXP
> */
>
> +#include <linux/clk.h>
> #include <linux/console.h>
> #include <linux/io.h>
> #include <linux/irq.h>
> @@ -120,9 +121,29 @@
>
> #define PREINIT_DELAY 2000 /* us */
>
> +struct linflex_devtype_data {
> + const char * const *clks_names;
> + int n_clks;
> +};
> +
> +struct linflex_port {
> + struct uart_port port;
> + struct clk_bulk_data *clks;
> + const struct linflex_devtype_data *devtype_data;
> +};
> +
> +static const char * const s32v234_clk_names[] = {
> + "ipg", "lin",
> +};
> +
> +static const struct linflex_devtype_data s32v234_data = {
> + .clks_names = s32v234_clk_names,
> + .n_clks = ARRAY_SIZE(s32v234_clk_names),
> +};
> +
> static const struct of_device_id linflex_dt_ids[] = {
> {
> - .compatible = "fsl,s32v234-linflexuart",
> + .compatible = "fsl,s32v234-linflexuart", .data = &s32v234_data,
> },
> { /* sentinel */ }
> };
> @@ -807,12 +828,13 @@ static struct uart_driver linflex_reg = {
> static int linflex_probe(struct platform_device *pdev)
> {
> struct device_node *np = pdev->dev.of_node;
> + struct linflex_port *lfport;
> struct uart_port *sport;
> struct resource *res;
> - int ret;
> + int i, ret;
>
> - sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
> - if (!sport)
> + lfport = devm_kzalloc(&pdev->dev, sizeof(*lfport), GFP_KERNEL);
> + if (!lfport)
> return -ENOMEM;
>
> ret = of_alias_get_id(np, "serial");
> @@ -826,8 +848,14 @@ static int linflex_probe(struct platform_device *pdev)
> return -ENOMEM;
> }
>
> + sport = &lfport->port;
> sport->line = ret;
>
> + lfport->devtype_data = of_device_get_match_data(&pdev->dev);
> + if (!lfport->devtype_data)
> + return dev_err_probe(&pdev->dev, -ENODEV,
> + "Failed to get linflexuart driver data\n");
> +
> sport->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> if (IS_ERR(sport->membase))
> return PTR_ERR(sport->membase);
> @@ -844,37 +872,63 @@ static int linflex_probe(struct platform_device *pdev)
> sport->flags = UPF_BOOT_AUTOCONF;
> sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE);
>
> - linflex_ports[sport->line] = sport;
> + lfport->clks = devm_kmalloc_array(&pdev->dev, lfport->devtype_data->n_clks,
> + sizeof(*lfport->clks), GFP_KERNEL);
> + if (!lfport->clks)
> + return -ENOMEM;
> +
> + for (i = 0; i < lfport->devtype_data->n_clks; i++)
> + lfport->clks[i].id = lfport->devtype_data->clks_names[i];
> +
> + ret = devm_clk_bulk_get_optional(&pdev->dev,
> + lfport->devtype_data->n_clks, lfport->clks);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret,
> + "Failed to get linflexuart clocks\n");
> +
> + ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
> + lfport->clks);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret,
> + "Failed to enable linflexuart clocks\n");
devm_clk_bulk_get_all_enable() will be more simple. If use
clk_bulk_prepare_enable() here, you need add a customer action
devm_add_action_or_reset() otherwise if uart_add_one_port() failure,
all clocks will be enabled.
Frank
>
> - platform_set_drvdata(pdev, sport);
> + linflex_ports[sport->line] = sport;
> + platform_set_drvdata(pdev, lfport);
>
> return uart_add_one_port(&linflex_reg, sport);
> }
>
> static void linflex_remove(struct platform_device *pdev)
> {
> - struct uart_port *sport = platform_get_drvdata(pdev);
> + struct linflex_port *lfport = platform_get_drvdata(pdev);
>
> - uart_remove_one_port(&linflex_reg, sport);
> + uart_remove_one_port(&linflex_reg, &lfport->port);
> }
>
> #ifdef CONFIG_PM_SLEEP
> static int linflex_suspend(struct device *dev)
> {
> - struct uart_port *sport = dev_get_drvdata(dev);
> + struct linflex_port *lfport = dev_get_drvdata(dev);
> +
> + uart_suspend_port(&linflex_reg, &lfport->port);
>
> - uart_suspend_port(&linflex_reg, sport);
> + clk_bulk_disable_unprepare(lfport->devtype_data->n_clks,
> + lfport->clks);
>
> return 0;
> }
>
> static int linflex_resume(struct device *dev)
> {
> - struct uart_port *sport = dev_get_drvdata(dev);
> + struct linflex_port *lfport = dev_get_drvdata(dev);
> + int ret;
>
> - uart_resume_port(&linflex_reg, sport);
> + ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
> + lfport->clks);
> + if (ret)
> + return ret;
>
> - return 0;
> + return uart_resume_port(&linflex_reg, &lfport->port);
> }
> #endif
>
> --
> 2.45.2
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] serial: fsl_linflexuart: add clock management
2024-11-11 21:57 ` Frank Li
@ 2024-11-12 17:36 ` Ciprian Marian Costea
0 siblings, 0 replies; 6+ messages in thread
From: Ciprian Marian Costea @ 2024-11-12 17:36 UTC (permalink / raw)
To: Frank Li
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chester Lin, linux-kernel, linux-serial, devicetree,
imx, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
On 11/11/2024 11:57 PM, Frank Li wrote:
> On Mon, Nov 11, 2024 at 01:29:21PM +0200, Ciprian Costea wrote:
>> From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>>
>> Add optional clock 'ipg' and 'lin' support to NXP LINFlexD UART driver,
>> which is used by S32G2 and S32G3 SoCs.
>>
>> LINFlex driver should perform clock management and not rely on a previous
>> bootloader configuration.
>>
>> Clocking support is added as optional in order to not break existing
>> support for S32V234 SoC. Therefore, there should be no impact if not
>> providing LINFlexD clocks and continue to rely on a bootloader clock
>> configuration and enablement.
>>
>> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>> ---
>> drivers/tty/serial/fsl_linflexuart.c | 82 +++++++++++++++++++++++-----
>> 1 file changed, 68 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c
>> index e972df4b188d..66b822f36d06 100644
>> --- a/drivers/tty/serial/fsl_linflexuart.c
>> +++ b/drivers/tty/serial/fsl_linflexuart.c
>> @@ -3,9 +3,10 @@
>> * Freescale LINFlexD UART serial port driver
>> *
>> * Copyright 2012-2016 Freescale Semiconductor, Inc.
>> - * Copyright 2017-2019 NXP
>> + * Copyright 2017-2019, 2024 NXP
>> */
>>
>> +#include <linux/clk.h>
>> #include <linux/console.h>
>> #include <linux/io.h>
>> #include <linux/irq.h>
>> @@ -120,9 +121,29 @@
>>
>> #define PREINIT_DELAY 2000 /* us */
>>
>> +struct linflex_devtype_data {
>> + const char * const *clks_names;
>> + int n_clks;
>> +};
>> +
>> +struct linflex_port {
>> + struct uart_port port;
>> + struct clk_bulk_data *clks;
>> + const struct linflex_devtype_data *devtype_data;
>> +};
>> +
>> +static const char * const s32v234_clk_names[] = {
>> + "ipg", "lin",
>> +};
>> +
>> +static const struct linflex_devtype_data s32v234_data = {
>> + .clks_names = s32v234_clk_names,
>> + .n_clks = ARRAY_SIZE(s32v234_clk_names),
>> +};
>> +
>> static const struct of_device_id linflex_dt_ids[] = {
>> {
>> - .compatible = "fsl,s32v234-linflexuart",
>> + .compatible = "fsl,s32v234-linflexuart", .data = &s32v234_data,
>> },
>> { /* sentinel */ }
>> };
>> @@ -807,12 +828,13 @@ static struct uart_driver linflex_reg = {
>> static int linflex_probe(struct platform_device *pdev)
>> {
>> struct device_node *np = pdev->dev.of_node;
>> + struct linflex_port *lfport;
>> struct uart_port *sport;
>> struct resource *res;
>> - int ret;
>> + int i, ret;
>>
>> - sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
>> - if (!sport)
>> + lfport = devm_kzalloc(&pdev->dev, sizeof(*lfport), GFP_KERNEL);
>> + if (!lfport)
>> return -ENOMEM;
>>
>> ret = of_alias_get_id(np, "serial");
>> @@ -826,8 +848,14 @@ static int linflex_probe(struct platform_device *pdev)
>> return -ENOMEM;
>> }
>>
>> + sport = &lfport->port;
>> sport->line = ret;
>>
>> + lfport->devtype_data = of_device_get_match_data(&pdev->dev);
>> + if (!lfport->devtype_data)
>> + return dev_err_probe(&pdev->dev, -ENODEV,
>> + "Failed to get linflexuart driver data\n");
>> +
>> sport->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
>> if (IS_ERR(sport->membase))
>> return PTR_ERR(sport->membase);
>> @@ -844,37 +872,63 @@ static int linflex_probe(struct platform_device *pdev)
>> sport->flags = UPF_BOOT_AUTOCONF;
>> sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE);
>>
>> - linflex_ports[sport->line] = sport;
>> + lfport->clks = devm_kmalloc_array(&pdev->dev, lfport->devtype_data->n_clks,
>> + sizeof(*lfport->clks), GFP_KERNEL);
>> + if (!lfport->clks)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < lfport->devtype_data->n_clks; i++)
>> + lfport->clks[i].id = lfport->devtype_data->clks_names[i];
>> +
>> + ret = devm_clk_bulk_get_optional(&pdev->dev,
>> + lfport->devtype_data->n_clks, lfport->clks);
>> + if (ret)
>> + return dev_err_probe(&pdev->dev, ret,
>> + "Failed to get linflexuart clocks\n");
>> +
>> + ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
>> + lfport->clks);
>> + if (ret)
>> + return dev_err_probe(&pdev->dev, ret,
>> + "Failed to enable linflexuart clocks\n");
>
> devm_clk_bulk_get_all_enable() will be more simple. If use
> clk_bulk_prepare_enable() here, you need add a customer action
> devm_add_action_or_reset() otherwise if uart_add_one_port() failure,
> all clocks will be enabled.
>
> Frank
>
Thanks for pointing this out. I will add 'devm_add_action_or_reset' for
handling clks disablement and keep clock management as optional in the
LINFlexD driver.
Ciprian
>>
>> - platform_set_drvdata(pdev, sport);
>> + linflex_ports[sport->line] = sport;
>> + platform_set_drvdata(pdev, lfport);
>>
>> return uart_add_one_port(&linflex_reg, sport);
>> }
>>
>> static void linflex_remove(struct platform_device *pdev)
>> {
>> - struct uart_port *sport = platform_get_drvdata(pdev);
>> + struct linflex_port *lfport = platform_get_drvdata(pdev);
>>
>> - uart_remove_one_port(&linflex_reg, sport);
>> + uart_remove_one_port(&linflex_reg, &lfport->port);
>> }
>>
>> #ifdef CONFIG_PM_SLEEP
>> static int linflex_suspend(struct device *dev)
>> {
>> - struct uart_port *sport = dev_get_drvdata(dev);
>> + struct linflex_port *lfport = dev_get_drvdata(dev);
>> +
>> + uart_suspend_port(&linflex_reg, &lfport->port);
>>
>> - uart_suspend_port(&linflex_reg, sport);
>> + clk_bulk_disable_unprepare(lfport->devtype_data->n_clks,
>> + lfport->clks);
>>
>> return 0;
>> }
>>
>> static int linflex_resume(struct device *dev)
>> {
>> - struct uart_port *sport = dev_get_drvdata(dev);
>> + struct linflex_port *lfport = dev_get_drvdata(dev);
>> + int ret;
>>
>> - uart_resume_port(&linflex_reg, sport);
>> + ret = clk_bulk_prepare_enable(lfport->devtype_data->n_clks,
>> + lfport->clks);
>> + if (ret)
>> + return ret;
>>
>> - return 0;
>> + return uart_resume_port(&linflex_reg, &lfport->port);
>> }
>> #endif
>>
>> --
>> 2.45.2
>>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-11-12 17:36 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-11 11:29 [PATCH v4 0/2] add NXP LINFlexD UART clock support for S32G2/S32G3 Ciprian Costea
2024-11-11 11:29 ` [PATCH v4 1/2] dt-bindings: serial: fsl-linflexuart: add clock definitions Ciprian Costea
2024-11-11 20:07 ` Conor Dooley
2024-11-11 11:29 ` [PATCH v4 2/2] serial: fsl_linflexuart: add clock management Ciprian Costea
2024-11-11 21:57 ` Frank Li
2024-11-12 17:36 ` Ciprian Marian Costea
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox