Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4013369f authored by Grant Likely's avatar Grant Likely Committed by Benjamin Herrenschmidt
Browse files

powerpc/irqdomain: Fix broken NR_IRQ references



The switch from using irq_map to irq_alloc_desc*() for managing irq
number allocations introduced new bugs in some of the powerpc
interrupt code.  Several functions rely on the value of NR_IRQS to
determine the maximum irq number that could get allocated.  However,
with sparse_irq and using irq_alloc_desc*() the maximum possible irq
number is now specified with 'nr_irqs' which may be a number larger
than NR_IRQS.  This has caused breakage on powermac when
CONFIG_NR_IRQS is set to 32.

This patch removes most of the direct references to NR_IRQS in the
powerpc code and replaces them with either a nr_irqs reference or by
using the common for_each_irq_desc() macro.  The powerpc-specific
for_each_irq() macro is removed at the same time.

Also, the Cell axon_msi driver is refactored to remove the global
build assumption on the size of NR_IRQS and instead add a limit to the
maximum irq number when calling irq_domain_add_nomap().

Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 8751ed14
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -18,10 +18,6 @@
#include <linux/atomic.h>


/* Define a way to iterate across irqs. */
#define for_each_irq(i) \
	for ((i) = 0; (i) < NR_IRQS; ++(i))

extern atomic_t ppc_n_lost_interrupts;

/* This number is used when no interrupt has been assigned */
+1 −5
Original line number Diff line number Diff line
@@ -330,14 +330,10 @@ void migrate_irqs(void)

	alloc_cpumask_var(&mask, GFP_KERNEL);

	for_each_irq(irq) {
	for_each_irq_desc(irq, desc) {
		struct irq_data *data;
		struct irq_chip *chip;

		desc = irq_to_desc(irq);
		if (!desc)
			continue;

		data = irq_desc_get_irq_data(desc);
		if (irqd_is_per_cpu(data))
			continue;
+2 −5
Original line number Diff line number Diff line
@@ -23,14 +23,11 @@

void machine_kexec_mask_interrupts(void) {
	unsigned int i;
	struct irq_desc *desc;

	for_each_irq(i) {
		struct irq_desc *desc = irq_to_desc(i);
	for_each_irq_desc(i, desc) {
		struct irq_chip *chip;

		if (!desc)
			continue;

		chip = irq_desc_get_chip(desc);
		if (!chip)
			continue;
+3 −5
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
		pr_devel("axon_msi: woff %x roff %x msi %x\n",
			  write_offset, msic->read_offset, msi);

		if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) {
		if (msi < nr_irqs && irq_get_chip_data(msi) == msic) {
			generic_handle_irq(msi);
			msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
		} else {
@@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
	if (rc)
		return rc;

	/* We rely on being able to stash a virq in a u16 */
	BUILD_BUG_ON(NR_IRQS > 65536);

	list_for_each_entry(entry, &dev->msi_list, list) {
		virq = irq_create_direct_mapping(msic->irq_domain);
		if (virq == NO_IRQ) {
@@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device)
	}
	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);

	msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
	/* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */
	msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic);
	if (!msic->irq_domain) {
		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
		       dn->full_name);
+1 −1
Original line number Diff line number Diff line
@@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void)
{
	int	i;

	for (i = 1; i < NR_IRQS; i++)
	for (i = 1; i < nr_irqs; i++)
		beat_destruct_irq_plug(i);
}
Loading