Skip to content

Commit

Permalink
mfd: palmas: Provide irq flags through DT/platform data
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Laxman Dewangan authored and Samuel Ortiz committed Mar 12, 2013
1 parent 5c854aa commit df545d1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
36 changes: 33 additions & 3 deletions drivers/mfd/palmas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/linux/mfd/palmas.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ struct palmas_clk_platform_data {
};

struct palmas_platform_data {
int irq_flags;
int gpio_base;

/* bit value to be loaded to the POWER_CTRL register */
Expand Down

0 comments on commit df545d1

Please sign in to comment.