From cee7413d84044a0c1919a7c70a2d761ae24390de Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 15 Jun 2017 17:46:37 +0200 Subject: [PATCH 1/7] pinctrl: samsung: Fix NULL pointer exception on external interrupts on S3C24xx After commit 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank"), the S3C24xx (and probably S3C64xx as well) fails: Unable to handle kernel NULL pointer dereference at virtual address 000000a8 ... (s3c24xx_demux_eint4_7) from [] (__handle_domain_irq+0x6c/0xcc) (__handle_domain_irq) from [] (s3c24xx_handle_irq+0x6c/0x12c) (s3c24xx_handle_irq) from [] (__irq_svc+0x5c/0x78) Mentioned commit moved the pointer to controller's base IO memory address from each controller's driver data (samsung_pinctrl_drv_data) to per-bank structure (samsung_pin_bank). The external interrupt demux handlers (s3c24xx_demux_eint()) tried to get this base address from opaque pointer stored under irq_chip data: struct irq_data *irqd = irq_desc_get_irq_data(desc); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); ... pend = readl(bank->eint_base + EINTPEND_REG); which is wrong because this is hardware irq and it bank was never set for this irq_chip. For S3C24xx and S3C64xx, this partially reverts mentioned commit by bringing back the virt_base stored under each controller's driver data (samsung_pinctrl_drv_data). This virt_base address will be now duplicated: - samsung_pinctrl_drv_data->virt_base: used on S3C24xx and S3C64xx, - samsung_pin_bank->pctl_base: used on Exynos. Fixes: 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank") Cc: Cc: Sergio Prado Reported-by: Sergio Prado Signed-off-by: Krzysztof Kozlowski Tested-by: Lihua Yao --- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 37 ++++++++++++--------- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 40 ++++++++++------------- drivers/pinctrl/samsung/pinctrl-samsung.c | 6 ++++ drivers/pinctrl/samsung/pinctrl-samsung.h | 5 +++ 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 49774851e84a..edf27264b603 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, u32 val; /* Make sure that pin is configured as interrupt */ - reg = bank->pctl_base + bank->pctl_offset; + reg = d->virt_base + bank->pctl_offset; shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; @@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_data *data, unsigned int type) s3c24xx_eint_set_handler(data, type); /* Set up interrupt trigger */ - reg = bank->eint_base + EINT_REG(index); + reg = d->virt_base + EINT_REG(index); shift = EINT_OFFS(index); val = readl(reg); @@ -259,29 +259,32 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc) static void s3c2412_eint0_3_ack(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long bitval = 1UL << data->hwirq; - writel(bitval, bank->eint_base + EINTPEND_REG); + writel(bitval, d->virt_base + EINTPEND_REG); } static void s3c2412_eint0_3_mask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long mask; - mask = readl(bank->eint_base + EINTMASK_REG); + mask = readl(d->virt_base + EINTMASK_REG); mask |= (1UL << data->hwirq); - writel(mask, bank->eint_base + EINTMASK_REG); + writel(mask, d->virt_base + EINTMASK_REG); } static void s3c2412_eint0_3_unmask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long mask; - mask = readl(bank->eint_base + EINTMASK_REG); + mask = readl(d->virt_base + EINTMASK_REG); mask &= ~(1UL << data->hwirq); - writel(mask, bank->eint_base + EINTMASK_REG); + writel(mask, d->virt_base + EINTMASK_REG); } static struct irq_chip s3c2412_eint0_3_chip = { @@ -316,31 +319,34 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc) static void s3c24xx_eint_ack(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; - writel(1UL << index, bank->eint_base + EINTPEND_REG); + writel(1UL << index, d->virt_base + EINTPEND_REG); } static void s3c24xx_eint_mask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; unsigned long mask; - mask = readl(bank->eint_base + EINTMASK_REG); + mask = readl(d->virt_base + EINTMASK_REG); mask |= (1UL << index); - writel(mask, bank->eint_base + EINTMASK_REG); + writel(mask, d->virt_base + EINTMASK_REG); } static void s3c24xx_eint_unmask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; unsigned long mask; - mask = readl(bank->eint_base + EINTMASK_REG); + mask = readl(d->virt_base + EINTMASK_REG); mask &= ~(1UL << index); - writel(mask, bank->eint_base + EINTMASK_REG); + writel(mask, d->virt_base + EINTMASK_REG); } static struct irq_chip s3c24xx_eint_chip = { @@ -356,14 +362,13 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc, { struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *irqd = irq_desc_get_irq_data(desc); - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); + struct samsung_pinctrl_drv_data *d = data->drvdata; unsigned int pend, mask; chained_irq_enter(chip, desc); - pend = readl(bank->eint_base + EINTPEND_REG); - mask = readl(bank->eint_base + EINTMASK_REG); + pend = readl(d->virt_base + EINTPEND_REG); + mask = readl(d->virt_base + EINTMASK_REG); pend &= ~mask; pend &= range; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 4a88d7446e87..e63663b32907 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, u32 val; /* Make sure that pin is configured as interrupt */ - reg = bank->pctl_base + bank->pctl_offset; + reg = d->virt_base + bank->pctl_offset; shift = pin; if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { /* 4-bit bank type with 2 con regs */ @@ -308,8 +308,9 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset); + void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); u32 val; val = readl(reg); @@ -333,8 +334,9 @@ static void s3c64xx_gpio_irq_mask(struct irq_data *irqd) static void s3c64xx_gpio_irq_ack(struct irq_data *irqd) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); + struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset); + void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); writel(1 << index, reg); } @@ -357,7 +359,7 @@ static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) s3c64xx_irq_set_handler(irqd, type); /* Set up interrupt trigger */ - reg = bank->eint_base + EINTCON_REG(bank->eint_offset); + reg = d->virt_base + EINTCON_REG(bank->eint_offset); shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ @@ -409,8 +411,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc); - struct irq_data *irqd = irq_desc_get_irq_data(desc); - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); + struct samsung_pinctrl_drv_data *drvdata = data->drvdata; chained_irq_enter(chip, desc); @@ -420,7 +421,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) unsigned int pin; unsigned int virq; - svc = readl(bank->eint_base + SERVICE_REG); + svc = readl(drvdata->virt_base + SERVICE_REG); group = SVC_GROUP(svc); pin = svc & SVC_NUM_MASK; @@ -515,15 +516,15 @@ static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask) { struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank *bank = ddata->bank; + struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; u32 val; - val = readl(bank->eint_base + EINT0MASK_REG); + val = readl(d->virt_base + EINT0MASK_REG); if (mask) val |= 1 << ddata->eints[irqd->hwirq]; else val &= ~(1 << ddata->eints[irqd->hwirq]); - writel(val, bank->eint_base + EINT0MASK_REG); + writel(val, d->virt_base + EINT0MASK_REG); } static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd) @@ -540,10 +541,10 @@ static void s3c64xx_eint0_irq_ack(struct irq_data *irqd) { struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank *bank = ddata->bank; + struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; writel(1 << ddata->eints[irqd->hwirq], - bank->eint_base + EINT0PEND_REG); + d->virt_base + EINT0PEND_REG); } static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) @@ -551,7 +552,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *bank = ddata->bank; - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; + struct samsung_pinctrl_drv_data *d = bank->drvdata; void __iomem *reg; int trigger; u8 shift; @@ -566,7 +567,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) s3c64xx_irq_set_handler(irqd, type); /* Set up interrupt trigger */ - reg = bank->eint_base + EINT0CON0_REG; + reg = d->virt_base + EINT0CON0_REG; shift = ddata->eints[irqd->hwirq]; if (shift >= EINT_MAX_PER_REG) { reg += 4; @@ -598,19 +599,14 @@ static struct irq_chip s3c64xx_eint0_irq_chip = { static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range) { struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_data *irqd = irq_desc_get_irq_data(desc); - struct s3c64xx_eint0_domain_data *ddata = - irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank *bank = ddata->bank; - struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc); - + struct samsung_pinctrl_drv_data *drvdata = data->drvdata; unsigned int pend, mask; chained_irq_enter(chip, desc); - pend = readl(bank->eint_base + EINT0PEND_REG); - mask = readl(bank->eint_base + EINT0MASK_REG); + pend = readl(drvdata->virt_base + EINT0PEND_REG); + mask = readl(drvdata->virt_base + EINT0MASK_REG); pend = pend & range & ~mask; pend &= range; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index f542642eed8d..61bbd54e35ba 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1013,6 +1013,12 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, bank->eint_base = virt_base[0]; bank->pctl_base = virt_base[bdata->pctl_res_idx]; } + /* + * Legacy platforms should provide only one resource with IO memory. + * Store it as virt_base because legacy driver needs to access it + * through samsung_pinctrl_drv_data. + */ + d->virt_base = virt_base[0]; for_each_child_of_node(node, np) { if (!of_find_property(np, "gpio-controller", NULL)) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 515a61035e54..61c4cab0ad24 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -247,6 +247,10 @@ struct samsung_pin_ctrl { /** * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. * @node: global list node + * @virt_base: register base address of the controller; this will be equal + * to each bank samsung_pin_bank->pctl_base and used on legacy + * platforms (like S3C24XX or S3C64XX) which has to access the base + * through samsung_pinctrl_drv_data, not samsung_pin_bank). * @dev: device instance representing the controller. * @irq: interrpt number used by the controller to notify gpio interrupts. * @ctrl: pin controller instance managed by the driver. @@ -262,6 +266,7 @@ struct samsung_pin_ctrl { */ struct samsung_pinctrl_drv_data { struct list_head node; + void __iomem *virt_base; struct device *dev; int irq; From af0b0baa89953aed07034725023371b2fa50a1e6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 14 Jun 2017 15:18:28 +0200 Subject: [PATCH 2/7] pinctrl: samsung: Fix invalid register offset used for Exynos5433 external interrupts When setting the pin function for external interrupts, the driver used wrong IO memory address base. The pin function register is always under pctl_base, not the eint_base. By updating wrong register, the external interrupts for chosen GPIO would not work at all and some other GPIO might be configured to wrong value. For example on Exynos5433-based boards, the external interrupts for gpf{1-5}-X GPIOs should not work at all (driver toggled reserved registers from ALIVE bank instead). Platforms other than Exynos5433 should not be affected as eint_base equals pctl_base in such case. Fixes: 8b1bd11c1f8f ("pinctrl: samsung: Add the support the multiple IORESOURCE_MEM for one pin-bank") Cc: Reported-by: Tomasz Figa Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki --- drivers/pinctrl/samsung/pinctrl-exynos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 731530a9ce38..9ab8faf528a6 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -174,10 +174,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd) spin_lock_irqsave(&bank->slock, flags); - con = readl(bank->eint_base + reg_con); + con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_EINT_FUNC << shift; - writel(con, bank->eint_base + reg_con); + writel(con, bank->pctl_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); @@ -202,10 +202,10 @@ static void exynos_irq_release_resources(struct irq_data *irqd) spin_lock_irqsave(&bank->slock, flags); - con = readl(bank->eint_base + reg_con); + con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); con |= FUNC_INPUT << shift; - writel(con, bank->eint_base + reg_con); + writel(con, bank->pctl_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); From ff60dcedbd99395c3355bc00fd302c31c96c9b92 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 15 Jun 2017 17:06:27 +0200 Subject: [PATCH 3/7] pinctrl: samsung: dt-bindings: Use better name for external interrupt function On Exynos, 0xf is always used as value of external interrupt in pin mux function thus a more descriptive macro name can be used. Signed-off-by: Krzysztof Kozlowski --- include/dt-bindings/pinctrl/samsung.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/pinctrl/samsung.h b/include/dt-bindings/pinctrl/samsung.h index b7aa3646208b..ceb672305f59 100644 --- a/include/dt-bindings/pinctrl/samsung.h +++ b/include/dt-bindings/pinctrl/samsung.h @@ -66,7 +66,8 @@ #define EXYNOS_PIN_FUNC_4 4 #define EXYNOS_PIN_FUNC_5 5 #define EXYNOS_PIN_FUNC_6 6 -#define EXYNOS_PIN_FUNC_F 0xf +#define EXYNOS_PIN_FUNC_EINT 0xf +#define EXYNOS_PIN_FUNC_F EXYNOS_PIN_FUNC_EINT /* Drive strengths for Exynos7 FSYS1 block */ #define EXYNOS7_FSYS1_PIN_DRV_LV1 0 From 4460dc21cbaf056cf34b82d72d9b6270ec0b02fe Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 15 Jun 2017 17:06:28 +0200 Subject: [PATCH 4/7] pinctrl: samsung: Use define from dt-bindings for pin mux function We already have macros for values used by driver and Device Tree sources for pin mux configuration. Use them instead of duplicating defines. Signed-off-by: Krzysztof Kozlowski --- drivers/pinctrl/samsung/pinctrl-exynos.c | 6 ++++-- drivers/pinctrl/samsung/pinctrl-exynos.h | 1 - drivers/pinctrl/samsung/pinctrl-samsung.c | 4 +++- drivers/pinctrl/samsung/pinctrl-samsung.h | 4 ---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 9ab8faf528a6..d68d52dc6804 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -31,6 +31,8 @@ #include #include +#include + #include "pinctrl-samsung.h" #include "pinctrl-exynos.h" @@ -176,7 +178,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd) con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); - con |= EXYNOS_EINT_FUNC << shift; + con |= EXYNOS_PIN_FUNC_EINT << shift; writel(con, bank->pctl_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); @@ -204,7 +206,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd) con = readl(bank->pctl_base + reg_con); con &= ~(mask << shift); - con |= FUNC_INPUT << shift; + con |= EXYNOS_PIN_FUNC_INPUT << shift; writel(con, bank->pctl_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h index b90139715c8f..7639b926c5c1 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.h +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h @@ -32,7 +32,6 @@ #define EXYNOS7_WKUP_EMASK_OFFSET 0x900 #define EXYNOS7_WKUP_EPEND_OFFSET 0xA00 #define EXYNOS_SVC_OFFSET 0xB08 -#define EXYNOS_EINT_FUNC 0xF /* helpers to access interrupt service register */ #define EXYNOS_SVC_GROUP_SHIFT 3 diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 61bbd54e35ba..1f73dd25665a 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -30,6 +30,8 @@ #include #include +#include + #include "../core.h" #include "pinctrl-samsung.h" @@ -586,7 +588,7 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, data = readl(reg); data &= ~(mask << shift); if (!input) - data |= FUNC_OUTPUT << shift; + data |= EXYNOS_PIN_FUNC_OUTPUT << shift; writel(data, reg); return 0; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 61c4cab0ad24..15b26c786b1e 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -25,10 +25,6 @@ #include -/* pinmux function number for pin as gpio output line */ -#define FUNC_INPUT 0x0 -#define FUNC_OUTPUT 0x1 - /** * enum pincfg_type - possible pin configuration types supported. * @PINCFG_TYPE_FUNC: Function configuration. From 52d0ed009cfba83b3cc869380497361f699a4545 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 15 Jun 2017 18:33:15 +0200 Subject: [PATCH 5/7] pinctrl: samsung: Use unsigned int for number of controller IO mem resources Number of IO memory resources cannot be negative obviously and the driver depends silently on this (by iterating from 0 to nr_ext_resources+1). Make this requirement explicit. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sylwester Nawrocki --- drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +- drivers/pinctrl/samsung/pinctrl-samsung.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 1f73dd25665a..6efb428b4882 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -960,7 +960,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, struct samsung_pin_bank *bank; struct resource *res; void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES]; - int i; + unsigned int i; id = of_alias_get_id(node, "pinctrl"); if (id < 0) { diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 15b26c786b1e..49a05f4fc37d 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -231,7 +231,7 @@ struct samsung_retention_data { struct samsung_pin_ctrl { const struct samsung_pin_bank_data *pin_banks; u32 nr_banks; - int nr_ext_resources; + unsigned int nr_ext_resources; const struct samsung_retention_data *retention_data; int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); From 12cdd5790fe342bf223cbfc13f9929201fbe22db Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 15 Jun 2017 18:33:16 +0200 Subject: [PATCH 6/7] pinctrl: samsung: Consistently use unsigned instead of u32 for nr_banks Unlike for other countable members, the driver used u32 for number of banks (nr_banks). There is no specific need for using fixed-width integer in this particular place. Make it consistent. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sylwester Nawrocki --- drivers/pinctrl/samsung/pinctrl-samsung.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 49a05f4fc37d..9af07af6cad6 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -230,7 +230,7 @@ struct samsung_retention_data { */ struct samsung_pin_ctrl { const struct samsung_pin_bank_data *pin_banks; - u32 nr_banks; + unsigned int nr_banks; unsigned int nr_ext_resources; const struct samsung_retention_data *retention_data; @@ -275,7 +275,7 @@ struct samsung_pinctrl_drv_data { unsigned int nr_functions; struct samsung_pin_bank *pin_banks; - u32 nr_banks; + unsigned int nr_banks; unsigned int pin_base; unsigned int nr_pins; From bbed85f45b2b727bb776b914b84c67e8fd825433 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 18 Jul 2017 19:43:28 +0200 Subject: [PATCH 7/7] pinctrl: samsung: Remove unneeded local variable initialization Two local variables (shift and reg_con) were initialized to unused values - they were overwritten just few lines after. Getting rid of this unused initialization allows dropping other variables and compacting slightly the code. Signed-off-by: Krzysztof Kozlowski --- drivers/pinctrl/samsung/pinctrl-exynos.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d68d52dc6804..c8d0de7ea160 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -151,15 +151,10 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) static int exynos_irq_request_resources(struct irq_data *irqd) { - struct irq_chip *chip = irq_data_get_irq_chip(irqd); - struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); const struct samsung_pin_bank_type *bank_type = bank->type; - unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; - unsigned long reg_con = our_chip->eint_con + bank->eint_offset; - unsigned long flags; - unsigned int mask; - unsigned int con; + unsigned long reg_con, flags; + unsigned int shift, mask, con; int ret; ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq); @@ -188,15 +183,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd) static void exynos_irq_release_resources(struct irq_data *irqd) { - struct irq_chip *chip = irq_data_get_irq_chip(irqd); - struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); const struct samsung_pin_bank_type *bank_type = bank->type; - unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; - unsigned long reg_con = our_chip->eint_con + bank->eint_offset; - unsigned long flags; - unsigned int mask; - unsigned int con; + unsigned long reg_con, flags; + unsigned int shift, mask, con; reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];