Loading arch/sh/kernel/cpu/sh4a/setup-sh7757.c +28 −28 Original line number Diff line number Diff line Loading @@ -183,7 +183,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF2_RX, .addr = 0x1f4b0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -197,7 +197,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF3_RX, .addr = 0x1f4c0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -211,7 +211,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF4_RX, .addr = 0x1f4d0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x42, }, Loading @@ -228,7 +228,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC0_RX, .addr = 0x1e500013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -242,7 +242,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC1_RX, .addr = 0x1e510013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -256,7 +256,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC2_RX, .addr = 0x1e520013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xa2, }, Loading @@ -265,12 +265,12 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { .addr = 0x1e530012, .chcr = SM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xab, .mid_rid = 0xa9, }, { .slave_id = SHDMA_SLAVE_RIIC3_RX, .addr = 0x1e530013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xaf, }, Loading @@ -279,14 +279,14 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { .addr = 0x1e540012, .chcr = SM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xc1, .mid_rid = 0xc5, }, { .slave_id = SHDMA_SLAVE_RIIC4_RX, .addr = 0x1e540013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xc2, .mid_rid = 0xc6, }, }; Loading @@ -301,7 +301,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC5_RX, .addr = 0x1e550013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -315,7 +315,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC6_RX, .addr = 0x1e560013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -329,7 +329,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC7_RX, .addr = 0x1e570013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x42, }, Loading @@ -343,7 +343,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC8_RX, .addr = 0x1e580013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x46, }, Loading @@ -357,7 +357,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC9_RX, .addr = 0x1e590013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x52, }, Loading Loading @@ -1089,13 +1089,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups, /* Support for external interrupt pins in IRQ mode */ static struct intc_vect vectors_irq0123[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240), INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0), }; static struct intc_vect vectors_irq4567[] __initdata = { INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340), INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0), }; static struct intc_sense_reg sense_registers[] __initdata = { Loading Loading @@ -1129,14 +1129,14 @@ static struct intc_vect vectors_irl0123[] __initdata = { }; static struct intc_vect vectors_irl4567[] __initdata = { INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20), INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60), INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0), INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0), INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20), INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60), INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0), INTC_VECT(IRL4_HHHL, 0xcc0), INTC_VECT(IRL4_LLLL, 0x200), INTC_VECT(IRL4_LLLH, 0x220), INTC_VECT(IRL4_LLHL, 0x240), INTC_VECT(IRL4_LLHH, 0x260), INTC_VECT(IRL4_LHLL, 0x280), INTC_VECT(IRL4_LHLH, 0x2a0), INTC_VECT(IRL4_LHHL, 0x2c0), INTC_VECT(IRL4_LHHH, 0x2e0), INTC_VECT(IRL4_HLLL, 0x300), INTC_VECT(IRL4_HLLH, 0x320), INTC_VECT(IRL4_HLHL, 0x340), INTC_VECT(IRL4_HLHH, 0x360), INTC_VECT(IRL4_HHLL, 0x380), INTC_VECT(IRL4_HHLH, 0x3a0), INTC_VECT(IRL4_HHHL, 0x3c0), }; static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7757-irl0123", vectors_irl0123, Loading drivers/tty/serial/sh-sci.c +120 −77 Original line number Diff line number Diff line Loading @@ -62,12 +62,6 @@ struct sci_port { /* Platform configuration */ struct plat_sci_port *cfg; /* Port enable callback */ void (*enable)(struct uart_port *port); /* Port disable callback */ void (*disable)(struct uart_port *port); /* Break timer */ struct timer_list break_timer; int break_flag; Loading @@ -77,6 +71,8 @@ struct sci_port { /* Function clock */ struct clk *fclk; char *irqstr[SCIx_NR_IRQS]; struct dma_chan *chan_tx; struct dma_chan *chan_rx; Loading Loading @@ -366,6 +362,29 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) return 0; } static void sci_port_enable(struct sci_port *sci_port) { if (!sci_port->port.dev) return; pm_runtime_get_sync(sci_port->port.dev); clk_enable(sci_port->iclk); sci_port->port.uartclk = clk_get_rate(sci_port->iclk); clk_enable(sci_port->fclk); } static void sci_port_disable(struct sci_port *sci_port) { if (!sci_port->port.dev) return; clk_disable(sci_port->fclk); clk_disable(sci_port->iclk); pm_runtime_put_sync(sci_port->port.dev); } #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) #ifdef CONFIG_CONSOLE_POLL Loading Loading @@ -651,8 +670,7 @@ static void sci_break_timer(unsigned long data) { struct sci_port *port = (struct sci_port *)data; if (port->enable) port->enable(&port->port); sci_port_enable(port); if (sci_rxd_in(&port->port) == 0) { port->break_flag = 1; Loading @@ -664,8 +682,7 @@ static void sci_break_timer(unsigned long data) } else port->break_flag = 0; if (port->disable) port->disable(&port->port); sci_port_disable(port); } static int sci_handle_errors(struct uart_port *port) Loading Loading @@ -939,74 +956,102 @@ static int sci_notifier(struct notifier_block *self, return NOTIFY_OK; } static void sci_clk_enable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); pm_runtime_get_sync(port->dev); static struct sci_irq_desc { const char *desc; irq_handler_t handler; } sci_irq_desc[] = { /* * Split out handlers, the default case. */ [SCIx_ERI_IRQ] = { .desc = "rx err", .handler = sci_er_interrupt, }, clk_enable(sci_port->iclk); sci_port->port.uartclk = clk_get_rate(sci_port->iclk); clk_enable(sci_port->fclk); } [SCIx_RXI_IRQ] = { .desc = "rx full", .handler = sci_rx_interrupt, }, static void sci_clk_disable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); [SCIx_TXI_IRQ] = { .desc = "tx empty", .handler = sci_tx_interrupt, }, clk_disable(sci_port->fclk); clk_disable(sci_port->iclk); [SCIx_BRI_IRQ] = { .desc = "break", .handler = sci_br_interrupt, }, pm_runtime_put_sync(port->dev); } /* * Special muxed handler. */ [SCIx_MUX_IRQ] = { .desc = "mux", .handler = sci_mpxed_interrupt, }, }; static int sci_request_irq(struct sci_port *port) { int i; irqreturn_t (*handlers[4])(int irq, void *ptr) = { sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt, sci_br_interrupt, }; const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", "SCI Transmit Data Empty", "SCI Break" }; struct uart_port *up = &port->port; int i, j, ret = 0; if (port->cfg->irqs[0] == port->cfg->irqs[1]) { if (unlikely(!port->cfg->irqs[0])) return -ENODEV; for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { struct sci_irq_desc *desc; unsigned int irq; if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt, IRQF_DISABLED, "sci", port)) { dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; } } else { for (i = 0; i < ARRAY_SIZE(handlers); i++) { if (unlikely(!port->cfg->irqs[i])) continue; if (SCIx_IRQ_IS_MUXED(port)) { i = SCIx_MUX_IRQ; irq = up->irq; } else irq = port->cfg->irqs[i]; if (request_irq(port->cfg->irqs[i], handlers[i], IRQF_DISABLED, desc[i], port)) { dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); if (!port->irqstr[j]) { dev_err(up->dev, "Failed to allocate %s IRQ string\n", desc->desc); goto out_nomem; } ret = request_irq(irq, desc->handler, up->irqflags, port->irqstr[j], port); if (unlikely(ret)) { dev_err(up->dev, "Can't allocate %s IRQ\n", desc->desc); goto out_noirq; } } return 0; out_noirq: while (--i >= 0) free_irq(port->cfg->irqs[i], port); out_nomem: while (--j >= 0) kfree(port->irqstr[j]); return ret; } static void sci_free_irq(struct sci_port *port) { int i; if (port->cfg->irqs[0] == port->cfg->irqs[1]) free_irq(port->cfg->irqs[0], port); else { for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) { if (!port->cfg->irqs[i]) continue; /* * Intentionally in reverse order so we iterate over the muxed * IRQ first. */ for (i = 0; i < SCIx_NR_IRQS; i++) { free_irq(port->cfg->irqs[i], port); kfree(port->irqstr[i]); if (SCIx_IRQ_IS_MUXED(port)) { /* If there's only one IRQ, we're done. */ return; } } } Loading Loading @@ -1537,8 +1582,7 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); if (s->enable) s->enable(port); sci_port_enable(s); ret = sci_request_irq(s); if (unlikely(ret < 0)) Loading @@ -1564,8 +1608,7 @@ static void sci_shutdown(struct uart_port *port) sci_free_dma(port); sci_free_irq(s); if (s->disable) s->disable(port); sci_port_disable(s); } static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, Loading Loading @@ -1612,8 +1655,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if (likely(baud && port->uartclk)) t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); if (s->enable) s->enable(port); sci_port_enable(s); do { status = sci_in(port, SCxSR); Loading Loading @@ -1683,8 +1725,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port); if (s->disable) s->disable(port); sci_port_disable(s); } static const char *sci_type(struct uart_port *port) Loading Loading @@ -1825,6 +1866,7 @@ static int __devinit sci_init_single(struct platform_device *dev, struct plat_sci_port *p) { struct uart_port *port = &sci_port->port; int ret; port->ops = &sci_uart_ops; port->iotype = UPIO_MEM; Loading @@ -1845,8 +1887,11 @@ 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 (p->regtype == SCIx_PROBE_REGTYPE) { ret = sci_probe_regmap(p); if (unlikely(!ret)) return ret; } if (dev) { sci_port->iclk = clk_get(&dev->dev, "sci_ick"); Loading @@ -1866,8 +1911,6 @@ static int __devinit sci_init_single(struct platform_device *dev, if (IS_ERR(sci_port->fclk)) sci_port->fclk = NULL; sci_port->enable = sci_clk_enable; sci_port->disable = sci_clk_disable; port->dev = &dev->dev; pm_runtime_enable(&dev->dev); Loading Loading @@ -1918,6 +1961,7 @@ static int __devinit sci_init_single(struct platform_device *dev, * For the muxed case there's nothing more to do. */ port->irq = p->irqs[SCIx_RXI_IRQ]; port->irqflags = IRQF_DISABLED; port->serial_in = sci_serial_in; port->serial_out = sci_serial_out; Loading Loading @@ -1946,8 +1990,7 @@ static void serial_console_write(struct console *co, const char *s, struct uart_port *port = &sci_port->port; unsigned short bits; if (sci_port->enable) sci_port->enable(port); sci_port_enable(sci_port); uart_console_write(port, s, count, serial_console_putchar); Loading @@ -1956,8 +1999,7 @@ static void serial_console_write(struct console *co, const char *s, while ((sci_in(port, SCxSR) & bits) != bits) cpu_relax(); if (sci_port->disable) sci_port->disable(port); sci_port_disable(sci_port); } static int __devinit serial_console_setup(struct console *co, char *options) Loading Loading @@ -1989,8 +2031,7 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (unlikely(ret != 0)) return ret; if (sci_port->enable) sci_port->enable(port); sci_port_enable(sci_port); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); Loading Loading @@ -2207,3 +2248,5 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); include/linux/serial_sci.h +7 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ enum { SCIx_TXI_IRQ, SCIx_BRI_IRQ, SCIx_NR_IRQS, SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ }; enum { Loading @@ -82,6 +84,11 @@ enum { [SCIx_BRI_IRQ] = (irq), \ } #define SCIx_IRQ_IS_MUXED(port) \ ((port)->cfg->irqs[SCIx_ERI_IRQ] == \ (port)->cfg->irqs[SCIx_RXI_IRQ]) || \ ((port)->cfg->irqs[SCIx_ERI_IRQ] && \ !(port)->cfg->irqs[SCIx_RXI_IRQ]) /* * SCI register subset common for all port types. * Not all registers will exist on all parts. Loading Loading
arch/sh/kernel/cpu/sh4a/setup-sh7757.c +28 −28 Original line number Diff line number Diff line Loading @@ -183,7 +183,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF2_RX, .addr = 0x1f4b0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -197,7 +197,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF3_RX, .addr = 0x1f4c0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -211,7 +211,7 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF4_RX, .addr = 0x1f4d0014, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x42, }, Loading @@ -228,7 +228,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC0_RX, .addr = 0x1e500013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -242,7 +242,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC1_RX, .addr = 0x1e510013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -256,7 +256,7 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC2_RX, .addr = 0x1e520013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xa2, }, Loading @@ -265,12 +265,12 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { .addr = 0x1e530012, .chcr = SM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xab, .mid_rid = 0xa9, }, { .slave_id = SHDMA_SLAVE_RIIC3_RX, .addr = 0x1e530013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xaf, }, Loading @@ -279,14 +279,14 @@ static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { .addr = 0x1e540012, .chcr = SM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xc1, .mid_rid = 0xc5, }, { .slave_id = SHDMA_SLAVE_RIIC4_RX, .addr = 0x1e540013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0xc2, .mid_rid = 0xc6, }, }; Loading @@ -301,7 +301,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC5_RX, .addr = 0x1e550013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x22, }, Loading @@ -315,7 +315,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC6_RX, .addr = 0x1e560013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x2a, }, Loading @@ -329,7 +329,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC7_RX, .addr = 0x1e570013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x42, }, Loading @@ -343,7 +343,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC8_RX, .addr = 0x1e580013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x46, }, Loading @@ -357,7 +357,7 @@ static const struct sh_dmae_slave_config sh7757_dmae3_slaves[] = { { .slave_id = SHDMA_SLAVE_RIIC9_RX, .addr = 0x1e590013, .chcr = SM_INC | 0x800 | 0x40000000 | .chcr = DM_INC | 0x800 | 0x40000000 | TS_INDEX2VAL(XMIT_SZ_8BIT), .mid_rid = 0x52, }, Loading Loading @@ -1089,13 +1089,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups, /* Support for external interrupt pins in IRQ mode */ static struct intc_vect vectors_irq0123[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240), INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0), }; static struct intc_vect vectors_irq4567[] __initdata = { INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340), INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0), }; static struct intc_sense_reg sense_registers[] __initdata = { Loading Loading @@ -1129,14 +1129,14 @@ static struct intc_vect vectors_irl0123[] __initdata = { }; static struct intc_vect vectors_irl4567[] __initdata = { INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20), INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60), INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0), INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0), INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20), INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60), INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0), INTC_VECT(IRL4_HHHL, 0xcc0), INTC_VECT(IRL4_LLLL, 0x200), INTC_VECT(IRL4_LLLH, 0x220), INTC_VECT(IRL4_LLHL, 0x240), INTC_VECT(IRL4_LLHH, 0x260), INTC_VECT(IRL4_LHLL, 0x280), INTC_VECT(IRL4_LHLH, 0x2a0), INTC_VECT(IRL4_LHHL, 0x2c0), INTC_VECT(IRL4_LHHH, 0x2e0), INTC_VECT(IRL4_HLLL, 0x300), INTC_VECT(IRL4_HLLH, 0x320), INTC_VECT(IRL4_HLHL, 0x340), INTC_VECT(IRL4_HLHH, 0x360), INTC_VECT(IRL4_HHLL, 0x380), INTC_VECT(IRL4_HHLH, 0x3a0), INTC_VECT(IRL4_HHHL, 0x3c0), }; static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7757-irl0123", vectors_irl0123, Loading
drivers/tty/serial/sh-sci.c +120 −77 Original line number Diff line number Diff line Loading @@ -62,12 +62,6 @@ struct sci_port { /* Platform configuration */ struct plat_sci_port *cfg; /* Port enable callback */ void (*enable)(struct uart_port *port); /* Port disable callback */ void (*disable)(struct uart_port *port); /* Break timer */ struct timer_list break_timer; int break_flag; Loading @@ -77,6 +71,8 @@ struct sci_port { /* Function clock */ struct clk *fclk; char *irqstr[SCIx_NR_IRQS]; struct dma_chan *chan_tx; struct dma_chan *chan_rx; Loading Loading @@ -366,6 +362,29 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) return 0; } static void sci_port_enable(struct sci_port *sci_port) { if (!sci_port->port.dev) return; pm_runtime_get_sync(sci_port->port.dev); clk_enable(sci_port->iclk); sci_port->port.uartclk = clk_get_rate(sci_port->iclk); clk_enable(sci_port->fclk); } static void sci_port_disable(struct sci_port *sci_port) { if (!sci_port->port.dev) return; clk_disable(sci_port->fclk); clk_disable(sci_port->iclk); pm_runtime_put_sync(sci_port->port.dev); } #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) #ifdef CONFIG_CONSOLE_POLL Loading Loading @@ -651,8 +670,7 @@ static void sci_break_timer(unsigned long data) { struct sci_port *port = (struct sci_port *)data; if (port->enable) port->enable(&port->port); sci_port_enable(port); if (sci_rxd_in(&port->port) == 0) { port->break_flag = 1; Loading @@ -664,8 +682,7 @@ static void sci_break_timer(unsigned long data) } else port->break_flag = 0; if (port->disable) port->disable(&port->port); sci_port_disable(port); } static int sci_handle_errors(struct uart_port *port) Loading Loading @@ -939,74 +956,102 @@ static int sci_notifier(struct notifier_block *self, return NOTIFY_OK; } static void sci_clk_enable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); pm_runtime_get_sync(port->dev); static struct sci_irq_desc { const char *desc; irq_handler_t handler; } sci_irq_desc[] = { /* * Split out handlers, the default case. */ [SCIx_ERI_IRQ] = { .desc = "rx err", .handler = sci_er_interrupt, }, clk_enable(sci_port->iclk); sci_port->port.uartclk = clk_get_rate(sci_port->iclk); clk_enable(sci_port->fclk); } [SCIx_RXI_IRQ] = { .desc = "rx full", .handler = sci_rx_interrupt, }, static void sci_clk_disable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); [SCIx_TXI_IRQ] = { .desc = "tx empty", .handler = sci_tx_interrupt, }, clk_disable(sci_port->fclk); clk_disable(sci_port->iclk); [SCIx_BRI_IRQ] = { .desc = "break", .handler = sci_br_interrupt, }, pm_runtime_put_sync(port->dev); } /* * Special muxed handler. */ [SCIx_MUX_IRQ] = { .desc = "mux", .handler = sci_mpxed_interrupt, }, }; static int sci_request_irq(struct sci_port *port) { int i; irqreturn_t (*handlers[4])(int irq, void *ptr) = { sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt, sci_br_interrupt, }; const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", "SCI Transmit Data Empty", "SCI Break" }; struct uart_port *up = &port->port; int i, j, ret = 0; if (port->cfg->irqs[0] == port->cfg->irqs[1]) { if (unlikely(!port->cfg->irqs[0])) return -ENODEV; for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { struct sci_irq_desc *desc; unsigned int irq; if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt, IRQF_DISABLED, "sci", port)) { dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; } } else { for (i = 0; i < ARRAY_SIZE(handlers); i++) { if (unlikely(!port->cfg->irqs[i])) continue; if (SCIx_IRQ_IS_MUXED(port)) { i = SCIx_MUX_IRQ; irq = up->irq; } else irq = port->cfg->irqs[i]; if (request_irq(port->cfg->irqs[i], handlers[i], IRQF_DISABLED, desc[i], port)) { dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); if (!port->irqstr[j]) { dev_err(up->dev, "Failed to allocate %s IRQ string\n", desc->desc); goto out_nomem; } ret = request_irq(irq, desc->handler, up->irqflags, port->irqstr[j], port); if (unlikely(ret)) { dev_err(up->dev, "Can't allocate %s IRQ\n", desc->desc); goto out_noirq; } } return 0; out_noirq: while (--i >= 0) free_irq(port->cfg->irqs[i], port); out_nomem: while (--j >= 0) kfree(port->irqstr[j]); return ret; } static void sci_free_irq(struct sci_port *port) { int i; if (port->cfg->irqs[0] == port->cfg->irqs[1]) free_irq(port->cfg->irqs[0], port); else { for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) { if (!port->cfg->irqs[i]) continue; /* * Intentionally in reverse order so we iterate over the muxed * IRQ first. */ for (i = 0; i < SCIx_NR_IRQS; i++) { free_irq(port->cfg->irqs[i], port); kfree(port->irqstr[i]); if (SCIx_IRQ_IS_MUXED(port)) { /* If there's only one IRQ, we're done. */ return; } } } Loading Loading @@ -1537,8 +1582,7 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); if (s->enable) s->enable(port); sci_port_enable(s); ret = sci_request_irq(s); if (unlikely(ret < 0)) Loading @@ -1564,8 +1608,7 @@ static void sci_shutdown(struct uart_port *port) sci_free_dma(port); sci_free_irq(s); if (s->disable) s->disable(port); sci_port_disable(s); } static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, Loading Loading @@ -1612,8 +1655,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if (likely(baud && port->uartclk)) t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); if (s->enable) s->enable(port); sci_port_enable(s); do { status = sci_in(port, SCxSR); Loading Loading @@ -1683,8 +1725,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port); if (s->disable) s->disable(port); sci_port_disable(s); } static const char *sci_type(struct uart_port *port) Loading Loading @@ -1825,6 +1866,7 @@ static int __devinit sci_init_single(struct platform_device *dev, struct plat_sci_port *p) { struct uart_port *port = &sci_port->port; int ret; port->ops = &sci_uart_ops; port->iotype = UPIO_MEM; Loading @@ -1845,8 +1887,11 @@ 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 (p->regtype == SCIx_PROBE_REGTYPE) { ret = sci_probe_regmap(p); if (unlikely(!ret)) return ret; } if (dev) { sci_port->iclk = clk_get(&dev->dev, "sci_ick"); Loading @@ -1866,8 +1911,6 @@ static int __devinit sci_init_single(struct platform_device *dev, if (IS_ERR(sci_port->fclk)) sci_port->fclk = NULL; sci_port->enable = sci_clk_enable; sci_port->disable = sci_clk_disable; port->dev = &dev->dev; pm_runtime_enable(&dev->dev); Loading Loading @@ -1918,6 +1961,7 @@ static int __devinit sci_init_single(struct platform_device *dev, * For the muxed case there's nothing more to do. */ port->irq = p->irqs[SCIx_RXI_IRQ]; port->irqflags = IRQF_DISABLED; port->serial_in = sci_serial_in; port->serial_out = sci_serial_out; Loading Loading @@ -1946,8 +1990,7 @@ static void serial_console_write(struct console *co, const char *s, struct uart_port *port = &sci_port->port; unsigned short bits; if (sci_port->enable) sci_port->enable(port); sci_port_enable(sci_port); uart_console_write(port, s, count, serial_console_putchar); Loading @@ -1956,8 +1999,7 @@ static void serial_console_write(struct console *co, const char *s, while ((sci_in(port, SCxSR) & bits) != bits) cpu_relax(); if (sci_port->disable) sci_port->disable(port); sci_port_disable(sci_port); } static int __devinit serial_console_setup(struct console *co, char *options) Loading Loading @@ -1989,8 +2031,7 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (unlikely(ret != 0)) return ret; if (sci_port->enable) sci_port->enable(port); sci_port_enable(sci_port); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); Loading Loading @@ -2207,3 +2248,5 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); MODULE_DESCRIPTION("SuperH SCI(F) serial driver");
include/linux/serial_sci.h +7 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ enum { SCIx_TXI_IRQ, SCIx_BRI_IRQ, SCIx_NR_IRQS, SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ }; enum { Loading @@ -82,6 +84,11 @@ enum { [SCIx_BRI_IRQ] = (irq), \ } #define SCIx_IRQ_IS_MUXED(port) \ ((port)->cfg->irqs[SCIx_ERI_IRQ] == \ (port)->cfg->irqs[SCIx_RXI_IRQ]) || \ ((port)->cfg->irqs[SCIx_ERI_IRQ] && \ !(port)->cfg->irqs[SCIx_RXI_IRQ]) /* * SCI register subset common for all port types. * Not all registers will exist on all parts. Loading