diff options
Diffstat (limited to 'arch/powerpc/sysdev/uic.c')
| -rw-r--r-- | arch/powerpc/sysdev/uic.c | 137 |
1 files changed, 57 insertions, 80 deletions
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 6f220a913e4..92033936a8f 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c @@ -18,7 +18,6 @@ #include <linux/stddef.h> #include <linux/sched.h> #include <linux/signal.h> -#include <linux/sysdev.h> #include <linux/device.h> #include <linux/bootmem.h> #include <linux/spinlock.h> @@ -41,74 +40,70 @@ #define UIC_VR 0x7 #define UIC_VCR 0x8 -#define uic_irq_to_hw(virq) (irq_map[virq].hwirq) - struct uic *primary_uic; struct uic { int index; int dcrbase; - spinlock_t lock; + raw_spinlock_t lock; /* The remapper for this UIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; }; -static void uic_unmask_irq(unsigned int virq) +static void uic_unmask_irq(struct irq_data *d) { - struct irq_desc *desc = irq_to_desc(virq); - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); + struct uic *uic = irq_data_get_irq_chip_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; u32 er, sr; sr = 1 << (31-src); - spin_lock_irqsave(&uic->lock, flags); + raw_spin_lock_irqsave(&uic->lock, flags); /* ack level-triggered interrupts here */ - if (desc->status & IRQ_LEVEL) + if (irqd_is_level_type(d)) mtdcr(uic->dcrbase + UIC_SR, sr); er = mfdcr(uic->dcrbase + UIC_ER); er |= sr; mtdcr(uic->dcrbase + UIC_ER, er); - spin_unlock_irqrestore(&uic->lock, flags); + raw_spin_unlock_irqrestore(&uic->lock, flags); } -static void uic_mask_irq(unsigned int virq) +static void uic_mask_irq(struct irq_data *d) { - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); + struct uic *uic = irq_data_get_irq_chip_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; u32 er; - spin_lock_irqsave(&uic->lock, flags); + raw_spin_lock_irqsave(&uic->lock, flags); er = mfdcr(uic->dcrbase + UIC_ER); er &= ~(1 << (31 - src)); mtdcr(uic->dcrbase + UIC_ER, er); - spin_unlock_irqrestore(&uic->lock, flags); + raw_spin_unlock_irqrestore(&uic->lock, flags); } -static void uic_ack_irq(unsigned int virq) +static void uic_ack_irq(struct irq_data *d) { - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); + struct uic *uic = irq_data_get_irq_chip_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; - spin_lock_irqsave(&uic->lock, flags); + raw_spin_lock_irqsave(&uic->lock, flags); mtdcr(uic->dcrbase + UIC_SR, 1 << (31-src)); - spin_unlock_irqrestore(&uic->lock, flags); + raw_spin_unlock_irqrestore(&uic->lock, flags); } -static void uic_mask_ack_irq(unsigned int virq) +static void uic_mask_ack_irq(struct irq_data *d) { - struct irq_desc *desc = irq_to_desc(virq); - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); + struct uic *uic = irq_data_get_irq_chip_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; u32 er, sr; sr = 1 << (31-src); - spin_lock_irqsave(&uic->lock, flags); + raw_spin_lock_irqsave(&uic->lock, flags); er = mfdcr(uic->dcrbase + UIC_ER); er &= ~sr; mtdcr(uic->dcrbase + UIC_ER, er); @@ -120,23 +115,22 @@ static void uic_mask_ack_irq(unsigned int virq) * level interrupts are ack'ed after the actual * isr call in the uic_unmask_irq() */ - if (!(desc->status & IRQ_LEVEL)) + if (!irqd_is_level_type(d)) mtdcr(uic->dcrbase + UIC_SR, sr); - spin_unlock_irqrestore(&uic->lock, flags); + raw_spin_unlock_irqrestore(&uic->lock, flags); } -static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) +static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type) { - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); - struct irq_desc *desc = irq_to_desc(virq); + struct uic *uic = irq_data_get_irq_chip_data(d); + unsigned int src = irqd_to_hwirq(d); unsigned long flags; int trigger, polarity; u32 tr, pr, mask; switch (flow_type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_NONE: - uic_mask_irq(virq); + uic_mask_irq(d); return 0; case IRQ_TYPE_EDGE_RISING: @@ -157,7 +151,7 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) mask = ~(1 << (31 - src)); - spin_lock_irqsave(&uic->lock, flags); + raw_spin_lock_irqsave(&uic->lock, flags); tr = mfdcr(uic->dcrbase + UIC_TR); pr = mfdcr(uic->dcrbase + UIC_PR); tr = (tr & mask) | (trigger << (31-src)); @@ -166,70 +160,55 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) mtdcr(uic->dcrbase + UIC_PR, pr); mtdcr(uic->dcrbase + UIC_TR, tr); - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; - if (!trigger) - desc->status |= IRQ_LEVEL; - - spin_unlock_irqrestore(&uic->lock, flags); + raw_spin_unlock_irqrestore(&uic->lock, flags); return 0; } static struct irq_chip uic_irq_chip = { - .name = " UIC ", - .unmask = uic_unmask_irq, - .mask = uic_mask_irq, - .mask_ack = uic_mask_ack_irq, - .ack = uic_ack_irq, - .set_type = uic_set_irq_type, + .name = "UIC", + .irq_unmask = uic_unmask_irq, + .irq_mask = uic_mask_irq, + .irq_mask_ack = uic_mask_ack_irq, + .irq_ack = uic_ack_irq, + .irq_set_type = uic_set_irq_type, }; -static int uic_host_map(struct irq_host *h, unsigned int virq, +static int uic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct uic *uic = h->host_data; - set_irq_chip_data(virq, uic); + irq_set_chip_data(virq, uic); /* Despite the name, handle_level_irq() works for both level * and edge irqs on UIC. FIXME: check this is correct */ - set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); + irq_set_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); /* Set default irq type */ - set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; -} - -static int uic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) + irq_set_irq_type(virq, IRQ_TYPE_NONE); -{ - /* UIC intspecs must have 2 cells */ - BUG_ON(intsize != 2); - *out_hwirq = intspec[0]; - *out_type = intspec[1]; return 0; } -static struct irq_host_ops uic_host_ops = { +static struct irq_domain_ops uic_host_ops = { .map = uic_host_map, - .xlate = uic_host_xlate, + .xlate = irq_domain_xlate_twocell, }; void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) { - struct uic *uic = get_irq_data(virq); + struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_data *idata = irq_desc_get_irq_data(desc); + struct uic *uic = irq_get_handler_data(virq); u32 msr; int src; int subvirq; raw_spin_lock(&desc->lock); - if (desc->status & IRQ_LEVEL) - desc->chip->mask(virq); + if (irqd_is_level_type(idata)) + chip->irq_mask(idata); else - desc->chip->mask_ack(virq); + chip->irq_mask_ack(idata); raw_spin_unlock(&desc->lock); msr = mfdcr(uic->dcrbase + UIC_MSR); @@ -243,10 +222,10 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) uic_irq_ret: raw_spin_lock(&desc->lock); - if (desc->status & IRQ_LEVEL) - desc->chip->ack(virq); - if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) - desc->chip->unmask(virq); + if (irqd_is_level_type(idata)) + chip->irq_ack(idata); + if (!irqd_irq_disabled(idata) && chip->irq_unmask) + chip->irq_unmask(idata); raw_spin_unlock(&desc->lock); } @@ -262,7 +241,7 @@ static struct uic * __init uic_init_one(struct device_node *node) if (! uic) return NULL; /* FIXME: panic? */ - spin_lock_init(&uic->lock); + raw_spin_lock_init(&uic->lock); indexp = of_get_property(node, "cell-index", &len); if (!indexp || (len != sizeof(u32))) { printk(KERN_ERR "uic: Device node %s has missing or invalid " @@ -279,13 +258,11 @@ static struct uic * __init uic_init_one(struct device_node *node) } uic->dcrbase = *dcrreg; - uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - NR_UIC_INTS, &uic_host_ops, -1); + uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops, + uic); if (! uic->irqhost) return NULL; /* FIXME: panic? */ - uic->irqhost->host_data = uic; - /* Start with all interrupts disabled, level and non-critical */ mtdcr(uic->dcrbase + UIC_ER, 0); mtdcr(uic->dcrbase + UIC_CR, 0); @@ -335,8 +312,8 @@ void __init uic_init_tree(void) cascade_virq = irq_of_parse_and_map(np, 0); - set_irq_data(cascade_virq, uic); - set_irq_chained_handler(cascade_virq, uic_irq_cascade); + irq_set_handler_data(cascade_virq, uic); + irq_set_chained_handler(cascade_virq, uic_irq_cascade); /* FIXME: setup critical cascade?? */ } |
