[PATCH 1/6] serial: samsung: Keep a copy of platform data in driver's private data

Grant Likely grant.likely at secretlab.ca
Mon Jun 20 11:54:58 EDT 2011


On Mon, Jun 20, 2011 at 5:02 AM, Thomas Abraham
<thomas.abraham at linaro.org> wrote:
> The driver depends on pdev->dev.platform_data to retrive information
> about the platform data even after the initialization. To add device
> tree support, this has to be changed in way that the platform data
> is avialable from driver's private data. This patch adds support
> for keeping a copy of the plaform data in s3c24xx_uart_info and using
> it when needed after the initialization.
>
> Signed-off-by: Thomas Abraham <thomas.abraham at linaro.org>
> ---
>  drivers/tty/serial/s5pv210.c |   12 ++++++++++--
>  drivers/tty/serial/samsung.c |   24 ++++++++++++++++++++----
>  drivers/tty/serial/samsung.h |    4 +++-
>  3 files changed, 33 insertions(+), 7 deletions(-)

Hi Thomas.

Don't forget you need to cc Alan Cox and the linux-serial mailing list
for tty driver patches.

Comments below...

>
> diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
> index d6b2423..3b2021a 100644
> --- a/drivers/tty/serial/s5pv210.c
> +++ b/drivers/tty/serial/s5pv210.c
> @@ -27,9 +27,13 @@
>  static int s5pv210_serial_setsource(struct uart_port *port,
>                                        struct s3c24xx_uart_clksrc *clk)
>  {
> -       struct s3c2410_uartcfg *cfg = port->dev->platform_data;
> +       struct s3c24xx_uart_port *ourport;
> +       struct s3c2410_uartcfg *cfg;
>        unsigned long ucon = rd_regl(port, S3C2410_UCON);
>
> +       ourport = container_of(port, struct s3c24xx_uart_port, port);
> +       cfg = &ourport->info->cfg;
> +
>        if ((cfg->clocks_size) == 1)
>                return 0;
>
> @@ -50,9 +54,13 @@ static int s5pv210_serial_setsource(struct uart_port *port,
>  static int s5pv210_serial_getsource(struct uart_port *port,
>                                        struct s3c24xx_uart_clksrc *clk)
>  {
> -       struct s3c2410_uartcfg *cfg = port->dev->platform_data;
> +       struct s3c24xx_uart_port *ourport;
> +       struct s3c2410_uartcfg *cfg;
>        u32 ucon = rd_regl(port, S3C2410_UCON);
>
> +       ourport = container_of(port, struct s3c24xx_uart_port, port);
> +       cfg = &ourport->info->cfg;
> +
>        clk->divisor = 1;
>
>        if ((cfg->clocks_size) == 1)
> diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
> index 7ead421..77d900f 100644
> --- a/drivers/tty/serial/samsung.c
> +++ b/drivers/tty/serial/samsung.c
> @@ -42,6 +42,7 @@
>  #include <linux/delay.h>
>  #include <linux/clk.h>
>  #include <linux/cpufreq.h>
> +#include <linux/slab.h>
>
>  #include <asm/irq.h>
>
> @@ -169,10 +170,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p
>
>  static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
>  {
> +       struct s3c24xx_uart_port *ourport;
> +
>        if (port->dev == NULL)
>                return NULL;
>
> -       return (struct s3c2410_uartcfg *)port->dev->platform_data;
> +       ourport = container_of(port, struct s3c24xx_uart_port, port);
> +       return &ourport->info->cfg;
>  }
>
>  static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
> @@ -1053,7 +1057,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
>                                    struct platform_device *platdev)
>  {
>        struct uart_port *port = &ourport->port;
> -       struct s3c2410_uartcfg *cfg;
> +       struct s3c2410_uartcfg *cfg = platdev->dev.platform_data;
>        struct resource *res;
>        int ret;
>
> @@ -1062,14 +1066,24 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
>        if (platdev == NULL)
>                return -ENODEV;
>
> -       cfg = s3c24xx_dev_to_cfg(&platdev->dev);
> -
>        if (port->mapbase != 0)
>                return 0;
>
> +       if (cfg) {
> +               memcpy((void *)&info->cfg, cfg, sizeof(struct s3c2410_uartcfg));

"info->cfg = *cfg;" should be sufficient.

> +               info->cfg.clocks = kzalloc(sizeof(struct s3c24xx_uart_clksrc) *
> +                                       cfg->clocks_size, GFP_KERNEL);
> +               if (!info->cfg.clocks)
> +                       return -ENOMEM;
> +               memcpy(info->cfg.clocks, cfg->clocks,
> +                       sizeof(struct s3c24xx_uart_clksrc) * cfg->clocks_size);
> +       }

ewwh. There has to be a better way to do this.  Part of the point of
putting a copy of pdata into the private data structure is to simplify
the driver so that kzallocing wouldn't be necessary.  With that clock
table, the driver actually gets more complex because both DT and
non-DT paths now need to kzalloc a clock array.



More information about the linux-arm-kernel mailing list