Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/renesas-irqc: Move over to nested generic chip

Convert the IRQC driver to rely on GENERIC_IRQ_CHIP and
set IRQ_GC_INIT_NESTED_LOCK to enable nested locking.

Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
Cc: jason@lakedaemon.net
Cc: geert+renesas@glider.be
Cc: horms@verge.net.au
Cc: Magnus Damm <magnus.damm@gmail.com>
Link: http://lkml.kernel.org/r/20150928094237.32552.83434.sendpatchset@little-apple
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Magnus Damm and committed by
Thomas Gleixner
99c221df e7dbe2da

+31 -56
+1
drivers/irqchip/Kconfig
··· 123 123 124 124 config RENESAS_IRQC 125 125 bool 126 + select GENERIC_IRQ_CHIP 126 127 select IRQ_DOMAIN 127 128 128 129 config ST_IRQCHIP
+30 -56
drivers/irqchip/irq-renesas-irqc.c
··· 62 62 struct irqc_irq irq[IRQC_IRQ_MAX]; 63 63 unsigned int number_of_irqs; 64 64 struct platform_device *pdev; 65 - struct irq_chip irq_chip; 65 + struct irq_chip_generic *gc; 66 66 struct irq_domain *irq_domain; 67 67 struct clk *clk; 68 68 }; 69 + 70 + static struct irqc_priv *irq_data_to_priv(struct irq_data *data) 71 + { 72 + return data->domain->host_data; 73 + } 69 74 70 75 static void irqc_dbg(struct irqc_irq *i, char *str) 71 76 { 72 77 dev_dbg(&i->p->pdev->dev, "%s (%d:%d)\n", 73 78 str, i->requested_irq, i->hw_irq); 74 - } 75 - 76 - static void irqc_irq_enable(struct irq_data *d) 77 - { 78 - struct irqc_priv *p = irq_data_get_irq_chip_data(d); 79 - int hw_irq = irqd_to_hwirq(d); 80 - 81 - irqc_dbg(&p->irq[hw_irq], "enable"); 82 - iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_SET); 83 - } 84 - 85 - static void irqc_irq_disable(struct irq_data *d) 86 - { 87 - struct irqc_priv *p = irq_data_get_irq_chip_data(d); 88 - int hw_irq = irqd_to_hwirq(d); 89 - 90 - irqc_dbg(&p->irq[hw_irq], "disable"); 91 - iowrite32(BIT(hw_irq), p->cpu_int_base + IRQC_EN_STS); 92 79 } 93 80 94 81 static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { ··· 88 101 89 102 static int irqc_irq_set_type(struct irq_data *d, unsigned int type) 90 103 { 91 - struct irqc_priv *p = irq_data_get_irq_chip_data(d); 104 + struct irqc_priv *p = irq_data_to_priv(d); 92 105 int hw_irq = irqd_to_hwirq(d); 93 106 unsigned char value = irqc_sense[type & IRQ_TYPE_SENSE_MASK]; 94 107 u32 tmp; ··· 107 120 108 121 static int irqc_irq_set_wake(struct irq_data *d, unsigned int on) 109 122 { 110 - struct irqc_priv *p = irq_data_get_irq_chip_data(d); 123 + struct irqc_priv *p = irq_data_to_priv(d); 111 124 int hw_irq = irqd_to_hwirq(d); 112 125 113 126 irq_set_irq_wake(p->irq[hw_irq].requested_irq, on); ··· 140 153 return IRQ_NONE; 141 154 } 142 155 143 - /* 144 - * This lock class tells lockdep that IRQC irqs are in a different 145 - * category than their parents, so it won't report false recursion. 146 - */ 147 - static struct lock_class_key irqc_irq_lock_class; 148 - 149 - static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, 150 - irq_hw_number_t hw) 151 - { 152 - struct irqc_priv *p = h->host_data; 153 - 154 - irqc_dbg(&p->irq[hw], "map"); 155 - irq_set_chip_data(virq, h->host_data); 156 - irq_set_lockdep_class(virq, &irqc_irq_lock_class); 157 - irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); 158 - return 0; 159 - } 160 - 161 - static const struct irq_domain_ops irqc_irq_domain_ops = { 162 - .map = irqc_irq_domain_map, 163 - .xlate = irq_domain_xlate_twocell, 164 - }; 165 - 166 156 static int irqc_probe(struct platform_device *pdev) 167 157 { 168 158 struct irqc_priv *p; 169 159 struct resource *io; 170 160 struct resource *irq; 171 - struct irq_chip *irq_chip; 172 161 const char *name = dev_name(&pdev->dev); 173 162 int ret; 174 163 int k; ··· 204 241 205 242 p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */ 206 243 207 - irq_chip = &p->irq_chip; 208 - irq_chip->name = name; 209 - irq_chip->irq_mask = irqc_irq_disable; 210 - irq_chip->irq_unmask = irqc_irq_enable; 211 - irq_chip->irq_set_type = irqc_irq_set_type; 212 - irq_chip->irq_set_wake = irqc_irq_set_wake; 213 - irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; 214 - 215 244 p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 216 245 p->number_of_irqs, 217 - &irqc_irq_domain_ops, p); 246 + &irq_generic_chip_ops, p); 218 247 if (!p->irq_domain) { 219 248 ret = -ENXIO; 220 249 dev_err(&pdev->dev, "cannot initialize irq domain\n"); 221 250 goto err2; 222 251 } 252 + 253 + ret = irq_alloc_domain_generic_chips(p->irq_domain, p->number_of_irqs, 254 + 1, name, handle_level_irq, 255 + 0, 0, IRQ_GC_INIT_NESTED_LOCK); 256 + if (ret) { 257 + dev_err(&pdev->dev, "cannot allocate generic chip\n"); 258 + goto err3; 259 + } 260 + 261 + p->gc = irq_get_domain_generic_chip(p->irq_domain, 0); 262 + p->gc->reg_base = p->cpu_int_base; 263 + p->gc->chip_types[0].regs.enable = IRQC_EN_SET; 264 + p->gc->chip_types[0].regs.disable = IRQC_EN_STS; 265 + p->gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; 266 + p->gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; 267 + p->gc->chip_types[0].chip.irq_set_type = irqc_irq_set_type; 268 + p->gc->chip_types[0].chip.irq_set_wake = irqc_irq_set_wake; 269 + p->gc->chip_types[0].chip.flags = IRQCHIP_MASK_ON_SUSPEND; 223 270 224 271 /* request interrupts one by one */ 225 272 for (k = 0; k < p->number_of_irqs; k++) { ··· 237 264 0, name, &p->irq[k])) { 238 265 dev_err(&pdev->dev, "failed to request IRQ\n"); 239 266 ret = -ENOENT; 240 - goto err3; 267 + goto err4; 241 268 } 242 269 } 243 270 244 271 dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); 245 272 246 273 return 0; 247 - err3: 274 + err4: 248 275 while (--k >= 0) 249 276 free_irq(p->irq[k].requested_irq, &p->irq[k]); 250 277 278 + err3: 251 279 irq_domain_remove(p->irq_domain); 252 280 err2: 253 281 iounmap(p->iomem);