TTY: amiserial, remove tasklet for tty_wakeup
tty_wakeup is safe to be called from all contexts. No need to schedule a tasklet for that. Let's call it directly like in other drivers. This allows us to kill another member of async_struct structure. (If we remove the dummy uses in simserial.) Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Tony Luck <tony.luck@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
9c8efecc91
Коммит
c5f0508b99
|
@ -572,7 +572,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
|||
shutdown(info);
|
||||
rs_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->event = 0;
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
if (info->close_delay)
|
||||
|
@ -610,7 +609,6 @@ static void rs_hangup(struct tty_struct *tty)
|
|||
return;
|
||||
shutdown(info);
|
||||
|
||||
info->event = 0;
|
||||
state->count = 0;
|
||||
info->flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
info->tty = NULL;
|
||||
|
|
|
@ -231,17 +231,6 @@ static void rs_start(struct tty_struct *tty)
|
|||
* -----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine is used by the interrupt handler to schedule
|
||||
* processing in the software interrupt portion of the driver.
|
||||
*/
|
||||
static void rs_sched_event(struct async_struct *info,
|
||||
int event)
|
||||
{
|
||||
info->event |= 1 << event;
|
||||
tasklet_schedule(&info->tlet);
|
||||
}
|
||||
|
||||
static void receive_chars(struct async_struct *info)
|
||||
{
|
||||
int status;
|
||||
|
@ -359,7 +348,7 @@ static void transmit_chars(struct async_struct *info)
|
|||
if (CIRC_CNT(info->xmit.head,
|
||||
info->xmit.tail,
|
||||
SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
|
||||
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
|
||||
tty_wakeup(info->tty);
|
||||
|
||||
#ifdef SERIAL_DEBUG_INTR
|
||||
printk("THRE...");
|
||||
|
@ -427,7 +416,7 @@ static void check_modem_status(struct async_struct *info)
|
|||
/* set a pending Tx Interrupt, transmitter should restart now */
|
||||
custom.intreq = IF_SETCLR | IF_TBE;
|
||||
mb();
|
||||
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
|
||||
tty_wakeup(info->tty);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -506,29 +495,6 @@ static irqreturn_t ser_tx_int(int irq, void *dev_id)
|
|||
* -------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine is used to handle the "bottom half" processing for the
|
||||
* serial driver, known also the "software interrupt" processing.
|
||||
* This processing is done at the kernel interrupt level, after the
|
||||
* rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
|
||||
* is where time-consuming activities which can not be done in the
|
||||
* interrupt driver proper are done; the interrupt driver schedules
|
||||
* them using rs_sched_event(), and they get done here.
|
||||
*/
|
||||
|
||||
static void do_softint(unsigned long private_)
|
||||
{
|
||||
struct async_struct *info = (struct async_struct *) private_;
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = info->tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
* Low level utility subroutines for the serial driver: routines to
|
||||
|
@ -1506,7 +1472,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
|||
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
if (info->close_delay) {
|
||||
|
@ -1597,7 +1562,6 @@ static void rs_hangup(struct tty_struct *tty)
|
|||
|
||||
rs_flush_buffer(tty);
|
||||
shutdown(info);
|
||||
info->event = 0;
|
||||
state->count = 0;
|
||||
info->flags &= ~ASYNC_NORMAL_ACTIVE;
|
||||
info->tty = NULL;
|
||||
|
@ -1744,7 +1708,6 @@ static int get_async_struct(int line, struct async_struct **ret_info)
|
|||
info->flags = sstate->flags;
|
||||
info->xmit_fifo_size = sstate->xmit_fifo_size;
|
||||
info->line = line;
|
||||
tasklet_init(&info->tlet, do_softint, (unsigned long)info);
|
||||
info->state = sstate;
|
||||
if (sstate->info) {
|
||||
kfree(info);
|
||||
|
@ -2050,7 +2013,6 @@ static int __exit amiga_serial_remove(struct platform_device *pdev)
|
|||
struct async_struct *info = state->info;
|
||||
|
||||
/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
|
||||
tasklet_kill(&info->tlet);
|
||||
if ((error = tty_unregister_driver(serial_driver)))
|
||||
printk("SERIAL: failed to unregister serial driver (%d)\n",
|
||||
error);
|
||||
|
|
|
@ -56,11 +56,9 @@ struct async_struct {
|
|||
unsigned short closing_wait;
|
||||
int IER; /* Interrupt Enable Register */
|
||||
int MCR; /* Modem control register */
|
||||
unsigned long event;
|
||||
int line;
|
||||
int blocked_open; /* # of blocked opens */
|
||||
struct circ_buf xmit;
|
||||
struct tasklet_struct tlet;
|
||||
wait_queue_head_t open_wait;
|
||||
wait_queue_head_t close_wait;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
|
@ -68,10 +66,4 @@ struct async_struct {
|
|||
struct async_struct *prev_port;
|
||||
};
|
||||
|
||||
/*
|
||||
* Events are used to schedule things to happen at timer-interrupt
|
||||
* time, instead of at rs interrupt time.
|
||||
*/
|
||||
#define RS_EVENT_WRITE_WAKEUP 0
|
||||
|
||||
#endif /* _LINUX_SERIAL_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче