]> Pileus Git - ~andy/linux/commitdiff
serial: sh-sci: Abstract register maps.
authorPaul Mundt <lethal@linux-sh.org>
Tue, 14 Jun 2011 03:40:19 +0000 (12:40 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Tue, 14 Jun 2011 03:40:19 +0000 (12:40 +0900)
This takes a bit of a sledgehammer to the horribly CPU subtype
ifdef-ridden header and abstracts all of the different register layouts
in to distinct types which in turn can be overriden on a per-port basis,
or permitted to default to the map matching the port type at probe time.

In the process this ultimately fixes up inumerable bugs with mismatches
on various CPU types (particularly the legacy ones that were obviously
broken years ago and no one noticed) and provides a more tightly coupled
and consolidated platform for extending and implementing generic
features.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
25 files changed:
arch/sh/Makefile
arch/sh/include/cpu-sh3/cpu/serial.h [new file with mode: 0644]
arch/sh/include/cpu-sh4a/cpu/serial.h [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/Makefile
arch/sh/kernel/cpu/sh3/serial-sh770x.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/serial-sh7710.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/serial-sh7720.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/Makefile
arch/sh/kernel/cpu/sh4a/serial-sh7722.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sh-sci.h
include/linux/serial_sci.h

index e3d8170ad00b98a8739d572fea653c22582a6953..99385d0b3f3b64bb08d894a91295f6639784c2de 100644 (file)
@@ -173,6 +173,7 @@ core-$(CONFIG_HD6446X_SERIES)       += arch/sh/cchips/hd6446x/
 cpuincdir-$(CONFIG_CPU_SH2A)   += cpu-sh2a
 cpuincdir-$(CONFIG_CPU_SH2)    += cpu-sh2
 cpuincdir-$(CONFIG_CPU_SH3)    += cpu-sh3
+cpuincdir-$(CONFIG_CPU_SH4A)   += cpu-sh4a
 cpuincdir-$(CONFIG_CPU_SH4)    += cpu-sh4
 cpuincdir-$(CONFIG_CPU_SH5)    += cpu-sh5
 cpuincdir-y                    += cpu-common   # Must be last
diff --git a/arch/sh/include/cpu-sh3/cpu/serial.h b/arch/sh/include/cpu-sh3/cpu/serial.h
new file mode 100644 (file)
index 0000000..7766329
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __CPU_SH3_SERIAL_H
+#define __CPU_SH3_SERIAL_H
+
+#include <linux/serial_sci.h>
+
+extern struct plat_sci_port_ops sh770x_sci_port_ops;
+extern struct plat_sci_port_ops sh7710_sci_port_ops;
+extern struct plat_sci_port_ops sh7720_sci_port_ops;
+
+#endif /* __CPU_SH3_SERIAL_H */
diff --git a/arch/sh/include/cpu-sh4a/cpu/serial.h b/arch/sh/include/cpu-sh4a/cpu/serial.h
new file mode 100644 (file)
index 0000000..ff1bc27
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __CPU_SH4A_SERIAL_H
+#define __CPU_SH4A_SERIAL_H
+
+/* arch/sh/kernel/cpu/sh4a/serial-sh7722.c */
+extern struct plat_sci_port_ops sh7722_sci_port_ops;
+
+#endif /* __CPU_SH4A_SERIAL_H */
index ecab274141a8bbda716b5669e450636e851fa445..6f13f33a35ffce3d0877deff87c3547a74754e60 100644 (file)
@@ -7,15 +7,15 @@ obj-y := ex.o probe.o entry.o setup-sh3.o
 obj-$(CONFIG_HIBERNATION)              += swsusp.o
 
 # CPU subtype setup
-obj-$(CONFIG_CPU_SUBTYPE_SH7705)       += setup-sh7705.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7706)       += setup-sh770x.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7707)       += setup-sh770x.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7708)       += setup-sh770x.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7709)       += setup-sh770x.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7710)       += setup-sh7710.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7712)       += setup-sh7710.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7720)       += setup-sh7720.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7721)       += setup-sh7720.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7705)       += setup-sh7705.o serial-sh770x.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7706)       += setup-sh770x.o serial-sh770x.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7707)       += setup-sh770x.o serial-sh770x.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7708)       += setup-sh770x.o serial-sh770x.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7709)       += setup-sh770x.o serial-sh770x.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7710)       += setup-sh7710.o serial-sh7710.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7712)       += setup-sh7710.o serial-sh7710.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7720)       += setup-sh7720.o serial-sh7720.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7721)       += setup-sh7720.o serial-sh7720.o
 
 # Primary on-chip clocks (common)
 clock-$(CONFIG_CPU_SH3)                        := clock-sh3.o
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh770x.c b/arch/sh/kernel/cpu/sh3/serial-sh770x.c
new file mode 100644 (file)
index 0000000..4f7242c
--- /dev/null
@@ -0,0 +1,33 @@
+#include <linux/serial_sci.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <cpu/serial.h>
+
+#define SCPCR 0xA4000116
+#define SCPDR 0xA4000136
+
+static void sh770x_sci_init_pins(struct uart_port *port, unsigned int cflag)
+{
+       unsigned short data;
+
+       /* We need to set SCPCR to enable RTS/CTS */
+       data = __raw_readw(SCPCR);
+       /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
+       __raw_writew(data & 0x0fcf, SCPCR);
+
+       if (!(cflag & CRTSCTS)) {
+               /* We need to set SCPCR to enable RTS/CTS */
+               data = __raw_readw(SCPCR);
+               /* Clear out SCP7MD1,0, SCP4MD1,0,
+                  Set SCP6MD1,0 = {01} (output)  */
+               __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
+
+               data = __raw_readb(SCPDR);
+               /* Set /RTS2 (bit6) = 0 */
+               __raw_writeb(data & 0xbf, SCPDR);
+       }
+}
+
+struct plat_sci_port_ops sh770x_sci_port_ops = {
+       .init_pins      = sh770x_sci_init_pins,
+};
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7710.c b/arch/sh/kernel/cpu/sh3/serial-sh7710.c
new file mode 100644 (file)
index 0000000..42190ef
--- /dev/null
@@ -0,0 +1,20 @@
+#include <linux/serial_sci.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <cpu/serial.h>
+
+#define PACR 0xa4050100
+#define PBCR 0xa4050102
+
+static void sh7710_sci_init_pins(struct uart_port *port, unsigned int cflag)
+{
+       if (port->mapbase == 0xA4400000) {
+               __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
+               __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
+       } else if (port->mapbase == 0xA4410000)
+               __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
+}
+
+struct plat_sci_port_ops sh7710_sci_port_ops = {
+       .init_pins      = sh7710_sci_init_pins,
+};
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7720.c b/arch/sh/kernel/cpu/sh3/serial-sh7720.c
new file mode 100644 (file)
index 0000000..8234e1e
--- /dev/null
@@ -0,0 +1,36 @@
+#include <linux/serial_sci.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <cpu/serial.h>
+
+static void sh7720_sci_init_pins(struct uart_port *port, unsigned int cflag)
+{
+       unsigned short data;
+
+       if (cflag & CRTSCTS) {
+               /* enable RTS/CTS */
+               if (port->mapbase == 0xa4430000) { /* SCIF0 */
+                       /* Clear PTCR bit 9-2; enable all scif pins but sck */
+                       data = __raw_readw(PORT_PTCR);
+                       __raw_writew((data & 0xfc03), PORT_PTCR);
+               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
+                       /* Clear PVCR bit 9-2 */
+                       data = __raw_readw(PORT_PVCR);
+                       __raw_writew((data & 0xfc03), PORT_PVCR);
+               }
+       } else {
+               if (port->mapbase == 0xa4430000) { /* SCIF0 */
+                       /* Clear PTCR bit 5-2; enable only tx and rx  */
+                       data = __raw_readw(PORT_PTCR);
+                       __raw_writew((data & 0xffc3), PORT_PTCR);
+               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
+                       /* Clear PVCR bit 5-2 */
+                       data = __raw_readw(PORT_PVCR);
+                       __raw_writew((data & 0xffc3), PORT_PVCR);
+               }
+       }
+}
+
+struct plat_sci_port_ops sh7720_sci_port_ops = {
+       .init_pins      = sh7720_sci_init_pins,
+};
index cd2e702feb7e113202f30be7b826d2cbfcc4caf3..2309618c015d06ec8b86d75882a21ce036db2cce 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <asm/rtc.h>
+#include <cpu/serial.h>
 
 enum {
        UNUSED = 0,
@@ -75,6 +76,8 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_4,
        .type           = PORT_SCIF,
        .irqs           = { 56, 56, 56 },
+       .ops            = &sh770x_sci_port_ops,
+       .regtype        = SCIx_SH7705_SCIF_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -92,6 +95,8 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_4,
        .type           = PORT_SCIF,
        .irqs           = { 52, 52, 52 },
+       .ops            = &sh770x_sci_port_ops,
+       .regtype        = SCIx_SH7705_SCIF_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
index 6d549792f791d24a49af54b896904665a3482f61..3f3d5fe5892d08c32671c382f9371d71f056e5e9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/serial.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
+#include <cpu/serial.h>
 
 enum {
        UNUSED = 0,
@@ -114,6 +115,8 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCI,
        .irqs           = { 23, 23, 23, 0 },
+       .ops            = &sh770x_sci_port_ops,
+       .regshift       = 1,
 };
 
 static struct platform_device scif0_device = {
@@ -133,6 +136,8 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 56, 56, 56, 56 },
+       .ops            = &sh770x_sci_port_ops,
+       .regtype        = SCIx_SH3_SCIF_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -147,11 +152,14 @@ static struct platform_device scif1_device = {
     defined(CONFIG_CPU_SUBTYPE_SH7709)
 static struct plat_sci_port scif2_platform_data = {
        .mapbase        = 0xa4000140,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_TE | SCSCR_RE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_IRDA,
        .irqs           = { 52, 52, 52, 52 },
+       .ops            = &sh770x_sci_port_ops,
+       .regshift       = 1,
 };
 
 static struct platform_device scif2_device = {
index 365b94a6fcb7da7c4c9eddd82bc92df585a561ef..94920345c14db53d144e9dc2513eaa7c67fd690b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <asm/rtc.h>
+#include <cpu/serial.h>
 
 static struct resource rtc_resources[] = {
        [0] = {
@@ -55,6 +56,8 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_4,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
+       .ops            = &sh7720_sci_port_ops,
+       .regtype        = SCIx_SH7705_SCIF_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -72,6 +75,8 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_4,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
+       .ops            = &sh7720_sci_port_ops,
+       .regtype        = SCIx_SH7705_SCIF_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
index 8ea26e791187b63701ddb44c6cbcac20540dcd66..c10db5b96e5974c7a277c8942a7d234b42f4fdf9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * SH7750/SH7751 Setup
+ * SH7091/SH7750/SH7750S/SH7750R/SH7751/SH7751R Setup
  *
  *  Copyright (C) 2006  Paul Mundt
  *  Copyright (C) 2006  Jamie Lenehan
@@ -44,6 +44,7 @@ static struct plat_sci_port sci_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCI,
        .irqs           = { 23, 23, 23, 0 },
+       .regshift       = 2,
 };
 
 static struct platform_device sci_device = {
index 78bbf232e3916b68b1373b4bbbba302471e173c7..c0b4c774700ec4fd07bf4def628f6dd80ceafd4b 100644 (file)
@@ -133,6 +133,7 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 52, 53, 55, 54 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -150,6 +151,7 @@ static struct plat_sci_port scif1_platform_data = {
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .irqs           = { 72, 73, 75, 74 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -167,6 +169,7 @@ static struct plat_sci_port scif2_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 76, 77, 79, 78 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -184,6 +187,7 @@ static struct plat_sci_port scif3_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCI,
        .irqs           = { 80, 81, 82, 0 },
+       .regshift       = 2,
 };
 
 static struct platform_device scif3_device = {
index cc122b1d303540ea6fcf13182c6d5f834901481b..c57fb287011e0a87278eecb5c0226a53fd70bc3b 100644 (file)
@@ -10,7 +10,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780)      += setup-sh7780.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7785)       += setup-sh7785.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7786)       += setup-sh7786.o intc-shx3.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7343)       += setup-sh7343.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7722)       += setup-sh7722.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7722)       += setup-sh7722.o serial-sh7722.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7723)       += setup-sh7723.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7724)       += setup-sh7724.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7366)       += setup-sh7366.o
diff --git a/arch/sh/kernel/cpu/sh4a/serial-sh7722.c b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c
new file mode 100644 (file)
index 0000000..59bc3a7
--- /dev/null
@@ -0,0 +1,23 @@
+#include <linux/serial_sci.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#define PSCR 0xA405011E
+
+static void sh7722_sci_init_pins(struct uart_port *port, unsigned int cflag)
+{
+       unsigned short data;
+
+       if (port->mapbase == 0xffe00000) {
+               data = __raw_readw(PSCR);
+               data &= ~0x03cf;
+               if (!(cflag & CRTSCTS))
+                       data |= 0x0340;
+
+               __raw_writew(data, PSCR);
+       }
+}
+
+struct plat_sci_port_ops sh7722_sci_port_ops = {
+       .init_pins      = sh7722_sci_init_pins,
+};
index 82616af64d62279465402d4d296171ee8f34e6be..87773869a2f3e952f8eb18a10b700f01cfe14e6e 100644 (file)
@@ -20,6 +20,7 @@
 
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffe00000,
+       .port_reg       = 0xa405013e,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
index 5813d8023619d1f0e0da06bb51808017d30f2d97..863249dbf05b786f19573e033fd8dc74d6d6c9b8 100644 (file)
@@ -185,6 +185,8 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
+       .ops            = &sh7722_sci_port_ops,
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -202,6 +204,8 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
+       .ops            = &sh7722_sci_port_ops,
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -219,6 +223,8 @@ static struct plat_sci_port scif2_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
+       .ops            = &sh7722_sci_port_ops,
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
index 072382280f96b8650c6f565bc181c60275152a53..3c2810d8f72e3caf81643baef9fabff588747736 100644 (file)
 /* Serial */
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffe00000,
+       .port_reg       = 0xa4050160,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -40,11 +42,13 @@ static struct platform_device scif0_device = {
 
 static struct plat_sci_port scif1_platform_data = {
        .mapbase        = 0xffe10000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -57,11 +61,13 @@ static struct platform_device scif1_device = {
 
 static struct plat_sci_port scif2_platform_data = {
        .mapbase        = 0xffe20000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -75,6 +81,7 @@ static struct platform_device scif2_device = {
 static struct plat_sci_port scif3_platform_data = {
        .mapbase        = 0xa4e30000,
        .flags          = UPF_BOOT_AUTOCONF,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
        .type           = PORT_SCIFA,
@@ -91,6 +98,7 @@ static struct platform_device scif3_device = {
 
 static struct plat_sci_port scif4_platform_data = {
        .mapbase        = 0xa4e40000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
@@ -108,6 +116,7 @@ static struct platform_device scif4_device = {
 
 static struct plat_sci_port scif5_platform_data = {
        .mapbase        = 0xa4e50000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
index 0333fe9e3881913e82c5458b45e4f6aef5d867dd..8c892887ebd7476dfc837142d78cd5b6b591c1a5 100644 (file)
@@ -256,11 +256,13 @@ static struct platform_device dma1_device = {
 /* Serial */
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffe00000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -273,11 +275,13 @@ static struct platform_device scif0_device = {
 
 static struct plat_sci_port scif1_platform_data = {
        .mapbase        = 0xffe10000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -290,11 +294,13 @@ static struct platform_device scif1_device = {
 
 static struct plat_sci_port scif2_platform_data = {
        .mapbase        = 0xffe20000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
+       .regtype        = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -307,6 +313,7 @@ static struct platform_device scif2_device = {
 
 static struct plat_sci_port scif3_platform_data = {
        .mapbase        = 0xa4e30000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
@@ -324,6 +331,7 @@ static struct platform_device scif3_device = {
 
 static struct plat_sci_port scif4_platform_data = {
        .mapbase        = 0xa4e40000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
@@ -341,6 +349,7 @@ static struct platform_device scif4_device = {
 
 static struct plat_sci_port scif5_platform_data = {
        .mapbase        = 0xa4e50000,
+       .port_reg       = SCIx_NOT_SUPPORTED,
        .flags          = UPF_BOOT_AUTOCONF,
        .scscr          = SCSCR_RE | SCSCR_TE,
        .scbrr_algo_id  = SCBRR_ALGO_3,
index 593eca6509b55c480787b704bca03cb8ebaa9ef0..00113515f23389d82baeab61841fc5c2a54d2e4b 100644 (file)
@@ -23,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 40, 40, 40, 40 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -40,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 76, 76, 76, 76 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -57,6 +59,7 @@ static struct plat_sci_port scif2_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           = { 104, 104, 104, 104 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
index 08add7fa684979f8d6f02231ba2b784ca00c7e95..3d4d2075c19ad334ac40b8803b8e7ecffced0a96 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_dma.h>
 #include <linux/sh_timer.h>
-
 #include <cpu/dma-register.h>
 
 static struct plat_sci_port scif0_platform_data = {
@@ -24,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 40, 40, 40, 40 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -41,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 76, 76, 76, 76 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
index 18d8fc136fb2b63c5d0ad3e9c80b87cfa695e27c..b29e6340414ab82ec54dd5f4c1c652eb50053aa5 100644 (file)
@@ -15,9 +15,7 @@
 #include <linux/mm.h>
 #include <linux/sh_dma.h>
 #include <linux/sh_timer.h>
-
 #include <asm/mmzone.h>
-
 #include <cpu/dma-register.h>
 
 static struct plat_sci_port scif0_platform_data = {
@@ -27,6 +25,7 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 40, 40, 40, 40 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -44,6 +43,7 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 44, 44, 44, 44 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -61,6 +61,7 @@ static struct plat_sci_port scif2_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 60, 60, 60, 60 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -78,6 +79,7 @@ static struct plat_sci_port scif3_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 61, 61, 61, 61 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif3_device = {
@@ -95,6 +97,7 @@ static struct plat_sci_port scif4_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 62, 62, 62, 62 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif4_device = {
@@ -112,6 +115,7 @@ static struct plat_sci_port scif5_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 63, 63, 63, 63 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif5_device = {
index beba32beb6d9899f95f9e8aad01c44845835bcf9..dd5e709f982163f809e8650c791dd6668ddc3264 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SH7786 Setup
  *
- * Copyright (C) 2009 - 2010  Renesas Solutions Corp.
+ * Copyright (C) 2009 - 2011  Renesas Solutions Corp.
  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
  * Paul Mundt <paul.mundt@renesas.com>
  *
@@ -33,6 +33,7 @@ static struct plat_sci_port scif0_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 40, 41, 43, 42 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -53,6 +54,7 @@ static struct plat_sci_port scif1_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 44, 44, 44, 44 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -70,6 +72,7 @@ static struct plat_sci_port scif2_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 50, 50, 50, 50 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -87,6 +90,7 @@ static struct plat_sci_port scif3_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 51, 51, 51, 51 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif3_device = {
@@ -104,6 +108,7 @@ static struct plat_sci_port scif4_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 52, 52, 52, 52 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif4_device = {
@@ -121,6 +126,7 @@ static struct plat_sci_port scif5_platform_data = {
        .scbrr_algo_id  = SCBRR_ALGO_1,
        .type           = PORT_SCIF,
        .irqs           = { 53, 53, 53, 53 },
+       .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif5_device = {
index 3248ddaa889df448ee5cc6820f80d1cf2187a1e6..14e1bae5039221c1384b911499e086fe5e86d887 100644 (file)
@@ -117,6 +117,255 @@ to_sci_port(struct uart_port *uart)
        return container_of(uart, struct sci_port, port);
 }
 
+struct plat_sci_reg {
+       u8 offset, size;
+};
+
+/* Helper for invalidating specific entries of an inherited map. */
+#define sci_reg_invalid        { .offset = 0, .size = 0 }
+
+static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+       [SCIx_PROBE_REGTYPE] = {
+               [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid,
+       },
+
+       /*
+        * Common SCI definitions, dependent on the port's regshift
+        * value.
+        */
+       [SCIx_SCI_REGTYPE] = {
+               [SCSMR]         = { 0x00,  8 },
+               [SCBRR]         = { 0x01,  8 },
+               [SCSCR]         = { 0x02,  8 },
+               [SCxTDR]        = { 0x03,  8 },
+               [SCxSR]         = { 0x04,  8 },
+               [SCxRDR]        = { 0x05,  8 },
+               [SCFCR]         = sci_reg_invalid,
+               [SCFDR]         = sci_reg_invalid,
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+
+       /*
+        * Common definitions for legacy IrDA ports, dependent on
+        * regshift value.
+        */
+       [SCIx_IRDA_REGTYPE] = {
+               [SCSMR]         = { 0x00,  8 },
+               [SCBRR]         = { 0x01,  8 },
+               [SCSCR]         = { 0x02,  8 },
+               [SCxTDR]        = { 0x03,  8 },
+               [SCxSR]         = { 0x04,  8 },
+               [SCxRDR]        = { 0x05,  8 },
+               [SCFCR]         = { 0x06,  8 },
+               [SCFDR]         = { 0x07, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+
+       /*
+        * Common SCIFA definitions.
+        */
+       [SCIx_SCIFA_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x20,  8 },
+               [SCxSR]         = { 0x14, 16 },
+               [SCxRDR]        = { 0x24,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+
+       /*
+        * Common SCIFB definitions.
+        */
+       [SCIx_SCIFB_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x40,  8 },
+               [SCxSR]         = { 0x14, 16 },
+               [SCxRDR]        = { 0x60,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+
+       /*
+        * Common SH-3 SCIF definitions.
+        */
+       [SCIx_SH3_SCIF_REGTYPE] = {
+               [SCSMR]         = { 0x00,  8 },
+               [SCBRR]         = { 0x02,  8 },
+               [SCSCR]         = { 0x04,  8 },
+               [SCxTDR]        = { 0x06,  8 },
+               [SCxSR]         = { 0x08, 16 },
+               [SCxRDR]        = { 0x0a,  8 },
+               [SCFCR]         = { 0x0c,  8 },
+               [SCFDR]         = { 0x0e, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+
+       /*
+        * Common SH-4(A) SCIF(B) definitions.
+        */
+       [SCIx_SH4_SCIF_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x0c,  8 },
+               [SCxSR]         = { 0x10, 16 },
+               [SCxRDR]        = { 0x14,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = { 0x20, 16 },
+               [SCLSR]         = { 0x24, 16 },
+       },
+
+       /*
+        * Common SH-4(A) SCIF(B) definitions for ports without an SCSPTR
+        * register.
+        */
+       [SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x0c,  8 },
+               [SCxSR]         = { 0x10, 16 },
+               [SCxRDR]        = { 0x14,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = { 0x24, 16 },
+       },
+
+       /*
+        * Common SH-4(A) SCIF(B) definitions for ports with FIFO data
+        * count registers.
+        */
+       [SCIx_SH4_SCIF_FIFODATA_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x0c,  8 },
+               [SCxSR]         = { 0x10, 16 },
+               [SCxRDR]        = { 0x14,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = { 0x1c, 16 }, /* aliased to SCFDR */
+               [SCRFDR]        = { 0x20, 16 },
+               [SCSPTR]        = { 0x24, 16 },
+               [SCLSR]         = { 0x28, 16 },
+       },
+
+       /*
+        * SH7705-style SCIF(B) ports, lacking both SCSPTR and SCLSR
+        * registers.
+        */
+       [SCIx_SH7705_SCIF_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x20,  8 },
+               [SCxSR]         = { 0x14, 16 },
+               [SCxRDR]        = { 0x24,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = sci_reg_invalid,
+               [SCLSR]         = sci_reg_invalid,
+       },
+};
+
+/*
+ * The "offset" here is rather misleading, in that it refers to an enum
+ * value relative to the port mapping rather than the fixed offset
+ * itself, which needs to be manually retrieved from the platform's
+ * register map for the given port.
+ */
+static unsigned int sci_serial_in(struct uart_port *p, int offset)
+{
+       struct sci_port *s = to_sci_port(p);
+       struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
+
+       if (reg->size == 8)
+               return ioread8(p->membase + (reg->offset << p->regshift));
+       else if (reg->size == 16)
+               return ioread16(p->membase + (reg->offset << p->regshift));
+       else
+               WARN(1, "Invalid register access\n");
+
+       return 0;
+}
+
+static void sci_serial_out(struct uart_port *p, int offset, int value)
+{
+       struct sci_port *s = to_sci_port(p);
+       struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
+
+       if (reg->size == 8)
+               iowrite8(value, p->membase + (reg->offset << p->regshift));
+       else if (reg->size == 16)
+               iowrite16(value, p->membase + (reg->offset << p->regshift));
+       else
+               WARN(1, "Invalid register access\n");
+}
+
+#define sci_in(up, offset)             (up->serial_in(up, offset))
+#define sci_out(up, offset, value)     (up->serial_out(up, offset, value))
+
+static int sci_probe_regmap(struct plat_sci_port *cfg)
+{
+       switch (cfg->type) {
+       case PORT_SCI:
+               cfg->regtype = SCIx_SCI_REGTYPE;
+               break;
+       case PORT_IRDA:
+               cfg->regtype = SCIx_IRDA_REGTYPE;
+               break;
+       case PORT_SCIFA:
+               cfg->regtype = SCIx_SCIFA_REGTYPE;
+               break;
+       case PORT_SCIFB:
+               cfg->regtype = SCIx_SCIFB_REGTYPE;
+               break;
+       case PORT_SCIF:
+               /*
+                * The SH-4 is a bit of a misnomer here, although that's
+                * where this particular port layout originated. This
+                * configuration (or some slight variation thereof)
+                * remains the dominant model for all SCIFs.
+                */
+               cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
+               break;
+       default:
+               printk(KERN_ERR "Can't probe register map for given port\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
 
 #ifdef CONFIG_CONSOLE_POLL
@@ -160,103 +409,29 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
-       if (port->mapbase == 0xA4400000) {
-               __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
-               __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
-       } else if (port->mapbase == 0xA4410000)
-               __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721)
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
-       unsigned short data;
-
-       if (cflag & CRTSCTS) {
-               /* enable RTS/CTS */
-               if (port->mapbase == 0xa4430000) { /* SCIF0 */
-                       /* Clear PTCR bit 9-2; enable all scif pins but sck */
-                       data = __raw_readw(PORT_PTCR);
-                       __raw_writew((data & 0xfc03), PORT_PTCR);
-               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
-                       /* Clear PVCR bit 9-2 */
-                       data = __raw_readw(PORT_PVCR);
-                       __raw_writew((data & 0xfc03), PORT_PVCR);
-               }
-       } else {
-               if (port->mapbase == 0xa4430000) { /* SCIF0 */
-                       /* Clear PTCR bit 5-2; enable only tx and rx  */
-                       data = __raw_readw(PORT_PTCR);
-                       __raw_writew((data & 0xffc3), PORT_PTCR);
-               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
-                       /* Clear PVCR bit 5-2 */
-                       data = __raw_readw(PORT_PVCR);
-                       __raw_writew((data & 0xffc3), PORT_PVCR);
-               }
-       }
-}
-#elif defined(CONFIG_CPU_SH3)
-/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
+static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 {
-       unsigned short data;
-
-       /* We need to set SCPCR to enable RTS/CTS */
-       data = __raw_readw(SCPCR);
-       /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
-       __raw_writew(data & 0x0fcf, SCPCR);
-
-       if (!(cflag & CRTSCTS)) {
-               /* We need to set SCPCR to enable RTS/CTS */
-               data = __raw_readw(SCPCR);
-               /* Clear out SCP7MD1,0, SCP4MD1,0,
-                  Set SCP6MD1,0 = {01} (output)  */
-               __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
+       struct sci_port *s = to_sci_port(port);
+       struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 
-               data = __raw_readb(SCPDR);
-               /* Set /RTS2 (bit6) = 0 */
-               __raw_writeb(data & 0xbf, SCPDR);
+       /*
+        * Use port-specific handler if provided.
+        */
+       if (s->cfg->ops && s->cfg->ops->init_pins) {
+               s->cfg->ops->init_pins(port, cflag);
+               return;
        }
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
-       unsigned short data;
 
-       if (port->mapbase == 0xffe00000) {
-               data = __raw_readw(PSCR);
-               data &= ~0x03cf;
-               if (!(cflag & CRTSCTS))
-                       data |= 0x0340;
+       /*
+        * For the generic path SCSPTR is necessary. Bail out if that's
+        * unavailable, too.
+        */
+       if (!reg->size)
+               return;
 
-               __raw_writew(data, PSCR);
-       }
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7780) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7785) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7786) || \
-      defined(CONFIG_CPU_SUBTYPE_SHX3)
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
-       if (!(cflag & CRTSCTS))
-               __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */
-}
-#elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A)
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
        if (!(cflag & CRTSCTS))
-               __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */
+               sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
 }
-#else
-static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
-{
-       /* Nothing to do */
-}
-#endif
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
     defined(CONFIG_CPU_SUBTYPE_SH7780) || \
@@ -1752,6 +1927,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
                break;
        }
 
+       if (p->regtype == SCIx_PROBE_REGTYPE)
+               BUG_ON(sci_probe_regmap(p) != 0);
+
        if (dev) {
                sci_port->iclk = clk_get(&dev->dev, "sci_ick");
                if (IS_ERR(sci_port->iclk)) {
@@ -1812,9 +1990,10 @@ static int __devinit sci_init_single(struct platform_device *dev,
        port->mapbase           = p->mapbase;
        port->type              = p->type;
        port->flags             = p->flags;
+       port->regshift          = p->regshift;
 
        /*
-        * The UART port needs an IRQ value, so we peg this to the TX IRQ
+        * The UART port needs an IRQ value, so we peg this to the RX IRQ
         * for the multi-IRQ ports, which is where we are primarily
         * concerned with the shutdown path synchronization.
         *
@@ -1822,6 +2001,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
         */
        port->irq               = p->irqs[SCIx_RXI_IRQ];
 
+       port->serial_in         = sci_serial_in;
+       port->serial_out        = sci_serial_out;
+
        if (p->dma_dev)
                dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n",
                        p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
index 5834f33d20ffb124b48a6b3f862d2ba011f59984..26de640a9d013c383876cd2eb47d6d7d09b00795 100644 (file)
@@ -2,69 +2,6 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7708) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-# define SCPCR  0xA4000116 /* 16 bit SCI and SCIF */
-# define SCPDR  0xA4000136 /* 8  bit SCI and SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-      defined(CONFIG_ARCH_SH73A0) || \
-      defined(CONFIG_ARCH_SH7367) || \
-      defined(CONFIG_ARCH_SH7377) || \
-      defined(CONFIG_ARCH_SH7372)
-# define PORT_PTCR        0xA405011EUL
-# define PORT_PVCR        0xA4050122UL
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750)  || \
-      defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7091)  || \
-      defined(CONFIG_CPU_SUBTYPE_SH7751)  || \
-      defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
-      defined(CONFIG_CPU_SUBTYPE_SH4_202)
-# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-# define SCSPTR0 0xfe600024 /* 16 bit SCIF */
-# define SCSPTR2 0xfe620024 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-# define SCSPTR0 0xA4400000      /* 16 bit SCIF */
-# define PACR 0xa4050100
-# define PBCR 0xa4050102
-#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
-# define SCSPTR0 0xffe00010    /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-# define PWDR                  0xA4050166
-# define PSCR                  0xA405011E
-#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
-# define SCPDR0                        0xA405013E      /* 16 bit SCIF0 PSDR */
-# define SCSPTR0               SCPDR0
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
-# define SCSPTR0                0xa4050160
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-# define SCSPTR0 0xfe4b0020
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7780)
-# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
-# define SCSPTR0 0xff923020 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7786)
-# define SCSPTR0       0xffea0024      /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7203) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7206) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7263)
-# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
-#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
-# define SCSPTR0 0xffc30020            /* 16 bit SCIF */
-#else
-# error CPU subtype not defined
-#endif
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
 
 #define SCI_MAJOR              204
 #define SCI_MINOR_START                8
-
-#define SCI_IN(size, offset)           \
-       ioread##size(port->membase + (offset))
-
-#define SCI_OUT(size, offset, value)   \
-       iowrite##size(value, port->membase + (offset))
-
-#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
-  static inline unsigned int sci_##name##_in(struct uart_port *port)   \
-  {                                                                    \
-    if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {         \
-      return SCI_IN(scif_size, scif_offset);                           \
-    } else {   /* PORT_SCI or PORT_SCIFA */                            \
-      return SCI_IN(sci_size, sci_offset);                             \
-    }                                                                  \
-  }                                                                    \
-  static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
-  {                                                                    \
-    if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {         \
-      SCI_OUT(scif_size, scif_offset, value);                          \
-    } else {   /* PORT_SCI or PORT_SCIFA */                            \
-      SCI_OUT(sci_size, sci_offset, value);                            \
-    }                                                                  \
-  }
-
-#define CPU_SCIF_FNS(name, scif_offset, scif_size)                     \
-  static inline unsigned int sci_##name##_in(struct uart_port *port)   \
-  {                                                                    \
-    return SCI_IN(scif_size, scif_offset);                             \
-  }                                                                    \
-  static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
-  {                                                                    \
-    SCI_OUT(scif_size, scif_offset, value);                            \
-  }
-
-#if defined(CONFIG_CPU_SH3) || \
-    defined(CONFIG_ARCH_SH73A0) || \
-    defined(CONFIG_ARCH_SH7367) || \
-    defined(CONFIG_ARCH_SH7377) || \
-    defined(CONFIG_ARCH_SH7372)
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
-                sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-  CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
-#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-         CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-      defined(CONFIG_ARCH_SH7367)
-#define SCIF_FNS(name, scif_offset, scif_size) \
-  CPU_SCIF_FNS(name, scif_offset, scif_size)
-#elif defined(CONFIG_ARCH_SH7377) || \
-      defined(CONFIG_ARCH_SH7372) || \
-      defined(CONFIG_ARCH_SH73A0)
-#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
-  CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
-#define SCIF_FNS(name, scif_offset, scif_size) \
-  CPU_SCIF_FNS(name, scif_offset, scif_size)
-#else
-#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
-                sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-  CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
-#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-  CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
-#endif
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
-      defined(CONFIG_CPU_SUBTYPE_SH7724)
-        #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \
-                CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size)
-        #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
-                CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
-#else
-#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
-                sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-  CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
-#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
-  CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
-#endif
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SH7367)
-
-SCIF_FNS(SCSMR,  0x00, 16)
-SCIF_FNS(SCBRR,  0x04,  8)
-SCIF_FNS(SCSCR,  0x08, 16)
-SCIF_FNS(SCxSR,  0x14, 16)
-SCIF_FNS(SCFCR,  0x18, 16)
-SCIF_FNS(SCFDR,  0x1c, 16)
-SCIF_FNS(SCxTDR, 0x20,  8)
-SCIF_FNS(SCxRDR, 0x24,  8)
-SCIF_FNS(SCLSR,  0x00,  0)
-#elif defined(CONFIG_ARCH_SH7377) || \
-      defined(CONFIG_ARCH_SH7372) || \
-      defined(CONFIG_ARCH_SH73A0)
-SCIF_FNS(SCSMR,  0x00, 16)
-SCIF_FNS(SCBRR,  0x04,  8)
-SCIF_FNS(SCSCR,  0x08, 16)
-SCIF_FNS(SCTDSR, 0x0c, 16)
-SCIF_FNS(SCFER,  0x10, 16)
-SCIF_FNS(SCxSR,  0x14, 16)
-SCIF_FNS(SCFCR,  0x18, 16)
-SCIF_FNS(SCFDR,  0x1c, 16)
-SCIF_FNS(SCTFDR, 0x38, 16)
-SCIF_FNS(SCRFDR, 0x3c, 16)
-SCIx_FNS(SCxTDR, 0x20,  8, 0x40,  8)
-SCIx_FNS(SCxRDR, 0x24,  8, 0x60,  8)
-SCIF_FNS(SCLSR,  0x00,  0)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
-      defined(CONFIG_CPU_SUBTYPE_SH7724)
-SCIx_FNS(SCSMR,  0x00, 16, 0x00, 16)
-SCIx_FNS(SCBRR,  0x04,  8, 0x04,  8)
-SCIx_FNS(SCSCR,  0x08, 16, 0x08, 16)
-SCIx_FNS(SCxTDR, 0x20,  8, 0x0c,  8)
-SCIx_FNS(SCxSR,  0x14, 16, 0x10, 16)
-SCIx_FNS(SCxRDR, 0x24,  8, 0x14,  8)
-SCIx_FNS(SCSPTR, 0,     0,    0,  0)
-SCIF_FNS(SCFCR,  0x18, 16)
-SCIF_FNS(SCFDR,  0x1c, 16)
-SCIF_FNS(SCLSR,  0x24, 16)
-#else
-/*      reg      SCI/SH3   SCI/SH4  SCIF/SH3   SCIF/SH4  */
-/*      name     off  sz   off  sz   off  sz   off  sz   */
-SCIx_FNS(SCSMR,  0x00,  8, 0x00,  8, 0x00,  8, 0x00, 16)
-SCIx_FNS(SCBRR,  0x02,  8, 0x04,  8, 0x02,  8, 0x04,  8)
-SCIx_FNS(SCSCR,  0x04,  8, 0x08,  8, 0x04,  8, 0x08, 16)
-SCIx_FNS(SCxTDR, 0x06,  8, 0x0c,  8, 0x06,  8, 0x0C,  8)
-SCIx_FNS(SCxSR,  0x08,  8, 0x10,  8, 0x08, 16, 0x10, 16)
-SCIx_FNS(SCxRDR, 0x0a,  8, 0x14,  8, 0x0A,  8, 0x14,  8)
-SCIF_FNS(SCFCR,                      0x0c,  8, 0x18, 16)
-#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7780) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7785) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7786)
-SCIF_FNS(SCFDR,                             0x0e, 16, 0x1C, 16)
-SCIF_FNS(SCTFDR,                    0x0e, 16, 0x1C, 16)
-SCIF_FNS(SCRFDR,                    0x0e, 16, 0x20, 16)
-SCIF_FNS(SCSPTR,                       0,  0, 0x24, 16)
-SCIF_FNS(SCLSR,                                0,  0, 0x28, 16)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-SCIF_FNS(SCFDR,                                0,  0, 0x1C, 16)
-SCIF_FNS(SCTFDR,                    0x0e, 16, 0x1C, 16)
-SCIF_FNS(SCRFDR,                    0x0e, 16, 0x20, 16)
-SCIF_FNS(SCSPTR,                       0,  0, 0x24, 16)
-SCIF_FNS(SCLSR,                                0,  0, 0x28, 16)
-#else
-SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
-#if defined(CONFIG_CPU_SUBTYPE_SH7722)
-SCIF_FNS(SCSPTR,                        0,  0, 0, 0)
-#else
-SCIF_FNS(SCSPTR,                        0,  0, 0x20, 16)
-#endif
-SCIF_FNS(SCLSR,                         0,  0, 0x24, 16)
-#endif
-#endif
-#define sci_in(port, reg) sci_##reg##_in(port)
-#define sci_out(port, reg, value) sci_##reg##_out(port, value)
index ecefec7c0b670c4abd3055b4ddecc5eb23b23bbf..4ca130a90ea557abcab6a88723acbacc6f8ca12d 100644 (file)
@@ -58,6 +58,22 @@ enum {
        SCIx_NR_IRQS,
 };
 
+enum {
+       SCIx_PROBE_REGTYPE,
+
+       SCIx_SCI_REGTYPE,
+       SCIx_IRDA_REGTYPE,
+       SCIx_SCIFA_REGTYPE,
+       SCIx_SCIFB_REGTYPE,
+       SCIx_SH3_SCIF_REGTYPE,
+       SCIx_SH4_SCIF_REGTYPE,
+       SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
+       SCIx_SH4_SCIF_FIFODATA_REGTYPE,
+       SCIx_SH7705_SCIF_REGTYPE,
+
+       SCIx_NR_REGTYPES,
+};
+
 #define SCIx_IRQ_MUXED(irq)            \
 {                                      \
        [SCIx_ERI_IRQ]  = (irq),        \
@@ -66,8 +82,24 @@ enum {
        [SCIx_BRI_IRQ]  = (irq),        \
 }
 
+/*
+ * SCI register subset common for all port types.
+ * Not all registers will exist on all parts.
+ */
+enum {
+       SCSMR, SCBRR, SCSCR, SCxSR,
+       SCFCR, SCFDR, SCxTDR, SCxRDR,
+       SCLSR, SCTFDR, SCRFDR, SCSPTR,
+
+       SCIx_NR_REGS,
+};
+
 struct device;
 
+struct plat_sci_port_ops {
+       void (*init_pins)(struct uart_port *, unsigned int cflag);
+};
+
 /*
  * Platform device specific platform_data struct
  */
@@ -87,6 +119,10 @@ struct plat_sci_port {
        unsigned int    error_mask;
 
        int             port_reg;
+       unsigned char   regshift;
+       unsigned char   regtype;
+
+       struct plat_sci_port_ops        *ops;
 
        struct device   *dma_dev;