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

Merge remote-tracking branch 'regmap/topic/irq' into regmap-next

+198 -81
+99 -43
drivers/base/regmap/regmap-irq.c
··· 44 44 45 45 unsigned int irq_reg_stride; 46 46 unsigned int type_reg_stride; 47 + 48 + bool clear_status:1; 47 49 }; 48 50 49 51 static inline const ··· 79 77 int i, ret; 80 78 u32 reg; 81 79 u32 unmask_offset; 80 + u32 val; 82 81 83 82 if (d->chip->runtime_pm) { 84 83 ret = pm_runtime_get_sync(map->dev); 85 84 if (ret < 0) 86 85 dev_err(map->dev, "IRQ sync failed to resume: %d\n", 87 86 ret); 87 + } 88 + 89 + if (d->clear_status) { 90 + for (i = 0; i < d->chip->num_regs; i++) { 91 + reg = d->chip->status_base + 92 + (i * map->reg_stride * d->irq_reg_stride); 93 + 94 + ret = regmap_read(map, reg, &val); 95 + if (ret) 96 + dev_err(d->map->dev, 97 + "Failed to clear the interrupt status bits\n"); 98 + } 99 + 100 + d->clear_status = false; 88 101 } 89 102 90 103 /* ··· 174 157 } 175 158 } 176 159 177 - for (i = 0; i < d->chip->num_type_reg; i++) { 178 - if (!d->type_buf_def[i]) 179 - continue; 180 - reg = d->chip->type_base + 181 - (i * map->reg_stride * d->type_reg_stride); 182 - if (d->chip->type_invert) 183 - ret = regmap_irq_update_bits(d, reg, 184 - d->type_buf_def[i], ~d->type_buf[i]); 185 - else 186 - ret = regmap_irq_update_bits(d, reg, 187 - d->type_buf_def[i], d->type_buf[i]); 188 - if (ret != 0) 189 - dev_err(d->map->dev, "Failed to sync type in %x\n", 190 - reg); 160 + /* Don't update the type bits if we're using mask bits for irq type. */ 161 + if (!d->chip->type_in_mask) { 162 + for (i = 0; i < d->chip->num_type_reg; i++) { 163 + if (!d->type_buf_def[i]) 164 + continue; 165 + reg = d->chip->type_base + 166 + (i * map->reg_stride * d->type_reg_stride); 167 + if (d->chip->type_invert) 168 + ret = regmap_irq_update_bits(d, reg, 169 + d->type_buf_def[i], ~d->type_buf[i]); 170 + else 171 + ret = regmap_irq_update_bits(d, reg, 172 + d->type_buf_def[i], d->type_buf[i]); 173 + if (ret != 0) 174 + dev_err(d->map->dev, "Failed to sync type in %x\n", 175 + reg); 176 + } 191 177 } 192 178 193 179 if (d->chip->runtime_pm) ··· 214 194 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 215 195 struct regmap *map = d->map; 216 196 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 197 + unsigned int mask, type; 217 198 218 - d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; 199 + type = irq_data->type.type_falling_val | irq_data->type.type_rising_val; 200 + 201 + /* 202 + * The type_in_mask flag means that the underlying hardware uses 203 + * separate mask bits for rising and falling edge interrupts, but 204 + * we want to make them into a single virtual interrupt with 205 + * configurable edge. 206 + * 207 + * If the interrupt we're enabling defines the falling or rising 208 + * masks then instead of using the regular mask bits for this 209 + * interrupt, use the value previously written to the type buffer 210 + * at the corresponding offset in regmap_irq_set_type(). 211 + */ 212 + if (d->chip->type_in_mask && type) 213 + mask = d->type_buf[irq_data->reg_offset / map->reg_stride]; 214 + else 215 + mask = irq_data->mask; 216 + 217 + if (d->chip->clear_on_unmask) 218 + d->clear_status = true; 219 + 220 + d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~mask; 219 221 } 220 222 221 223 static void regmap_irq_disable(struct irq_data *data) ··· 254 212 struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); 255 213 struct regmap *map = d->map; 256 214 const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 257 - int reg = irq_data->type_reg_offset / map->reg_stride; 215 + int reg; 216 + const struct regmap_irq_type *t = &irq_data->type; 258 217 259 - if (!(irq_data->type_rising_mask | irq_data->type_falling_mask)) 260 - return 0; 218 + if ((t->types_supported & type) != type) 219 + return -ENOTSUPP; 261 220 262 - d->type_buf[reg] &= ~(irq_data->type_falling_mask | 263 - irq_data->type_rising_mask); 221 + reg = t->type_reg_offset / map->reg_stride; 222 + 223 + if (t->type_reg_mask) 224 + d->type_buf[reg] &= ~t->type_reg_mask; 225 + else 226 + d->type_buf[reg] &= ~(t->type_falling_val | 227 + t->type_rising_val | 228 + t->type_level_low_val | 229 + t->type_level_high_val); 264 230 switch (type) { 265 231 case IRQ_TYPE_EDGE_FALLING: 266 - d->type_buf[reg] |= irq_data->type_falling_mask; 232 + d->type_buf[reg] |= t->type_falling_val; 267 233 break; 268 234 269 235 case IRQ_TYPE_EDGE_RISING: 270 - d->type_buf[reg] |= irq_data->type_rising_mask; 236 + d->type_buf[reg] |= t->type_rising_val; 271 237 break; 272 238 273 239 case IRQ_TYPE_EDGE_BOTH: 274 - d->type_buf[reg] |= (irq_data->type_falling_mask | 275 - irq_data->type_rising_mask); 240 + d->type_buf[reg] |= (t->type_falling_val | 241 + t->type_rising_val); 276 242 break; 277 243 244 + case IRQ_TYPE_LEVEL_HIGH: 245 + d->type_buf[reg] |= t->type_level_high_val; 246 + break; 247 + 248 + case IRQ_TYPE_LEVEL_LOW: 249 + d->type_buf[reg] |= t->type_level_low_val; 250 + break; 278 251 default: 279 252 return -EINVAL; 280 253 } ··· 487 430 struct regmap_irq_chip_data *d; 488 431 int i; 489 432 int ret = -ENOMEM; 433 + int num_type_reg; 490 434 u32 reg; 491 435 u32 unmask_offset; 492 436 493 437 if (chip->num_regs <= 0) 438 + return -EINVAL; 439 + 440 + if (chip->clear_on_unmask && (chip->ack_base || chip->use_ack)) 494 441 return -EINVAL; 495 442 496 443 for (i = 0; i < chip->num_irqs; i++) { ··· 540 479 goto err_alloc; 541 480 } 542 481 543 - if (chip->num_type_reg) { 544 - d->type_buf_def = kcalloc(chip->num_type_reg, 545 - sizeof(unsigned int), GFP_KERNEL); 482 + num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg; 483 + if (num_type_reg) { 484 + d->type_buf_def = kcalloc(num_type_reg, 485 + sizeof(unsigned int), GFP_KERNEL); 546 486 if (!d->type_buf_def) 547 487 goto err_alloc; 548 488 549 - d->type_buf = kcalloc(chip->num_type_reg, sizeof(unsigned int), 489 + d->type_buf = kcalloc(num_type_reg, sizeof(unsigned int), 550 490 GFP_KERNEL); 551 491 if (!d->type_buf) 552 492 goto err_alloc; ··· 662 600 } 663 601 } 664 602 665 - if (chip->num_type_reg) { 666 - for (i = 0; i < chip->num_irqs; i++) { 667 - reg = chip->irqs[i].type_reg_offset / map->reg_stride; 668 - d->type_buf_def[reg] |= chip->irqs[i].type_rising_mask | 669 - chip->irqs[i].type_falling_mask; 670 - } 603 + if (chip->num_type_reg && !chip->type_in_mask) { 671 604 for (i = 0; i < chip->num_type_reg; ++i) { 672 605 if (!d->type_buf_def[i]) 673 606 continue; 674 607 675 608 reg = chip->type_base + 676 609 (i * map->reg_stride * d->type_reg_stride); 677 - if (chip->type_invert) 678 - ret = regmap_irq_update_bits(d, reg, 679 - d->type_buf_def[i], 0xFF); 680 - else 681 - ret = regmap_irq_update_bits(d, reg, 682 - d->type_buf_def[i], 0x0); 683 - if (ret != 0) { 684 - dev_err(map->dev, 685 - "Failed to set type in 0x%x: %x\n", 610 + 611 + ret = regmap_read(map, reg, &d->type_buf_def[i]); 612 + 613 + if (d->chip->type_invert) 614 + d->type_buf_def[i] = ~d->type_buf_def[i]; 615 + 616 + if (ret) { 617 + dev_err(map->dev, "Failed to get type defaults at 0x%x: %d\n", 686 618 reg, ret); 687 619 goto err_alloc; 688 620 }
+64 -32
drivers/gpio/gpio-max77620.c
··· 25 25 26 26 static const struct regmap_irq max77620_gpio_irqs[] = { 27 27 [0] = { 28 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE0, 29 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 30 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 31 28 .reg_offset = 0, 32 - .type_reg_offset = 0, 29 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE0, 30 + .type = { 31 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 32 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 33 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 34 + .type_reg_offset = 0, 35 + .types_supported = IRQ_TYPE_EDGE_BOTH, 36 + }, 33 37 }, 34 38 [1] = { 35 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE1, 36 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 37 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 38 39 .reg_offset = 0, 39 - .type_reg_offset = 1, 40 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE1, 41 + .type = { 42 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 43 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 44 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 45 + .type_reg_offset = 1, 46 + .types_supported = IRQ_TYPE_EDGE_BOTH, 47 + }, 40 48 }, 41 49 [2] = { 42 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE2, 43 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 44 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 45 50 .reg_offset = 0, 46 - .type_reg_offset = 2, 51 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE2, 52 + .type = { 53 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 54 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 55 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 56 + .type_reg_offset = 2, 57 + .types_supported = IRQ_TYPE_EDGE_BOTH, 58 + }, 47 59 }, 48 60 [3] = { 49 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE3, 50 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 51 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 52 61 .reg_offset = 0, 53 - .type_reg_offset = 3, 62 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE3, 63 + .type = { 64 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 65 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 66 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 67 + .type_reg_offset = 3, 68 + .types_supported = IRQ_TYPE_EDGE_BOTH, 69 + }, 54 70 }, 55 71 [4] = { 56 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE4, 57 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 58 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 59 72 .reg_offset = 0, 60 - .type_reg_offset = 4, 73 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE4, 74 + .type = { 75 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 76 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 77 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 78 + .type_reg_offset = 4, 79 + .types_supported = IRQ_TYPE_EDGE_BOTH, 80 + }, 61 81 }, 62 82 [5] = { 63 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE5, 64 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 65 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 66 83 .reg_offset = 0, 67 - .type_reg_offset = 5, 84 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE5, 85 + .type = { 86 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 87 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 88 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 89 + .type_reg_offset = 5, 90 + .types_supported = IRQ_TYPE_EDGE_BOTH, 91 + }, 68 92 }, 69 93 [6] = { 70 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE6, 71 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 72 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 73 94 .reg_offset = 0, 74 - .type_reg_offset = 6, 95 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE6, 96 + .type = { 97 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 98 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 99 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 100 + .type_reg_offset = 6, 101 + .types_supported = IRQ_TYPE_EDGE_BOTH, 102 + }, 75 103 }, 76 104 [7] = { 77 - .mask = MAX77620_IRQ_LVL2_GPIO_EDGE7, 78 - .type_rising_mask = MAX77620_CNFG_GPIO_INT_RISING, 79 - .type_falling_mask = MAX77620_CNFG_GPIO_INT_FALLING, 80 105 .reg_offset = 0, 81 - .type_reg_offset = 7, 106 + .mask = MAX77620_IRQ_LVL2_GPIO_EDGE7, 107 + .type = { 108 + .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, 109 + .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, 110 + .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, 111 + .type_reg_offset = 7, 112 + .types_supported = IRQ_TYPE_EDGE_BOTH, 113 + }, 82 114 }, 83 115 }; 84 116
+35 -6
include/linux/regmap.h
··· 1089 1089 int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, 1090 1090 unsigned int mask, unsigned int val, 1091 1091 bool *change, bool async, bool force); 1092 + /** 1093 + * struct regmap_irq_type - IRQ type definitions. 1094 + * 1095 + * @type_reg_offset: Offset register for the irq type setting. 1096 + * @type_rising_val: Register value to configure RISING type irq. 1097 + * @type_falling_val: Register value to configure FALLING type irq. 1098 + * @type_level_low_val: Register value to configure LEVEL_LOW type irq. 1099 + * @type_level_high_val: Register value to configure LEVEL_HIGH type irq. 1100 + * @types_supported: logical OR of IRQ_TYPE_* flags indicating supported types. 1101 + */ 1102 + struct regmap_irq_type { 1103 + unsigned int type_reg_offset; 1104 + unsigned int type_reg_mask; 1105 + unsigned int type_rising_val; 1106 + unsigned int type_falling_val; 1107 + unsigned int type_level_low_val; 1108 + unsigned int type_level_high_val; 1109 + unsigned int types_supported; 1110 + }; 1092 1111 1093 1112 /** 1094 1113 * struct regmap_irq - Description of an IRQ for the generic regmap irq_chip. 1095 1114 * 1096 1115 * @reg_offset: Offset of the status/mask register within the bank 1097 1116 * @mask: Mask used to flag/control the register. 1098 - * @type_reg_offset: Offset register for the irq type setting. 1099 - * @type_rising_mask: Mask bit to configure RISING type irq. 1100 - * @type_falling_mask: Mask bit to configure FALLING type irq. 1117 + * @type: IRQ trigger type setting details if supported. 1101 1118 */ 1102 1119 struct regmap_irq { 1103 1120 unsigned int reg_offset; 1104 1121 unsigned int mask; 1105 - unsigned int type_reg_offset; 1106 - unsigned int type_rising_mask; 1107 - unsigned int type_falling_mask; 1122 + struct regmap_irq_type type; 1108 1123 }; 1109 1124 1110 1125 #define REGMAP_IRQ_REG(_irq, _off, _mask) \ 1111 1126 [_irq] = { .reg_offset = (_off), .mask = (_mask) } 1127 + 1128 + #define REGMAP_IRQ_REG_LINE(_id, _reg_bits) \ 1129 + [_id] = { \ 1130 + .mask = BIT((_id) % (_reg_bits)), \ 1131 + .reg_offset = (_id) / (_reg_bits), \ 1132 + } 1112 1133 1113 1134 /** 1114 1135 * struct regmap_irq_chip - Description of a generic regmap irq_chip. ··· 1152 1131 * @ack_invert: Inverted ack register: cleared bits for ack. 1153 1132 * @wake_invert: Inverted wake register: cleared bits are wake enabled. 1154 1133 * @type_invert: Invert the type flags. 1134 + * @type_in_mask: Use the mask registers for controlling irq type. For 1135 + * interrupts defining type_rising/falling_mask use mask_base 1136 + * for edge configuration and never update bits in type_base. 1137 + * @clear_on_unmask: For chips with interrupts cleared on read: read the status 1138 + * registers before unmasking interrupts to clear any bits 1139 + * set when they were masked. 1155 1140 * @runtime_pm: Hold a runtime PM lock on the device when accessing it. 1156 1141 * 1157 1142 * @num_regs: Number of registers in each control bank. ··· 1196 1169 bool wake_invert:1; 1197 1170 bool runtime_pm:1; 1198 1171 bool type_invert:1; 1172 + bool type_in_mask:1; 1173 + bool clear_on_unmask:1; 1199 1174 1200 1175 int num_regs; 1201 1176