diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-12-16 06:07:27 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-12-22 04:44:43 -0500 |
commit | d5701647f1aaaea5da20023976d86af79ab84707 (patch) | |
tree | bbab402d7c58fabd874b390736515723bce69a96 /drivers/serial/sh-sci.c | |
parent | d830fa4584a4015989b9b396a80779f28f277baa (diff) |
serial: sh-sci: Generalize port pin initialization.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 145 |
1 files changed, 43 insertions, 102 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index b0feea493985..cf663b718697 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -64,10 +64,6 @@ struct sci_port { | |||
64 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ | 64 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ |
65 | unsigned int irqs[SCIx_NR_IRQS]; | 65 | unsigned int irqs[SCIx_NR_IRQS]; |
66 | 66 | ||
67 | /* Port pin configuration */ | ||
68 | void (*init_pins)(struct uart_port *port, | ||
69 | unsigned int cflag); | ||
70 | |||
71 | /* Port enable callback */ | 67 | /* Port enable callback */ |
72 | void (*enable)(struct uart_port *port); | 68 | void (*enable)(struct uart_port *port); |
73 | 69 | ||
@@ -172,7 +168,7 @@ static inline void h8300_sci_disable(struct uart_port *port) | |||
172 | #endif | 168 | #endif |
173 | 169 | ||
174 | #if defined(__H8300H__) || defined(__H8300S__) | 170 | #if defined(__H8300H__) || defined(__H8300S__) |
175 | static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) | 171 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
176 | { | 172 | { |
177 | int ch = (port->mapbase - SMR0) >> 3; | 173 | int ch = (port->mapbase - SMR0) >> 3; |
178 | 174 | ||
@@ -187,140 +183,99 @@ static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) | |||
187 | /* tx mark output*/ | 183 | /* tx mark output*/ |
188 | H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; | 184 | H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; |
189 | } | 185 | } |
190 | #else | 186 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
191 | #define sci_init_pins_sci NULL | 187 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
192 | #endif | ||
193 | |||
194 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
195 | static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) | ||
196 | { | 188 | { |
197 | unsigned int fcr_val = 0; | 189 | if (port->mapbase == 0xA4400000) { |
198 | 190 | __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); | |
199 | if (cflag & CRTSCTS) | 191 | __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); |
200 | fcr_val |= SCFCR_MCE; | 192 | } else if (port->mapbase == 0xA4410000) |
201 | 193 | __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); | |
202 | sci_out(port, SCFCR, fcr_val); | ||
203 | } | ||
204 | #else | ||
205 | #define sci_init_pins_irda NULL | ||
206 | #endif | ||
207 | |||
208 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
209 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
210 | { | ||
211 | unsigned int fcr_val = 0; | ||
212 | |||
213 | set_sh771x_scif_pfc(port); | ||
214 | if (cflag & CRTSCTS) | ||
215 | fcr_val |= SCFCR_MCE; | ||
216 | sci_out(port, SCFCR, fcr_val); | ||
217 | } | 194 | } |
218 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) | 195 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) |
219 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 196 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
220 | { | 197 | { |
221 | unsigned int fcr_val = 0; | ||
222 | unsigned short data; | 198 | unsigned short data; |
223 | 199 | ||
224 | if (cflag & CRTSCTS) { | 200 | if (cflag & CRTSCTS) { |
225 | /* enable RTS/CTS */ | 201 | /* enable RTS/CTS */ |
226 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | 202 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ |
227 | /* Clear PTCR bit 9-2; enable all scif pins but sck */ | 203 | /* Clear PTCR bit 9-2; enable all scif pins but sck */ |
228 | data = ctrl_inw(PORT_PTCR); | 204 | data = __raw_readw(PORT_PTCR); |
229 | ctrl_outw((data & 0xfc03), PORT_PTCR); | 205 | __raw_writew((data & 0xfc03), PORT_PTCR); |
230 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | 206 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ |
231 | /* Clear PVCR bit 9-2 */ | 207 | /* Clear PVCR bit 9-2 */ |
232 | data = ctrl_inw(PORT_PVCR); | 208 | data = __raw_readw(PORT_PVCR); |
233 | ctrl_outw((data & 0xfc03), PORT_PVCR); | 209 | __raw_writew((data & 0xfc03), PORT_PVCR); |
234 | } | 210 | } |
235 | fcr_val |= SCFCR_MCE; | ||
236 | } else { | 211 | } else { |
237 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | 212 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ |
238 | /* Clear PTCR bit 5-2; enable only tx and rx */ | 213 | /* Clear PTCR bit 5-2; enable only tx and rx */ |
239 | data = ctrl_inw(PORT_PTCR); | 214 | data = __raw_readw(PORT_PTCR); |
240 | ctrl_outw((data & 0xffc3), PORT_PTCR); | 215 | __raw_writew((data & 0xffc3), PORT_PTCR); |
241 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | 216 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ |
242 | /* Clear PVCR bit 5-2 */ | 217 | /* Clear PVCR bit 5-2 */ |
243 | data = ctrl_inw(PORT_PVCR); | 218 | data = __raw_readw(PORT_PVCR); |
244 | ctrl_outw((data & 0xffc3), PORT_PVCR); | 219 | __raw_writew((data & 0xffc3), PORT_PVCR); |
245 | } | 220 | } |
246 | } | 221 | } |
247 | sci_out(port, SCFCR, fcr_val); | ||
248 | } | 222 | } |
249 | #elif defined(CONFIG_CPU_SH3) | 223 | #elif defined(CONFIG_CPU_SH3) |
250 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ | 224 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ |
251 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 225 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
252 | { | 226 | { |
253 | unsigned int fcr_val = 0; | ||
254 | unsigned short data; | 227 | unsigned short data; |
255 | 228 | ||
256 | /* We need to set SCPCR to enable RTS/CTS */ | 229 | /* We need to set SCPCR to enable RTS/CTS */ |
257 | data = ctrl_inw(SCPCR); | 230 | data = __raw_readw(SCPCR); |
258 | /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ | 231 | /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ |
259 | ctrl_outw(data & 0x0fcf, SCPCR); | 232 | __raw_writew(data & 0x0fcf, SCPCR); |
260 | 233 | ||
261 | if (cflag & CRTSCTS) | 234 | if (!(cflag & CRTSCTS)) { |
262 | fcr_val |= SCFCR_MCE; | ||
263 | else { | ||
264 | /* We need to set SCPCR to enable RTS/CTS */ | 235 | /* We need to set SCPCR to enable RTS/CTS */ |
265 | data = ctrl_inw(SCPCR); | 236 | data = __raw_readw(SCPCR); |
266 | /* Clear out SCP7MD1,0, SCP4MD1,0, | 237 | /* Clear out SCP7MD1,0, SCP4MD1,0, |
267 | Set SCP6MD1,0 = {01} (output) */ | 238 | Set SCP6MD1,0 = {01} (output) */ |
268 | ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); | 239 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
269 | 240 | ||
270 | data = ctrl_inb(SCPDR); | 241 | data = ctrl_inb(SCPDR); |
271 | /* Set /RTS2 (bit6) = 0 */ | 242 | /* Set /RTS2 (bit6) = 0 */ |
272 | ctrl_outb(data & 0xbf, SCPDR); | 243 | ctrl_outb(data & 0xbf, SCPDR); |
273 | } | 244 | } |
274 | |||
275 | sci_out(port, SCFCR, fcr_val); | ||
276 | } | 245 | } |
277 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 246 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
278 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 247 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
279 | { | 248 | { |
280 | unsigned int fcr_val = 0; | ||
281 | unsigned short data; | 249 | unsigned short data; |
282 | 250 | ||
283 | if (port->mapbase == 0xffe00000) { | 251 | if (port->mapbase == 0xffe00000) { |
284 | data = ctrl_inw(PSCR); | 252 | data = __raw_readw(PSCR); |
285 | data &= ~0x03cf; | 253 | data &= ~0x03cf; |
286 | if (cflag & CRTSCTS) | 254 | if (!(cflag & CRTSCTS)) |
287 | fcr_val |= SCFCR_MCE; | ||
288 | else | ||
289 | data |= 0x0340; | 255 | data |= 0x0340; |
290 | 256 | ||
291 | ctrl_outw(data, PSCR); | 257 | __raw_writew(data, PSCR); |
292 | } | 258 | } |
293 | /* SCIF1 and SCIF2 should be setup by board code */ | ||
294 | |||
295 | sci_out(port, SCFCR, fcr_val); | ||
296 | } | ||
297 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
298 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
299 | { | ||
300 | /* Nothing to do here.. */ | ||
301 | sci_out(port, SCFCR, 0); | ||
302 | } | 259 | } |
303 | #else | ||
304 | /* For SH7750 */ | ||
305 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
306 | { | ||
307 | unsigned int fcr_val = 0; | ||
308 | |||
309 | if (cflag & CRTSCTS) { | ||
310 | fcr_val |= SCFCR_MCE; | ||
311 | } else { | ||
312 | #if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366) | ||
313 | /* Nothing */ | ||
314 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 260 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
315 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 261 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
316 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 262 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
317 | defined(CONFIG_CPU_SUBTYPE_SHX3) | 263 | defined(CONFIG_CPU_SUBTYPE_SHX3) |
318 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ | 264 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
265 | { | ||
266 | if (!(cflag & CRTSCTS)) | ||
267 | __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ | ||
268 | } | ||
269 | #elif defined(CONFIG_CPU_SH4) | ||
270 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
271 | { | ||
272 | if (!(cflag & CRTSCTS)) | ||
273 | __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ | ||
274 | } | ||
319 | #else | 275 | #else |
320 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ | 276 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
321 | #endif | 277 | { |
322 | } | 278 | /* Nothing to do */ |
323 | sci_out(port, SCFCR, fcr_val); | ||
324 | } | 279 | } |
325 | #endif | 280 | #endif |
326 | 281 | ||
@@ -941,7 +896,6 @@ static void sci_shutdown(struct uart_port *port) | |||
941 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 896 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
942 | struct ktermios *old) | 897 | struct ktermios *old) |
943 | { | 898 | { |
944 | struct sci_port *s = &sci_ports[port->line]; | ||
945 | unsigned int status, baud, smr_val; | 899 | unsigned int status, baud, smr_val; |
946 | int t = -1; | 900 | int t = -1; |
947 | 901 | ||
@@ -983,8 +937,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
983 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ | 937 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ |
984 | } | 938 | } |
985 | 939 | ||
986 | if (likely(s->init_pins)) | 940 | sci_init_pins(port, termios->c_cflag); |
987 | s->init_pins(port, termios->c_cflag); | 941 | sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); |
988 | 942 | ||
989 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 943 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
990 | 944 | ||
@@ -1025,19 +979,6 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
1025 | 979 | ||
1026 | port->type = s->type; | 980 | port->type = s->type; |
1027 | 981 | ||
1028 | switch (port->type) { | ||
1029 | case PORT_SCI: | ||
1030 | s->init_pins = sci_init_pins_sci; | ||
1031 | break; | ||
1032 | case PORT_SCIF: | ||
1033 | case PORT_SCIFA: | ||
1034 | s->init_pins = sci_init_pins_scif; | ||
1035 | break; | ||
1036 | case PORT_IRDA: | ||
1037 | s->init_pins = sci_init_pins_irda; | ||
1038 | break; | ||
1039 | } | ||
1040 | |||
1041 | if (port->flags & UPF_IOREMAP && !port->membase) { | 982 | if (port->flags & UPF_IOREMAP && !port->membase) { |
1042 | #if defined(CONFIG_SUPERH64) | 983 | #if defined(CONFIG_SUPERH64) |
1043 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); | 984 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); |