aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2018-09-24 19:52:35 -0400
committerWolfram Sang <wsa@the-dreams.de>2018-10-11 17:09:58 -0400
commita676973e4501991e2ede959ee69c6553caa29038 (patch)
tree1bad2429946e2a9968916e752b2242ff9650a5ac
parentef8d1639f2b71c683277cc2b27354541792f6ecf (diff)
i2c: i2c-qcom-geni: Simplify irq handler
We don't need to use goto here, we can just collapse the if statement and goto chain into multiple branches and then combine some duplicate completion calls into one big if statement. Let's do it to clean up code some more. Signed-off-by: Stephen Boyd <swboyd@chromium.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Alok Chauhan <alokc@codeaurora.org> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-qcom-geni.c70
1 files changed, 29 insertions, 41 deletions
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 0b466835cf40..527f55c8c4c7 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -201,21 +201,23 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
201static irqreturn_t geni_i2c_irq(int irq, void *dev) 201static irqreturn_t geni_i2c_irq(int irq, void *dev)
202{ 202{
203 struct geni_i2c_dev *gi2c = dev; 203 struct geni_i2c_dev *gi2c = dev;
204 int j; 204 void __iomem *base = gi2c->se.base;
205 int j, p;
205 u32 m_stat; 206 u32 m_stat;
206 u32 rx_st; 207 u32 rx_st;
207 u32 dm_tx_st; 208 u32 dm_tx_st;
208 u32 dm_rx_st; 209 u32 dm_rx_st;
209 u32 dma; 210 u32 dma;
211 u32 val;
210 struct i2c_msg *cur; 212 struct i2c_msg *cur;
211 unsigned long flags; 213 unsigned long flags;
212 214
213 spin_lock_irqsave(&gi2c->lock, flags); 215 spin_lock_irqsave(&gi2c->lock, flags);
214 m_stat = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS); 216 m_stat = readl_relaxed(base + SE_GENI_M_IRQ_STATUS);
215 rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS); 217 rx_st = readl_relaxed(base + SE_GENI_RX_FIFO_STATUS);
216 dm_tx_st = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT); 218 dm_tx_st = readl_relaxed(base + SE_DMA_TX_IRQ_STAT);
217 dm_rx_st = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT); 219 dm_rx_st = readl_relaxed(base + SE_DMA_RX_IRQ_STAT);
218 dma = readl_relaxed(gi2c->se.base + SE_GENI_DMA_MODE_EN); 220 dma = readl_relaxed(base + SE_GENI_DMA_MODE_EN);
219 cur = gi2c->cur; 221 cur = gi2c->cur;
220 222
221 if (!cur || 223 if (!cur ||
@@ -238,26 +240,17 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
238 240
239 /* Disable the TX Watermark interrupt to stop TX */ 241 /* Disable the TX Watermark interrupt to stop TX */
240 if (!dma) 242 if (!dma)
241 writel_relaxed(0, gi2c->se.base + 243 writel_relaxed(0, base + SE_GENI_TX_WATERMARK_REG);
242 SE_GENI_TX_WATERMARK_REG); 244 } else if (dma) {
243 goto irqret;
244 }
245
246 if (dma) {
247 dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n", 245 dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
248 dm_tx_st, dm_rx_st); 246 dm_tx_st, dm_rx_st);
249 goto irqret; 247 } else if (cur->flags & I2C_M_RD &&
250 } 248 m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
251
252 if (cur->flags & I2C_M_RD &&
253 m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
254 u32 rxcnt = rx_st & RX_FIFO_WC_MSK; 249 u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
255 250
256 for (j = 0; j < rxcnt; j++) { 251 for (j = 0; j < rxcnt; j++) {
257 u32 val; 252 p = 0;
258 int p = 0; 253 val = readl_relaxed(base + SE_GENI_RX_FIFOn);
259
260 val = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFOn);
261 while (gi2c->cur_rd < cur->len && p < sizeof(val)) { 254 while (gi2c->cur_rd < cur->len && p < sizeof(val)) {
262 cur->buf[gi2c->cur_rd++] = val & 0xff; 255 cur->buf[gi2c->cur_rd++] = val & 0xff;
263 val >>= 8; 256 val >>= 8;
@@ -270,44 +263,39 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
270 m_stat & M_TX_FIFO_WATERMARK_EN) { 263 m_stat & M_TX_FIFO_WATERMARK_EN) {
271 for (j = 0; j < gi2c->tx_wm; j++) { 264 for (j = 0; j < gi2c->tx_wm; j++) {
272 u32 temp; 265 u32 temp;
273 u32 val = 0;
274 int p = 0;
275 266
267 val = 0;
268 p = 0;
276 while (gi2c->cur_wr < cur->len && p < sizeof(val)) { 269 while (gi2c->cur_wr < cur->len && p < sizeof(val)) {
277 temp = cur->buf[gi2c->cur_wr++]; 270 temp = cur->buf[gi2c->cur_wr++];
278 val |= temp << (p * 8); 271 val |= temp << (p * 8);
279 p++; 272 p++;
280 } 273 }
281 writel_relaxed(val, gi2c->se.base + SE_GENI_TX_FIFOn); 274 writel_relaxed(val, base + SE_GENI_TX_FIFOn);
282 /* TX Complete, Disable the TX Watermark interrupt */ 275 /* TX Complete, Disable the TX Watermark interrupt */
283 if (gi2c->cur_wr == cur->len) { 276 if (gi2c->cur_wr == cur->len) {
284 writel_relaxed(0, gi2c->se.base + 277 writel_relaxed(0, base + SE_GENI_TX_WATERMARK_REG);
285 SE_GENI_TX_WATERMARK_REG);
286 break; 278 break;
287 } 279 }
288 } 280 }
289 } 281 }
290irqret: 282
291 if (m_stat) 283 if (m_stat)
292 writel_relaxed(m_stat, gi2c->se.base + SE_GENI_M_IRQ_CLEAR); 284 writel_relaxed(m_stat, base + SE_GENI_M_IRQ_CLEAR);
285
286 if (dma && dm_tx_st)
287 writel_relaxed(dm_tx_st, base + SE_DMA_TX_IRQ_CLR);
288 if (dma && dm_rx_st)
289 writel_relaxed(dm_rx_st, base + SE_DMA_RX_IRQ_CLR);
293 290
294 if (dma) {
295 if (dm_tx_st)
296 writel_relaxed(dm_tx_st, gi2c->se.base +
297 SE_DMA_TX_IRQ_CLR);
298 if (dm_rx_st)
299 writel_relaxed(dm_rx_st, gi2c->se.base +
300 SE_DMA_RX_IRQ_CLR);
301 }
302 /* if this is err with done-bit not set, handle that through timeout. */ 291 /* if this is err with done-bit not set, handle that through timeout. */
303 if (m_stat & M_CMD_DONE_EN || m_stat & M_CMD_ABORT_EN) 292 if (m_stat & M_CMD_DONE_EN || m_stat & M_CMD_ABORT_EN ||
304 complete(&gi2c->done); 293 dm_tx_st & TX_DMA_DONE || dm_tx_st & TX_RESET_DONE ||
305 else if (dm_tx_st & TX_DMA_DONE || dm_tx_st & TX_RESET_DONE) 294 dm_rx_st & RX_DMA_DONE || dm_rx_st & RX_RESET_DONE)
306 complete(&gi2c->done);
307 else if (dm_rx_st & RX_DMA_DONE || dm_rx_st & RX_RESET_DONE)
308 complete(&gi2c->done); 295 complete(&gi2c->done);
309 296
310 spin_unlock_irqrestore(&gi2c->lock, flags); 297 spin_unlock_irqrestore(&gi2c->lock, flags);
298
311 return IRQ_HANDLED; 299 return IRQ_HANDLED;
312} 300}
313 301