Commit d5cb1319 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Greg Kroah-Hartman

serial: sh-sci: Remove manual break debouncing

The sh-sci driver implements manual break debouncing for a few SH
platforms by reading the value of the RX pin port register. This feature
is optional and the driver considers all negative or zero values of the
platform data port_reg field as invalid. As the four platforms that set
the field to a register address all use an address higher than
0x7fffffff, the driver will always consider the value as invalid and
never perform debouncing. The feature is unused, remove it.

Debouncing could be implemented properly in the future using the pinctrl
and GPIO APIs if desired.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 219fb0c1
...@@ -125,10 +125,6 @@ struct sci_port { ...@@ -125,10 +125,6 @@ struct sci_port {
resource_size_t reg_size; resource_size_t reg_size;
struct mctrl_gpios *gpios; struct mctrl_gpios *gpios;
/* Break timer */
struct timer_list break_timer;
int break_flag;
/* Clocks */ /* Clocks */
struct clk *clks[SCI_NUM_CLKS]; struct clk *clks[SCI_NUM_CLKS];
unsigned long clk_rates[SCI_NUM_CLKS]; unsigned long clk_rates[SCI_NUM_CLKS];
...@@ -517,14 +513,6 @@ static void sci_port_disable(struct sci_port *sci_port) ...@@ -517,14 +513,6 @@ static void sci_port_disable(struct sci_port *sci_port)
if (!sci_port->port.dev) if (!sci_port->port.dev)
return; return;
/* 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;
for (i = SCI_NUM_CLKS; i-- > 0; ) for (i = SCI_NUM_CLKS; i-- > 0; )
clk_disable_unprepare(sci_port->clks[i]); clk_disable_unprepare(sci_port->clks[i]);
...@@ -751,20 +739,6 @@ static int sci_rxfill(struct uart_port *port) ...@@ -751,20 +739,6 @@ static int sci_rxfill(struct uart_port *port)
return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
} }
/*
* SCI helper for checking the state of the muxed port/RXD pins.
*/
static inline int sci_rxd_in(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
if (s->cfg->port_reg <= 0)
return 1;
/* Cast for ARM damage */
return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg);
}
/* ********************************************************************** * /* ********************************************************************** *
* the interrupt related routines * * the interrupt related routines *
* ********************************************************************** */ * ********************************************************************** */
...@@ -832,7 +806,6 @@ static void sci_transmit_chars(struct uart_port *port) ...@@ -832,7 +806,6 @@ static void sci_transmit_chars(struct uart_port *port)
static void sci_receive_chars(struct uart_port *port) static void sci_receive_chars(struct uart_port *port)
{ {
struct sci_port *sci_port = to_sci_port(port);
struct tty_port *tport = &port->state->port; struct tty_port *tport = &port->state->port;
int i, count, copied = 0; int i, count, copied = 0;
unsigned short status; unsigned short status;
...@@ -852,8 +825,7 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -852,8 +825,7 @@ static void sci_receive_chars(struct uart_port *port)
if (port->type == PORT_SCI) { if (port->type == PORT_SCI) {
char c = serial_port_in(port, SCxRDR); char c = serial_port_in(port, SCxRDR);
if (uart_handle_sysrq_char(port, c) || if (uart_handle_sysrq_char(port, c))
sci_port->break_flag)
count = 0; count = 0;
else else
tty_insert_flip_char(tport, c, TTY_NORMAL); tty_insert_flip_char(tport, c, TTY_NORMAL);
...@@ -862,25 +834,6 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -862,25 +834,6 @@ static void sci_receive_chars(struct uart_port *port)
char c = serial_port_in(port, SCxRDR); char c = serial_port_in(port, SCxRDR);
status = serial_port_in(port, SCxSR); status = serial_port_in(port, SCxSR);
#if defined(CONFIG_CPU_SH3)
/* Skip "chars" during break */
if (sci_port->break_flag) {
if ((c == 0) &&
(status & SCxSR_FER(port))) {
count--; i--;
continue;
}
/* Nonzero => end-of-break */
dev_dbg(port->dev, "debounce<%02x>\n", c);
sci_port->break_flag = 0;
if (STEPFN(c)) {
count--; i--;
continue;
}
}
#endif /* CONFIG_CPU_SH3 */
if (uart_handle_sysrq_char(port, c)) { if (uart_handle_sysrq_char(port, c)) {
count--; i--; count--; i--;
continue; continue;
...@@ -918,37 +871,6 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -918,37 +871,6 @@ static void sci_receive_chars(struct uart_port *port)
} }
} }
#define SCI_BREAK_JIFFIES (HZ/20)
/*
* The sci generates interrupts during the break,
* 1 per millisecond or so during the break period, for 9600 baud.
* So dont bother disabling interrupts.
* But dont want more than 1 break event.
* Use a kernel timer to periodically poll the rx line until
* the break is finished.
*/
static inline void sci_schedule_break_timer(struct sci_port *port)
{
mod_timer(&port->break_timer, jiffies + SCI_BREAK_JIFFIES);
}
/* Ensure that two consecutive samples find the break over. */
static void sci_break_timer(unsigned long data)
{
struct sci_port *port = (struct sci_port *)data;
if (sci_rxd_in(&port->port) == 0) {
port->break_flag = 1;
sci_schedule_break_timer(port);
} else if (port->break_flag == 1) {
/* break is over. */
port->break_flag = 2;
sci_schedule_break_timer(port);
} else
port->break_flag = 0;
}
static int sci_handle_errors(struct uart_port *port) static int sci_handle_errors(struct uart_port *port)
{ {
int copied = 0; int copied = 0;
...@@ -968,35 +890,13 @@ static int sci_handle_errors(struct uart_port *port) ...@@ -968,35 +890,13 @@ static int sci_handle_errors(struct uart_port *port)
} }
if (status & SCxSR_FER(port)) { if (status & SCxSR_FER(port)) {
if (sci_rxd_in(port) == 0) { /* frame error */
/* Notify of BREAK */ port->icount.frame++;
struct sci_port *sci_port = to_sci_port(port);
if (!sci_port->break_flag) {
port->icount.brk++;
sci_port->break_flag = 1;
sci_schedule_break_timer(sci_port);
/* Do sysrq handling. */
if (uart_handle_break(port))
return 0;
dev_dbg(port->dev, "BREAK detected\n");
if (tty_insert_flip_char(tport, 0, TTY_BREAK))
copied++;
}
} else {
/* frame error */
port->icount.frame++;
if (tty_insert_flip_char(tport, 0, TTY_FRAME)) if (tty_insert_flip_char(tport, 0, TTY_FRAME))
copied++; copied++;
dev_notice(port->dev, "frame error\n"); dev_notice(port->dev, "frame error\n");
}
} }
if (status & SCxSR_PER(port)) { if (status & SCxSR_PER(port)) {
...@@ -1049,17 +949,11 @@ static int sci_handle_breaks(struct uart_port *port) ...@@ -1049,17 +949,11 @@ static int sci_handle_breaks(struct uart_port *port)
int copied = 0; int copied = 0;
unsigned short status = serial_port_in(port, SCxSR); unsigned short status = serial_port_in(port, SCxSR);
struct tty_port *tport = &port->state->port; struct tty_port *tport = &port->state->port;
struct sci_port *s = to_sci_port(port);
if (uart_handle_break(port)) if (uart_handle_break(port))
return 0; return 0;
if (!s->break_flag && status & SCxSR_BRK(port)) { if (status & SCxSR_BRK(port)) {
#if defined(CONFIG_CPU_SH3)
/* Debounce break */
s->break_flag = 1;
#endif
port->icount.brk++; port->icount.brk++;
/* Notify of BREAK */ /* Notify of BREAK */
...@@ -2677,10 +2571,6 @@ static int sci_init_single(struct platform_device *dev, ...@@ -2677,10 +2571,6 @@ static int sci_init_single(struct platform_device *dev,
pm_runtime_enable(&dev->dev); pm_runtime_enable(&dev->dev);
} }
sci_port->break_timer.data = (unsigned long)sci_port;
sci_port->break_timer.function = sci_break_timer;
init_timer(&sci_port->break_timer);
port->type = p->type; port->type = p->type;
port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags; port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags;
port->regshift = p->regshift; port->regshift = p->regshift;
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
* Generic header for SuperH (H)SCI(F) (used by sh/sh64 and related parts) * Generic header for SuperH (H)SCI(F) (used by sh/sh64 and related parts)
*/ */
#define SCIx_NOT_SUPPORTED (-1)
/* Serial Control Register (@ = not supported by all parts) */ /* Serial Control Register (@ = not supported by all parts) */
#define SCSCR_TIE BIT(7) /* Transmit Interrupt Enable */ #define SCSCR_TIE BIT(7) /* Transmit Interrupt Enable */
#define SCSCR_RIE BIT(6) /* Receive Interrupt Enable */ #define SCSCR_RIE BIT(6) /* Receive Interrupt Enable */
...@@ -41,8 +39,6 @@ enum { ...@@ -41,8 +39,6 @@ enum {
SCIx_NR_REGTYPES, SCIx_NR_REGTYPES,
}; };
struct device;
struct plat_sci_port_ops { struct plat_sci_port_ops {
void (*init_pins)(struct uart_port *, unsigned int cflag); void (*init_pins)(struct uart_port *, unsigned int cflag);
}; };
...@@ -66,7 +62,6 @@ struct plat_sci_port { ...@@ -66,7 +62,6 @@ struct plat_sci_port {
/* /*
* Platform overrides if necessary, defaults otherwise. * Platform overrides if necessary, defaults otherwise.
*/ */
int port_reg;
unsigned char regshift; unsigned char regshift;
unsigned char regtype; unsigned char regtype;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment