diff options
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3853ed50186e..de161cfcc678 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -54,6 +54,7 @@ #include <asm/platform_early.h> #endif +#include "rsci.h" #include "serial_mctrl_gpio.h" #include "sh-sci.h" #include "sh-sci-common.h" @@ -550,6 +551,7 @@ void sci_port_enable(struct sci_port *sci_port) } sci_port->port.uartclk = sci_port->clk_rates[SCI_FCK]; } +EXPORT_SYMBOL_NS_GPL(sci_port_enable, "SH_SCI"); void sci_port_disable(struct sci_port *sci_port) { @@ -563,6 +565,7 @@ void sci_port_disable(struct sci_port *sci_port) pm_runtime_put_sync(sci_port->port.dev); } +EXPORT_SYMBOL_NS_GPL(sci_port_disable, "SH_SCI"); static inline unsigned long port_rx_irq_mask(struct uart_port *port) { @@ -1828,7 +1831,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) unsigned long flags; u32 ctrl; - if (s->type != PORT_SCI) + if (s->type != PORT_SCI && s->type != SCI_PORT_RSCI) return sci_tx_interrupt(irq, ptr); uart_port_lock_irqsave(port, &flags); @@ -2289,6 +2292,7 @@ int sci_startup(struct uart_port *port) return 0; } +EXPORT_SYMBOL_NS_GPL(sci_startup, "SH_SCI"); void sci_shutdown(struct uart_port *port) { @@ -2319,6 +2323,7 @@ void sci_shutdown(struct uart_port *port) sci_free_irq(s); sci_free_dma(port); } +EXPORT_SYMBOL_NS_GPL(sci_shutdown, "SH_SCI"); static int sci_sck_calc(struct sci_port *s, unsigned int bps, unsigned int *srr) @@ -2750,6 +2755,7 @@ void sci_pm(struct uart_port *port, unsigned int state, break; } } +EXPORT_SYMBOL_NS_GPL(sci_pm, "SH_SCI"); static const char *sci_type(struct uart_port *port) { @@ -2812,6 +2818,7 @@ void sci_release_port(struct uart_port *port) release_mem_region(port->mapbase, sport->reg_size); } +EXPORT_SYMBOL_NS_GPL(sci_release_port, "SH_SCI"); int sci_request_port(struct uart_port *port) { @@ -2834,6 +2841,7 @@ int sci_request_port(struct uart_port *port) return 0; } +EXPORT_SYMBOL_NS_GPL(sci_request_port, "SH_SCI"); void sci_config_port(struct uart_port *port, int flags) { @@ -2843,6 +2851,7 @@ void sci_config_port(struct uart_port *port, int flags) sci_request_port(port); } } +EXPORT_SYMBOL_NS_GPL(sci_config_port, "SH_SCI"); int sci_verify_port(struct uart_port *port, struct serial_struct *ser) { @@ -2852,6 +2861,7 @@ int sci_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } +EXPORT_SYMBOL_NS_GPL(sci_verify_port, "SH_SCI"); static void sci_prepare_console_write(struct uart_port *port, u32 ctrl) { @@ -2977,14 +2987,27 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) struct clk *clk; unsigned int i; - if (sci_port->type == PORT_HSCIF) + if (sci_port->type == PORT_HSCIF) { clk_names[SCI_SCK] = "hsck"; + } else if (sci_port->type == SCI_PORT_RSCI) { + clk_names[SCI_FCK] = "operation"; + clk_names[SCI_BRG_INT] = "bus"; + } for (i = 0; i < SCI_NUM_CLKS; i++) { - clk = devm_clk_get_optional(dev, clk_names[i]); + const char *name = clk_names[i]; + + clk = devm_clk_get_optional(dev, name); if (IS_ERR(clk)) return PTR_ERR(clk); + if (!clk && sci_port->type == SCI_PORT_RSCI && + (i == SCI_FCK || i == SCI_BRG_INT)) { + return dev_err_probe(dev, -ENODEV, + "failed to get %s\n", + name); + } + if (!clk && i == SCI_FCK) { /* * Not all SH platforms declare a clock lookup entry @@ -2995,13 +3018,13 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) if (IS_ERR(clk)) return dev_err_probe(dev, PTR_ERR(clk), "failed to get %s\n", - clk_names[i]); + name); } if (!clk) - dev_dbg(dev, "failed to get %s\n", clk_names[i]); + dev_dbg(dev, "failed to get %s\n", name); else - dev_dbg(dev, "clk %s is %pC rate %lu\n", clk_names[i], + dev_dbg(dev, "clk %s is %pC rate %lu\n", name, clk, clk_get_rate(clk)); sci_port->clks[i] = clk; } @@ -3085,10 +3108,10 @@ static int sci_init_single(struct platform_device *dev, } /* - * The fourth interrupt on SCI port is transmit end interrupt, so + * The fourth interrupt on SCI and RSCI port is transmit end interrupt, so * shuffle the interrupts. */ - if (p->type == PORT_SCI) + if (p->type == PORT_SCI || p->type == SCI_PORT_RSCI) swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]); /* The SCI generates several interrupts. They can be muxed together or @@ -3122,6 +3145,9 @@ static int sci_init_single(struct platform_device *dev, else sci_port->rx_trigger = 8; break; + case SCI_PORT_RSCI: + sci_port->rx_trigger = 15; + break; default: sci_port->rx_trigger = 1; break; @@ -3346,7 +3372,8 @@ static void sci_remove(struct platform_device *dev) if (s->port.fifosize > 1) device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger); - if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF) + if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF || + type == SCI_PORT_RSCI) device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout); } @@ -3440,6 +3467,12 @@ static const struct of_device_id of_sci_match[] __maybe_unused = { .compatible = "renesas,scif-r9a09g057", .data = &of_sci_scif_rzv2h, }, +#ifdef CONFIG_SERIAL_RSCI + { + .compatible = "renesas,r9a09g077-rsci", + .data = &of_sci_rsci_data, + }, +#endif /* CONFIG_SERIAL_RSCI */ /* Family-specific types */ { .compatible = "renesas,rcar-gen1-scif", @@ -3702,7 +3735,7 @@ static int sci_probe(struct platform_device *dev) return ret; } if (sp->type == PORT_SCIFA || sp->type == PORT_SCIFB || - sp->type == PORT_HSCIF) { + sp->type == PORT_HSCIF || sp->type == SCI_PORT_RSCI) { ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_timeout); if (ret) { if (sp->port.fifosize > 1) { |