* [PATCH v2 0/2] mfd: max77693: improve regmap support @ 2014-04-29 5:48 Robert Baldyga 2014-04-29 5:48 ` [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions Robert Baldyga 2014-04-29 5:48 ` [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap Robert Baldyga 0 siblings, 2 replies; 8+ messages in thread From: Robert Baldyga @ 2014-04-29 5:48 UTC (permalink / raw) To: sameo, lee.jones Cc: a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski, Robert Baldyga This patchset modifies max77693 driver and associated function drivers to improve regmap support. It removes unnecessary wrapper functions, which make code more clean, and modifies IRQ handling to use regmap irq. Best regards Robert Baldyga Samsung R&D Institute Poland Changelog: v2: - change type of array given to regmap_bulk_read() from unsigned int to u8 - remove mfd_remove_devices() call from error handling, since it's not needed - call disable_irq()/enable_irq() in suspend/resume regardless of wakeup source v1: https://lkml.org/lkml/2014/4/28/298 Robert Baldyga (2): mfd: max77693: remove unnecessary wrapper functions mfd: max77693: handle IRQs using regmap drivers/extcon/extcon-max77693.c | 35 ++-- drivers/mfd/Kconfig | 1 + drivers/mfd/Makefile | 2 +- drivers/mfd/max77693-irq.c | 336 ----------------------------------- drivers/mfd/max77693.c | 203 ++++++++++++++------- drivers/regulator/max77693.c | 12 +- include/linux/mfd/max77693-private.h | 55 ++++-- 7 files changed, 213 insertions(+), 431 deletions(-) delete mode 100644 drivers/mfd/max77693-irq.c -- 1.9.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions 2014-04-29 5:48 [PATCH v2 0/2] mfd: max77693: improve regmap support Robert Baldyga @ 2014-04-29 5:48 ` Robert Baldyga 2014-04-29 6:41 ` Krzysztof Kozlowski 2014-04-29 7:52 ` Lee Jones 2014-04-29 5:48 ` [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap Robert Baldyga 1 sibling, 2 replies; 8+ messages in thread From: Robert Baldyga @ 2014-04-29 5:48 UTC (permalink / raw) To: sameo, lee.jones Cc: a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski, Robert Baldyga This patch removes wrapper functions used to access regmap, and make driver using regmap_*() functions instead. Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> --- drivers/extcon/extcon-max77693.c | 32 ++++++++++----------- drivers/mfd/max77693-irq.c | 50 +++++++++++++++++++------------- drivers/mfd/max77693.c | 56 ++---------------------------------- drivers/regulator/max77693.c | 12 ++++---- include/linux/mfd/max77693-private.h | 8 ------ 5 files changed, 54 insertions(+), 104 deletions(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index da268fb..0b09bf3 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -255,10 +255,10 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, case ADC_DEBOUNCE_TIME_10MS: case ADC_DEBOUNCE_TIME_25MS: case ADC_DEBOUNCE_TIME_38_62MS: - ret = max77693_update_reg(info->max77693->regmap_muic, + ret = regmap_update_bits(info->max77693->regmap_muic, MAX77693_MUIC_REG_CTRL3, - time << CONTROL3_ADCDBSET_SHIFT, - CONTROL3_ADCDBSET_MASK); + CONTROL3_ADCDBSET_MASK, + time << CONTROL3_ADCDBSET_SHIFT); if (ret) { dev_err(info->dev, "failed to set ADC debounce time\n"); return ret; @@ -286,15 +286,15 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, u8 val, bool attached) { int ret = 0; - u8 ctrl1, ctrl2 = 0; + unsigned int ctrl1, ctrl2 = 0; if (attached) ctrl1 = val; else ctrl1 = CONTROL1_SW_OPEN; - ret = max77693_update_reg(info->max77693->regmap_muic, - MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK); + ret = regmap_update_bits(info->max77693->regmap_muic, + MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); return ret; @@ -305,9 +305,9 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, else ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ - ret = max77693_update_reg(info->max77693->regmap_muic, - MAX77693_MUIC_REG_CTRL2, ctrl2, - CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); + ret = regmap_update_bits(info->max77693->regmap_muic, + MAX77693_MUIC_REG_CTRL2, + CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2); if (ret < 0) { dev_err(info->dev, "failed to update MUIC register\n"); return ret; @@ -969,8 +969,8 @@ static void max77693_muic_irq_work(struct work_struct *work) if (info->irq == muic_irqs[i].virq) irq_type = muic_irqs[i].irq; - ret = max77693_bulk_read(info->max77693->regmap_muic, - MAX77693_MUIC_REG_STATUS1, 2, info->status); + ret = regmap_bulk_read(info->max77693->regmap_muic, + MAX77693_MUIC_REG_STATUS1, info->status, 2); if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); mutex_unlock(&info->mutex); @@ -1042,8 +1042,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info) mutex_lock(&info->mutex); /* Read STATUSx register to detect accessory */ - ret = max77693_bulk_read(info->max77693->regmap_muic, - MAX77693_MUIC_REG_STATUS1, 2, info->status); + ret = regmap_bulk_read(info->max77693->regmap_muic, + MAX77693_MUIC_REG_STATUS1, info->status, 2); if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); mutex_unlock(&info->mutex); @@ -1095,7 +1095,7 @@ static int max77693_muic_probe(struct platform_device *pdev) int delay_jiffies; int ret; int i; - u8 id; + unsigned int id; info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info), GFP_KERNEL); @@ -1205,7 +1205,7 @@ static int max77693_muic_probe(struct platform_device *pdev) enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; - max77693_write_reg(info->max77693->regmap_muic, + regmap_write(info->max77693->regmap_muic, init_data[i].addr, init_data[i].data); @@ -1263,7 +1263,7 @@ static int max77693_muic_probe(struct platform_device *pdev) max77693_muic_set_path(info, info->path_uart, true); /* Check revision number of MUIC device*/ - ret = max77693_read_reg(info->max77693->regmap_muic, + ret = regmap_read(info->max77693->regmap_muic, MAX77693_MUIC_REG_ID, &id); if (ret < 0) { dev_err(&pdev->dev, "failed to read revision number\n"); diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 66b58fe..7d8f99f 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c @@ -30,8 +30,9 @@ #include <linux/irqdomain.h> #include <linux/mfd/max77693.h> #include <linux/mfd/max77693-private.h> +#include <linux/regmap.h> -static const u8 max77693_mask_reg[] = { +static const unsigned int max77693_mask_reg[] = { [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK, [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK, [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK, @@ -118,7 +119,7 @@ static void max77693_irq_sync_unlock(struct irq_data *data) continue; max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i]; - max77693_write_reg(map, max77693_mask_reg[i], + regmap_write(map, max77693_mask_reg[i], max77693->irq_masks_cur[i]); } @@ -178,11 +179,11 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) { struct max77693_dev *max77693 = data; u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {}; - u8 irq_src; + unsigned int irq_src; int ret; int i, cur_irq; - ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC, + ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC, &irq_src); if (ret < 0) { dev_err(max77693->dev, "Failed to read interrupt source: %d\n", @@ -190,25 +191,34 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) return IRQ_NONE; } - if (irq_src & MAX77693_IRQSRC_CHG) + if (irq_src & MAX77693_IRQSRC_CHG) { /* CHG_INT */ - ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT, - &irq_reg[CHG_INT]); + unsigned int data; + ret = regmap_read(max77693->regmap, + MAX77693_CHG_REG_CHG_INT, &data); + irq_reg[CHG_INT] = data; + } - if (irq_src & MAX77693_IRQSRC_TOP) + if (irq_src & MAX77693_IRQSRC_TOP) { /* TOPSYS_INT */ - ret = max77693_read_reg(max77693->regmap, - MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]); + unsigned int data; + ret = regmap_read(max77693->regmap, + MAX77693_PMIC_REG_TOPSYS_INT, &data); + irq_reg[TOPSYS_INT] = data; + } - if (irq_src & MAX77693_IRQSRC_FLASH) + if (irq_src & MAX77693_IRQSRC_FLASH) { /* LED_INT */ - ret = max77693_read_reg(max77693->regmap, - MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]); + unsigned int data; + ret = regmap_read(max77693->regmap, + MAX77693_LED_REG_FLASH_INT, &data); + irq_reg[LED_INT] = data; + } if (irq_src & MAX77693_IRQSRC_MUIC) /* MUIC INT1 ~ INT3 */ - max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, - MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); + regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, + &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS); /* Apply masking */ for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { @@ -263,7 +273,7 @@ int max77693_irq_init(struct max77693_dev *max77693) struct irq_domain *domain; int i; int ret = 0; - u8 intsrc_mask; + unsigned int intsrc_mask; mutex_init(&max77693->irqlock); @@ -286,9 +296,9 @@ int max77693_irq_init(struct max77693_dev *max77693) if (max77693_mask_reg[i] == MAX77693_REG_INVALID) continue; if (i >= MUIC_INT1 && i <= MUIC_INT3) - max77693_write_reg(map, max77693_mask_reg[i], 0x00); + regmap_write(map, max77693_mask_reg[i], 0x00); else - max77693_write_reg(map, max77693_mask_reg[i], 0xff); + regmap_write(map, max77693_mask_reg[i], 0xff); } domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR, @@ -301,7 +311,7 @@ int max77693_irq_init(struct max77693_dev *max77693) max77693->irq_domain = domain; /* Unmask max77693 interrupt */ - ret = max77693_read_reg(max77693->regmap, + ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); if (ret < 0) { dev_err(max77693->dev, "fail to read PMIC register\n"); @@ -311,7 +321,7 @@ int max77693_irq_init(struct max77693_dev *max77693) intsrc_mask &= ~(MAX77693_IRQSRC_CHG); intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); - ret = max77693_write_reg(max77693->regmap, + ret = regmap_write(max77693->regmap, MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); if (ret < 0) { dev_err(max77693->dev, "fail to write PMIC register\n"); diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index c5535f0..6336251 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -49,58 +49,6 @@ static const struct mfd_cell max77693_devs[] = { { .name = "max77693-haptic", }, }; -int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest) -{ - unsigned int val; - int ret; - - ret = regmap_read(map, reg, &val); - *dest = val; - - return ret; -} -EXPORT_SYMBOL_GPL(max77693_read_reg); - -int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf) -{ - int ret; - - ret = regmap_bulk_read(map, reg, buf, count); - - return ret; -} -EXPORT_SYMBOL_GPL(max77693_bulk_read); - -int max77693_write_reg(struct regmap *map, u8 reg, u8 value) -{ - int ret; - - ret = regmap_write(map, reg, value); - - return ret; -} -EXPORT_SYMBOL_GPL(max77693_write_reg); - -int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf) -{ - int ret; - - ret = regmap_bulk_write(map, reg, buf, count); - - return ret; -} -EXPORT_SYMBOL_GPL(max77693_bulk_write); - -int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask) -{ - int ret; - - ret = regmap_update_bits(map, reg, mask, val); - - return ret; -} -EXPORT_SYMBOL_GPL(max77693_update_reg); - static const struct regmap_config max77693_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -117,7 +65,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77693_dev *max77693; - u8 reg_data; + unsigned int reg_data; int ret = 0; max77693 = devm_kzalloc(&i2c->dev, @@ -139,7 +87,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, return ret; } - ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, + ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, ®_data); if (ret < 0) { dev_err(max77693->dev, "device not found on this channel\n"); diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index 653a58b..c67ff05 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c @@ -31,6 +31,7 @@ #include <linux/mfd/max77693.h> #include <linux/mfd/max77693-private.h> #include <linux/regulator/of_regulator.h> +#include <linux/regmap.h> #define CHGIN_ILIM_STEP_20mA 20000 @@ -39,9 +40,9 @@ static int max77693_chg_is_enabled(struct regulator_dev *rdev) { int ret; - u8 val; + unsigned int val; - ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val); + ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); if (ret) return ret; @@ -57,12 +58,11 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev) { unsigned int chg_min_uA = rdev->constraints->min_uA; unsigned int chg_max_uA = rdev->constraints->max_uA; - u8 reg, sel; + unsigned int reg, sel; unsigned int val; int ret; - ret = max77693_read_reg(rdev->regmap, - MAX77693_CHG_REG_CHG_CNFG_09, ®); + ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, ®); if (ret < 0) return ret; @@ -96,7 +96,7 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev, /* the first four codes for charger current are all 60mA */ sel += 3; - return max77693_write_reg(rdev->regmap, + return regmap_write(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, sel); } /* end of CHARGER regulator ops */ diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h index 3e050b9..80ec31d 100644 --- a/include/linux/mfd/max77693-private.h +++ b/include/linux/mfd/max77693-private.h @@ -332,14 +332,6 @@ enum max77693_types { TYPE_MAX77693, }; -extern int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest); -extern int max77693_bulk_read(struct regmap *map, u8 reg, int count, - u8 *buf); -extern int max77693_write_reg(struct regmap *map, u8 reg, u8 value); -extern int max77693_bulk_write(struct regmap *map, u8 reg, int count, - u8 *buf); -extern int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask); - extern int max77693_irq_init(struct max77693_dev *max77686); extern void max77693_irq_exit(struct max77693_dev *max77686); extern int max77693_irq_resume(struct max77693_dev *max77686); -- 1.9.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions 2014-04-29 5:48 ` [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions Robert Baldyga @ 2014-04-29 6:41 ` Krzysztof Kozlowski 2014-04-29 7:52 ` Lee Jones 1 sibling, 0 replies; 8+ messages in thread From: Krzysztof Kozlowski @ 2014-04-29 6:41 UTC (permalink / raw) To: Robert Baldyga Cc: sameo, lee.jones, a.zummo, linux-kernel, rtc-linux, m.szyprowski On wto, 2014-04-29 at 07:48 +0200, Robert Baldyga wrote: > This patch removes wrapper functions used to access regmap, and > make driver using regmap_*() functions instead. > > Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> > --- > drivers/extcon/extcon-max77693.c | 32 ++++++++++----------- > drivers/mfd/max77693-irq.c | 50 +++++++++++++++++++------------- > drivers/mfd/max77693.c | 56 ++---------------------------------- > drivers/regulator/max77693.c | 12 ++++---- > include/linux/mfd/max77693-private.h | 8 ------ > 5 files changed, 54 insertions(+), 104 deletions(-) Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Best regards, Krzysztof > diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c > index da268fb..0b09bf3 100644 > --- a/drivers/extcon/extcon-max77693.c > +++ b/drivers/extcon/extcon-max77693.c > @@ -255,10 +255,10 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, > case ADC_DEBOUNCE_TIME_10MS: > case ADC_DEBOUNCE_TIME_25MS: > case ADC_DEBOUNCE_TIME_38_62MS: > - ret = max77693_update_reg(info->max77693->regmap_muic, > + ret = regmap_update_bits(info->max77693->regmap_muic, > MAX77693_MUIC_REG_CTRL3, > - time << CONTROL3_ADCDBSET_SHIFT, > - CONTROL3_ADCDBSET_MASK); > + CONTROL3_ADCDBSET_MASK, > + time << CONTROL3_ADCDBSET_SHIFT); > if (ret) { > dev_err(info->dev, "failed to set ADC debounce time\n"); > return ret; > @@ -286,15 +286,15 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, > u8 val, bool attached) > { > int ret = 0; > - u8 ctrl1, ctrl2 = 0; > + unsigned int ctrl1, ctrl2 = 0; > > if (attached) > ctrl1 = val; > else > ctrl1 = CONTROL1_SW_OPEN; > > - ret = max77693_update_reg(info->max77693->regmap_muic, > - MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK); > + ret = regmap_update_bits(info->max77693->regmap_muic, > + MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1); > if (ret < 0) { > dev_err(info->dev, "failed to update MUIC register\n"); > return ret; > @@ -305,9 +305,9 @@ static int max77693_muic_set_path(struct max77693_muic_info *info, > else > ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ > > - ret = max77693_update_reg(info->max77693->regmap_muic, > - MAX77693_MUIC_REG_CTRL2, ctrl2, > - CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); > + ret = regmap_update_bits(info->max77693->regmap_muic, > + MAX77693_MUIC_REG_CTRL2, > + CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2); > if (ret < 0) { > dev_err(info->dev, "failed to update MUIC register\n"); > return ret; > @@ -969,8 +969,8 @@ static void max77693_muic_irq_work(struct work_struct *work) > if (info->irq == muic_irqs[i].virq) > irq_type = muic_irqs[i].irq; > > - ret = max77693_bulk_read(info->max77693->regmap_muic, > - MAX77693_MUIC_REG_STATUS1, 2, info->status); > + ret = regmap_bulk_read(info->max77693->regmap_muic, > + MAX77693_MUIC_REG_STATUS1, info->status, 2); > if (ret) { > dev_err(info->dev, "failed to read MUIC register\n"); > mutex_unlock(&info->mutex); > @@ -1042,8 +1042,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info) > mutex_lock(&info->mutex); > > /* Read STATUSx register to detect accessory */ > - ret = max77693_bulk_read(info->max77693->regmap_muic, > - MAX77693_MUIC_REG_STATUS1, 2, info->status); > + ret = regmap_bulk_read(info->max77693->regmap_muic, > + MAX77693_MUIC_REG_STATUS1, info->status, 2); > if (ret) { > dev_err(info->dev, "failed to read MUIC register\n"); > mutex_unlock(&info->mutex); > @@ -1095,7 +1095,7 @@ static int max77693_muic_probe(struct platform_device *pdev) > int delay_jiffies; > int ret; > int i; > - u8 id; > + unsigned int id; > > info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info), > GFP_KERNEL); > @@ -1205,7 +1205,7 @@ static int max77693_muic_probe(struct platform_device *pdev) > enum max77693_irq_source irq_src > = MAX77693_IRQ_GROUP_NR; > > - max77693_write_reg(info->max77693->regmap_muic, > + regmap_write(info->max77693->regmap_muic, > init_data[i].addr, > init_data[i].data); > > @@ -1263,7 +1263,7 @@ static int max77693_muic_probe(struct platform_device *pdev) > max77693_muic_set_path(info, info->path_uart, true); > > /* Check revision number of MUIC device*/ > - ret = max77693_read_reg(info->max77693->regmap_muic, > + ret = regmap_read(info->max77693->regmap_muic, > MAX77693_MUIC_REG_ID, &id); > if (ret < 0) { > dev_err(&pdev->dev, "failed to read revision number\n"); > diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c > index 66b58fe..7d8f99f 100644 > --- a/drivers/mfd/max77693-irq.c > +++ b/drivers/mfd/max77693-irq.c > @@ -30,8 +30,9 @@ > #include <linux/irqdomain.h> > #include <linux/mfd/max77693.h> > #include <linux/mfd/max77693-private.h> > +#include <linux/regmap.h> > > -static const u8 max77693_mask_reg[] = { > +static const unsigned int max77693_mask_reg[] = { > [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK, > [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK, > [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK, > @@ -118,7 +119,7 @@ static void max77693_irq_sync_unlock(struct irq_data *data) > continue; > max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i]; > > - max77693_write_reg(map, max77693_mask_reg[i], > + regmap_write(map, max77693_mask_reg[i], > max77693->irq_masks_cur[i]); > } > > @@ -178,11 +179,11 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) > { > struct max77693_dev *max77693 = data; > u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {}; > - u8 irq_src; > + unsigned int irq_src; > int ret; > int i, cur_irq; > > - ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC, > + ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC, > &irq_src); > if (ret < 0) { > dev_err(max77693->dev, "Failed to read interrupt source: %d\n", > @@ -190,25 +191,34 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) > return IRQ_NONE; > } > > - if (irq_src & MAX77693_IRQSRC_CHG) > + if (irq_src & MAX77693_IRQSRC_CHG) { > /* CHG_INT */ > - ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT, > - &irq_reg[CHG_INT]); > + unsigned int data; > + ret = regmap_read(max77693->regmap, > + MAX77693_CHG_REG_CHG_INT, &data); > + irq_reg[CHG_INT] = data; > + } > > - if (irq_src & MAX77693_IRQSRC_TOP) > + if (irq_src & MAX77693_IRQSRC_TOP) { > /* TOPSYS_INT */ > - ret = max77693_read_reg(max77693->regmap, > - MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]); > + unsigned int data; > + ret = regmap_read(max77693->regmap, > + MAX77693_PMIC_REG_TOPSYS_INT, &data); > + irq_reg[TOPSYS_INT] = data; > + } > > - if (irq_src & MAX77693_IRQSRC_FLASH) > + if (irq_src & MAX77693_IRQSRC_FLASH) { > /* LED_INT */ > - ret = max77693_read_reg(max77693->regmap, > - MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]); > + unsigned int data; > + ret = regmap_read(max77693->regmap, > + MAX77693_LED_REG_FLASH_INT, &data); > + irq_reg[LED_INT] = data; > + } > > if (irq_src & MAX77693_IRQSRC_MUIC) > /* MUIC INT1 ~ INT3 */ > - max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, > - MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); > + regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, > + &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS); > > /* Apply masking */ > for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { > @@ -263,7 +273,7 @@ int max77693_irq_init(struct max77693_dev *max77693) > struct irq_domain *domain; > int i; > int ret = 0; > - u8 intsrc_mask; > + unsigned int intsrc_mask; > > mutex_init(&max77693->irqlock); > > @@ -286,9 +296,9 @@ int max77693_irq_init(struct max77693_dev *max77693) > if (max77693_mask_reg[i] == MAX77693_REG_INVALID) > continue; > if (i >= MUIC_INT1 && i <= MUIC_INT3) > - max77693_write_reg(map, max77693_mask_reg[i], 0x00); > + regmap_write(map, max77693_mask_reg[i], 0x00); > else > - max77693_write_reg(map, max77693_mask_reg[i], 0xff); > + regmap_write(map, max77693_mask_reg[i], 0xff); > } > > domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR, > @@ -301,7 +311,7 @@ int max77693_irq_init(struct max77693_dev *max77693) > max77693->irq_domain = domain; > > /* Unmask max77693 interrupt */ > - ret = max77693_read_reg(max77693->regmap, > + ret = regmap_read(max77693->regmap, > MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); > if (ret < 0) { > dev_err(max77693->dev, "fail to read PMIC register\n"); > @@ -311,7 +321,7 @@ int max77693_irq_init(struct max77693_dev *max77693) > intsrc_mask &= ~(MAX77693_IRQSRC_CHG); > intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); > intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); > - ret = max77693_write_reg(max77693->regmap, > + ret = regmap_write(max77693->regmap, > MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); > if (ret < 0) { > dev_err(max77693->dev, "fail to write PMIC register\n"); > diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c > index c5535f0..6336251 100644 > --- a/drivers/mfd/max77693.c > +++ b/drivers/mfd/max77693.c > @@ -49,58 +49,6 @@ static const struct mfd_cell max77693_devs[] = { > { .name = "max77693-haptic", }, > }; > > -int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest) > -{ > - unsigned int val; > - int ret; > - > - ret = regmap_read(map, reg, &val); > - *dest = val; > - > - return ret; > -} > -EXPORT_SYMBOL_GPL(max77693_read_reg); > - > -int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf) > -{ > - int ret; > - > - ret = regmap_bulk_read(map, reg, buf, count); > - > - return ret; > -} > -EXPORT_SYMBOL_GPL(max77693_bulk_read); > - > -int max77693_write_reg(struct regmap *map, u8 reg, u8 value) > -{ > - int ret; > - > - ret = regmap_write(map, reg, value); > - > - return ret; > -} > -EXPORT_SYMBOL_GPL(max77693_write_reg); > - > -int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf) > -{ > - int ret; > - > - ret = regmap_bulk_write(map, reg, buf, count); > - > - return ret; > -} > -EXPORT_SYMBOL_GPL(max77693_bulk_write); > - > -int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask) > -{ > - int ret; > - > - ret = regmap_update_bits(map, reg, mask, val); > - > - return ret; > -} > -EXPORT_SYMBOL_GPL(max77693_update_reg); > - > static const struct regmap_config max77693_regmap_config = { > .reg_bits = 8, > .val_bits = 8, > @@ -117,7 +65,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, > const struct i2c_device_id *id) > { > struct max77693_dev *max77693; > - u8 reg_data; > + unsigned int reg_data; > int ret = 0; > > max77693 = devm_kzalloc(&i2c->dev, > @@ -139,7 +87,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, > return ret; > } > > - ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, > + ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, > ®_data); > if (ret < 0) { > dev_err(max77693->dev, "device not found on this channel\n"); > diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c > index 653a58b..c67ff05 100644 > --- a/drivers/regulator/max77693.c > +++ b/drivers/regulator/max77693.c > @@ -31,6 +31,7 @@ > #include <linux/mfd/max77693.h> > #include <linux/mfd/max77693-private.h> > #include <linux/regulator/of_regulator.h> > +#include <linux/regmap.h> > > #define CHGIN_ILIM_STEP_20mA 20000 > > @@ -39,9 +40,9 @@ > static int max77693_chg_is_enabled(struct regulator_dev *rdev) > { > int ret; > - u8 val; > + unsigned int val; > > - ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val); > + ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); > if (ret) > return ret; > > @@ -57,12 +58,11 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev) > { > unsigned int chg_min_uA = rdev->constraints->min_uA; > unsigned int chg_max_uA = rdev->constraints->max_uA; > - u8 reg, sel; > + unsigned int reg, sel; > unsigned int val; > int ret; > > - ret = max77693_read_reg(rdev->regmap, > - MAX77693_CHG_REG_CHG_CNFG_09, ®); > + ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, ®); > if (ret < 0) > return ret; > > @@ -96,7 +96,7 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev, > /* the first four codes for charger current are all 60mA */ > sel += 3; > > - return max77693_write_reg(rdev->regmap, > + return regmap_write(rdev->regmap, > MAX77693_CHG_REG_CHG_CNFG_09, sel); > } > /* end of CHARGER regulator ops */ > diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h > index 3e050b9..80ec31d 100644 > --- a/include/linux/mfd/max77693-private.h > +++ b/include/linux/mfd/max77693-private.h > @@ -332,14 +332,6 @@ enum max77693_types { > TYPE_MAX77693, > }; > > -extern int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest); > -extern int max77693_bulk_read(struct regmap *map, u8 reg, int count, > - u8 *buf); > -extern int max77693_write_reg(struct regmap *map, u8 reg, u8 value); > -extern int max77693_bulk_write(struct regmap *map, u8 reg, int count, > - u8 *buf); > -extern int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask); > - > extern int max77693_irq_init(struct max77693_dev *max77686); > extern void max77693_irq_exit(struct max77693_dev *max77686); > extern int max77693_irq_resume(struct max77693_dev *max77686); ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions 2014-04-29 5:48 ` [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions Robert Baldyga 2014-04-29 6:41 ` Krzysztof Kozlowski @ 2014-04-29 7:52 ` Lee Jones 2014-04-29 8:05 ` Chanwoo Choi 1 sibling, 1 reply; 8+ messages in thread From: Lee Jones @ 2014-04-29 7:52 UTC (permalink / raw) To: Robert Baldyga Cc: sameo, a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski > This patch removes wrapper functions used to access regmap, and > make driver using regmap_*() functions instead. > > Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> > --- > drivers/extcon/extcon-max77693.c | 32 ++++++++++----------- > drivers/mfd/max77693-irq.c | 50 +++++++++++++++++++------------- > drivers/mfd/max77693.c | 56 ++---------------------------------- > drivers/regulator/max77693.c | 12 ++++---- > include/linux/mfd/max77693-private.h | 8 ------ > 5 files changed, 54 insertions(+), 104 deletions(-) Bye bye abstraction for the sake for abstraction. Works for me! Acked-by: Lee Jones <lee.jones@linaro.org> Chanwoo, I can add this to ib-mfd-extcon-3.16 with your Ack if you like. That should make things somewhat easier. -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions 2014-04-29 7:52 ` Lee Jones @ 2014-04-29 8:05 ` Chanwoo Choi 0 siblings, 0 replies; 8+ messages in thread From: Chanwoo Choi @ 2014-04-29 8:05 UTC (permalink / raw) To: Lee Jones Cc: Robert Baldyga, sameo, a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski On 04/29/2014 04:52 PM, Lee Jones wrote: >> This patch removes wrapper functions used to access regmap, and >> make driver using regmap_*() functions instead. >> >> Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> >> --- >> drivers/extcon/extcon-max77693.c | 32 ++++++++++----------- >> drivers/mfd/max77693-irq.c | 50 +++++++++++++++++++------------- >> drivers/mfd/max77693.c | 56 ++---------------------------------- >> drivers/regulator/max77693.c | 12 ++++---- >> include/linux/mfd/max77693-private.h | 8 ------ >> 5 files changed, 54 insertions(+), 104 deletions(-) > > Bye bye abstraction for the sake for abstraction. Works for me! > > Acked-by: Lee Jones <lee.jones@linaro.org> > > Chanwoo, > I can add this to ib-mfd-extcon-3.16 with your Ack if you like. > That should make things somewhat easier. > OK, For extcon part about patch[1-2]. Acked-by: Chanwoo Choi <cw00.choi@samsung.com> Thanks, Chanwoo Choi ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap 2014-04-29 5:48 [PATCH v2 0/2] mfd: max77693: improve regmap support Robert Baldyga 2014-04-29 5:48 ` [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions Robert Baldyga @ 2014-04-29 5:48 ` Robert Baldyga 2014-04-29 6:42 ` Krzysztof Kozlowski 2014-04-29 7:59 ` Lee Jones 1 sibling, 2 replies; 8+ messages in thread From: Robert Baldyga @ 2014-04-29 5:48 UTC (permalink / raw) To: sameo, lee.jones Cc: a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski, Robert Baldyga This patch modifies mfd driver to use regmap for handling interrupts. It allows to simplify irq handling process. This modifications needed to make small changes in function drivers, which use interrupts. Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> --- drivers/extcon/extcon-max77693.c | 3 +- drivers/mfd/Kconfig | 1 + drivers/mfd/Makefile | 2 +- drivers/mfd/max77693-irq.c | 346 ----------------------------------- drivers/mfd/max77693.c | 151 ++++++++++++++- include/linux/mfd/max77693-private.h | 47 ++++- 6 files changed, 191 insertions(+), 359 deletions(-) delete mode 100644 drivers/mfd/max77693-irq.c diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 0b09bf3..725190a 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev) struct max77693_muic_irq *muic_irq = &muic_irqs[i]; unsigned int virq = 0; - virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); + virq = regmap_irq_get_virq(max77693->irq_data_muic, + muic_irq->irq); if (!virq) { ret = -EINVAL; goto err_irq; diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 67141e8..9e479d0 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -372,6 +372,7 @@ config MFD_MAX77693 depends on I2C=y select MFD_CORE select REGMAP_I2C + select REGMAP_IRQ help Say yes here to add support for Maxim Semiconductor MAX77693. This is a companion Power Management IC with Flash, Haptic, Charger, diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 6d0f65e..b0c55e4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -114,7 +114,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o obj-$(CONFIG_MFD_MAX14577) += max14577.o obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o -obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o +obj-$(CONFIG_MFD_MAX77693) += max77693.o obj-$(CONFIG_MFD_MAX8907) += max8907.o max8925-objs := max8925-core.o max8925-i2c.o obj-$(CONFIG_MFD_MAX8925) += max8925.o diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c deleted file mode 100644 index 7d8f99f..0000000 --- a/drivers/mfd/max77693-irq.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * max77693-irq.c - Interrupt controller support for MAX77693 - * - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * SangYoung Son <hello.son@samsung.com> - * - * This program is not provided / owned by Maxim Integrated Products. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8997-irq.c - */ - -#include <linux/err.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/irqdomain.h> -#include <linux/mfd/max77693.h> -#include <linux/mfd/max77693-private.h> -#include <linux/regmap.h> - -static const unsigned int max77693_mask_reg[] = { - [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK, - [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK, - [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK, - [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1, - [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2, - [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3, -}; - -static struct regmap *max77693_get_regmap(struct max77693_dev *max77693, - enum max77693_irq_source src) -{ - switch (src) { - case LED_INT ... CHG_INT: - return max77693->regmap; - case MUIC_INT1 ... MUIC_INT3: - return max77693->regmap_muic; - default: - return ERR_PTR(-EINVAL); - } -} - -struct max77693_irq_data { - int mask; - enum max77693_irq_source group; -}; - -#define DECLARE_IRQ(idx, _group, _mask) \ - [(idx)] = { .group = (_group), .mask = (_mask) } -static const struct max77693_irq_data max77693_irqs[] = { - DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0), - DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1), - DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2), - DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3), - DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4), - - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0), - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1), - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3), - - DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0), - DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2), - DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3), - DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4), - DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6), - - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3), - - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5), - - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4), - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5), -}; - -static void max77693_irq_lock(struct irq_data *data) -{ - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); - - mutex_lock(&max77693->irqlock); -} - -static void max77693_irq_sync_unlock(struct irq_data *data) -{ - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); - int i; - - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { - u8 mask_reg = max77693_mask_reg[i]; - struct regmap *map = max77693_get_regmap(max77693, i); - - if (mask_reg == MAX77693_REG_INVALID || - IS_ERR_OR_NULL(map)) - continue; - max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i]; - - regmap_write(map, max77693_mask_reg[i], - max77693->irq_masks_cur[i]); - } - - mutex_unlock(&max77693->irqlock); -} - -static const inline struct max77693_irq_data * -irq_to_max77693_irq(struct max77693_dev *max77693, int irq) -{ - struct irq_data *data = irq_get_irq_data(irq); - return &max77693_irqs[data->hwirq]; -} - -static void max77693_irq_mask(struct irq_data *data) -{ - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); - const struct max77693_irq_data *irq_data = - irq_to_max77693_irq(max77693, data->irq); - - if (irq_data->group >= MAX77693_IRQ_GROUP_NR) - return; - - if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) - max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; - else - max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; -} - -static void max77693_irq_unmask(struct irq_data *data) -{ - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); - const struct max77693_irq_data *irq_data = - irq_to_max77693_irq(max77693, data->irq); - - if (irq_data->group >= MAX77693_IRQ_GROUP_NR) - return; - - if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) - max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; - else - max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; -} - -static struct irq_chip max77693_irq_chip = { - .name = "max77693", - .irq_bus_lock = max77693_irq_lock, - .irq_bus_sync_unlock = max77693_irq_sync_unlock, - .irq_mask = max77693_irq_mask, - .irq_unmask = max77693_irq_unmask, -}; - -#define MAX77693_IRQSRC_CHG (1 << 0) -#define MAX77693_IRQSRC_TOP (1 << 1) -#define MAX77693_IRQSRC_FLASH (1 << 2) -#define MAX77693_IRQSRC_MUIC (1 << 3) -static irqreturn_t max77693_irq_thread(int irq, void *data) -{ - struct max77693_dev *max77693 = data; - u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {}; - unsigned int irq_src; - int ret; - int i, cur_irq; - - ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC, - &irq_src); - if (ret < 0) { - dev_err(max77693->dev, "Failed to read interrupt source: %d\n", - ret); - return IRQ_NONE; - } - - if (irq_src & MAX77693_IRQSRC_CHG) { - /* CHG_INT */ - unsigned int data; - ret = regmap_read(max77693->regmap, - MAX77693_CHG_REG_CHG_INT, &data); - irq_reg[CHG_INT] = data; - } - - if (irq_src & MAX77693_IRQSRC_TOP) { - /* TOPSYS_INT */ - unsigned int data; - ret = regmap_read(max77693->regmap, - MAX77693_PMIC_REG_TOPSYS_INT, &data); - irq_reg[TOPSYS_INT] = data; - } - - if (irq_src & MAX77693_IRQSRC_FLASH) { - /* LED_INT */ - unsigned int data; - ret = regmap_read(max77693->regmap, - MAX77693_LED_REG_FLASH_INT, &data); - irq_reg[LED_INT] = data; - } - - if (irq_src & MAX77693_IRQSRC_MUIC) - /* MUIC INT1 ~ INT3 */ - regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, - &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS); - - /* Apply masking */ - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { - if (i >= MUIC_INT1 && i <= MUIC_INT3) - irq_reg[i] &= max77693->irq_masks_cur[i]; - else - irq_reg[i] &= ~max77693->irq_masks_cur[i]; - } - - /* Report */ - for (i = 0; i < MAX77693_IRQ_NR; i++) { - if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) { - cur_irq = irq_find_mapping(max77693->irq_domain, i); - if (cur_irq) - handle_nested_irq(cur_irq); - } - } - - return IRQ_HANDLED; -} - -int max77693_irq_resume(struct max77693_dev *max77693) -{ - if (max77693->irq) - max77693_irq_thread(0, max77693); - - return 0; -} - -static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - struct max77693_dev *max77693 = d->host_data; - - irq_set_chip_data(irq, max77693); - irq_set_chip_and_handler(irq, &max77693_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 max77693_irq_domain_ops = { - .map = max77693_irq_domain_map, -}; - -int max77693_irq_init(struct max77693_dev *max77693) -{ - struct irq_domain *domain; - int i; - int ret = 0; - unsigned int intsrc_mask; - - mutex_init(&max77693->irqlock); - - /* Mask individual interrupt sources */ - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { - struct regmap *map; - /* MUIC IRQ 0:MASK 1:NOT MASK */ - /* Other IRQ 1:MASK 0:NOT MASK */ - if (i >= MUIC_INT1 && i <= MUIC_INT3) { - max77693->irq_masks_cur[i] = 0x00; - max77693->irq_masks_cache[i] = 0x00; - } else { - max77693->irq_masks_cur[i] = 0xff; - max77693->irq_masks_cache[i] = 0xff; - } - map = max77693_get_regmap(max77693, i); - - if (IS_ERR_OR_NULL(map)) - continue; - if (max77693_mask_reg[i] == MAX77693_REG_INVALID) - continue; - if (i >= MUIC_INT1 && i <= MUIC_INT3) - regmap_write(map, max77693_mask_reg[i], 0x00); - else - regmap_write(map, max77693_mask_reg[i], 0xff); - } - - domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR, - &max77693_irq_domain_ops, max77693); - if (!domain) { - dev_err(max77693->dev, "could not create irq domain\n"); - ret = -ENODEV; - goto err_irq; - } - max77693->irq_domain = domain; - - /* Unmask max77693 interrupt */ - ret = regmap_read(max77693->regmap, - MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); - if (ret < 0) { - dev_err(max77693->dev, "fail to read PMIC register\n"); - goto err_irq; - } - - intsrc_mask &= ~(MAX77693_IRQSRC_CHG); - intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); - intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); - ret = regmap_write(max77693->regmap, - MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); - if (ret < 0) { - dev_err(max77693->dev, "fail to write PMIC register\n"); - goto err_irq; - } - - ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "max77693-irq", max77693); - if (ret) - dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", - max77693->irq, ret); - -err_irq: - return ret; -} - -void max77693_irq_exit(struct max77693_dev *max77693) -{ - if (max77693->irq) - free_irq(max77693->irq, max77693); -} diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index 6336251..5b85dc3 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = { .max_register = MAX77693_PMIC_REG_END, }; +static const struct regmap_irq max77693_led_irqs[] = { + { .mask = LED_IRQ_FLED2_OPEN, }, + { .mask = LED_IRQ_FLED2_SHORT, }, + { .mask = LED_IRQ_FLED1_OPEN, }, + { .mask = LED_IRQ_FLED1_SHORT, }, + { .mask = LED_IRQ_MAX_FLASH, }, +}; + +static const struct regmap_irq_chip max77693_led_irq_chip = { + .name = "max77693-led", + .status_base = MAX77693_LED_REG_FLASH_INT, + .mask_base = MAX77693_LED_REG_FLASH_INT_MASK, + .mask_invert = false, + .num_regs = 1, + .irqs = max77693_led_irqs, + .num_irqs = ARRAY_SIZE(max77693_led_irqs), +}; + +static const struct regmap_irq max77693_topsys_irqs[] = { + { .mask = TOPSYS_IRQ_T120C_INT, }, + { .mask = TOPSYS_IRQ_T140C_INT, }, + { .mask = TOPSYS_IRQ_LOWSYS_INT, }, +}; + +static const struct regmap_irq_chip max77693_topsys_irq_chip = { + .name = "max77693-topsys", + .status_base = MAX77693_PMIC_REG_TOPSYS_INT, + .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK, + .mask_invert = false, + .num_regs = 1, + .irqs = max77693_topsys_irqs, + .num_irqs = ARRAY_SIZE(max77693_topsys_irqs), +}; + +static const struct regmap_irq max77693_charger_irqs[] = { + { .mask = CHG_IRQ_BYP_I, }, + { .mask = CHG_IRQ_THM_I, }, + { .mask = CHG_IRQ_BAT_I, }, + { .mask = CHG_IRQ_CHG_I, }, + { .mask = CHG_IRQ_CHGIN_I, }, +}; + +static const struct regmap_irq_chip max77693_charger_irq_chip = { + .name = "max77693-charger", + .status_base = MAX77693_CHG_REG_CHG_INT, + .mask_base = MAX77693_CHG_REG_CHG_INT_MASK, + .mask_invert = false, + .num_regs = 1, + .irqs = max77693_charger_irqs, + .num_irqs = ARRAY_SIZE(max77693_charger_irqs), +}; + static const struct regmap_config max77693_regmap_muic_config = { .reg_bits = 8, .val_bits = 8, .max_register = MAX77693_MUIC_REG_END, }; +static const struct regmap_irq max77693_muic_irqs[] = { + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, }, + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, }, + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, }, + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, }, + + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, }, + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, }, + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, }, + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, }, + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, }, + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, }, + + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, }, + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, }, + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, }, + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, }, + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, }, + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, }, +}; + +static const struct regmap_irq_chip max77693_muic_irq_chip = { + .name = "max77693-muic", + .status_base = MAX77693_MUIC_REG_INT1, + .mask_base = MAX77693_MUIC_REG_INTMASK1, + .mask_invert = true, + .num_regs = 3, + .irqs = max77693_muic_irqs, + .num_irqs = ARRAY_SIZE(max77693_muic_irqs), +}; + static int max77693_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c, goto err_regmap_muic; } - ret = max77693_irq_init(max77693); - if (ret < 0) - goto err_irq; + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, + IRQF_ONESHOT | IRQF_SHARED | + IRQF_TRIGGER_FALLING, 0, + &max77693_led_irq_chip, + &max77693->irq_data_led); + if (ret) { + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); + goto err_regmap_muic; + } + + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, + IRQF_ONESHOT | IRQF_SHARED | + IRQF_TRIGGER_FALLING, 0, + &max77693_topsys_irq_chip, + &max77693->irq_data_topsys); + if (ret) { + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); + goto err_irq_topsys; + } + + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, + IRQF_ONESHOT | IRQF_SHARED | + IRQF_TRIGGER_FALLING, 0, + &max77693_charger_irq_chip, + &max77693->irq_data_charger); + if (ret) { + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); + goto err_irq_charger; + } + + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, + IRQF_ONESHOT | IRQF_SHARED | + IRQF_TRIGGER_FALLING, 0, + &max77693_muic_irq_chip, + &max77693->irq_data_muic); + if (ret) { + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); + goto err_irq_muic; + } pm_runtime_set_active(max77693->dev); @@ -138,8 +257,13 @@ static int max77693_i2c_probe(struct i2c_client *i2c, return ret; err_mfd: - max77693_irq_exit(max77693); -err_irq: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); +err_irq_muic: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); +err_irq_charger: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); +err_irq_topsys: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); err_regmap_muic: i2c_unregister_device(max77693->haptic); err_i2c_haptic: @@ -152,7 +276,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c) struct max77693_dev *max77693 = i2c_get_clientdata(i2c); mfd_remove_devices(max77693->dev); - max77693_irq_exit(max77693); + + regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); + regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); + regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); + regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); + i2c_unregister_device(max77693->muic); i2c_unregister_device(max77693->haptic); @@ -171,7 +300,9 @@ static int max77693_suspend(struct device *dev) struct max77693_dev *max77693 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) - irq_set_irq_wake(max77693->irq, 1); + enable_irq_wake(max77693->irq); + disable_irq(max77693->irq); + return 0; } @@ -181,8 +312,10 @@ static int max77693_resume(struct device *dev) struct max77693_dev *max77693 = i2c_get_clientdata(i2c); if (device_may_wakeup(dev)) - irq_set_irq_wake(max77693->irq, 0); - return max77693_irq_resume(max77693); + disable_irq_wake(max77693->irq); + enable_irq(max77693->irq); + + return 0; } static const struct dev_pm_ops max77693_pm = { diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h index 80ec31d..7257f3b 100644 --- a/include/linux/mfd/max77693-private.h +++ b/include/linux/mfd/max77693-private.h @@ -262,6 +262,42 @@ enum max77693_irq_source { MAX77693_IRQ_GROUP_NR, }; +#define LED_IRQ_FLED2_OPEN (0x1 << 0) +#define LED_IRQ_FLED2_SHORT (0x1 << 1) +#define LED_IRQ_FLED1_OPEN (0x1 << 2) +#define LED_IRQ_FLED1_SHORT (0x1 << 3) +#define LED_IRQ_MAX_FLASH (0x1 << 4) + +#define TOPSYS_IRQ_T120C_INT (0x1 << 0) +#define TOPSYS_IRQ_T140C_INT (0x1 << 1) +#define TOPSYS_IRQ_LOWSYS_INT (0x1 << 3) + +#define CHG_IRQ_BYP_I (0x1 << 0) +#define CHG_IRQ_THM_I (0x1 << 2) +#define CHG_IRQ_BAT_I (0x1 << 3) +#define CHG_IRQ_CHG_I (0x1 << 4) +#define CHG_IRQ_CHGIN_I (0x1 << 6) + +#define MUIC_IRQ_INT1_ADC (0x1 << 0) +#define MUIC_IRQ_INT1_ADC_LOW (0x1 << 1) +#define MUIC_IRQ_INT1_ADC_ERR (0x1 << 2) +#define MUIC_IRQ_INT1_ADC1K (0x1 << 3) + +#define MUIC_IRQ_INT2_CHGTYP (0x1 << 0) +#define MUIC_IRQ_INT2_CHGDETREUN (0x1 << 1) +#define MUIC_IRQ_INT2_DCDTMR (0x1 << 2) +#define MUIC_IRQ_INT2_DXOVP (0x1 << 3) +#define MUIC_IRQ_INT2_VBVOLT (0x1 << 4) +#define MUIC_IRQ_INT2_VIDRM (0x1 << 5) + +#define MUIC_IRQ_INT3_EOC (0x1 << 0) +#define MUIC_IRQ_INT3_CGMBC (0x1 << 1) +#define MUIC_IRQ_INT3_OVP (0x1 << 2) +#define MUIC_IRQ_INT3_MBCCHG_ERR (0x1 << 3) +#define MUIC_IRQ_INT3_CHG_ENABLED (0x1 << 4) +#define MUIC_IRQ_INT3_BAT_DET (0x1 << 5) + + enum max77693_irq { /* PMIC - FLASH */ MAX77693_LED_IRQ_FLED2_OPEN, @@ -282,6 +318,10 @@ enum max77693_irq { MAX77693_CHG_IRQ_CHG_I, MAX77693_CHG_IRQ_CHGIN_I, + MAX77693_IRQ_NR, +}; + +enum max77693_irq_muic { /* MUIC INT1 */ MAX77693_MUIC_IRQ_INT1_ADC, MAX77693_MUIC_IRQ_INT1_ADC_LOW, @@ -304,7 +344,7 @@ enum max77693_irq { MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MAX77693_MUIC_IRQ_INT3_BAT_DET, - MAX77693_IRQ_NR, + MAX77693_MUIC_IRQ_NR, }; struct max77693_dev { @@ -319,7 +359,10 @@ struct max77693_dev { struct regmap *regmap_muic; struct regmap *regmap_haptic; - struct irq_domain *irq_domain; + struct regmap_irq_chip_data *irq_data_led; + struct regmap_irq_chip_data *irq_data_topsys; + struct regmap_irq_chip_data *irq_data_charger; + struct regmap_irq_chip_data *irq_data_muic; int irq; int irq_gpio; -- 1.9.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap 2014-04-29 5:48 ` [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap Robert Baldyga @ 2014-04-29 6:42 ` Krzysztof Kozlowski 2014-04-29 7:59 ` Lee Jones 1 sibling, 0 replies; 8+ messages in thread From: Krzysztof Kozlowski @ 2014-04-29 6:42 UTC (permalink / raw) To: Robert Baldyga Cc: sameo, lee.jones, a.zummo, linux-kernel, rtc-linux, m.szyprowski On wto, 2014-04-29 at 07:48 +0200, Robert Baldyga wrote: > This patch modifies mfd driver to use regmap for handling interrupts. > It allows to simplify irq handling process. This modifications needed > to make small changes in function drivers, which use interrupts. > > Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> > --- > drivers/extcon/extcon-max77693.c | 3 +- > drivers/mfd/Kconfig | 1 + > drivers/mfd/Makefile | 2 +- > drivers/mfd/max77693-irq.c | 346 ----------------------------------- > drivers/mfd/max77693.c | 151 ++++++++++++++- > include/linux/mfd/max77693-private.h | 47 ++++- > 6 files changed, 191 insertions(+), 359 deletions(-) > delete mode 100644 drivers/mfd/max77693-irq.c Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Best regards, Krzysztof > diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c > index 0b09bf3..725190a 100644 > --- a/drivers/extcon/extcon-max77693.c > +++ b/drivers/extcon/extcon-max77693.c > @@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev) > struct max77693_muic_irq *muic_irq = &muic_irqs[i]; > unsigned int virq = 0; > > - virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); > + virq = regmap_irq_get_virq(max77693->irq_data_muic, > + muic_irq->irq); > if (!virq) { > ret = -EINVAL; > goto err_irq; > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 67141e8..9e479d0 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -372,6 +372,7 @@ config MFD_MAX77693 > depends on I2C=y > select MFD_CORE > select REGMAP_I2C > + select REGMAP_IRQ > help > Say yes here to add support for Maxim Semiconductor MAX77693. > This is a companion Power Management IC with Flash, Haptic, Charger, > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index 6d0f65e..b0c55e4 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -114,7 +114,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o > > obj-$(CONFIG_MFD_MAX14577) += max14577.o > obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o > -obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o > +obj-$(CONFIG_MFD_MAX77693) += max77693.o > obj-$(CONFIG_MFD_MAX8907) += max8907.o > max8925-objs := max8925-core.o max8925-i2c.o > obj-$(CONFIG_MFD_MAX8925) += max8925.o > diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c > deleted file mode 100644 > index 7d8f99f..0000000 > --- a/drivers/mfd/max77693-irq.c > +++ /dev/null > @@ -1,346 +0,0 @@ > -/* > - * max77693-irq.c - Interrupt controller support for MAX77693 > - * > - * Copyright (C) 2012 Samsung Electronics Co.Ltd > - * SangYoung Son <hello.son@samsung.com> > - * > - * This program is not provided / owned by Maxim Integrated Products. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 of the License, or > - * (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > - * > - * This driver is based on max8997-irq.c > - */ > - > -#include <linux/err.h> > -#include <linux/irq.h> > -#include <linux/interrupt.h> > -#include <linux/module.h> > -#include <linux/irqdomain.h> > -#include <linux/mfd/max77693.h> > -#include <linux/mfd/max77693-private.h> > -#include <linux/regmap.h> > - > -static const unsigned int max77693_mask_reg[] = { > - [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK, > - [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK, > - [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK, > - [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1, > - [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2, > - [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3, > -}; > - > -static struct regmap *max77693_get_regmap(struct max77693_dev *max77693, > - enum max77693_irq_source src) > -{ > - switch (src) { > - case LED_INT ... CHG_INT: > - return max77693->regmap; > - case MUIC_INT1 ... MUIC_INT3: > - return max77693->regmap_muic; > - default: > - return ERR_PTR(-EINVAL); > - } > -} > - > -struct max77693_irq_data { > - int mask; > - enum max77693_irq_source group; > -}; > - > -#define DECLARE_IRQ(idx, _group, _mask) \ > - [(idx)] = { .group = (_group), .mask = (_mask) } > -static const struct max77693_irq_data max77693_irqs[] = { > - DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0), > - DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1), > - DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2), > - DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3), > - DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4), > - > - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0), > - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1), > - DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3), > - > - DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0), > - DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2), > - DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3), > - DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4), > - DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6), > - > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3), > - > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5), > - > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4), > - DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5), > -}; > - > -static void max77693_irq_lock(struct irq_data *data) > -{ > - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); > - > - mutex_lock(&max77693->irqlock); > -} > - > -static void max77693_irq_sync_unlock(struct irq_data *data) > -{ > - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); > - int i; > - > - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { > - u8 mask_reg = max77693_mask_reg[i]; > - struct regmap *map = max77693_get_regmap(max77693, i); > - > - if (mask_reg == MAX77693_REG_INVALID || > - IS_ERR_OR_NULL(map)) > - continue; > - max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i]; > - > - regmap_write(map, max77693_mask_reg[i], > - max77693->irq_masks_cur[i]); > - } > - > - mutex_unlock(&max77693->irqlock); > -} > - > -static const inline struct max77693_irq_data * > -irq_to_max77693_irq(struct max77693_dev *max77693, int irq) > -{ > - struct irq_data *data = irq_get_irq_data(irq); > - return &max77693_irqs[data->hwirq]; > -} > - > -static void max77693_irq_mask(struct irq_data *data) > -{ > - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); > - const struct max77693_irq_data *irq_data = > - irq_to_max77693_irq(max77693, data->irq); > - > - if (irq_data->group >= MAX77693_IRQ_GROUP_NR) > - return; > - > - if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) > - max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; > - else > - max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; > -} > - > -static void max77693_irq_unmask(struct irq_data *data) > -{ > - struct max77693_dev *max77693 = irq_get_chip_data(data->irq); > - const struct max77693_irq_data *irq_data = > - irq_to_max77693_irq(max77693, data->irq); > - > - if (irq_data->group >= MAX77693_IRQ_GROUP_NR) > - return; > - > - if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) > - max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; > - else > - max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; > -} > - > -static struct irq_chip max77693_irq_chip = { > - .name = "max77693", > - .irq_bus_lock = max77693_irq_lock, > - .irq_bus_sync_unlock = max77693_irq_sync_unlock, > - .irq_mask = max77693_irq_mask, > - .irq_unmask = max77693_irq_unmask, > -}; > - > -#define MAX77693_IRQSRC_CHG (1 << 0) > -#define MAX77693_IRQSRC_TOP (1 << 1) > -#define MAX77693_IRQSRC_FLASH (1 << 2) > -#define MAX77693_IRQSRC_MUIC (1 << 3) > -static irqreturn_t max77693_irq_thread(int irq, void *data) > -{ > - struct max77693_dev *max77693 = data; > - u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {}; > - unsigned int irq_src; > - int ret; > - int i, cur_irq; > - > - ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_INTSRC, > - &irq_src); > - if (ret < 0) { > - dev_err(max77693->dev, "Failed to read interrupt source: %d\n", > - ret); > - return IRQ_NONE; > - } > - > - if (irq_src & MAX77693_IRQSRC_CHG) { > - /* CHG_INT */ > - unsigned int data; > - ret = regmap_read(max77693->regmap, > - MAX77693_CHG_REG_CHG_INT, &data); > - irq_reg[CHG_INT] = data; > - } > - > - if (irq_src & MAX77693_IRQSRC_TOP) { > - /* TOPSYS_INT */ > - unsigned int data; > - ret = regmap_read(max77693->regmap, > - MAX77693_PMIC_REG_TOPSYS_INT, &data); > - irq_reg[TOPSYS_INT] = data; > - } > - > - if (irq_src & MAX77693_IRQSRC_FLASH) { > - /* LED_INT */ > - unsigned int data; > - ret = regmap_read(max77693->regmap, > - MAX77693_LED_REG_FLASH_INT, &data); > - irq_reg[LED_INT] = data; > - } > - > - if (irq_src & MAX77693_IRQSRC_MUIC) > - /* MUIC INT1 ~ INT3 */ > - regmap_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, > - &irq_reg[MUIC_INT1], MAX77693_NUM_IRQ_MUIC_REGS); > - > - /* Apply masking */ > - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { > - if (i >= MUIC_INT1 && i <= MUIC_INT3) > - irq_reg[i] &= max77693->irq_masks_cur[i]; > - else > - irq_reg[i] &= ~max77693->irq_masks_cur[i]; > - } > - > - /* Report */ > - for (i = 0; i < MAX77693_IRQ_NR; i++) { > - if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) { > - cur_irq = irq_find_mapping(max77693->irq_domain, i); > - if (cur_irq) > - handle_nested_irq(cur_irq); > - } > - } > - > - return IRQ_HANDLED; > -} > - > -int max77693_irq_resume(struct max77693_dev *max77693) > -{ > - if (max77693->irq) > - max77693_irq_thread(0, max77693); > - > - return 0; > -} > - > -static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq, > - irq_hw_number_t hw) > -{ > - struct max77693_dev *max77693 = d->host_data; > - > - irq_set_chip_data(irq, max77693); > - irq_set_chip_and_handler(irq, &max77693_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 max77693_irq_domain_ops = { > - .map = max77693_irq_domain_map, > -}; > - > -int max77693_irq_init(struct max77693_dev *max77693) > -{ > - struct irq_domain *domain; > - int i; > - int ret = 0; > - unsigned int intsrc_mask; > - > - mutex_init(&max77693->irqlock); > - > - /* Mask individual interrupt sources */ > - for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { > - struct regmap *map; > - /* MUIC IRQ 0:MASK 1:NOT MASK */ > - /* Other IRQ 1:MASK 0:NOT MASK */ > - if (i >= MUIC_INT1 && i <= MUIC_INT3) { > - max77693->irq_masks_cur[i] = 0x00; > - max77693->irq_masks_cache[i] = 0x00; > - } else { > - max77693->irq_masks_cur[i] = 0xff; > - max77693->irq_masks_cache[i] = 0xff; > - } > - map = max77693_get_regmap(max77693, i); > - > - if (IS_ERR_OR_NULL(map)) > - continue; > - if (max77693_mask_reg[i] == MAX77693_REG_INVALID) > - continue; > - if (i >= MUIC_INT1 && i <= MUIC_INT3) > - regmap_write(map, max77693_mask_reg[i], 0x00); > - else > - regmap_write(map, max77693_mask_reg[i], 0xff); > - } > - > - domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR, > - &max77693_irq_domain_ops, max77693); > - if (!domain) { > - dev_err(max77693->dev, "could not create irq domain\n"); > - ret = -ENODEV; > - goto err_irq; > - } > - max77693->irq_domain = domain; > - > - /* Unmask max77693 interrupt */ > - ret = regmap_read(max77693->regmap, > - MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); > - if (ret < 0) { > - dev_err(max77693->dev, "fail to read PMIC register\n"); > - goto err_irq; > - } > - > - intsrc_mask &= ~(MAX77693_IRQSRC_CHG); > - intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); > - intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); > - ret = regmap_write(max77693->regmap, > - MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); > - if (ret < 0) { > - dev_err(max77693->dev, "fail to write PMIC register\n"); > - goto err_irq; > - } > - > - ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, > - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, > - "max77693-irq", max77693); > - if (ret) > - dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", > - max77693->irq, ret); > - > -err_irq: > - return ret; > -} > - > -void max77693_irq_exit(struct max77693_dev *max77693) > -{ > - if (max77693->irq) > - free_irq(max77693->irq, max77693); > -} > diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c > index 6336251..5b85dc3 100644 > --- a/drivers/mfd/max77693.c > +++ b/drivers/mfd/max77693.c > @@ -55,12 +55,95 @@ static const struct regmap_config max77693_regmap_config = { > .max_register = MAX77693_PMIC_REG_END, > }; > > +static const struct regmap_irq max77693_led_irqs[] = { > + { .mask = LED_IRQ_FLED2_OPEN, }, > + { .mask = LED_IRQ_FLED2_SHORT, }, > + { .mask = LED_IRQ_FLED1_OPEN, }, > + { .mask = LED_IRQ_FLED1_SHORT, }, > + { .mask = LED_IRQ_MAX_FLASH, }, > +}; > + > +static const struct regmap_irq_chip max77693_led_irq_chip = { > + .name = "max77693-led", > + .status_base = MAX77693_LED_REG_FLASH_INT, > + .mask_base = MAX77693_LED_REG_FLASH_INT_MASK, > + .mask_invert = false, > + .num_regs = 1, > + .irqs = max77693_led_irqs, > + .num_irqs = ARRAY_SIZE(max77693_led_irqs), > +}; > + > +static const struct regmap_irq max77693_topsys_irqs[] = { > + { .mask = TOPSYS_IRQ_T120C_INT, }, > + { .mask = TOPSYS_IRQ_T140C_INT, }, > + { .mask = TOPSYS_IRQ_LOWSYS_INT, }, > +}; > + > +static const struct regmap_irq_chip max77693_topsys_irq_chip = { > + .name = "max77693-topsys", > + .status_base = MAX77693_PMIC_REG_TOPSYS_INT, > + .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK, > + .mask_invert = false, > + .num_regs = 1, > + .irqs = max77693_topsys_irqs, > + .num_irqs = ARRAY_SIZE(max77693_topsys_irqs), > +}; > + > +static const struct regmap_irq max77693_charger_irqs[] = { > + { .mask = CHG_IRQ_BYP_I, }, > + { .mask = CHG_IRQ_THM_I, }, > + { .mask = CHG_IRQ_BAT_I, }, > + { .mask = CHG_IRQ_CHG_I, }, > + { .mask = CHG_IRQ_CHGIN_I, }, > +}; > + > +static const struct regmap_irq_chip max77693_charger_irq_chip = { > + .name = "max77693-charger", > + .status_base = MAX77693_CHG_REG_CHG_INT, > + .mask_base = MAX77693_CHG_REG_CHG_INT_MASK, > + .mask_invert = false, > + .num_regs = 1, > + .irqs = max77693_charger_irqs, > + .num_irqs = ARRAY_SIZE(max77693_charger_irqs), > +}; > + > static const struct regmap_config max77693_regmap_muic_config = { > .reg_bits = 8, > .val_bits = 8, > .max_register = MAX77693_MUIC_REG_END, > }; > > +static const struct regmap_irq max77693_muic_irqs[] = { > + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, }, > + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, }, > + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, }, > + { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, }, > + > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, }, > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, }, > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, }, > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, }, > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, }, > + { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, }, > + > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, }, > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, }, > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, }, > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, }, > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, }, > + { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, }, > +}; > + > +static const struct regmap_irq_chip max77693_muic_irq_chip = { > + .name = "max77693-muic", > + .status_base = MAX77693_MUIC_REG_INT1, > + .mask_base = MAX77693_MUIC_REG_INTMASK1, > + .mask_invert = true, > + .num_regs = 3, > + .irqs = max77693_muic_irqs, > + .num_irqs = ARRAY_SIZE(max77693_muic_irqs), > +}; > + > static int max77693_i2c_probe(struct i2c_client *i2c, > const struct i2c_device_id *id) > { > @@ -124,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c, > goto err_regmap_muic; > } > > - ret = max77693_irq_init(max77693); > - if (ret < 0) > - goto err_irq; > + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, > + IRQF_ONESHOT | IRQF_SHARED | > + IRQF_TRIGGER_FALLING, 0, > + &max77693_led_irq_chip, > + &max77693->irq_data_led); > + if (ret) { > + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); > + goto err_regmap_muic; > + } > + > + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, > + IRQF_ONESHOT | IRQF_SHARED | > + IRQF_TRIGGER_FALLING, 0, > + &max77693_topsys_irq_chip, > + &max77693->irq_data_topsys); > + if (ret) { > + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); > + goto err_irq_topsys; > + } > + > + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, > + IRQF_ONESHOT | IRQF_SHARED | > + IRQF_TRIGGER_FALLING, 0, > + &max77693_charger_irq_chip, > + &max77693->irq_data_charger); > + if (ret) { > + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); > + goto err_irq_charger; > + } > + > + ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, > + IRQF_ONESHOT | IRQF_SHARED | > + IRQF_TRIGGER_FALLING, 0, > + &max77693_muic_irq_chip, > + &max77693->irq_data_muic); > + if (ret) { > + dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); > + goto err_irq_muic; > + } > > pm_runtime_set_active(max77693->dev); > > @@ -138,8 +257,13 @@ static int max77693_i2c_probe(struct i2c_client *i2c, > return ret; > > err_mfd: > - max77693_irq_exit(max77693); > -err_irq: > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); > +err_irq_muic: > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); > +err_irq_charger: > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); > +err_irq_topsys: > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); > err_regmap_muic: > i2c_unregister_device(max77693->haptic); > err_i2c_haptic: > @@ -152,7 +276,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c) > struct max77693_dev *max77693 = i2c_get_clientdata(i2c); > > mfd_remove_devices(max77693->dev); > - max77693_irq_exit(max77693); > + > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); > + regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); > + > i2c_unregister_device(max77693->muic); > i2c_unregister_device(max77693->haptic); > > @@ -171,7 +300,9 @@ static int max77693_suspend(struct device *dev) > struct max77693_dev *max77693 = i2c_get_clientdata(i2c); > > if (device_may_wakeup(dev)) > - irq_set_irq_wake(max77693->irq, 1); > + enable_irq_wake(max77693->irq); > + disable_irq(max77693->irq); > + > return 0; > } > > @@ -181,8 +312,10 @@ static int max77693_resume(struct device *dev) > struct max77693_dev *max77693 = i2c_get_clientdata(i2c); > > if (device_may_wakeup(dev)) > - irq_set_irq_wake(max77693->irq, 0); > - return max77693_irq_resume(max77693); > + disable_irq_wake(max77693->irq); > + enable_irq(max77693->irq); > + > + return 0; > } > > static const struct dev_pm_ops max77693_pm = { > diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h > index 80ec31d..7257f3b 100644 > --- a/include/linux/mfd/max77693-private.h > +++ b/include/linux/mfd/max77693-private.h > @@ -262,6 +262,42 @@ enum max77693_irq_source { > MAX77693_IRQ_GROUP_NR, > }; > > +#define LED_IRQ_FLED2_OPEN (0x1 << 0) > +#define LED_IRQ_FLED2_SHORT (0x1 << 1) > +#define LED_IRQ_FLED1_OPEN (0x1 << 2) > +#define LED_IRQ_FLED1_SHORT (0x1 << 3) > +#define LED_IRQ_MAX_FLASH (0x1 << 4) > + > +#define TOPSYS_IRQ_T120C_INT (0x1 << 0) > +#define TOPSYS_IRQ_T140C_INT (0x1 << 1) > +#define TOPSYS_IRQ_LOWSYS_INT (0x1 << 3) > + > +#define CHG_IRQ_BYP_I (0x1 << 0) > +#define CHG_IRQ_THM_I (0x1 << 2) > +#define CHG_IRQ_BAT_I (0x1 << 3) > +#define CHG_IRQ_CHG_I (0x1 << 4) > +#define CHG_IRQ_CHGIN_I (0x1 << 6) > + > +#define MUIC_IRQ_INT1_ADC (0x1 << 0) > +#define MUIC_IRQ_INT1_ADC_LOW (0x1 << 1) > +#define MUIC_IRQ_INT1_ADC_ERR (0x1 << 2) > +#define MUIC_IRQ_INT1_ADC1K (0x1 << 3) > + > +#define MUIC_IRQ_INT2_CHGTYP (0x1 << 0) > +#define MUIC_IRQ_INT2_CHGDETREUN (0x1 << 1) > +#define MUIC_IRQ_INT2_DCDTMR (0x1 << 2) > +#define MUIC_IRQ_INT2_DXOVP (0x1 << 3) > +#define MUIC_IRQ_INT2_VBVOLT (0x1 << 4) > +#define MUIC_IRQ_INT2_VIDRM (0x1 << 5) > + > +#define MUIC_IRQ_INT3_EOC (0x1 << 0) > +#define MUIC_IRQ_INT3_CGMBC (0x1 << 1) > +#define MUIC_IRQ_INT3_OVP (0x1 << 2) > +#define MUIC_IRQ_INT3_MBCCHG_ERR (0x1 << 3) > +#define MUIC_IRQ_INT3_CHG_ENABLED (0x1 << 4) > +#define MUIC_IRQ_INT3_BAT_DET (0x1 << 5) > + > + > enum max77693_irq { > /* PMIC - FLASH */ > MAX77693_LED_IRQ_FLED2_OPEN, > @@ -282,6 +318,10 @@ enum max77693_irq { > MAX77693_CHG_IRQ_CHG_I, > MAX77693_CHG_IRQ_CHGIN_I, > > + MAX77693_IRQ_NR, > +}; > + > +enum max77693_irq_muic { > /* MUIC INT1 */ > MAX77693_MUIC_IRQ_INT1_ADC, > MAX77693_MUIC_IRQ_INT1_ADC_LOW, > @@ -304,7 +344,7 @@ enum max77693_irq { > MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, > MAX77693_MUIC_IRQ_INT3_BAT_DET, > > - MAX77693_IRQ_NR, > + MAX77693_MUIC_IRQ_NR, > }; > > struct max77693_dev { > @@ -319,7 +359,10 @@ struct max77693_dev { > struct regmap *regmap_muic; > struct regmap *regmap_haptic; > > - struct irq_domain *irq_domain; > + struct regmap_irq_chip_data *irq_data_led; > + struct regmap_irq_chip_data *irq_data_topsys; > + struct regmap_irq_chip_data *irq_data_charger; > + struct regmap_irq_chip_data *irq_data_muic; > > int irq; > int irq_gpio; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap 2014-04-29 5:48 ` [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap Robert Baldyga 2014-04-29 6:42 ` Krzysztof Kozlowski @ 2014-04-29 7:59 ` Lee Jones 1 sibling, 0 replies; 8+ messages in thread From: Lee Jones @ 2014-04-29 7:59 UTC (permalink / raw) To: Robert Baldyga Cc: sameo, a.zummo, linux-kernel, rtc-linux, m.szyprowski, k.kozlowski > This patch modifies mfd driver to use regmap for handling interrupts. > It allows to simplify irq handling process. This modifications needed > to make small changes in function drivers, which use interrupts. > > Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> > --- > drivers/extcon/extcon-max77693.c | 3 +- > drivers/mfd/Kconfig | 1 + > drivers/mfd/Makefile | 2 +- > drivers/mfd/max77693-irq.c | 346 ----------------------------------- > drivers/mfd/max77693.c | 151 ++++++++++++++- > include/linux/mfd/max77693-private.h | 47 ++++- > 6 files changed, 191 insertions(+), 359 deletions(-) > delete mode 100644 drivers/mfd/max77693-irq.c Patch looks _mostly_ okay and the diffstat looks great. [...] > +static const struct regmap_irq max77693_led_irqs[] = { > + { .mask = LED_IRQ_FLED2_OPEN, }, > + { .mask = LED_IRQ_FLED2_SHORT, }, > + { .mask = LED_IRQ_FLED1_OPEN, }, > + { .mask = LED_IRQ_FLED1_SHORT, }, > + { .mask = LED_IRQ_MAX_FLASH, }, > +}; Tiny-nit: If you can line those '}'s up, that'd be great. :) Same below. You've already gone to the trouble with the '='s. /me likes straight lines. > +static const struct regmap_irq_chip max77693_led_irq_chip = { > + .name = "max77693-led", > + .status_base = MAX77693_LED_REG_FLASH_INT, > + .mask_base = MAX77693_LED_REG_FLASH_INT_MASK, > + .mask_invert = false, > + .num_regs = 1, > + .irqs = max77693_led_irqs, > + .num_irqs = ARRAY_SIZE(max77693_led_irqs), > +}; > + > +static const struct regmap_irq max77693_topsys_irqs[] = { > + { .mask = TOPSYS_IRQ_T120C_INT, }, > + { .mask = TOPSYS_IRQ_T140C_INT, }, > + { .mask = TOPSYS_IRQ_LOWSYS_INT, }, > +}; [...] > +#define LED_IRQ_FLED2_OPEN (0x1 << 0) > +#define LED_IRQ_FLED2_SHORT (0x1 << 1) > +#define LED_IRQ_FLED1_OPEN (0x1 << 2) > +#define LED_IRQ_FLED1_SHORT (0x1 << 3) > +#define LED_IRQ_MAX_FLASH (0x1 << 4) > + > +#define TOPSYS_IRQ_T120C_INT (0x1 << 0) > +#define TOPSYS_IRQ_T140C_INT (0x1 << 1) > +#define TOPSYS_IRQ_LOWSYS_INT (0x1 << 3) > + > +#define CHG_IRQ_BYP_I (0x1 << 0) > +#define CHG_IRQ_THM_I (0x1 << 2) > +#define CHG_IRQ_BAT_I (0x1 << 3) > +#define CHG_IRQ_CHG_I (0x1 << 4) > +#define CHG_IRQ_CHGIN_I (0x1 << 6) > + > +#define MUIC_IRQ_INT1_ADC (0x1 << 0) > +#define MUIC_IRQ_INT1_ADC_LOW (0x1 << 1) > +#define MUIC_IRQ_INT1_ADC_ERR (0x1 << 2) > +#define MUIC_IRQ_INT1_ADC1K (0x1 << 3) > + > +#define MUIC_IRQ_INT2_CHGTYP (0x1 << 0) > +#define MUIC_IRQ_INT2_CHGDETREUN (0x1 << 1) > +#define MUIC_IRQ_INT2_DCDTMR (0x1 << 2) > +#define MUIC_IRQ_INT2_DXOVP (0x1 << 3) > +#define MUIC_IRQ_INT2_VBVOLT (0x1 << 4) > +#define MUIC_IRQ_INT2_VIDRM (0x1 << 5) > + > +#define MUIC_IRQ_INT3_EOC (0x1 << 0) > +#define MUIC_IRQ_INT3_CGMBC (0x1 << 1) > +#define MUIC_IRQ_INT3_OVP (0x1 << 2) > +#define MUIC_IRQ_INT3_MBCCHG_ERR (0x1 << 3) > +#define MUIC_IRQ_INT3_CHG_ENABLED (0x1 << 4) > +#define MUIC_IRQ_INT3_BAT_DET (0x1 << 5) Use BIT() for these. > + > + One more '\n' than you need. [...] -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-04-29 8:05 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-04-29 5:48 [PATCH v2 0/2] mfd: max77693: improve regmap support Robert Baldyga 2014-04-29 5:48 ` [PATCH v2 1/2] mfd: max77693: remove unnecessary wrapper functions Robert Baldyga 2014-04-29 6:41 ` Krzysztof Kozlowski 2014-04-29 7:52 ` Lee Jones 2014-04-29 8:05 ` Chanwoo Choi 2014-04-29 5:48 ` [PATCH v2 2/2] mfd: max77693: handle IRQs using regmap Robert Baldyga 2014-04-29 6:42 ` Krzysztof Kozlowski 2014-04-29 7:59 ` Lee Jones
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox