As part of the transition to arch/powerpc, this patch moves the mpc5200 PSC
driver over to the OF platform bus infrastructure.

This patch is not acceptable for mainline as-is because it breaks arch/ppc
support for the mpc52xx.  More rework is needed to allow it to compile for
either arch (or alternately, fork the driver)

Signed-off-by: Grant Likely <[EMAIL PROTECTED]>
---
 drivers/serial/mpc52xx_uart.c |  146 +++++++++++++++++++++++++++++------------
 1 files changed, 105 insertions(+), 41 deletions(-)

diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 29c9300..09bf8e0 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -42,7 +42,8 @@
  * will be mapped to.
  */
 
-#include <linux/platform_device.h>
+#define DEBUG
+
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
@@ -51,6 +52,7 @@ #include <linux/console.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
+#include <asm/of_device.h>
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>
@@ -371,7 +373,7 @@ mpc52xx_uart_verify_port(struct uart_por
 
        if ( (ser->irq != port->irq) ||
             (ser->io_type != SERIAL_IO_MEM) ||
-            (ser->baud_base != port->uartclk)  ||
+            (ser->baud_base != port->uartclk) ||
             (ser->iomem_base != (void*)port->mapbase) ||
             (ser->hub6 != 0 ) )
                return -EINVAL;
@@ -561,13 +563,13 @@ mpc52xx_console_get_options(struct uart_
        struct mpc52xx_psc __iomem *psc = PSC(port);
        unsigned char mr1;
 
+       pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
        /* Read the mode registers */
        out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
        mr1 = in_8(&psc->mode);
 
        /* CT{U,L}R are write-only ! */
-       *baud = __res.bi_baudrate ?
-               __res.bi_baudrate : CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
+       *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
 
        /* Parse them */
        switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
@@ -604,10 +606,10 @@ mpc52xx_console_write(struct console *co
        for (i = 0; i < count; i++, s++) {
                /* Line return handling */
                if (*s == '\n')
-                       out_8(&psc->mpc52xx_psc_buffer_8, '\r');
+                       out_8(&psc->buffer.buffer_8, '\r');
 
                /* Send the char */
-               out_8(&psc->mpc52xx_psc_buffer_8, *s);
+               out_8(&psc->buffer.buffer_8, *s);
 
                /* Wait the TX buffer to be empty */
                j = 20000;      /* Maximum wait */
@@ -624,33 +626,74 @@ static int __init
 mpc52xx_console_setup(struct console *co, char *options)
 {
        struct uart_port *port = &mpc52xx_uart_ports[co->index];
+       struct device_node *np = NULL;
+       struct device_node *np_idx;
+       const void *pp = NULL;
+       struct resource res;
+       int index = 0;
+       int ret;
 
        int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
        int bits = 8;
        int parity = 'n';
        int flow = 'n';
 
-       if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM)
+       pr_debug("mpc52xx_console_setup co=%p, options=%s, index=%i\n",
+                co, options, co->index);
+
+       while ((np = of_find_compatible_node(np, "serial", "mpc52xx-psc"))) {
+               if (index == co->index)
+                       break;
+               index++;
+       }
+
+       if (!np) {
+               pr_debug("PSC%x not found in device tree\n", co->index);
+               return -EINVAL;
+       }
+
+       /* Fetch register locations */
+       if ((ret = of_address_to_resource(np, 0, &res)) != 0) {
+               pr_debug("Could not get resources for PSC%x\n", index);
+               return ret;
+       }
+
+       /* Search for bus-frequency property in this node or a parent */
+       np_idx = np;
+       while (np_idx) {
+               if ((pp = get_property(np_idx, "bus-frequency", NULL)) != NULL)
+                       break;
+               np_idx = of_get_parent(np_idx);
+       }
+       if (!pp) {
+               pr_debug("Could not find bus-frequency property!\n");
                return -EINVAL;
+       }
 
        /* Basic port init. Needed since we use some uart_??? func before
         * real init for early access */
        spin_lock_init(&port->lock);
-       port->uartclk   = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
+       port->uartclk   = *(const u32*)pp / 2;
        port->ops       = &mpc52xx_uart_ops;
-       port->mapbase   = MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1));
+       port->mapbase = res.start;
+       port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
+       port->irq = irq_of_parse_and_map(np, 0);
 
-       /* We ioremap ourself */
-       port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
        if (port->membase == NULL)
                return -EINVAL;
 
+       pr_debug("mpc52xx_psc at %lx mapped to %p; irq=%x freq=%i\n",
+                port->mapbase, port->membase, port->irq, port->uartclk);
+
        /* Setup the port parameters accoding to options */
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        else
                mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
 
+       pr_debug("Setting console parameters: %i %i%c1 flow=%c\n",
+                baud, bits, parity, flow);
+
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
@@ -703,28 +746,26 @@ static struct uart_driver mpc52xx_uart_d
 /* ======================================================================== */
 
 static int __devinit
-mpc52xx_uart_probe(struct platform_device *dev)
+mpc52xx_uart_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct resource *res = dev->resource;
-
+       static int idx = 0;
        struct uart_port *port = NULL;
-       int i, idx, ret;
+       struct resource res;
+       int ret;
+
+       printk("Got here!\n");
+       dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match);
 
        /* Check validity & presence */
-       idx = dev->id;
-       if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
+       if (idx >= MPC52xx_PSC_MAXNUM)
                return -EINVAL;
 
-       if (!mpc52xx_match_psc_function(idx,"uart"))
-               return -ENODEV;
-
        /* Init the port structure */
        port = &mpc52xx_uart_ports[idx];
 
        memset(port, 0x00, sizeof(struct uart_port));
 
        spin_lock_init(&port->lock);
-       port->uartclk   = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
        port->fifosize  = 512;
        port->iotype    = UPIO_MEM;
        port->flags     = UPF_BOOT_AUTOCONF |
@@ -733,29 +774,36 @@ mpc52xx_uart_probe(struct platform_devic
        port->ops       = &mpc52xx_uart_ops;
 
        /* Search for IRQ and mapbase */
-       for (i=0 ; i<dev->num_resources ; i++, res++) {
-               if (res->flags & IORESOURCE_MEM)
-                       port->mapbase = res->start;
-               else if (res->flags & IORESOURCE_IRQ)
-                       port->irq = res->start;
-       }
-       if (!port->irq || !port->mapbase)
+       if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)
+               return ret;
+
+       port->mapbase = res.start;
+       port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
+       port->irq = irq_of_parse_and_map(op->node, 0);
+
+       dev_dbg(&op->dev, "mpc52xx-psc UART at %lx. mapped to %p, irq %x\n",
+                port->mapbase, port->membase, port->irq);
+
+       //if (!port->irq || !port->mapbase) {
+       if (!port->mapbase) {
+               printk(KERN_ERR "Could not allocate resources for PSC\n");
                return -EINVAL;
+       }
 
        /* Add the port to the uart sub-system */
        ret = uart_add_one_port(&mpc52xx_uart_driver, port);
        if (!ret)
-               platform_set_drvdata(dev, (void*)port);
+               dev_set_drvdata(&op->dev, (void*)port);
 
+       idx++;
        return ret;
 }
 
 static int
