Commit bfb79854 authored by Alex Elder's avatar Alex Elder Committed by Jakub Kicinski
Browse files

net: ipa: don't maintain IPA interrupt handler array



We can call the two IPA interrupt handler functions directly;
there's no need to maintain the array of handler function pointers
any more.

Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 8d8d3f1a
Loading
Loading
Loading
Loading
+22 −28
Original line number Diff line number Diff line
@@ -30,54 +30,52 @@
#include "ipa_uc.h"
#include "ipa_interrupt.h"

typedef void (*ipa_irq_handler_t)(struct ipa *ipa, enum ipa_irq_id irq_id);

/**
 * struct ipa_interrupt - IPA interrupt information
 * @ipa:		IPA pointer
 * @irq:		Linux IRQ number used for IPA interrupts
 * @enabled:		Mask indicating which interrupts are enabled
 * @handler:		Array of handlers indexed by IPA interrupt ID
 */
struct ipa_interrupt {
	struct ipa *ipa;
	u32 irq;
	u32 enabled;
	ipa_irq_handler_t handler[IPA_IRQ_COUNT];
};

/* Returns true if the interrupt type is associated with the microcontroller */
static bool ipa_interrupt_uc(struct ipa_interrupt *interrupt, u32 irq_id)
{
	return irq_id == IPA_IRQ_UC_0 || irq_id == IPA_IRQ_UC_1;
}

/* Process a particular interrupt type that has been received */
static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
{
	bool uc_irq = ipa_interrupt_uc(interrupt, irq_id);
	struct ipa *ipa = interrupt->ipa;
	const struct ipa_reg *reg;
	u32 mask = BIT(irq_id);
	u32 offset;

	/* For microcontroller interrupts, clear the interrupt right away,
	 * "to avoid clearing unhandled interrupts."
	 */
	reg = ipa_reg(ipa, IPA_IRQ_CLR);
	offset = ipa_reg_offset(reg);
	if (uc_irq)
		iowrite32(mask, ipa->reg_virt + offset);

	if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id])
		interrupt->handler[irq_id](interrupt->ipa, irq_id);

	/* Clearing the SUSPEND_TX interrupt also clears the register
	 * that tells us which suspended endpoint(s) caused the interrupt,
	 * so defer clearing until after the handler has been called.
	switch (irq_id) {
	case IPA_IRQ_UC_0:
	case IPA_IRQ_UC_1:
		/* For microcontroller interrupts, clear the interrupt right
		 * away, "to avoid clearing unhandled interrupts."
		 */
		iowrite32(mask, ipa->reg_virt + offset);
		ipa_uc_interrupt_handler(ipa, irq_id);
		break;

	case IPA_IRQ_TX_SUSPEND:
		/* Clearing the SUSPEND_TX interrupt also clears the
		 * register that tells us which suspended endpoint(s)
		 * caused the interrupt, so defer clearing until after
		 * the handler has been called.
		 */
	if (!uc_irq)
		ipa_power_suspend_handler(ipa, irq_id);
		fallthrough;

	default:	/* Silently ignore (and clear) any other condition */
		iowrite32(mask, ipa->reg_virt + offset);
		break;
	}
}

/* IPA IRQ handler is threaded */
@@ -267,10 +265,6 @@ struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa)
		goto err_free_irq;
	}

	interrupt->handler[IPA_IRQ_UC_0] = ipa_uc_interrupt_handler;
	interrupt->handler[IPA_IRQ_UC_1] = ipa_uc_interrupt_handler;
	interrupt->handler[IPA_IRQ_TX_SUSPEND] = ipa_power_suspend_handler;

	return interrupt;

err_free_irq: