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

Commit df613361 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drivers: mfd: donot clear interrupt status" into msm-4.9

parents 902465e1 f4ea7f31
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -293,7 +293,7 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1);
	struct wcd9xxx_core_resource *wcd9xxx_res = data;
	int num_irq_regs = wcd9xxx_res->num_irq_regs;
	u8 status[num_irq_regs], status1[num_irq_regs];
	u8 status[4], status1[4] = {0}, unmask_status[4] = {0};

	if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) {
		dev_err(wcd9xxx_res->dev, "Failed to hold suspend\n");
@@ -317,6 +317,23 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
				"Failed to read interrupt status: %d\n", ret);
		goto err_disable_irq;
	}
	/*
	 * If status is 0 return without clearing.
	 * status contains: HW status - masked interrupts
	 * status1 contains: unhandled interrupts - masked interrupts
	 * unmasked_status contains: unhandled interrupts
	 */
	if (unlikely(!memcmp(status, status1, sizeof(status)))) {
		pr_debug("%s: status is 0\n", __func__);
		wcd9xxx_unlock_sleep(wcd9xxx_res);
		return IRQ_HANDLED;
	}

	/*
	 * Copy status to unmask_status before masking, otherwise SW may miss
	 * to clear masked interrupt in corner case.
	 */
	memcpy(unmask_status, status, sizeof(unmask_status));

	/* Apply masking */
	for (i = 0; i < num_irq_regs; i++)
@@ -340,6 +357,8 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
			wcd9xxx_irq_dispatch(wcd9xxx_res, &irqdata);
			status1[BIT_BYTE(irqdata.intr_num)] &=
					~BYTE_BIT_MASK(irqdata.intr_num);
			unmask_status[BIT_BYTE(irqdata.intr_num)] &=
					~BYTE_BIT_MASK(irqdata.intr_num);
		}
	}

@@ -361,12 +380,13 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
					   linebuf, sizeof(linebuf), false);
			pr_warn("%s: status1 : %s\n", __func__, linebuf);
		}

		memset(status, 0xff, num_irq_regs);

		/*
		 * unmask_status contains unhandled interrupts, hence clear all
		 * unhandled interrupts.
		 */
		ret = regmap_bulk_write(wcd9xxx_res->wcd_core_regmap,
			wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE],
			status, num_irq_regs);
			unmask_status, num_irq_regs);
		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
			regmap_write(wcd9xxx_res->wcd_core_regmap,
				wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],