From be717102c8ba2d0ea0225e9fe0590fd71e24caf4 Mon Sep 17 00:00:00 2001 From: Tomaz Solc Date: Mon, 18 Feb 2019 12:32:15 +0100 Subject: pinctrl: bcm2835: move existing code from gpio. Signed-off-by: Sascha Hauer --- drivers/gpio/Kconfig | 4 - drivers/gpio/Makefile | 1 - drivers/gpio/gpio-bcm2835.c | 162 -------------------------------------- drivers/pinctrl/Kconfig | 6 ++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-bcm2835.c | 162 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 169 insertions(+), 167 deletions(-) delete mode 100644 drivers/gpio/gpio-bcm2835.c create mode 100644 drivers/pinctrl/pinctrl-bcm2835.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index ed93e868ae..c535904ed0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -21,10 +21,6 @@ config GPIO_74164 shift registers. This driver can be used to provide access to more gpio outputs. -config GPIO_BCM283X - bool "GPIO support for BCM283X" - depends on ARCH_BCM283X - config GPIO_CLPS711X bool "GPIO support for CLPS711X" depends on ARCH_CLPS711X diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index f5ed876d5e..52280f0bb4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -2,7 +2,6 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o obj-$(CONFIG_GPIO_74164) += gpio-74164.o obj-$(CONFIG_MACH_MIPS_ATH79) += gpio-ath79.o -obj-$(CONFIG_GPIO_BCM283X) += gpio-bcm2835.o obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o obj-$(CONFIG_GPIO_DIGIC) += gpio-digic.o diff --git a/drivers/gpio/gpio-bcm2835.c b/drivers/gpio/gpio-bcm2835.c deleted file mode 100644 index 1802ab7ccb..0000000000 --- a/drivers/gpio/gpio-bcm2835.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Author: Carlo Caione - * - * Based on linux/arch/arm/mach-bcm2708/bcm2708_gpio.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#define GPIOFSEL(x) (0x00+(x)*4) -#define GPIOSET(x) (0x1c+(x)*4) -#define GPIOCLR(x) (0x28+(x)*4) -#define GPIOLEV(x) (0x34+(x)*4) -#define GPIOEDS(x) (0x40+(x)*4) -#define GPIOREN(x) (0x4c+(x)*4) -#define GPIOFEN(x) (0x58+(x)*4) -#define GPIOHEN(x) (0x64+(x)*4) -#define GPIOLEN(x) (0x70+(x)*4) -#define GPIOAREN(x) (0x7c+(x)*4) -#define GPIOAFEN(x) (0x88+(x)*4) -#define GPIOUD(x) (0x94+(x)*4) -#define GPIOUDCLK(x) (0x98+(x)*4) - -enum { - GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, - GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, - GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, - GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, -}; - -struct bcm2835_gpio_chip { - void __iomem *base; - struct gpio_chip chip; -}; - -static int bcm2835_set_function(struct gpio_chip *chip, unsigned gpio, int function) -{ - struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); - void __iomem *base = bcmgpio->base; - unsigned gpiodir; - unsigned gpio_bank = gpio / 10; - unsigned gpio_field_offset = (gpio - 10 * gpio_bank) * 3; - - gpiodir = readl(base + GPIOFSEL(gpio_bank)); - gpiodir &= ~(7 << gpio_field_offset); - gpiodir |= function << gpio_field_offset; - writel(gpiodir, base + GPIOFSEL(gpio_bank)); - gpiodir = readl(base + GPIOFSEL(gpio_bank)); - - return 0; -} - -static void bcm2835_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) -{ - struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); - void __iomem *base = bcmgpio->base; - unsigned gpio_bank = gpio / 32; - unsigned gpio_field_offset = gpio % 32; - - if (value) - writel(1 << gpio_field_offset, base + GPIOSET(gpio_bank)); - else - writel(1 << gpio_field_offset, base + GPIOCLR(gpio_bank)); -} - -static int bcm2835_gpio_get_value(struct gpio_chip *chip, unsigned gpio) -{ - struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); - void __iomem *base = bcmgpio->base; - unsigned gpio_bank = gpio / 32; - unsigned gpio_field_offset = gpio % 32; - unsigned lev; - - lev = readl(base + GPIOLEV(gpio_bank)); - return 0x1 & (lev >> gpio_field_offset); -} - -static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -{ - return bcm2835_set_function(chip, gpio, GPIO_FSEL_INPUT); -} - -static int bcm2835_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) -{ - bcm2835_set_function(chip, gpio, GPIO_FSEL_OUTPUT); - bcm2835_gpio_set_value(chip, gpio, value); - - return 0; -} - -static struct gpio_ops bcm2835_gpio_ops = { - .direction_input = bcm2835_gpio_direction_input, - .direction_output = bcm2835_gpio_direction_output, - .get = bcm2835_gpio_get_value, - .set = bcm2835_gpio_set_value, -}; - -static int bcm2835_gpio_probe(struct device_d *dev) -{ - struct resource *iores; - struct bcm2835_gpio_chip *bcmgpio; - int ret; - - bcmgpio = xzalloc(sizeof(*bcmgpio)); - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); - bcmgpio->base = IOMEM(iores->start); - bcmgpio->chip.ops = &bcm2835_gpio_ops; - bcmgpio->chip.base = 0; - bcmgpio->chip.ngpio = 54; - bcmgpio->chip.dev = dev; - - ret = gpiochip_add(&bcmgpio->chip); - if (ret) { - dev_err(dev, "couldn't add gpiochip, ret = %d\n", ret); - goto err; - } - dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, bcmgpio->chip.base); - - return 0; - -err: - kfree(bcmgpio); - - return ret; -} - -static __maybe_unused struct of_device_id bcm2835_gpio_dt_ids[] = { - { - .compatible = "brcm,bcm2835-gpio", - }, { - /* sentinel */ - } -}; - -static struct driver_d bcm2835_gpio_driver = { - .name = "bcm2835-gpio", - .probe = bcm2835_gpio_probe, - .of_compatible = DRV_OF_COMPAT(bcm2835_gpio_dt_ids), -}; - -static int bcm2835_gpio_add(void) -{ - return platform_driver_register(&bcm2835_gpio_driver); -} -coredevice_initcall(bcm2835_gpio_add); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index de83c124a1..45c3b351d6 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -17,6 +17,12 @@ config PINCTRL_AT91 help The pinmux controller found on AT91 SoCs. +config PINCTRL_BCM283X + bool "GPIO and pinmux support for BCM283X" + depends on ARCH_BCM283X + help + The pinmux controller on BCM2835 + config PINCTRL_IMX_IOMUX_V1 bool help diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 9450dbbdf5..35b2d4707c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o +obj-$(CONFIG_PINCTRL_BCM283X) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c new file mode 100644 index 0000000000..1802ab7ccb --- /dev/null +++ b/drivers/pinctrl/pinctrl-bcm2835.c @@ -0,0 +1,162 @@ +/* + * Author: Carlo Caione + * + * Based on linux/arch/arm/mach-bcm2708/bcm2708_gpio.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +#define GPIOFSEL(x) (0x00+(x)*4) +#define GPIOSET(x) (0x1c+(x)*4) +#define GPIOCLR(x) (0x28+(x)*4) +#define GPIOLEV(x) (0x34+(x)*4) +#define GPIOEDS(x) (0x40+(x)*4) +#define GPIOREN(x) (0x4c+(x)*4) +#define GPIOFEN(x) (0x58+(x)*4) +#define GPIOHEN(x) (0x64+(x)*4) +#define GPIOLEN(x) (0x70+(x)*4) +#define GPIOAREN(x) (0x7c+(x)*4) +#define GPIOAFEN(x) (0x88+(x)*4) +#define GPIOUD(x) (0x94+(x)*4) +#define GPIOUDCLK(x) (0x98+(x)*4) + +enum { + GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, + GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, + GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, + GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, +}; + +struct bcm2835_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; + +static int bcm2835_set_function(struct gpio_chip *chip, unsigned gpio, int function) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpiodir; + unsigned gpio_bank = gpio / 10; + unsigned gpio_field_offset = (gpio - 10 * gpio_bank) * 3; + + gpiodir = readl(base + GPIOFSEL(gpio_bank)); + gpiodir &= ~(7 << gpio_field_offset); + gpiodir |= function << gpio_field_offset; + writel(gpiodir, base + GPIOFSEL(gpio_bank)); + gpiodir = readl(base + GPIOFSEL(gpio_bank)); + + return 0; +} + +static void bcm2835_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpio_bank = gpio / 32; + unsigned gpio_field_offset = gpio % 32; + + if (value) + writel(1 << gpio_field_offset, base + GPIOSET(gpio_bank)); + else + writel(1 << gpio_field_offset, base + GPIOCLR(gpio_bank)); +} + +static int bcm2835_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpio_bank = gpio / 32; + unsigned gpio_field_offset = gpio % 32; + unsigned lev; + + lev = readl(base + GPIOLEV(gpio_bank)); + return 0x1 & (lev >> gpio_field_offset); +} + +static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + return bcm2835_set_function(chip, gpio, GPIO_FSEL_INPUT); +} + +static int bcm2835_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) +{ + bcm2835_set_function(chip, gpio, GPIO_FSEL_OUTPUT); + bcm2835_gpio_set_value(chip, gpio, value); + + return 0; +} + +static struct gpio_ops bcm2835_gpio_ops = { + .direction_input = bcm2835_gpio_direction_input, + .direction_output = bcm2835_gpio_direction_output, + .get = bcm2835_gpio_get_value, + .set = bcm2835_gpio_set_value, +}; + +static int bcm2835_gpio_probe(struct device_d *dev) +{ + struct resource *iores; + struct bcm2835_gpio_chip *bcmgpio; + int ret; + + bcmgpio = xzalloc(sizeof(*bcmgpio)); + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + bcmgpio->base = IOMEM(iores->start); + bcmgpio->chip.ops = &bcm2835_gpio_ops; + bcmgpio->chip.base = 0; + bcmgpio->chip.ngpio = 54; + bcmgpio->chip.dev = dev; + + ret = gpiochip_add(&bcmgpio->chip); + if (ret) { + dev_err(dev, "couldn't add gpiochip, ret = %d\n", ret); + goto err; + } + dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, bcmgpio->chip.base); + + return 0; + +err: + kfree(bcmgpio); + + return ret; +} + +static __maybe_unused struct of_device_id bcm2835_gpio_dt_ids[] = { + { + .compatible = "brcm,bcm2835-gpio", + }, { + /* sentinel */ + } +}; + +static struct driver_d bcm2835_gpio_driver = { + .name = "bcm2835-gpio", + .probe = bcm2835_gpio_probe, + .of_compatible = DRV_OF_COMPAT(bcm2835_gpio_dt_ids), +}; + +static int bcm2835_gpio_add(void) +{ + return platform_driver_register(&bcm2835_gpio_driver); +} +coredevice_initcall(bcm2835_gpio_add); -- cgit v1.2.3