diff options
Diffstat (limited to 'arch/powerpc/platforms/cell')
-rw-r--r-- | arch/powerpc/platforms/cell/interrupt.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spider-pic.c | 70 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 6 |
3 files changed, 45 insertions, 35 deletions
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 9d5da7896892..d7bbb61109f9 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -159,7 +159,7 @@ static void iic_request_ipi(int ipi, const char *name) if (iic_hosts[node] == NULL) continue; virq = irq_create_mapping(iic_hosts[node], - iic_ipi_to_irq(ipi), 0); + iic_ipi_to_irq(ipi)); if (virq == NO_IRQ) { printk(KERN_ERR "iic: failed to map IPI %s on node %d\n", @@ -197,7 +197,7 @@ static int iic_host_match(struct irq_host *h, struct device_node *node) } static int iic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw, unsigned int flags) + irq_hw_number_t hw) { if (hw < IIC_IRQ_IPI0) set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index ae7ef88f1a37..15217bb0402f 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -85,9 +85,6 @@ static void spider_unmask_irq(unsigned int virq) struct spider_pic *pic = spider_virq_to_pic(virq); void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); - /* We use no locking as we should be covered by the descriptor lock - * for access to invidual source configuration registers - */ out_be32(cfg, in_be32(cfg) | 0x30000000u); } @@ -96,9 +93,6 @@ static void spider_mask_irq(unsigned int virq) struct spider_pic *pic = spider_virq_to_pic(virq); void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); - /* We use no locking as we should be covered by the descriptor lock - * for access to invidual source configuration registers - */ out_be32(cfg, in_be32(cfg) & ~0x30000000u); } @@ -120,26 +114,14 @@ static void spider_ack_irq(unsigned int virq) out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf)); } -static struct irq_chip spider_pic = { - .typename = " SPIDER ", - .unmask = spider_unmask_irq, - .mask = spider_mask_irq, - .ack = spider_ack_irq, -}; - -static int spider_host_match(struct irq_host *h, struct device_node *node) -{ - struct spider_pic *pic = h->host_data; - return node == pic->of_node; -} - -static int spider_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw, unsigned int flags) +static int spider_set_irq_type(unsigned int virq, unsigned int type) { - unsigned int sense = flags & IRQ_TYPE_SENSE_MASK; - struct spider_pic *pic = h->host_data; + unsigned int sense = type & IRQ_TYPE_SENSE_MASK; + struct spider_pic *pic = spider_virq_to_pic(virq); + unsigned int hw = irq_map[virq].hwirq; void __iomem *cfg = spider_get_irq_config(pic, hw); - int level = 0; + struct irq_desc *desc = get_irq_desc(virq); + u32 old_mask; u32 ic; /* Note that only level high is supported for most interrupts */ @@ -157,29 +139,57 @@ static int spider_host_map(struct irq_host *h, unsigned int virq, break; case IRQ_TYPE_LEVEL_LOW: ic = 0x0; - level = 1; break; case IRQ_TYPE_LEVEL_HIGH: case IRQ_TYPE_NONE: ic = 0x1; - level = 1; break; default: return -EINVAL; } + /* Update irq_desc */ + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= type & IRQ_TYPE_SENSE_MASK; + if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + /* Configure the source. One gross hack that was there before and * that I've kept around is the priority to the BE which I set to * be the same as the interrupt source number. I don't know wether * that's supposed to make any kind of sense however, we'll have to * decide that, but for now, I'm not changing the behaviour. */ - out_be32(cfg, (ic << 24) | (0x7 << 16) | (pic->node_id << 4) | 0xe); + old_mask = in_be32(cfg) & 0x30000000u; + out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) | + (pic->node_id << 4) | 0xe); out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff)); - if (level) - get_irq_desc(virq)->status |= IRQ_LEVEL; + return 0; +} + +static struct irq_chip spider_pic = { + .typename = " SPIDER ", + .unmask = spider_unmask_irq, + .mask = spider_mask_irq, + .ack = spider_ack_irq, + .set_type = spider_set_irq_type, +}; + +static int spider_host_match(struct irq_host *h, struct device_node *node) +{ + struct spider_pic *pic = h->host_data; + return node == pic->of_node; +} + +static int spider_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); + + /* Set default irq type */ + set_irq_type(virq, IRQ_TYPE_NONE); + return 0; } @@ -283,7 +293,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) if (iic_host == NULL) return NO_IRQ; /* Manufacture an IIC interrupt number of class 2 */ - virq = irq_create_mapping(iic_host, 0x20 | unit, 0); + virq = irq_create_mapping(iic_host, 0x20 | unit); if (virq == NO_IRQ) printk(KERN_ERR "spider_pic: failed to map cascade !"); return virq; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 5d2313a6c82b..d06042deb021 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -583,9 +583,9 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) spu->isrc = isrc = tmp[0]; /* Now map interrupts of all 3 classes */ - spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc, 0); - spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc, 0); - spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc, 0); + spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc); + spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc); + spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc); /* Right now, we only fail if class 2 failed */ return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; |