Revert "serial: 8250: Handle UART without interrupt on TEMT using em485"
This partially reverts commitf6f586102a
. The code added by that commit containted math overflow for 32-bit archs. In addition, the approach used in it is unnecessarily complicated requiring a dedicated timer just for notemt. A simpler approach for providing UART_CAP_NOTEMT already exists (patches 1-2): https://lore.kernel.org/linux-serial/20220411083321.9131-3-ilpo.jarvinen@linux.intel.com/T/#u Thus, simply revert the UART_CAP_NOTEMT change for now. There were two driver changes within the patch series adding UART_CAP_NOTEMT taking advantage of the newly added flag. This does not revert the driver changes and therefore also UART_CAP_NOTEMT define has to remain. UART_CAP_NOTEMT remains no-op until support is again added. Fixes:f6f586102a
("serial: 8250: Handle UART without interrupt on TEMT using em485") Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/r/5f874142-fb1f-bff7-f33-fac823e65e2e@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2a72b1b2db
commit
7a107b2c6b
|
@ -571,21 +571,8 @@ static void serial8250_clear_fifos(struct uart_8250_port *p)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void serial8250_em485_update_temt_delay(struct uart_8250_port *p,
|
||||
unsigned int cflag, unsigned int baud)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
if (!p->em485)
|
||||
return;
|
||||
|
||||
bits = tty_get_frame_size(cflag);
|
||||
p->em485->no_temt_delay = DIV_ROUND_UP(bits * NSEC_PER_SEC, baud);
|
||||
}
|
||||
|
||||
static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t);
|
||||
static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t);
|
||||
static enum hrtimer_restart serial8250_em485_handle_no_temt(struct hrtimer *t);
|
||||
|
||||
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
|
||||
{
|
||||
|
@ -644,16 +631,6 @@ static int serial8250_em485_init(struct uart_8250_port *p)
|
|||
HRTIMER_MODE_REL);
|
||||
hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC,
|
||||
HRTIMER_MODE_REL);
|
||||
|
||||
if (p->capabilities & UART_CAP_NOTEMT) {
|
||||
struct tty_struct *tty = p->port.state->port.tty;
|
||||
|
||||
serial8250_em485_update_temt_delay(p, tty->termios.c_cflag,
|
||||
tty_get_baud_rate(tty));
|
||||
hrtimer_init(&p->em485->no_temt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
p->em485->no_temt_timer.function = &serial8250_em485_handle_no_temt;
|
||||
}
|
||||
|
||||
p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx;
|
||||
p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx;
|
||||
p->em485->port = p;
|
||||
|
@ -685,7 +662,6 @@ void serial8250_em485_destroy(struct uart_8250_port *p)
|
|||
|
||||
hrtimer_cancel(&p->em485->start_tx_timer);
|
||||
hrtimer_cancel(&p->em485->stop_tx_timer);
|
||||
hrtimer_cancel(&p->em485->no_temt_timer);
|
||||
|
||||
kfree(p->em485);
|
||||
p->em485 = NULL;
|
||||
|
@ -1528,11 +1504,6 @@ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
|
|||
hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
static void start_hrtimer_ns(struct hrtimer *hrt, unsigned long nsec)
|
||||
{
|
||||
hrtimer_start(hrt, ns_to_ktime(nsec), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
static void __stop_tx_rs485(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_em485 *em485 = p->em485;
|
||||
|
@ -1564,33 +1535,14 @@ static inline void __stop_tx(struct uart_8250_port *p)
|
|||
|
||||
if (em485) {
|
||||
unsigned char lsr = serial_in(p, UART_LSR);
|
||||
|
||||
p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
|
||||
|
||||
/*
|
||||
* To provide required timing and allow FIFO transfer,
|
||||
* To provide required timeing and allow FIFO transfer,
|
||||
* __stop_tx_rs485() must be called only when both FIFO and
|
||||
* shift register are empty. It is for device driver to enable
|
||||
* interrupt on TEMT.
|
||||
*/
|
||||
if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) {
|
||||
if (!(p->capabilities & UART_CAP_NOTEMT))
|
||||
/* __stop_tx will be called again once TEMT triggers */
|
||||
return;
|
||||
|
||||
if (!(lsr & UART_LSR_THRE))
|
||||
/* __stop_tx will be called again once THRE triggers */
|
||||
return;
|
||||
|
||||
/*
|
||||
* On devices with no TEMT interrupt available, start
|
||||
* a timer for a byte time. The timer will recall
|
||||
* __stop_tx().
|
||||
*/
|
||||
em485->active_timer = &em485->no_temt_timer;
|
||||
start_hrtimer_ns(&em485->no_temt_timer, em485->no_temt_delay);
|
||||
if ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
|
||||
return;
|
||||
}
|
||||
|
||||
__stop_tx_rs485(p);
|
||||
}
|
||||
|
@ -1701,27 +1653,6 @@ static inline void start_tx_rs485(struct uart_port *port)
|
|||
__start_tx(port);
|
||||
}
|
||||
|
||||
static enum hrtimer_restart serial8250_em485_handle_no_temt(struct hrtimer *t)
|
||||
{
|
||||
struct uart_8250_em485 *em485;
|
||||
struct uart_8250_port *p;
|
||||
unsigned long flags;
|
||||
|
||||
em485 = container_of(t, struct uart_8250_em485, no_temt_timer);
|
||||
p = em485->port;
|
||||
|
||||
serial8250_rpm_get(p);
|
||||
spin_lock_irqsave(&p->port.lock, flags);
|
||||
if (em485->active_timer == &em485->no_temt_timer) {
|
||||
em485->active_timer = NULL;
|
||||
__stop_tx(p);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&p->port.lock, flags);
|
||||
serial8250_rpm_put(p);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t)
|
||||
{
|
||||
struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485,
|
||||
|
@ -2927,9 +2858,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
|
||||
serial8250_set_divisor(port, baud, quot, frac);
|
||||
|
||||
if (up->capabilities & UART_CAP_NOTEMT)
|
||||
serial8250_em485_update_temt_delay(up, termios->c_cflag, baud);
|
||||
|
||||
/*
|
||||
* LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
|
||||
* is written without DLAB set, this mode will be disabled.
|
||||
|
|
|
@ -79,9 +79,7 @@ struct uart_8250_ops {
|
|||
struct uart_8250_em485 {
|
||||
struct hrtimer start_tx_timer; /* "rs485 start tx" timer */
|
||||
struct hrtimer stop_tx_timer; /* "rs485 stop tx" timer */
|
||||
struct hrtimer no_temt_timer; /* "rs485 no TEMT interrupt" timer */
|
||||
struct hrtimer *active_timer; /* pointer to active timer */
|
||||
unsigned long no_temt_delay; /* Delay for no_temt_timer */
|
||||
struct uart_8250_port *port; /* for hrtimer callbacks */
|
||||
unsigned int tx_stopped:1; /* tx is currently stopped */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue