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

Commit 32f4125e authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

genirq: Move INPROGRESS, MASKED and DISABLED state flags to irq_data



We really need these flags for some of the interrupt chips. Move it
from internal state to irq_data and provide proper accessors.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: David Daney <ddaney@caviumnetworks.com>
parent c2d0c555
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -174,8 +174,9 @@ struct irq_data {
 *				  from suspend
 * IRDQ_MOVE_PCNTXT		- Interrupt can be moved in process
 *				  context
 * IRQD_IRQ_DISABLED		- Some chip function need to know the
 *				  disabled state.
 * IRQD_IRQ_DISABLED		- Disabled state of the interrupt
 * IRQD_IRQ_MASKED		- Masked state of the interrupt
 * IRQD_IRQ_INPROGRESS		- In progress state of the interrupt
 */
enum {
	IRQD_TRIGGER_MASK		= 0xf,
@@ -187,6 +188,8 @@ enum {
	IRQD_WAKEUP_STATE		= (1 << 14),
	IRQD_MOVE_PCNTXT		= (1 << 15),
	IRQD_IRQ_DISABLED		= (1 << 16),
	IRQD_IRQ_MASKED			= (1 << 17),
	IRQD_IRQ_INPROGRESS		= (1 << 18),
};

static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
@@ -243,6 +246,16 @@ static inline bool irqd_irq_disabled(struct irq_data *d)
	return d->state_use_accessors & IRQD_IRQ_DISABLED;
}

static inline bool irqd_irq_masked(struct irq_data *d)
{
	return d->state_use_accessors & IRQD_IRQ_MASKED;
}

static inline bool irqd_irq_inprogress(struct irq_data *d)
{
	return d->state_use_accessors & IRQD_IRQ_INPROGRESS;
}

/**
 * struct irq_chip - hardware interrupt chip descriptor
 *
+19 −21
Original line number Diff line number Diff line
@@ -140,27 +140,25 @@ EXPORT_SYMBOL_GPL(irq_get_irq_data);

static void irq_state_clr_disabled(struct irq_desc *desc)
{
	desc->istate &= ~IRQS_DISABLED;
	irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED);
	irq_compat_clr_disabled(desc);
}

static void irq_state_set_disabled(struct irq_desc *desc)
{
	desc->istate |= IRQS_DISABLED;
	irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
	irq_compat_set_disabled(desc);
}

static void irq_state_clr_masked(struct irq_desc *desc)
{
	desc->istate &= ~IRQS_MASKED;
	irqd_clear(&desc->irq_data, IRQD_IRQ_MASKED);
	irq_compat_clr_masked(desc);
}

static void irq_state_set_masked(struct irq_desc *desc)
{
	desc->istate |= IRQS_MASKED;
	irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
	irq_compat_set_masked(desc);
}

@@ -380,11 +378,11 @@ void handle_nested_irq(unsigned int irq)
	kstat_incr_irqs_this_cpu(irq, desc);

	action = desc->action;
	if (unlikely(!action || (desc->istate & IRQS_DISABLED)))
	if (unlikely(!action || irqd_irq_disabled(&desc->irq_data)))
		goto out_unlock;

	irq_compat_set_progress(desc);
	desc->istate |= IRQS_INPROGRESS;
	irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	raw_spin_unlock_irq(&desc->lock);

	action_ret = action->thread_fn(action->irq, action->dev_id);
@@ -392,7 +390,7 @@ void handle_nested_irq(unsigned int irq)
		note_interrupt(irq, desc, action_ret);

	raw_spin_lock_irq(&desc->lock);
	desc->istate &= ~IRQS_INPROGRESS;
	irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	irq_compat_clr_progress(desc);

out_unlock:
@@ -424,14 +422,14 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
{
	raw_spin_lock(&desc->lock);

	if (unlikely(desc->istate & IRQS_INPROGRESS))
	if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
		if (!irq_check_poll(desc))
			goto out_unlock;

	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
	kstat_incr_irqs_this_cpu(irq, desc);

	if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED)))
	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
		goto out_unlock;

	handle_irq_event(desc);
@@ -456,7 +454,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
	raw_spin_lock(&desc->lock);
	mask_ack_irq(desc);

	if (unlikely(desc->istate & IRQS_INPROGRESS))
	if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
		if (!irq_check_poll(desc))
			goto out_unlock;

@@ -467,12 +465,12 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
	 * If its disabled or no action available
	 * keep it masked and get out of here
	 */
	if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED)))
	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
		goto out_unlock;

	handle_irq_event(desc);

	if (!(desc->istate & (IRQS_DISABLED | IRQS_ONESHOT)))
	if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
		unmask_irq(desc);
out_unlock:
	raw_spin_unlock(&desc->lock);
@@ -504,7 +502,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
{
	raw_spin_lock(&desc->lock);

	if (unlikely(desc->istate & IRQS_INPROGRESS))
	if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
		if (!irq_check_poll(desc))
			goto out;

@@ -515,7 +513,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
	 * If its disabled or no action available
	 * then mask it and get out of here:
	 */
	if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) {
	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
		irq_compat_set_pending(desc);
		desc->istate |= IRQS_PENDING;
		mask_irq(desc);
@@ -566,8 +564,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
	 * we shouldn't process the IRQ. Mark it pending, handle
	 * the necessary masking and go out
	 */
	if (unlikely((desc->istate & (IRQS_DISABLED | IRQS_INPROGRESS) ||
		      !desc->action))) {
	if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
		     irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
		if (!irq_check_poll(desc)) {
			irq_compat_set_pending(desc);
			desc->istate |= IRQS_PENDING;
@@ -592,15 +590,15 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
		 * Renable it, if it was not disabled in meantime.
		 */
		if (unlikely(desc->istate & IRQS_PENDING)) {
			if (!(desc->istate & IRQS_DISABLED) &&
			    (desc->istate & IRQS_MASKED))
			if (!irqd_irq_disabled(&desc->irq_data) &&
			    irqd_irq_masked(&desc->irq_data))
				unmask_irq(desc);
		}

		handle_irq_event(desc);

	} while ((desc->istate & IRQS_PENDING) &&
		 !(desc->istate & IRQS_DISABLED));
		 !irqd_irq_disabled(&desc->irq_data));

out_unlock:
	raw_spin_unlock(&desc->lock);
@@ -720,7 +718,7 @@ void irq_cpu_online(void)
		chip = irq_data_get_irq_chip(&desc->irq_data);
		if (chip && chip->irq_cpu_online &&
		    (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
		     !(desc->istate & IRQS_DISABLED)))
		     !irqd_irq_disabled(&desc->irq_data)))
			chip->irq_cpu_online(&desc->irq_data);

		raw_spin_unlock_irqrestore(&desc->lock, flags);
@@ -750,7 +748,7 @@ void irq_cpu_offline(void)
		chip = irq_data_get_irq_chip(&desc->irq_data);
		if (chip && chip->irq_cpu_offline &&
		    (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
		     !(desc->istate & IRQS_DISABLED)))
		     !irqd_irq_disabled(&desc->irq_data)))
			chip->irq_cpu_offline(&desc->irq_data);

		raw_spin_unlock_irqrestore(&desc->lock, flags);
+7 −3
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@

#define P(f) if (desc->status & f) printk("%14s set\n", #f)
#define PS(f) if (desc->istate & f) printk("%14s set\n", #f)
/* FIXME */
#define PD(f) do { } while (0)

static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
{
@@ -28,13 +30,15 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
	P(IRQ_NOAUTOEN);

	PS(IRQS_AUTODETECT);
	PS(IRQS_INPROGRESS);
	PS(IRQS_REPLAY);
	PS(IRQS_WAITING);
	PS(IRQS_DISABLED);
	PS(IRQS_PENDING);
	PS(IRQS_MASKED);

	PD(IRQS_INPROGRESS);
	PD(IRQS_DISABLED);
	PD(IRQS_MASKED);
}

#undef P
#undef PS
#undef PD
+2 −2
Original line number Diff line number Diff line
@@ -178,13 +178,13 @@ irqreturn_t handle_irq_event(struct irq_desc *desc)
	irq_compat_clr_pending(desc);
	desc->istate &= ~IRQS_PENDING;
	irq_compat_set_progress(desc);
	desc->istate |= IRQS_INPROGRESS;
	irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	raw_spin_unlock(&desc->lock);

	ret = handle_irq_event_percpu(desc, action);

	raw_spin_lock(&desc->lock);
	desc->istate &= ~IRQS_INPROGRESS;
	irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	irq_compat_clr_progress(desc);
	return ret;
}
+0 −6
Original line number Diff line number Diff line
@@ -44,26 +44,20 @@ enum {
 * IRQS_SPURIOUS_DISABLED	- was disabled due to spurious interrupt
 *				  detection
 * IRQS_POLL_INPROGRESS		- polling in progress
 * IRQS_INPROGRESS		- Interrupt in progress
 * IRQS_ONESHOT			- irq is not unmasked in primary handler
 * IRQS_REPLAY			- irq is replayed
 * IRQS_WAITING			- irq is waiting
 * IRQS_DISABLED		- irq is disabled
 * IRQS_PENDING			- irq is pending and replayed later
 * IRQS_MASKED			- irq is masked
 * IRQS_SUSPENDED		- irq is suspended
 */
enum {
	IRQS_AUTODETECT		= 0x00000001,
	IRQS_SPURIOUS_DISABLED	= 0x00000002,
	IRQS_POLL_INPROGRESS	= 0x00000008,
	IRQS_INPROGRESS		= 0x00000010,
	IRQS_ONESHOT		= 0x00000020,
	IRQS_REPLAY		= 0x00000040,
	IRQS_WAITING		= 0x00000080,
	IRQS_DISABLED		= 0x00000100,
	IRQS_PENDING		= 0x00000200,
	IRQS_MASKED		= 0x00000400,
	IRQS_SUSPENDED		= 0x00000800,
};

Loading