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 | SIM0_HPD_F, | 33 | SIM0_HPD_F, |
| 34 | SIM1_HPD_R, | 34 | SIM1_HPD_R, |
| 35 | SIM1_HPD_F, | 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_BANK_SIZE 2 |
| 40 | #define HISI_IRQ_NUM (HISI_IRQ_ARRAY * 8) | ||
| 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 | 48 | /* |
| 45 | #define HISI_IRQ_KEY_VALUE (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP)) | 49 | * Registers for IRQ address and IRQ mask bits |
| 46 | #define HISI_MASK GENMASK(HISI_BITS - 1, 0) | 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 | * The IRQs are mapped as: | 59 | * The IRQs are mapped as: |
| @@ -67,13 +77,14 @@ enum hi6421_spmi_pmic_irq_list { · 17 unmodified lines | |||
| 67 | * SIM1_HPD_R 0x0203 0x213 bit 4 | 77 | * SIM1_HPD_R 0x0203 0x213 bit 4 |
| 68 | * SIM1_HPD_F 0x0203 0x213 bit 5 | 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 | 84 | #define HISI_IRQ_MASK_REG(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \ |
| 72 | #define SOC_PMIC_IRQ0_ADDR 0x0212 | 85 | (irqd_to_hwirq(irq_data) / BITS_PER_BYTE)) |
| 73 | 86 | #define HISI_IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & (BITS_PER_BYTE - 1)) | |
| 74 | #define IRQ_MASK_REGISTER(irq_data) (SOC_PMIC_IRQ_MASK_0_ADDR + \ | 87 | #define HISI_8BITS_MASK 0xff |
| 75 | (irqd_to_hwirq(irq_data) >> 3)) | ||
| 76 | #define IRQ_MASK_BIT(irq_data) BIT(irqd_to_hwirq(irq_data) & 0x07) | ||
| 77 | 88 | ||
| 78 | static const struct mfd_cell hi6421v600_devs[] = { | 89 | static const struct mfd_cell hi6421v600_devs[] = { |
| 79 | { .name = "hi6421v600-regulator", }, | 90 | { .name = "hi6421v600-regulator", }, |
| @@ -86,23 +97,31 @@ static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv) · 6 unmodified lines | |||
| 86 | unsigned int in; | 97 | unsigned int in; |
| 87 | int i, offset; | 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 | regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in); | 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 && | 103 | /* Mark pending IRQs as handled */ |
| 95 | (pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE) { | 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 | generic_handle_irq(ddata->irqs[POWERKEY_DOWN]); | 114 | generic_handle_irq(ddata->irqs[POWERKEY_DOWN]); |
| 97 | generic_handle_irq(ddata->irqs[POWERKEY_UP]); | 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 | if (!pending) | 119 | if (!pending) |
| 102 | continue; | 120 | continue; |
| 103 | 121 | ||
| 104 | for_each_set_bit(offset, &pending, HISI_BITS) | 122 | for_each_set_bit(offset, &pending, BITS_PER_BYTE) { |
| 105 | generic_handle_irq(ddata->irqs[offset + i * HISI_BITS]); | 123 | generic_handle_irq(ddata->irqs[offset + i * BITS_PER_BYTE]); |
| 124 | } | ||
| 106 | } | 125 | } |
| 107 | 126 | ||
| 108 | return IRQ_HANDLED; | 127 | return IRQ_HANDLED; |
| @@ -115,12 +134,12 @@ static void hi6421_spmi_irq_mask(struct irq_data *d) · 6 unmodified lines | |||
| 115 | unsigned int data; | 134 | unsigned int data; |
| 116 | u32 offset; | 135 | u32 offset; |
| 117 | 136 | ||
| 118 | offset = IRQ_MASK_REGISTER(d); | 137 | offset = HISI_IRQ_MASK_REG(d); |
| 119 | 138 | ||
| 120 | spin_lock_irqsave(&ddata->lock, flags); | 139 | spin_lock_irqsave(&ddata->lock, flags); |
| 121 | 140 | ||
| 122 | regmap_read(ddata->regmap, offset, &data); | 141 | regmap_read(ddata->regmap, offset, &data); |
| 123 | data |= IRQ_MASK_BIT(d); | 142 | data |= HISI_IRQ_MASK_BIT(d); |
| 124 | regmap_write(ddata->regmap, offset, data); | 143 | regmap_write(ddata->regmap, offset, data); |
| 125 | 144 | ||
| 126 | spin_unlock_irqrestore(&ddata->lock, flags); | 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 | u32 data, offset; | 151 | u32 data, offset; |
| 133 | unsigned long flags; | 152 | unsigned long flags; |
| 134 | 153 | ||
| 135 | offset = (irqd_to_hwirq(d) >> 3); | 154 | offset = HISI_IRQ_MASK_REG(d); |
| 136 | offset += SOC_PMIC_IRQ_MASK_0_ADDR; | ||
| 137 | 155 | ||
| 138 | spin_lock_irqsave(&ddata->lock, flags); | 156 | spin_lock_irqsave(&ddata->lock, flags); |
| 139 | 157 | ||
| 140 | regmap_read(ddata->regmap, offset, &data); | 158 | regmap_read(ddata->regmap, offset, &data); |
| 141 | data &= ~(1 << (irqd_to_hwirq(d) & 0x07)); | 159 | data &= ~HISI_IRQ_MASK_BIT(d); |
| 142 | regmap_write(ddata->regmap, offset, data); | 160 | regmap_write(ddata->regmap, offset, data); |
| 143 | 161 | ||
| 144 | spin_unlock_irqrestore(&ddata->lock, flags); | 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 | int i; | 193 | int i; |
| 176 | unsigned int pending; | 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 | regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i, | 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 | regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending); | 203 | regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending); |
| 184 | regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, | 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 | hi6421_spmi_pmic_irq_init(ddata); | 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 | if (!ddata->irqs) | 254 | if (!ddata->irqs) |
| 235 | return -ENOMEM; | 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 | &hi6421_spmi_domain_ops, ddata); | 258 | &hi6421_spmi_domain_ops, ddata); |
| 239 | if (!ddata->domain) { | 259 | if (!ddata->domain) { |
| 240 | dev_err(dev, "Failed to create IRQ domain\n"); | 260 | dev_err(dev, "Failed to create IRQ domain\n"); |
| 241 | return -ENODEV; | 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 | virq = irq_create_mapping(ddata->domain, i); | 265 | virq = irq_create_mapping(ddata->domain, i); |
| 246 | if (!virq) { | 266 | if (!virq) { |
| 247 | dev_err(dev, "Failed to map H/W IRQ\n"); | 267 | dev_err(dev, "Failed to map H/W IRQ\n"); |