Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: mt6358: Refine interrupt code

This patch refines the interrupt related code to support new chips.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Hsin-Hsiung Wang and committed by
Lee Jones
d8570c18 6efb943b

+41 -32
+38 -27
drivers/mfd/mt6358-irq.c
··· 13 13 #include <linux/platform_device.h> 14 14 #include <linux/regmap.h> 15 15 16 - static struct irq_top_t mt6358_ints[] = { 16 + #define MTK_PMIC_REG_WIDTH 16 17 + 18 + static const struct irq_top_t mt6358_ints[] = { 17 19 MT6358_TOP_GEN(BUCK), 18 20 MT6358_TOP_GEN(LDO), 19 21 MT6358_TOP_GEN(PSC), ··· 24 22 MT6358_TOP_GEN(HK), 25 23 MT6358_TOP_GEN(AUD), 26 24 MT6358_TOP_GEN(MISC), 25 + }; 26 + 27 + static struct pmic_irq_data mt6358_irqd = { 28 + .num_top = ARRAY_SIZE(mt6358_ints), 29 + .num_pmic_irqs = MT6358_IRQ_NR, 30 + .top_int_status_reg = MT6358_TOP_INT_STATUS0, 31 + .pmic_ints = mt6358_ints, 27 32 }; 28 33 29 34 static void pmic_irq_enable(struct irq_data *data) ··· 71 62 /* Find out the IRQ group */ 72 63 top_gp = 0; 73 64 while ((top_gp + 1) < irqd->num_top && 74 - i >= mt6358_ints[top_gp + 1].hwirq_base) 65 + i >= irqd->pmic_ints[top_gp + 1].hwirq_base) 75 66 top_gp++; 76 67 77 68 /* Find the IRQ registers */ 78 - gp_offset = i - mt6358_ints[top_gp].hwirq_base; 79 - int_regs = gp_offset / MT6358_REG_WIDTH; 80 - shift = gp_offset % MT6358_REG_WIDTH; 81 - en_reg = mt6358_ints[top_gp].en_reg + 82 - (mt6358_ints[top_gp].en_reg_shift * int_regs); 69 + gp_offset = i - irqd->pmic_ints[top_gp].hwirq_base; 70 + int_regs = gp_offset / MTK_PMIC_REG_WIDTH; 71 + shift = gp_offset % MTK_PMIC_REG_WIDTH; 72 + en_reg = irqd->pmic_ints[top_gp].en_reg + 73 + (irqd->pmic_ints[top_gp].en_reg_shift * int_regs); 83 74 84 75 regmap_update_bits(chip->regmap, en_reg, BIT(shift), 85 76 irqd->enable_hwirq[i] << shift); ··· 104 95 unsigned int irq_status, sta_reg, status; 105 96 unsigned int hwirq, virq; 106 97 int i, j, ret; 98 + struct pmic_irq_data *irqd = chip->irq_data; 107 99 108 - for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) { 109 - sta_reg = mt6358_ints[top_gp].sta_reg + 110 - mt6358_ints[top_gp].sta_reg_shift * i; 100 + for (i = 0; i < irqd->pmic_ints[top_gp].num_int_regs; i++) { 101 + sta_reg = irqd->pmic_ints[top_gp].sta_reg + 102 + irqd->pmic_ints[top_gp].sta_reg_shift * i; 111 103 112 104 ret = regmap_read(chip->regmap, sta_reg, &irq_status); 113 105 if (ret) { ··· 124 114 do { 125 115 j = __ffs(status); 126 116 127 - hwirq = mt6358_ints[top_gp].hwirq_base + 128 - MT6358_REG_WIDTH * i + j; 117 + hwirq = irqd->pmic_ints[top_gp].hwirq_base + 118 + MTK_PMIC_REG_WIDTH * i + j; 129 119 130 120 virq = irq_find_mapping(chip->irq_domain, hwirq); 131 121 if (virq) ··· 141 131 static irqreturn_t mt6358_irq_handler(int irq, void *data) 142 132 { 143 133 struct mt6397_chip *chip = data; 144 - struct pmic_irq_data *mt6358_irq_data = chip->irq_data; 134 + struct pmic_irq_data *irqd = chip->irq_data; 145 135 unsigned int bit, i, top_irq_status = 0; 146 136 int ret; 147 137 148 138 ret = regmap_read(chip->regmap, 149 - mt6358_irq_data->top_int_status_reg, 139 + irqd->top_int_status_reg, 150 140 &top_irq_status); 151 141 if (ret) { 152 142 dev_err(chip->dev, ··· 154 144 return IRQ_NONE; 155 145 } 156 146 157 - for (i = 0; i < mt6358_irq_data->num_top; i++) { 158 - bit = BIT(mt6358_ints[i].top_offset); 147 + for (i = 0; i < irqd->num_top; i++) { 148 + bit = BIT(irqd->pmic_ints[i].top_offset); 159 149 if (top_irq_status & bit) { 160 150 mt6358_irq_sp_handler(chip, i); 161 151 top_irq_status &= ~bit; ··· 190 180 int i, j, ret; 191 181 struct pmic_irq_data *irqd; 192 182 193 - irqd = devm_kzalloc(chip->dev, sizeof(*irqd), GFP_KERNEL); 194 - if (!irqd) 195 - return -ENOMEM; 183 + switch (chip->chip_id) { 184 + case MT6358_CHIP_ID: 185 + chip->irq_data = &mt6358_irqd; 186 + break; 196 187 197 - chip->irq_data = irqd; 188 + default: 189 + dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id); 190 + return -ENODEV; 191 + } 198 192 199 193 mutex_init(&chip->irqlock); 200 - irqd->top_int_status_reg = MT6358_TOP_INT_STATUS0; 201 - irqd->num_pmic_irqs = MT6358_IRQ_NR; 202 - irqd->num_top = ARRAY_SIZE(mt6358_ints); 203 - 194 + irqd = chip->irq_data; 204 195 irqd->enable_hwirq = devm_kcalloc(chip->dev, 205 196 irqd->num_pmic_irqs, 206 197 sizeof(*irqd->enable_hwirq), ··· 218 207 219 208 /* Disable all interrupts for initializing */ 220 209 for (i = 0; i < irqd->num_top; i++) { 221 - for (j = 0; j < mt6358_ints[i].num_int_regs; j++) 210 + for (j = 0; j < irqd->pmic_ints[i].num_int_regs; j++) 222 211 regmap_write(chip->regmap, 223 - mt6358_ints[i].en_reg + 224 - mt6358_ints[i].en_reg_shift * j, 0); 212 + irqd->pmic_ints[i].en_reg + 213 + irqd->pmic_ints[i].en_reg_shift * j, 0); 225 214 } 226 215 227 216 chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
+3 -5
include/linux/mfd/mt6358/core.h
··· 6 6 #ifndef __MFD_MT6358_CORE_H__ 7 7 #define __MFD_MT6358_CORE_H__ 8 8 9 - #define MT6358_REG_WIDTH 16 10 - 11 9 struct irq_top_t { 12 10 int hwirq_base; 13 11 unsigned int num_int_regs; 14 - unsigned int num_int_bits; 15 12 unsigned int en_reg; 16 13 unsigned int en_reg_shift; 17 14 unsigned int sta_reg; ··· 22 25 unsigned short top_int_status_reg; 23 26 bool *enable_hwirq; 24 27 bool *cache_hwirq; 28 + const struct irq_top_t *pmic_ints; 25 29 }; 26 30 27 31 enum mt6358_irq_top_status_shift { ··· 144 146 { \ 145 147 .hwirq_base = MT6358_IRQ_##sp##_BASE, \ 146 148 .num_int_regs = \ 147 - ((MT6358_IRQ_##sp##_BITS - 1) / MT6358_REG_WIDTH) + 1, \ 148 - .num_int_bits = MT6358_IRQ_##sp##_BITS, \ 149 + ((MT6358_IRQ_##sp##_BITS - 1) / \ 150 + MTK_PMIC_REG_WIDTH) + 1, \ 149 151 .en_reg = MT6358_##sp##_TOP_INT_CON0, \ 150 152 .en_reg_shift = 0x6, \ 151 153 .sta_reg = MT6358_##sp##_TOP_INT_STATUS0, \