Sounds good, I fixed up the patch and will submit it again.  There are
a couple of warnings from checkpath.pl still but I don't
think they need to be fixed up.  I can post the output if anyone would
like to see it.  I also had the original publisher wrong,
I fixed that up and added the sign off at the bottom.

Let me know if I missed anything.

Thanks

Greg

On Mon, Jan 8, 2018 at 1:03 PM, Jan Kiszka <jan.kis...@siemens.com> wrote:
> On 2018-01-08 18:52, Greg Gallagher wrote:
>> Hi,
>>  The patch I submitted was based on one that was submitted by Wolfgang
>> Netbal back in Feb
>>  2016.  The original thread that this patch was derived from is located here
>> https://xenomai.org/pipermail/xenomai/2016-February/035924.html
>>
>> Just wanted to make sure proper credit was given, I think I put this
>> info in the patch as well.
>
> Just write a commit message (which is desirable anyway) and mention the
> origin there. In case you barely changed the original version, you could
> also leave the original author in place by starting the body with "From:
> Author <email>" and then just mention your changes at the end of the log
> message (usually before your signed-off-by, but Xenomai does not enforce
> that protocol yet).
>
> Could you sort out the unrelated style changes? Preferred style is that
> of the kernel. The kernel has a checker (scripts/checkpatch.pl), which
> does not mean there can be sometimes exceptions, but it should not a
> guideline still.
>
> Thanks for picking this up!
> Jan
>
>>
>> -Greg
>>
>> On Mon, Jan 8, 2018 at 12:49 PM, Greg Gallagher <g...@embeddedgreg.com> 
>> wrote:
>>> ---
>>>  kernel/drivers/serial/rt_imx_uart.c | 299 
>>> ++++++++++++++++++++++++------------
>>>  1 file changed, 204 insertions(+), 95 deletions(-)
>>>
>>> diff --git a/kernel/drivers/serial/rt_imx_uart.c 
>>> b/kernel/drivers/serial/rt_imx_uart.c
>>> index 092cecc..db63df6 100644
>>> --- a/kernel/drivers/serial/rt_imx_uart.c
>>> +++ b/kernel/drivers/serial/rt_imx_uart.c
>>> @@ -36,8 +36,10 @@
>>>  #include <asm/irq.h>
>>>  #include <asm/dma.h>
>>>  #include <asm/div64.h>
>>> -#include <mach/hardware.h>
>>> -#include <mach/imx-uart.h>
>>> +#include <linux/platform_data/serial-imx.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_device.h>
>>>
>>>  #include <rtdm/serial.h>
>>>  #include <rtdm/driver.h>
>>> @@ -65,7 +67,10 @@ MODULE_LICENSE("GPL");
>>>  #define UBMR   0xa8 /* BRM Modulator Register */
>>>  #define UBRC   0xac /* Baud Rate Count Register */
>>>  #define MX2_ONEMS 0xb0 /* One Millisecond register */
>>> -#define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */
>>> +#define IMX1_UTS 0xd0 /* UART Test Register on i.mx1 */
>>> +#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
>>> +
>>> +
>>>
>>>  /* UART Control Register Bit Fields.*/
>>>  #define URXD_CHARRDY   (1<<15)
>>> @@ -189,9 +194,25 @@ MODULE_LICENSE("GPL");
>>>  #define RT_IMX_UART_MAX                5
>>>
>>>  static int tx_fifo[RT_IMX_UART_MAX];
>>> -compat_module_param_array(tx_fifo, int, RT_IMX_UART_MAX, 0400);
>>> +module_param_array(tx_fifo, int, NULL, 0400);
>>>  MODULE_PARM_DESC(tx_fifo, "Transmitter FIFO size");
>>>
>>> +/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
>>> +enum imx_uart_type {
>>> +       IMX1_UART,
>>> +       IMX21_UART,
>>> +       IMX53_UART,
>>> +       IMX6Q_UART,
>>> +        IMX7D_UART,
>>> +};
>>> +
>>> +/* device type dependent stuff */
>>> +struct imx_uart_data {
>>> +       unsigned uts_reg;
>>> +       enum imx_uart_type devtype;
>>> +};
>>> +
>>> +
>>>  struct rt_imx_uart_port {
>>>         unsigned char __iomem *membase; /* read/write[bwl] */
>>>         resource_size_t mapbase;        /* for ioremap */
>>> @@ -200,11 +221,69 @@ struct rt_imx_uart_port {
>>>         unsigned int have_rtscts;
>>>         unsigned int use_dcedte;
>>>         unsigned int use_hwflow;
>>> -       struct clk *clk;                /* clock id for UART clock */
>>> -       unsigned int uartclk;           /* base uart clock */
>>> +       struct clk *clk_ipg;            /* clock id for UART clock */
>>> +       struct clk *clk_per;            /* clock id for UART clock */
>>> +        const struct imx_uart_data *devdata;
>>> +        unsigned int uartclk;          /* base uart clock */
>>>         struct rtdm_device rtdm_dev;    /* RTDM device structure */
>>>  };
>>>
>>> +
>>> +static struct imx_uart_data imx_uart_devdata[] = {
>>> +       [IMX1_UART] = {
>>> +               .uts_reg = IMX1_UTS,
>>> +               .devtype = IMX1_UART,
>>> +       },
>>> +       [IMX21_UART] = {
>>> +               .uts_reg = IMX21_UTS,
>>> +               .devtype = IMX21_UART,
>>> +       },
>>> +       [IMX53_UART] = {
>>> +               .uts_reg = IMX21_UTS,
>>> +               .devtype = IMX53_UART,
>>> +       },
>>> +       [IMX6Q_UART] = {
>>> +               .uts_reg = IMX21_UTS,
>>> +               .devtype = IMX6Q_UART,
>>> +       },
>>> +        [IMX7D_UART] = {
>>> +                .uts_reg = IMX21_UTS,
>>> +                .devtype = IMX7D_UART,
>>> +        },
>>> +};
>>> +
>>> +static const struct platform_device_id rt_imx_uart_id_table[] = {
>>> +        {
>>> +               .name = "imx1-uart",
>>> +               .driver_data = (kernel_ulong_t) 
>>> &imx_uart_devdata[IMX1_UART],
>>> +       }, {
>>> +               .name = "imx21-uart",
>>> +               .driver_data = (kernel_ulong_t) 
>>> &imx_uart_devdata[IMX21_UART],
>>> +       }, {
>>> +               .name = "imx53-uart",
>>> +               .driver_data = (kernel_ulong_t) 
>>> &imx_uart_devdata[IMX53_UART],
>>> +       }, {
>>> +               .name = "imx6q-uart",
>>> +               .driver_data = (kernel_ulong_t) 
>>> &imx_uart_devdata[IMX6Q_UART],
>>> +       }, {
>>> +                .name = "imx-uart",
>>> +                .driver_data = (kernel_ulong_t) 
>>> &imx_uart_devdata[IMX7D_UART],
>>> +        }, {
>>> +               /* sentinel */
>>> +       }
>>> +};
>>> +MODULE_DEVICE_TABLE(platform, rt_imx_uart_id_table);
>>> +
>>> +static const struct of_device_id rt_imx_uart_dt_ids[] = {
>>> +       { .compatible = "fsl,imx7d-uart", .data = 
>>> &imx_uart_devdata[IMX7D_UART], },
>>> +        { .compatible = "fsl,imx6q-uart", .data = 
>>> &imx_uart_devdata[IMX6Q_UART], },
>>> +       { .compatible = "fsl,imx53-uart", .data = 
>>> &imx_uart_devdata[IMX53_UART], },
>>> +       { .compatible = "fsl,imx1-uart", .data = 
>>> &imx_uart_devdata[IMX1_UART], },
>>> +       { .compatible = "fsl,imx21-uart", .data = 
>>> &imx_uart_devdata[IMX21_UART], },
>>> +       { /* sentinel */ }
>>> +};
>>> +MODULE_DEVICE_TABLE(of, rt_imx_uart_dt_ids);
>>> +
>>>  struct rt_imx_uart_ctx {
>>>         struct rtser_config config;     /* current device configuration */
>>>
>>> @@ -344,6 +423,7 @@ static int rt_imx_uart_rx_chars(struct rt_imx_uart_ctx 
>>> *ctx,
>>>  static void rt_imx_uart_tx_chars(struct rt_imx_uart_ctx *ctx)
>>>  {
>>>         int ch, count;
>>> +        unsigned uts_reg = ctx->port->devdata->uts_reg;
>>>
>>>         for (count = ctx->port->tx_fifo;
>>>              (count > 0) && (ctx->out_npend > 0);
>>> @@ -352,7 +432,7 @@ static void rt_imx_uart_tx_chars(struct rt_imx_uart_ctx 
>>> *ctx)
>>>                 writel(ch, ctx->port->membase + URTX0);
>>>                 ctx->out_head &= (OUT_BUFFER_SIZE - 1);
>>>
>>> -               if (readl(ctx->port->membase + UTS) & UTS_TXFULL)
>>> +               if (readl(ctx->port->membase + uts_reg) & UTS_TXFULL)
>>>                         break;
>>>         }
>>>  }
>>> @@ -493,9 +573,10 @@ static unsigned int rt_imx_uart_get_msr(struct 
>>> rt_imx_uart_ctx *ctx)
>>>  static void rt_imx_uart_set_mcr(struct rt_imx_uart_ctx *ctx,
>>>                                 unsigned int mcr)
>>>  {
>>> -       unsigned long ucr2 = readl(ctx->port->membase + UCR2);
>>> +       unsigned uts_reg = ctx->port->devdata->uts_reg;
>>> +        unsigned long ucr2 = readl(ctx->port->membase + UCR2);
>>>         unsigned long ucr3 = readl(ctx->port->membase + UCR3);
>>> -       unsigned long uts = readl(ctx->port->membase + UTS);
>>> +       unsigned long uts = readl(ctx->port->membase + uts_reg);
>>>
>>>         if (mcr & RTSER_MCR_RTS) {
>>>                 /*
>>> @@ -523,7 +604,7 @@ static void rt_imx_uart_set_mcr(struct rt_imx_uart_ctx 
>>> *ctx,
>>>                 uts |= UTS_LOOP;
>>>         else
>>>                 uts &= ~UTS_LOOP;
>>> -       writel(uts, ctx->port->membase + UTS);
>>> +       writel(uts, ctx->port->membase + uts_reg);
>>>  }
>>>
>>>  static void rt_imx_uart_break_ctl(struct rt_imx_uart_ctx *ctx,
>>> @@ -723,7 +804,7 @@ static int rt_imx_uart_setup_ufcr(struct 
>>> rt_imx_uart_port *port)
>>>          * RFDIV is set such way to satisfy requested uartclk value
>>>          */
>>>         val = TXTL << 10 | RXTL;
>>> -       ufcr_rfdiv = (clk_get_rate(port->clk) + port->uartclk / 2) /
>>> +       ufcr_rfdiv = (clk_get_rate(port->clk_per) + port->uartclk / 2) /
>>>                 port->uartclk;
>>>
>>>         if (!ufcr_rfdiv)
>>> @@ -897,7 +978,7 @@ static int rt_imx_uart_ioctl(struct rtdm_fd *fd,
>>>                 }
>>>
>>>                 if ((config->config_mask & RTSER_SET_BAUD) &&
>>> -                   (config->baud_rate > clk_get_rate(ctx->port->clk) / 16 
>>> ||
>>> +                   (config->baud_rate > clk_get_rate(ctx->port->clk_per) / 
>>> 16 ||
>>>                      config->baud_rate <= 0))
>>>                         /* invalid baudrate for this port */
>>>                         return -EINVAL;
>>> @@ -1382,42 +1463,96 @@ static struct rtdm_driver imx_uart_driver = {
>>>         },
>>>  };
>>>
>>> +
>>> +#ifdef CONFIG_OF
>>> +
>>> +/*
>>> + * This function returns 1 iff pdev isn't a device instatiated by dt, 0 
>>> iff it
>>> + * could successfully get all information from dt or a negative errno.
>>> + */
>>> +static int rt_imx_uart_probe_dt(struct rt_imx_uart_port *port,
>>> +                                struct platform_device *pdev)
>>> +{
>>> +        struct device_node *np = pdev->dev.of_node;
>>> +        const struct of_device_id *of_id =
>>> +                        of_match_device(rt_imx_uart_dt_ids, &pdev->dev);
>>> +        int ret;
>>> +
>>> +        if (!np)
>>> +                /* no device tree device */
>>> +                return 1;
>>> +
>>> +        ret = of_alias_get_id(np, "serial");
>>> +        if (ret < 0) {
>>> +                dev_err(&pdev->dev, "failed to get alias id, errno %d\n", 
>>> ret);
>>> +                return ret;
>>> +        }
>>> +
>>> +       pdev->id = ret;
>>> +
>>> +        if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
>>> +                port->have_rtscts = 1;
>>> +        if (of_get_property(np, "fsl,irda-mode", NULL))
>>> +                dev_warn(&pdev->dev, "IRDA not yet supported\n");
>>> +
>>> +        if (of_get_property(np, "fsl,dte-mode", NULL))
>>> +               port->use_dcedte = 1;
>>> +
>>> +        port->devdata = of_id->data;
>>> +
>>> +        return 0;
>>> +}
>>> +#else
>>> +static inline int rt_imx_uart_probe_dt(struct rt_imx_uart_port *port,
>>> +                                       struct platform_device *pdev)
>>> +{
>>> +        return 1;
>>> +}
>>> +#endif
>>> +
>>> +static void rt_imx_uart_probe_pdata(struct rt_imx_uart_port *port,
>>> +                                    struct platform_device *pdev)
>>> +{
>>> +        struct imxuart_platform_data *pdata = dev_get_platdata(&pdev->dev);
>>> +
>>> +        port->devdata = (struct imx_uart_data  *) 
>>> pdev->id_entry->driver_data;
>>> +
>>> +        if (!pdata)
>>> +                return;
>>> +
>>> +        if (pdata->flags & IMXUART_HAVE_RTSCTS)
>>> +                port->have_rtscts = 1;
>>> +}
>>> +
>>>  static int rt_imx_uart_probe(struct platform_device *pdev)
>>>  {
>>> -       struct imxuart_platform_data *pdata;
>>>         struct rtdm_device *dev;
>>>         struct rt_imx_uart_port *port;
>>>         struct resource *res;
>>> -       int err;
>>> +       int ret;
>>>
>>> -       port = kzalloc(sizeof(*port), GFP_KERNEL);
>>> +       port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
>>>         if (!port)
>>>                 return -ENOMEM;
>>>
>>> +        ret = rt_imx_uart_probe_dt(port, pdev);
>>> +        if (ret > 0)
>>> +                rt_imx_uart_probe_pdata(port, pdev);
>>> +        else if (ret < 0)
>>> +                return ret;
>>> +
>>>         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> -       if (!res) {
>>> -               err = -ENODEV;
>>> -               goto kfree_out;
>>> -       }
>>> -       port->mapbase = res->start;
>>> +       if (!res)
>>> +               return -ENODEV;
>>>
>>>         port->irq = platform_get_irq(pdev, 0);
>>> -       if (port->irq <= 0) {
>>> -               err = -ENODEV;
>>> -               goto kfree_out;
>>> -       }
>>>
>>> -       if (!request_mem_region(port->mapbase, PAGE_SIZE, DRIVER_NAME)) {
>>> -               err = -EBUSY;
>>> -               goto kfree_out;
>>> -       }
>>> -
>>> -       port->membase = ioremap(port->mapbase, PAGE_SIZE);
>>> -       if (!port->membase) {
>>> -               err = -ENOMEM;
>>> -               goto release_mem_region_out;
>>> -       }
>>> +        if (port->irq <= 0)
>>> +               return -ENODEV;
>>>
>>> +       port->membase = devm_ioremap_resource(&pdev->dev, res);
>>> +       if (IS_ERR(port->membase))
>>> +               return PTR_ERR(port->membase);
>>>
>>>         dev = &port->rtdm_dev;
>>>         dev->driver = &imx_uart_driver;
>>> @@ -1429,54 +1564,31 @@ static int rt_imx_uart_probe(struct platform_device 
>>> *pdev)
>>>         else
>>>                 port->tx_fifo = tx_fifo[pdev->id];
>>>
>>> -       port->clk = clk_get(&pdev->dev, "uart");
>>> -       if (IS_ERR(port->clk)) {
>>> -               err = PTR_ERR(port->clk);
>>> -               goto iounmap_out;
>>> -       }
>>> -       clk_enable(port->clk);
>>> -       port->uartclk = clk_get_rate(port->clk);
>>> +       port->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
>>> +       if (IS_ERR(port->clk_ipg))
>>> +               return PTR_ERR(port->clk_ipg);
>>>
>>> -       port->use_hwflow = 1;
>>> +        port->clk_per = devm_clk_get(&pdev->dev, "per");
>>> +       if (IS_ERR(port->clk_per))
>>> +               return PTR_ERR(port->clk_per);
>>>
>>> -       pdata = pdev->dev.platform_data;
>>> -       if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
>>> -               port->have_rtscts = 1;
>>> -       if (pdata && (pdata->flags & IMXUART_USE_DCEDTE))
>>> -               port->use_dcedte = 1;
>>> -       if (pdata && pdata->init) {
>>> -               err = pdata->init(pdev);
>>> -               if (err)
>>> -                       goto clk_disable_out;
>>> -       }
>>> +       clk_enable(port->clk_ipg);
>>> +       clk_enable(port->clk_per);
>>> +       port->uartclk = clk_get_rate(port->clk_per);
>>> +
>>> +       port->use_hwflow = 1;
>>>
>>> -       err = rtdm_dev_register(dev);
>>> -       if (err)
>>> -               goto pdata_exit_out;
>>> +        ret = rtdm_dev_register(dev);
>>> +       if (ret)
>>> +               return ret;
>>>
>>>         platform_set_drvdata(pdev, port);
>>>
>>>         printk(KERN_INFO
>>> -              "%s on IMX UART%d: membase=0x%p mapbase=%#x irq=%d 
>>> uartclk=%d\n",
>>> -              dev->name, pdev->id, port->membase, (u32)port->mapbase,
>>> -              port->irq, port->uartclk);
>>> -
>>> -       return 0;
>>> -
>>> -pdata_exit_out:
>>> -       if (pdata && pdata->exit)
>>> -               pdata->exit(pdev);
>>> -clk_disable_out:
>>> -       clk_put(port->clk);
>>> -       clk_disable(port->clk);
>>> -iounmap_out:
>>> -       iounmap(port->membase);
>>> -release_mem_region_out:
>>> -       release_mem_region(port->mapbase, SZ_4K);
>>> -kfree_out:
>>> -       kfree(port);
>>> -
>>> -       return err;
>>> +              "%s on IMX UART%d: membase=0x%p irq=%d uartclk=%d\n",
>>> +              dev->name, pdev->id, port->membase, port->irq, 
>>> port->uartclk);
>>> +
>>> +        return 0;
>>>  }
>>>
>>>  static int rt_imx_uart_remove(struct platform_device *pdev)
>>> @@ -1490,26 +1602,9 @@ static int rt_imx_uart_remove(struct platform_device 
>>> *pdev)
>>>
>>>         rtdm_dev_unregister(dev);
>>>
>>> -       if (port->clk) {
>>> -               clk_put(port->clk);
>>> -               clk_disable(port->clk);
>>> -       }
>>> -
>>> -       if (pdata && pdata->exit)
>>> -               pdata->exit(pdev);
>>> -
>>> -       iounmap(port->membase);
>>> -       release_mem_region(port->mapbase, PAGE_SIZE);
>>> -       kfree(port);
>>> -
>>> -       return 0;
>>> +        return 0;
>>>  }
>>>
>>> -static const struct platform_device_id rt_imx_uart_id_table[] = {
>>> -       {"imx-uart",},
>>> -       {},
>>> -};
>>> -
>>>  static struct platform_driver rt_imx_uart_driver = {
>>>         .probe = rt_imx_uart_probe,
>>>         .remove = rt_imx_uart_remove,
>>> @@ -1517,15 +1612,29 @@ static struct platform_driver rt_imx_uart_driver = {
>>>         .driver = {
>>>                 .name = DRIVER_NAME,
>>>                 .owner = THIS_MODULE,
>>> +                .of_match_table = rt_imx_uart_dt_ids,
>>>         },
>>> +        .prevent_deferred_probe = true,
>>>  };
>>>
>>> +
>>>  static int __init rt_imx_uart_init(void)
>>>  {
>>> -       if (!realtime_core_enabled())
>>> +        int ret;
>>> +
>>> +        if (!realtime_core_enabled())
>>>                 return 0;
>>>
>>> -       return platform_driver_register(&rt_imx_uart_driver);
>>> +
>>> +       ret = platform_driver_register(&rt_imx_uart_driver);
>>> +        if (ret) {
>>> +                printk(KERN_ERR
>>> +                        "%s; Could not register  driver (err=%d)\n",
>>> +                       __func__, ret);
>>> +
>>> +        }
>>> +
>>> +        return ret;;
>>>  }
>>>
>>>  static void __exit rt_imx_uart_exit(void)
>>> --
>>> 2.7.4
>>>
>
> --
> Siemens AG, Corporate Technology, CT RDA IOT SES-DE
> Corporate Competence Center Embedded Linux

_______________________________________________
Xenomai mailing list
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to