Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: ezx-pcap: Replace mutex_lock with spin_lock

As mutex_lock might sleep. Function pcap_adc_irq is an interrupt handler.
The use of mutex_lock in pcap_adc_irq may cause sleep in IRQ context.
Replace mutex_lock with spin_lock to avoid this.

Signed-off-by: Fuqian Huang <huangfq.daxian@gmail.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Fuqian Huang and committed by
Lee Jones
b65dc4f6 5cd690a3

+30 -23
+30 -23
drivers/mfd/ezx-pcap.c
··· 35 35 36 36 /* IO */ 37 37 u32 buf; 38 - struct mutex io_mutex; 38 + spinlock_t io_lock; 39 39 40 40 /* IRQ */ 41 41 unsigned int irq_base; ··· 48 48 struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ]; 49 49 u8 adc_head; 50 50 u8 adc_tail; 51 - struct mutex adc_mutex; 51 + spinlock_t adc_lock; 52 52 }; 53 53 54 54 /* IO */ ··· 76 76 77 77 int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value) 78 78 { 79 + unsigned long flags; 79 80 int ret; 80 81 81 - mutex_lock(&pcap->io_mutex); 82 + spin_lock_irqsave(&pcap->io_lock, flags); 82 83 value &= PCAP_REGISTER_VALUE_MASK; 83 84 value |= PCAP_REGISTER_WRITE_OP_BIT 84 85 | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); 85 86 ret = ezx_pcap_putget(pcap, &value); 86 - mutex_unlock(&pcap->io_mutex); 87 + spin_unlock_irqrestore(&pcap->io_lock, flags); 87 88 88 89 return ret; 89 90 } ··· 92 91 93 92 int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value) 94 93 { 94 + unsigned long flags; 95 95 int ret; 96 96 97 - mutex_lock(&pcap->io_mutex); 97 + spin_lock_irqsave(&pcap->io_lock, flags); 98 98 *value = PCAP_REGISTER_READ_OP_BIT 99 99 | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); 100 100 101 101 ret = ezx_pcap_putget(pcap, value); 102 - mutex_unlock(&pcap->io_mutex); 102 + spin_unlock_irqrestore(&pcap->io_lock, flags); 103 103 104 104 return ret; 105 105 } ··· 108 106 109 107 int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val) 110 108 { 109 + unsigned long flags; 111 110 int ret; 112 111 u32 tmp = PCAP_REGISTER_READ_OP_BIT | 113 112 (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); 114 113 115 - mutex_lock(&pcap->io_mutex); 114 + spin_lock_irqsave(&pcap->io_lock, flags); 116 115 ret = ezx_pcap_putget(pcap, &tmp); 117 116 if (ret) 118 117 goto out_unlock; ··· 124 121 125 122 ret = ezx_pcap_putget(pcap, &tmp); 126 123 out_unlock: 127 - mutex_unlock(&pcap->io_mutex); 124 + spin_unlock_irqrestore(&pcap->io_lock, flags); 128 125 129 126 return ret; 130 127 } ··· 215 212 /* ADC */ 216 213 void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits) 217 214 { 215 + unsigned long flags; 218 216 u32 tmp; 219 217 220 - mutex_lock(&pcap->adc_mutex); 218 + spin_lock_irqsave(&pcap->adc_lock, flags); 221 219 ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); 222 220 tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); 223 221 tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); 224 222 ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); 225 - mutex_unlock(&pcap->adc_mutex); 223 + spin_unlock_irqrestore(&pcap->adc_lock, flags); 226 224 } 227 225 EXPORT_SYMBOL_GPL(pcap_set_ts_bits); 228 226 ··· 238 234 239 235 static void pcap_adc_trigger(struct pcap_chip *pcap) 240 236 { 237 + unsigned long flags; 241 238 u32 tmp; 242 239 u8 head; 243 240 244 - mutex_lock(&pcap->adc_mutex); 241 + spin_lock_irqsave(&pcap->adc_lock, flags); 245 242 head = pcap->adc_head; 246 243 if (!pcap->adc_queue[head]) { 247 244 /* queue is empty, save power */ 248 245 pcap_disable_adc(pcap); 249 - mutex_unlock(&pcap->adc_mutex); 246 + spin_unlock_irqrestore(&pcap->adc_lock, flags); 250 247 return; 251 248 } 252 249 /* start conversion on requested bank, save TS_M bits */ ··· 259 254 tmp |= PCAP_ADC_AD_SEL1; 260 255 261 256 ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); 262 - mutex_unlock(&pcap->adc_mutex); 257 + spin_unlock_irqrestore(&pcap->adc_lock, flags); 263 258 ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC); 264 259 } 265 260 ··· 270 265 u16 res[2]; 271 266 u32 tmp; 272 267 273 - mutex_lock(&pcap->adc_mutex); 268 + spin_lock(&pcap->adc_lock); 274 269 req = pcap->adc_queue[pcap->adc_head]; 275 270 276 271 if (WARN(!req, "adc irq without pending request\n")) { 277 - mutex_unlock(&pcap->adc_mutex); 272 + spin_unlock(&pcap->adc_lock); 278 273 return IRQ_HANDLED; 279 274 } 280 275 ··· 290 285 291 286 pcap->adc_queue[pcap->adc_head] = NULL; 292 287 pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1); 293 - mutex_unlock(&pcap->adc_mutex); 288 + spin_unlock(&pcap->adc_lock); 294 289 295 290 /* pass the results and release memory */ 296 291 req->callback(req->data, res); ··· 306 301 void *callback, void *data) 307 302 { 308 303 struct pcap_adc_request *req; 304 + unsigned long irq_flags; 309 305 310 306 /* This will be freed after we have a result */ 311 307 req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL); ··· 320 314 req->callback = callback; 321 315 req->data = data; 322 316 323 - mutex_lock(&pcap->adc_mutex); 317 + spin_lock_irqsave(&pcap->adc_lock, irq_flags); 324 318 if (pcap->adc_queue[pcap->adc_tail]) { 325 - mutex_unlock(&pcap->adc_mutex); 319 + spin_unlock_irqrestore(&pcap->adc_lock, irq_flags); 326 320 kfree(req); 327 321 return -EBUSY; 328 322 } 329 323 pcap->adc_queue[pcap->adc_tail] = req; 330 324 pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1); 331 - mutex_unlock(&pcap->adc_mutex); 325 + spin_unlock_irqrestore(&pcap->adc_lock, irq_flags); 332 326 333 327 /* start conversion */ 334 328 pcap_adc_trigger(pcap); ··· 395 389 static int ezx_pcap_remove(struct spi_device *spi) 396 390 { 397 391 struct pcap_chip *pcap = spi_get_drvdata(spi); 392 + unsigned long flags; 398 393 int i; 399 394 400 395 /* remove all registered subdevs */ 401 396 device_for_each_child(&spi->dev, NULL, pcap_remove_subdev); 402 397 403 398 /* cleanup ADC */ 404 - mutex_lock(&pcap->adc_mutex); 399 + spin_lock_irqsave(&pcap->adc_lock, flags); 405 400 for (i = 0; i < PCAP_ADC_MAXQ; i++) 406 401 kfree(pcap->adc_queue[i]); 407 - mutex_unlock(&pcap->adc_mutex); 402 + spin_unlock_irqrestore(&pcap->adc_lock, flags); 408 403 409 404 /* cleanup irqchip */ 410 405 for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) ··· 433 426 goto ret; 434 427 } 435 428 436 - mutex_init(&pcap->io_mutex); 437 - mutex_init(&pcap->adc_mutex); 429 + spin_lock_init(&pcap->io_lock); 430 + spin_lock_init(&pcap->adc_lock); 438 431 INIT_WORK(&pcap->isr_work, pcap_isr_work); 439 432 INIT_WORK(&pcap->msr_work, pcap_msr_work); 440 433 spi_set_drvdata(spi, pcap);