#define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */
#define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */
#define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */
- #define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */
+ #define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */
+ #define IRQ_AFFINITY_SET 0x02000000 /* IRQ affinity was set from userspace*/
#ifdef CONFIG_IRQ_PER_CPU
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
const char *typename;
};
+ ++struct timer_rand_state;
+ ++struct irq_2_iommu;
/**
* struct irq_desc - interrupt descriptor
- *
+ * @irq: interrupt number for this descriptor
+ ++ * @timer_rand_state: pointer to timer rand state struct
+ ++ * @kstat_irqs: irq stats per cpu
+ ++ * @irq_2_iommu: iommu with this irq
* @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
* @chip: low level interrupt hardware access
* @msi_desc: MSI descriptor
* @depth: disable-depth, for nested irq_disable() calls
* @wake_depth: enable depth, for multiple set_irq_wake() callers
* @irq_count: stats field to detect stalled irqs
--- * @irqs_unhandled: stats field for spurious unhandled interrupts
* @last_unhandled: aging timer for unhandled count
+++ * @irqs_unhandled: stats field for spurious unhandled interrupts
* @lock: locking for SMP
* @affinity: IRQ affinity on SMP
* @cpu: cpu index useful for balancing
* @pending_mask: pending rebalanced interrupts
* @dir: /proc/irq/ procfs entry
- * @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
unsigned int irq;
+ ++#ifdef CONFIG_SPARSE_IRQ
+ ++ struct timer_rand_state *timer_rand_state;
+ ++ unsigned int *kstat_irqs;
+ ++# ifdef CONFIG_INTR_REMAP
+ ++ struct irq_2_iommu *irq_2_iommu;
+ ++# endif
+ ++#endif
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
--- unsigned int irqs_unhandled;
unsigned long last_unhandled; /* Aging timer for unhandled count */
+++ unsigned int irqs_unhandled;
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_t affinity;
const char *name;
} ____cacheline_internodealigned_in_smp;
+ ++extern void early_irq_init(void);
+ ++extern void arch_early_irq_init(void);
+ ++extern void arch_init_chip_data(struct irq_desc *desc, int cpu);
+ ++extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
+ ++ struct irq_desc *desc, int cpu);
+ ++extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
+ ++#ifndef CONFIG_SPARSE_IRQ
extern struct irq_desc irq_desc[NR_IRQS];
static inline struct irq_desc *irq_to_desc(unsigned int irq)
{
- -- return (irq < nr_irqs) ? irq_desc + irq : NULL;
+ ++ return (irq < NR_IRQS) ? irq_desc + irq : NULL;
+ ++}
+ ++static inline struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
+ ++{
+ ++ return irq_to_desc(irq);
+ ++}
+ ++
+ ++#else
+ ++
+ ++extern struct irq_desc *irq_to_desc(unsigned int irq);
+ ++extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
+ ++extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
+ ++
+ ++# define for_each_irq_desc(irq, desc) \
+ ++ for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; irq++, desc = irq_to_desc(irq))
+ ++# define for_each_irq_desc_reverse(irq, desc) \
+ ++ for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; irq--, desc = irq_to_desc(irq))
+ ++
+ ++#define kstat_irqs_this_cpu(DESC) \
+ ++ ((DESC)->kstat_irqs[smp_processor_id()])
+ ++#define kstat_incr_irqs_this_cpu(irqno, DESC) \
+ ++ ((DESC)->kstat_irqs[smp_processor_id()]++)
+ ++
+ ++#endif
+ ++
+ ++static inline struct irq_desc *
+ ++irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
+ ++{
+ ++#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
+ ++ return irq_to_desc(irq);
+ ++#else
+ ++ return desc;
+ ++#endif
}
/*
#ifdef CONFIG_GENERIC_PENDING_IRQ
- void set_pending_irq(unsigned int irq, cpumask_t mask);
void move_native_irq(int irq);
void move_masked_irq(int irq);
{
}
- static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
- {
- }
-
#endif /* CONFIG_GENERIC_PENDING_IRQ */
#else /* CONFIG_SMP */
#define get_irq_data(irq) (irq_to_desc(irq)->handler_data)
#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc)
+ ++#define get_irq_desc_chip(desc) ((desc)->chip)
+ ++#define get_irq_desc_chip_data(desc) ((desc)->chip_data)
+ ++#define get_irq_desc_data(desc) ((desc)->handler_data)
+ ++#define get_irq_desc_msi(desc) ((desc)->msi_desc)
+ ++
#endif /* CONFIG_GENERIC_HARDIRQS */
#endif /* !CONFIG_S390 */
*/
void dynamic_irq_init(unsigned int irq)
{
- -- struct irq_desc *desc = irq_to_desc(irq);
+ ++ struct irq_desc *desc;
unsigned long flags;
+ ++ desc = irq_to_desc(irq);
if (!desc) {
WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
return;
return -ENODEV;
}
++ + type &= IRQ_TYPE_SENSE_MASK;
if (type == IRQ_TYPE_NONE)
return 0;
spin_lock(&desc->lock);
mask_ack_irq(desc, irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
desc->status &= ~IRQ_INPROGRESS;
out:
desc->chip->eoi(irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
spin_unlock(&desc->lock);
}
!desc->action)) {
desc->status |= (IRQ_PENDING | IRQ_MASKED);
mask_ack_irq(desc, irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
goto out_unlock;
}
kstat_incr_irqs_this_cpu(irq, desc);
/* Start handling the irq */
desc->chip->ack(irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
/* Mark the IRQ currently in progress.*/
desc->status |= IRQ_INPROGRESS;
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
- -- if (desc->chip->eoi)
+ ++ if (desc->chip->eoi) {
desc->chip->eoi(irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
+ ++ }
}
void
/* Uninstall? */
if (handle == handle_bad_irq) {
- -- if (desc->chip != &no_irq_chip)
+ ++ if (desc->chip != &no_irq_chip) {
mask_ack_irq(desc, irq);
+ ++ desc = irq_remap_to_desc(irq, desc);
+ ++ }
desc->status |= IRQ_DISABLED;
desc->depth = 1;
}