lkml.org 
[lkml]   [2007]   [Oct]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 7/17] drivers/char/{rio,specialix,sx}: irq handler cleanups
    Date
    commit ac608e65f5c2a99affced5f02eefe24125f9c5bd
    Author: Jeff Garzik <jeff@garzik.org>
    Date: Fri Oct 19 16:43:21 2007 -0400

    drivers/char/{rio,specialix,sx}: irq handler cleanups

    * explicitly separate polled and irq-driven modes of operation

    * no need to reference 'irq' function arg

    * mark a free_irq() -in-irq-handler use with a FIXME (ugh!)

    Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

    drivers/char/rio/rio_linux.c | 23 +++++++++++++----------
    drivers/char/specialix.c | 10 ++++------
    drivers/char/sx.c | 22 ++++++++++++++--------
    3 files changed, 31 insertions(+), 24 deletions(-)

    ac608e65f5c2a99affced5f02eefe24125f9c5bd
    diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
    index 0ce9667..fb06665 100644
    --- a/drivers/char/rio/rio_linux.c
    +++ b/drivers/char/rio/rio_linux.c
    @@ -362,14 +362,11 @@ static void rio_reset_interrupt(struct Host *HostP)
    func_exit();
    }

    -
    -static irqreturn_t rio_interrupt(int irq, void *ptr)
    +static irqreturn_t __rio_interrupt(struct Host *HostP, bool polled)
    {
    - struct Host *HostP;
    func_enter();

    - HostP = ptr; /* &p->RIOHosts[(long)ptr]; */
    - rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec);
    + rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d)\n", HostP->Ivec);

    /* AAargh! The order in which to do these things is essential and
    not trivial.
    @@ -389,7 +386,7 @@ static irqreturn_t rio_interrupt(int irq, void *ptr)
    */

    rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n");
    - if (HostP->Ivec == irq) {
    + if (!polled) {
    /* Tell the card we've noticed the interrupt. */
    rio_reset_interrupt(HostP);
    }
    @@ -398,26 +395,32 @@ static irqreturn_t rio_interrupt(int irq, void *ptr)
    return IRQ_HANDLED;

    if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) {
    - printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec);
    + printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n",
    + HostP, HostP->Ivec);
    return IRQ_HANDLED;
    }

    RIOServiceHost(p, HostP);

    - rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type);
    + rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n",
    + HostP, HostP->Type);

    clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks);
    - rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec);
    + rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d)\n", HostP->Ivec);
    func_exit();
    return IRQ_HANDLED;
    }

    +static irqreturn_t rio_interrupt(int dummy, void *ptr)
    +{
    + return __rio_interrupt(ptr, false);
    +}

    static void rio_pollfunc(unsigned long data)
    {
    func_enter();

    - rio_interrupt(0, &p->RIOHosts[data]);
    + __rio_interrupt(&p->RIOHosts[data], true);
    mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll);

    func_exit();
    diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
    index 4558556..706e74f 100644
    --- a/drivers/char/specialix.c
    +++ b/drivers/char/specialix.c
    @@ -446,8 +446,7 @@ void missed_irq (unsigned long data)
    spin_unlock_irqrestore(&bp->lock, flags);
    if (irq) {
    printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
    - sx_interrupt (((struct specialix_board *)data)->irq,
    - (void*)data);
    + sx_interrupt (-1, bp);
    }
    mod_timer(&missed_irq_timer, jiffies + sx_poll);
    }
    @@ -876,23 +875,22 @@ static inline void sx_check_modem(struct specialix_board * bp)


    /* The main interrupt processing routine */
    -static irqreturn_t sx_interrupt(int irq, void *dev_id)
    +static irqreturn_t sx_interrupt(int dummy, void *dev_id)
    {
    unsigned char status;
    unsigned char ack;
    - struct specialix_board *bp;
    + struct specialix_board *bp = dev_id;
    unsigned long loop = 0;
    int saved_reg;
    unsigned long flags;

    func_enter();

    - bp = dev_id;
    spin_lock_irqsave(&bp->lock, flags);

    dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
    if (!(bp->flags & SX_BOARD_ACTIVE)) {
    - dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
    + dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq);
    spin_unlock_irqrestore(&bp->lock, flags);
    func_exit();
    return IRQ_NONE;
    diff --git a/drivers/char/sx.c b/drivers/char/sx.c
    index a6e1c9b..ae9e973 100644
    --- a/drivers/char/sx.c
    +++ b/drivers/char/sx.c
    @@ -1241,15 +1241,13 @@ static inline void sx_check_modem_signals(struct sx_port *port)
    * Small, elegant, clear.
    */

    -static irqreturn_t sx_interrupt(int irq, void *ptr)
    +static irqreturn_t __sx_interrupt(struct sx_board *board, bool polled)
    {
    - struct sx_board *board = ptr;
    struct sx_port *port;
    int i;

    func_enter();
    - sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq,
    - board->irq);
    + sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d)\n", board->irq);

    /* AAargh! The order in which to do these things is essential and
    not trivial.
    @@ -1281,6 +1279,10 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)

    if (lastjif == jiffies) {
    if (++nintr > IRQ_RATE_LIMIT) {
    + /*
    + * FIXME: free_irq() inside irq handler
    + * is unwise
    + */
    free_irq(board->irq, board);
    printk(KERN_ERR "sx: Too many interrupts. "
    "Turning off interrupt %d.\n",
    @@ -1293,7 +1295,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
    }
    #endif

    - if (board->irq == irq) {
    + if (!polled) {
    /* Tell the card we've noticed the interrupt. */

    sx_write_board_word(board, cc_int_pending, 0);
    @@ -1339,19 +1341,23 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)

    clear_bit(SX_BOARD_INTR_LOCK, &board->locks);

    - sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq,
    - board->irq);
    + sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d)\n", board->irq);
    func_exit();
    return IRQ_HANDLED;
    }

    +static irqreturn_t sx_interrupt(int dummy, void *data)
    +{
    + return __sx_interrupt(data, false);
    +}
    +
    static void sx_pollfunc(unsigned long data)
    {
    struct sx_board *board = (struct sx_board *)data;

    func_enter();

    - sx_interrupt(0, board);
    + __sx_interrupt(board, true);

    mod_timer(&board->timer, jiffies + sx_poll);
    func_exit();
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-10-21 09:59    [W:0.029 / U:60.012 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site