aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/cpm_uart
diff options
context:
space:
mode:
authorLaurent Pinchart <laurentp@cse-semaphore.com>2008-04-10 11:01:27 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-04-17 02:01:36 -0400
commitd464df2667cf181419604e656773f80996cf0470 (patch)
treefedca2185763550331f0a73450c1d82f0c146ad6 /drivers/serial/cpm_uart
parent1028d4f162796a99b87565b6b40b5fec79c242d0 (diff)
[POWERPC] cpm_uart: Allocate DPRAM memory for SMC ports on CPM2-based platforms.
This patch allocates parameter RAM for SMC serial ports without relying on previous initialisation by a boot loader or a wrapper layer. SMC parameter RAM on CPM2-based platforms can be allocated anywhere in the general-purpose areas of the dual-port RAM. The current code relies on the boot loader to allocate a section of general-purpose CPM RAM and gets the section address from the device tree. This patch modifies the device tree address usage to reference the SMC parameter RAM base pointer instead of a pre-allocated RAM section and allocates memory from the CPM dual-port RAM when initialising the SMC port. CPM1-based platforms are not affected. Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com> Acked-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'drivers/serial/cpm_uart')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h3
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c19
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c14
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c52
4 files changed, 78 insertions, 10 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 32b9737759c..0cc39f82d7c 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -92,6 +92,9 @@ extern struct uart_cpm_port cpm_uart_ports[UART_NR];
92 92
93/* these are located in their respective files */ 93/* these are located in their respective files */
94void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd); 94void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd);
95void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
96 struct device_node *np);
97void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram);
95int cpm_uart_init_portdesc(void); 98int cpm_uart_init_portdesc(void);
96int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); 99int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con);
97void cpm_uart_freebuf(struct uart_cpm_port *pinfo); 100void cpm_uart_freebuf(struct uart_cpm_port *pinfo);
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 236af9d3385..a638ba0679a 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -966,24 +966,23 @@ static int cpm_uart_init_port(struct device_node *np,
966 if (!mem) 966 if (!mem)
967 return -ENOMEM; 967 return -ENOMEM;
968 968
969 pram = of_iomap(np, 1);
970 if (!pram) {
971 ret = -ENOMEM;
972 goto out_mem;
973 }
974
975 if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || 969 if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") ||
976 of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { 970 of_device_is_compatible(np, "fsl,cpm2-scc-uart")) {
977 pinfo->sccp = mem; 971 pinfo->sccp = mem;
978 pinfo->sccup = pram; 972 pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np);
979 } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || 973 } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") ||
980 of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { 974 of_device_is_compatible(np, "fsl,cpm2-smc-uart")) {
981 pinfo->flags |= FLAG_SMC; 975 pinfo->flags |= FLAG_SMC;
982 pinfo->smcp = mem; 976 pinfo->smcp = mem;
983 pinfo->smcup = pram; 977 pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np);
984 } else { 978 } else {
985 ret = -ENODEV; 979 ret = -ENODEV;
986 goto out_pram; 980 goto out_mem;
981 }
982
983 if (!pram) {
984 ret = -ENOMEM;
985 goto out_mem;
987 } 986 }
988 987
989 pinfo->tx_nrfifos = TX_NUM_FIFO; 988 pinfo->tx_nrfifos = TX_NUM_FIFO;
@@ -1007,7 +1006,7 @@ static int cpm_uart_init_port(struct device_node *np,
1007 return cpm_uart_request_port(&pinfo->port); 1006 return cpm_uart_request_port(&pinfo->port);
1008 1007
1009out_pram: 1008out_pram:
1010 iounmap(pram); 1009 cpm_uart_unmap_pram(pinfo, pram);
1011out_mem: 1010out_mem:
1012 iounmap(mem); 1011 iounmap(mem);
1013 return ret; 1012 return ret;
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 6ea0366e26a..74f1432bb24 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -45,6 +45,8 @@
45#include <linux/serial_core.h> 45#include <linux/serial_core.h>
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47 47
48#include <linux/of.h>
49
48#include "cpm_uart.h" 50#include "cpm_uart.h"
49 51
50/**************************************************************/ 52/**************************************************************/
@@ -54,6 +56,18 @@ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
54{ 56{
55 cpm_command(port->command, cmd); 57 cpm_command(port->command, cmd);
56} 58}
59
60void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
61 struct device_node *np)
62{
63 return of_iomap(np, 1);
64}
65
66void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
67{
68 iounmap(pram);
69}
70
57#else 71#else
58void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 72void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
59{ 73{
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index d9af06a791b..bb862e2f54c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -41,6 +41,9 @@
41#include <asm/io.h> 41#include <asm/io.h>
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/fs_pd.h> 43#include <asm/fs_pd.h>
44#ifdef CONFIG_PPC_CPM_NEW_BINDING
45#include <asm/prom.h>
46#endif
44 47
45#include <linux/serial_core.h> 48#include <linux/serial_core.h>
46#include <linux/kernel.h> 49#include <linux/kernel.h>
@@ -54,6 +57,55 @@ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
54{ 57{
55 cpm_command(port->command, cmd); 58 cpm_command(port->command, cmd);
56} 59}
60
61void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
62 struct device_node *np)
63{
64 void __iomem *pram;
65 unsigned long offset;
66 struct resource res;
67 unsigned long len;
68
69 /* Don't remap parameter RAM if it has already been initialized
70 * during console setup.
71 */
72 if (IS_SMC(port) && port->smcup)
73 return port->smcup;
74 else if (!IS_SMC(port) && port->sccup)
75 return port->sccup;
76
77 if (of_address_to_resource(np, 1, &res))
78 return NULL;
79
80 len = 1 + res.end - res.start;
81 pram = ioremap(res.start, len);
82 if (!pram)
83 return NULL;
84
85 if (!IS_SMC(port))
86 return pram;
87
88 if (len != 2) {
89 printk(KERN_WARNING "cpm_uart[%d]: device tree references "
90 "SMC pram, using boot loader/wrapper pram mapping. "
91 "Please fix your device tree to reference the pram "
92 "base register instead.\n",
93 port->port.line);
94 return pram;
95 }
96
97 offset = cpm_dpalloc(PROFF_SMC_SIZE, 64);
98 out_be16(pram, offset);
99 iounmap(pram);
100 return cpm_muram_addr(offset);
101}
102
103void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
104{
105 if (!IS_SMC(port))
106 iounmap(pram);
107}
108
57#else 109#else
58void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 110void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
59{ 111{