All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sylvain Munaut <tnt@246tNt.com>
To: Andrew Morton <akpm@osdl.org>
Cc: Sylvain Munaut <tnt@246tNt.com>,
	ML linuxppc-embedded <linuxppc-embedded@ozlabs.org>
Subject: [PATCH 5/6] serial: Update mpc52xx_uart.c to use platform bus
Date: Sun, 27 Mar 2005 00:47:13 +0100 (CET)	[thread overview]
Message-ID: <5.20050327_004704.tnt@patchsend.246tNt.com> (raw)
In-Reply-To: <0.20050327_004704.tnt@patchsend.246tNt.com>

serial: Update mpc52xx_uart.c to use platform bus

All Freescale MPC52xx related code now use new constants and
the platform bus for it's driver. This patch makes this driver
make use of that.


Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
---
diff -Nru a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
--- a/drivers/serial/mpc52xx_uart.c	2005-03-26 19:56:30 +01:00
+++ b/drivers/serial/mpc52xx_uart.c	2005-03-26 19:56:30 +01:00
@@ -18,7 +18,7 @@
  * Some of the code has been inspired/copied from the 2.4 code written
  * by Dale Farnsworth <dfarnsworth@mvista.com>.
  * 
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
  * Copyright (C) 2003 MontaVista, Software, Inc.
  * 
  * This file is licensed under the terms of the GNU General Public License
@@ -26,33 +26,26 @@
  * kind, whether express or implied.
  */
  
-/* OCP Usage :
+/* Platform device Usage :
  *
- * This drivers uses the OCP model. To load the serial driver for one of the
- * PSCs, just add this to the core_ocp table :
+ * Since PSCs can have multiple function, the correct driver for each one
+ * is selected by calling mpc52xx_match_psc_function(...). The function
+ * handled by this driver is "uart".
  *
- * {
- * 	.vendor         = OCP_VENDOR_FREESCALE,
- * 	.function       = OCP_FUNC_PSC_UART,
- * 	.index          = 0,
- * 	.paddr          = MPC52xx_PSC1,
- * 	.irq            = MPC52xx_PSC1_IRQ,
- * 	.pm             = OCP_CPM_NA,
- * },
- *
- * This is for PSC1, replace the paddr and irq according to the PSC you want to
- * use. The driver all necessary registers to place the PSC in uart mode without
+ * The driver init all necessary registers to place the PSC in uart mode without
  * DCD. However, the pin multiplexing aren't changed and should be set either
  * by the bootloader or in the platform init code.
- * The index field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
+ *
+ * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
  * and so on). So the PSC1 is mapped to /dev/ttyS0, PSC2 to /dev/ttyS1 and so
  * on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly for
  * the console code : without this 1:1 mapping, at early boot time, when we are
  * parsing the kernel args console=ttyS?, we wouldn't know wich PSC it will be
- * mapped to because OCP stuff is not yet initialized.
+ * mapped to.
  */
 
 #include <linux/config.h>
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
@@ -61,7 +54,6 @@
 
 #include <asm/delay.h>
 #include <asm/io.h>
-#include <asm/ocp.h>
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>
@@ -191,6 +183,13 @@
 mpc52xx_uart_startup(struct uart_port *port)
 {
 	struct mpc52xx_psc __iomem *psc = PSC(port);
+	int ret;
+
+	/* Request IRQ */
+	ret = request_irq(port->irq, mpc52xx_uart_int,
+		SA_INTERRUPT | SA_SAMPLE_RANDOM, "mpc52xx_psc_uart", port);
+	if (ret)
+		return ret;
 
 	/* Reset/activate the port, clear and enable interrupts */
 	out_8(&psc->command,MPC52xx_PSC_RST_RX);
@@ -225,6 +224,9 @@
 	
 	port->read_status_mask = 0; 
 	out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
+
+	/* Release interrupt */
+	free_irq(port->irq, port);
 }
 
 static void 
@@ -326,15 +328,21 @@
 		iounmap(port->membase);
 		port->membase = NULL;
 	}
+
+	release_mem_region(port->mapbase, MPC52xx_PSC_SIZE);
 }
 
 static int
 mpc52xx_uart_request_port(struct uart_port *port)
 {
 	if (port->flags & UPF_IOREMAP) /* Need to remap ? */
-		port->membase = ioremap(port->mapbase, sizeof(struct mpc52xx_psc));
-	
-	return port->membase != NULL ? 0 : -EBUSY;
+		port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
+
+	if (!port->membase)
+		return -EINVAL;
+
+	return request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
+			"mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
 }
 
 static void
