aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tbogendoerfer@suse.de>2019-05-07 17:09:15 -0400
committerPaul Burton <paul.burton@mips.com>2019-05-09 19:48:20 -0400
commite6308b6d35ea706c23a589a8c709fa444ff13e17 (patch)
tree12679cc0d20fe704547ff21e047a26e96be1bb1a
parenta57140e9a850582ddafdd8f115b78713baaf0d00 (diff)
MIPS: SGI-IP27: abstract chipset irq from bridge
Bridge ASIC is widely used in different SGI systems, but the connected chipset is either HUB, HEART or BEDROCK. This commit switches to irq domain hierarchy for hub and bridge interrupts to get bridge setup out of hub interrupt code. Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de> [paul.burton@mips.com: Resolve conflict with commit 69a07a41d908 ("MIPS: SGI-IP27: rework HUB interrupts").] Signed-off-by: Paul Burton <paul.burton@mips.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <jhogan@kernel.org> Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/include/asm/pci/bridge.h3
-rw-r--r--arch/mips/include/asm/sn/irq_alloc.h11
-rw-r--r--arch/mips/pci/pci-xtalk-bridge.c178
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c191
5 files changed, 265 insertions, 119 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0e7a48598b26..d6406c176048 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -675,6 +675,7 @@ config SGI_IP27
675 select SYS_HAS_EARLY_PRINTK 675 select SYS_HAS_EARLY_PRINTK
676 select HAVE_PCI 676 select HAVE_PCI
677 select IRQ_MIPS_CPU 677 select IRQ_MIPS_CPU
678 select IRQ_DOMAIN_HIERARCHY
678 select NR_CPUS_DEFAULT_64 679 select NR_CPUS_DEFAULT_64
679 select PCI_DRIVERS_GENERIC 680 select PCI_DRIVERS_GENERIC
680 select PCI_XTALK_BRIDGE 681 select PCI_XTALK_BRIDGE
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index d42b27c97c23..a92cd30b48c9 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -805,6 +805,7 @@ struct bridge_controller {
805 struct bridge_regs *base; 805 struct bridge_regs *base;
806 unsigned long baddr; 806 unsigned long baddr;
807 unsigned long intr_addr; 807 unsigned long intr_addr;
808 struct irq_domain *domain;
808 unsigned int pci_int[8]; 809 unsigned int pci_int[8];
809 nasid_t nasid; 810 nasid_t nasid;
810}; 811};
@@ -819,6 +820,4 @@ struct bridge_controller {
819#define bridge_clr(bc, reg, val) \ 820#define bridge_clr(bc, reg, val) \
820 __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg) 821 __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)
821 822
822extern int request_bridge_irq(struct bridge_controller *bc, int pin);
823
824#endif /* _ASM_PCI_BRIDGE_H */ 823#endif /* _ASM_PCI_BRIDGE_H */
diff --git a/arch/mips/include/asm/sn/irq_alloc.h b/arch/mips/include/asm/sn/irq_alloc.h
new file mode 100644
index 000000000000..09b89cecff56
--- /dev/null
+++ b/arch/mips/include/asm/sn/irq_alloc.h
@@ -0,0 +1,11 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_SN_IRQ_ALLOC_H
3#define __ASM_SN_IRQ_ALLOC_H
4
5struct irq_alloc_info {
6 void *ctrl;
7 nasid_t nasid;
8 int pin;
9};
10
11#endif /* __ASM_SN_IRQ_ALLOC_H */
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index 8f481984ab6e..bcf7f559789a 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -14,7 +14,7 @@
14 14
15#include <asm/pci/bridge.h> 15#include <asm/pci/bridge.h>
16#include <asm/paccess.h> 16#include <asm/paccess.h>
17#include <asm/sn/intr.h> 17#include <asm/sn/irq_alloc.h>
18 18
19/* 19/*
20 * Most of the IOC3 PCI config register aren't present 20 * Most of the IOC3 PCI config register aren't present
@@ -310,6 +310,135 @@ static struct pci_ops bridge_pci_ops = {
310 .write = pci_write_config, 310 .write = pci_write_config,
311}; 311};
312 312
313struct bridge_irq_chip_data {
314 struct bridge_controller *bc;
315 nasid_t nasid;
316};
317
318static int bridge_set_affinity(struct irq_data *d, const struct cpumask *mask,
319 bool force)
320{
321#ifdef CONFIG_NUMA
322 struct bridge_irq_chip_data *data = d->chip_data;
323 int bit = d->parent_data->hwirq;
324 int pin = d->hwirq;
325 nasid_t nasid;
326 int ret, cpu;
327
328 ret = irq_chip_set_affinity_parent(d, mask, force);
329 if (ret >= 0) {
330 cpu = cpumask_first_and(mask, cpu_online_mask);
331 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
332 bridge_write(data->bc, b_int_addr[pin].addr,
333 (((data->bc->intr_addr >> 30) & 0x30000) |
334 bit | (nasid << 8)));
335 bridge_read(data->bc, b_wid_tflush);
336 }
337 return ret;
338#else
339 return irq_chip_set_affinity_parent(d, mask, force);
340#endif
341}
342
343struct irq_chip bridge_irq_chip = {
344 .name = "BRIDGE",
345 .irq_mask = irq_chip_mask_parent,
346 .irq_unmask = irq_chip_unmask_parent,
347 .irq_set_affinity = bridge_set_affinity
348};
349
350static int bridge_domain_alloc(struct irq_domain *domain, unsigned int virq,
351 unsigned int nr_irqs, void *arg)
352{
353 struct bridge_irq_chip_data *data;
354 struct irq_alloc_info *info = arg;
355 int ret;
356
357 if (nr_irqs > 1 || !info)
358 return -EINVAL;
359
360 data = kzalloc(sizeof(*data), GFP_KERNEL);
361 if (!data)
362 return -ENOMEM;
363
364 ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
365 if (ret >= 0) {
366 data->bc = info->ctrl;
367 data->nasid = info->nasid;
368 irq_domain_set_info(domain, virq, info->pin, &bridge_irq_chip,
369 data, handle_level_irq, NULL, NULL);
370 } else {
371 kfree(data);
372 }
373
374 return ret;
375}
376
377static void bridge_domain_free(struct irq_domain *domain, unsigned int virq,
378 unsigned int nr_irqs)
379{
380 struct irq_data *irqd = irq_domain_get_irq_data(domain, virq);
381
382 if (nr_irqs)
383 return;
384
385 kfree(irqd->chip_data);
386 irq_domain_free_irqs_top(domain, virq, nr_irqs);
387}
388
389static int bridge_domain_activate(struct irq_domain *domain,
390 struct irq_data *irqd, bool reserve)
391{
392 struct bridge_irq_chip_data *data = irqd->chip_data;
393 struct bridge_controller *bc = data->bc;
394 int bit = irqd->parent_data->hwirq;
395 int pin = irqd->hwirq;
396 u32 device;
397
398 bridge_write(bc, b_int_addr[pin].addr,
399 (((bc->intr_addr >> 30) & 0x30000) |
400 bit | (data->nasid << 8)));
401 bridge_set(bc, b_int_enable, (1 << pin));
402 bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
403
404 /*
405 * Enable sending of an interrupt clear packt to the hub on a high to
406 * low transition of the interrupt pin.
407 *
408 * IRIX sets additional bits in the address which are documented as
409 * reserved in the bridge docs.
410 */
411 bridge_set(bc, b_int_mode, (1UL << pin));
412
413 /*
414 * We assume the bridge to have a 1:1 mapping between devices
415 * (slots) and intr pins.
416 */
417 device = bridge_read(bc, b_int_device);
418 device &= ~(7 << (pin*3));
419 device |= (pin << (pin*3));
420 bridge_write(bc, b_int_device, device);
421
422 bridge_read(bc, b_wid_tflush);
423 return 0;
424}
425
426static void bridge_domain_deactivate(struct irq_domain *domain,
427 struct irq_data *irqd)
428{
429 struct bridge_irq_chip_data *data = irqd->chip_data;
430
431 bridge_clr(data->bc, b_int_enable, (1 << irqd->hwirq));
432 bridge_read(data->bc, b_wid_tflush);
433}
434
435static const struct irq_domain_ops bridge_domain_ops = {
436 .alloc = bridge_domain_alloc,
437 .free = bridge_domain_free,
438 .activate = bridge_domain_activate,
439 .deactivate = bridge_domain_deactivate
440};
441
313/* 442/*
314 * All observed requests have pin == 1. We could have a global here, that 443 * All observed requests have pin == 1. We could have a global here, that
315 * gets incremented and returned every time - unfortunately, pci_map_irq 444 * gets incremented and returned every time - unfortunately, pci_map_irq
@@ -322,11 +451,16 @@ static struct pci_ops bridge_pci_ops = {
322static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 451static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
323{ 452{
324 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); 453 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
454 struct irq_alloc_info info;
325 int irq; 455 int irq;
326 456
327 irq = bc->pci_int[slot]; 457 irq = bc->pci_int[slot];
328 if (irq == -1) { 458 if (irq == -1) {
329 irq = request_bridge_irq(bc, slot); 459 info.ctrl = bc;
460 info.nasid = bc->nasid;
461 info.pin = slot;
462
463 irq = irq_domain_alloc_irqs(bc->domain, 1, bc->nasid, &info);
330 if (irq < 0) 464 if (irq < 0)
331 return irq; 465 return irq;
332 466
@@ -337,18 +471,34 @@ static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
337 471
338static int bridge_probe(struct platform_device *pdev) 472static int bridge_probe(struct platform_device *pdev)
339{ 473{
474 struct xtalk_bridge_platform_data *bd = dev_get_platdata(&pdev->dev);
340 struct device *dev = &pdev->dev; 475 struct device *dev = &pdev->dev;
341 struct bridge_controller *bc; 476 struct bridge_controller *bc;
342 struct pci_host_bridge *host; 477 struct pci_host_bridge *host;
478 struct irq_domain *domain, *parent;
479 struct fwnode_handle *fn;
343 int slot; 480 int slot;
344 int err; 481 int err;
345 struct xtalk_bridge_platform_data *bd = dev_get_platdata(&pdev->dev); 482
483 parent = irq_get_default_host();
484 if (!parent)
485 return -ENODEV;
486 fn = irq_domain_alloc_named_fwnode("BRIDGE");
487 if (!fn)
488 return -ENOMEM;
489 domain = irq_domain_create_hierarchy(parent, 0, 8, fn,
490 &bridge_domain_ops, NULL);
491 irq_domain_free_fwnode(fn);
492 if (!domain)
493 return -ENOMEM;
346 494
347 pci_set_flags(PCI_PROBE_ONLY); 495 pci_set_flags(PCI_PROBE_ONLY);
348 496
349 host = devm_pci_alloc_host_bridge(dev, sizeof(*bc)); 497 host = devm_pci_alloc_host_bridge(dev, sizeof(*bc));
350 if (!host) 498 if (!host) {
351 return -ENOMEM; 499 err = -ENOMEM;
500 goto err_remove_domain;
501 }
352 502
353 bc = pci_host_bridge_priv(host); 503 bc = pci_host_bridge_priv(host);
354 504
@@ -357,15 +507,15 @@ static int bridge_probe(struct platform_device *pdev)
357 bc->busn.end = 0xff; 507 bc->busn.end = 0xff;
358 bc->busn.flags = IORESOURCE_BUS; 508 bc->busn.flags = IORESOURCE_BUS;
359 509
510 bc->domain = domain;
511
360 pci_add_resource_offset(&host->windows, &bd->mem, bd->mem_offset); 512 pci_add_resource_offset(&host->windows, &bd->mem, bd->mem_offset);
361 pci_add_resource_offset(&host->windows, &bd->io, bd->io_offset); 513 pci_add_resource_offset(&host->windows, &bd->io, bd->io_offset);
362 pci_add_resource(&host->windows, &bc->busn); 514 pci_add_resource(&host->windows, &bc->busn);
363 515
364 err = devm_request_pci_bus_resources(dev, &host->windows); 516 err = devm_request_pci_bus_resources(dev, &host->windows);
365 if (err < 0) { 517 if (err < 0)
366 pci_free_resource_list(&host->windows); 518 goto err_free_resource;
367 return err;
368 }
369 519
370 bc->nasid = bd->nasid; 520 bc->nasid = bd->nasid;
371 521
@@ -419,7 +569,7 @@ static int bridge_probe(struct platform_device *pdev)
419 569
420 err = pci_scan_root_bus_bridge(host); 570 err = pci_scan_root_bus_bridge(host);
421 if (err < 0) 571 if (err < 0)
422 return err; 572 goto err_free_resource;
423 573
424 pci_bus_claim_resources(host->bus); 574 pci_bus_claim_resources(host->bus);
425 pci_bus_add_devices(host->bus); 575 pci_bus_add_devices(host->bus);
@@ -427,12 +577,20 @@ static int bridge_probe(struct platform_device *pdev)
427 platform_set_drvdata(pdev, host->bus); 577 platform_set_drvdata(pdev, host->bus);
428 578
429 return 0; 579 return 0;
580
581err_free_resource:
582 pci_free_resource_list(&host->windows);
583err_remove_domain:
584 irq_domain_remove(domain);
585 return err;
430} 586}
431 587
432static int bridge_remove(struct platform_device *pdev) 588static int bridge_remove(struct platform_device *pdev)
433{ 589{
434 struct pci_bus *bus = platform_get_drvdata(pdev); 590 struct pci_bus *bus = platform_get_drvdata(pdev);
591 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
435 592
593 irq_domain_remove(bc->domain);
436 pci_lock_rescan_remove(); 594 pci_lock_rescan_remove();
437 pci_stop_root_bus(bus); 595 pci_stop_root_bus(bus);
438 pci_remove_root_bus(bus); 596 pci_remove_root_bus(bus);
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 710a59764b01..37be04975831 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -12,22 +12,20 @@
12#include <linux/ioport.h> 12#include <linux/ioport.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/bitops.h> 14#include <linux/bitops.h>
15#include <linux/sched.h>
15 16
16#include <asm/io.h> 17#include <asm/io.h>
17#include <asm/irq_cpu.h> 18#include <asm/irq_cpu.h>
18#include <asm/pci/bridge.h>
19#include <asm/sn/addrs.h> 19#include <asm/sn/addrs.h>
20#include <asm/sn/agent.h> 20#include <asm/sn/agent.h>
21#include <asm/sn/arch.h> 21#include <asm/sn/arch.h>
22#include <asm/sn/hub.h> 22#include <asm/sn/hub.h>
23#include <asm/sn/intr.h> 23#include <asm/sn/intr.h>
24#include <asm/sn/irq_alloc.h>
24 25
25struct hub_irq_data { 26struct hub_irq_data {
26 struct bridge_controller *bc;
27 u64 *irq_mask[2]; 27 u64 *irq_mask[2];
28 cpuid_t cpu; 28 cpuid_t cpu;
29 int bit;
30 int pin;
31}; 29};
32 30
33static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT); 31static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT);
@@ -54,7 +52,7 @@ static void enable_hub_irq(struct irq_data *d)
54 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); 52 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
55 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); 53 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
56 54
57 set_bit(hd->bit, mask); 55 set_bit(d->hwirq, mask);
58 __raw_writeq(mask[0], hd->irq_mask[0]); 56 __raw_writeq(mask[0], hd->irq_mask[0]);
59 __raw_writeq(mask[1], hd->irq_mask[1]); 57 __raw_writeq(mask[1], hd->irq_mask[1]);
60} 58}
@@ -64,72 +62,11 @@ static void disable_hub_irq(struct irq_data *d)
64 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); 62 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
65 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); 63 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
66 64
67 clear_bit(hd->bit, mask); 65 clear_bit(d->hwirq, mask);
68 __raw_writeq(mask[0], hd->irq_mask[0]); 66 __raw_writeq(mask[0], hd->irq_mask[0]);
69 __raw_writeq(mask[1], hd->irq_mask[1]); 67 __raw_writeq(mask[1], hd->irq_mask[1]);
70} 68}
71 69
72static unsigned int startup_bridge_irq(struct irq_data *d)
73{
74 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
75 struct bridge_controller *bc;
76 nasid_t nasid;
77 u32 device;
78 int pin;
79
80 if (!hd)
81 return -EINVAL;
82
83 pin = hd->pin;
84 bc = hd->bc;
85
86 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(hd->cpu));
87 bridge_write(bc, b_int_addr[pin].addr,
88 (0x20000 | hd->bit | (nasid << 8)));
89 bridge_set(bc, b_int_enable, (1 << pin));
90 bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
91
92 /*
93 * Enable sending of an interrupt clear packt to the hub on a high to
94 * low transition of the interrupt pin.
95 *
96 * IRIX sets additional bits in the address which are documented as
97 * reserved in the bridge docs.
98 */
99 bridge_set(bc, b_int_mode, (1UL << pin));
100
101 /*
102 * We assume the bridge to have a 1:1 mapping between devices
103 * (slots) and intr pins.
104 */
105 device = bridge_read(bc, b_int_device);
106 device &= ~(7 << (pin*3));
107 device |= (pin << (pin*3));
108 bridge_write(bc, b_int_device, device);
109
110 bridge_read(bc, b_wid_tflush);
111
112 enable_hub_irq(d);
113
114 return 0; /* Never anything pending. */
115}
116
117static void shutdown_bridge_irq(struct irq_data *d)
118{
119 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
120 struct bridge_controller *bc;
121 int pin = hd->pin;
122
123 if (!hd)
124 return;
125
126 disable_hub_irq(d);
127
128 bc = hd->bc;
129 bridge_clr(bc, b_int_enable, (1 << pin));
130 bridge_read(bc, b_wid_tflush);
131}
132
133static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask) 70static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
134{ 71{
135 nasid_t nasid; 72 nasid_t nasid;
@@ -145,9 +82,6 @@ static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
145 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B); 82 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B);
146 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B); 83 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B);
147 } 84 }
148
149 /* Make sure it's not already pending when we connect it. */
150 REMOTE_HUB_CLR_INTR(nasid, hd->bit);
151} 85}
152 86
153static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask, 87static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
@@ -164,7 +98,7 @@ static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
164 setup_hub_mask(hd, mask); 98 setup_hub_mask(hd, mask);
165 99
166 if (irqd_is_started(d)) 100 if (irqd_is_started(d))
167 startup_bridge_irq(d); 101 enable_hub_irq(d);
168 102
169 irq_data_update_effective_affinity(d, cpumask_of(hd->cpu)); 103 irq_data_update_effective_affinity(d, cpumask_of(hd->cpu));
170 104
@@ -173,20 +107,22 @@ static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
173 107
174static struct irq_chip hub_irq_type = { 108static struct irq_chip hub_irq_type = {
175 .name = "HUB", 109 .name = "HUB",
176 .irq_startup = startup_bridge_irq,
177 .irq_shutdown = shutdown_bridge_irq,
178 .irq_mask = disable_hub_irq, 110 .irq_mask = disable_hub_irq,
179 .irq_unmask = enable_hub_irq, 111 .irq_unmask = enable_hub_irq,
180 .irq_set_affinity = set_affinity_hub_irq, 112 .irq_set_affinity = set_affinity_hub_irq,
181}; 113};
182 114
183int request_bridge_irq(struct bridge_controller *bc, int pin) 115static int hub_domain_alloc(struct irq_domain *domain, unsigned int virq,
116 unsigned int nr_irqs, void *arg)
184{ 117{
118 struct irq_alloc_info *info = arg;
185 struct hub_irq_data *hd; 119 struct hub_irq_data *hd;
186 struct hub_data *hub; 120 struct hub_data *hub;
187 struct irq_desc *desc; 121 struct irq_desc *desc;
188 int swlevel; 122 int swlevel;
189 int irq; 123
124 if (nr_irqs > 1 || !info)
125 return -EINVAL;
190 126
191 hd = kzalloc(sizeof(*hd), GFP_KERNEL); 127 hd = kzalloc(sizeof(*hd), GFP_KERNEL);
192 if (!hd) 128 if (!hd)
@@ -197,46 +133,41 @@ int request_bridge_irq(struct bridge_controller *bc, int pin)
197 kfree(hd); 133 kfree(hd);
198 return -EAGAIN; 134 return -EAGAIN;
199 } 135 }
200 irq = swlevel + IP27_HUB_IRQ_BASE; 136 irq_domain_set_info(domain, virq, swlevel, &hub_irq_type, hd,
201 137 handle_level_irq, NULL, NULL);
202 hd->bc = bc;
203 hd->bit = swlevel;
204 hd->pin = pin;
205 irq_set_chip_data(irq, hd);
206 138
207 /* use CPU connected to nearest hub */ 139 /* use CPU connected to nearest hub */
208 hub = hub_data(NASID_TO_COMPACT_NODEID(bc->nasid)); 140 hub = hub_data(NASID_TO_COMPACT_NODEID(info->nasid));
209 setup_hub_mask(hd, &hub->h_cpus); 141 setup_hub_mask(hd, &hub->h_cpus);
210 142
211 desc = irq_to_desc(irq); 143 /* Make sure it's not already pending when we connect it. */
212 desc->irq_common_data.node = bc->nasid; 144 REMOTE_HUB_CLR_INTR(info->nasid, swlevel);
145
146 desc = irq_to_desc(virq);
147 desc->irq_common_data.node = info->nasid;
213 cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus); 148 cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus);
214 149
215 return irq; 150 return 0;
216} 151}
217 152
218void ip27_hub_irq_init(void) 153static void hub_domain_free(struct irq_domain *domain,
154 unsigned int virq, unsigned int nr_irqs)
219{ 155{
220 int i; 156 struct irq_data *irqd;
221 157
222 for (i = IP27_HUB_IRQ_BASE; 158 if (nr_irqs > 1)
223 i < (IP27_HUB_IRQ_BASE + IP27_HUB_IRQ_COUNT); i++) 159 return;
224 irq_set_chip_and_handler(i, &hub_irq_type, handle_level_irq);
225
226 /*
227 * Some interrupts are reserved by hardware or by software convention.
228 * Mark these as reserved right away so they won't be used accidentally
229 * later.
230 */
231 for (i = 0; i <= BASE_PCI_IRQ; i++)
232 set_bit(i, hub_irq_map);
233
234 set_bit(IP_PEND0_6_63, hub_irq_map);
235 160
236 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) 161 irqd = irq_domain_get_irq_data(domain, virq);
237 set_bit(i, hub_irq_map); 162 if (irqd && irqd->chip_data)
163 kfree(irqd->chip_data);
238} 164}
239 165
166static const struct irq_domain_ops hub_domain_ops = {
167 .alloc = hub_domain_alloc,
168 .free = hub_domain_free,
169};
170
240/* 171/*
241 * This code is unnecessarily complex, because we do 172 * This code is unnecessarily complex, because we do
242 * intr enabling. Basically, once we grab the set of intrs we need 173 * intr enabling. Basically, once we grab the set of intrs we need
@@ -253,7 +184,9 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
253{ 184{
254 cpuid_t cpu = smp_processor_id(); 185 cpuid_t cpu = smp_processor_id();
255 unsigned long *mask = per_cpu(irq_enable_mask, cpu); 186 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
187 struct irq_domain *domain;
256 u64 pend0; 188 u64 pend0;
189 int irq;
257 190
258 /* copied from Irix intpend0() */ 191 /* copied from Irix intpend0() */
259 pend0 = LOCAL_HUB_L(PI_INT_PEND0); 192 pend0 = LOCAL_HUB_L(PI_INT_PEND0);
@@ -277,7 +210,14 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
277 generic_smp_call_function_interrupt(); 210 generic_smp_call_function_interrupt();
278 } else 211 } else
279#endif 212#endif
280 generic_handle_irq(__ffs(pend0) + IP27_HUB_IRQ_BASE); 213 {
214 domain = irq_desc_get_handler_data(desc);
215 irq = irq_linear_revmap(domain, __ffs(pend0));
216 if (irq)
217 generic_handle_irq(irq);
218 else
219 spurious_interrupt();
220 }
281 221
282 LOCAL_HUB_L(PI_INT_PEND0); 222 LOCAL_HUB_L(PI_INT_PEND0);
283} 223}
@@ -286,7 +226,9 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
286{ 226{
287 cpuid_t cpu = smp_processor_id(); 227 cpuid_t cpu = smp_processor_id();
288 unsigned long *mask = per_cpu(irq_enable_mask, cpu); 228 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
229 struct irq_domain *domain;
289 u64 pend1; 230 u64 pend1;
231 int irq;
290 232
291 /* copied from Irix intpend0() */ 233 /* copied from Irix intpend0() */
292 pend1 = LOCAL_HUB_L(PI_INT_PEND1); 234 pend1 = LOCAL_HUB_L(PI_INT_PEND1);
@@ -295,7 +237,12 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
295 if (!pend1) 237 if (!pend1)
296 return; 238 return;
297 239
298 generic_handle_irq(__ffs(pend1) + IP27_HUB_IRQ_BASE + 64); 240 domain = irq_desc_get_handler_data(desc);
241 irq = irq_linear_revmap(domain, __ffs(pend1) + 64);
242 if (irq)
243 generic_handle_irq(irq);
244 else
245 spurious_interrupt();
299 246
300 LOCAL_HUB_L(PI_INT_PEND1); 247 LOCAL_HUB_L(PI_INT_PEND1);
301} 248}
@@ -326,11 +273,41 @@ void install_ipi(void)
326 273
327void __init arch_init_irq(void) 274void __init arch_init_irq(void)
328{ 275{
276 struct irq_domain *domain;
277 struct fwnode_handle *fn;
278 int i;
279
329 mips_cpu_irq_init(); 280 mips_cpu_irq_init();
330 ip27_hub_irq_init(); 281
282 /*
283 * Some interrupts are reserved by hardware or by software convention.
284 * Mark these as reserved right away so they won't be used accidentally
285 * later.
286 */
287 for (i = 0; i <= BASE_PCI_IRQ; i++)
288 set_bit(i, hub_irq_map);
289
290 set_bit(IP_PEND0_6_63, hub_irq_map);
291
292 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
293 set_bit(i, hub_irq_map);
294
295 fn = irq_domain_alloc_named_fwnode("HUB");
296 WARN_ON(fn == NULL);
297 if (!fn)
298 return;
299 domain = irq_domain_create_linear(fn, IP27_HUB_IRQ_COUNT,
300 &hub_domain_ops, NULL);
301 WARN_ON(domain == NULL);
302 if (!domain)
303 return;
304
305 irq_set_default_host(domain);
331 306
332 irq_set_percpu_devid(IP27_HUB_PEND0_IRQ); 307 irq_set_percpu_devid(IP27_HUB_PEND0_IRQ);
333 irq_set_chained_handler(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0); 308 irq_set_chained_handler_and_data(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0,
309 domain);
334 irq_set_percpu_devid(IP27_HUB_PEND1_IRQ); 310 irq_set_percpu_devid(IP27_HUB_PEND1_IRQ);
335 irq_set_chained_handler(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1); 311 irq_set_chained_handler_and_data(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1,
312 domain);
336} 313}