diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-01 07:28:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-01 07:28:14 -0400 |
commit | 06e23d51151fd06c225c80ace26675532bdf406d (patch) | |
tree | 25d869bed6c4bdfd9addb799c72941e08c162ac2 /drivers/mfd/max77620.c | |
parent | dd9671172a06830071c8edb31fb2176f222a2c6e (diff) | |
parent | f37be01e6dc606f2fcc5e95c9933d948ce19bd35 (diff) |
Merge tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"Core Framework:
- New API to call bespoke pre/post IRQ handlers; Regmap
New Device Support:
- Add support for RN5T567 to rn5t618
- Add support for COMe-cSL6 and COMe-mAL10 to kempld-core
New Functionality:
- Add support for USB Power Supply to axp20x
- Add support for Power Key to hi655x-pmic
Fix-ups:
- Update MAINTAINERS; Dialog, Altera
- Remove module support; max77843, max77620, max8998, max8997, max8925-i2c
- Add module support; max14577
- Constifying; max77620
- Allow bespoke IRQ masking/unmasking; max77620
- Remove superfluous code; arizona, qcom_rpm, smsc-ece1099
- Power Management fixups; arizona-core
- Error-path improvement; twl-core, dm355evm_msp, smsc-ece1099, hi655x
- Clocking fixups; twl6040
- Trivial (spelling, headers, coding-style, whitespace, (re)naming);
si476x-i2c, omap-usb-tll, ti_am335x_tscadc, tps6507, hi655x-pmic
Bug Fixes:
- Fix offset error for MSM8660; qcom_rpm
- Fix possible spurious IRQs; arizona, hi655x-pmic"
* tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (42 commits)
mfd: qcom_rpm: Parametrize also ack selector size
mfd: twl6040: Handle mclk used for HPPLL and optional internal clock source
mfd: Add support for COMe-cSL6 and COMe-mAL10 to Kontron PLD driver
mfd: hi655x: Fix return value check in hi655x_pmic_probe()
mfd: smsc-ece1099: Return directly after a function failure in smsc_i2c_probe()
mfd: smsc-ece1099: Delete an unnecessary variable initialisation in smsc_i2c_probe()
mfd: dm355evm_msp: Return directly after a failed platform_device_alloc() in add_child()
mfd: twl-core: Refactoring for add_numbered_child()
mfd: twl-core: Return directly after a failed platform_device_alloc() in add_numbered_child()
mfd: arizona: Add missing disable of PM runtime on probe error path
mfd: stmpe: Move platform data into MFD driver
mfd: max14577: Allow driver to be built as a module
mfd: max14577: Use module_init() instead of subsys_initcall()
mfd: arizona: Remove some duplicate defines
mfd: qcom_rpm: Remove unused define
mfd: hi655x-pmic: Add powerkey device to hi655x PMIC driver
mfd: hi655x-pmic: Rename some interrupt macro names
mfd: hi655x-pmic: Fixup issue with un-acked interrupts
mfd: arizona: Check if AOD interrupts are pending before dispatching
mfd: qcom_rpm: Fix offset error for msm8660
...
Diffstat (limited to 'drivers/mfd/max77620.c')
-rw-r--r-- | drivers/mfd/max77620.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index f32fbb8e8129..258757e216c4 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -31,25 +31,25 @@ #include <linux/interrupt.h> #include <linux/mfd/core.h> #include <linux/mfd/max77620.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/regmap.h> #include <linux/slab.h> -static struct resource gpio_resources[] = { +static const struct resource gpio_resources[] = { DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO), }; -static struct resource power_resources[] = { +static const struct resource power_resources[] = { DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW), }; -static struct resource rtc_resources[] = { +static const struct resource rtc_resources[] = { DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC), }; -static struct resource thermal_resources[] = { +static const struct resource thermal_resources[] = { DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1), DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2), }; @@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = { }, }; -static struct regmap_irq_chip max77620_top_irq_chip = { - .name = "max77620-top", - .irqs = max77620_top_irqs, - .num_irqs = ARRAY_SIZE(max77620_top_irqs), - .num_regs = 2, - .status_base = MAX77620_REG_IRQTOP, - .mask_base = MAX77620_REG_IRQTOPM, -}; - static const struct regmap_range max77620_readable_ranges[] = { regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4), }; @@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = { .volatile_table = &max77620_volatile_table, }; +/* + * MAX77620 and MAX20024 has the following steps of the interrupt handling + * for TOP interrupts: + * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM. + * 2. Read IRQTOP and service the interrupt. + * 3. Once all interrupts has been checked and serviced, the interrupt service + * routine un-masks the hardware interrupt line by clearing GLBLM. + */ +static int max77620_irq_global_mask(void *irq_drv_data) +{ + struct max77620_chip *chip = irq_drv_data; + int ret; + + ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT, + MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK); + if (ret < 0) + dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret); + + return ret; +} + +static int max77620_irq_global_unmask(void *irq_drv_data) +{ + struct max77620_chip *chip = irq_drv_data; + int ret; + + ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT, + MAX77620_GLBLM_MASK, 0); + if (ret < 0) + dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret); + + return ret; +} + +static struct regmap_irq_chip max77620_top_irq_chip = { + .name = "max77620-top", + .irqs = max77620_top_irqs, + .num_irqs = ARRAY_SIZE(max77620_top_irqs), + .num_regs = 2, + .status_base = MAX77620_REG_IRQTOP, + .mask_base = MAX77620_REG_IRQTOPM, + .handle_pre_irq = max77620_irq_global_mask, + .handle_post_irq = max77620_irq_global_unmask, +}; + /* max77620_get_fps_period_reg_value: Get FPS bit field value from * requested periods. * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560 @@ -433,6 +469,7 @@ static int max77620_probe(struct i2c_client *client, if (ret < 0) return ret; + max77620_top_irq_chip.irq_drv_data = chip; ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, IRQF_ONESHOT | IRQF_SHARED, chip->irq_base, &max77620_top_irq_chip, @@ -568,7 +605,6 @@ static const struct i2c_device_id max77620_id[] = { {"max20024", MAX20024}, {}, }; -MODULE_DEVICE_TABLE(i2c, max77620_id); static const struct dev_pm_ops max77620_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume) @@ -582,11 +618,4 @@ static struct i2c_driver max77620_driver = { .probe = max77620_probe, .id_table = max77620_id, }; - -module_i2c_driver(max77620_driver); - -MODULE_DESCRIPTION("MAX77620/MAX20024 Multi Function Device Core Driver"); -MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); -MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>"); -MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>"); -MODULE_LICENSE("GPL v2"); +builtin_i2c_driver(max77620_driver); |