Add support for Qualcomm MFD PMIC register layout
Subsystems (3)
v5 cover Add support for Qualcomm MFD PMIC register layout
Changes from v4:
- Only one cosmetic change: Moved the declaration of num_virt_regs under num_type_reg instead of under num_main_regs in struct regmap_irq_chip so as to reinforce the idea that it is related to the type setting of IRQs.
- No other changes.
Changes from v3:
- Implemented the scheme proposed in my response to Mark in [4].
- Dropped the RFC tag from this patch series as this series has been tested on target with a client driver utilizing these changes.
Changes from v2:
- Split up framework changes patch for better comprehension.
- Dropped PM8008 driver example and converted it into example code in cover letter and commit text.
- Added more info in cover letter and commit message as per v2 feedback.
This is a follow-up as promised [1] to the earlier attempts [2] [3] to upstream the driver that has been hitherto used to handle IRQs for Qualcomm's PMICs that have multiple on-board peripherals when they are interfaced over the I2C interface.
This series is a rewrite of that driver while making use of the regmap-irq framework, which needs some modifications to handle the register layout of Qualcomm's PMICs. This is an RFC because I would like to get feedback on my general approach before submitting as a patch per se.
Qualcomm's MFD chips that are interfaced over I2C have a top level interrupt status register and sub-irqs (peripherals). When a bit in the main status register goes high, it means that the peripheral corresponding to that bit has an unserviced interrupt. If the bit is not set, this means that the corresponding peripheral does not.
The differences between Qualcomm's register layout and what the regmap-irq framework assumes are best described with an example:
Suppose that there are three peripherals onboard an MFD chip: MISC, TEMP_ALARM and GPIO01. Each of these peripherals has the following IRQ configuration
registers: mask, type and ack. There is a top level interrupt status register and per-peripheral status registers as well (not shown below).
The regmap-irq framework expects all similar registers to be at a fixed stride from each other, for each peripheral, as below (with stride = 1).
/* All mask registers together */ MISC_INT_MASK 0x1011 TEMP_ALARM_INT_MASK 0x1012 GPIO01_INT_MASK 0x1013 /* All type registers together */ MISC_INT_TYPE 0x2011 TEMP_ALARM_INT_TYPE 0x2012 GPIO01_INT_TYPE 0x2013 /* All ack registers together */ MISC_INT_ACK 0x3011 TEMP_ALARM_INT_ACK 0x3012 GPIO01_INT_ACK 0x3013
In contrast, QCOM's registers are laid out as follows:
/* All of MISC peripheral's registers together */ MISC_INT_MASK 0x1011 MISC_INT_TYPE 0x1012 MISC_INT_ACK 0x1013 /* All of TEMP_ALARM peripheral's registers together */ TEMP_ALARM_INT_MASK 0x2011 TEMP_ALARM_INT_TYPE 0x2012 TEMP_ALARM_INT_ACK 0x2013 /* All of GPIO01 peripheral's registers together */ GPIO01_INT_MASK 0x3011 GPIO01_INT_TYPE 0x3012 GPIO01_INT_ACK 0x3013
As is evident, the different IRQ configuration registers are just (0x11, 0x12, 0x13) with offsets of (0x1000, 0x2000 and 0x3000) respectively in QCOM's case. If the *_base registers fed to the struct regmap_irq_chip could be set to the first peripheral (MISC in this example), then through the sub_reg_offsets mechanism, we could add the offsets _to_ the *_base register values to get at the configuration registers for each peripheral.
Hopefully this will help when reviewing the changes in this series.
[1] https://lore.kernel.org/lkml/[email protected]/
[2] https://lore.kernel.org/lkml/[email protected]/
[3] https://lore.kernel.org/lkml/[email protected]/
[4] https://lore.kernel.org/lkml/[email protected]/
Guru Das Srinagesh (2):
regmap-irq: Introduce virtual regs to handle more config regs
regmap-irq: Add driver callback to configure virtual regs
drivers/base/regmap/regmap-irq.c | 43 +++++++++++++++++++++++++++++++++++++++- include/linux/regmap.h | 9 +++++++++ 2 files changed, 51 insertions(+), 1 deletion(-)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v5 1/2 regmap-irq: Introduce virtual regs to handle more config regs
Add "virtual" registers support to handle any irq configuration registers in addition to the ones the framework currently supports (status, mask, unmask, wake, type and ack). These are non-standard registers that further configure irq type on some devices, so enable the framework to add a variable number of them.
--- drivers/base/regmap/regmap-irq.c | 38 +++++++++++++++++++++++++++++++++++++- include/linux/regmap.h | 5 +++++ 2 files changed, 42 insertions(+), 1 deletion(-)
drivers/base/regmap/regmap-irq.c +37 -1
@@ -38,6 +38,7 @@ struct regmap_irq_chip_data {unsigned int *wake_buf;unsigned int *type_buf;unsigned int *type_buf_def; +unsigned int **virt_buf;unsigned int irq_reg_stride;unsigned int type_reg_stride;
@@ -94,7 +95,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) {struct regmap_irq_chip_data *d =irq_data_get_irq_chip_data (data);struct regmap *map = d->map; -int i, ret; +int i, j, ret;u32 reg;u32 unmask_offset;u32 val;
@@ -218,6 +219,20 @@ static void regmap_irq_sync_unlock(struct irq_data *data) } } +if (d->chip->num_virt_regs) { +for (i =0 ; i < d->chip->num_virt_regs; i++) { +for (j =0 ; j < d->chip->num_regs; j++) { + reg =sub_irq_reg (d, d->chip->virt_reg_base[i], + j); + ret =regmap_write (map, reg, d->virt_buf[i][j]); +if (ret !=0 ) +dev_err (d->map->dev, +"Failed to write virt 0x%x: %d\n" , + reg, ret); + } + } + } +if (d->chip->runtime_pm)pm_runtime_put (map->dev);
@@ -691,6 +706,24 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, goto err_alloc; } +if (chip->num_virt_regs) { +/* +* Create virt_buf[chip->num_extra_config_regs][chip->num_regs] +*/ + d->virt_buf =kcalloc (chip->num_virt_regs,sizeof (*d->virt_buf), +GFP_KERNEL ); +if (!d->virt_buf) + goto err_alloc; + +for (i =0 ; i < chip->num_virt_regs; i++) { + d->virt_buf[i] =kcalloc (chip->num_regs, +sizeof (unsigned int ), +GFP_KERNEL ); +if (!d->virt_buf[i]) + goto err_alloc; + } + } + d->irq_chip = regmap_irq_chip; d->irq_chip.name = chip->name; d->irq = irq;
@@ -863,6 +896,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,kfree (d->mask_buf);kfree (d->status_buf);kfree (d->status_reg_buf); +for (i =0 ; i < chip->num_virt_regs; i++) +kfree (d->virt_buf[i]); +kfree (d->virt_buf);kfree (d);return ret; }
include/linux/regmap.h +5 -0
@@ -1393,6 +1393,7 @@ struct regmap_irq_sub_irq_map {* Using zero value is possible with @use_ack bit. * @wake_base: Base address for wake enables. If zero unsupported. * @type_base: Base address for irq type. If zero unsupported. +* @virt_reg_base: Base addresses for extra config regs. * @irq_reg_stride: Stride to use for chips where registers are not contiguous. * @init_ack_masked: Ack all masked interrupts once during initalization. * @mask_invert: Inverted mask register: cleared bits are masked out.
@@ -1417,6 +1418,8 @@ struct regmap_irq_sub_irq_map {* assigned based on the index in the array of the interrupt. * @num_irqs: Number of descriptors. * @num_type_reg: Number of type registers. +* @num_virt_regs: Number of non-standard irq configuration registers. +* If zero unsupported. * @type_reg_stride: Stride to use for chips where type registers are not * contiguous. * @handle_pre_irq: Driver specific callback to handle interrupt from device
@@ -1444,6 +1447,7 @@ struct regmap_irq_chip {unsigned int ack_base;unsigned int wake_base;unsigned int type_base; +unsigned int *virt_reg_base;unsigned int irq_reg_stride; bool mask_writeonly:1; bool init_ack_masked:1;
@@ -1464,6 +1468,7 @@ struct regmap_irq_chip {int num_irqs;int num_type_reg; +int num_virt_regs;unsigned int type_reg_stride;int (*handle_pre_irq)(void *irq_drv_data);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v5 2/2 regmap-irq: Add driver callback to configure virtual regs
In reply to Guru Das SrinageshEnable drivers to configure and modify "virtual" registers, which are non-standard registers that further configure irq type on some devices. Since they are non-standard, enable drivers to configure them according to their particular idiosyncrasies by specifying an optional callback function while registering with the framework.
--- drivers/base/regmap/regmap-irq.c | 5 +++++ include/linux/regmap.h | 4 ++++ 2 files changed, 9 insertions(+)
drivers/base/regmap/regmap-irq.c +5 -0
@@ -333,6 +333,11 @@ static int regmap_irq_set_type(struct irq_data *data, unsigned int type)default :return -EINVAL ; } + +if (d->chip->set_type_virt) +return d->chip->set_type_virt (d->virt_buf, type, data->hwirq, + reg); +return 0 ; }
include/linux/regmap.h +4 -0
@@ -1426,6 +1426,8 @@ struct regmap_irq_sub_irq_map {* before regmap_irq_handler process the interrupts. * @handle_post_irq: Driver specific callback to handle interrupt from device * after handling the interrupts in regmap_irq_handler(). +* @set_type_virt: Driver specific callback to extend regmap_irq_set_type() +* and configure virt regs. * @irq_drv_data: Driver specific IRQ data which is passed as parameter when * driver specific pre/post interrupt handler is called. *
@@ -1473,6 +1475,8 @@ struct regmap_irq_chip {int (*handle_pre_irq)(void *irq_drv_data);int (*handle_post_irq)(void *irq_drv_data); +int (*set_type_virt)(unsigned int **buf,unsigned int type, +unsigned long hwirq,int reg);void *irq_drv_data; };
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Mark Brown
maintainerQuoted 6 lines · Guru Das Srinagesh
Changes from v4:
- Only one cosmetic change: Moved the declaration ofnum_virt_regsundernum_type_reginstead of undernum_main_regsinstruct regmap_irq_chipso as to reinforce the idea that it is related to the type setting of IRQs.
- No other changes.
Quoted 6 lines
Changes from v3:
- Implemented the scheme proposed in my response to Mark in [4].
- Dropped the RFC tag from this patch series as this series has been tested on target with a client driver utilizing these changes.[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next
Thanks!
[1/2] regmap-irq: Introduce virtual regs to handle more config regs
commit: 4c5014456305482412b35a081ca0fb4fefd69764
[2/2] regmap-irq: Add driver callback to configure virtual regs
commit: 394409aafd017adfcffd075595cb01cc456a9327All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 16 lines · Mark Brown
Quoted 6 lines · Guru Das Srinagesh
Changes from v4:
- Only one cosmetic change: Moved the declaration ofnum_virt_regsundernum_type_reginstead of undernum_main_regsinstruct regmap_irq_chipso as to reinforce the idea that it is related to the type setting of IRQs.
- No other changes.Quoted 6 lines
Changes from v3:
- Implemented the scheme proposed in my response to Mark in [4].
- Dropped the RFC tag from this patch series as this series has been tested on target with a client driver utilizing these changes.[...]
Applied to
Quoted 9 lines
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next
Thanks!
[1/2] regmap-irq: Introduce virtual regs to handle more config regs
commit: 4c5014456305482412b35a081ca0fb4fefd69764 [2/2] regmap-irq: Add driver callback to configure virtual regs commit: 394409aafd017adfcffd075595cb01cc456a9327
Thanks for accepting the patches. I'll send out the driver utilizing these changes after code cleanup in the next couple of weeks.
Thank you.
Guru Das.
Quoted 21 lines · Guru Das Srinagesh
Quoted 20 lines · Mark Brown
Quoted 6 lines · Guru Das Srinagesh
Changes from v4:
- Only one cosmetic change: Moved the declaration ofnum_virt_regsundernum_type_reginstead of undernum_main_regsinstruct regmap_irq_chipso as to reinforce the idea that it is related to the type setting of IRQs.
- No other changes.Quoted 6 lines
Changes from v3:
- Implemented the scheme proposed in my response to Mark in [4].
- Dropped the RFC tag from this patch series as this series has been tested on target with a client driver utilizing these changes.[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next
Thanks!
Quoted 8 lines
Quoted 5 lines
[1/2] regmap-irq: Introduce virtual regs to handle more config regs
commit: 4c5014456305482412b35a081ca0fb4fefd69764 [2/2] regmap-irq: Add driver callback to configure virtual regs commit: 394409aafd017adfcffd075595cb01cc456a9327Thanks for accepting the patches. I'll send out the driver utilizing these changes after code cleanup in the next couple of weeks.
Here it is:
https://lore.kernel.org/lkml/[email protected]/
Guru Das.
This series was applied to qcom/linux.git (refs/heads/for-next):
Hello:
This series was applied to qcom/linux.git (refs/heads/for-next):
Quoted 6 lines · On Wed, 24 Mar 2021 12:28:52 -0700 you wrote:
Changes from v4:
- Only one cosmetic change: Moved the declaration ofnum_virt_regsundernum_type_reginstead of undernum_main_regsinstruct regmap_irq_chipso as to reinforce the idea that it is related to the type setting of IRQs.
- No other changes.
Quoted 6 lines
Changes from v3:
- Implemented the scheme proposed in my response to Mark in [4].
- Dropped the RFC tag from this patch series as this series has been tested on target with a client driver utilizing these changes.[...]
Here is the summary with links:
- [v5,1/2] regmap-irq: Introduce virtual regs to handle more config regs
https://git.kernel.org/qcom/c/4c5014456305 - [v5,2/2] regmap-irq: Add driver callback to configure virtual regs https://git.kernel.org/qcom/c/394409aafd01
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html