summaryrefslogtreecommitdiff
path: root/drivers/mfd/tps65217.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-19 08:16:26 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-19 08:16:26 -0800
commitac5a28b0d3d173ba0a581342416ed339f2c3be3d (patch)
treea6c891c1874507679acd613c83674f1662b1665f /drivers/mfd/tps65217.c
parentb0b3a37b908b5906524c11f3ca12cd7c9d4adc1c (diff)
parent93559191e71bc0f862638b0a9644d4592452a5db (diff)
Merge tag 'mfd-for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "New Device Support - Add support for Ricoh RC5T619 PMIC to rn5t618 - Add support for PM8821 PMIC to qcom-pm8xxx New Functionality: - Add support for GPIO to lpc_ich - Add support for GPADC to sun4i - Add ability for rk808 to shutdown Fix-ups: - Simplify/strip unnecessary code; tps65218, palmas, tps65217 - Device Tree binding updates; tps65218, altera-a10sr - Provide/export device ID info; tps65218, axp20x-i2c, hi655x-pmic, fsl-imx25-tsadc, intel_soc_pmic_bxtwc - Use MFD API instead of of_platform_populate(); tps65218 - Generalise name-space; pm8xxx - Supply/edit regmap configuration; axp20x, cs47l24-tables, axp20x - Enable compile testing; max77620, max77686, exynos-lpass, abx500-core - Coding style issues; wm8994-core, wm5102-tables - Supply endian support; syscon - Remove module support; ab3100-core, ab8500-debugfs, ab8500-gpadc, abx500-core Bug Fixes: - Fix ordering issues; wm8994 - Fix dependencies (build-time/run-time); exynos_lpass, sun4i-gpadc - Fix compiler warnings; sun4i-gpadc - Fix leaks; mfd-core - Fix page fault during module unload; tps65217" * tag 'mfd-for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (49 commits) mfd: tps65217: Support an interrupt pin as the system wakeup mfd: tps65217: Make an interrupt handler simpler mfd: tps65217: Update register interrupt mask bits instead of writing operation mfd: tps65217: Specify the IRQ name mfd: tps65217: Fix page fault on unloading modules mfd: palmas: Remove redundant check in palmas_power_off mfd: arizona: Disable IRQs during driver remove mfd: pm8xxx: add support to pm8821 mfd: intel-lpss: Try to enable Memory-Write-Invalidate mfd: rn5t618: Add Ricoh RC5T619 PMIC support mfd: axp20x: Add address extension registers for AXP806 regmap mfd: intel_soc_pmic_bxtwc: Fix a typo in MODULE_DEVICE_TABLE() mfd: core: Fix device reference leak in mfd_clone_cell mfd: bcm590xx: Simplify a test mfd: sun4i-gpadc: Select regmap-irq mfd: abx500-core: drop unused MODULE_ tags from non-modular code mfd: ab8500: make sysctrl explicitly non-modular mfd: ab8500-gpadc: Make it explicitly non-modular mfd: ab8500-debugfs: Make it explicitly non-modular mfd: ab8500-core: Make it explicitly non-modular ...
Diffstat (limited to 'drivers/mfd/tps65217.c')
-rw-r--r--drivers/mfd/tps65217.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 9a4d8684dd32..f769c7d4e335 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -42,26 +42,6 @@ static struct resource pb_resources[] = {
DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
};
-struct tps65217_irq {
- int mask;
- int interrupt;
-};
-
-static const struct tps65217_irq tps65217_irqs[] = {
- [TPS65217_IRQ_PB] = {
- .mask = TPS65217_INT_PBM,
- .interrupt = TPS65217_INT_PBI,
- },
- [TPS65217_IRQ_AC] = {
- .mask = TPS65217_INT_ACM,
- .interrupt = TPS65217_INT_ACI,
- },
- [TPS65217_IRQ_USB] = {
- .mask = TPS65217_INT_USBM,
- .interrupt = TPS65217_INT_USBI,
- },
-};
-
static void tps65217_irq_lock(struct irq_data *data)
{
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
@@ -74,37 +54,32 @@ static void tps65217_irq_sync_unlock(struct irq_data *data)
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
int ret;
- ret = tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
- TPS65217_PROTECT_NONE);
+ ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
+ tps->irq_mask, TPS65217_PROTECT_NONE);
if (ret != 0)
dev_err(tps->dev, "Failed to sync IRQ masks\n");
mutex_unlock(&tps->irq_lock);
}
-static inline const struct tps65217_irq *
-irq_to_tps65217_irq(struct tps65217 *tps, struct irq_data *data)
-{
- return &tps65217_irqs[data->hwirq];
-}
-
static void tps65217_irq_enable(struct irq_data *data)
{
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
- const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
+ u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
- tps->irq_mask &= ~irq_data->mask;
+ tps->irq_mask &= ~mask;
}
static void tps65217_irq_disable(struct irq_data *data)
{
struct tps65217 *tps = irq_data_get_irq_chip_data(data);
- const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
+ u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
- tps->irq_mask |= irq_data->mask;
+ tps->irq_mask |= mask;
}
static struct irq_chip tps65217_irq_chip = {
+ .name = "tps65217",
.irq_bus_lock = tps65217_irq_lock,
.irq_bus_sync_unlock = tps65217_irq_sync_unlock,
.irq_enable = tps65217_irq_enable,
@@ -149,8 +124,8 @@ static irqreturn_t tps65217_irq_thread(int irq, void *data)
return IRQ_NONE;
}
- for (i = 0; i < ARRAY_SIZE(tps65217_irqs); i++) {
- if (status & tps65217_irqs[i].interrupt) {
+ for (i = 0; i < TPS65217_NUM_IRQ; i++) {
+ if (status & BIT(i)) {
handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
handled = true;
}
@@ -188,10 +163,9 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
tps->irq = irq;
/* Mask all interrupt sources */
- tps->irq_mask = (TPS65217_INT_RESERVEDM | TPS65217_INT_PBM
- | TPS65217_INT_ACM | TPS65217_INT_USBM);
- tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
- TPS65217_PROTECT_NONE);
+ tps->irq_mask = TPS65217_INT_MASK;
+ tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
+ TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
@@ -209,6 +183,8 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
return ret;
}
+ enable_irq_wake(irq);
+
return 0;
}
@@ -424,6 +400,24 @@ static int tps65217_probe(struct i2c_client *client,
return 0;
}
+static int tps65217_remove(struct i2c_client *client)
+{
+ struct tps65217 *tps = i2c_get_clientdata(client);
+ unsigned int virq;
+ int i;
+
+ for (i = 0; i < TPS65217_NUM_IRQ; i++) {
+ virq = irq_find_mapping(tps->irq_domain, i);
+ if (virq)
+ irq_dispose_mapping(virq);
+ }
+
+ irq_domain_remove(tps->irq_domain);
+ tps->irq_domain = NULL;
+
+ return 0;
+}
+
static const struct i2c_device_id tps65217_id_table[] = {
{"tps65217", TPS65217},
{ /* sentinel */ }
@@ -437,6 +431,7 @@ static struct i2c_driver tps65217_driver = {
},
.id_table = tps65217_id_table,
.probe = tps65217_probe,
+ .remove = tps65217_remove,
};
static int __init tps65217_init(void)