mirror of https://gitee.com/openkylin/linux.git
Merge branch 'renesas/drivers-sci2' into next/drivers
* renesas/drivers-sci2: serial: sh-sci: Rework baud rate calculation serial: sh-sci: Compute overrun_bit without using baud rate algo serial: sh-sci: Remove unused GPIO request code serial: sh-sci: Move overrun_bit and error_mask fields out of pdata serial: sh-sci: Support resources passed through platform resources serial: sh-sci: Don't check IRQ in verify port operation serial: sh-sci: Set the UPF_FIXED_PORT flag serial: sh-sci: Remove duplicate interrupt check in verify port op serial: sh-sci: Simplify baud rate calculation algorithms serial: sh-sci: Remove baud rate calculation algorithm 5 serial: sh-sci: Sort headers alphabetically serial: sh-sci: Convert to clk_prepare/unprepare serial: sh-sci: Don't enable/disable port from within break timer serial: sh-sci: Fix warnings due to improper casts and printk formats
This commit is contained in:
commit
6878e0c0a5
|
@ -23,35 +23,34 @@
|
|||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
|
||||
#ifdef CONFIG_SUPERH
|
||||
#include <asm/sh_bios.h>
|
||||
|
@ -64,6 +63,10 @@ struct sci_port {
|
|||
|
||||
/* Platform configuration */
|
||||
struct plat_sci_port *cfg;
|
||||
int overrun_bit;
|
||||
unsigned int error_mask;
|
||||
unsigned int sampling_rate;
|
||||
|
||||
|
||||
/* Break timer */
|
||||
struct timer_list break_timer;
|
||||
|
@ -74,8 +77,8 @@ struct sci_port {
|
|||
/* Function clock */
|
||||
struct clk *fclk;
|
||||
|
||||
int irqs[SCIx_NR_IRQS];
|
||||
char *irqstr[SCIx_NR_IRQS];
|
||||
char *gpiostr[SCIx_NR_FNS];
|
||||
|
||||
struct dma_chan *chan_tx;
|
||||
struct dma_chan *chan_rx;
|
||||
|
@ -421,9 +424,9 @@ static void sci_port_enable(struct sci_port *sci_port)
|
|||
|
||||
pm_runtime_get_sync(sci_port->port.dev);
|
||||
|
||||
clk_enable(sci_port->iclk);
|
||||
clk_prepare_enable(sci_port->iclk);
|
||||
sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
|
||||
clk_enable(sci_port->fclk);
|
||||
clk_prepare_enable(sci_port->fclk);
|
||||
}
|
||||
|
||||
static void sci_port_disable(struct sci_port *sci_port)
|
||||
|
@ -431,8 +434,16 @@ 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);
|
||||
/* Cancel the break timer to ensure that the timer handler will not try
|
||||
* to access the hardware with clocks and power disabled. Reset the
|
||||
* break flag to make the break debouncing state machine ready for the
|
||||
* next break.
|
||||
*/
|
||||
del_timer_sync(&sci_port->break_timer);
|
||||
sci_port->break_flag = 0;
|
||||
|
||||
clk_disable_unprepare(sci_port->fclk);
|
||||
clk_disable_unprepare(sci_port->iclk);
|
||||
|
||||
pm_runtime_put_sync(sci_port->port.dev);
|
||||
}
|
||||
|
@ -557,7 +568,7 @@ static inline int sci_rxd_in(struct uart_port *port)
|
|||
return 1;
|
||||
|
||||
/* Cast for ARM damage */
|
||||
return !!__raw_readb((void __iomem *)s->cfg->port_reg);
|
||||
return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg);
|
||||
}
|
||||
|
||||
/* ********************************************************************** *
|
||||
|
@ -733,8 +744,6 @@ static void sci_break_timer(unsigned long data)
|
|||
{
|
||||
struct sci_port *port = (struct sci_port *)data;
|
||||
|
||||
sci_port_enable(port);
|
||||
|
||||
if (sci_rxd_in(&port->port) == 0) {
|
||||
port->break_flag = 1;
|
||||
sci_schedule_break_timer(port);
|
||||
|
@ -744,8 +753,6 @@ static void sci_break_timer(unsigned long data)
|
|||
sci_schedule_break_timer(port);
|
||||
} else
|
||||
port->break_flag = 0;
|
||||
|
||||
sci_port_disable(port);
|
||||
}
|
||||
|
||||
static int sci_handle_errors(struct uart_port *port)
|
||||
|
@ -755,19 +762,15 @@ static int sci_handle_errors(struct uart_port *port)
|
|||
struct tty_port *tport = &port->state->port;
|
||||
struct sci_port *s = to_sci_port(port);
|
||||
|
||||
/*
|
||||
* Handle overruns, if supported.
|
||||
*/
|
||||
if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
|
||||
if (status & (1 << s->cfg->overrun_bit)) {
|
||||
port->icount.overrun++;
|
||||
/* Handle overruns */
|
||||
if (status & (1 << s->overrun_bit)) {
|
||||
port->icount.overrun++;
|
||||
|
||||
/* overrun error */
|
||||
if (tty_insert_flip_char(tport, 0, TTY_OVERRUN))
|
||||
copied++;
|
||||
/* overrun error */
|
||||
if (tty_insert_flip_char(tport, 0, TTY_OVERRUN))
|
||||
copied++;
|
||||
|
||||
dev_notice(port->dev, "overrun error");
|
||||
}
|
||||
dev_notice(port->dev, "overrun error");
|
||||
}
|
||||
|
||||
if (status & SCxSR_FER(port)) {
|
||||
|
@ -829,7 +832,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
|
|||
if (!reg->size)
|
||||
return 0;
|
||||
|
||||
if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
|
||||
if ((serial_port_in(port, SCLSR) & (1 << s->overrun_bit))) {
|
||||
serial_port_out(port, SCLSR, 0);
|
||||
|
||||
port->icount.overrun++;
|
||||
|
@ -1075,19 +1078,19 @@ static int sci_request_irq(struct sci_port *port)
|
|||
|
||||
for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
|
||||
struct sci_irq_desc *desc;
|
||||
unsigned int irq;
|
||||
int irq;
|
||||
|
||||
if (SCIx_IRQ_IS_MUXED(port)) {
|
||||
i = SCIx_MUX_IRQ;
|
||||
irq = up->irq;
|
||||
} else {
|
||||
irq = port->cfg->irqs[i];
|
||||
irq = port->irqs[i];
|
||||
|
||||
/*
|
||||
* Certain port types won't support all of the
|
||||
* available interrupt sources.
|
||||
*/
|
||||
if (unlikely(!irq))
|
||||
if (unlikely(irq < 0))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1112,7 +1115,7 @@ static int sci_request_irq(struct sci_port *port)
|
|||
|
||||
out_noirq:
|
||||
while (--i >= 0)
|
||||
free_irq(port->cfg->irqs[i], port);
|
||||
free_irq(port->irqs[i], port);
|
||||
|
||||
out_nomem:
|
||||
while (--j >= 0)
|
||||
|
@ -1130,16 +1133,16 @@ static void sci_free_irq(struct sci_port *port)
|
|||
* IRQ first.
|
||||
*/
|
||||
for (i = 0; i < SCIx_NR_IRQS; i++) {
|
||||
unsigned int irq = port->cfg->irqs[i];
|
||||
int irq = port->irqs[i];
|
||||
|
||||
/*
|
||||
* Certain port types won't support all of the available
|
||||
* interrupt sources.
|
||||
*/
|
||||
if (unlikely(!irq))
|
||||
if (unlikely(irq < 0))
|
||||
continue;
|
||||
|
||||
free_irq(port->cfg->irqs[i], port);
|
||||
free_irq(port->irqs[i], port);
|
||||
kfree(port->irqstr[i]);
|
||||
|
||||
if (SCIx_IRQ_IS_MUXED(port)) {
|
||||
|
@ -1149,67 +1152,6 @@ static void sci_free_irq(struct sci_port *port)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *sci_gpio_names[SCIx_NR_FNS] = {
|
||||
"sck", "rxd", "txd", "cts", "rts",
|
||||
};
|
||||
|
||||
static const char *sci_gpio_str(unsigned int index)
|
||||
{
|
||||
return sci_gpio_names[index];
|
||||
}
|
||||
|
||||
static void sci_init_gpios(struct sci_port *port)
|
||||
{
|
||||
struct uart_port *up = &port->port;
|
||||
int i;
|
||||
|
||||
if (!port->cfg)
|
||||
return;
|
||||
|
||||
for (i = 0; i < SCIx_NR_FNS; i++) {
|
||||
const char *desc;
|
||||
int ret;
|
||||
|
||||
if (!port->cfg->gpios[i])
|
||||
continue;
|
||||
|
||||
desc = sci_gpio_str(i);
|
||||
|
||||
port->gpiostr[i] = kasprintf(GFP_KERNEL, "%s:%s",
|
||||
dev_name(up->dev), desc);
|
||||
|
||||
/*
|
||||
* If we've failed the allocation, we can still continue
|
||||
* on with a NULL string.
|
||||
*/
|
||||
if (!port->gpiostr[i])
|
||||
dev_notice(up->dev, "%s string allocation failure\n",
|
||||
desc);
|
||||
|
||||
ret = gpio_request(port->cfg->gpios[i], port->gpiostr[i]);
|
||||
if (unlikely(ret != 0)) {
|
||||
dev_notice(up->dev, "failed %s gpio request\n", desc);
|
||||
|
||||
/*
|
||||
* If we can't get the GPIO for whatever reason,
|
||||
* no point in keeping the verbose string around.
|
||||
*/
|
||||
kfree(port->gpiostr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sci_free_gpios(struct sci_port *port)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SCIx_NR_FNS; i++)
|
||||
if (port->cfg->gpios[i]) {
|
||||
gpio_free(port->cfg->gpios[i]);
|
||||
kfree(port->gpiostr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int sci_tx_empty(struct uart_port *port)
|
||||
{
|
||||
unsigned short status = serial_port_in(port, SCxSR);
|
||||
|
@ -1309,7 +1251,7 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count)
|
|||
}
|
||||
|
||||
if (room < count)
|
||||
dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
|
||||
dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
|
||||
count - room);
|
||||
if (!room)
|
||||
return room;
|
||||
|
@ -1442,7 +1384,7 @@ static void work_fn_rx(struct work_struct *work)
|
|||
int count;
|
||||
|
||||
chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
|
||||
dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
|
||||
dev_dbg(port->dev, "Read %zu bytes with cookie %d\n",
|
||||
sh_desc->partial, sh_desc->cookie);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
@ -1655,7 +1597,7 @@ static void rx_timer_fn(unsigned long arg)
|
|||
|
||||
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
|
||||
scr &= ~0x4000;
|
||||
enable_irq(s->cfg->irqs[1]);
|
||||
enable_irq(s->irqs[SCIx_RXI_IRQ]);
|
||||
}
|
||||
serial_port_out(port, SCSCR, scr | SCSCR_RIE);
|
||||
dev_dbg(port->dev, "DMA Rx timed out\n");
|
||||
|
@ -1691,16 +1633,17 @@ static void sci_request_dma(struct uart_port *port)
|
|||
s->chan_tx = chan;
|
||||
sg_init_table(&s->sg_tx, 1);
|
||||
/* UART circular tx buffer is an aligned page. */
|
||||
BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
|
||||
BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
|
||||
sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
|
||||
UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
|
||||
UART_XMIT_SIZE,
|
||||
(uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
|
||||
nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
|
||||
if (!nent)
|
||||
sci_tx_dma_release(s, false);
|
||||
else
|
||||
dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
|
||||
sg_dma_len(&s->sg_tx),
|
||||
port->state->xmit.buf, sg_dma_address(&s->sg_tx));
|
||||
dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
|
||||
sg_dma_len(&s->sg_tx), port->state->xmit.buf,
|
||||
&sg_dma_address(&s->sg_tx));
|
||||
|
||||
s->sg_len_tx = nent;
|
||||
|
||||
|
@ -1740,7 +1683,7 @@ static void sci_request_dma(struct uart_port *port)
|
|||
|
||||
sg_init_table(sg, 1);
|
||||
sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
|
||||
(int)buf[i] & ~PAGE_MASK);
|
||||
(uintptr_t)buf[i] & ~PAGE_MASK);
|
||||
sg_dma_address(sg) = dma[i];
|
||||
}
|
||||
|
||||
|
@ -1808,20 +1751,21 @@ static void sci_shutdown(struct uart_port *port)
|
|||
sci_free_irq(s);
|
||||
}
|
||||
|
||||
static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
|
||||
static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
|
||||
unsigned long freq)
|
||||
{
|
||||
switch (algo_id) {
|
||||
if (s->sampling_rate)
|
||||
return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1;
|
||||
|
||||
switch (s->cfg->scbrr_algo_id) {
|
||||
case SCBRR_ALGO_1:
|
||||
return ((freq + 16 * bps) / (16 * bps) - 1);
|
||||
return freq / (16 * bps);
|
||||
case SCBRR_ALGO_2:
|
||||
return ((freq + 16 * bps) / (32 * bps) - 1);
|
||||
return DIV_ROUND_CLOSEST(freq, 32 * bps) - 1;
|
||||
case SCBRR_ALGO_3:
|
||||
return (((freq * 2) + 16 * bps) / (16 * bps) - 1);
|
||||
return freq / (8 * bps);
|
||||
case SCBRR_ALGO_4:
|
||||
return (((freq * 2) + 16 * bps) / (32 * bps) - 1);
|
||||
case SCBRR_ALGO_5:
|
||||
return (((freq * 1000 / 32) / bps) - 1);
|
||||
return DIV_ROUND_CLOSEST(freq, 16 * bps) - 1;
|
||||
}
|
||||
|
||||
/* Warn, but use a safe default */
|
||||
|
@ -1903,12 +1847,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
|
||||
baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
|
||||
if (likely(baud && port->uartclk)) {
|
||||
if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) {
|
||||
if (s->cfg->type == PORT_HSCIF) {
|
||||
sci_baud_calc_hscif(baud, port->uartclk, &t, &srr,
|
||||
&cks);
|
||||
} else {
|
||||
t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud,
|
||||
port->uartclk);
|
||||
t = sci_scbrr_calc(s, baud, port->uartclk);
|
||||
for (cks = 0; t >= 256 && cks <= 3; cks++)
|
||||
t >>= 2;
|
||||
}
|
||||
|
@ -2115,10 +2058,6 @@ static void sci_config_port(struct uart_port *port, int flags)
|
|||
|
||||
static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||
{
|
||||
struct sci_port *s = to_sci_port(port);
|
||||
|
||||
if (ser->irq != s->cfg->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs)
|
||||
return -EINVAL;
|
||||
if (ser->baud_base < 2400)
|
||||
/* No paper tape reader for Mitch.. */
|
||||
return -EINVAL;
|
||||
|
@ -2151,11 +2090,13 @@ static struct uart_ops sci_uart_ops = {
|
|||
};
|
||||
|
||||
static int sci_init_single(struct platform_device *dev,
|
||||
struct sci_port *sci_port,
|
||||
unsigned int index,
|
||||
struct plat_sci_port *p)
|
||||
struct sci_port *sci_port, unsigned int index,
|
||||
struct plat_sci_port *p, bool early)
|
||||
{
|
||||
struct uart_port *port = &sci_port->port;
|
||||
const struct resource *res;
|
||||
unsigned int sampling_rate;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
sci_port->cfg = p;
|
||||
|
@ -2164,22 +2105,36 @@ static int sci_init_single(struct platform_device *dev,
|
|||
port->iotype = UPIO_MEM;
|
||||
port->line = index;
|
||||
|
||||
switch (p->type) {
|
||||
case PORT_SCIFB:
|
||||
port->fifosize = 256;
|
||||
break;
|
||||
case PORT_HSCIF:
|
||||
port->fifosize = 128;
|
||||
break;
|
||||
case PORT_SCIFA:
|
||||
port->fifosize = 64;
|
||||
break;
|
||||
case PORT_SCIF:
|
||||
port->fifosize = 16;
|
||||
break;
|
||||
default:
|
||||
port->fifosize = 1;
|
||||
break;
|
||||
if (dev->num_resources) {
|
||||
/* Device has resources, use them. */
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
port->mapbase = res->start;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
|
||||
sci_port->irqs[i] = platform_get_irq(dev, i);
|
||||
|
||||
/* The SCI generates several interrupts. They can be muxed
|
||||
* together or connected to different interrupt lines. In the
|
||||
* muxed case only one interrupt resource is specified. In the
|
||||
* non-muxed case three or four interrupt resources are
|
||||
* specified, as the BRI interrupt is optional.
|
||||
*/
|
||||
if (sci_port->irqs[0] < 0)
|
||||
return -ENXIO;
|
||||
|
||||
if (sci_port->irqs[1] < 0) {
|
||||
sci_port->irqs[1] = sci_port->irqs[0];
|
||||
sci_port->irqs[2] = sci_port->irqs[0];
|
||||
sci_port->irqs[3] = sci_port->irqs[0];
|
||||
}
|
||||
} else {
|
||||
/* No resources, use old-style platform data. */
|
||||
port->mapbase = p->mapbase;
|
||||
for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
|
||||
sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO;
|
||||
}
|
||||
|
||||
if (p->regtype == SCIx_PROBE_REGTYPE) {
|
||||
|
@ -2188,7 +2143,52 @@ static int sci_init_single(struct platform_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
switch (p->type) {
|
||||
case PORT_SCIFB:
|
||||
port->fifosize = 256;
|
||||
sci_port->overrun_bit = 9;
|
||||
sampling_rate = 16;
|
||||
break;
|
||||
case PORT_HSCIF:
|
||||
port->fifosize = 128;
|
||||
sampling_rate = 0;
|
||||
sci_port->overrun_bit = 0;
|
||||
break;
|
||||
case PORT_SCIFA:
|
||||
port->fifosize = 64;
|
||||
sci_port->overrun_bit = 9;
|
||||
sampling_rate = 16;
|
||||
break;
|
||||
case PORT_SCIF:
|
||||
port->fifosize = 16;
|
||||
if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) {
|
||||
sci_port->overrun_bit = 9;
|
||||
sampling_rate = 16;
|
||||
} else {
|
||||
sci_port->overrun_bit = 0;
|
||||
sampling_rate = 32;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
port->fifosize = 1;
|
||||
sci_port->overrun_bit = 5;
|
||||
sampling_rate = 32;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the sampling rate if the baud rate calculation algorithm isn't
|
||||
* specified.
|
||||
*/
|
||||
if (p->scbrr_algo_id == SCBRR_ALGO_NONE) {
|
||||
/* SCIFA on sh7723 and sh7724 need a custom sampling rate that
|
||||
* doesn't match the SoC datasheet, this should be investigated.
|
||||
* Let platform data override the sampling rate for now.
|
||||
*/
|
||||
sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate
|
||||
: sampling_rate;
|
||||
}
|
||||
|
||||
if (!early) {
|
||||
sci_port->iclk = clk_get(&dev->dev, "sci_ick");
|
||||
if (IS_ERR(sci_port->iclk)) {
|
||||
sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
|
||||
|
@ -2208,8 +2208,6 @@ static int sci_init_single(struct platform_device *dev,
|
|||
|
||||
port->dev = &dev->dev;
|
||||
|
||||
sci_init_gpios(sci_port);
|
||||
|
||||
pm_runtime_enable(&dev->dev);
|
||||
}
|
||||
|
||||
|
@ -2220,32 +2218,22 @@ static int sci_init_single(struct platform_device *dev,
|
|||
/*
|
||||
* Establish some sensible defaults for the error detection.
|
||||
*/
|
||||
if (!p->error_mask)
|
||||
p->error_mask = (p->type == PORT_SCI) ?
|
||||
sci_port->error_mask = (p->type == PORT_SCI) ?
|
||||
SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK;
|
||||
|
||||
/*
|
||||
* Establish sensible defaults for the overrun detection, unless
|
||||
* the part has explicitly disabled support for it.
|
||||
*/
|
||||
if (p->overrun_bit != SCIx_NOT_SUPPORTED) {
|
||||
if (p->type == PORT_SCI)
|
||||
p->overrun_bit = 5;
|
||||
else if (p->scbrr_algo_id == SCBRR_ALGO_4)
|
||||
p->overrun_bit = 9;
|
||||
else
|
||||
p->overrun_bit = 0;
|
||||
|
||||
/*
|
||||
* Make the error mask inclusive of overrun detection, if
|
||||
* supported.
|
||||
*/
|
||||
p->error_mask |= (1 << p->overrun_bit);
|
||||
}
|
||||
/*
|
||||
* Make the error mask inclusive of overrun detection, if
|
||||
* supported.
|
||||
*/
|
||||
sci_port->error_mask |= 1 << sci_port->overrun_bit;
|
||||
|
||||
port->mapbase = p->mapbase;
|
||||
port->type = p->type;
|
||||
port->flags = p->flags;
|
||||
port->flags = UPF_FIXED_PORT | p->flags;
|
||||
port->regshift = p->regshift;
|
||||
|
||||
/*
|
||||
|
@ -2255,7 +2243,7 @@ static int 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->irq = sci_port->irqs[SCIx_RXI_IRQ];
|
||||
port->irqflags = 0;
|
||||
|
||||
port->serial_in = sci_serial_in;
|
||||
|
@ -2270,8 +2258,6 @@ static int sci_init_single(struct platform_device *dev,
|
|||
|
||||
static void sci_cleanup_single(struct sci_port *port)
|
||||
{
|
||||
sci_free_gpios(port);
|
||||
|
||||
clk_put(port->iclk);
|
||||
clk_put(port->fclk);
|
||||
|
||||
|
@ -2387,7 +2373,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)
|
|||
|
||||
early_serial_console.index = pdev->id;
|
||||
|
||||
sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg);
|
||||
sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true);
|
||||
|
||||
serial_console_setup(&early_serial_console, early_serial_buf);
|
||||
|
||||
|
@ -2454,7 +2440,7 @@ static int sci_probe_single(struct platform_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = sci_init_single(dev, sciport, index, p);
|
||||
ret = sci_init_single(dev, sciport, index, p, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
|
||||
#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
|
||||
|
||||
#define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask)
|
||||
#define SCxSR_ERRORS(port) (to_sci_port(port)->error_mask)
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#define SCIx_NOT_SUPPORTED (-1)
|
||||
|
||||
enum {
|
||||
SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */
|
||||
SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */
|
||||
SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */
|
||||
SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */
|
||||
SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */
|
||||
SCBRR_ALGO_NONE, /* Compute sampling rate in the driver */
|
||||
SCBRR_ALGO_1, /* clk / (16 * bps) */
|
||||
SCBRR_ALGO_2, /* DIV_ROUND_CLOSEST(clk, 32 * bps) - 1 */
|
||||
SCBRR_ALGO_3, /* clk / (8 * bps) */
|
||||
SCBRR_ALGO_4, /* DIV_ROUND_CLOSEST(clk, 16 * bps) - 1 */
|
||||
SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */
|
||||
};
|
||||
|
||||
|
@ -70,17 +70,6 @@ enum {
|
|||
SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */
|
||||
};
|
||||
|
||||
/* Offsets into the sci_port->gpios array */
|
||||
enum {
|
||||
SCIx_SCK,
|
||||
SCIx_RXD,
|
||||
SCIx_TXD,
|
||||
SCIx_CTS,
|
||||
SCIx_RTS,
|
||||
|
||||
SCIx_NR_FNS,
|
||||
};
|
||||
|
||||
enum {
|
||||
SCIx_PROBE_REGTYPE,
|
||||
|
||||
|
@ -108,10 +97,10 @@ enum {
|
|||
}
|
||||
|
||||
#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])
|
||||
((port)->irqs[SCIx_ERI_IRQ] == \
|
||||
(port)->irqs[SCIx_RXI_IRQ]) || \
|
||||
((port)->irqs[SCIx_ERI_IRQ] && \
|
||||
((port)->irqs[SCIx_RXI_IRQ] < 0))
|
||||
/*
|
||||
* SCI register subset common for all port types.
|
||||
* Not all registers will exist on all parts.
|
||||
|
@ -142,20 +131,17 @@ struct plat_sci_port_ops {
|
|||
struct plat_sci_port {
|
||||
unsigned long mapbase; /* resource base */
|
||||
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
|
||||
unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */
|
||||
unsigned int type; /* SCI / SCIF / IRDA / HSCIF */
|
||||
upf_t flags; /* UPF_* flags */
|
||||
unsigned long capabilities; /* Port features/capabilities */
|
||||
|
||||
unsigned int sampling_rate;
|
||||
unsigned int scbrr_algo_id; /* SCBRR calculation algo */
|
||||
unsigned int scscr; /* SCSCR initialization */
|
||||
|
||||
/*
|
||||
* Platform overrides if necessary, defaults otherwise.
|
||||
*/
|
||||
int overrun_bit;
|
||||
unsigned int error_mask;
|
||||
|
||||
int port_reg;
|
||||
unsigned char regshift;
|
||||
unsigned char regtype;
|
||||
|
|
Loading…
Reference in New Issue