Skip to content

Commit

Permalink
mfd: Add irq domain support for max8997 interrupts
Browse files Browse the repository at this point in the history
Add irq domain support for max8997 interrupts. The reverse mapping method
used is linear mapping since the sub-drivers of max8997 such as regulator
and charger drivers can use the max8997 irq_domain to get the linux irq
number for max8997 interrupts. All uses of irq_base in platform data and
max8997 driver private data are removed.

Reviwed-by: Mark Brown <[email protected]>
Acked-by: MyungJoo Ham <[email protected]>
Acked-by: Grant Likely <[email protected]>
Signed-off-by: Thomas Abraham <[email protected]>
Signed-off-by: Chanwoo Choi <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
Thomas Abraham authored and Samuel Ortiz committed Jul 8, 2012
1 parent bad7699 commit b41511f
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 33 deletions.
4 changes: 0 additions & 4 deletions arch/arm/mach-exynos/mach-nuri.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,12 +1067,8 @@ static struct platform_device nuri_max8903_device = {
static void __init nuri_power_init(void)
{
int gpio;
int irq_base = IRQ_GPIO_END + 1;
int ta_en = 0;

nuri_max8997_pdata.irq_base = irq_base;
irq_base += MAX8997_IRQ_NR;

gpio = EXYNOS4_GPX0(7);
gpio_request(gpio, "AP_PMIC_IRQ");
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
Expand Down
1 change: 0 additions & 1 deletion arch/arm/mach-exynos/mach-origen.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
.buck1_gpiodvs = false,
.buck2_gpiodvs = false,
.buck5_gpiodvs = false,
.irq_base = IRQ_GPIO_END + 1,

.ignore_gpiodvs_side_effect = true,
.buck125_default_idx = 0x0,
Expand Down
1 change: 1 addition & 0 deletions drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ config MFD_MAX8997
bool "Maxim Semiconductor MAX8997/8966 PMIC Support"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select IRQ_DOMAIN
help
Say yes here to support for Maxim Semiconductor MAX8997/8966.
This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
Expand Down
62 changes: 37 additions & 25 deletions drivers/mfd/max8997-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
static const inline struct max8997_irq_data *
irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
{
return &max8997_irqs[irq - max8997->irq_base];
struct irq_data *data = irq_get_irq_data(irq);
return &max8997_irqs[data->hwirq];
}

static void max8997_irq_mask(struct irq_data *data)
Expand Down Expand Up @@ -182,7 +183,7 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)
u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
u8 irq_src;
int ret;
int i;
int i, cur_irq;

ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
if (ret < 0) {
Expand Down Expand Up @@ -269,35 +270,52 @@ static irqreturn_t max8997_irq_thread(int irq, void *data)

/* Report */
for (i = 0; i < MAX8997_IRQ_NR; i++) {
if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
handle_nested_irq(max8997->irq_base + i);
if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask) {
cur_irq = irq_find_mapping(max8997->irq_domain, i);
if (cur_irq)
handle_nested_irq(cur_irq);
}
}

return IRQ_HANDLED;
}

int max8997_irq_resume(struct max8997_dev *max8997)
{
if (max8997->irq && max8997->irq_base)
max8997_irq_thread(max8997->irq_base, max8997);
if (max8997->irq && max8997->irq_domain)
max8997_irq_thread(0, max8997);
return 0;
}

static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
struct max8997_dev *max8997 = d->host_data;

irq_set_chip_data(irq, max8997);
irq_set_chip_and_handler(irq, &max8997_irq_chip, handle_edge_irq);
irq_set_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
return 0;
}

static struct irq_domain_ops max8997_irq_domain_ops = {
.map = max8997_irq_domain_map,
};

int max8997_irq_init(struct max8997_dev *max8997)
{
struct irq_domain *domain;
int i;
int cur_irq;
int ret;
u8 val;

if (!max8997->irq) {
dev_warn(max8997->dev, "No interrupt specified.\n");
max8997->irq_base = 0;
return 0;
}

if (!max8997->irq_base) {
dev_err(max8997->dev, "No interrupt base specified.\n");
return 0;
}

Expand Down Expand Up @@ -327,19 +345,13 @@ int max8997_irq_init(struct max8997_dev *max8997)
true : false;
}

/* Register with genirq */
for (i = 0; i < MAX8997_IRQ_NR; i++) {
cur_irq = i + max8997->irq_base;
irq_set_chip_data(cur_irq, max8997);
irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
handle_edge_irq);
irq_set_nested_thread(cur_irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(cur_irq, IRQF_VALID);
#else
irq_set_noprobe(cur_irq);
#endif
domain = irq_domain_add_linear(NULL, MAX8997_IRQ_NR,
&max8997_irq_domain_ops, max8997);
if (!domain) {
dev_err(max8997->dev, "could not create irq domain\n");
return -ENODEV;
}
max8997->irq_domain = domain;

ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
Expand Down
1 change: 0 additions & 1 deletion drivers/mfd/max8997.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
if (!pdata)
goto err;

max8997->irq_base = pdata->irq_base;
max8997->ono = pdata->ono;

mutex_init(&max8997->iolock);
Expand Down
4 changes: 3 additions & 1 deletion include/linux/mfd/max8997-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#define __LINUX_MFD_MAX8997_PRIV_H

#include <linux/i2c.h>
#include <linux/export.h>
#include <linux/irqdomain.h>

#define MAX8997_REG_INVALID (0xff)

Expand Down Expand Up @@ -325,7 +327,7 @@ struct max8997_dev {

int irq;
int ono;
int irq_base;
struct irq_domain *irq_domain;
struct mutex irqlock;
int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
Expand Down
1 change: 0 additions & 1 deletion include/linux/mfd/max8997.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ struct max8997_led_platform_data {

struct max8997_platform_data {
/* IRQ */
int irq_base;
int ono;
int wakeup;

Expand Down

0 comments on commit b41511f

Please sign in to comment.