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

Commit 41fb5e62 authored by Milton Miller's avatar Milton Miller Committed by Benjamin Herrenschmidt
Browse files

powerpc: Make IRQ_NOREQUEST last to clear, first to set



When creating an irq, don't allow a concurent driver request until
we have caled map, which will likley call set_chip_and_handler to
change the irq_chip and its operations.

Similarly, when tearing down an IRQ, make sure no new uses come
along while we change the irq back to the nop chip and then reset
the descriptor to freed status.

Signed-off-by: default avatarMilton Miller <miltonm@bga.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 1e8c2301
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -586,14 +586,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
			irq_map[i].host = host;
			smp_wmb();

			/* Clear norequest flags */
			irq_clear_status_flags(i, IRQ_NOREQUEST);

			/* Legacy flags are left to default at this point,
			 * one can then use irq_create_mapping() to
			 * explicitly change them
			 */
			ops->map(host, i, i);

			/* Clear norequest flags */
			irq_clear_status_flags(i, IRQ_NOREQUEST);
		}
		break;
	case IRQ_HOST_MAP_LINEAR:
@@ -664,8 +664,6 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
		goto error;
	}

	irq_clear_status_flags(virq, IRQ_NOREQUEST);

	/* map it */
	smp_wmb();
	irq_map[virq].hwirq = hwirq;
@@ -676,6 +674,8 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
		goto errdesc;
	}

	irq_clear_status_flags(virq, IRQ_NOREQUEST);

	return 0;

errdesc:
@@ -819,6 +819,8 @@ void irq_dispose_mapping(unsigned int virq)
	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
		return;

	irq_set_status_flags(virq, IRQ_NOREQUEST);

	/* remove chip and handler */
	irq_set_chip_and_handler(virq, NULL, NULL);

@@ -848,8 +850,6 @@ void irq_dispose_mapping(unsigned int virq)
	smp_mb();
	irq_map[virq].hwirq = host->inval_irq;

	irq_set_status_flags(virq, IRQ_NOREQUEST);

	irq_free_descs(virq, 1);
	/* Free it */
	irq_free_virt(virq, 1);