diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-18 15:22:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-18 15:22:04 -0500 |
commit | 2d6c4e40ab7eb1ab7b8cd4a232b0c9554ea8de9b (patch) | |
tree | 8334cad2075d7652024eb586a4b21ffba530170f | |
parent | 59e4721544a9650cb74f66857e7b2ab49e983144 (diff) | |
parent | 6dee6ae9d62642e81def4d461d71f13a6496ab59 (diff) |
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"A small set of updates mostly for irq chip drivers:
- MIPS GIC fix for spurious, masked interrupts
- fix for a subtle IPI bug in GICv3
- do not probe GICv3 ITSs that are marked as disabled
- multi-MSI support for GICv2m
- various small cleanups"
* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqdomain: Re-use DEFINE_SHOW_ATTRIBUTE() macro
irqchip/bcm: Remove hashed address printing
irqchip/gic-v2m: Add PCI Multi-MSI support
irqchip/gic-v3: Ignore disabled ITS nodes
irqchip/gic-v3: Use wmb() instead of smb_wmb() in gic_raise_softirq()
irqchip/gic-v3: Change pr_debug message to pr_devel
irqchip/mips-gic: Avoid spuriously handling masked interrupts
-rw-r--r-- | drivers/irqchip/irq-bcm7038-l1.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-bcm7120-l2.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-brcmstb-l2.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v2m.c | 46 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its-pci-msi.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its-platform-msi.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-mips-gic.c | 2 | ||||
-rw-r--r-- | drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 2 | ||||
-rw-r--r-- | kernel/irq/irqdomain.c | 18 |
11 files changed, 36 insertions, 51 deletions
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index 55cfb986225b..faf734ff4cf3 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c | |||
@@ -339,9 +339,6 @@ int __init bcm7038_l1_of_init(struct device_node *dn, | |||
339 | goto out_unmap; | 339 | goto out_unmap; |
340 | } | 340 | } |
341 | 341 | ||
342 | pr_info("registered BCM7038 L1 intc (mem: 0x%p, IRQs: %d)\n", | ||
343 | intc->cpus[0]->map_base, IRQS_PER_WORD * intc->n_words); | ||
344 | |||
345 | return 0; | 342 | return 0; |
346 | 343 | ||
347 | out_unmap: | 344 | out_unmap: |
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 983640eba418..8968e5e93fcb 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c | |||
@@ -318,9 +318,6 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, | |||
318 | } | 318 | } |
319 | } | 319 | } |
320 | 320 | ||
321 | pr_info("registered %s intc (mem: 0x%p, parent IRQ(s): %d)\n", | ||
322 | intc_name, data->map_base[0], data->num_parent_irqs); | ||
323 | |||
324 | return 0; | 321 | return 0; |
325 | 322 | ||
326 | out_free_domain: | 323 | out_free_domain: |
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index 691d20eb0bec..0e65f609352e 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c | |||
@@ -262,9 +262,6 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
262 | ct->chip.irq_set_wake = irq_gc_set_wake; | 262 | ct->chip.irq_set_wake = irq_gc_set_wake; |
263 | } | 263 | } |
264 | 264 | ||
265 | pr_info("registered L2 intc (mem: 0x%p, parent irq: %d)\n", | ||
266 | base, parent_irq); | ||
267 | |||
268 | return 0; | 265 | return 0; |
269 | 266 | ||
270 | out_free_domain: | 267 | out_free_domain: |
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 993a8426a453..1ff38aff9f29 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c | |||
@@ -94,7 +94,7 @@ static struct irq_chip gicv2m_msi_irq_chip = { | |||
94 | 94 | ||
95 | static struct msi_domain_info gicv2m_msi_domain_info = { | 95 | static struct msi_domain_info gicv2m_msi_domain_info = { |
96 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | 96 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | |
97 | MSI_FLAG_PCI_MSIX), | 97 | MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), |
98 | .chip = &gicv2m_msi_irq_chip, | 98 | .chip = &gicv2m_msi_irq_chip, |
99 | }; | 99 | }; |
100 | 100 | ||
@@ -155,18 +155,12 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain, | |||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
157 | 157 | ||
158 | static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq) | 158 | static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq, |
159 | int nr_irqs) | ||
159 | { | 160 | { |
160 | int pos; | ||
161 | |||
162 | pos = hwirq - v2m->spi_start; | ||
163 | if (pos < 0 || pos >= v2m->nr_spis) { | ||
164 | pr_err("Failed to teardown msi. Invalid hwirq %d\n", hwirq); | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | spin_lock(&v2m_lock); | 161 | spin_lock(&v2m_lock); |
169 | __clear_bit(pos, v2m->bm); | 162 | bitmap_release_region(v2m->bm, hwirq - v2m->spi_start, |
163 | get_count_order(nr_irqs)); | ||
170 | spin_unlock(&v2m_lock); | 164 | spin_unlock(&v2m_lock); |
171 | } | 165 | } |
172 | 166 | ||
@@ -174,13 +168,13 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
174 | unsigned int nr_irqs, void *args) | 168 | unsigned int nr_irqs, void *args) |
175 | { | 169 | { |
176 | struct v2m_data *v2m = NULL, *tmp; | 170 | struct v2m_data *v2m = NULL, *tmp; |
177 | int hwirq, offset, err = 0; | 171 | int hwirq, offset, i, err = 0; |
178 | 172 | ||
179 | spin_lock(&v2m_lock); | 173 | spin_lock(&v2m_lock); |
180 | list_for_each_entry(tmp, &v2m_nodes, entry) { | 174 | list_for_each_entry(tmp, &v2m_nodes, entry) { |
181 | offset = find_first_zero_bit(tmp->bm, tmp->nr_spis); | 175 | offset = bitmap_find_free_region(tmp->bm, tmp->nr_spis, |
182 | if (offset < tmp->nr_spis) { | 176 | get_count_order(nr_irqs)); |
183 | __set_bit(offset, tmp->bm); | 177 | if (offset >= 0) { |
184 | v2m = tmp; | 178 | v2m = tmp; |
185 | break; | 179 | break; |
186 | } | 180 | } |
@@ -192,16 +186,21 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | |||
192 | 186 | ||
193 | hwirq = v2m->spi_start + offset; | 187 | hwirq = v2m->spi_start + offset; |
194 | 188 | ||
195 | err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq); | 189 | for (i = 0; i < nr_irqs; i++) { |
196 | if (err) { | 190 | err = gicv2m_irq_gic_domain_alloc(domain, virq + i, hwirq + i); |
197 | gicv2m_unalloc_msi(v2m, hwirq); | 191 | if (err) |
198 | return err; | 192 | goto fail; |
199 | } | ||
200 | 193 | ||
201 | irq_domain_set_hwirq_and_chip(domain, virq, hwirq, | 194 | irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, |
202 | &gicv2m_irq_chip, v2m); | 195 | &gicv2m_irq_chip, v2m); |
196 | } | ||
203 | 197 | ||
204 | return 0; | 198 | return 0; |
199 | |||
200 | fail: | ||
201 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); | ||
202 | gicv2m_unalloc_msi(v2m, hwirq, get_count_order(nr_irqs)); | ||
203 | return err; | ||
205 | } | 204 | } |
206 | 205 | ||
207 | static void gicv2m_irq_domain_free(struct irq_domain *domain, | 206 | static void gicv2m_irq_domain_free(struct irq_domain *domain, |
@@ -210,8 +209,7 @@ static void gicv2m_irq_domain_free(struct irq_domain *domain, | |||
210 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); | 209 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
211 | struct v2m_data *v2m = irq_data_get_irq_chip_data(d); | 210 | struct v2m_data *v2m = irq_data_get_irq_chip_data(d); |
212 | 211 | ||
213 | BUG_ON(nr_irqs != 1); | 212 | gicv2m_unalloc_msi(v2m, d->hwirq, nr_irqs); |
214 | gicv2m_unalloc_msi(v2m, d->hwirq); | ||
215 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); | 213 | irq_domain_free_irqs_parent(domain, virq, nr_irqs); |
216 | } | 214 | } |
217 | 215 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c index 14a8c0a7e095..25a98de5cfb2 100644 --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c | |||
@@ -132,6 +132,8 @@ static int __init its_pci_of_msi_init(void) | |||
132 | 132 | ||
133 | for (np = of_find_matching_node(NULL, its_device_id); np; | 133 | for (np = of_find_matching_node(NULL, its_device_id); np; |
134 | np = of_find_matching_node(np, its_device_id)) { | 134 | np = of_find_matching_node(np, its_device_id)) { |
135 | if (!of_device_is_available(np)) | ||
136 | continue; | ||
135 | if (!of_property_read_bool(np, "msi-controller")) | 137 | if (!of_property_read_bool(np, "msi-controller")) |
136 | continue; | 138 | continue; |
137 | 139 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c index 833a90fe33ae..8881a053c173 100644 --- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c | |||
@@ -154,6 +154,8 @@ static void __init its_pmsi_of_init(void) | |||
154 | 154 | ||
155 | for (np = of_find_matching_node(NULL, its_device_id); np; | 155 | for (np = of_find_matching_node(NULL, its_device_id); np; |
156 | np = of_find_matching_node(np, its_device_id)) { | 156 | np = of_find_matching_node(np, its_device_id)) { |
157 | if (!of_device_is_available(np)) | ||
158 | continue; | ||
157 | if (!of_property_read_bool(np, "msi-controller")) | 159 | if (!of_property_read_bool(np, "msi-controller")) |
158 | continue; | 160 | continue; |
159 | 161 | ||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 06f025fd5726..1d3056f53747 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -3314,6 +3314,8 @@ static int __init its_of_probe(struct device_node *node) | |||
3314 | 3314 | ||
3315 | for (np = of_find_matching_node(node, its_device_id); np; | 3315 | for (np = of_find_matching_node(node, its_device_id); np; |
3316 | np = of_find_matching_node(np, its_device_id)) { | 3316 | np = of_find_matching_node(np, its_device_id)) { |
3317 | if (!of_device_is_available(np)) | ||
3318 | continue; | ||
3317 | if (!of_property_read_bool(np, "msi-controller")) { | 3319 | if (!of_property_read_bool(np, "msi-controller")) { |
3318 | pr_warn("%pOF: no msi-controller property, ITS ignored\n", | 3320 | pr_warn("%pOF: no msi-controller property, ITS ignored\n", |
3319 | np); | 3321 | np); |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index a57c0fbbd34a..d99cc07903ec 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -673,7 +673,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) | |||
673 | MPIDR_TO_SGI_RS(cluster_id) | | 673 | MPIDR_TO_SGI_RS(cluster_id) | |
674 | tlist << ICC_SGI1R_TARGET_LIST_SHIFT); | 674 | tlist << ICC_SGI1R_TARGET_LIST_SHIFT); |
675 | 675 | ||
676 | pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); | 676 | pr_devel("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); |
677 | gic_write_sgi1r(val); | 677 | gic_write_sgi1r(val); |
678 | } | 678 | } |
679 | 679 | ||
@@ -688,7 +688,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
688 | * Ensure that stores to Normal memory are visible to the | 688 | * Ensure that stores to Normal memory are visible to the |
689 | * other CPUs before issuing the IPI. | 689 | * other CPUs before issuing the IPI. |
690 | */ | 690 | */ |
691 | smp_wmb(); | 691 | wmb(); |
692 | 692 | ||
693 | for_each_cpu(cpu, mask) { | 693 | for_each_cpu(cpu, mask) { |
694 | u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID(cpu_logical_map(cpu)); | 694 | u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID(cpu_logical_map(cpu)); |
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index ef92a4d2038e..d32268cc1174 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -424,8 +424,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
424 | spin_lock_irqsave(&gic_lock, flags); | 424 | spin_lock_irqsave(&gic_lock, flags); |
425 | write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); | 425 | write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); |
426 | write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); | 426 | write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); |
427 | gic_clear_pcpu_masks(intr); | ||
428 | set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); | ||
429 | irq_data_update_effective_affinity(data, cpumask_of(cpu)); | 427 | irq_data_update_effective_affinity(data, cpumask_of(cpu)); |
430 | spin_unlock_irqrestore(&gic_lock, flags); | 428 | spin_unlock_irqrestore(&gic_lock, flags); |
431 | 429 | ||
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c index 5064d5ddf581..fc2013aade51 100644 --- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | |||
@@ -73,6 +73,8 @@ static int __init its_fsl_mc_msi_init(void) | |||
73 | 73 | ||
74 | for (np = of_find_matching_node(NULL, its_device_id); np; | 74 | for (np = of_find_matching_node(NULL, its_device_id); np; |
75 | np = of_find_matching_node(np, its_device_id)) { | 75 | np = of_find_matching_node(np, its_device_id)) { |
76 | if (!of_device_is_available(np)) | ||
77 | continue; | ||
76 | if (!of_property_read_bool(np, "msi-controller")) | 78 | if (!of_property_read_bool(np, "msi-controller")) |
77 | continue; | 79 | continue; |
78 | 80 | ||
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e6a9c36470ee..82b8b18ee1eb 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c | |||
@@ -1726,25 +1726,14 @@ static int irq_domain_debug_show(struct seq_file *m, void *p) | |||
1726 | irq_domain_debug_show_one(m, d, 0); | 1726 | irq_domain_debug_show_one(m, d, 0); |
1727 | return 0; | 1727 | return 0; |
1728 | } | 1728 | } |
1729 | 1729 | DEFINE_SHOW_ATTRIBUTE(irq_domain_debug); | |
1730 | static int irq_domain_debug_open(struct inode *inode, struct file *file) | ||
1731 | { | ||
1732 | return single_open(file, irq_domain_debug_show, inode->i_private); | ||
1733 | } | ||
1734 | |||
1735 | static const struct file_operations dfs_domain_ops = { | ||
1736 | .open = irq_domain_debug_open, | ||
1737 | .read = seq_read, | ||
1738 | .llseek = seq_lseek, | ||
1739 | .release = single_release, | ||
1740 | }; | ||
1741 | 1730 | ||
1742 | static void debugfs_add_domain_dir(struct irq_domain *d) | 1731 | static void debugfs_add_domain_dir(struct irq_domain *d) |
1743 | { | 1732 | { |
1744 | if (!d->name || !domain_dir || d->debugfs_file) | 1733 | if (!d->name || !domain_dir || d->debugfs_file) |
1745 | return; | 1734 | return; |
1746 | d->debugfs_file = debugfs_create_file(d->name, 0444, domain_dir, d, | 1735 | d->debugfs_file = debugfs_create_file(d->name, 0444, domain_dir, d, |
1747 | &dfs_domain_ops); | 1736 | &irq_domain_debug_fops); |
1748 | } | 1737 | } |
1749 | 1738 | ||
1750 | static void debugfs_remove_domain_dir(struct irq_domain *d) | 1739 | static void debugfs_remove_domain_dir(struct irq_domain *d) |
@@ -1760,7 +1749,8 @@ void __init irq_domain_debugfs_init(struct dentry *root) | |||
1760 | if (!domain_dir) | 1749 | if (!domain_dir) |
1761 | return; | 1750 | return; |
1762 | 1751 | ||
1763 | debugfs_create_file("default", 0444, domain_dir, NULL, &dfs_domain_ops); | 1752 | debugfs_create_file("default", 0444, domain_dir, NULL, |
1753 | &irq_domain_debug_fops); | ||
1764 | mutex_lock(&irq_domain_mutex); | 1754 | mutex_lock(&irq_domain_mutex); |
1765 | list_for_each_entry(d, &irq_domain_list, link) | 1755 | list_for_each_entry(d, &irq_domain_list, link) |
1766 | debugfs_add_domain_dir(d); | 1756 | debugfs_add_domain_dir(d); |