@@ -354,7 +362,7 @@
 	if ( (ser->irq != port->irq) ||
 	     (ser->io_type != SERIAL_IO_MEM) ||
 	     (ser->baud_base != port->uartclk)  || 
-	     // FIXME Should check addresses/irq as well ?
+	     (ser->iomem_base != (void*)port->mapbase) ||
 	     (ser->hub6 != 0 ) )
 		return -EINVAL;
 
@@ -630,7 +638,7 @@
 {
 	struct uart_port *port = &mpc52xx_uart_ports[co->index];
 
-	int baud = 9600;
+	int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
 	int bits = 8;
 	int parity = 'n';
 	int flow = 'n';
@@ -643,14 +651,12 @@
 	spin_lock_init(&port->lock);
 	port->uartclk	= __res.bi_ipbfreq / 2; /* Look at CTLR doc */
 	port->ops	= &mpc52xx_uart_ops;
-	port->mapbase	= MPC52xx_PSCx(co->index);
+	port->mapbase	= MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1));
 
-		/* We ioremap ourself */
-	port->membase = ioremap(port->mapbase, sizeof(struct mpc52xx_psc));
-	if (port->membase == NULL) {
-		release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
-		return -EBUSY;
-	}
+	/* We ioremap ourself */
+	port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
+	if (port->membase == NULL)
+		return -EINVAL;
 
 	/* Setup the port parameters accoding to options */
 	if (options)
@@ -707,26 +713,32 @@
 
 
 /* ======================================================================== */
-/* OCP Driver                                                               */
+/* Platform Driver                                                          */
 /* ======================================================================== */
 
 static int __devinit
-mpc52xx_uart_probe(struct ocp_device *ocp)
+mpc52xx_uart_probe(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *res = pdev->resource;
+
 	struct uart_port *port = NULL;
-	int idx, ret;
+	int i, idx, ret;
 
-	/* Get the corresponding port struct */
-	idx = ocp->def->index;
+	/* Check validity & presence */
+	idx = pdev->id;
 	if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
 		return -EINVAL;
-	
-	port = &mpc52xx_uart_ports[idx];
+
+	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->mapbase	= ocp->def->paddr;
-	port->irq	= ocp->def->irq;
 	port->uartclk	= __res.bi_ipbfreq / 2; /* Look at CTLR doc */
 	port->fifosize	= 255; /* Should be 512 ! But it can't be */
 	                       /* stored in a unsigned char       */
@@ -735,95 +747,65 @@
 			  ( uart_console(port) ? 0 : UPF_IOREMAP );
 	port->line	= idx;
 	port->ops	= &mpc52xx_uart_ops;
-	port->read_status_mask = 0;
-	
-	/* Requests the mem & irqs */
-	/* Unlike other serial drivers, we reserve the resources here, so we
-	 * can detect early if multiple drivers uses the same PSC. Special
-	 * care must be taken with the console PSC
-	 */
-	ret = request_irq(
-		port->irq, mpc52xx_uart_int,
-		SA_INTERRUPT | SA_SAMPLE_RANDOM, "mpc52xx_psc_uart", port);
-	if (ret)
-		goto error;
 
-	ret = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc),
-	                         "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
-	if (ret)
-		goto free_irq;
+	/* Search for IRQ and mapbase */
+	for (i=0 ; i<pdev->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)
+		return -EINVAL;
 
 	/* Add the port to the uart sub-system */
 	ret = uart_add_one_port(&mpc52xx_uart_driver, port);
-	if (ret)
-		goto release_mem;
-
-	ocp_set_drvdata(ocp, (void*)port);
-
-	return 0;
-
-
-free_irq:
-	free_irq(port->irq, mpc52xx_uart_int);
-
-release_mem:
-	release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
-
-error:
-	if (uart_console(port))
-		printk(	"mpc52xx_uart.c: Error during resource alloction for "
-			"the console port !!! Check that the console PSC is "
-			"not used by another OCP driver !!!\n" );
+	if (!ret)
+		dev_set_drvdata(dev, (void*)port);
 
 	return ret;
 }
 
-static void
-mpc52xx_uart_remove(struct ocp_device *ocp)
+static int
+mpc52xx_uart_remove(struct device *dev)
 {
-	struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
 
-	ocp_set_drvdata(ocp, NULL);
+	dev_set_drvdata(dev, NULL);
 
-	if (port) {
+	if (port)
 		uart_remove_one_port(&mpc52xx_uart_driver, port);
-		release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
-		free_irq(port->irq, mpc52xx_uart_int);
-	}
+
+	return 0;
 }
 
 #ifdef CONFIG_PM
 static int
