i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue

iproc_i2c_rd_reg() and iproc_i2c_wr_reg() are called from both
interrupt context (e.g. bcm_iproc_i2c_isr) and process context
(e.g. bcm_iproc_i2c_suspend). Therefore, interrupts should be
disabled to avoid potential deadlock. To prevent this scenario,
use spin_lock_irqsave().

Fixes: 9a1038728037 ("i2c: iproc: add NIC I2C support")
Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
Acked-by: Ray Jui <ray.jui@broadcom.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Signed-off-by: Wolfram Sang <wsa@kernel.org>

authored by Chengfeng Ye and committed by Wolfram Sang 4caf4cb1 7d711966

Changed files
+7 -4
drivers
i2c
+7 -4
drivers/i2c/busses/i2c-bcm-iproc.c
··· 233 233 u32 offset) 234 234 { 235 235 u32 val; 236 + unsigned long flags; 236 237 237 238 if (iproc_i2c->idm_base) { 238 - spin_lock(&iproc_i2c->idm_lock); 239 + spin_lock_irqsave(&iproc_i2c->idm_lock, flags); 239 240 writel(iproc_i2c->ape_addr_mask, 240 241 iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); 241 242 val = readl(iproc_i2c->base + offset); 242 - spin_unlock(&iproc_i2c->idm_lock); 243 + spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); 243 244 } else { 244 245 val = readl(iproc_i2c->base + offset); 245 246 } ··· 251 250 static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c, 252 251 u32 offset, u32 val) 253 252 { 253 + unsigned long flags; 254 + 254 255 if (iproc_i2c->idm_base) { 255 - spin_lock(&iproc_i2c->idm_lock); 256 + spin_lock_irqsave(&iproc_i2c->idm_lock, flags); 256 257 writel(iproc_i2c->ape_addr_mask, 257 258 iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); 258 259 writel(val, iproc_i2c->base + offset); 259 - spin_unlock(&iproc_i2c->idm_lock); 260 + spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); 260 261 } else { 261 262 writel(val, iproc_i2c->base + offset); 262 263 }