Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: sh-sci: Abstract register maps.

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>

+516 -328
+1
arch/sh/Makefile
··· 173 173 cpuincdir-$(CONFIG_CPU_SH2A) += cpu-sh2a 174 174 cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2 175 175 cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3 176 + cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a 176 177 cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 177 178 cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5 178 179 cpuincdir-y += cpu-common # Must be last
+10
arch/sh/include/cpu-sh3/cpu/serial.h
··· 1 + #ifndef __CPU_SH3_SERIAL_H 2 + #define __CPU_SH3_SERIAL_H 3 + 4 + #include <linux/serial_sci.h> 5 + 6 + extern struct plat_sci_port_ops sh770x_sci_port_ops; 7 + extern struct plat_sci_port_ops sh7710_sci_port_ops; 8 + extern struct plat_sci_port_ops sh7720_sci_port_ops; 9 + 10 + #endif /* __CPU_SH3_SERIAL_H */
+7
arch/sh/include/cpu-sh4a/cpu/serial.h
··· 1 + #ifndef __CPU_SH4A_SERIAL_H 2 + #define __CPU_SH4A_SERIAL_H 3 + 4 + /* arch/sh/kernel/cpu/sh4a/serial-sh7722.c */ 5 + extern struct plat_sci_port_ops sh7722_sci_port_ops; 6 + 7 + #endif /* __CPU_SH4A_SERIAL_H */
+9 -9
arch/sh/kernel/cpu/sh3/Makefile
··· 7 7 obj-$(CONFIG_HIBERNATION) += swsusp.o 8 8 9 9 # CPU subtype setup 10 - obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o 11 - obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o 12 - obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o 13 - obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o 14 - obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o 15 - obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o 16 - obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o 17 - obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o 18 - obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o 10 + obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o serial-sh770x.o 11 + obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o serial-sh770x.o 12 + obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o serial-sh770x.o 13 + obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o serial-sh770x.o 14 + obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o serial-sh770x.o 15 + obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o serial-sh7710.o 16 + obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o serial-sh7710.o 17 + obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o serial-sh7720.o 18 + obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o serial-sh7720.o 19 19 20 20 # Primary on-chip clocks (common) 21 21 clock-$(CONFIG_CPU_SH3) := clock-sh3.o
+33
arch/sh/kernel/cpu/sh3/serial-sh770x.c
··· 1 + #include <linux/serial_sci.h> 2 + #include <linux/serial_core.h> 3 + #include <linux/io.h> 4 + #include <cpu/serial.h> 5 + 6 + #define SCPCR 0xA4000116 7 + #define SCPDR 0xA4000136 8 + 9 + static void sh770x_sci_init_pins(struct uart_port *port, unsigned int cflag) 10 + { 11 + unsigned short data; 12 + 13 + /* We need to set SCPCR to enable RTS/CTS */ 14 + data = __raw_readw(SCPCR); 15 + /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ 16 + __raw_writew(data & 0x0fcf, SCPCR); 17 + 18 + if (!(cflag & CRTSCTS)) { 19 + /* We need to set SCPCR to enable RTS/CTS */ 20 + data = __raw_readw(SCPCR); 21 + /* Clear out SCP7MD1,0, SCP4MD1,0, 22 + Set SCP6MD1,0 = {01} (output) */ 23 + __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); 24 + 25 + data = __raw_readb(SCPDR); 26 + /* Set /RTS2 (bit6) = 0 */ 27 + __raw_writeb(data & 0xbf, SCPDR); 28 + } 29 + } 30 + 31 + struct plat_sci_port_ops sh770x_sci_port_ops = { 32 + .init_pins = sh770x_sci_init_pins, 33 + };
+20
arch/sh/kernel/cpu/sh3/serial-sh7710.c
··· 1 + #include <linux/serial_sci.h> 2 + #include <linux/serial_core.h> 3 + #include <linux/io.h> 4 + #include <cpu/serial.h> 5 + 6 + #define PACR 0xa4050100 7 + #define PBCR 0xa4050102 8 + 9 + static void sh7710_sci_init_pins(struct uart_port *port, unsigned int cflag) 10 + { 11 + if (port->mapbase == 0xA4400000) { 12 + __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); 13 + __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); 14 + } else if (port->mapbase == 0xA4410000) 15 + __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); 16 + } 17 + 18 + struct plat_sci_port_ops sh7710_sci_port_ops = { 19 + .init_pins = sh7710_sci_init_pins, 20 + };
+36
arch/sh/kernel/cpu/sh3/serial-sh7720.c
··· 1 + #include <linux/serial_sci.h> 2 + #include <linux/serial_core.h> 3 + #include <linux/io.h> 4 + #include <cpu/serial.h> 5 + 6 + static void sh7720_sci_init_pins(struct uart_port *port, unsigned int cflag) 7 + { 8 + unsigned short data; 9 + 10 + if (cflag & CRTSCTS) { 11 + /* enable RTS/CTS */ 12 + if (port->mapbase == 0xa4430000) { /* SCIF0 */ 13 + /* Clear PTCR bit 9-2; enable all scif pins but sck */ 14 + data = __raw_readw(PORT_PTCR); 15 + __raw_writew((data & 0xfc03), PORT_PTCR); 16 + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 17 + /* Clear PVCR bit 9-2 */ 18 + data = __raw_readw(PORT_PVCR); 19 + __raw_writew((data & 0xfc03), PORT_PVCR); 20 + } 21 + } else { 22 + if (port->mapbase == 0xa4430000) { /* SCIF0 */ 23 + /* Clear PTCR bit 5-2; enable only tx and rx */ 24 + data = __raw_readw(PORT_PTCR); 25 + __raw_writew((data & 0xffc3), PORT_PTCR); 26 + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 27 + /* Clear PVCR bit 5-2 */ 28 + data = __raw_readw(PORT_PVCR); 29 + __raw_writew((data & 0xffc3), PORT_PVCR); 30 + } 31 + } 32 + } 33 + 34 + struct plat_sci_port_ops sh7720_sci_port_ops = { 35 + .init_pins = sh7720_sci_init_pins, 36 + };
+5
arch/sh/kernel/cpu/sh3/setup-sh7705.c
··· 15 15 #include <linux/serial_sci.h> 16 16 #include <linux/sh_timer.h> 17 17 #include <asm/rtc.h> 18 + #include <cpu/serial.h> 18 19 19 20 enum { 20 21 UNUSED = 0, ··· 76 75 .scbrr_algo_id = SCBRR_ALGO_4, 77 76 .type = PORT_SCIF, 78 77 .irqs = { 56, 56, 56 }, 78 + .ops = &sh770x_sci_port_ops, 79 + .regtype = SCIx_SH7705_SCIF_REGTYPE, 79 80 }; 80 81 81 82 static struct platform_device scif0_device = { ··· 95 92 .scbrr_algo_id = SCBRR_ALGO_4, 96 93 .type = PORT_SCIF, 97 94 .irqs = { 52, 52, 52 }, 95 + .ops = &sh770x_sci_port_ops, 96 + .regtype = SCIx_SH7705_SCIF_REGTYPE, 98 97 }; 99 98 100 99 static struct platform_device scif1_device = {
+8
arch/sh/kernel/cpu/sh3/setup-sh770x.c
··· 19 19 #include <linux/serial.h> 20 20 #include <linux/serial_sci.h> 21 21 #include <linux/sh_timer.h> 22 + #include <cpu/serial.h> 22 23 23 24 enum { 24 25 UNUSED = 0, ··· 115 114 .scbrr_algo_id = SCBRR_ALGO_2, 116 115 .type = PORT_SCI, 117 116 .irqs = { 23, 23, 23, 0 }, 117 + .ops = &sh770x_sci_port_ops, 118 + .regshift = 1, 118 119 }; 119 120 120 121 static struct platform_device scif0_device = { ··· 136 133 .scbrr_algo_id = SCBRR_ALGO_2, 137 134 .type = PORT_SCIF, 138 135 .irqs = { 56, 56, 56, 56 }, 136 + .ops = &sh770x_sci_port_ops, 137 + .regtype = SCIx_SH3_SCIF_REGTYPE, 139 138 }; 140 139 141 140 static struct platform_device scif1_device = { ··· 152 147 defined(CONFIG_CPU_SUBTYPE_SH7709) 153 148 static struct plat_sci_port scif2_platform_data = { 154 149 .mapbase = 0xa4000140, 150 + .port_reg = SCIx_NOT_SUPPORTED, 155 151 .flags = UPF_BOOT_AUTOCONF, 156 152 .scscr = SCSCR_TE | SCSCR_RE, 157 153 .scbrr_algo_id = SCBRR_ALGO_2, 158 154 .type = PORT_IRDA, 159 155 .irqs = { 52, 52, 52, 52 }, 156 + .ops = &sh770x_sci_port_ops, 157 + .regshift = 1, 160 158 }; 161 159 162 160 static struct platform_device scif2_device = {
+5
arch/sh/kernel/cpu/sh3/setup-sh7720.c
··· 20 20 #include <linux/serial_sci.h> 21 21 #include <linux/sh_timer.h> 22 22 #include <asm/rtc.h> 23 + #include <cpu/serial.h> 23 24 24 25 static struct resource rtc_resources[] = { 25 26 [0] = { ··· 56 55 .scbrr_algo_id = SCBRR_ALGO_4, 57 56 .type = PORT_SCIF, 58 57 .irqs = { 80, 80, 80, 80 }, 58 + .ops = &sh7720_sci_port_ops, 59 + .regtype = SCIx_SH7705_SCIF_REGTYPE, 59 60 }; 60 61 61 62 static struct platform_device scif0_device = { ··· 75 72 .scbrr_algo_id = SCBRR_ALGO_4, 76 73 .type = PORT_SCIF, 77 74 .irqs = { 81, 81, 81, 81 }, 75 + .ops = &sh7720_sci_port_ops, 76 + .regtype = SCIx_SH7705_SCIF_REGTYPE, 78 77 }; 79 78 80 79 static struct platform_device scif1_device = {
+2 -1
arch/sh/kernel/cpu/sh4/setup-sh7750.c
··· 1 1 /* 2 - * SH7750/SH7751 Setup 2 + * SH7091/SH7750/SH7750S/SH7750R/SH7751/SH7751R Setup 3 3 * 4 4 * Copyright (C) 2006 Paul Mundt 5 5 * Copyright (C) 2006 Jamie Lenehan ··· 44 44 .scbrr_algo_id = SCBRR_ALGO_2, 45 45 .type = PORT_SCI, 46 46 .irqs = { 23, 23, 23, 0 }, 47 + .regshift = 2, 47 48 }; 48 49 49 50 static struct platform_device sci_device = {
+4
arch/sh/kernel/cpu/sh4/setup-sh7760.c
··· 133 133 .scbrr_algo_id = SCBRR_ALGO_2, 134 134 .type = PORT_SCIF, 135 135 .irqs = { 52, 53, 55, 54 }, 136 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 136 137 }; 137 138 138 139 static struct platform_device scif0_device = { ··· 151 150 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 152 151 .scbrr_algo_id = SCBRR_ALGO_2, 153 152 .irqs = { 72, 73, 75, 74 }, 153 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 154 154 }; 155 155 156 156 static struct platform_device scif1_device = { ··· 169 167 .scbrr_algo_id = SCBRR_ALGO_2, 170 168 .type = PORT_SCIF, 171 169 .irqs = { 76, 77, 79, 78 }, 170 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 172 171 }; 173 172 174 173 static struct platform_device scif2_device = { ··· 187 184 .scbrr_algo_id = SCBRR_ALGO_2, 188 185 .type = PORT_SCI, 189 186 .irqs = { 80, 81, 82, 0 }, 187 + .regshift = 2, 190 188 }; 191 189 192 190 static struct platform_device scif3_device = {
+1 -1
arch/sh/kernel/cpu/sh4a/Makefile
··· 10 10 obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o 11 11 obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o 12 12 obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o 13 - obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o 13 + obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o serial-sh7722.o 14 14 obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o 15 15 obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o 16 16 obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
+23
arch/sh/kernel/cpu/sh4a/serial-sh7722.c
··· 1 + #include <linux/serial_sci.h> 2 + #include <linux/serial_core.h> 3 + #include <linux/io.h> 4 + 5 + #define PSCR 0xA405011E 6 + 7 + static void sh7722_sci_init_pins(struct uart_port *port, unsigned int cflag) 8 + { 9 + unsigned short data; 10 + 11 + if (port->mapbase == 0xffe00000) { 12 + data = __raw_readw(PSCR); 13 + data &= ~0x03cf; 14 + if (!(cflag & CRTSCTS)) 15 + data |= 0x0340; 16 + 17 + __raw_writew(data, PSCR); 18 + } 19 + } 20 + 21 + struct plat_sci_port_ops sh7722_sci_port_ops = { 22 + .init_pins = sh7722_sci_init_pins, 23 + };
+1
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
··· 20 20 21 21 static struct plat_sci_port scif0_platform_data = { 22 22 .mapbase = 0xffe00000, 23 + .port_reg = 0xa405013e, 23 24 .flags = UPF_BOOT_AUTOCONF, 24 25 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 25 26 .scbrr_algo_id = SCBRR_ALGO_2,
+6
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
··· 185 185 .scbrr_algo_id = SCBRR_ALGO_2, 186 186 .type = PORT_SCIF, 187 187 .irqs = { 80, 80, 80, 80 }, 188 + .ops = &sh7722_sci_port_ops, 189 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 188 190 }; 189 191 190 192 static struct platform_device scif0_device = { ··· 204 202 .scbrr_algo_id = SCBRR_ALGO_2, 205 203 .type = PORT_SCIF, 206 204 .irqs = { 81, 81, 81, 81 }, 205 + .ops = &sh7722_sci_port_ops, 206 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 207 207 }; 208 208 209 209 static struct platform_device scif1_device = { ··· 223 219 .scbrr_algo_id = SCBRR_ALGO_2, 224 220 .type = PORT_SCIF, 225 221 .irqs = { 82, 82, 82, 82 }, 222 + .ops = &sh7722_sci_port_ops, 223 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 226 224 }; 227 225 228 226 static struct platform_device scif2_device = {
+9
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
··· 23 23 /* Serial */ 24 24 static struct plat_sci_port scif0_platform_data = { 25 25 .mapbase = 0xffe00000, 26 + .port_reg = 0xa4050160, 26 27 .flags = UPF_BOOT_AUTOCONF, 27 28 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 28 29 .scbrr_algo_id = SCBRR_ALGO_2, 29 30 .type = PORT_SCIF, 30 31 .irqs = { 80, 80, 80, 80 }, 32 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 31 33 }; 32 34 33 35 static struct platform_device scif0_device = { ··· 42 40 43 41 static struct plat_sci_port scif1_platform_data = { 44 42 .mapbase = 0xffe10000, 43 + .port_reg = SCIx_NOT_SUPPORTED, 45 44 .flags = UPF_BOOT_AUTOCONF, 46 45 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 47 46 .scbrr_algo_id = SCBRR_ALGO_2, 48 47 .type = PORT_SCIF, 49 48 .irqs = { 81, 81, 81, 81 }, 49 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 50 50 }; 51 51 52 52 static struct platform_device scif1_device = { ··· 61 57 62 58 static struct plat_sci_port scif2_platform_data = { 63 59 .mapbase = 0xffe20000, 60 + .port_reg = SCIx_NOT_SUPPORTED, 64 61 .flags = UPF_BOOT_AUTOCONF, 65 62 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 66 63 .scbrr_algo_id = SCBRR_ALGO_2, 67 64 .type = PORT_SCIF, 68 65 .irqs = { 82, 82, 82, 82 }, 66 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 69 67 }; 70 68 71 69 static struct platform_device scif2_device = { ··· 81 75 static struct plat_sci_port scif3_platform_data = { 82 76 .mapbase = 0xa4e30000, 83 77 .flags = UPF_BOOT_AUTOCONF, 78 + .port_reg = SCIx_NOT_SUPPORTED, 84 79 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 85 80 .scbrr_algo_id = SCBRR_ALGO_3, 86 81 .type = PORT_SCIFA, ··· 98 91 99 92 static struct plat_sci_port scif4_platform_data = { 100 93 .mapbase = 0xa4e40000, 94 + .port_reg = SCIx_NOT_SUPPORTED, 101 95 .flags = UPF_BOOT_AUTOCONF, 102 96 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 103 97 .scbrr_algo_id = SCBRR_ALGO_3, ··· 116 108 117 109 static struct plat_sci_port scif5_platform_data = { 118 110 .mapbase = 0xa4e50000, 111 + .port_reg = SCIx_NOT_SUPPORTED, 119 112 .flags = UPF_BOOT_AUTOCONF, 120 113 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 121 114 .scbrr_algo_id = SCBRR_ALGO_3,
+9
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
··· 256 256 /* Serial */ 257 257 static struct plat_sci_port scif0_platform_data = { 258 258 .mapbase = 0xffe00000, 259 + .port_reg = SCIx_NOT_SUPPORTED, 259 260 .flags = UPF_BOOT_AUTOCONF, 260 261 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 261 262 .scbrr_algo_id = SCBRR_ALGO_2, 262 263 .type = PORT_SCIF, 263 264 .irqs = { 80, 80, 80, 80 }, 265 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 264 266 }; 265 267 266 268 static struct platform_device scif0_device = { ··· 275 273 276 274 static struct plat_sci_port scif1_platform_data = { 277 275 .mapbase = 0xffe10000, 276 + .port_reg = SCIx_NOT_SUPPORTED, 278 277 .flags = UPF_BOOT_AUTOCONF, 279 278 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 280 279 .scbrr_algo_id = SCBRR_ALGO_2, 281 280 .type = PORT_SCIF, 282 281 .irqs = { 81, 81, 81, 81 }, 282 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 283 283 }; 284 284 285 285 static struct platform_device scif1_device = { ··· 294 290 295 291 static struct plat_sci_port scif2_platform_data = { 296 292 .mapbase = 0xffe20000, 293 + .port_reg = SCIx_NOT_SUPPORTED, 297 294 .flags = UPF_BOOT_AUTOCONF, 298 295 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 299 296 .scbrr_algo_id = SCBRR_ALGO_2, 300 297 .type = PORT_SCIF, 301 298 .irqs = { 82, 82, 82, 82 }, 299 + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 302 300 }; 303 301 304 302 static struct platform_device scif2_device = { ··· 313 307 314 308 static struct plat_sci_port scif3_platform_data = { 315 309 .mapbase = 0xa4e30000, 310 + .port_reg = SCIx_NOT_SUPPORTED, 316 311 .flags = UPF_BOOT_AUTOCONF, 317 312 .scscr = SCSCR_RE | SCSCR_TE, 318 313 .scbrr_algo_id = SCBRR_ALGO_3, ··· 331 324 332 325 static struct plat_sci_port scif4_platform_data = { 333 326 .mapbase = 0xa4e40000, 327 + .port_reg = SCIx_NOT_SUPPORTED, 334 328 .flags = UPF_BOOT_AUTOCONF, 335 329 .scscr = SCSCR_RE | SCSCR_TE, 336 330 .scbrr_algo_id = SCBRR_ALGO_3, ··· 349 341 350 342 static struct plat_sci_port scif5_platform_data = { 351 343 .mapbase = 0xa4e50000, 344 + .port_reg = SCIx_NOT_SUPPORTED, 352 345 .flags = UPF_BOOT_AUTOCONF, 353 346 .scscr = SCSCR_RE | SCSCR_TE, 354 347 .scbrr_algo_id = SCBRR_ALGO_3,
+3
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
··· 23 23 .scbrr_algo_id = SCBRR_ALGO_2, 24 24 .type = PORT_SCIF, 25 25 .irqs = { 40, 40, 40, 40 }, 26 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 26 27 }; 27 28 28 29 static struct platform_device scif0_device = { ··· 41 40 .scbrr_algo_id = SCBRR_ALGO_2, 42 41 .type = PORT_SCIF, 43 42 .irqs = { 76, 76, 76, 76 }, 43 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 44 44 }; 45 45 46 46 static struct platform_device scif1_device = { ··· 59 57 .scbrr_algo_id = SCBRR_ALGO_2, 60 58 .type = PORT_SCIF, 61 59 .irqs = { 104, 104, 104, 104 }, 60 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 62 61 }; 63 62 64 63 static struct platform_device scif2_device = {
+2 -1
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
··· 14 14 #include <linux/serial_sci.h> 15 15 #include <linux/sh_dma.h> 16 16 #include <linux/sh_timer.h> 17 - 18 17 #include <cpu/dma-register.h> 19 18 20 19 static struct plat_sci_port scif0_platform_data = { ··· 23 24 .scbrr_algo_id = SCBRR_ALGO_1, 24 25 .type = PORT_SCIF, 25 26 .irqs = { 40, 40, 40, 40 }, 27 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 26 28 }; 27 29 28 30 static struct platform_device scif0_device = { ··· 41 41 .scbrr_algo_id = SCBRR_ALGO_1, 42 42 .type = PORT_SCIF, 43 43 .irqs = { 76, 76, 76, 76 }, 44 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 44 45 }; 45 46 46 47 static struct platform_device scif1_device = {
+6 -2
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
··· 15 15 #include <linux/mm.h> 16 16 #include <linux/sh_dma.h> 17 17 #include <linux/sh_timer.h> 18 - 19 18 #include <asm/mmzone.h> 20 - 21 19 #include <cpu/dma-register.h> 22 20 23 21 static struct plat_sci_port scif0_platform_data = { ··· 25 27 .scbrr_algo_id = SCBRR_ALGO_1, 26 28 .type = PORT_SCIF, 27 29 .irqs = { 40, 40, 40, 40 }, 30 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 28 31 }; 29 32 30 33 static struct platform_device scif0_device = { ··· 43 44 .scbrr_algo_id = SCBRR_ALGO_1, 44 45 .type = PORT_SCIF, 45 46 .irqs = { 44, 44, 44, 44 }, 47 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 46 48 }; 47 49 48 50 static struct platform_device scif1_device = { ··· 61 61 .scbrr_algo_id = SCBRR_ALGO_1, 62 62 .type = PORT_SCIF, 63 63 .irqs = { 60, 60, 60, 60 }, 64 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 64 65 }; 65 66 66 67 static struct platform_device scif2_device = { ··· 79 78 .scbrr_algo_id = SCBRR_ALGO_1, 80 79 .type = PORT_SCIF, 81 80 .irqs = { 61, 61, 61, 61 }, 81 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 82 82 }; 83 83 84 84 static struct platform_device scif3_device = { ··· 97 95 .scbrr_algo_id = SCBRR_ALGO_1, 98 96 .type = PORT_SCIF, 99 97 .irqs = { 62, 62, 62, 62 }, 98 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 100 99 }; 101 100 102 101 static struct platform_device scif4_device = { ··· 115 112 .scbrr_algo_id = SCBRR_ALGO_1, 116 113 .type = PORT_SCIF, 117 114 .irqs = { 63, 63, 63, 63 }, 115 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 118 116 }; 119 117 120 118 static struct platform_device scif5_device = {
+7 -1
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
··· 1 1 /* 2 2 * SH7786 Setup 3 3 * 4 - * Copyright (C) 2009 - 2010 Renesas Solutions Corp. 4 + * Copyright (C) 2009 - 2011 Renesas Solutions Corp. 5 5 * Kuninori Morimoto <morimoto.kuninori@renesas.com> 6 6 * Paul Mundt <paul.mundt@renesas.com> 7 7 * ··· 33 33 .scbrr_algo_id = SCBRR_ALGO_1, 34 34 .type = PORT_SCIF, 35 35 .irqs = { 40, 41, 43, 42 }, 36 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 36 37 }; 37 38 38 39 static struct platform_device scif0_device = { ··· 54 53 .scbrr_algo_id = SCBRR_ALGO_1, 55 54 .type = PORT_SCIF, 56 55 .irqs = { 44, 44, 44, 44 }, 56 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 57 57 }; 58 58 59 59 static struct platform_device scif1_device = { ··· 72 70 .scbrr_algo_id = SCBRR_ALGO_1, 73 71 .type = PORT_SCIF, 74 72 .irqs = { 50, 50, 50, 50 }, 73 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 75 74 }; 76 75 77 76 static struct platform_device scif2_device = { ··· 90 87 .scbrr_algo_id = SCBRR_ALGO_1, 91 88 .type = PORT_SCIF, 92 89 .irqs = { 51, 51, 51, 51 }, 90 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 93 91 }; 94 92 95 93 static struct platform_device scif3_device = { ··· 108 104 .scbrr_algo_id = SCBRR_ALGO_1, 109 105 .type = PORT_SCIF, 110 106 .irqs = { 52, 52, 52, 52 }, 107 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 111 108 }; 112 109 113 110 static struct platform_device scif4_device = { ··· 126 121 .scbrr_algo_id = SCBRR_ALGO_1, 127 122 .type = PORT_SCIF, 128 123 .irqs = { 53, 53, 53, 53 }, 124 + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, 129 125 }; 130 126 131 127 static struct platform_device scif5_device = {
+273 -91
drivers/tty/serial/sh-sci.c
··· 117 117 return container_of(uart, struct sci_port, port); 118 118 } 119 119 120 + struct plat_sci_reg { 121 + u8 offset, size; 122 + }; 123 + 124 + /* Helper for invalidating specific entries of an inherited map. */ 125 + #define sci_reg_invalid { .offset = 0, .size = 0 } 126 + 127 + static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { 128 + [SCIx_PROBE_REGTYPE] = { 129 + [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid, 130 + }, 131 + 132 + /* 133 + * Common SCI definitions, dependent on the port's regshift 134 + * value. 135 + */ 136 + [SCIx_SCI_REGTYPE] = { 137 + [SCSMR] = { 0x00, 8 }, 138 + [SCBRR] = { 0x01, 8 }, 139 + [SCSCR] = { 0x02, 8 }, 140 + [SCxTDR] = { 0x03, 8 }, 141 + [SCxSR] = { 0x04, 8 }, 142 + [SCxRDR] = { 0x05, 8 }, 143 + [SCFCR] = sci_reg_invalid, 144 + [SCFDR] = sci_reg_invalid, 145 + [SCTFDR] = sci_reg_invalid, 146 + [SCRFDR] = sci_reg_invalid, 147 + [SCSPTR] = sci_reg_invalid, 148 + [SCLSR] = sci_reg_invalid, 149 + }, 150 + 151 + /* 152 + * Common definitions for legacy IrDA ports, dependent on 153 + * regshift value. 154 + */ 155 + [SCIx_IRDA_REGTYPE] = { 156 + [SCSMR] = { 0x00, 8 }, 157 + [SCBRR] = { 0x01, 8 }, 158 + [SCSCR] = { 0x02, 8 }, 159 + [SCxTDR] = { 0x03, 8 }, 160 + [SCxSR] = { 0x04, 8 }, 161 + [SCxRDR] = { 0x05, 8 }, 162 + [SCFCR] = { 0x06, 8 }, 163 + [SCFDR] = { 0x07, 16 }, 164 + [SCTFDR] = sci_reg_invalid, 165 + [SCRFDR] = sci_reg_invalid, 166 + [SCSPTR] = sci_reg_invalid, 167 + [SCLSR] = sci_reg_invalid, 168 + }, 169 + 170 + /* 171 + * Common SCIFA definitions. 172 + */ 173 + [SCIx_SCIFA_REGTYPE] = { 174 + [SCSMR] = { 0x00, 16 }, 175 + [SCBRR] = { 0x04, 8 }, 176 + [SCSCR] = { 0x08, 16 }, 177 + [SCxTDR] = { 0x20, 8 }, 178 + [SCxSR] = { 0x14, 16 }, 179 + [SCxRDR] = { 0x24, 8 }, 180 + [SCFCR] = { 0x18, 16 }, 181 + [SCFDR] = { 0x1c, 16 }, 182 + [SCTFDR] = sci_reg_invalid, 183 + [SCRFDR] = sci_reg_invalid, 184 + [SCSPTR] = sci_reg_invalid, 185 + [SCLSR] = sci_reg_invalid, 186 + }, 187 + 188 + /* 189 + * Common SCIFB definitions. 190 + */ 191 + [SCIx_SCIFB_REGTYPE] = { 192 + [SCSMR] = { 0x00, 16 }, 193 + [SCBRR] = { 0x04, 8 }, 194 + [SCSCR] = { 0x08, 16 }, 195 + [SCxTDR] = { 0x40, 8 }, 196 + [SCxSR] = { 0x14, 16 }, 197 + [SCxRDR] = { 0x60, 8 }, 198 + [SCFCR] = { 0x18, 16 }, 199 + [SCFDR] = { 0x1c, 16 }, 200 + [SCTFDR] = sci_reg_invalid, 201 + [SCRFDR] = sci_reg_invalid, 202 + [SCSPTR] = sci_reg_invalid, 203 + [SCLSR] = sci_reg_invalid, 204 + }, 205 + 206 + /* 207 + * Common SH-3 SCIF definitions. 208 + */ 209 + [SCIx_SH3_SCIF_REGTYPE] = { 210 + [SCSMR] = { 0x00, 8 }, 211 + [SCBRR] = { 0x02, 8 }, 212 + [SCSCR] = { 0x04, 8 }, 213 + [SCxTDR] = { 0x06, 8 }, 214 + [SCxSR] = { 0x08, 16 }, 215 + [SCxRDR] = { 0x0a, 8 }, 216 + [SCFCR] = { 0x0c, 8 }, 217 + [SCFDR] = { 0x0e, 16 }, 218 + [SCTFDR] = sci_reg_invalid, 219 + [SCRFDR] = sci_reg_invalid, 220 + [SCSPTR] = sci_reg_invalid, 221 + [SCLSR] = sci_reg_invalid, 222 + }, 223 + 224 + /* 225 + * Common SH-4(A) SCIF(B) definitions. 226 + */ 227 + [SCIx_SH4_SCIF_REGTYPE] = { 228 + [SCSMR] = { 0x00, 16 }, 229 + [SCBRR] = { 0x04, 8 }, 230 + [SCSCR] = { 0x08, 16 }, 231 + [SCxTDR] = { 0x0c, 8 }, 232 + [SCxSR] = { 0x10, 16 }, 233 + [SCxRDR] = { 0x14, 8 }, 234 + [SCFCR] = { 0x18, 16 }, 235 + [SCFDR] = { 0x1c, 16 }, 236 + [SCTFDR] = sci_reg_invalid, 237 + [SCRFDR] = sci_reg_invalid, 238 + [SCSPTR] = { 0x20, 16 }, 239 + [SCLSR] = { 0x24, 16 }, 240 + }, 241 + 242 + /* 243 + * Common SH-4(A) SCIF(B) definitions for ports without an SCSPTR 244 + * register. 245 + */ 246 + [SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE] = { 247 + [SCSMR] = { 0x00, 16 }, 248 + [SCBRR] = { 0x04, 8 }, 249 + [SCSCR] = { 0x08, 16 }, 250 + [SCxTDR] = { 0x0c, 8 }, 251 + [SCxSR] = { 0x10, 16 }, 252 + [SCxRDR] = { 0x14, 8 }, 253 + [SCFCR] = { 0x18, 16 }, 254 + [SCFDR] = { 0x1c, 16 }, 255 + [SCTFDR] = sci_reg_invalid, 256 + [SCRFDR] = sci_reg_invalid, 257 + [SCSPTR] = sci_reg_invalid, 258 + [SCLSR] = { 0x24, 16 }, 259 + }, 260 + 261 + /* 262 + * Common SH-4(A) SCIF(B) definitions for ports with FIFO data 263 + * count registers. 264 + */ 265 + [SCIx_SH4_SCIF_FIFODATA_REGTYPE] = { 266 + [SCSMR] = { 0x00, 16 }, 267 + [SCBRR] = { 0x04, 8 }, 268 + [SCSCR] = { 0x08, 16 }, 269 + [SCxTDR] = { 0x0c, 8 }, 270 + [SCxSR] = { 0x10, 16 }, 271 + [SCxRDR] = { 0x14, 8 }, 272 + [SCFCR] = { 0x18, 16 }, 273 + [SCFDR] = { 0x1c, 16 }, 274 + [SCTFDR] = { 0x1c, 16 }, /* aliased to SCFDR */ 275 + [SCRFDR] = { 0x20, 16 }, 276 + [SCSPTR] = { 0x24, 16 }, 277 + [SCLSR] = { 0x28, 16 }, 278 + }, 279 + 280 + /* 281 + * SH7705-style SCIF(B) ports, lacking both SCSPTR and SCLSR 282 + * registers. 283 + */ 284 + [SCIx_SH7705_SCIF_REGTYPE] = { 285 + [SCSMR] = { 0x00, 16 }, 286 + [SCBRR] = { 0x04, 8 }, 287 + [SCSCR] = { 0x08, 16 }, 288 + [SCxTDR] = { 0x20, 8 }, 289 + [SCxSR] = { 0x14, 16 }, 290 + [SCxRDR] = { 0x24, 8 }, 291 + [SCFCR] = { 0x18, 16 }, 292 + [SCFDR] = { 0x1c, 16 }, 293 + [SCTFDR] = sci_reg_invalid, 294 + [SCRFDR] = sci_reg_invalid, 295 + [SCSPTR] = sci_reg_invalid, 296 + [SCLSR] = sci_reg_invalid, 297 + }, 298 + }; 299 + 300 + /* 301 + * The "offset" here is rather misleading, in that it refers to an enum 302 + * value relative to the port mapping rather than the fixed offset 303 + * itself, which needs to be manually retrieved from the platform's 304 + * register map for the given port. 305 + */ 306 + static unsigned int sci_serial_in(struct uart_port *p, int offset) 307 + { 308 + struct sci_port *s = to_sci_port(p); 309 + struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset; 310 + 311 + if (reg->size == 8) 312 + return ioread8(p->membase + (reg->offset << p->regshift)); 313 + else if (reg->size == 16) 314 + return ioread16(p->membase + (reg->offset << p->regshift)); 315 + else 316 + WARN(1, "Invalid register access\n"); 317 + 318 + return 0; 319 + } 320 + 321 + static void sci_serial_out(struct uart_port *p, int offset, int value) 322 + { 323 + struct sci_port *s = to_sci_port(p); 324 + struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset; 325 + 326 + if (reg->size == 8) 327 + iowrite8(value, p->membase + (reg->offset << p->regshift)); 328 + else if (reg->size == 16) 329 + iowrite16(value, p->membase + (reg->offset << p->regshift)); 330 + else 331 + WARN(1, "Invalid register access\n"); 332 + } 333 + 334 + #define sci_in(up, offset) (up->serial_in(up, offset)) 335 + #define sci_out(up, offset, value) (up->serial_out(up, offset, value)) 336 + 337 + static int sci_probe_regmap(struct plat_sci_port *cfg) 338 + { 339 + switch (cfg->type) { 340 + case PORT_SCI: 341 + cfg->regtype = SCIx_SCI_REGTYPE; 342 + break; 343 + case PORT_IRDA: 344 + cfg->regtype = SCIx_IRDA_REGTYPE; 345 + break; 346 + case PORT_SCIFA: 347 + cfg->regtype = SCIx_SCIFA_REGTYPE; 348 + break; 349 + case PORT_SCIFB: 350 + cfg->regtype = SCIx_SCIFB_REGTYPE; 351 + break; 352 + case PORT_SCIF: 353 + /* 354 + * The SH-4 is a bit of a misnomer here, although that's 355 + * where this particular port layout originated. This 356 + * configuration (or some slight variation thereof) 357 + * remains the dominant model for all SCIFs. 358 + */ 359 + cfg->regtype = SCIx_SH4_SCIF_REGTYPE; 360 + break; 361 + default: 362 + printk(KERN_ERR "Can't probe register map for given port\n"); 363 + return -EINVAL; 364 + } 365 + 366 + return 0; 367 + } 368 + 120 369 #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) 121 370 122 371 #ifdef CONFIG_CONSOLE_POLL ··· 409 160 } 410 161 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ 411 162 412 - #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) 413 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 163 + static void sci_init_pins(struct uart_port *port, unsigned int cflag) 414 164 { 415 - if (port->mapbase == 0xA4400000) { 416 - __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); 417 - __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); 418 - } else if (port->mapbase == 0xA4410000) 419 - __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); 420 - } 421 - #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) 422 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 423 - { 424 - unsigned short data; 165 + struct sci_port *s = to_sci_port(port); 166 + struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; 425 167 426 - if (cflag & CRTSCTS) { 427 - /* enable RTS/CTS */ 428 - if (port->mapbase == 0xa4430000) { /* SCIF0 */ 429 - /* Clear PTCR bit 9-2; enable all scif pins but sck */ 430 - data = __raw_readw(PORT_PTCR); 431 - __raw_writew((data & 0xfc03), PORT_PTCR); 432 - } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 433 - /* Clear PVCR bit 9-2 */ 434 - data = __raw_readw(PORT_PVCR); 435 - __raw_writew((data & 0xfc03), PORT_PVCR); 436 - } 437 - } else { 438 - if (port->mapbase == 0xa4430000) { /* SCIF0 */ 439 - /* Clear PTCR bit 5-2; enable only tx and rx */ 440 - data = __raw_readw(PORT_PTCR); 441 - __raw_writew((data & 0xffc3), PORT_PTCR); 442 - } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ 443 - /* Clear PVCR bit 5-2 */ 444 - data = __raw_readw(PORT_PVCR); 445 - __raw_writew((data & 0xffc3), PORT_PVCR); 446 - } 168 + /* 169 + * Use port-specific handler if provided. 170 + */ 171 + if (s->cfg->ops && s->cfg->ops->init_pins) { 172 + s->cfg->ops->init_pins(port, cflag); 173 + return; 447 174 } 448 - } 449 - #elif defined(CONFIG_CPU_SH3) 450 - /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ 451 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 452 - { 453 - unsigned short data; 454 175 455 - /* We need to set SCPCR to enable RTS/CTS */ 456 - data = __raw_readw(SCPCR); 457 - /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ 458 - __raw_writew(data & 0x0fcf, SCPCR); 176 + /* 177 + * For the generic path SCSPTR is necessary. Bail out if that's 178 + * unavailable, too. 179 + */ 180 + if (!reg->size) 181 + return; 459 182 460 - if (!(cflag & CRTSCTS)) { 461 - /* We need to set SCPCR to enable RTS/CTS */ 462 - data = __raw_readw(SCPCR); 463 - /* Clear out SCP7MD1,0, SCP4MD1,0, 464 - Set SCP6MD1,0 = {01} (output) */ 465 - __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); 466 - 467 - data = __raw_readb(SCPDR); 468 - /* Set /RTS2 (bit6) = 0 */ 469 - __raw_writeb(data & 0xbf, SCPDR); 470 - } 471 - } 472 - #elif defined(CONFIG_CPU_SUBTYPE_SH7722) 473 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 474 - { 475 - unsigned short data; 476 - 477 - if (port->mapbase == 0xffe00000) { 478 - data = __raw_readw(PSCR); 479 - data &= ~0x03cf; 480 - if (!(cflag & CRTSCTS)) 481 - data |= 0x0340; 482 - 483 - __raw_writew(data, PSCR); 484 - } 485 - } 486 - #elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \ 487 - defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 488 - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 489 - defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 490 - defined(CONFIG_CPU_SUBTYPE_SH7786) || \ 491 - defined(CONFIG_CPU_SUBTYPE_SHX3) 492 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 493 - { 494 183 if (!(cflag & CRTSCTS)) 495 - __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ 184 + sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */ 496 185 } 497 - #elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A) 498 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 499 - { 500 - if (!(cflag & CRTSCTS)) 501 - __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ 502 - } 503 - #else 504 - static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) 505 - { 506 - /* Nothing to do */ 507 - } 508 - #endif 509 186 510 187 #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 511 188 defined(CONFIG_CPU_SUBTYPE_SH7780) || \ ··· 1927 1752 break; 1928 1753 } 1929 1754 1755 + if (p->regtype == SCIx_PROBE_REGTYPE) 1756 + BUG_ON(sci_probe_regmap(p) != 0); 1757 + 1930 1758 if (dev) { 1931 1759 sci_port->iclk = clk_get(&dev->dev, "sci_ick"); 1932 1760 if (IS_ERR(sci_port->iclk)) { ··· 1990 1812 port->mapbase = p->mapbase; 1991 1813 port->type = p->type; 1992 1814 port->flags = p->flags; 1815 + port->regshift = p->regshift; 1993 1816 1994 1817 /* 1995 - * The UART port needs an IRQ value, so we peg this to the TX IRQ 1818 + * The UART port needs an IRQ value, so we peg this to the RX IRQ 1996 1819 * for the multi-IRQ ports, which is where we are primarily 1997 1820 * concerned with the shutdown path synchronization. 1998 1821 * 1999 1822 * For the muxed case there's nothing more to do. 2000 1823 */ 2001 1824 port->irq = p->irqs[SCIx_RXI_IRQ]; 1825 + 1826 + port->serial_in = sci_serial_in; 1827 + port->serial_out = sci_serial_out; 2002 1828 2003 1829 if (p->dma_dev) 2004 1830 dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n",
-222
drivers/tty/serial/sh-sci.h
··· 3 3 #include <linux/gpio.h> 4 4 5 5 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 6 - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ 7 - defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 8 - defined(CONFIG_CPU_SUBTYPE_SH7708) || \ 9 - defined(CONFIG_CPU_SUBTYPE_SH7709) 10 - # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */ 11 - # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ 12 - #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 13 - defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 14 - defined(CONFIG_ARCH_SH73A0) || \ 15 - defined(CONFIG_ARCH_SH7367) || \ 16 - defined(CONFIG_ARCH_SH7377) || \ 17 - defined(CONFIG_ARCH_SH7372) 18 - # define PORT_PTCR 0xA405011EUL 19 - # define PORT_PVCR 0xA4050122UL 20 - #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ 21 - defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ 22 - defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ 23 - defined(CONFIG_CPU_SUBTYPE_SH7091) || \ 24 - defined(CONFIG_CPU_SUBTYPE_SH7751) || \ 25 - defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ 26 - defined(CONFIG_CPU_SUBTYPE_SH4_202) 27 - # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ 28 - #elif defined(CONFIG_CPU_SUBTYPE_SH7760) 29 - # define SCSPTR0 0xfe600024 /* 16 bit SCIF */ 30 - # define SCSPTR2 0xfe620024 /* 16 bit SCIF */ 31 - #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) 32 - # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ 33 - # define PACR 0xa4050100 34 - # define PBCR 0xa4050102 35 - #elif defined(CONFIG_CPU_SUBTYPE_SH7343) 36 - # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ 37 - #elif defined(CONFIG_CPU_SUBTYPE_SH7722) 38 - # define PWDR 0xA4050166 39 - # define PSCR 0xA405011E 40 - #elif defined(CONFIG_CPU_SUBTYPE_SH7366) 41 - # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ 42 - # define SCSPTR0 SCPDR0 43 - #elif defined(CONFIG_CPU_SUBTYPE_SH7723) 44 - # define SCSPTR0 0xa4050160 45 - #elif defined(CONFIG_CPU_SUBTYPE_SH7757) 46 - # define SCSPTR0 0xfe4b0020 47 - #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 48 - defined(CONFIG_CPU_SUBTYPE_SH7780) 49 - # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ 50 - #elif defined(CONFIG_CPU_SUBTYPE_SH7770) 51 - # define SCSPTR0 0xff923020 /* 16 bit SCIF */ 52 - #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 53 - defined(CONFIG_CPU_SUBTYPE_SH7786) 54 - # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ 55 - #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ 56 - defined(CONFIG_CPU_SUBTYPE_SH7203) || \ 57 - defined(CONFIG_CPU_SUBTYPE_SH7206) || \ 58 - defined(CONFIG_CPU_SUBTYPE_SH7263) 59 - # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ 60 - #elif defined(CONFIG_CPU_SUBTYPE_SH7619) 61 - # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ 62 - #elif defined(CONFIG_CPU_SUBTYPE_SHX3) 63 - # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ 64 - #else 65 - # error CPU subtype not defined 66 - #endif 67 - 68 - #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 69 6 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 70 7 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 71 8 defined(CONFIG_ARCH_SH73A0) || \ ··· 56 119 57 120 #define SCI_MAJOR 204 58 121 #define SCI_MINOR_START 8 59 - 60 - #define SCI_IN(size, offset) \ 61 - ioread##size(port->membase + (offset)) 62 - 63 - #define SCI_OUT(size, offset, value) \ 64 - iowrite##size(value, port->membase + (offset)) 65 - 66 - #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ 67 - static inline unsigned int sci_##name##_in(struct uart_port *port) \ 68 - { \ 69 - if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ 70 - return SCI_IN(scif_size, scif_offset); \ 71 - } else { /* PORT_SCI or PORT_SCIFA */ \ 72 - return SCI_IN(sci_size, sci_offset); \ 73 - } \ 74 - } \ 75 - static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ 76 - { \ 77 - if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ 78 - SCI_OUT(scif_size, scif_offset, value); \ 79 - } else { /* PORT_SCI or PORT_SCIFA */ \ 80 - SCI_OUT(sci_size, sci_offset, value); \ 81 - } \ 82 - } 83 - 84 - #define CPU_SCIF_FNS(name, scif_offset, scif_size) \ 85 - static inline unsigned int sci_##name##_in(struct uart_port *port) \ 86 - { \ 87 - return SCI_IN(scif_size, scif_offset); \ 88 - } \ 89 - static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ 90 - { \ 91 - SCI_OUT(scif_size, scif_offset, value); \ 92 - } 93 - 94 - #if defined(CONFIG_CPU_SH3) || \ 95 - defined(CONFIG_ARCH_SH73A0) || \ 96 - defined(CONFIG_ARCH_SH7367) || \ 97 - defined(CONFIG_ARCH_SH7377) || \ 98 - defined(CONFIG_ARCH_SH7372) 99 - #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) 100 - #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ 101 - sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 102 - CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) 103 - #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 104 - CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) 105 - #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 106 - defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 107 - defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 108 - defined(CONFIG_ARCH_SH7367) 109 - #define SCIF_FNS(name, scif_offset, scif_size) \ 110 - CPU_SCIF_FNS(name, scif_offset, scif_size) 111 - #elif defined(CONFIG_ARCH_SH7377) || \ 112 - defined(CONFIG_ARCH_SH7372) || \ 113 - defined(CONFIG_ARCH_SH73A0) 114 - #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ 115 - CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) 116 - #define SCIF_FNS(name, scif_offset, scif_size) \ 117 - CPU_SCIF_FNS(name, scif_offset, scif_size) 118 - #else 119 - #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ 120 - sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 121 - CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size) 122 - #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 123 - CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size) 124 - #endif 125 - #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ 126 - defined(CONFIG_CPU_SUBTYPE_SH7724) 127 - #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \ 128 - CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) 129 - #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ 130 - CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) 131 - #else 132 - #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ 133 - sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 134 - CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) 135 - #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ 136 - CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) 137 - #endif 138 - 139 - #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 140 - defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 141 - defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 142 - defined(CONFIG_ARCH_SH7367) 143 - 144 - SCIF_FNS(SCSMR, 0x00, 16) 145 - SCIF_FNS(SCBRR, 0x04, 8) 146 - SCIF_FNS(SCSCR, 0x08, 16) 147 - SCIF_FNS(SCxSR, 0x14, 16) 148 - SCIF_FNS(SCFCR, 0x18, 16) 149 - SCIF_FNS(SCFDR, 0x1c, 16) 150 - SCIF_FNS(SCxTDR, 0x20, 8) 151 - SCIF_FNS(SCxRDR, 0x24, 8) 152 - SCIF_FNS(SCLSR, 0x00, 0) 153 - #elif defined(CONFIG_ARCH_SH7377) || \ 154 - defined(CONFIG_ARCH_SH7372) || \ 155 - defined(CONFIG_ARCH_SH73A0) 156 - SCIF_FNS(SCSMR, 0x00, 16) 157 - SCIF_FNS(SCBRR, 0x04, 8) 158 - SCIF_FNS(SCSCR, 0x08, 16) 159 - SCIF_FNS(SCTDSR, 0x0c, 16) 160 - SCIF_FNS(SCFER, 0x10, 16) 161 - SCIF_FNS(SCxSR, 0x14, 16) 162 - SCIF_FNS(SCFCR, 0x18, 16) 163 - SCIF_FNS(SCFDR, 0x1c, 16) 164 - SCIF_FNS(SCTFDR, 0x38, 16) 165 - SCIF_FNS(SCRFDR, 0x3c, 16) 166 - SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) 167 - SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) 168 - SCIF_FNS(SCLSR, 0x00, 0) 169 - #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ 170 - defined(CONFIG_CPU_SUBTYPE_SH7724) 171 - SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) 172 - SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8) 173 - SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16) 174 - SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8) 175 - SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16) 176 - SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8) 177 - SCIx_FNS(SCSPTR, 0, 0, 0, 0) 178 - SCIF_FNS(SCFCR, 0x18, 16) 179 - SCIF_FNS(SCFDR, 0x1c, 16) 180 - SCIF_FNS(SCLSR, 0x24, 16) 181 - #else 182 - /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 */ 183 - /* name off sz off sz off sz off sz */ 184 - SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16) 185 - SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8) 186 - SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16) 187 - SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8) 188 - SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16) 189 - SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8) 190 - SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) 191 - #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 192 - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 193 - defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 194 - defined(CONFIG_CPU_SUBTYPE_SH7786) 195 - SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) 196 - SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) 197 - SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) 198 - SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) 199 - SCIF_FNS(SCLSR, 0, 0, 0x28, 16) 200 - #elif defined(CONFIG_CPU_SUBTYPE_SH7763) 201 - SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) 202 - SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) 203 - SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) 204 - SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) 205 - SCIF_FNS(SCLSR, 0, 0, 0x28, 16) 206 - #else 207 - SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) 208 - #if defined(CONFIG_CPU_SUBTYPE_SH7722) 209 - SCIF_FNS(SCSPTR, 0, 0, 0, 0) 210 - #else 211 - SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) 212 - #endif 213 - SCIF_FNS(SCLSR, 0, 0, 0x24, 16) 214 - #endif 215 - #endif 216 - #define sci_in(port, reg) sci_##reg##_in(port) 217 - #define sci_out(port, reg, value) sci_##reg##_out(port, value)
+36
include/linux/serial_sci.h
··· 58 58 SCIx_NR_IRQS, 59 59 }; 60 60 61 + enum { 62 + SCIx_PROBE_REGTYPE, 63 + 64 + SCIx_SCI_REGTYPE, 65 + SCIx_IRDA_REGTYPE, 66 + SCIx_SCIFA_REGTYPE, 67 + SCIx_SCIFB_REGTYPE, 68 + SCIx_SH3_SCIF_REGTYPE, 69 + SCIx_SH4_SCIF_REGTYPE, 70 + SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, 71 + SCIx_SH4_SCIF_FIFODATA_REGTYPE, 72 + SCIx_SH7705_SCIF_REGTYPE, 73 + 74 + SCIx_NR_REGTYPES, 75 + }; 76 + 61 77 #define SCIx_IRQ_MUXED(irq) \ 62 78 { \ 63 79 [SCIx_ERI_IRQ] = (irq), \ ··· 82 66 [SCIx_BRI_IRQ] = (irq), \ 83 67 } 84 68 69 + /* 70 + * SCI register subset common for all port types. 71 + * Not all registers will exist on all parts. 72 + */ 73 + enum { 74 + SCSMR, SCBRR, SCSCR, SCxSR, 75 + SCFCR, SCFDR, SCxTDR, SCxRDR, 76 + SCLSR, SCTFDR, SCRFDR, SCSPTR, 77 + 78 + SCIx_NR_REGS, 79 + }; 80 + 85 81 struct device; 82 + 83 + struct plat_sci_port_ops { 84 + void (*init_pins)(struct uart_port *, unsigned int cflag); 85 + }; 86 86 87 87 /* 88 88 * Platform device specific platform_data struct ··· 119 87 unsigned int error_mask; 120 88 121 89 int port_reg; 90 + unsigned char regshift; 91 + unsigned char regtype; 92 + 93 + struct plat_sci_port_ops *ops; 122 94 123 95 struct device *dma_dev; 124 96