-mpc52xx_uart_remove(struct platform_device *dev)
+mpc52xx_uart_remove(struct of_device *op)
 {
-       struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
-
-       platform_set_drvdata(dev, NULL);
+       struct uart_port *port = dev_get_drvdata(&op->dev);
+       dev_set_drvdata(&op->dev, NULL);
 
        if (port)
                uart_remove_one_port(&mpc52xx_uart_driver, port);
@@ -787,7 +835,19 @@ mpc52xx_uart_resume(struct platform_devi
 }
 #endif
 
-static struct platform_driver mpc52xx_uart_platform_driver = {
+static struct of_device_id mpc52xx_uart_match[] = {
+       {
+               .name = "serial",
+               .compatible = "mpc52xx-psc",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mpc52xx_uart_match);
+
+static struct of_platform_driver mpc52xx_uart_of_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "mpc52xx-uart",
+       .match_table    = mpc52xx_uart_match,
        .probe          = mpc52xx_uart_probe,
        .remove         = mpc52xx_uart_remove,
 #ifdef CONFIG_PM
@@ -811,20 +871,24 @@ mpc52xx_uart_init(void)
 
        printk(KERN_INFO "Serial: MPC52xx PSC driver\n");
 
-       ret = uart_register_driver(&mpc52xx_uart_driver);
-       if (ret == 0) {
-               ret = platform_driver_register(&mpc52xx_uart_platform_driver);
-               if (ret)
-                       uart_unregister_driver(&mpc52xx_uart_driver);
+       if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {
+               printk(KERN_ERR "Could not register mpc52xx uart driver\n");
+               return ret;
        }
 
-       return ret;
+       if ((ret = of_register_driver(&mpc52xx_uart_of_driver)) != 0) {
+               printk(KERN_ERR "Could not register mpc52xx of driver\n");
+               uart_unregister_driver(&mpc52xx_uart_driver);
+               return ret;
+       }
+
+       return 0;
 }
 
 static void __exit
 mpc52xx_uart_exit(void)
 {
-       platform_driver_unregister(&mpc52xx_uart_platform_driver);
+       of_unregister_driver(&mpc52xx_uart_of_driver);
        uart_unregister_driver(&mpc52xx_uart_driver);
 }
 
-- 
1.4.3.rc2.g0503

_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

Reply via email to