From af99a7507469d4fa6dd4d8d633e093b1ff7aff6e Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 21 May 2013 00:56:13 +0900 Subject: pinctrl: Add pinctrl-s3c24xx driver The s3c24xx pins follow a similar pattern as the other Samsung SoCs and can therefore reuse the already introduced infrastructure. The s3c24xx SoCs have one design oddity in that the first 4 external interrupts do not reside in the eint pending register but in the main interrupt controller instead. We solve this by forwarding the external interrupt from the main controller into the irq domain of the pin bank. The masking/acking of these interrupts is handled in the same way. Furthermore the S3C2412/2413 SoCs contain another oddity in that they keep the same 4 eints in the main interrupt controller and eintpend register and requiring ack operations to happen in both. This is solved by using different compatible properties for the wakeup eint node which set a property accordingly. Signed-off-by: Heiko Stuebner Reviewed-by: Tomasz Figa Reviewed-by: Sylwester Nawrocki Acked-by: Linus Walleij Signed-off-by: Kukjin Kim --- drivers/gpio/gpio-samsung.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b22ca793374..83a0d711b15 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -3026,6 +3026,10 @@ static __init int samsung_gpiolib_init(void) */ struct device_node *pctrl_np; static const struct of_device_id exynos_pinctrl_ids[] = { + { .compatible = "samsung,s3c2412-pinctrl", }, + { .compatible = "samsung,s3c2416-pinctrl", }, + { .compatible = "samsung,s3c2440-pinctrl", }, + { .compatible = "samsung,s3c2450-pinctrl", }, { .compatible = "samsung,exynos4210-pinctrl", }, { .compatible = "samsung,exynos4x12-pinctrl", }, { .compatible = "samsung,exynos5250-pinctrl", }, -- cgit v1.2.3 From 9fdb27d48a3a1abae4c3554b82dce9f0aafc377a Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 10 Jun 2013 18:22:19 +0900 Subject: gpio: samsung: Remove OF support for s3c24xx There is no users of this code and there is already a pinctrl driver written for s3c24xx which is going to be used on any s3c24xx DT platforms. Hence this has been effectively a dead code in mainline. This reverts commit 172c6a13653ac8cd6a231293b87c93821e90c1d6 gpio: samsung: add devicetree init for s3c24xx arches Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Heiko Stuebner Acked-by: Linus Walleij Signed-off-by: Kukjin Kim --- drivers/gpio/gpio-samsung.c | 63 --------------------------------------------- 1 file changed, 63 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index b22ca793374..96f6a7c7a32 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -933,67 +933,6 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) s3c_gpiolib_track(chip); } -#if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) -static int s3c24xx_gpio_xlate(struct gpio_chip *gc, - const struct of_phandle_args *gpiospec, u32 *flags) -{ - unsigned int pin; - - if (WARN_ON(gc->of_gpio_n_cells < 3)) - return -EINVAL; - - if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) - return -EINVAL; - - if (gpiospec->args[0] > gc->ngpio) - return -EINVAL; - - pin = gc->base + gpiospec->args[0]; - - if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) - pr_warn("gpio_xlate: failed to set pin function\n"); - if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff)) - pr_warn("gpio_xlate: failed to set pin pull up/down\n"); - - if (flags) - *flags = gpiospec->args[2] >> 16; - - return gpiospec->args[0]; -} - -static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = { - { .compatible = "samsung,s3c24xx-gpio", }, - {} -}; - -static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, - u64 base, u64 offset) -{ - struct gpio_chip *gc = &chip->chip; - u64 address; - - if (!of_have_populated_dt()) - return; - - address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset; - gc->of_node = of_find_matching_node_by_address(NULL, - s3c24xx_gpio_dt_match, address); - if (!gc->of_node) { - pr_info("gpio: device tree node not found for gpio controller" - " with base address %08llx\n", address); - return; - } - gc->of_gpio_n_cells = 3; - gc->of_xlate = s3c24xx_gpio_xlate; -} -#else -static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, - u64 base, u64 offset) -{ - return; -} -#endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */ - static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, int nr_chips, void __iomem *base) { @@ -1018,8 +957,6 @@ static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, gc->direction_output = samsung_gpiolib_2bit_output; samsung_gpiolib_add(chip); - - s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10); } } -- cgit v1.2.3 From 159f8a0209aff155af7f6fcdedd4a4484dd19c23 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 May 2013 13:40:06 +0200 Subject: gpio-rcar: Add DT support Add DT bindings for the gpio-rcar driver and read the device configuration from the DT node at probe time if available. Cc: devicetree-discuss@lists.ozlabs.org Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- drivers/gpio/gpio-rcar.c | 66 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 10 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index d173d56dbb8..5a693dd0ac7 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -51,6 +51,8 @@ struct gpio_rcar_priv { #define FILONOFF 0x28 #define BOTHEDGE 0x4c +#define RCAR_MAX_GPIO_PER_BANK 32 + static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs) { return ioread32(p->base + offs); @@ -274,9 +276,39 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = { .map = gpio_rcar_irq_domain_map, }; +static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) +{ + struct gpio_rcar_config *pdata = p->pdev->dev.platform_data; +#ifdef CONFIG_OF + struct device_node *np = p->pdev->dev.of_node; + struct of_phandle_args args; + int ret; +#endif + + if (pdata) + p->config = *pdata; +#ifdef CONFIG_OF + else if (np) { + ret = of_parse_phandle_with_args(np, "gpio-ranges", + "#gpio-range-cells", 0, &args); + p->config.number_of_pins = ret == 0 && args.args_count == 3 + ? args.args[2] + : RCAR_MAX_GPIO_PER_BANK; + p->config.gpio_base = -1; + } +#endif + + if (p->config.number_of_pins == 0 || + p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) { + dev_warn(&p->pdev->dev, + "Invalid number of gpio lines %u, using %u\n", + p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK); + p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK; + } +} + static int gpio_rcar_probe(struct platform_device *pdev) { - struct gpio_rcar_config *pdata = pdev->dev.platform_data; struct gpio_rcar_priv *p; struct resource *io, *irq; struct gpio_chip *gpio_chip; @@ -291,14 +323,14 @@ static int gpio_rcar_probe(struct platform_device *pdev) goto err0; } - /* deal with driver instance configuration */ - if (pdata) - p->config = *pdata; - p->pdev = pdev; - platform_set_drvdata(pdev, p); spin_lock_init(&p->lock); + /* Get device configuration from DT node or platform data. */ + gpio_rcar_parse_pdata(p); + + platform_set_drvdata(pdev, p); + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -325,6 +357,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) gpio_chip->set = gpio_rcar_set; gpio_chip->to_irq = gpio_rcar_to_irq; gpio_chip->label = name; + gpio_chip->dev = &pdev->dev; gpio_chip->owner = THIS_MODULE; gpio_chip->base = p->config.gpio_base; gpio_chip->ngpio = p->config.number_of_pins; @@ -371,10 +404,12 @@ static int gpio_rcar_probe(struct platform_device *pdev) p->config.irq_base, ret); } - ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, - gpio_chip->base, gpio_chip->ngpio); - if (ret < 0) - dev_warn(&pdev->dev, "failed to add pin range\n"); + if (p->config.pctl_name) { + ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0, + gpio_chip->base, gpio_chip->ngpio); + if (ret < 0) + dev_warn(&pdev->dev, "failed to add pin range\n"); + } return 0; @@ -397,11 +432,22 @@ static int gpio_rcar_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id gpio_rcar_of_table[] = { + { + .compatible = "renesas,gpio-rcar", + }, +}; + +MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); +#endif + static struct platform_driver gpio_rcar_device_driver = { .probe = gpio_rcar_probe, .remove = gpio_rcar_remove, .driver = { .name = "gpio_rcar", + .of_match_table = of_match_ptr(gpio_rcar_of_table), } }; -- cgit v1.2.3 From e305062e94719ef543ae936dd56501b5a36406c6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 18 Jun 2013 12:29:49 +0200 Subject: gpio-rcar: Remove #ifdef CONFIG_OF around OF-specific sections All functions and data types used by OF-specific code paths are declared in regardless of CONFIG_OF. Replace the #ifdef CONFIG_OF guard with a if(IS_ENABLED(CONFIG_OF)) and let the compiler optimize the unused code away. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- drivers/gpio/gpio-rcar.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 5a693dd0ac7..7fd09efd708 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -279,16 +279,13 @@ static struct irq_domain_ops gpio_rcar_irq_domain_ops = { static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) { struct gpio_rcar_config *pdata = p->pdev->dev.platform_data; -#ifdef CONFIG_OF struct device_node *np = p->pdev->dev.of_node; struct of_phandle_args args; int ret; -#endif - if (pdata) + if (pdata) { p->config = *pdata; -#ifdef CONFIG_OF - else if (np) { + } else if (IS_ENABLED(CONFIG_OF) && np) { ret = of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-range-cells", 0, &args); p->config.number_of_pins = ret == 0 && args.args_count == 3 @@ -296,7 +293,6 @@ static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p) : RCAR_MAX_GPIO_PER_BANK; p->config.gpio_base = -1; } -#endif if (p->config.number_of_pins == 0 || p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) { -- cgit v1.2.3 From 30d2266c685ce9f560e5023e4add58f890554a46 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 17 Jun 2013 09:55:50 +0200 Subject: gpio: rcar: fix gpio_rcar_of_table The device table needs to be terminated with an empty element. Signed-off-by: Arnd Bergmann Cc: Laurent Pinchart Cc: Simon Horman --- drivers/gpio/gpio-rcar.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 5a693dd0ac7..f3327533bfd 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -437,6 +437,7 @@ static const struct of_device_id gpio_rcar_of_table[] = { { .compatible = "renesas,gpio-rcar", }, + { }, }; MODULE_DEVICE_TABLE(of, gpio_rcar_of_table); -- cgit v1.2.3