summaryrefslogtreecommitdiffstats
path: root/drivers/mfd/palmas.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-03-01 15:43:46 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2013-03-12 09:25:49 +0100
commitdf545d1cd01aab3ba3f687d5423e6c3687b069d8 (patch)
treea492f6d8bfe0ea5d1684d14bf9a6109c749f89dd /drivers/mfd/palmas.c
parentmfd: Make AB8500_CORE select POWER_SUPPLY to fix build error (diff)
downloadlinux-df545d1cd01aab3ba3f687d5423e6c3687b069d8.tar.xz
linux-df545d1cd01aab3ba3f687d5423e6c3687b069d8.zip
mfd: palmas: Provide irq flags through DT/platform data
Currently driver sets the irq type to IRQF_TRIGGER_LOW which is causing interrupt registration failure in ARM based SoCs as: [ 0.208479] genirq: Setting trigger mode 8 for irq 118 failed (gic_set_type+0x0/0xf0) [ 0.208513] dummy 0-0059: Failed to request IRQ 118: -22 Provide the irq flags through platform data if device is registered through board file or get the irq type from DT node property in place of hardcoding the irq flag in driver to support multiple platforms. Also configure the device to generate the interrupt signal according to flag type. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/palmas.c')
-rw-r--r--drivers/mfd/palmas.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index bbdbc50a3cca..73bf76df1044 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -257,9 +257,24 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
-static void palmas_dt_to_pdata(struct device_node *node,
+static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
struct palmas_platform_data *pdata)
{
+ struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
+ if (!irq_data) {
+ dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
+ return -EINVAL;
+ }
+
+ pdata->irq_flags = irqd_get_trigger_type(irq_data);
+ dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags);
+ return 0;
+}
+
+static void palmas_dt_to_pdata(struct i2c_client *i2c,
+ struct palmas_platform_data *pdata)
+{
+ struct device_node *node = i2c->dev.of_node;
int ret;
u32 prop;
@@ -283,6 +298,8 @@ static void palmas_dt_to_pdata(struct device_node *node,
pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
PALMAS_POWER_CTRL_ENABLE1_MASK |
PALMAS_POWER_CTRL_ENABLE2_MASK;
+ if (i2c->irq)
+ palmas_set_pdata_irq_flag(i2c, pdata);
}
static int palmas_i2c_probe(struct i2c_client *i2c,
@@ -304,7 +321,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
if (!pdata)
return -ENOMEM;
- palmas_dt_to_pdata(node, pdata);
+ palmas_dt_to_pdata(i2c, pdata);
}
if (!pdata)
@@ -344,6 +361,19 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
}
}
+ /* Change interrupt line output polarity */
+ if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH)
+ reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
+ else
+ reg = 0;
+ ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE,
+ PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY,
+ reg);
+ if (ret < 0) {
+ dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
+ goto err;
+ }
+
/* Change IRQ into clear on read mode for efficiency */
slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
@@ -352,7 +382,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
regmap_write(palmas->regmap[slave], addr, reg);
ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
- IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
+ IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
&palmas->irq_data);
if (ret < 0)
goto err;