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

mfd: Use completion interrupt for WM835x AUXADC

Use the completion interrupt generated by the device rather than
polling for conversions to complete. As a backup we still check
the state of the AUXADC if we don't get a completion, mostly for
systems that don't have the WM8350 interrupt infrastructure hooked
up.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Mark Brown and committed by
Samuel Ortiz
d19663ac 11a441ce

+31 -6
+29 -6
drivers/mfd/wm8350-core.c
··· 339 339 int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) 340 340 { 341 341 u16 reg, result = 0; 342 - int tries = 5; 343 342 344 343 if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) 345 344 return -EINVAL; ··· 362 363 reg |= 1 << channel | WM8350_AUXADC_POLL; 363 364 wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); 364 365 365 - do { 366 - schedule_timeout_interruptible(1); 367 - reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); 368 - } while ((reg & WM8350_AUXADC_POLL) && --tries); 366 + /* We ignore the result of the completion and just check for a 367 + * conversion result, allowing us to soldier on if the IRQ 368 + * infrastructure is not set up for the chip. */ 369 + wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5)); 369 370 370 - if (!tries) 371 + reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); 372 + if (reg & WM8350_AUXADC_POLL) 371 373 dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); 372 374 else 373 375 result = wm8350_reg_read(wm8350, ··· 384 384 return result & WM8350_AUXADC_DATA1_MASK; 385 385 } 386 386 EXPORT_SYMBOL_GPL(wm8350_read_auxadc); 387 + 388 + static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data) 389 + { 390 + struct wm8350 *wm8350 = irq_data; 391 + 392 + complete(&wm8350->auxadc_done); 393 + 394 + return IRQ_HANDLED; 395 + } 387 396 388 397 /* 389 398 * Cache is always host endian. ··· 691 682 } 692 683 693 684 mutex_init(&wm8350->auxadc_mutex); 685 + init_completion(&wm8350->auxadc_done); 694 686 695 687 ret = wm8350_irq_init(wm8350, irq, pdata); 696 688 if (ret < 0) 697 689 goto err; 690 + 691 + if (wm8350->irq_base) { 692 + ret = request_threaded_irq(wm8350->irq_base + 693 + WM8350_IRQ_AUXADC_DATARDY, 694 + NULL, wm8350_auxadc_irq, 0, 695 + "auxadc", wm8350); 696 + if (ret < 0) 697 + dev_warn(wm8350->dev, 698 + "Failed to request AUXADC IRQ: %d\n", ret); 699 + } 698 700 699 701 if (pdata && pdata->init) { 700 702 ret = pdata->init(wm8350); ··· 755 735 platform_device_unregister(wm8350->hwmon.pdev); 756 736 platform_device_unregister(wm8350->gpio.pdev); 757 737 platform_device_unregister(wm8350->codec.pdev); 738 + 739 + if (wm8350->irq_base) 740 + free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); 758 741 759 742 wm8350_irq_exit(wm8350); 760 743
+2
include/linux/mfd/wm8350/core.h
··· 16 16 #include <linux/kernel.h> 17 17 #include <linux/mutex.h> 18 18 #include <linux/interrupt.h> 19 + #include <linux/completion.h> 19 20 20 21 #include <linux/mfd/wm8350/audio.h> 21 22 #include <linux/mfd/wm8350/gpio.h> ··· 622 621 u16 *reg_cache; 623 622 624 623 struct mutex auxadc_mutex; 624 + struct completion auxadc_done; 625 625 626 626 /* Interrupt handling */ 627 627 struct mutex irq_lock;