TTY: amiserial, remove tasklet for tty_wakeup
Jiri Slaby [Mon, 5 Mar 2012 13:52:13 +0000 (14:52 +0100)]
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>

arch/ia64/hp/sim/simserial.c
drivers/tty/amiserial.c
include/linux/serialP.h

index 9890b58..0d324e8 100644 (file)
@@ -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;
index c6d8913..d5fac86 100644 (file)
@@ -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 {
@@ -507,29 +496,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
  * figure out the appropriate timeout for an interrupt chain, routines
@@ -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);
index c1acdb2..beaf39f 100644 (file)
@@ -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 */