diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-23 19:37:49 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-23 19:37:49 -0700 |
| commit | 4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc (patch) | |
| tree | 531c3121c4d1502c98d5a18903bac50b6d5be1b3 | |
| parent | d0b3cfee333eb7eecb6ce72f06f5a02d249b9bdf (diff) | |
| parent | 8391c6cb2414d9a75bbe247a838d28cb0cee77ee (diff) | |
| download | linux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.tar.gz linux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.tar.bz2 linux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.zip | |
Merge tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"New Drivers:
- Add support for Merrifield Basin Cove PMIC
New Device Support:
- Add support for Intel Tiger Lake to Intel LPSS PCI
- Add support for Intel Sky Lake to Intel LPSS PCI
- Add support for ST-Ericsson DB8520 to DB8500 PRCMU
New Functionality:
- Add RTC and PWRC support to MT6323
Fix-ups:
- Clean-up include files; davinci_voicecodec, asic3, sm501, mt6397
- Ignore return values from debugfs_create*(); ab3100-*, ab8500-debugfs, aat2870-core
- Device Tree changes; rn5t618, mt6397
- Use new I2C API; tps80031, 88pm860x-core, ab3100-core, bcm590xx,
da9150-core, max14577, max77693, max77843, max8907,
max8925-i2c, max8997, max8998, palmas, twl-core,
- Remove obsolete code; da9063, jz4740-adc
- Simplify semantics; timberdale, htc-i2cpld
- Add 'fall-through' tags; omap-usb-host, db8500-prcmu
- Remove superfluous prints; ab8500-debugfs, db8500-prcmu, fsl-imx25-tsadc,
intel_soc_pmic_bxtwc, qcom_rpm, sm501
- Trivial rename/whitespace/typo fixes; mt6397-core, MAINTAINERS
- Reorganise code structure; mt6397-*
- Improve code consistency; intel-lpss
- Use MODULE_SOFTDEP() helper; intel-lpss
- Use DEFINE_RES_*() helpers; mt6397-core
Bug Fixes:
- Clean-up resources; max77620
- Prevent input events being dropped on resume; intel-lpss-pci
- Prevent sleeping in IRQ context; ezx-pcap"
* tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (48 commits)
mfd: mt6323: Add MT6323 RTC and PWRC
mfd: mt6323: Replace boilerplate resource code with DEFINE_RES_* macros
mfd: mt6397: Add mutex include
dt-bindings: mfd: mediatek: Add MT6323 Power Controller
dt-bindings: mfd: mediatek: Update RTC to include MT6323
dt-bindings: mfd: mediatek: mt6397: Change to relative paths
mfd: db8500-prcmu: Support the higher DB8520 ARMSS
mfd: intel-lpss: Use MODULE_SOFTDEP() instead of implicit request
mfd: htc-i2cpld: Drop check because i2c_unregister_device() is NULL safe
mfd: sm501: Include the GPIO driver header
mfd: intel-lpss: Add Intel Skylake ACPI IDs
mfd: intel-lpss: Consistently use GENMASK()
mfd: Add support for Merrifield Basin Cove PMIC
mfd: ezx-pcap: Replace mutex_lock with spin_lock
mfd: asic3: Include the right header
MAINTAINERS: altera-sysmgr: Fix typo in a filepath
mfd: mt6397: Extract IRQ related code from core driver
mfd: mt6397: Rename macros to something more readable
mfd: Remove dev_err() usage after platform_get_irq()
mfd: db8500-prcmu: Mark expected switch fall-throughs
...
45 files changed, 742 insertions, 727 deletions
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt index 0ebd08af777d..a9b105ac00a8 100644 --- a/Documentation/devicetree/bindings/mfd/mt6397.txt +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt @@ -8,11 +8,12 @@ MT6397/MT6323 is a multifunction device with the following sub modules: - Clock - LED - Keys +- Power controller It is interfaced to host controller using SPI interface by a proprietary hardware called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap. See the following for pwarp node definitions: -Documentation/devicetree/bindings/soc/mediatek/pwrap.txt +../soc/mediatek/pwrap.txt This document describes the binding for MFD device and its sub module. @@ -22,14 +23,16 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323" Optional subnodes: - rtc - Required properties: + Required properties: Should be one of follows + - compatible: "mediatek,mt6323-rtc" - compatible: "mediatek,mt6397-rtc" + For details, see ../rtc/rtc-mt6397.txt - regulators Required properties: - compatible: "mediatek,mt6397-regulator" - see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt + see ../regulator/mt6397-regulator.txt - compatible: "mediatek,mt6323-regulator" - see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt + see ../regulator/mt6323-regulator.txt - codec Required properties: - compatible: "mediatek,mt6397-codec" @@ -39,12 +42,17 @@ Optional subnodes: - led Required properties: - compatible: "mediatek,mt6323-led" - see Documentation/devicetree/bindings/leds/leds-mt6323.txt + see ../leds/leds-mt6323.txt - keys Required properties: - compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" - see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt + see ../input/mtk-pmic-keys.txt + +- power-controller + Required properties: + - compatible: "mediatek,mt6323-pwrc" + For details, see ../power/reset/mt6323-poweroff.txt Example: pwrap: pwrap@1000f000 { diff --git a/Documentation/devicetree/bindings/mfd/rn5t618.txt b/Documentation/devicetree/bindings/mfd/rn5t618.txt index 65c23263cc54..b74e5e94d1cb 100644 --- a/Documentation/devicetree/bindings/mfd/rn5t618.txt +++ b/Documentation/devicetree/bindings/mfd/rn5t618.txt @@ -14,6 +14,10 @@ Required properties: "ricoh,rc5t619" - reg: the I2C slave address of the device +Optional properties: + - system-power-controller: + See Documentation/devicetree/bindings/power/power-controller.txt + Sub-nodes: - regulators: the node is required if the regulator functionality is needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4 @@ -28,6 +32,7 @@ Example: pmic@32 { compatible = "ricoh,rn5t618"; reg = <0x32>; + system-power-controller; regulators { DCDC1 { diff --git a/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt new file mode 100644 index 000000000000..933f0c48e887 --- /dev/null +++ b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt @@ -0,0 +1,20 @@ +Device Tree Bindings for Power Controller on MediaTek PMIC + +The power controller which could be found on PMIC is responsible for externally +powering off or on the remote MediaTek SoC through the circuit BBPU. + +Required properties: +- compatible: Should be one of follows + "mediatek,mt6323-pwrc": for MT6323 PMIC + +Example: + + pmic { + compatible = "mediatek,mt6323"; + + ... + + power-controller { + compatible = "mediatek,mt6323-pwrc"; + }; + } diff --git a/MAINTAINERS b/MAINTAINERS index 1360243a7ff3..54f1286087e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -728,7 +728,7 @@ ALTERA SYSTEM MANAGER DRIVER M: Thor Thayer <thor.thayer@linux.intel.com> S: Maintained F: drivers/mfd/altera-sysmgr.c -F: include/linux/mfd/altera-sysgmr.h +F: include/linux/mfd/altera-sysmgr.h ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT M: Thor Thayer <thor.thayer@linux.intel.com> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index f2d9fb4c4e8e..4e8d0d6b9b5c 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -425,10 +425,10 @@ static int pm800_pages_init(struct pm80x_chip *chip) return -ENODEV; /* PM800 block power page */ - subchip->power_page = i2c_new_dummy(client->adapter, + subchip->power_page = i2c_new_dummy_device(client->adapter, subchip->power_page_addr); - if (subchip->power_page == NULL) { - ret = -ENODEV; + if (IS_ERR(subchip->power_page)) { + ret = PTR_ERR(subchip->power_page); goto out; } @@ -444,10 +444,10 @@ static int pm800_pages_init(struct pm80x_chip *chip) i2c_set_clientdata(subchip->power_page, chip); /* PM800 block GPADC */ - subchip->gpadc_page = i2c_new_dummy(client->adapter, + subchip->gpadc_page = i2c_new_dummy_device(client->adapter, subchip->gpadc_page_addr); - if (subchip->gpadc_page == NULL) { - ret = -ENODEV; + if (IS_ERR(subchip->gpadc_page)) { + ret = PTR_ERR(subchip->gpadc_page); goto out; } diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 9e0bd135730f..c9bae71f643a 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -1178,12 +1178,12 @@ static int pm860x_probe(struct i2c_client *client) */ if (pdata->companion_addr && (pdata->companion_addr != client->addr)) { chip->companion_addr = pdata->companion_addr; - chip->companion = i2c_new_dummy(chip->client->adapter, + chip->companion = i2c_new_dummy_device(chip->client->adapter, chip->companion_addr); - if (!chip->companion) { + if (IS_ERR(chip->companion)) { dev_err(&client->dev, "Failed to allocate I2C companion device\n"); - return -ENODEV; + return PTR_ERR(chip->companion); } chip->regmap_companion = regmap_init_i2c(chip->companion, &pm860x_regmap_config); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index c9c49da42446..ae24d3ea68ea 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -589,6 +589,17 @@ config INTEL_SOC_PMIC_CHTDC_TI Select this option for supporting Dollar Cove (TI version) PMIC device that is found on some Intel Cherry Trail systems. +config INTEL_SOC_PMIC_MRFLD + tristate "Support for Intel Merrifield Basin Cove PMIC" + depends on GPIOLIB + depends on ACPI + depends on INTEL_SCU_IPC + select MFD_CORE + select REGMAP_IRQ + help + Select this option for supporting Basin Cove PMIC device + that is found on Intel Merrifield systems. + config MFD_INTEL_LPSS tristate select COMMON_CLK @@ -641,15 +652,6 @@ config MFD_JANZ_CMODIO host many different types of MODULbus daughterboards, including CAN and GPIO controllers. -config MFD_JZ4740_ADC - bool "Janz JZ4740 ADC core" - select MFD_CORE - select GENERIC_IRQ_CHIP - depends on MACH_JZ4740 - help - Say yes here if you want support for the ADC unit in the JZ4740 SoC. - This driver is necessary for jz4740-battery and jz4740-hwmon driver. - config MFD_KEMPLD tristate "Kontron module PLD device" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 0c0a848e62df..c1067ea46204 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -189,7 +189,6 @@ obj-$(CONFIG_LPC_SCH) += lpc_sch.o obj-$(CONFIG_LPC_ICH) += lpc_ich.o obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o -obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o @@ -239,7 +238,9 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o -obj-$(CONFIG_MFD_MT6397) += mt6397-core.o +mt6397-objs := mt6397-core.o mt6397-irq.o +obj-$(CONFIG_MFD_MT6397) += mt6397.o +obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 9f3dbc31d3e9..57723f116bb5 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -865,10 +865,10 @@ static int ab3100_probe(struct i2c_client *client, &ab3100->chip_name[0]); /* Attach a second dummy i2c_client to the test register address */ - ab3100->testreg_client = i2c_new_dummy(client->adapter, + ab3100->testreg_client = i2c_new_dummy_device(client->adapter, client->addr + 1); - if (!ab3100->testreg_client) { - err = -ENOMEM; + if (IS_ERR(ab3100->testreg_client)) { + err = PTR_ERR(ab3100->testreg_client); goto exit_no_testreg_client; } diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 567a34b073dd..f4e26b6e5362 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -2680,16 +2680,12 @@ static int ab8500_debug_probe(struct platform_device *plf) irq_ab8500 = res->start; irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); - if (irq_first < 0) { - dev_err(&plf->dev, "First irq not found, err %d\n", irq_first); + if (irq_first < 0) return irq_first; - } irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); - if (irq_last < 0) { - dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last); + if (irq_last < 0) return irq_last; - } ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 83b18c998d6f..a6bd2134cea2 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/irq.h> -#include <linux/gpio.h> +#include <linux/gpio/driver.h> #include <linux/export.h> #include <linux/io.h> #include <linux/slab.h> diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c index 1aeb5e498d91..bfac5dc091ca 100644 --- a/drivers/mfd/bcm590xx.c +++ b/drivers/mfd/bcm590xx.c @@ -61,11 +61,11 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri, } /* Secondary I2C slave address is the base address with A(2) asserted */ - bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter, + bcm590xx->i2c_sec = i2c_new_dummy_device(i2c_pri->adapter, i2c_pri->addr | BIT(2)); - if (!bcm590xx->i2c_sec) { + if (IS_ERR(bcm590xx->i2c_sec)) { dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n"); - return -ENODEV; + return PTR_ERR(bcm590xx->i2c_sec); } i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx); diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index 13033068721a..7f0aa1e8db96 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -420,10 +420,10 @@ static int da9150_probe(struct i2c_client *client, qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A); qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1; qif_addr |= DA9150_QIF_I2C_ADDR_LSB; - da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr); - if (!da9150->core_qif) { + da9150->core_qif = i2c_new_dummy_device(client->adapter, qif_addr); + if (IS_ERR(da9150->core_qif)) { dev_err(da9150->dev, "Failed to attach QIF client\n"); - return -ENODEV; + return PTR_ERR(da9150->core_qif); } i2c_set_clientdata(da9150->core_qif, da9150); diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 13ca7203e193..e5c8bc998eb4 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -19,7 +19,6 @@ #include <sound/pcm.h> #include <linux/mfd/davinci_voicecodec.h> -#include <mach/hardware.h> static const struct regmap_config davinci_vc_regmap = { .reg_bits = 32, @@ -31,6 +30,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) struct davinci_vc *davinci_vc; struct resource *res; struct mfd_cell *cell = NULL; + dma_addr_t fifo_base; int ret; davinci_vc = devm_kzalloc(&pdev->dev, @@ -48,6 +48,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + fifo_base = (dma_addr_t)res->start; davinci_vc->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(davinci_vc->base)) { ret = PTR_ERR(davinci_vc->base); @@ -70,8 +71,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) } davinci_vc->davinci_vcif.dma_tx_channel = res->start; - davinci_vc->davinci_vcif.dma_tx_addr = - (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); + davinci_vc->davinci_vcif.dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO; res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { @@ -81,8 +81,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) } davinci_vc->davinci_vcif.dma_rx_channel = res->start; - davinci_vc->davinci_vcif.dma_rx_addr = - (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); + davinci_vc->davinci_vcif.dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO; davinci_vc->dev = &pdev->dev; davinci_vc->pdev = pdev; diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 90e0f21bc49c..0e019cc5da42 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -1695,21 +1695,41 @@ static long round_clock_rate(u8 clock, unsigned long rate) return rounded_rate; } -static const unsigned long armss_freqs[] = { +static const unsigned long db8500_armss_freqs[] = { 200000000, 400000000, 800000000, 998400000 }; +/* The DB8520 has slightly higher ARMSS max frequency */ +static const unsigned long db8520_armss_freqs[] = { + 200000000, + 400000000, + 800000000, + 1152000000 +}; + + + static long round_armss_rate(unsigned long rate) { unsigned long freq = 0; + const unsigned long *freqs; + int nfreqs; int i; + if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) { + freqs = db8520_armss_freqs; + nfreqs = ARRAY_SIZE(db8520_armss_freqs); + } else { + freqs = db8500_armss_freqs; + nfreqs = ARRAY_SIZE(db8500_armss_freqs); + } + /* Find the corresponding arm opp from the cpufreq table. */ - for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) { - freq = armss_freqs[i]; + for (i = 0; i < nfreqs; i++) { + freq = freqs[i]; if (rate <= freq) break; } @@ -1854,11 +1874,21 @@ static int set_armss_rate(unsigned long rate) { unsigned long freq; u8 opps[] = { ARM_EXTCLK, ARM_50_OPP, ARM_100_OPP, ARM_MAX_OPP }; + const unsigned long *freqs; + int nfreqs; int i; + if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) { + freqs = db8520_armss_freqs; + nfreqs = ARRAY_SIZE(db8520_armss_freqs); + } else { + freqs = db8500_armss_freqs; + nfreqs = ARRAY_SIZE(db8500_armss_freqs); + } + /* Find the corresponding arm opp from the cpufreq table. */ - for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) { - freq = armss_freqs[i]; + for (i = 0; i < nfreqs; i++) { + freq = freqs[i]; if (rate == freq) break; } @@ -3130,10 +3160,8 @@ static int db8500_prcmu_probe(struct platform_device *pdev) writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - dev_err(&pdev->dev, "no prcmu irq provided\n"); + if (irq <= 0) return irq; - } err = request_threaded_irq(irq, prcmu_irq_handler, prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index f505e3e1274b..70fa18b04ad2 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c @@ -35,7 +35,7 @@ struct pcap_chip { /* IO */ u32 buf; - struct mutex io_mutex; + spinlock_t io_lock; /* IRQ */ unsigned int irq_base; @@ -48,7 +48,7 @@ struct pcap_chip { struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ]; u8 adc_head; u8 adc_tail; - struct mutex adc_mutex; + spinlock_t adc_lock; }; /* IO */ @@ -76,14 +76,15 @@ static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data) int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value) { + unsigned long flags; int ret; - mutex_lock(&pcap->io_mutex); + spin_lock_irqsave(&pcap->io_lock, flags); value &= PCAP_REGISTER_VALUE_MASK; value |= PCAP_REGISTER_WRITE_OP_BIT | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); ret = ezx_pcap_putget(pcap, &value); - mutex_unlock(&pcap->io_mutex); + spin_unlock_irqrestore(&pcap->io_lock, flags); return ret; } @@ -91,14 +92,15 @@ EXPORT_SYMBOL_GPL(ezx_pcap_write); int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value) { + unsigned long flags; int ret; - mutex_lock(&pcap->io_mutex); + spin_lock_irqsave(&pcap->io_lock, flags); *value = PCAP_REGISTER_READ_OP_BIT | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); ret = ezx_pcap_putget(pcap, value); - mutex_unlock(&pcap->io_mutex); + spin_unlock_irqrestore(&pcap->io_lock, flags); return ret; } @@ -106,11 +108,12 @@ EXPORT_SYMBOL_GPL(ezx_pcap_read); int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val) { + unsigned long flags; int ret; u32 tmp = PCAP_REGISTER_READ_OP_BIT | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT); - mutex_lock(&pcap->io_mutex); + spin_lock_irqsave(&pcap->io_lock, flags); ret = ezx_pcap_putget(pcap, &tmp); if (ret) goto out_unlock; @@ -121,7 +124,7 @@ int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val) ret = ezx_pcap_putget(pcap, &tmp); out_unlock: - mutex_unlock(&pcap->io_mutex); + spin_unlock_irqrestore(&pcap->io_lock, flags); return ret; } @@ -212,14 +215,15 @@ static void pcap_irq_handler(struct irq_desc *desc) /* ADC */ void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits) { + unsigned long flags; u32 tmp; - mutex_lock(&pcap->adc_mutex); + spin_lock_irqsave(&pcap->adc_lock, flags); ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR); ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); - mutex_unlock(&pcap->adc_mutex); + spin_unlock_irqrestore(&pcap->adc_lock, flags); } EXPORT_SYMBOL_GPL(pcap_set_ts_bits); @@ -234,15 +238,16 @@ static void pcap_disable_adc(struct pcap_chip *pcap) static void pcap_adc_trigger(struct pcap_chip *pcap) { + unsigned long flags; u32 tmp; u8 head; - mutex_lock(&pcap->adc_mutex); + spin_lock_irqsave(&pcap->adc_lock, flags); head = pcap->adc_head; if (!pcap->adc_queue[head]) { /* queue is empty, save power */ pcap_disable_adc(pcap); - mutex_unlock(&pcap->adc_mutex); + spin_unlock_irqrestore(&pcap->adc_lock, flags); return; } /* start conversion on requested bank, save TS_M bits */ @@ -254,7 +259,7 @@ static void pcap_adc_trigger(struct pcap_chip *pcap) tmp |= PCAP_ADC_AD_SEL1; ezx_pcap_write(pcap, PCAP_REG_ADC, tmp); - mutex_unlock(&pcap->adc_mutex); + spin_unlock_irqrestore(&pcap->adc_lock, flags); ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC); } @@ -265,11 +270,11 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) u16 res[2]; u32 tmp; - mutex_lock(&pcap->adc_mutex); + spin_lock(&pcap->adc_lock); req = pcap->adc_queue[pcap->adc_head]; if (WARN(!req, "adc irq without pending request\n")) { - mutex_unlock(&pcap->adc_mutex); + spin_unlock(&pcap->adc_lock); return IRQ_HANDLED; } @@ -285,7 +290,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) pcap->adc_queue[pcap->adc_head] = NULL; pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1); - mutex_unlock(&pcap->adc_mutex); + spin_unlock(&pcap->adc_lock); /* pass the results and release memory */ req->callback(req->data, res); @@ -301,6 +306,7 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[], void *callback, void *data) { struct pcap_adc_request *req; + unsigned long irq_flags; /* This will be freed after we have a result * |
