From 57b851d2af03a8cb77a3d2b34b6041f4f31d9d9d Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Thu, 13 Feb 2020 11:07:49 -0800 Subject: [PATCH] eud: Handle multiple events with eud interrupt With USB spoof connect functionality, eud hardware is generating interrupt with status register updated with VBUS present and TX buffer empty. Current eud ISR expects to have only single event generated with each interrupt. It doesn't handle received valid events. Fix this ISR logic to handle multiple events. Change-Id: I819b8a7f5be5b32753467495416103b690a4a83e Signed-off-by: Mayank Rana --- drivers/soc/qcom/eud.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/soc/qcom/eud.c b/drivers/soc/qcom/eud.c index 6b750473d068..a1045a720bf1 100644 --- a/drivers/soc/qcom/eud.c +++ b/drivers/soc/qcom/eud.c @@ -453,41 +453,53 @@ static void eud_uart_tx(struct eud_chip *chip) static irqreturn_t handle_eud_irq(int irq, void *data) { struct eud_chip *chip = data; - u32 reg; + u8 reg; u32 int_mask_en1 = readl_relaxed(chip->eud_reg_base + EUD_REG_INT1_EN_MASK); /* read status register and find out which interrupt triggered */ - reg = readl_relaxed(chip->eud_reg_base + EUD_REG_INT_STATUS_1); - switch (reg & EUD_INT_ALL) { - case EUD_INT_RX: + reg = readb_relaxed(chip->eud_reg_base + EUD_REG_INT_STATUS_1); + dev_dbg(chip->dev, "EUD Interrupt is received status:%x\n", reg); + + if (reg & EUD_INT_RX) { dev_dbg(chip->dev, "EUD RX Interrupt is received\n"); eud_uart_rx(chip); - break; - case EUD_INT_TX: + reg &= ~EUD_INT_RX; + } + + if (reg & EUD_INT_TX) { if (EUD_INT_TX & int_mask_en1) { dev_dbg(chip->dev, "EUD TX Interrupt is received\n"); eud_uart_tx(chip); } - break; - case EUD_INT_VBUS: + reg &= ~EUD_INT_TX; + } + + if (reg & EUD_INT_VBUS) { dev_dbg(chip->dev, "EUD VBUS Interrupt is received\n"); chip->int_status = EUD_INT_VBUS; usb_attach_detach(chip); - break; - case EUD_INT_CHGR: + reg &= ~EUD_INT_VBUS; + } + + if (reg & EUD_INT_CHGR) { dev_dbg(chip->dev, "EUD CHGR Interrupt is received\n"); chip->int_status = EUD_INT_CHGR; chgr_enable_disable(chip); - break; - case EUD_INT_SAFE_MODE: + reg &= ~EUD_INT_CHGR; + } + + if (reg & EUD_INT_SAFE_MODE) { dev_dbg(chip->dev, "EUD SAFE MODE Interrupt is received\n"); pet_eud(chip); - break; - default: - dev_dbg(chip->dev, "Unknown EUD Interrupt is received\n"); + reg &= ~EUD_INT_SAFE_MODE; + } + + if (reg) { + dev_dbg(chip->dev, "Unhandled EUD interrupt status:%x\n", reg); return IRQ_NONE; } + return IRQ_HANDLED; }