lkml.org 
[lkml]   [2011]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 3/4] genirq: Add IRQF_FORCE_RESUME
    Xen needs to reenable interrupts which are marked IRQF_NO_SUSPEND in the
    resume path. Add a flag to force the reenabling in the resume code.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
    include/linux/interrupt.h | 3 ++-
    include/linux/irq.h | 4 +++-
    kernel/irq/manage.c | 11 ++++++++++-
    kernel/irq/pm.c | 3 ---
    4 files changed, 15 insertions(+), 6 deletions(-)

    Index: linux-next/include/linux/interrupt.h
    ===================================================================
    --- linux-next.orig/include/linux/interrupt.h
    +++ linux-next/include/linux/interrupt.h
    @@ -57,7 +57,7 @@
    * Used by threaded interrupts which need to keep the
    * irq line disabled until the threaded handler has been run.
    * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
    - *
    + * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
    */
    #define IRQF_DISABLED 0x00000020
    #define IRQF_SAMPLE_RANDOM 0x00000040
    @@ -69,6 +69,7 @@
    #define IRQF_IRQPOLL 0x00001000
    #define IRQF_ONESHOT 0x00002000
    #define IRQF_NO_SUSPEND 0x00004000
    +#define IRQF_FORCE_RESUME 0x00008000

    #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND)

    Index: linux-next/include/linux/irq.h
    ===================================================================
    --- linux-next.orig/include/linux/irq.h
    +++ linux-next/include/linux/irq.h
    @@ -71,10 +71,12 @@ typedef void (*irq_flow_handler_t)(unsig
    #define IRQ_SUSPENDED 0x04000000 /* IRQ has gone through suspend sequence */
    #define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */
    #define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */
    +#define IRQ_FORCE_SUSPEND 0x20000000 /* Ignore IRQF_NO_SUSPEND */

    #define IRQF_MODIFY_MASK \
    (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
    - IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL)
    + IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL \
    + IRQ_FORCE_SUSPEND)

    #ifdef CONFIG_IRQ_PER_CPU
    # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
    Index: linux-next/kernel/irq/manage.c
    ===================================================================
    --- linux-next.orig/kernel/irq/manage.c
    +++ linux-next/kernel/irq/manage.c
    @@ -359,8 +359,17 @@ EXPORT_SYMBOL(disable_irq);

    void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
    {
    - if (resume)
    + if (resume) {
    + if (!(desc->status & IRQ_SUSPENDED)) {
    + if (!desc->action)
    + return;
    + if (!(desc->action->flags & IRQF_FORCE_RESUME))
    + return;
    + /* Pretend that it got disabled ! */
    + desc->depth++;
    + }
    desc->status &= ~IRQ_SUSPENDED;
    + }

    switch (desc->depth) {
    case 0:
    Index: linux-next/kernel/irq/pm.c
    ===================================================================
    --- linux-next.orig/kernel/irq/pm.c
    +++ linux-next/kernel/irq/pm.c
    @@ -53,9 +53,6 @@ void resume_device_irqs(void)
    for_each_irq_desc(irq, desc) {
    unsigned long flags;

    - if (!(desc->status & IRQ_SUSPENDED))
    - continue;
    -
    raw_spin_lock_irqsave(&desc->lock, flags);
    __enable_irq(desc, irq, true);
    raw_spin_unlock_irqrestore(&desc->lock, flags);



    \
     
     \ /
      Last update: 2011-02-05 21:11    [W:0.028 / U:239.484 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site