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

mfd: Add s2mps11 irq driver

This patch support irq handling driver for s2mps11.
As this patch use regmap_irq, s5m8767 and s5m8763 are modified with
regmap_irq.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Sangbeom Kim and committed by
Samuel Ortiz
6445b84a 9b6d1343

+193 -329
+1
drivers/mfd/Kconfig
··· 513 513 depends on I2C=y && GENERIC_HARDIRQS 514 514 select MFD_CORE 515 515 select REGMAP_I2C 516 + select REGMAP_IRQ 516 517 help 517 518 Support for the Samsung Electronics MFD series. 518 519 This driver provides common support for accessing the device,
+148 -329
drivers/mfd/sec-irq.c
··· 14 14 #include <linux/device.h> 15 15 #include <linux/interrupt.h> 16 16 #include <linux/irq.h> 17 + #include <linux/regmap.h> 18 + 17 19 #include <linux/mfd/samsung/core.h> 18 20 #include <linux/mfd/samsung/irq.h> 21 + #include <linux/mfd/samsung/s2mps11.h> 19 22 #include <linux/mfd/samsung/s5m8763.h> 20 23 #include <linux/mfd/samsung/s5m8767.h> 21 24 22 - struct sec_irq_data { 23 - int reg; 24 - int mask; 25 + static struct regmap_irq s2mps11_irqs[] = { 26 + [S2MPS11_IRQ_PWRONF] = { 27 + .reg_offset = 1, 28 + .mask = S2MPS11_IRQ_PWRONF_MASK, 29 + }, 30 + [S2MPS11_IRQ_PWRONR] = { 31 + .reg_offset = 1, 32 + .mask = S2MPS11_IRQ_PWRONR_MASK, 33 + }, 34 + [S2MPS11_IRQ_JIGONBF] = { 35 + .reg_offset = 1, 36 + .mask = S2MPS11_IRQ_JIGONBF_MASK, 37 + }, 38 + [S2MPS11_IRQ_JIGONBR] = { 39 + .reg_offset = 1, 40 + .mask = S2MPS11_IRQ_JIGONBR_MASK, 41 + }, 42 + [S2MPS11_IRQ_ACOKBF] = { 43 + .reg_offset = 1, 44 + .mask = S2MPS11_IRQ_ACOKBF_MASK, 45 + }, 46 + [S2MPS11_IRQ_ACOKBR] = { 47 + .reg_offset = 1, 48 + .mask = S2MPS11_IRQ_ACOKBR_MASK, 49 + }, 50 + [S2MPS11_IRQ_PWRON1S] = { 51 + .reg_offset = 1, 52 + .mask = S2MPS11_IRQ_PWRON1S_MASK, 53 + }, 54 + [S2MPS11_IRQ_MRB] = { 55 + .reg_offset = 1, 56 + .mask = S2MPS11_IRQ_MRB_MASK, 57 + }, 58 + [S2MPS11_IRQ_RTC60S] = { 59 + .reg_offset = 2, 60 + .mask = S2MPS11_IRQ_RTC60S_MASK, 61 + }, 62 + [S2MPS11_IRQ_RTCA1] = { 63 + .reg_offset = 2, 64 + .mask = S2MPS11_IRQ_RTCA1_MASK, 65 + }, 66 + [S2MPS11_IRQ_RTCA2] = { 67 + .reg_offset = 2, 68 + .mask = S2MPS11_IRQ_RTCA2_MASK, 69 + }, 70 + [S2MPS11_IRQ_SMPL] = { 71 + .reg_offset = 2, 72 + .mask = S2MPS11_IRQ_SMPL_MASK, 73 + }, 74 + [S2MPS11_IRQ_RTC1S] = { 75 + .reg_offset = 2, 76 + .mask = S2MPS11_IRQ_RTC1S_MASK, 77 + }, 78 + [S2MPS11_IRQ_WTSR] = { 79 + .reg_offset = 2, 80 + .mask = S2MPS11_IRQ_WTSR_MASK, 81 + }, 82 + [S2MPS11_IRQ_INT120C] = { 83 + .reg_offset = 3, 84 + .mask = S2MPS11_IRQ_INT120C_MASK, 85 + }, 86 + [S2MPS11_IRQ_INT140C] = { 87 + .reg_offset = 3, 88 + .mask = S2MPS11_IRQ_INT140C_MASK, 89 + }, 25 90 }; 26 91 27 - static struct sec_irq_data s5m8767_irqs[] = { 92 + 93 + static struct regmap_irq s5m8767_irqs[] = { 28 94 [S5M8767_IRQ_PWRR] = { 29 - .reg = 1, 95 + .reg_offset = 1, 30 96 .mask = S5M8767_IRQ_PWRR_MASK, 31 97 }, 32 98 [S5M8767_IRQ_PWRF] = { 33 - .reg = 1, 99 + .reg_offset = 1, 34 100 .mask = S5M8767_IRQ_PWRF_MASK, 35 101 }, 36 102 [S5M8767_IRQ_PWR1S] = { 37 - .reg = 1, 103 + .reg_offset = 1, 38 104 .mask = S5M8767_IRQ_PWR1S_MASK, 39 105 }, 40 106 [S5M8767_IRQ_JIGR] = { 41 - .reg = 1, 107 + .reg_offset = 1, 42 108 .mask = S5M8767_IRQ_JIGR_MASK, 43 109 }, 44 110 [S5M8767_IRQ_JIGF] = { 45 - .reg = 1, 111 + .reg_offset = 1, 46 112 .mask = S5M8767_IRQ_JIGF_MASK, 47 113 }, 48 114 [S5M8767_IRQ_LOWBAT2] = { 49 - .reg = 1, 115 + .reg_offset = 1, 50 116 .mask = S5M8767_IRQ_LOWBAT2_MASK, 51 117 }, 52 118 [S5M8767_IRQ_LOWBAT1] = { 53 - .reg = 1, 119 + .reg_offset = 1, 54 120 .mask = S5M8767_IRQ_LOWBAT1_MASK, 55 121 }, 56 122 [S5M8767_IRQ_MRB] = { 57 - .reg = 2, 123 + .reg_offset = 2, 58 124 .mask = S5M8767_IRQ_MRB_MASK, 59 125 }, 60 126 [S5M8767_IRQ_DVSOK2] = { 61 - .reg = 2, 127 + .reg_offset = 2, 62 128 .mask = S5M8767_IRQ_DVSOK2_MASK, 63 129 }, 64 130 [S5M8767_IRQ_DVSOK3] = { 65 - .reg = 2, 131 + .reg_offset = 2, 66 132 .mask = S5M8767_IRQ_DVSOK3_MASK, 67 133 }, 68 134 [S5M8767_IRQ_DVSOK4] = { 69 - .reg = 2, 135 + .reg_offset = 2, 70 136 .mask = S5M8767_IRQ_DVSOK4_MASK, 71 137 }, 72 138 [S5M8767_IRQ_RTC60S] = { 73 - .reg = 3, 139 + .reg_offset = 3, 74 140 .mask = S5M8767_IRQ_RTC60S_MASK, 75 141 }, 76 142 [S5M8767_IRQ_RTCA1] = { 77 - .reg = 3, 143 + .reg_offset = 3, 78 144 .mask = S5M8767_IRQ_RTCA1_MASK, 79 145 }, 80 146 [S5M8767_IRQ_RTCA2] = { 81 - .reg = 3, 147 + .reg_offset = 3, 82 148 .mask = S5M8767_IRQ_RTCA2_MASK, 83 149 }, 84 150 [S5M8767_IRQ_SMPL] = { 85 - .reg = 3, 151 + .reg_offset = 3, 86 152 .mask = S5M8767_IRQ_SMPL_MASK, 87 153 }, 88 154 [S5M8767_IRQ_RTC1S] = { 89 - .reg = 3, 155 + .reg_offset = 3, 90 156 .mask = S5M8767_IRQ_RTC1S_MASK, 91 157 }, 92 158 [S5M8767_IRQ_WTSR] = { 93 - .reg = 3, 159 + .reg_offset = 3, 94 160 .mask = S5M8767_IRQ_WTSR_MASK, 95 161 }, 96 162 }; 97 163 98 - static struct sec_irq_data s5m8763_irqs[] = { 164 + static struct regmap_irq s5m8763_irqs[] = { 99 165 [S5M8763_IRQ_DCINF] = { 100 - .reg = 1, 166 + .reg_offset = 1, 101 167 .mask = S5M8763_IRQ_DCINF_MASK, 102 168 }, 103 169 [S5M8763_IRQ_DCINR] = { 104 - .reg = 1, 170 + .reg_offset = 1, 105 171 .mask = S5M8763_IRQ_DCINR_MASK, 106 172 }, 107 173 [S5M8763_IRQ_JIGF] = { 108 - .reg = 1, 174 + .reg_offset = 1, 109 175 .mask = S5M8763_IRQ_JIGF_MASK, 110 176 }, 111 177 [S5M8763_IRQ_JIGR] = { 112 - .reg = 1, 178 + .reg_offset = 1, 113 179 .mask = S5M8763_IRQ_JIGR_MASK, 114 180 }, 115 181 [S5M8763_IRQ_PWRONF] = { 116 - .reg = 1, 182 + .reg_offset = 1, 117 183 .mask = S5M8763_IRQ_PWRONF_MASK, 118 184 }, 119 185 [S5M8763_IRQ_PWRONR] = { 120 - .reg = 1, 186 + .reg_offset = 1, 121 187 .mask = S5M8763_IRQ_PWRONR_MASK, 122 188 }, 123 189 [S5M8763_IRQ_WTSREVNT] = { 124 - .reg = 2, 190 + .reg_offset = 2, 125 191 .mask = S5M8763_IRQ_WTSREVNT_MASK, 126 192 }, 127 193 [S5M8763_IRQ_SMPLEVNT] = { 128 - .reg = 2, 194 + .reg_offset = 2, 129 195 .mask = S5M8763_IRQ_SMPLEVNT_MASK, 130 196 }, 131 197 [S5M8763_IRQ_ALARM1] = { 132 - .reg = 2, 198 + .reg_offset = 2, 133 199 .mask = S5M8763_IRQ_ALARM1_MASK, 134 200 }, 135 201 [S5M8763_IRQ_ALARM0] = { 136 - .reg = 2, 202 + .reg_offset = 2, 137 203 .mask = S5M8763_IRQ_ALARM0_MASK, 138 204 }, 139 205 [S5M8763_IRQ_ONKEY1S] = { 140 - .reg = 3, 206 + .reg_offset = 3, 141 207 .mask = S5M8763_IRQ_ONKEY1S_MASK, 142 208 }, 143 209 [S5M8763_IRQ_TOPOFFR] = { 144 - .reg = 3, 210 + .reg_offset = 3, 145 211 .mask = S5M8763_IRQ_TOPOFFR_MASK, 146 212 }, 147 213 [S5M8763_IRQ_DCINOVPR] = { 148 - .reg = 3, 214 + .reg_offset = 3, 149 215 .mask = S5M8763_IRQ_DCINOVPR_MASK, 150 216 }, 151 217 [S5M8763_IRQ_CHGRSTF] = { 152 - .reg = 3, 218 + .reg_offset = 3, 153 219 .mask = S5M8763_IRQ_CHGRSTF_MASK, 154 220 }, 155 221 [S5M8763_IRQ_DONER] = { 156 - .reg = 3, 222 + .reg_offset = 3, 157 223 .mask = S5M8763_IRQ_DONER_MASK, 158 224 }, 159 225 [S5M8763_IRQ_CHGFAULT] = { 160 - .reg = 3, 226 + .reg_offset = 3, 161 227 .mask = S5M8763_IRQ_CHGFAULT_MASK, 162 228 }, 163 229 [S5M8763_IRQ_LOBAT1] = { 164 - .reg = 4, 230 + .reg_offset = 4, 165 231 .mask = S5M8763_IRQ_LOBAT1_MASK, 166 232 }, 167 233 [S5M8763_IRQ_LOBAT2] = { 168 - .reg = 4, 234 + .reg_offset = 4, 169 235 .mask = S5M8763_IRQ_LOBAT2_MASK, 170 236 }, 171 237 }; 172 238 173 - static inline struct sec_irq_data * 174 - irq_to_s5m8767_irq(struct sec_pmic_dev *sec_pmic, int irq) 175 - { 176 - return &s5m8767_irqs[irq - sec_pmic->irq_base]; 177 - } 239 + static struct regmap_irq_chip s2mps11_irq_chip = { 240 + .name = "s2mps11", 241 + .irqs = s2mps11_irqs, 242 + .num_irqs = ARRAY_SIZE(s2mps11_irqs), 243 + .num_regs = 3, 244 + .status_base = S2MPS11_REG_INT1, 245 + .mask_base = S2MPS11_REG_INT1M, 246 + .ack_base = S2MPS11_REG_INT1, 247 + }; 178 248 179 - static void s5m8767_irq_lock(struct irq_data *data) 180 - { 181 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 182 - 183 - mutex_lock(&sec_pmic->irqlock); 184 - } 185 - 186 - static void s5m8767_irq_sync_unlock(struct irq_data *data) 187 - { 188 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 189 - int i; 190 - 191 - for (i = 0; i < ARRAY_SIZE(sec_pmic->irq_masks_cur); i++) { 192 - if (sec_pmic->irq_masks_cur[i] != sec_pmic->irq_masks_cache[i]) { 193 - sec_pmic->irq_masks_cache[i] = sec_pmic->irq_masks_cur[i]; 194 - sec_reg_write(sec_pmic, S5M8767_REG_INT1M + i, 195 - sec_pmic->irq_masks_cur[i]); 196 - } 197 - } 198 - 199 - mutex_unlock(&sec_pmic->irqlock); 200 - } 201 - 202 - static void s5m8767_irq_unmask(struct irq_data *data) 203 - { 204 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 205 - struct sec_irq_data *irq_data = irq_to_s5m8767_irq(sec_pmic, 206 - data->irq); 207 - 208 - sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 209 - } 210 - 211 - static void s5m8767_irq_mask(struct irq_data *data) 212 - { 213 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 214 - struct sec_irq_data *irq_data = irq_to_s5m8767_irq(sec_pmic, 215 - data->irq); 216 - 217 - sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 218 - } 219 - 220 - static struct irq_chip s5m8767_irq_chip = { 249 + static struct regmap_irq_chip s5m8767_irq_chip = { 221 250 .name = "s5m8767", 222 - .irq_bus_lock = s5m8767_irq_lock, 223 - .irq_bus_sync_unlock = s5m8767_irq_sync_unlock, 224 - .irq_mask = s5m8767_irq_mask, 225 - .irq_unmask = s5m8767_irq_unmask, 251 + .irqs = s5m8767_irqs, 252 + .num_irqs = ARRAY_SIZE(s5m8767_irqs), 253 + .num_regs = 3, 254 + .status_base = S5M8767_REG_INT1, 255 + .mask_base = S5M8767_REG_INT1M, 256 + .ack_base = S5M8767_REG_INT1, 226 257 }; 227 258 228 - static inline struct sec_irq_data * 229 - irq_to_s5m8763_irq(struct sec_pmic_dev *sec_pmic, int irq) 230 - { 231 - return &s5m8763_irqs[irq - sec_pmic->irq_base]; 232 - } 233 - 234 - static void s5m8763_irq_lock(struct irq_data *data) 235 - { 236 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 237 - 238 - mutex_lock(&sec_pmic->irqlock); 239 - } 240 - 241 - static void s5m8763_irq_sync_unlock(struct irq_data *data) 242 - { 243 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 244 - int i; 245 - 246 - for (i = 0; i < ARRAY_SIZE(sec_pmic->irq_masks_cur); i++) { 247 - if (sec_pmic->irq_masks_cur[i] != sec_pmic->irq_masks_cache[i]) { 248 - sec_pmic->irq_masks_cache[i] = sec_pmic->irq_masks_cur[i]; 249 - sec_reg_write(sec_pmic, S5M8763_REG_IRQM1 + i, 250 - sec_pmic->irq_masks_cur[i]); 251 - } 252 - } 253 - 254 - mutex_unlock(&sec_pmic->irqlock); 255 - } 256 - 257 - static void s5m8763_irq_unmask(struct irq_data *data) 258 - { 259 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 260 - struct sec_irq_data *irq_data = irq_to_s5m8763_irq(sec_pmic, 261 - data->irq); 262 - 263 - sec_pmic->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 264 - } 265 - 266 - static void s5m8763_irq_mask(struct irq_data *data) 267 - { 268 - struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data); 269 - struct sec_irq_data *irq_data = irq_to_s5m8763_irq(sec_pmic, 270 - data->irq); 271 - 272 - sec_pmic->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 273 - } 274 - 275 - static struct irq_chip s5m8763_irq_chip = { 259 + static struct regmap_irq_chip s5m8763_irq_chip = { 276 260 .name = "s5m8763", 277 - .irq_bus_lock = s5m8763_irq_lock, 278 - .irq_bus_sync_unlock = s5m8763_irq_sync_unlock, 279 - .irq_mask = s5m8763_irq_mask, 280 - .irq_unmask = s5m8763_irq_unmask, 261 + .irqs = s5m8763_irqs, 262 + .num_irqs = ARRAY_SIZE(s5m8763_irqs), 263 + .num_regs = 4, 264 + .status_base = S5M8763_REG_IRQ1, 265 + .mask_base = S5M8763_REG_IRQM1, 266 + .ack_base = S5M8763_REG_IRQ1, 281 267 }; 282 - 283 - 284 - static irqreturn_t s5m8767_irq_thread(int irq, void *data) 285 - { 286 - struct sec_pmic_dev *sec_pmic = data; 287 - u8 irq_reg[NUM_IRQ_REGS-1]; 288 - int ret; 289 - int i; 290 - 291 - 292 - ret = sec_bulk_read(sec_pmic, S5M8767_REG_INT1, 293 - NUM_IRQ_REGS - 1, irq_reg); 294 - if (ret < 0) { 295 - dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n", 296 - ret); 297 - return IRQ_NONE; 298 - } 299 - 300 - for (i = 0; i < NUM_IRQ_REGS - 1; i++) 301 - irq_reg[i] &= ~sec_pmic->irq_masks_cur[i]; 302 - 303 - for (i = 0; i < S5M8767_IRQ_NR; i++) { 304 - if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask) 305 - handle_nested_irq(sec_pmic->irq_base + i); 306 - } 307 - 308 - return IRQ_HANDLED; 309 - } 310 - 311 - static irqreturn_t s5m8763_irq_thread(int irq, void *data) 312 - { 313 - struct sec_pmic_dev *sec_pmic = data; 314 - u8 irq_reg[NUM_IRQ_REGS]; 315 - int ret; 316 - int i; 317 - 318 - ret = sec_bulk_read(sec_pmic, S5M8763_REG_IRQ1, 319 - NUM_IRQ_REGS, irq_reg); 320 - if (ret < 0) { 321 - dev_err(sec_pmic->dev, "Failed to read interrupt register: %d\n", 322 - ret); 323 - return IRQ_NONE; 324 - } 325 - 326 - for (i = 0; i < NUM_IRQ_REGS; i++) 327 - irq_reg[i] &= ~sec_pmic->irq_masks_cur[i]; 328 - 329 - for (i = 0; i < S5M8763_IRQ_NR; i++) { 330 - if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask) 331 - handle_nested_irq(sec_pmic->irq_base + i); 332 - } 333 - 334 - return IRQ_HANDLED; 335 - } 336 - 337 - int sec_irq_resume(struct sec_pmic_dev *sec_pmic) 338 - { 339 - if (sec_pmic->irq && sec_pmic->irq_base) { 340 - switch (sec_pmic->device_type) { 341 - case S5M8763X: 342 - s5m8763_irq_thread(sec_pmic->irq_base, sec_pmic); 343 - break; 344 - case S5M8767X: 345 - s5m8767_irq_thread(sec_pmic->irq_base, sec_pmic); 346 - break; 347 - default: 348 - dev_err(sec_pmic->dev, 349 - "Unknown device type %d\n", 350 - sec_pmic->device_type); 351 - return -EINVAL; 352 - 353 - } 354 - } 355 - return 0; 356 - } 357 268 358 269 int sec_irq_init(struct sec_pmic_dev *sec_pmic) 359 270 { 360 - int i; 361 - int cur_irq; 362 271 int ret = 0; 363 272 int type = sec_pmic->device_type; 364 273 ··· 278 369 return 0; 279 370 } 280 371 281 - if (!sec_pmic->irq_base) { 282 - dev_err(sec_pmic->dev, 283 - "No interrupt base specified, no interrupts\n"); 284 - return 0; 285 - } 286 - 287 - mutex_init(&sec_pmic->irqlock); 288 - 289 372 switch (type) { 290 373 case S5M8763X: 291 - for (i = 0; i < NUM_IRQ_REGS; i++) { 292 - sec_pmic->irq_masks_cur[i] = 0xff; 293 - sec_pmic->irq_masks_cache[i] = 0xff; 294 - sec_reg_write(sec_pmic, S5M8763_REG_IRQM1 + i, 295 - 0xff); 296 - } 297 - 298 - sec_reg_write(sec_pmic, S5M8763_REG_STATUSM1, 0xff); 299 - sec_reg_write(sec_pmic, S5M8763_REG_STATUSM2, 0xff); 300 - 301 - for (i = 0; i < S5M8763_IRQ_NR; i++) { 302 - cur_irq = i + sec_pmic->irq_base; 303 - irq_set_chip_data(cur_irq, sec_pmic); 304 - irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip, 305 - handle_edge_irq); 306 - irq_set_nested_thread(cur_irq, 1); 307 - #ifdef CONFIG_ARM 308 - set_irq_flags(cur_irq, IRQF_VALID); 309 - #else 310 - irq_set_noprobe(cur_irq); 311 - #endif 312 - } 313 - 314 - ret = request_threaded_irq(sec_pmic->irq, NULL, 315 - s5m8763_irq_thread, 316 - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 317 - "sec-pmic-irq", sec_pmic); 318 - if (ret) { 319 - dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", 320 - sec_pmic->irq, ret); 321 - return ret; 322 - } 374 + ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq, 375 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 376 + sec_pmic->irq_base, &s5m8763_irq_chip, 377 + &sec_pmic->irq_data); 323 378 break; 324 379 case S5M8767X: 325 - for (i = 0; i < NUM_IRQ_REGS - 1; i++) { 326 - sec_pmic->irq_masks_cur[i] = 0xff; 327 - sec_pmic->irq_masks_cache[i] = 0xff; 328 - sec_reg_write(sec_pmic, S5M8767_REG_INT1M + i, 329 - 0xff); 330 - } 331 - for (i = 0; i < S5M8767_IRQ_NR; i++) { 332 - cur_irq = i + sec_pmic->irq_base; 333 - irq_set_chip_data(cur_irq, sec_pmic); 334 - if (ret) { 335 - dev_err(sec_pmic->dev, 336 - "Failed to irq_set_chip_data %d: %d\n", 337 - sec_pmic->irq, ret); 338 - return ret; 339 - } 340 - 341 - irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip, 342 - handle_edge_irq); 343 - irq_set_nested_thread(cur_irq, 1); 344 - #ifdef CONFIG_ARM 345 - set_irq_flags(cur_irq, IRQF_VALID); 346 - #else 347 - irq_set_noprobe(cur_irq); 348 - #endif 349 - } 350 - 351 - ret = request_threaded_irq(sec_pmic->irq, NULL, 352 - s5m8767_irq_thread, 353 - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 354 - "sec-pmic-irq", sec_pmic); 355 - if (ret) { 356 - dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", 357 - sec_pmic->irq, ret); 358 - return ret; 359 - } 380 + ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq, 381 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 382 + sec_pmic->irq_base, &s5m8767_irq_chip, 383 + &sec_pmic->irq_data); 384 + break; 385 + case S2MPS11X: 386 + ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq, 387 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 388 + sec_pmic->irq_base, &s2mps11_irq_chip, 389 + &sec_pmic->irq_data); 360 390 break; 361 391 default: 362 - dev_err(sec_pmic->dev, 363 - "Unknown device type %d\n", sec_pmic->device_type); 392 + dev_err(sec_pmic->dev, "Unknown device type %d\n", 393 + sec_pmic->device_type); 364 394 return -EINVAL; 365 395 } 366 396 367 - if (!sec_pmic->ono) 368 - return 0; 369 - 370 - switch (type) { 371 - case S5M8763X: 372 - ret = request_threaded_irq(sec_pmic->ono, NULL, 373 - s5m8763_irq_thread, 374 - IRQF_TRIGGER_FALLING | 375 - IRQF_TRIGGER_RISING | 376 - IRQF_ONESHOT, "sec_pmic-ono", 377 - sec_pmic); 378 - break; 379 - case S5M8767X: 380 - ret = request_threaded_irq(sec_pmic->ono, NULL, 381 - s5m8767_irq_thread, 382 - IRQF_TRIGGER_FALLING | 383 - IRQF_TRIGGER_RISING | 384 - IRQF_ONESHOT, "sec_pmic-ono", sec_pmic); 385 - break; 386 - default: 387 - ret = -EINVAL; 388 - break; 389 - } 390 - 391 - if (ret) { 392 - dev_err(sec_pmic->dev, "Failed to request IRQ %d: %d\n", 393 - sec_pmic->ono, ret); 397 + if (ret != 0) { 398 + dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret); 394 399 return ret; 395 400 } 396 401 ··· 313 490 314 491 void sec_irq_exit(struct sec_pmic_dev *sec_pmic) 315 492 { 316 - if (sec_pmic->ono) 317 - free_irq(sec_pmic->ono, sec_pmic); 318 - 319 - if (sec_pmic->irq) 320 - free_irq(sec_pmic->irq, sec_pmic); 493 + regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data); 321 494 }
+2
include/linux/mfd/samsung/core.h
··· 48 48 int device_type; 49 49 int irq_base; 50 50 int irq; 51 + struct regmap_irq_chip_data *irq_data; 52 + 51 53 int ono; 52 54 u8 irq_masks_cur[NUM_IRQ_REGS]; 53 55 u8 irq_masks_cache[NUM_IRQ_REGS];
+42
include/linux/mfd/samsung/irq.h
··· 13 13 #ifndef __LINUX_MFD_SEC_IRQ_H 14 14 #define __LINUX_MFD_SEC_IRQ_H 15 15 16 + enum s2mps11_irq { 17 + S2MPS11_IRQ_PWRONF, 18 + S2MPS11_IRQ_PWRONR, 19 + S2MPS11_IRQ_JIGONBF, 20 + S2MPS11_IRQ_JIGONBR, 21 + S2MPS11_IRQ_ACOKBF, 22 + S2MPS11_IRQ_ACOKBR, 23 + S2MPS11_IRQ_PWRON1S, 24 + S2MPS11_IRQ_MRB, 25 + 26 + S2MPS11_IRQ_RTC60S, 27 + S2MPS11_IRQ_RTCA1, 28 + S2MPS11_IRQ_RTCA2, 29 + S2MPS11_IRQ_SMPL, 30 + S2MPS11_IRQ_RTC1S, 31 + S2MPS11_IRQ_WTSR, 32 + 33 + S2MPS11_IRQ_INT120C, 34 + S2MPS11_IRQ_INT140C, 35 + 36 + S2MPS11_IRQ_NR, 37 + }; 38 + 39 + #define S2MPS11_IRQ_PWRONF_MASK (1 << 0) 40 + #define S2MPS11_IRQ_PWRONR_MASK (1 << 1) 41 + #define S2MPS11_IRQ_JIGONBF_MASK (1 << 2) 42 + #define S2MPS11_IRQ_JIGONBR_MASK (1 << 3) 43 + #define S2MPS11_IRQ_ACOKBF_MASK (1 << 4) 44 + #define S2MPS11_IRQ_ACOKBR_MASK (1 << 5) 45 + #define S2MPS11_IRQ_PWRON1S_MASK (1 << 6) 46 + #define S2MPS11_IRQ_MRB_MASK (1 << 7) 47 + 48 + #define S2MPS11_IRQ_RTC60S_MASK (1 << 0) 49 + #define S2MPS11_IRQ_RTCA1_MASK (1 << 1) 50 + #define S2MPS11_IRQ_RTCA2_MASK (1 << 2) 51 + #define S2MPS11_IRQ_SMPL_MASK (1 << 3) 52 + #define S2MPS11_IRQ_RTC1S_MASK (1 << 4) 53 + #define S2MPS11_IRQ_WTSR_MASK (1 << 5) 54 + 55 + #define S2MPS11_IRQ_INT120C_MASK (1 << 0) 56 + #define S2MPS11_IRQ_INT140C_MASK (1 << 1) 57 + 16 58 enum s5m8767_irq { 17 59 S5M8767_IRQ_PWRR, 18 60 S5M8767_IRQ_PWRF,