-mpc52xx_uart_suspend(struct ocp_device *ocp, u32 state)
+mpc52xx_uart_suspend(struct device *dev, u32 state, u32 level)
 {
-	struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
 
-	uart_suspend_port(&mpc52xx_uart_driver, port);
+	if (sport && level == SUSPEND_DISABLE)
+		uart_suspend_port(&mpc52xx_uart_driver, port);
 
 	return 0;
 }
 
 static int
-mpc52xx_uart_resume(struct ocp_device *ocp)
+mpc52xx_uart_resume(struct device *dev, u32 level)
 {
-	struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
 
-	uart_resume_port(&mpc52xx_uart_driver, port);
+	if (port && level == RESUME_ENABLE)
+		uart_resume_port(&mpc52xx_uart_driver, port);
 
 	return 0;
 }
 #endif
 
-static struct ocp_device_id mpc52xx_uart_ids[] __devinitdata = {
-	{ .vendor = OCP_VENDOR_FREESCALE, .function = OCP_FUNC_PSC_UART },
-	{ .vendor = OCP_VENDOR_INVALID /* Terminating entry */ }
-};
-
-MODULE_DEVICE_TABLE(ocp, mpc52xx_uart_ids);
-
-static struct ocp_driver mpc52xx_uart_ocp_driver = {
-	.name		= "mpc52xx_psc_uart",
-	.id_table	= mpc52xx_uart_ids,
+static struct device_driver mpc52xx_uart_platform_driver = {
+	.name		= "mpc52xx-psc",
+	.bus		= &platform_bus_type,
 	.probe		= mpc52xx_uart_probe,
 	.remove		= mpc52xx_uart_remove,
 #ifdef CONFIG_PM
@@ -845,10 +827,11 @@
 	printk(KERN_INFO "Serial: MPC52xx PSC driver\n");
 
 	ret = uart_register_driver(&mpc52xx_uart_driver);
-	if (ret)
-		return ret;
-
-	ret = ocp_register_driver(&mpc52xx_uart_ocp_driver);
+	if (ret == 0) {
+		ret = driver_register(&mpc52xx_uart_platform_driver);
+		if (ret)
+			uart_unregister_driver(&mpc52xx_uart_driver);
+	}
 
 	return ret;
 }
@@ -856,7 +839,7 @@
 static void __exit
 mpc52xx_uart_exit(void)
 {
-	ocp_unregister_driver(&mpc52xx_uart_ocp_driver);
+	driver_unregister(&mpc52xx_uart_platform_driver);
 	uart_unregister_driver(&mpc52xx_uart_driver);
 }

  parent reply	other threads:[~2005-03-26 23:49 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-26 23:44 [PATCH 0/6] Change MPC52xx to platform bus / ppc_sys model Sylvain Munaut
2005-03-26 23:45 ` [PATCH 1/6] ppc32: Remove unnecessary test in MPC52xx reset code Sylvain Munaut
2005-03-26 23:45 ` [PATCH 2/6] ppc32: Remove the OCP system from the Freescale MPC52xx support Sylvain Munaut
2005-03-26 23:46 ` [PATCH 3/6] ppc32: Change constants style in Freescale MPC52xx related code Sylvain Munaut
2005-03-26 23:46 ` [PATCH 4/6] ppc32: Use platform bus / ppc_sys model for Freescale MPC52xx Sylvain Munaut
2005-03-26 23:47 ` Sylvain Munaut [this message]
2005-03-26 23:47 ` [PATCH 6/6] ppc32: Adds necessary cpu init to use USB on LITE5200 Platform Sylvain Munaut
2005-03-27 13:45 ` [PATCH 0/6] Change MPC52xx to platform bus / ppc_sys model Andrey Volkov
2005-03-28  8:58   ` tnt
2005-04-01 20:02   ` [PATCH 1/1] Change MPC52xx-fec " Andrey Volkov
  -- strict thread matches above, loose matches on Subject: below --
2005-03-21 23:06 [PATCH 0/6] [RFC] Change MPC52xx to " Sylvain Munaut
2005-03-21 23:09 ` [PATCH 5/6] serial: Update mpc52xx_uart.c to use platform bus Sylvain Munaut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5.20050327_004704.tnt@patchsend.246tNt.com \
    --to=tnt@246tnt.com \
    --cc=akpm@osdl.org \
    --cc=linuxppc-embedded@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.