mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 12:49:08 +00:00
serial: sh-sci: fix handling of SCIFB sh-mobile ports
SCIFB ports have a slightly different register layout and a different FIFO size from SCIFA ports, in DMA mode they have to be treated just like SCIFA. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
75b93489b4
commit
d1d4b10cda
@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port)
|
|||||||
return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
|
return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(CONFIG_ARCH_SH7372)
|
||||||
|
static int scif_txfill(struct uart_port *port)
|
||||||
|
{
|
||||||
|
if (port->type == PORT_SCIFA)
|
||||||
|
return sci_in(port, SCFDR) >> 8;
|
||||||
|
else
|
||||||
|
return sci_in(port, SCTFDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scif_txroom(struct uart_port *port)
|
||||||
|
{
|
||||||
|
return port->fifosize - scif_txfill(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scif_rxfill(struct uart_port *port)
|
||||||
|
{
|
||||||
|
if (port->type == PORT_SCIFA)
|
||||||
|
return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
|
||||||
|
else
|
||||||
|
return sci_in(port, SCRFDR);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static int scif_txfill(struct uart_port *port)
|
static int scif_txfill(struct uart_port *port)
|
||||||
{
|
{
|
||||||
@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
|
|||||||
u16 ssr = sci_in(port, SCxSR);
|
u16 ssr = sci_in(port, SCxSR);
|
||||||
|
|
||||||
/* Disable future Rx interrupts */
|
/* Disable future Rx interrupts */
|
||||||
if (port->type == PORT_SCIFA) {
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||||
disable_irq_nosync(irq);
|
disable_irq_nosync(irq);
|
||||||
scr |= 0x4000;
|
scr |= 0x4000;
|
||||||
} else {
|
} else {
|
||||||
@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg)
|
|||||||
|
|
||||||
if (!uart_circ_empty(xmit)) {
|
if (!uart_circ_empty(xmit)) {
|
||||||
schedule_work(&s->work_tx);
|
schedule_work(&s->work_tx);
|
||||||
} else if (port->type == PORT_SCIFA) {
|
} else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||||
u16 ctrl = sci_in(port, SCSCR);
|
u16 ctrl = sci_in(port, SCSCR);
|
||||||
sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
|
sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
|
||||||
}
|
}
|
||||||
@ -1183,7 +1204,7 @@ static void sci_start_tx(struct uart_port *port)
|
|||||||
unsigned short ctrl;
|
unsigned short ctrl;
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
||||||
if (port->type == PORT_SCIFA) {
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||||
u16 new, scr = sci_in(port, SCSCR);
|
u16 new, scr = sci_in(port, SCSCR);
|
||||||
if (s->chan_tx)
|
if (s->chan_tx)
|
||||||
new = scr | 0x8000;
|
new = scr | 0x8000;
|
||||||
@ -1196,7 +1217,7 @@ static void sci_start_tx(struct uart_port *port)
|
|||||||
s->cookie_tx < 0)
|
s->cookie_tx < 0)
|
||||||
schedule_work(&s->work_tx);
|
schedule_work(&s->work_tx);
|
||||||
#endif
|
#endif
|
||||||
if (!s->chan_tx || port->type == PORT_SCIFA) {
|
if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||||
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
|
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
|
||||||
ctrl = sci_in(port, SCSCR);
|
ctrl = sci_in(port, SCSCR);
|
||||||
sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
|
sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
|
||||||
@ -1209,7 +1230,7 @@ static void sci_stop_tx(struct uart_port *port)
|
|||||||
|
|
||||||
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
|
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
|
||||||
ctrl = sci_in(port, SCSCR);
|
ctrl = sci_in(port, SCSCR);
|
||||||
if (port->type == PORT_SCIFA)
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
|
||||||
ctrl &= ~0x8000;
|
ctrl &= ~0x8000;
|
||||||
ctrl &= ~SCI_CTRL_FLAGS_TIE;
|
ctrl &= ~SCI_CTRL_FLAGS_TIE;
|
||||||
sci_out(port, SCSCR, ctrl);
|
sci_out(port, SCSCR, ctrl);
|
||||||
@ -1221,7 +1242,7 @@ static void sci_start_rx(struct uart_port *port)
|
|||||||
|
|
||||||
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
|
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
|
||||||
ctrl |= sci_in(port, SCSCR);
|
ctrl |= sci_in(port, SCSCR);
|
||||||
if (port->type == PORT_SCIFA)
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
|
||||||
ctrl &= ~0x4000;
|
ctrl &= ~0x4000;
|
||||||
sci_out(port, SCSCR, ctrl);
|
sci_out(port, SCSCR, ctrl);
|
||||||
}
|
}
|
||||||
@ -1232,7 +1253,7 @@ static void sci_stop_rx(struct uart_port *port)
|
|||||||
|
|
||||||
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
|
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
|
||||||
ctrl = sci_in(port, SCSCR);
|
ctrl = sci_in(port, SCSCR);
|
||||||
if (port->type == PORT_SCIFA)
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
|
||||||
ctrl &= ~0x4000;
|
ctrl &= ~0x4000;
|
||||||
ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
|
ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
|
||||||
sci_out(port, SCSCR, ctrl);
|
sci_out(port, SCSCR, ctrl);
|
||||||
@ -1270,7 +1291,7 @@ static void rx_timer_fn(unsigned long arg)
|
|||||||
struct uart_port *port = &s->port;
|
struct uart_port *port = &s->port;
|
||||||
u16 scr = sci_in(port, SCSCR);
|
u16 scr = sci_in(port, SCSCR);
|
||||||
|
|
||||||
if (port->type == PORT_SCIFA) {
|
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||||
scr &= ~0x4000;
|
scr &= ~0x4000;
|
||||||
enable_irq(s->irqs[1]);
|
enable_irq(s->irqs[1]);
|
||||||
}
|
}
|
||||||
@ -1523,6 +1544,8 @@ static const char *sci_type(struct uart_port *port)
|
|||||||
return "scif";
|
return "scif";
|
||||||
case PORT_SCIFA:
|
case PORT_SCIFA:
|
||||||
return "scifa";
|
return "scifa";
|
||||||
|
case PORT_SCIFB:
|
||||||
|
return "scifb";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1611,6 +1634,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
|
|||||||
port->line = index;
|
port->line = index;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
|
case PORT_SCIFB:
|
||||||
|
port->fifosize = 256;
|
||||||
|
break;
|
||||||
case PORT_SCIFA:
|
case PORT_SCIFA:
|
||||||
port->fifosize = 64;
|
port->fifosize = 64;
|
||||||
break;
|
break;
|
||||||
|
@ -322,7 +322,7 @@
|
|||||||
#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
|
#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
|
||||||
static inline unsigned int sci_##name##_in(struct uart_port *port) \
|
static inline unsigned int sci_##name##_in(struct uart_port *port) \
|
||||||
{ \
|
{ \
|
||||||
if (port->type == PORT_SCIF) { \
|
if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
|
||||||
SCI_IN(scif_size, scif_offset) \
|
SCI_IN(scif_size, scif_offset) \
|
||||||
} else { /* PORT_SCI or PORT_SCIFA */ \
|
} else { /* PORT_SCI or PORT_SCIFA */ \
|
||||||
SCI_IN(sci_size, sci_offset); \
|
SCI_IN(sci_size, sci_offset); \
|
||||||
@ -330,7 +330,7 @@
|
|||||||
} \
|
} \
|
||||||
static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
|
static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
|
||||||
{ \
|
{ \
|
||||||
if (port->type == PORT_SCIF) { \
|
if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
|
||||||
SCI_OUT(scif_size, scif_offset, value) \
|
SCI_OUT(scif_size, scif_offset, value) \
|
||||||
} else { /* PORT_SCI or PORT_SCIFA */ \
|
} else { /* PORT_SCI or PORT_SCIFA */ \
|
||||||
SCI_OUT(sci_size, sci_offset, value); \
|
SCI_OUT(sci_size, sci_offset, value); \
|
||||||
@ -384,8 +384,12 @@
|
|||||||
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
||||||
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
|
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
|
||||||
defined(CONFIG_ARCH_SH7367) || \
|
defined(CONFIG_ARCH_SH7367) || \
|
||||||
defined(CONFIG_ARCH_SH7377) || \
|
defined(CONFIG_ARCH_SH7377)
|
||||||
defined(CONFIG_ARCH_SH7372)
|
#define SCIF_FNS(name, scif_offset, scif_size) \
|
||||||
|
CPU_SCIF_FNS(name, scif_offset, scif_size)
|
||||||
|
#elif defined(CONFIG_ARCH_SH7372)
|
||||||
|
#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) \
|
#define SCIF_FNS(name, scif_offset, scif_size) \
|
||||||
CPU_SCIF_FNS(name, scif_offset, scif_size)
|
CPU_SCIF_FNS(name, scif_offset, scif_size)
|
||||||
#else
|
#else
|
||||||
@ -422,8 +426,7 @@
|
|||||||
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
||||||
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
|
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
|
||||||
defined(CONFIG_ARCH_SH7367) || \
|
defined(CONFIG_ARCH_SH7367) || \
|
||||||
defined(CONFIG_ARCH_SH7377) || \
|
defined(CONFIG_ARCH_SH7377)
|
||||||
defined(CONFIG_ARCH_SH7372)
|
|
||||||
|
|
||||||
SCIF_FNS(SCSMR, 0x00, 16)
|
SCIF_FNS(SCSMR, 0x00, 16)
|
||||||
SCIF_FNS(SCBRR, 0x04, 8)
|
SCIF_FNS(SCBRR, 0x04, 8)
|
||||||
@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16)
|
|||||||
SCIF_FNS(SCxTDR, 0x20, 8)
|
SCIF_FNS(SCxTDR, 0x20, 8)
|
||||||
SCIF_FNS(SCxRDR, 0x24, 8)
|
SCIF_FNS(SCxRDR, 0x24, 8)
|
||||||
SCIF_FNS(SCLSR, 0x00, 0)
|
SCIF_FNS(SCLSR, 0x00, 0)
|
||||||
|
#elif defined(CONFIG_ARCH_SH7372)
|
||||||
|
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) ||\
|
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
|
||||||
defined(CONFIG_CPU_SUBTYPE_SH7724)
|
defined(CONFIG_CPU_SUBTYPE_SH7724)
|
||||||
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
|
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
|
||||||
|
Loading…
Reference in New Issue
Block a user