* [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs @ 2017-12-08 15:46 Alexandre Belloni 2017-12-08 15:46 ` [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot Alexandre Belloni ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Alexandre Belloni @ 2017-12-08 15:46 UTC (permalink / raw) To: Ralf Baechle Cc: linux-mips, linux-kernel, Alexandre Belloni, Rob Herring, devicetree, Thomas Gleixner, Jason Cooper, Linus Walleij, linux-gpio, Sebastian Reichel, linux-pm Hi, This patch series adds initial support for the Microsemi MIPS SoCs. It is currently focusing on the Microsemi Ocelot (VSC7513, VSC7514). It adds support for the IRQ controller, pinmux and gpio controller and reset control. This produces a kernel that can boot to the console. This is a single series for reference but it can also be taken separately by each maintainer as each drivers are independant. Changes in v2: - removed the wildcard in MAINAINERS - corrected the Cc list - added proper documentation for both syscons - removed the mscc,cpucontrol property - updated the ranges property in the ocelot dtsi Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: linux-gpio@vger.kernel.org Cc: Sebastian Reichel <sre@kernel.org> Cc: linux-pm@vger.kernel.org Alexandre Belloni (13): dt-bindings: Add vendor prefix for Microsemi Corporation dt-bindings: interrupt-controller: Add binding for the Microsemi Ocelot interrupt controller irqchip: Add a driver for the Microsemi Ocelot controller dt-bindings: pinctrl: Add bindings for Microsemi Ocelot pinctrl: Add Microsemi Ocelot SoC driver dt-bindings: mips: Add bindings for Microsemi SoCs dt-bindings: power: reset: Document ocelot-reset binding power: reset: Add a driver for the Microsemi Ocelot reset MIPS: mscc: Add initial support for Microsemi MIPS SoCs MIPS: mscc: add ocelot dtsi MIPS: mscc: add ocelot PCB123 device tree MIPS: defconfigs: add a defconfig for Microsemi SoCs MAINTAINERS: Add entry for Microsemi MIPS SoCs .../interrupt-controller/mscc,ocelot-icpu-intr.txt | 22 + Documentation/devicetree/bindings/mips/mscc.txt | 46 ++ .../bindings/pinctrl/mscc,ocelot-pinctrl.txt | 39 ++ .../bindings/power/reset/ocelot-reset.txt | 17 + .../devicetree/bindings/vendor-prefixes.txt | 1 + MAINTAINERS | 7 + arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 24 + arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/mscc/Makefile | 6 + arch/mips/boot/dts/mscc/ocelot.dtsi | 115 +++++ arch/mips/boot/dts/mscc/ocelot_pcb123.dts | 27 ++ arch/mips/configs/mscc_defconfig | 84 ++++ arch/mips/mscc/Makefile | 11 + arch/mips/mscc/Platform | 12 + arch/mips/mscc/setup.c | 106 +++++ drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-mscc-ocelot.c | 109 +++++ drivers/pinctrl/Kconfig | 10 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-ocelot.c | 505 +++++++++++++++++++++ drivers/power/reset/Kconfig | 7 + drivers/power/reset/Makefile | 1 + drivers/power/reset/ocelot-reset.c | 86 ++++ 25 files changed, 1244 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.txt create mode 100644 Documentation/devicetree/bindings/mips/mscc.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt create mode 100644 Documentation/devicetree/bindings/power/reset/ocelot-reset.txt create mode 100644 arch/mips/boot/dts/mscc/Makefile create mode 100644 arch/mips/boot/dts/mscc/ocelot.dtsi create mode 100644 arch/mips/boot/dts/mscc/ocelot_pcb123.dts create mode 100644 arch/mips/configs/mscc_defconfig create mode 100644 arch/mips/mscc/Makefile create mode 100644 arch/mips/mscc/Platform create mode 100644 arch/mips/mscc/setup.c create mode 100644 drivers/irqchip/irq-mscc-ocelot.c create mode 100644 drivers/pinctrl/pinctrl-ocelot.c create mode 100644 drivers/power/reset/ocelot-reset.c -- 2.15.1 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot 2017-12-08 15:46 [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs Alexandre Belloni @ 2017-12-08 15:46 ` Alexandre Belloni 2017-12-13 7:39 ` Linus Walleij 2017-12-08 15:46 ` [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver Alexandre Belloni 2017-12-17 16:59 ` [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs PrasannaKumar Muralidharan 2 siblings, 1 reply; 14+ messages in thread From: Alexandre Belloni @ 2017-12-08 15:46 UTC (permalink / raw) To: Ralf Baechle Cc: linux-mips, linux-kernel, Alexandre Belloni, Linus Walleij, linux-gpio Add the documentation for the Microsemi Ocelot pinmuxing and gpio controller. Cc: Linus Walleij <linus.walleij@linaro.org> Cc: linux-gpio@vger.kernel.org Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Rob Herring <robh@kernel.org> --- .../bindings/pinctrl/mscc,ocelot-pinctrl.txt | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt diff --git a/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt new file mode 100644 index 000000000000..24a210e0c59a --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt @@ -0,0 +1,39 @@ +Microsemi Ocelot pin controller Device Tree Bindings +---------------------------------------------------- + +Required properties: + - compatible : Should be "mscc,ocelot-pinctrl" + - reg : Address and length of the register set for the device + - gpio-controller : Indicates this device is a GPIO controller + - #gpio-cells : Must be 2. + The first cell is the pin number and the + second cell specifies GPIO flags, as defined in + <dt-bindings/gpio/gpio.h>. + - gpio-ranges : Range of pins managed by the GPIO controller. + + +The ocelot-pinctrl driver uses the generic pin multiplexing and generic pin +configuration documented in pinctrl-bindings.txt. + +The following generic properties are supported: + - function + - pins + +Example: + gpio: pinctrl@71070034 { + compatible = "mscc,ocelot-pinctrl"; + reg = <0x71070034 0x28>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 22>; + + uart_pins: uart-pins { + pins = "GPIO_6", "GPIO_7"; + function = "uart"; + }; + + uart2_pins: uart2-pins { + pins = "GPIO_12", "GPIO_13"; + function = "uart2"; + }; + }; -- 2.15.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot 2017-12-08 15:46 ` [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot Alexandre Belloni @ 2017-12-13 7:39 ` Linus Walleij 0 siblings, 0 replies; 14+ messages in thread From: Linus Walleij @ 2017-12-13 7:39 UTC (permalink / raw) To: Alexandre Belloni Cc: Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On Fri, Dec 8, 2017 at 4:46 PM, Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote: > Add the documentation for the Microsemi Ocelot pinmuxing and gpio > controller. > > Cc: Linus Walleij <linus.walleij@linaro.org> > Cc: linux-gpio@vger.kernel.org > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > Acked-by: Rob Herring <robh@kernel.org> Patch applied. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-08 15:46 [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs Alexandre Belloni 2017-12-08 15:46 ` [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot Alexandre Belloni @ 2017-12-08 15:46 ` Alexandre Belloni 2017-12-13 8:15 ` Linus Walleij 2017-12-17 16:59 ` [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs PrasannaKumar Muralidharan 2 siblings, 1 reply; 14+ messages in thread From: Alexandre Belloni @ 2017-12-08 15:46 UTC (permalink / raw) To: Ralf Baechle Cc: linux-mips, linux-kernel, Alexandre Belloni, Linus Walleij, linux-gpio The Microsemi Ocelot SoC has a few pins that can be used as GPIOs or take multiple other functions. Add a driver for the pinmuxing and the GPIOs. There is currently no support for interrupts. Cc: Linus Walleij <linus.walleij@linaro.org> Cc: linux-gpio@vger.kernel.org Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> --- drivers/pinctrl/Kconfig | 10 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-ocelot.c | 505 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 516 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-ocelot.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4571cc098b76..99c36baedbad 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -343,6 +343,16 @@ config PINCTRL_RK805 help This selects the pinctrl driver for RK805. +config PINCTRL_OCELOT + bool "Pinctrl driver for the Microsemi Ocelot SoCs" + default y + depends on OF + depends on MSCC_OCELOT || COMPILE_TEST + select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select REGMAP_MMIO + source "drivers/pinctrl/aspeed/Kconfig" source "drivers/pinctrl/bcm/Kconfig" source "drivers/pinctrl/berlin/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index d0d4844f8022..b1cae074a949 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o +obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-y += bcm/ diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c new file mode 100644 index 000000000000..677e172bb945 --- /dev/null +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -0,0 +1,505 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <alexandre.belloni@free-electrons.com> + * License: Dual MIT/GPL + * Copyright (c) 2017 Microsemi Corporation + */ + +#include <linux/compiler.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +#include "core.h" +#include "pinconf.h" +#include "pinmux.h" + +#define OCELOT_GPIO_OUT_SET 0x0 +#define OCELOT_GPIO_OUT_CLR 0x4 +#define OCELOT_GPIO_OUT 0x8 +#define OCELOT_GPIO_IN 0xc +#define OCELOT_GPIO_OE 0x10 +#define OCELOT_GPIO_INTR 0x14 +#define OCELOT_GPIO_INTR_ENA 0x18 +#define OCELOT_GPIO_INTR_IDENT 0x1c +#define OCELOT_GPIO_ALT0 0x20 +#define OCELOT_GPIO_ALT1 0x24 +#define OCELOT_GPIO_SD_MAP 0x28 + +#define OCELOT_PINS 22 +#define OCELOT_FUNC_PER_PIN 4 + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_IRQ0_IN, + FUNC_IRQ0_OUT, + FUNC_IRQ1_IN, + FUNC_IRQ1_OUT, + FUNC_MIIM1, + FUNC_PCI_WAKE, + FUNC_PTP0, + FUNC_PTP1, + FUNC_PTP2, + FUNC_PTP3, + FUNC_PWM, + FUNC_RECO_CLK0, + FUNC_RECO_CLK1, + FUNC_SFP0, + FUNC_SFP1, + FUNC_SFP2, + FUNC_SFP3, + FUNC_SFP4, + FUNC_SFP5, + FUNC_SG0, + FUNC_SI, + FUNC_TACHO, + FUNC_TWI, + FUNC_TWI_SCL_M, + FUNC_UART, + FUNC_UART2, + FUNC_MAX +}; + +static const char *const ocelot_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_IRQ0_IN] = "irq0_in", + [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1_IN] = "irq1_in", + [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_MIIM1] = "miim1", + [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_PTP0] = "ptp0", + [FUNC_PTP1] = "ptp1", + [FUNC_PTP2] = "ptp2", + [FUNC_PTP3] = "ptp3", + [FUNC_PWM] = "pwm", + [FUNC_RECO_CLK0] = "reco_clk0", + [FUNC_RECO_CLK1] = "reco_clk1", + [FUNC_SFP0] = "sfp0", + [FUNC_SFP1] = "sfp1", + [FUNC_SFP2] = "sfp2", + [FUNC_SFP3] = "sfp3", + [FUNC_SFP4] = "sfp4", + [FUNC_SFP5] = "sfp5", + [FUNC_SG0] = "sg0", + [FUNC_SI] = "si", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_TWI_SCL_M] = "twi_scl_m", + [FUNC_UART] = "uart", + [FUNC_UART2] = "uart2", +}; + +struct ocelot_pmx_func { + const char **groups; + unsigned int ngroups; +}; + +struct ocelot_pin_caps { + unsigned int pin; + unsigned char functions[OCELOT_FUNC_PER_PIN]; +}; + +struct ocelot_pinctrl { + struct device *dev; + struct pinctrl_dev *pctl; + struct gpio_chip gpio_chip; + struct regmap *map; + struct ocelot_pmx_func func[FUNC_MAX]; +}; + +#define OCELOT_P(p, f0, f1, f2) \ +static struct ocelot_pin_caps ocelot_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2, \ + }, \ +} + +OCELOT_P(0, SG0, NONE, NONE); +OCELOT_P(1, SG0, NONE, NONE); +OCELOT_P(2, SG0, NONE, NONE); +OCELOT_P(3, SG0, NONE, NONE); +OCELOT_P(4, IRQ0_IN, IRQ0_OUT, TWI); +OCELOT_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); +OCELOT_P(6, UART, TWI_SCL_M, NONE); +OCELOT_P(7, UART, TWI_SCL_M, NONE); +OCELOT_P(8, SI, TWI_SCL_M, IRQ0_OUT); +OCELOT_P(9, SI, TWI_SCL_M, IRQ1_OUT); +OCELOT_P(10, PTP2, TWI_SCL_M, SFP0); +OCELOT_P(11, PTP3, TWI_SCL_M, SFP1); +OCELOT_P(12, UART2, TWI_SCL_M, SFP2); +OCELOT_P(13, UART2, TWI_SCL_M, SFP3); +OCELOT_P(14, MIIM1, TWI_SCL_M, SFP4); +OCELOT_P(15, MIIM1, TWI_SCL_M, SFP5); +OCELOT_P(16, TWI, NONE, SI); +OCELOT_P(17, TWI, TWI_SCL_M, SI); +OCELOT_P(18, PTP0, TWI_SCL_M, NONE); +OCELOT_P(19, PTP1, TWI_SCL_M, NONE); +OCELOT_P(20, RECO_CLK0, TACHO, NONE); +OCELOT_P(21, RECO_CLK1, PWM, NONE); + +#define OCELOT_PIN(n) { \ + .number = n, \ + .name = "GPIO_"#n, \ + .drv_data = &ocelot_pin_##n \ +} + +static const struct pinctrl_pin_desc ocelot_pins[] = { + OCELOT_PIN(0), + OCELOT_PIN(1), + OCELOT_PIN(2), + OCELOT_PIN(3), + OCELOT_PIN(4), + OCELOT_PIN(5), + OCELOT_PIN(6), + OCELOT_PIN(7), + OCELOT_PIN(8), + OCELOT_PIN(9), + OCELOT_PIN(10), + OCELOT_PIN(11), + OCELOT_PIN(12), + OCELOT_PIN(13), + OCELOT_PIN(14), + OCELOT_PIN(15), + OCELOT_PIN(16), + OCELOT_PIN(17), + OCELOT_PIN(18), + OCELOT_PIN(19), + OCELOT_PIN(20), + OCELOT_PIN(21), +}; + +static int ocelot_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(ocelot_function_names); +} + +static const char *ocelot_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + return ocelot_function_names[function]; +} + +static int ocelot_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char *const **groups, + unsigned *const num_groups) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + *groups = info->func[function].groups; + *num_groups = info->func[function].ngroups; + + return 0; +} + +static int ocelot_pin_function_idx(unsigned int pin, unsigned int function) +{ + struct ocelot_pin_caps *p = ocelot_pins[pin].drv_data; + int i; + + for (i = 0; i < OCELOT_FUNC_PER_PIN; i++) { + if (function == p->functions[i]) + return i; + } + + return -1; +} + +static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int selector, unsigned int group) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct ocelot_pin_caps *pin = ocelot_pins[group].drv_data; + int f; + + f = ocelot_pin_function_idx(group, selector); + if (f < 0) + return -EINVAL; + + regmap_update_bits(info->map, OCELOT_GPIO_ALT0, BIT(pin->pin), + f << pin->pin); + regmap_update_bits(info->map, OCELOT_GPIO_ALT1, BIT(pin->pin), + f << (pin->pin - 1)); + + return 0; +} + +static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + regmap_update_bits(info->map, OCELOT_GPIO_OE, BIT(pin), + input ? BIT(pin) : 0); + + return 0; +} + +static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + regmap_update_bits(info->map, OCELOT_GPIO_ALT0, BIT(offset), 0); + regmap_update_bits(info->map, OCELOT_GPIO_ALT1, BIT(offset), 0); + + return 0; +} + +static const struct pinmux_ops ocelot_pmx_ops = { + .get_functions_count = ocelot_get_functions_count, + .get_function_name = ocelot_get_function_name, + .get_function_groups = ocelot_get_function_groups, + .set_mux = ocelot_pinmux_set_mux, + .gpio_set_direction = ocelot_gpio_set_direction, + .gpio_request_enable = ocelot_gpio_request_enable, +}; + +static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(ocelot_pins); +} + +static const char *ocelot_pctl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + return ocelot_pins[group].name; +} + +static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &ocelot_pins[group].number; + *num_pins = 1; + + return 0; +} + +static const struct pinctrl_ops ocelot_pctl_ops = { + .get_groups_count = ocelot_pctl_get_groups_count, + .get_group_name = ocelot_pctl_get_group_name, + .get_group_pins = ocelot_pctl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static struct pinctrl_desc ocelot_desc = { + .name = "ocelot-pinctrl", + .pins = ocelot_pins, + .npins = ARRAY_SIZE(ocelot_pins), + .pctlops = &ocelot_pctl_ops, + .pmxops = &ocelot_pmx_ops, + .owner = THIS_MODULE, +}; + +static int ocelot_create_group_func_map(struct device *dev, + struct ocelot_pinctrl *info) +{ + u16 pins[ARRAY_SIZE(ocelot_pins)]; + int f, npins, i; + + for (f = 0; f < FUNC_MAX; f++) { + for (npins = 0, i = 0; i < ARRAY_SIZE(ocelot_pins); i++) { + if (ocelot_pin_function_idx(i, f) >= 0) + pins[npins++] = i; + } + + info->func[f].ngroups = npins; + info->func[f].groups = devm_kzalloc(dev, npins * + sizeof(char *), + GFP_KERNEL); + if (!info->func[f].groups) + return -ENOMEM; + + for (i = 0; i < npins; i++) + info->func[f].groups[i] = ocelot_pins[pins[i]].name; + } + + return 0; +} + +static int ocelot_pinctrl_register(struct platform_device *pdev, + struct ocelot_pinctrl *info) +{ + int ret; + + ret = ocelot_create_group_func_map(&pdev->dev, info); + if (ret) { + dev_err(&pdev->dev, "Unable to create group func map.\n"); + return ret; + } + + info->pctl = devm_pinctrl_register(&pdev->dev, &ocelot_desc, info); + if (IS_ERR(info->pctl)) { + dev_err(&pdev->dev, "Failed to register pinctrl\n"); + return PTR_ERR(info->pctl); + } + + return 0; +} + +static int ocelot_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int val; + + regmap_read(info->map, OCELOT_GPIO_IN, &val); + + return !!(val & BIT(offset)); +} + +static void ocelot_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + + if (value) + regmap_write(info->map, OCELOT_GPIO_OUT_SET, BIT(offset)); + else + regmap_write(info->map, OCELOT_GPIO_OUT_CLR, BIT(offset)); +} + +static int ocelot_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int val; + + regmap_read(info->map, OCELOT_GPIO_OE, &val); + + return !(val & BIT(offset)); +} + +static int ocelot_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + + return regmap_update_bits(info->map, OCELOT_GPIO_OE, BIT(offset), 0); +} + +static int ocelot_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int pin = BIT(offset); + + if (value) + regmap_write(info->map, OCELOT_GPIO_OUT_SET, pin); + else + regmap_write(info->map, OCELOT_GPIO_OUT_CLR, pin); + + return regmap_update_bits(info->map, OCELOT_GPIO_OE, pin, pin); +} + +static const struct gpio_chip ocelot_gpiolib_chip = { + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .set = ocelot_gpio_set, + .get = ocelot_gpio_get, + .get_direction = ocelot_gpio_get_direction, + .direction_input = ocelot_gpio_direction_input, + .direction_output = ocelot_gpio_direction_output, + .owner = THIS_MODULE, +}; + +static int ocelot_gpiochip_register(struct platform_device *pdev, + struct ocelot_pinctrl *info) +{ + struct gpio_chip *gc; + int ret; + + info->gpio_chip = ocelot_gpiolib_chip; + + gc = &info->gpio_chip; + gc->ngpio = OCELOT_PINS; + gc->parent = &pdev->dev; + gc->base = 0; + gc->of_node = info->dev->of_node; + gc->label = "ocelot-gpio"; + + ret = devm_gpiochip_add_data(&pdev->dev, gc, info); + if (ret) + return ret; + //TODO irqchip + + return 0; +} + +static const struct regmap_config ocelot_pinctrl_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +static const struct of_device_id ocelot_pinctrl_of_match[] = { + { .compatible = "mscc,ocelot-pinctrl" }, + {}, +}; + +int ocelot_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ocelot_pinctrl *info; + void __iomem *base; + int ret; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + base = devm_ioremap_resource(dev, + platform_get_resource(pdev, IORESOURCE_MEM, 0)); + if (IS_ERR(base)) { + dev_err(dev, "Failed to ioremap registers\n"); + return PTR_ERR(base); + } + + info->map = devm_regmap_init_mmio(dev, base, + &ocelot_pinctrl_regmap_config); + if (IS_ERR(info->map)) { + dev_err(dev, "Failed to create regmap\n"); + return PTR_ERR(info->map); + } + dev_set_drvdata(dev, info->map); + info->dev = dev; + + ret = ocelot_pinctrl_register(pdev, info); + if (ret) + return ret; + + ret = ocelot_gpiochip_register(pdev, info); + if (ret) + return ret; + + return 0; +} + +static struct platform_driver ocelot_pinctrl_driver = { + .driver = { + .name = "pinctrl-ocelot", + .of_match_table = of_match_ptr(ocelot_pinctrl_of_match), + .suppress_bind_attrs = true, + }, + .probe = ocelot_pinctrl_probe, +}; +builtin_platform_driver(ocelot_pinctrl_driver); -- 2.15.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-08 15:46 ` [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver Alexandre Belloni @ 2017-12-13 8:15 ` Linus Walleij 2017-12-13 9:23 ` Philippe Ombredanne ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Linus Walleij @ 2017-12-13 8:15 UTC (permalink / raw) To: Alexandre Belloni Cc: Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On Fri, Dec 8, 2017 at 4:46 PM, Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote: > The Microsemi Ocelot SoC has a few pins that can be used as GPIOs or take > multiple other functions. Add a driver for the pinmuxing and the GPIOs. > > There is currently no support for interrupts. > > Cc: Linus Walleij <linus.walleij@linaro.org> > Cc: linux-gpio@vger.kernel.org > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> This looks very good. Nice work! I was close to just applying it but found some very minor things. When you resend this just send this patch and I can apply it directly since there are only Kconfig symbol dependencies and no compile-time dependencies in this patch. > +config PINCTRL_OCELOT > + bool "Pinctrl driver for the Microsemi Ocelot SoCs" > + default y > + depends on OF > + depends on MSCC_OCELOT || COMPILE_TEST > + select GENERIC_PINCONF > + select GENERIC_PINCTRL_GROUPS > + select GENERIC_PINMUX_FUNCTIONS > + select REGMAP_MMIO select GPIOLIB When you run COMPILE_TEST you don't know if you have GPIOLIB so select it. > +// SPDX-License-Identifier: (GPL-2.0 OR MIT) Wow never saw that before. OK I guess. > +#include <linux/compiler.h> > +#include <linux/gpio.h> Just: #include <linux/gpio/driver.h> <linux/gpio.h> is a legacy include and should not be used. > +static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, > + unsigned int selector, unsigned int group) > +{ > + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); > + struct ocelot_pin_caps *pin = ocelot_pins[group].drv_data; > + int f; > + > + f = ocelot_pin_function_idx(group, selector); > + if (f < 0) > + return -EINVAL; > + > + regmap_update_bits(info->map, OCELOT_GPIO_ALT0, BIT(pin->pin), > + f << pin->pin); > + regmap_update_bits(info->map, OCELOT_GPIO_ALT1, BIT(pin->pin), > + f << (pin->pin - 1)); You need to add some comment on what is happening here and how the bits are used because just reading these two lines is pretty hard. I guess f = 0, 1, 2 .... 31 or so. pin->pin is also 0, 1, 2 ... 31? BIT(pin->pin) is pretty self-evident. It is masking the bit controlling this pin in each register. But setting bits (f << (pin->pin)) and then in the other register (f << (pin->pin -1))? Maybe you should even add an illustrative dev_dbg() print here showing which bits you mask and set, or use some helper bools so it is crystal clear what is going on. So there is two registers to select "alternative functions" (I guess?) And each has one bit for the *same* pin. This is the case also in drivers/pinctrl/nomadik/pinctrl-nomadik.c. It turns out to be a pretty horrible design decision: since the two bits are not changed in the same register transaction, switching from say function "00" to function "11" creates a "glitch" where you first activate funcion "10" after writing the first register, then finally go to function "11" after writing the second. This had horrible electrical consequences and required special workarounds in Nomadik so be on the lookout for this type of problem. > +static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, > + struct pinctrl_gpio_range *range, > + unsigned int pin, bool input) > +{ > + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); > + > + regmap_update_bits(info->map, OCELOT_GPIO_OE, BIT(pin), > + input ? BIT(pin) : 0); > + > + return 0; > +} (...) > +static const struct pinmux_ops ocelot_pmx_ops = { > + .get_functions_count = ocelot_get_functions_count, > + .get_function_name = ocelot_get_function_name, > + .get_function_groups = ocelot_get_function_groups, > + .set_mux = ocelot_pinmux_set_mux, > + .gpio_set_direction = ocelot_gpio_set_direction, > + .gpio_request_enable = ocelot_gpio_request_enable, > +}; This looks a bit weird since the same register is also written by the gpiochip to set direction. If you want to relay the direction setting entirely to the pin control subsystem, then just have your callbacks in the gpiochip like this: static int ocelot_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { return pinctrl_gpio_direction_input(chip->base + offset); } static int ocelot_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { struct ocelot_pinctrl *info = gpiochip_get_data(chip); unsigned int pin = BIT(offset); if (value) regmap_write(info->map, OCELOT_GPIO_OUT_SET, pin); else regmap_write(info->map, OCELOT_GPIO_OUT_CLR, pin); return pinctrl_gpio_direction_output(chip->base + offset); } Then all direction setting will just be relayed to the pin control side. Shouldn't this call also set up the altfunction so you know the pin is now set in GPIO mode? That is how some other drivers do it at least. But maybe you prefer to do the muxing "on the side" (using pinmux ops only, and explicitly setting up the line as GPIO in e.g. the device tree)? In that case I think you might not need this callback at all. Also: are you should you do not need to disable OCELOT_GPIO_OE in the .gpio_disable_free() callback? > +static const struct pinctrl_ops ocelot_pctl_ops = { > + .get_groups_count = ocelot_pctl_get_groups_count, > + .get_group_name = ocelot_pctl_get_group_name, > + .get_group_pins = ocelot_pctl_get_group_pins, > + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, > + .dt_free_map = pinconf_generic_dt_free_map, > +}; Nice use of the generic parsers, thanks! > + ret = devm_gpiochip_add_data(&pdev->dev, gc, info); > + if (ret) > + return ret; > + //TODO irqchip /* Please use oldschool comments for now, the license on the top is fine though */ > +static const struct regmap_config ocelot_pinctrl_regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > +}; Looks like it could have some more limitations (like max register and so on) but it's OK. > + base = devm_ioremap_resource(dev, > + platform_get_resource(pdev, IORESOURCE_MEM, 0)); > + if (IS_ERR(base)) { > + dev_err(dev, "Failed to ioremap registers\n"); > + return PTR_ERR(base); > + } > + > + info->map = devm_regmap_init_mmio(dev, base, > + &ocelot_pinctrl_regmap_config); > + if (IS_ERR(info->map)) { > + dev_err(dev, "Failed to create regmap\n"); > + return PTR_ERR(info->map); > + } Nice use of regmap MMIO! Yours, Linus Walleij ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-13 8:15 ` Linus Walleij @ 2017-12-13 9:23 ` Philippe Ombredanne 2017-12-14 23:53 ` Linus Walleij 2018-01-05 23:46 ` Alexandre Belloni 2018-01-06 0:09 ` [PATCH v3] " Alexandre Belloni 2 siblings, 1 reply; 14+ messages in thread From: Philippe Ombredanne @ 2017-12-13 9:23 UTC (permalink / raw) To: Linus Walleij Cc: Alexandre Belloni, Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On Wed, Dec 13, 2017 at 9:15 AM, Linus Walleij <linus.walleij@linaro.org> wrote: >> +// SPDX-License-Identifier: (GPL-2.0 OR MIT) > > Wow never saw that before. OK I guess. That's the new thing. Less legalese boilerplate, and more code for the better IMHO. You can check the doc patches from Thomas for details [1] [1] https://lkml.org/lkml/2017/12/4/934 -- Cordially Philippe Ombredanne ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-13 9:23 ` Philippe Ombredanne @ 2017-12-14 23:53 ` Linus Walleij 2017-12-15 7:59 ` Philippe Ombredanne 0 siblings, 1 reply; 14+ messages in thread From: Linus Walleij @ 2017-12-14 23:53 UTC (permalink / raw) To: Philippe Ombredanne Cc: Alexandre Belloni, Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On Wed, Dec 13, 2017 at 10:23 AM, Philippe Ombredanne <pombredanne@nexb.com> wrote: > On Wed, Dec 13, 2017 at 9:15 AM, Linus Walleij <linus.walleij@linaro.org> wrote: >>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT) >> >> Wow never saw that before. OK I guess. > > That's the new thing. Less legalese boilerplate, and more code for the > better IMHO. > > You can check the doc patches from Thomas for details [1] > > [1] https://lkml.org/lkml/2017/12/4/934 Yeah I'm aware of this part, but I didn't see that combined license before. What is the reason for not just using GPL 2 here? Yours, Linus Walleij ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-14 23:53 ` Linus Walleij @ 2017-12-15 7:59 ` Philippe Ombredanne 2017-12-18 16:09 ` Alexandre Belloni 0 siblings, 1 reply; 14+ messages in thread From: Philippe Ombredanne @ 2017-12-15 7:59 UTC (permalink / raw) To: Alexandre Belloni, Linus Walleij Cc: Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio Alexandre, Linux On Fri, Dec 15, 2017 at 12:53 AM, Linus Walleij <linus.walleij@linaro.org> wrote: > On Wed, Dec 13, 2017 at 10:23 AM, Philippe Ombredanne > <pombredanne@nexb.com> wrote: >> On Wed, Dec 13, 2017 at 9:15 AM, Linus Walleij <linus.walleij@linaro.org> wrote: >>>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT) >>> >>> Wow never saw that before. OK I guess. >> >> That's the new thing. Less legalese boilerplate, and more code for the >> better IMHO. >> >> You can check the doc patches from Thomas for details [1] >> >> [1] https://lkml.org/lkml/2017/12/4/934 > > Yeah I'm aware of this part, but I didn't see that combined license > before. > > What is the reason for not just using GPL 2 here? Linus, That'a a question for Alexandre that submitted this patch in the first place, not me. Alexandre? -- Cordially Philippe Ombredanne ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-15 7:59 ` Philippe Ombredanne @ 2017-12-18 16:09 ` Alexandre Belloni 0 siblings, 0 replies; 14+ messages in thread From: Alexandre Belloni @ 2017-12-18 16:09 UTC (permalink / raw) To: Philippe Ombredanne Cc: Linus Walleij, Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On 15/12/2017 at 08:59:15 +0100, Philippe Ombredanne wrote: > Alexandre, Linux > > On Fri, Dec 15, 2017 at 12:53 AM, Linus Walleij > <linus.walleij@linaro.org> wrote: > > On Wed, Dec 13, 2017 at 10:23 AM, Philippe Ombredanne > > <pombredanne@nexb.com> wrote: > >> On Wed, Dec 13, 2017 at 9:15 AM, Linus Walleij <linus.walleij@linaro.org> wrote: > >>>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT) > >>> > >>> Wow never saw that before. OK I guess. > >> > >> That's the new thing. Less legalese boilerplate, and more code for the > >> better IMHO. > >> > >> You can check the doc patches from Thomas for details [1] > >> > >> [1] https://lkml.org/lkml/2017/12/4/934 > > > > Yeah I'm aware of this part, but I didn't see that combined license > > before. > > > > What is the reason for not just using GPL 2 here? > > Linus, > That'a a question for Alexandre that submitted this patch in the first > place, not me. > > Alexandre? > I'm not the one taking that decision and I don't think this choice has a particular issue (we use the same one for device trees). I guess the idea behind it is to be able to reuse the same code in other non-GPL projects. -- Alexandre Belloni, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-13 8:15 ` Linus Walleij 2017-12-13 9:23 ` Philippe Ombredanne @ 2018-01-05 23:46 ` Alexandre Belloni 2018-01-06 0:09 ` [PATCH v3] " Alexandre Belloni 2 siblings, 0 replies; 14+ messages in thread From: Alexandre Belloni @ 2018-01-05 23:46 UTC (permalink / raw) To: Linus Walleij Cc: Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org, linux-gpio On 13/12/2017 at 09:15:20 +0100, Linus Walleij wrote: > You need to add some comment on what is happening here and how the > bits are used because just reading these two lines is pretty hard. > > I guess f = 0, 1, 2 .... 31 or so. > > pin->pin is also 0, 1, 2 ... 31? > > BIT(pin->pin) is pretty self-evident. It is masking the bit controlling > this pin in each register. > > But setting bits (f << (pin->pin)) and then in the other register > (f << (pin->pin -1))? > I've added a comment. f can take 4 values, that is 2 bits. bit 0 goes to bit(pin) of ALT0 and bit 1 goes to bit(pin) of ALT1 > Maybe you should even add an illustrative dev_dbg() print here > showing which bits you mask and set, or use some helper bools > so it is crystal clear what is going on. > > So there is two registers to select "alternative functions" (I guess?) > And each has one bit for the *same* pin. > That is correct. > This is the case also in drivers/pinctrl/nomadik/pinctrl-nomadik.c. > It turns out to be a pretty horrible design decision: since the two > bits are not changed in the same register transaction, switching > from say function "00" to function "11" creates a "glitch" where > you first activate funcion "10" after writing the first register, > then finally go to function "11" after writing the second. > > This had horrible electrical consequences and required special > workarounds in Nomadik so be on the lookout for this type > of problem. > Yes, it is definitively racy. I've added that in the comment but I don't expect that to cause any real issue soon. But I'll keep that in mind. > > +static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, > > + struct pinctrl_gpio_range *range, > > + unsigned int pin, bool input) > > +{ > > + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); > > + > > + regmap_update_bits(info->map, OCELOT_GPIO_OE, BIT(pin), > > + input ? BIT(pin) : 0); > > + > > + return 0; > > +} > (...) > > +static const struct pinmux_ops ocelot_pmx_ops = { > > + .get_functions_count = ocelot_get_functions_count, > > + .get_function_name = ocelot_get_function_name, > > + .get_function_groups = ocelot_get_function_groups, > > + .set_mux = ocelot_pinmux_set_mux, > > + .gpio_set_direction = ocelot_gpio_set_direction, > > + .gpio_request_enable = ocelot_gpio_request_enable, > > +}; > > This looks a bit weird since the same register is also written > by the gpiochip to set direction. > > If you want to relay the direction setting entirely to the pin > control subsystem, then just have your callbacks in the > gpiochip like this: > > static int ocelot_gpio_direction_input(struct gpio_chip *chip, unsigned offset) > { > return pinctrl_gpio_direction_input(chip->base + offset); > } > > static int ocelot_gpio_direction_output(struct gpio_chip *chip, unsigned offset, > int value) > { > struct ocelot_pinctrl *info = gpiochip_get_data(chip); > unsigned int pin = BIT(offset); > > if (value) > regmap_write(info->map, OCELOT_GPIO_OUT_SET, pin); > else > regmap_write(info->map, OCELOT_GPIO_OUT_CLR, pin); > > return pinctrl_gpio_direction_output(chip->base + offset); > } > > Then all direction setting will just be relayed to the pin control > side. > > Shouldn't this call also set up the altfunction so you know > the pin is now set in GPIO mode? That is how some other > drivers do it at least. But maybe you prefer to do the > muxing "on the side" (using pinmux ops only, and explicitly > setting up the line as GPIO in e.g. the device tree)? > Yes, my plan was to have an explicit muxing to GPIO in the device tree. > In that case I think you might not need this callback at all. > > Also: are you should you do not need to disable OCELOT_GPIO_OE > in the .gpio_disable_free() callback? > OCELOT_GPIO_OE doesn't matter if the pin is not muxed to GPIO. I must admit I only tested the GPIO functionnality using /sys/class/gpio as I only have one GPIO available on my board. I'm sending v3 now. -- Alexandre Belloni, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3] pinctrl: Add Microsemi Ocelot SoC driver 2017-12-13 8:15 ` Linus Walleij 2017-12-13 9:23 ` Philippe Ombredanne 2018-01-05 23:46 ` Alexandre Belloni @ 2018-01-06 0:09 ` Alexandre Belloni 2018-01-09 13:56 ` Linus Walleij 2 siblings, 1 reply; 14+ messages in thread From: Alexandre Belloni @ 2018-01-06 0:09 UTC (permalink / raw) To: Linus Walleij Cc: linux-gpio, Ralf Baechle, linux-mips, linux-kernel, Alexandre Belloni The Microsemi Ocelot SoC has a few pins that can be used as GPIOs or take multiple other functions. Add a driver for the pinmuxing and the GPIOs. There is currently no support for interrupts. Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> --- - use pinctrl_gpio_direction_input/output from ocelot_gpio_direction_input/output - add a comment for ALT0/ALT1 - fill .max_register of ocelot_pinctrl_regmap_config drivers/pinctrl/Kconfig | 11 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-ocelot.c | 511 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 523 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-ocelot.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4571cc098b76..640fb829935a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -343,6 +343,17 @@ config PINCTRL_RK805 help This selects the pinctrl driver for RK805. +config PINCTRL_OCELOT + bool "Pinctrl driver for the Microsemi Ocelot SoCs" + default y + depends on OF + depends on MSCC_OCELOT || COMPILE_TEST + select GPIOLIB + select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select REGMAP_MMIO + source "drivers/pinctrl/aspeed/Kconfig" source "drivers/pinctrl/bcm/Kconfig" source "drivers/pinctrl/berlin/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index d0d4844f8022..b1cae074a949 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o +obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-y += bcm/ diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c new file mode 100644 index 000000000000..01a50d969111 --- /dev/null +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -0,0 +1,511 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <alexandre.belloni@free-electrons.com> + * License: Dual MIT/GPL + * Copyright (c) 2017 Microsemi Corporation + */ + +#include <linux/gpio/driver.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +#include "core.h" +#include "pinconf.h" +#include "pinmux.h" + +#define OCELOT_GPIO_OUT_SET 0x0 +#define OCELOT_GPIO_OUT_CLR 0x4 +#define OCELOT_GPIO_OUT 0x8 +#define OCELOT_GPIO_IN 0xc +#define OCELOT_GPIO_OE 0x10 +#define OCELOT_GPIO_INTR 0x14 +#define OCELOT_GPIO_INTR_ENA 0x18 +#define OCELOT_GPIO_INTR_IDENT 0x1c +#define OCELOT_GPIO_ALT0 0x20 +#define OCELOT_GPIO_ALT1 0x24 +#define OCELOT_GPIO_SD_MAP 0x28 + +#define OCELOT_PINS 22 +#define OCELOT_FUNC_PER_PIN 4 + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_IRQ0_IN, + FUNC_IRQ0_OUT, + FUNC_IRQ1_IN, + FUNC_IRQ1_OUT, + FUNC_MIIM1, + FUNC_PCI_WAKE, + FUNC_PTP0, + FUNC_PTP1, + FUNC_PTP2, + FUNC_PTP3, + FUNC_PWM, + FUNC_RECO_CLK0, + FUNC_RECO_CLK1, + FUNC_SFP0, + FUNC_SFP1, + FUNC_SFP2, + FUNC_SFP3, + FUNC_SFP4, + FUNC_SFP5, + FUNC_SG0, + FUNC_SI, + FUNC_TACHO, + FUNC_TWI, + FUNC_TWI_SCL_M, + FUNC_UART, + FUNC_UART2, + FUNC_MAX +}; + +static const char *const ocelot_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_IRQ0_IN] = "irq0_in", + [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1_IN] = "irq1_in", + [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_MIIM1] = "miim1", + [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_PTP0] = "ptp0", + [FUNC_PTP1] = "ptp1", + [FUNC_PTP2] = "ptp2", + [FUNC_PTP3] = "ptp3", + [FUNC_PWM] = "pwm", + [FUNC_RECO_CLK0] = "reco_clk0", + [FUNC_RECO_CLK1] = "reco_clk1", + [FUNC_SFP0] = "sfp0", + [FUNC_SFP1] = "sfp1", + [FUNC_SFP2] = "sfp2", + [FUNC_SFP3] = "sfp3", + [FUNC_SFP4] = "sfp4", + [FUNC_SFP5] = "sfp5", + [FUNC_SG0] = "sg0", + [FUNC_SI] = "si", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_TWI_SCL_M] = "twi_scl_m", + [FUNC_UART] = "uart", + [FUNC_UART2] = "uart2", +}; + +struct ocelot_pmx_func { + const char **groups; + unsigned int ngroups; +}; + +struct ocelot_pin_caps { + unsigned int pin; + unsigned char functions[OCELOT_FUNC_PER_PIN]; +}; + +struct ocelot_pinctrl { + struct device *dev; + struct pinctrl_dev *pctl; + struct gpio_chip gpio_chip; + struct regmap *map; + struct ocelot_pmx_func func[FUNC_MAX]; +}; + +#define OCELOT_P(p, f0, f1, f2) \ +static struct ocelot_pin_caps ocelot_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2, \ + }, \ +} + +OCELOT_P(0, SG0, NONE, NONE); +OCELOT_P(1, SG0, NONE, NONE); +OCELOT_P(2, SG0, NONE, NONE); +OCELOT_P(3, SG0, NONE, NONE); +OCELOT_P(4, IRQ0_IN, IRQ0_OUT, TWI); +OCELOT_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); +OCELOT_P(6, UART, TWI_SCL_M, NONE); +OCELOT_P(7, UART, TWI_SCL_M, NONE); +OCELOT_P(8, SI, TWI_SCL_M, IRQ0_OUT); +OCELOT_P(9, SI, TWI_SCL_M, IRQ1_OUT); +OCELOT_P(10, PTP2, TWI_SCL_M, SFP0); +OCELOT_P(11, PTP3, TWI_SCL_M, SFP1); +OCELOT_P(12, UART2, TWI_SCL_M, SFP2); +OCELOT_P(13, UART2, TWI_SCL_M, SFP3); +OCELOT_P(14, MIIM1, TWI_SCL_M, SFP4); +OCELOT_P(15, MIIM1, TWI_SCL_M, SFP5); +OCELOT_P(16, TWI, NONE, SI); +OCELOT_P(17, TWI, TWI_SCL_M, SI); +OCELOT_P(18, PTP0, TWI_SCL_M, NONE); +OCELOT_P(19, PTP1, TWI_SCL_M, NONE); +OCELOT_P(20, RECO_CLK0, TACHO, NONE); +OCELOT_P(21, RECO_CLK1, PWM, NONE); + +#define OCELOT_PIN(n) { \ + .number = n, \ + .name = "GPIO_"#n, \ + .drv_data = &ocelot_pin_##n \ +} + +static const struct pinctrl_pin_desc ocelot_pins[] = { + OCELOT_PIN(0), + OCELOT_PIN(1), + OCELOT_PIN(2), + OCELOT_PIN(3), + OCELOT_PIN(4), + OCELOT_PIN(5), + OCELOT_PIN(6), + OCELOT_PIN(7), + OCELOT_PIN(8), + OCELOT_PIN(9), + OCELOT_PIN(10), + OCELOT_PIN(11), + OCELOT_PIN(12), + OCELOT_PIN(13), + OCELOT_PIN(14), + OCELOT_PIN(15), + OCELOT_PIN(16), + OCELOT_PIN(17), + OCELOT_PIN(18), + OCELOT_PIN(19), + OCELOT_PIN(20), + OCELOT_PIN(21), +}; + +static int ocelot_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(ocelot_function_names); +} + +static const char *ocelot_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + return ocelot_function_names[function]; +} + +static int ocelot_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char *const **groups, + unsigned *const num_groups) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + *groups = info->func[function].groups; + *num_groups = info->func[function].ngroups; + + return 0; +} + +static int ocelot_pin_function_idx(unsigned int pin, unsigned int function) +{ + struct ocelot_pin_caps *p = ocelot_pins[pin].drv_data; + int i; + + for (i = 0; i < OCELOT_FUNC_PER_PIN; i++) { + if (function == p->functions[i]) + return i; + } + + return -1; +} + +static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int selector, unsigned int group) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct ocelot_pin_caps *pin = ocelot_pins[group].drv_data; + int f; + + f = ocelot_pin_function_idx(group, selector); + if (f < 0) + return -EINVAL; + + /* + * f is encoded on two bits. + * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of + * ALT1 + * This is racy because both registers can't be updated at the same time + * but it doesn't matter much for now. + */ + regmap_update_bits(info->map, OCELOT_GPIO_ALT0, BIT(pin->pin), + f << pin->pin); + regmap_update_bits(info->map, OCELOT_GPIO_ALT1, BIT(pin->pin), + f << (pin->pin - 1)); + + return 0; +} + +static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + regmap_update_bits(info->map, OCELOT_GPIO_OE, BIT(pin), + input ? BIT(pin) : 0); + + return 0; +} + +static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + regmap_update_bits(info->map, OCELOT_GPIO_ALT0, BIT(offset), 0); + regmap_update_bits(info->map, OCELOT_GPIO_ALT1, BIT(offset), 0); + + return 0; +} + +static const struct pinmux_ops ocelot_pmx_ops = { + .get_functions_count = ocelot_get_functions_count, + .get_function_name = ocelot_get_function_name, + .get_function_groups = ocelot_get_function_groups, + .set_mux = ocelot_pinmux_set_mux, + .gpio_set_direction = ocelot_gpio_set_direction, + .gpio_request_enable = ocelot_gpio_request_enable, +}; + +static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(ocelot_pins); +} + +static const char *ocelot_pctl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + return ocelot_pins[group].name; +} + +static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &ocelot_pins[group].number; + *num_pins = 1; + + return 0; +} + +static const struct pinctrl_ops ocelot_pctl_ops = { + .get_groups_count = ocelot_pctl_get_groups_count, + .get_group_name = ocelot_pctl_get_group_name, + .get_group_pins = ocelot_pctl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static struct pinctrl_desc ocelot_desc = { + .name = "ocelot-pinctrl", + .pins = ocelot_pins, + .npins = ARRAY_SIZE(ocelot_pins), + .pctlops = &ocelot_pctl_ops, + .pmxops = &ocelot_pmx_ops, + .owner = THIS_MODULE, +}; + +static int ocelot_create_group_func_map(struct device *dev, + struct ocelot_pinctrl *info) +{ + u16 pins[ARRAY_SIZE(ocelot_pins)]; + int f, npins, i; + + for (f = 0; f < FUNC_MAX; f++) { + for (npins = 0, i = 0; i < ARRAY_SIZE(ocelot_pins); i++) { + if (ocelot_pin_function_idx(i, f) >= 0) + pins[npins++] = i; + } + + info->func[f].ngroups = npins; + info->func[f].groups = devm_kzalloc(dev, npins * + sizeof(char *), + GFP_KERNEL); + if (!info->func[f].groups) + return -ENOMEM; + + for (i = 0; i < npins; i++) + info->func[f].groups[i] = ocelot_pins[pins[i]].name; + } + + return 0; +} + +static int ocelot_pinctrl_register(struct platform_device *pdev, + struct ocelot_pinctrl *info) +{ + int ret; + + ret = ocelot_create_group_func_map(&pdev->dev, info); + if (ret) { + dev_err(&pdev->dev, "Unable to create group func map.\n"); + return ret; + } + + info->pctl = devm_pinctrl_register(&pdev->dev, &ocelot_desc, info); + if (IS_ERR(info->pctl)) { + dev_err(&pdev->dev, "Failed to register pinctrl\n"); + return PTR_ERR(info->pctl); + } + + return 0; +} + +static int ocelot_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int val; + + regmap_read(info->map, OCELOT_GPIO_IN, &val); + + return !!(val & BIT(offset)); +} + +static void ocelot_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + + if (value) + regmap_write(info->map, OCELOT_GPIO_OUT_SET, BIT(offset)); + else + regmap_write(info->map, OCELOT_GPIO_OUT_CLR, BIT(offset)); +} + +static int ocelot_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int val; + + regmap_read(info->map, OCELOT_GPIO_OE, &val); + + return !(val & BIT(offset)); +} + +static int ocelot_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + return pinctrl_gpio_direction_input(chip->base + offset); +} + +static int ocelot_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int pin = BIT(offset); + + if (value) + regmap_write(info->map, OCELOT_GPIO_OUT_SET, pin); + else + regmap_write(info->map, OCELOT_GPIO_OUT_CLR, pin); + + return pinctrl_gpio_direction_output(chip->base + offset); +} + +static const struct gpio_chip ocelot_gpiolib_chip = { + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .set = ocelot_gpio_set, + .get = ocelot_gpio_get, + .get_direction = ocelot_gpio_get_direction, + .direction_input = ocelot_gpio_direction_input, + .direction_output = ocelot_gpio_direction_output, + .owner = THIS_MODULE, +}; + +static int ocelot_gpiochip_register(struct platform_device *pdev, + struct ocelot_pinctrl *info) +{ + struct gpio_chip *gc; + int ret; + + info->gpio_chip = ocelot_gpiolib_chip; + + gc = &info->gpio_chip; + gc->ngpio = OCELOT_PINS; + gc->parent = &pdev->dev; + gc->base = 0; + gc->of_node = info->dev->of_node; + gc->label = "ocelot-gpio"; + + ret = devm_gpiochip_add_data(&pdev->dev, gc, info); + if (ret) + return ret; + + /* TODO: this can be used as an irqchip but no board is using that */ + + return 0; +} + +static const struct regmap_config ocelot_pinctrl_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x64, +}; + +static const struct of_device_id ocelot_pinctrl_of_match[] = { + { .compatible = "mscc,ocelot-pinctrl" }, + {}, +}; + +int ocelot_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ocelot_pinctrl *info; + void __iomem *base; + int ret; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + base = devm_ioremap_resource(dev, + platform_get_resource(pdev, IORESOURCE_MEM, 0)); + if (IS_ERR(base)) { + dev_err(dev, "Failed to ioremap registers\n"); + return PTR_ERR(base); + } + + info->map = devm_regmap_init_mmio(dev, base, + &ocelot_pinctrl_regmap_config); + if (IS_ERR(info->map)) { + dev_err(dev, "Failed to create regmap\n"); + return PTR_ERR(info->map); + } + dev_set_drvdata(dev, info->map); + info->dev = dev; + + ret = ocelot_pinctrl_register(pdev, info); + if (ret) + return ret; + + ret = ocelot_gpiochip_register(pdev, info); + if (ret) + return ret; + + return 0; +} + +static struct platform_driver ocelot_pinctrl_driver = { + .driver = { + .name = "pinctrl-ocelot", + .of_match_table = of_match_ptr(ocelot_pinctrl_of_match), + .suppress_bind_attrs = true, + }, + .probe = ocelot_pinctrl_probe, +}; +builtin_platform_driver(ocelot_pinctrl_driver); -- 2.15.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v3] pinctrl: Add Microsemi Ocelot SoC driver 2018-01-06 0:09 ` [PATCH v3] " Alexandre Belloni @ 2018-01-09 13:56 ` Linus Walleij 2018-01-09 14:07 ` Alexandre Belloni 0 siblings, 1 reply; 14+ messages in thread From: Linus Walleij @ 2018-01-09 13:56 UTC (permalink / raw) To: Alexandre Belloni Cc: linux-gpio, Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org On Sat, Jan 6, 2018 at 1:09 AM, Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote: > The Microsemi Ocelot SoC has a few pins that can be used as GPIOs or take > multiple other functions. Add a driver for the pinmuxing and the GPIOs. > > There is currently no support for interrupts. > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > --- > - use pinctrl_gpio_direction_input/output from > ocelot_gpio_direction_input/output > - add a comment for ALT0/ALT1 > - fill .max_register of ocelot_pinctrl_regmap_config Patch applied. And it looks very good too. This was all I had to do, right? No dependent patches? Yours, Linus Walleij ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3] pinctrl: Add Microsemi Ocelot SoC driver 2018-01-09 13:56 ` Linus Walleij @ 2018-01-09 14:07 ` Alexandre Belloni 0 siblings, 0 replies; 14+ messages in thread From: Alexandre Belloni @ 2018-01-09 14:07 UTC (permalink / raw) To: Linus Walleij Cc: linux-gpio, Ralf Baechle, Linux MIPS, linux-kernel@vger.kernel.org On 09/01/2018 at 14:56:36 +0100, Linus Walleij wrote: > On Sat, Jan 6, 2018 at 1:09 AM, Alexandre Belloni > <alexandre.belloni@free-electrons.com> wrote: > > > The Microsemi Ocelot SoC has a few pins that can be used as GPIOs or take > > multiple other functions. Add a driver for the pinmuxing and the GPIOs. > > > > There is currently no support for interrupts. > > > > Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> > > --- > > - use pinctrl_gpio_direction_input/output from > > ocelot_gpio_direction_input/output > > - add a comment for ALT0/ALT1 > > - fill .max_register of ocelot_pinctrl_regmap_config > > Patch applied. And it looks very good too. > > This was all I had to do, right? No dependent patches? > Nothing more for you, thanks! I'll get back to this driver if there is interest in having IRQ support but I don't think this will happen soon. -- Alexandre Belloni, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs 2017-12-08 15:46 [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs Alexandre Belloni 2017-12-08 15:46 ` [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot Alexandre Belloni 2017-12-08 15:46 ` [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver Alexandre Belloni @ 2017-12-17 16:59 ` PrasannaKumar Muralidharan 2 siblings, 0 replies; 14+ messages in thread From: PrasannaKumar Muralidharan @ 2017-12-17 16:59 UTC (permalink / raw) To: Alexandre Belloni Cc: Ralf Baechle, linux-mips, open list, Rob Herring, devicetree, Thomas Gleixner, Jason Cooper, Linus Walleij, linux-gpio, Sebastian Reichel, linux-pm Hi Alexandre, With very small amount of code in arch/mips this series looks really nice. On 8 December 2017 at 21:16, Alexandre Belloni <alexandre.belloni@free-electrons.com> wrote: > Hi, > > This patch series adds initial support for the Microsemi MIPS SoCs. It > is currently focusing on the Microsemi Ocelot (VSC7513, VSC7514). > > It adds support for the IRQ controller, pinmux and gpio controller and > reset control. > > This produces a kernel that can boot to the console. > > This is a single series for reference but it can also be taken > separately by each maintainer as each drivers are independant. > > Changes in v2: > - removed the wildcard in MAINAINERS > - corrected the Cc list > - added proper documentation for both syscons > - removed the mscc,cpucontrol property > - updated the ranges property in the ocelot dtsi > > Cc: Rob Herring <robh+dt@kernel.org> > Cc: devicetree@vger.kernel.org > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Jason Cooper <jason@lakedaemon.net> > Cc: Linus Walleij <linus.walleij@linaro.org> > Cc: linux-gpio@vger.kernel.org > Cc: Sebastian Reichel <sre@kernel.org> > Cc: linux-pm@vger.kernel.org > > > Alexandre Belloni (13): > dt-bindings: Add vendor prefix for Microsemi Corporation > dt-bindings: interrupt-controller: Add binding for the Microsemi > Ocelot interrupt controller > irqchip: Add a driver for the Microsemi Ocelot controller > dt-bindings: pinctrl: Add bindings for Microsemi Ocelot > pinctrl: Add Microsemi Ocelot SoC driver > dt-bindings: mips: Add bindings for Microsemi SoCs > dt-bindings: power: reset: Document ocelot-reset binding > power: reset: Add a driver for the Microsemi Ocelot reset > MIPS: mscc: Add initial support for Microsemi MIPS SoCs > MIPS: mscc: add ocelot dtsi > MIPS: mscc: add ocelot PCB123 device tree > MIPS: defconfigs: add a defconfig for Microsemi SoCs > MAINTAINERS: Add entry for Microsemi MIPS SoCs > > .../interrupt-controller/mscc,ocelot-icpu-intr.txt | 22 + > Documentation/devicetree/bindings/mips/mscc.txt | 46 ++ > .../bindings/pinctrl/mscc,ocelot-pinctrl.txt | 39 ++ > .../bindings/power/reset/ocelot-reset.txt | 17 + > .../devicetree/bindings/vendor-prefixes.txt | 1 + > MAINTAINERS | 7 + > arch/mips/Kbuild.platforms | 1 + > arch/mips/Kconfig | 24 + > arch/mips/boot/dts/Makefile | 1 + > arch/mips/boot/dts/mscc/Makefile | 6 + > arch/mips/boot/dts/mscc/ocelot.dtsi | 115 +++++ > arch/mips/boot/dts/mscc/ocelot_pcb123.dts | 27 ++ > arch/mips/configs/mscc_defconfig | 84 ++++ > arch/mips/mscc/Makefile | 11 + > arch/mips/mscc/Platform | 12 + > arch/mips/mscc/setup.c | 106 +++++ > drivers/irqchip/Kconfig | 5 + > drivers/irqchip/Makefile | 1 + > drivers/irqchip/irq-mscc-ocelot.c | 109 +++++ > drivers/pinctrl/Kconfig | 10 + > drivers/pinctrl/Makefile | 1 + > drivers/pinctrl/pinctrl-ocelot.c | 505 +++++++++++++++++++++ > drivers/power/reset/Kconfig | 7 + > drivers/power/reset/Makefile | 1 + > drivers/power/reset/ocelot-reset.c | 86 ++++ > 25 files changed, 1244 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mscc,ocelot-icpu-intr.txt > create mode 100644 Documentation/devicetree/bindings/mips/mscc.txt > create mode 100644 Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.txt > create mode 100644 Documentation/devicetree/bindings/power/reset/ocelot-reset.txt > create mode 100644 arch/mips/boot/dts/mscc/Makefile > create mode 100644 arch/mips/boot/dts/mscc/ocelot.dtsi > create mode 100644 arch/mips/boot/dts/mscc/ocelot_pcb123.dts > create mode 100644 arch/mips/configs/mscc_defconfig > create mode 100644 arch/mips/mscc/Makefile > create mode 100644 arch/mips/mscc/Platform > create mode 100644 arch/mips/mscc/setup.c > create mode 100644 drivers/irqchip/irq-mscc-ocelot.c > create mode 100644 drivers/pinctrl/pinctrl-ocelot.c > create mode 100644 drivers/power/reset/ocelot-reset.c > > -- > 2.15.1 > > Except for irqchip driver and pinctrl driver other parts of the series is Reviewed-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com> Regards, PrasannaKumar ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2018-01-09 14:07 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-12-08 15:46 [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs Alexandre Belloni 2017-12-08 15:46 ` [PATCH v2 04/13] dt-bindings: pinctrl: Add bindings for Microsemi Ocelot Alexandre Belloni 2017-12-13 7:39 ` Linus Walleij 2017-12-08 15:46 ` [PATCH v2 05/13] pinctrl: Add Microsemi Ocelot SoC driver Alexandre Belloni 2017-12-13 8:15 ` Linus Walleij 2017-12-13 9:23 ` Philippe Ombredanne 2017-12-14 23:53 ` Linus Walleij 2017-12-15 7:59 ` Philippe Ombredanne 2017-12-18 16:09 ` Alexandre Belloni 2018-01-05 23:46 ` Alexandre Belloni 2018-01-06 0:09 ` [PATCH v3] " Alexandre Belloni 2018-01-09 13:56 ` Linus Walleij 2018-01-09 14:07 ` Alexandre Belloni 2017-12-17 16:59 ` [PATCH v2 00/13] MIPS: add support for the Microsemi MIPS SoCs PrasannaKumar Muralidharan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).