Before moving this driver out of staging, cleanup the macros, in order to make the driver clearer. No functional changes.
Unified · Split
| @@ -33,17 +33,27 @@ enum hi6421_spmi_pmic_irq_list { · 32 unmodified lines | ||
| 33 | 33 | SIM0_HPD_F, |
| 34 | 34 | SIM1_HPD_R, |
| 35 | 35 | SIM1_HPD_F, |
| 36 | − PMIC_IRQ_LIST_MAX, | |
| 36 | + | |
| 37 | + PMIC_IRQ_LIST_MAX | |
| 37 | 38 | }; |
| 38 | 39 | |
| 39 | −#define HISI_IRQ_ARRAY 2 | |
| 40 | −#define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8) | |
| 40 | +#define HISI_IRQ_BANK_SIZE 2 | |
| 41 | 41 | |
| 42 | −#define HISI_IRQ_KEY_NUM 0 | |
| 42 | +/* | |
| 43 | + * IRQ number for the power key button and mask for both UP and DOWN IRQs | |
| 44 | + */ | |
| 45 | +#define HISI_POWERKEY_IRQ_NUM 0 | |
| 46 | +#define HISI_IRQ_POWERKEY_UP_DOWN (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP)) | |
| 43 | 47 | |
| 44 | −#define HISI_BITS 8 | |
| 45 | −#define HISI_IRQ_KEY_VALUE (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP)) | |
| 46 | −#define HISI_MASK GENMASK(HISI_BITS - 1, 0) | |
| 48 | +/* | |
| 49 | + * Registers for IRQ address and IRQ mask bits | |
| 50 | + * | |
| 51 | + * Please notice that we need to regmap a larger region, as other | |
| 52 | + * registers are used by the regulators. | |
| 53 | + * See drivers/regulator/hi6421-regulator.c. | |
| 54 | + */ | |
| 55 | +#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 | |
| 56 | +#define SOC_PMIC_IRQ0_ADDR 0x0212 | |
| 47 | 57 | |
| 48 | 58 | /* |
| 49 | 59 | * The IRQs are mapped as: |
| @@ -67,13 +77,14 @@ enum hi6421_spmi_pmic_irq_list { · 17 unmodified lines | ||
| 67 | 77 | * SIM1_HPD_R 0x0203 0x213 bit 4 |
| 68 | 78 | * SIM1_HPD_F 0x0203 0x213 bit 5 |
| 69 | 79 | * ====================== ============= ============ ===== |
| 80 | + * | |
| 81 | + * Each mask register contains 8 bits. The ancillary macros below | |
| 82 | + * convert a number from 0 to 14 into a register address and a bit mask | |
| 70 | 83 | */ |
| 71 | −#define SOC_PMIC_IRQ_MASK_0_ADDR 0x0202 | |
| 72 | −#define SOC_PMIC_IRQ0_ADDR 0x0212 | |
| 73 | − | |
| 74 | −#define IRQ_MASK_REGISTER(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \ | |
| 75 | − (irqd_to_hwirq(irq_data) >> 3)) | |
| 76 | −#define IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & 0x07) | |
| 84 | +#define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \ | |
| 85 | + (irqd_to_hwirq(irq_data) / BITS_PER_BYTE)) | |
| 86 | +#define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1)) | |
| 87 | +#define HISI_8BITS_MASK 0xff | |
| 77 | 88 | |
| 78 | 89 | static const struct mfd_cell hi6421v600_devs[] = { |
| 79 | 90 | { .name = "hi6421v600-regulator", }, |
| @@ -86,23 +97,31 @@ static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv) · 6 unmodified lines | ||
| 86 | 97 | unsigned int in; |
| 87 | 98 | int i, offset; |
| 88 | 99 | |
| 89 | − for (i = 0; i < HISI_IRQ_ARRAY; i++) { | |
| 100 | + for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) { | |
| 90 | 101 | regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in); |
| 91 | − pending = HISI_MASK & in; | |
| 92 | − regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, pending); | |
| 93 | 102 | |
| 94 | − if (i == HISI_IRQ_KEY_NUM && | |
| 95 | − (pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE) { | |
| 103 | + /* Mark pending IRQs as handled */ | |
| 104 | + regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, in); | |
| 105 | + | |
| 106 | + pending = in & HISI_8BITS_MASK; | |
| 107 | + | |
| 108 | + if (i == HISI_POWERKEY_IRQ_NUM && | |
| 109 | + (pending & HISI_IRQ_POWERKEY_UP_DOWN) == HISI_IRQ_POWERKEY_UP_DOWN) { | |
| 110 | + /* | |
| 111 | + * If both powerkey down and up IRQs are received, | |
| 112 | + * handle them at the right order | |
| 113 | + */ | |
| 96 | 114 | generic_handle_irq(ddata->irqs[POWERKEY_DOWN]); |
| 97 | 115 | generic_handle_irq(ddata->irqs[POWERKEY_UP]); |
| 98 | − pending &= (~HISI_IRQ_KEY_VALUE); | |
| 116 | + pending &= ~HISI_IRQ_POWERKEY_UP_DOWN; | |
| 99 | 117 | } |
| 100 | 118 | |
| 101 | 119 | if (!pending) |
| 102 | 120 | continue; |
| 103 | 121 | |
| 104 | − for_each_set_bit(offset, &pending, HISI_BITS) | |
| 105 | − generic_handle_irq(ddata->irqs[offset + i * HISI_BITS]); | |
| 122 | + for_each_set_bit(offset, &pending, BITS_PER_BYTE) { | |
| 123 | + generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]); | |
| 124 | + } | |
| 106 | 125 | } |
| 107 | 126 | |
| 108 | 127 | return IRQ_HANDLED; |
| @@ -115,12 +134,12 @@ static void hi6421_spmi_irq_mask(struct irq_data *d) · 6 unmodified lines | ||
| 115 | 134 | unsigned int data; |
| 116 | 135 | u32 offset; |
| 117 | 136 | |
| 118 | − offset = IRQ_MASK_REGISTER(d); | |
| 137 | + offset = HISI_IRQ_MASK_REG(d); | |
| 119 | 138 | |
| 120 | 139 | spin_lock_irqsave(&ddata->lock, flags); |
| 121 | 140 | |
| 122 | 141 | regmap_read(ddata->regmap, offset, &data); |
| 123 | − data |= IRQ_MASK_BIT(d); | |
| 142 | + data |= HISI_IRQ_MASK_BIT(d); | |
| 124 | 143 | regmap_write(ddata->regmap, offset, data); |
| 125 | 144 | |
| 126 | 145 | spin_unlock_irqrestore(&ddata->lock, flags); |
| @@ -132,13 +151,12 @@ static void hi6421_spmi_irq_unmask(struct irq_data *d) · 5 unmodified lines | ||
| 132 | 151 | u32 data, offset; |
| 133 | 152 | unsigned long flags; |
| 134 | 153 | |
| 135 | − offset = (irqd_to_hwirq(d) >> 3); | |
| 136 | − offset += SOC_PMIC_IRQ_MASK_0_ADDR; | |
| 154 | + offset = HISI_IRQ_MASK_REG(d); | |
| 137 | 155 | |
| 138 | 156 | spin_lock_irqsave(&ddata->lock, flags); |
| 139 | 157 | |
| 140 | 158 | regmap_read(ddata->regmap, offset, &data); |
| 141 | − data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); | |
| 159 | + data &= ~HISI_IRQ_MASK_BIT(d); | |
| 142 | 160 | regmap_write(ddata->regmap, offset, data); |
| 143 | 161 | |
| 144 | 162 | spin_unlock_irqrestore(&ddata->lock, flags); |
| @@ -175,14 +193,16 @@ static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata) · 30 unmodified lines | ||
| 175 | 193 | int i; |
| 176 | 194 | unsigned int pending; |
| 177 | 195 | |
| 178 | − for (i = 0; i < HISI_IRQ_ARRAY; i++) | |
| 196 | + /* Mask all IRQs */ | |
| 197 | + for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) | |
| 179 | 198 | regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i, |
| 180 | − HISI_MASK); | |
| 199 | + HISI_8BITS_MASK); | |
| 181 | 200 | |
| 182 | − for (i = 0; i < HISI_IRQ_ARRAY; i++) { | |
| 201 | + /* Mark all IRQs as handled */ | |
| 202 | + for (i = 0; i < HISI_IRQ_BANK_SIZE; i++) { | |
| 183 | 203 | regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending); |
| 184 | 204 | regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, |
| 185 | − HISI_MASK); | |
| 205 | + HISI_8BITS_MASK); | |
| 186 | 206 | } |
| 187 | 207 | } |
| 188 | 208 | |
| @@ -230,18 +250,18 @@ static int hi6421_spmi_pmic_probe(struct spmi_device *pdev) · 41 unmodified lines | ||
| 230 | 250 | |
| 231 | 251 | hi6421_spmi_pmic_irq_init(ddata); |
| 232 | 252 | |
| 233 | − ddata->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL); | |
| 253 | + ddata->irqs = devm_kzalloc(dev, PMIC_IRQ_LIST_MAX * sizeof(int), GFP_KERNEL); | |
| 234 | 254 | if (!ddata->irqs) |
| 235 | 255 | return -ENOMEM; |
| 236 | 256 | |
| 237 | − ddata->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0, | |
| 257 | + ddata->domain = irq_domain_add_simple(np, PMIC_IRQ_LIST_MAX, 0, | |
| 238 | 258 | &hi6421_spmi_domain_ops, ddata); |
| 239 | 259 | if (!ddata->domain) { |
| 240 | 260 | dev_err(dev, "Failed to create IRQ domain\n"); |
| 241 | 261 | return -ENODEV; |
| 242 | 262 | } |
| 243 | 263 | |
| 244 | − for (i = 0; i < HISI_IRQ_NUM; i++) { | |
| 264 | + for (i = 0; i < PMIC_IRQ_LIST_MAX; i++) { | |
| 245 | 265 | virq = irq_create_mapping(ddata->domain, i); |
| 246 | 266 | if (!virq) { |
| 247 | 267 | dev_err(dev, "Failed to map H/W IRQ\n"); |