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

Merge tag 'samsung-pinctrl-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung into devel

Samsung pinctrl driver changes for v4.14:
1. Fix NULL pointer dereference on S3C24XX. This was reported some time ago and
unfortunately it took few releases to fix.
2. Fix invalid register offset used for external interrupts on Exynos5433.
This was caused by the same commit as above, although on different path.
3. Consolidate between drivers and bindings the defines for pin mux functions.
4. Minor code improvements.

+71 -69
+12 -20
drivers/pinctrl/samsung/pinctrl-exynos.c
··· 31 31 #include <linux/err.h> 32 32 #include <linux/soc/samsung/exynos-pmu.h> 33 33 34 + #include <dt-bindings/pinctrl/samsung.h> 35 + 34 36 #include "pinctrl-samsung.h" 35 37 #include "pinctrl-exynos.h" 36 38 ··· 151 149 152 150 static int exynos_irq_request_resources(struct irq_data *irqd) 153 151 { 154 - struct irq_chip *chip = irq_data_get_irq_chip(irqd); 155 - struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 156 152 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 157 153 const struct samsung_pin_bank_type *bank_type = bank->type; 158 - unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; 159 - unsigned long reg_con = our_chip->eint_con + bank->eint_offset; 160 - unsigned long flags; 161 - unsigned int mask; 162 - unsigned int con; 154 + unsigned long reg_con, flags; 155 + unsigned int shift, mask, con; 163 156 int ret; 164 157 165 158 ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq); ··· 171 174 172 175 spin_lock_irqsave(&bank->slock, flags); 173 176 174 - con = readl(bank->eint_base + reg_con); 177 + con = readl(bank->pctl_base + reg_con); 175 178 con &= ~(mask << shift); 176 - con |= EXYNOS_EINT_FUNC << shift; 177 - writel(con, bank->eint_base + reg_con); 179 + con |= EXYNOS_PIN_FUNC_EINT << shift; 180 + writel(con, bank->pctl_base + reg_con); 178 181 179 182 spin_unlock_irqrestore(&bank->slock, flags); 180 183 ··· 183 186 184 187 static void exynos_irq_release_resources(struct irq_data *irqd) 185 188 { 186 - struct irq_chip *chip = irq_data_get_irq_chip(irqd); 187 - struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); 188 189 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 189 190 const struct samsung_pin_bank_type *bank_type = bank->type; 190 - unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; 191 - unsigned long reg_con = our_chip->eint_con + bank->eint_offset; 192 - unsigned long flags; 193 - unsigned int mask; 194 - unsigned int con; 191 + unsigned long reg_con, flags; 192 + unsigned int shift, mask, con; 195 193 196 194 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; 197 195 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; ··· 194 202 195 203 spin_lock_irqsave(&bank->slock, flags); 196 204 197 - con = readl(bank->eint_base + reg_con); 205 + con = readl(bank->pctl_base + reg_con); 198 206 con &= ~(mask << shift); 199 - con |= FUNC_INPUT << shift; 200 - writel(con, bank->eint_base + reg_con); 207 + con |= EXYNOS_PIN_FUNC_INPUT << shift; 208 + writel(con, bank->pctl_base + reg_con); 201 209 202 210 spin_unlock_irqrestore(&bank->slock, flags); 203 211
-1
drivers/pinctrl/samsung/pinctrl-exynos.h
··· 32 32 #define EXYNOS7_WKUP_EMASK_OFFSET 0x900 33 33 #define EXYNOS7_WKUP_EPEND_OFFSET 0xA00 34 34 #define EXYNOS_SVC_OFFSET 0xB08 35 - #define EXYNOS_EINT_FUNC 0xF 36 35 37 36 /* helpers to access interrupt service register */ 38 37 #define EXYNOS_SVC_GROUP_SHIFT 3
+21 -16
drivers/pinctrl/samsung/pinctrl-s3c24xx.c
··· 151 151 u32 val; 152 152 153 153 /* Make sure that pin is configured as interrupt */ 154 - reg = bank->pctl_base + bank->pctl_offset; 154 + reg = d->virt_base + bank->pctl_offset; 155 155 shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; 156 156 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; 157 157 ··· 184 184 s3c24xx_eint_set_handler(data, type); 185 185 186 186 /* Set up interrupt trigger */ 187 - reg = bank->eint_base + EINT_REG(index); 187 + reg = d->virt_base + EINT_REG(index); 188 188 shift = EINT_OFFS(index); 189 189 190 190 val = readl(reg); ··· 259 259 static void s3c2412_eint0_3_ack(struct irq_data *data) 260 260 { 261 261 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 262 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 262 263 263 264 unsigned long bitval = 1UL << data->hwirq; 264 - writel(bitval, bank->eint_base + EINTPEND_REG); 265 + writel(bitval, d->virt_base + EINTPEND_REG); 265 266 } 266 267 267 268 static void s3c2412_eint0_3_mask(struct irq_data *data) 268 269 { 269 270 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 271 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 270 272 unsigned long mask; 271 273 272 - mask = readl(bank->eint_base + EINTMASK_REG); 274 + mask = readl(d->virt_base + EINTMASK_REG); 273 275 mask |= (1UL << data->hwirq); 274 - writel(mask, bank->eint_base + EINTMASK_REG); 276 + writel(mask, d->virt_base + EINTMASK_REG); 275 277 } 276 278 277 279 static void s3c2412_eint0_3_unmask(struct irq_data *data) 278 280 { 279 281 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 282 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 280 283 unsigned long mask; 281 284 282 - mask = readl(bank->eint_base + EINTMASK_REG); 285 + mask = readl(d->virt_base + EINTMASK_REG); 283 286 mask &= ~(1UL << data->hwirq); 284 - writel(mask, bank->eint_base + EINTMASK_REG); 287 + writel(mask, d->virt_base + EINTMASK_REG); 285 288 } 286 289 287 290 static struct irq_chip s3c2412_eint0_3_chip = { ··· 319 316 static void s3c24xx_eint_ack(struct irq_data *data) 320 317 { 321 318 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 319 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 322 320 unsigned char index = bank->eint_offset + data->hwirq; 323 321 324 - writel(1UL << index, bank->eint_base + EINTPEND_REG); 322 + writel(1UL << index, d->virt_base + EINTPEND_REG); 325 323 } 326 324 327 325 static void s3c24xx_eint_mask(struct irq_data *data) 328 326 { 329 327 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 328 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 330 329 unsigned char index = bank->eint_offset + data->hwirq; 331 330 unsigned long mask; 332 331 333 - mask = readl(bank->eint_base + EINTMASK_REG); 332 + mask = readl(d->virt_base + EINTMASK_REG); 334 333 mask |= (1UL << index); 335 - writel(mask, bank->eint_base + EINTMASK_REG); 334 + writel(mask, d->virt_base + EINTMASK_REG); 336 335 } 337 336 338 337 static void s3c24xx_eint_unmask(struct irq_data *data) 339 338 { 340 339 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 340 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 341 341 unsigned char index = bank->eint_offset + data->hwirq; 342 342 unsigned long mask; 343 343 344 - mask = readl(bank->eint_base + EINTMASK_REG); 344 + mask = readl(d->virt_base + EINTMASK_REG); 345 345 mask &= ~(1UL << index); 346 - writel(mask, bank->eint_base + EINTMASK_REG); 346 + writel(mask, d->virt_base + EINTMASK_REG); 347 347 } 348 348 349 349 static struct irq_chip s3c24xx_eint_chip = { ··· 362 356 { 363 357 struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc); 364 358 struct irq_chip *chip = irq_desc_get_chip(desc); 365 - struct irq_data *irqd = irq_desc_get_irq_data(desc); 366 - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 359 + struct samsung_pinctrl_drv_data *d = data->drvdata; 367 360 unsigned int pend, mask; 368 361 369 362 chained_irq_enter(chip, desc); 370 363 371 - pend = readl(bank->eint_base + EINTPEND_REG); 372 - mask = readl(bank->eint_base + EINTMASK_REG); 364 + pend = readl(d->virt_base + EINTPEND_REG); 365 + mask = readl(d->virt_base + EINTMASK_REG); 373 366 374 367 pend &= ~mask; 375 368 pend &= range;
+18 -22
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
··· 280 280 u32 val; 281 281 282 282 /* Make sure that pin is configured as interrupt */ 283 - reg = bank->pctl_base + bank->pctl_offset; 283 + reg = d->virt_base + bank->pctl_offset; 284 284 shift = pin; 285 285 if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { 286 286 /* 4-bit bank type with 2 con regs */ ··· 308 308 static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask) 309 309 { 310 310 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 311 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 311 312 unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; 312 - void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset); 313 + void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); 313 314 u32 val; 314 315 315 316 val = readl(reg); ··· 334 333 static void s3c64xx_gpio_irq_ack(struct irq_data *irqd) 335 334 { 336 335 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 336 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 337 337 unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; 338 - void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset); 338 + void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); 339 339 340 340 writel(1 << index, reg); 341 341 } ··· 359 357 s3c64xx_irq_set_handler(irqd, type); 360 358 361 359 /* Set up interrupt trigger */ 362 - reg = bank->eint_base + EINTCON_REG(bank->eint_offset); 360 + reg = d->virt_base + EINTCON_REG(bank->eint_offset); 363 361 shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; 364 362 shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ 365 363 ··· 411 409 { 412 410 struct irq_chip *chip = irq_desc_get_chip(desc); 413 411 struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc); 414 - struct irq_data *irqd = irq_desc_get_irq_data(desc); 415 - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); 412 + struct samsung_pinctrl_drv_data *drvdata = data->drvdata; 416 413 417 414 chained_irq_enter(chip, desc); 418 415 ··· 421 420 unsigned int pin; 422 421 unsigned int virq; 423 422 424 - svc = readl(bank->eint_base + SERVICE_REG); 423 + svc = readl(drvdata->virt_base + SERVICE_REG); 425 424 group = SVC_GROUP(svc); 426 425 pin = svc & SVC_NUM_MASK; 427 426 ··· 516 515 { 517 516 struct s3c64xx_eint0_domain_data *ddata = 518 517 irq_data_get_irq_chip_data(irqd); 519 - struct samsung_pin_bank *bank = ddata->bank; 518 + struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; 520 519 u32 val; 521 520 522 - val = readl(bank->eint_base + EINT0MASK_REG); 521 + val = readl(d->virt_base + EINT0MASK_REG); 523 522 if (mask) 524 523 val |= 1 << ddata->eints[irqd->hwirq]; 525 524 else 526 525 val &= ~(1 << ddata->eints[irqd->hwirq]); 527 - writel(val, bank->eint_base + EINT0MASK_REG); 526 + writel(val, d->virt_base + EINT0MASK_REG); 528 527 } 529 528 530 529 static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd) ··· 541 540 { 542 541 struct s3c64xx_eint0_domain_data *ddata = 543 542 irq_data_get_irq_chip_data(irqd); 544 - struct samsung_pin_bank *bank = ddata->bank; 543 + struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; 545 544 546 545 writel(1 << ddata->eints[irqd->hwirq], 547 - bank->eint_base + EINT0PEND_REG); 546 + d->virt_base + EINT0PEND_REG); 548 547 } 549 548 550 549 static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) ··· 552 551 struct s3c64xx_eint0_domain_data *ddata = 553 552 irq_data_get_irq_chip_data(irqd); 554 553 struct samsung_pin_bank *bank = ddata->bank; 555 - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; 554 + struct samsung_pinctrl_drv_data *d = bank->drvdata; 556 555 void __iomem *reg; 557 556 int trigger; 558 557 u8 shift; ··· 567 566 s3c64xx_irq_set_handler(irqd, type); 568 567 569 568 /* Set up interrupt trigger */ 570 - reg = bank->eint_base + EINT0CON0_REG; 569 + reg = d->virt_base + EINT0CON0_REG; 571 570 shift = ddata->eints[irqd->hwirq]; 572 571 if (shift >= EINT_MAX_PER_REG) { 573 572 reg += 4; ··· 599 598 static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range) 600 599 { 601 600 struct irq_chip *chip = irq_desc_get_chip(desc); 602 - struct irq_data *irqd = irq_desc_get_irq_data(desc); 603 - struct s3c64xx_eint0_domain_data *ddata = 604 - irq_data_get_irq_chip_data(irqd); 605 - struct samsung_pin_bank *bank = ddata->bank; 606 - 607 601 struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc); 608 - 602 + struct samsung_pinctrl_drv_data *drvdata = data->drvdata; 609 603 unsigned int pend, mask; 610 604 611 605 chained_irq_enter(chip, desc); 612 606 613 - pend = readl(bank->eint_base + EINT0PEND_REG); 614 - mask = readl(bank->eint_base + EINT0MASK_REG); 607 + pend = readl(drvdata->virt_base + EINT0PEND_REG); 608 + mask = readl(drvdata->virt_base + EINT0MASK_REG); 615 609 616 610 pend = pend & range & ~mask; 617 611 pend &= range;
+10 -2
drivers/pinctrl/samsung/pinctrl-samsung.c
··· 30 30 #include <linux/of_device.h> 31 31 #include <linux/spinlock.h> 32 32 33 + #include <dt-bindings/pinctrl/samsung.h> 34 + 33 35 #include "../core.h" 34 36 #include "pinctrl-samsung.h" 35 37 ··· 588 586 data = readl(reg); 589 587 data &= ~(mask << shift); 590 588 if (!input) 591 - data |= FUNC_OUTPUT << shift; 589 + data |= EXYNOS_PIN_FUNC_OUTPUT << shift; 592 590 writel(data, reg); 593 591 594 592 return 0; ··· 960 958 struct samsung_pin_bank *bank; 961 959 struct resource *res; 962 960 void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES]; 963 - int i; 961 + unsigned int i; 964 962 965 963 id = of_alias_get_id(node, "pinctrl"); 966 964 if (id < 0) { ··· 1015 1013 bank->eint_base = virt_base[0]; 1016 1014 bank->pctl_base = virt_base[bdata->pctl_res_idx]; 1017 1015 } 1016 + /* 1017 + * Legacy platforms should provide only one resource with IO memory. 1018 + * Store it as virt_base because legacy driver needs to access it 1019 + * through samsung_pinctrl_drv_data. 1020 + */ 1021 + d->virt_base = virt_base[0]; 1018 1022 1019 1023 for_each_child_of_node(node, np) { 1020 1024 if (!of_find_property(np, "gpio-controller", NULL))
+8 -7
drivers/pinctrl/samsung/pinctrl-samsung.h
··· 25 25 26 26 #include <linux/gpio.h> 27 27 28 - /* pinmux function number for pin as gpio output line */ 29 - #define FUNC_INPUT 0x0 30 - #define FUNC_OUTPUT 0x1 31 - 32 28 /** 33 29 * enum pincfg_type - possible pin configuration types supported. 34 30 * @PINCFG_TYPE_FUNC: Function configuration. ··· 230 234 */ 231 235 struct samsung_pin_ctrl { 232 236 const struct samsung_pin_bank_data *pin_banks; 233 - u32 nr_banks; 234 - int nr_ext_resources; 237 + unsigned int nr_banks; 238 + unsigned int nr_ext_resources; 235 239 const struct samsung_retention_data *retention_data; 236 240 237 241 int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); ··· 243 247 /** 244 248 * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. 245 249 * @node: global list node 250 + * @virt_base: register base address of the controller; this will be equal 251 + * to each bank samsung_pin_bank->pctl_base and used on legacy 252 + * platforms (like S3C24XX or S3C64XX) which has to access the base 253 + * through samsung_pinctrl_drv_data, not samsung_pin_bank). 246 254 * @dev: device instance representing the controller. 247 255 * @irq: interrpt number used by the controller to notify gpio interrupts. 248 256 * @ctrl: pin controller instance managed by the driver. ··· 262 262 */ 263 263 struct samsung_pinctrl_drv_data { 264 264 struct list_head node; 265 + void __iomem *virt_base; 265 266 struct device *dev; 266 267 int irq; 267 268 ··· 275 274 unsigned int nr_functions; 276 275 277 276 struct samsung_pin_bank *pin_banks; 278 - u32 nr_banks; 277 + unsigned int nr_banks; 279 278 unsigned int pin_base; 280 279 unsigned int nr_pins; 281 280
+2 -1
include/dt-bindings/pinctrl/samsung.h
··· 66 66 #define EXYNOS_PIN_FUNC_4 4 67 67 #define EXYNOS_PIN_FUNC_5 5 68 68 #define EXYNOS_PIN_FUNC_6 6 69 - #define EXYNOS_PIN_FUNC_F 0xf 69 + #define EXYNOS_PIN_FUNC_EINT 0xf 70 + #define EXYNOS_PIN_FUNC_F EXYNOS_PIN_FUNC_EINT 70 71 71 72 /* Drive strengths for Exynos7 FSYS1 block */ 72 73 #define EXYNOS7_FSYS1_PIN_DRV_LV1 0