All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] pinctrl: add BCM63XX pincontrol support
@ 2016-08-19 10:53 Jonas Gorski
  2016-08-19 10:53 ` [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328 Jonas Gorski
                   ` (7 more replies)
  0 siblings, 8 replies; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

This patchset adds appropriate binding documentation and drivers for
pin controller cores found in the BCM63XX MIPS SoCs currently supported.

While the GPIO part is always the same, the pinmux part varies quite a
lot between different SoCs. Sometimes they have defined groups which
can be muxed into different functions, sometimes each function has a
different group. Sometimes you can mux individual pins. Often it is a
combination of single pins and groups.

Some core versions require the GPIO direction to be set according to the
function, most do not. Sometimes the mux register(s) contain bits for
unrelated other functions.

I intentionally left out any MIPS patches so keep the patchset smaller
and to make it clearer to which tree this belongs.

Some implementation notes:

BCM6348 has one mux function that enables two unrelated functions at the
same time; additional SPI CS signals as well as extra UART pins. This
means that in case both the uart as well as the spi driver needs it, it
would need to be requested globally, as the same mux can't be requested
by two different devices. Since this is a linux internal detail, I
chose to not try to split this function and try to work around it in
the driver (by refcounting etc).

BCM6358 has two "invert-mii-clock" bits in its GPIO Mode register for
the ethernet cores. This didn't seem to fit well into pinmux/conf; at
best as two pins which you could apply exactly one property,
"brcm,invert-clock". So I chose syscon so the ethernet driver can poke
at the bits itself.

BCM6368 has several additional bits in its GPIO BaseMode register for
enabling RGMII pins, UTOPIA, or changing the PCI clock to 66 MHz. These
seemed to fit even less.


Based on the current HEAD of linux-pinctrl/for-next.

Jonas Gorski (13):
  pinctrl: add bcm63xx base code
  Documentation: add BCM6328 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6328
  Documentation: add BCM6348 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6348
  Documentation: add BCM6358 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6358
  Documentation: add BCM6362 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6362
  Documentation: add BCM6368 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6368
  Documentation: add BCM63268 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM63268

 .../bindings/pinctrl/brcm,bcm63268-pinctrl.txt     |  88 +++
 .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      |  61 ++
 .../bindings/pinctrl/brcm,bcm6348-pinctrl.txt      |  32 +
 .../bindings/pinctrl/brcm,bcm6358-pinctrl.txt      |  44 ++
 .../bindings/pinctrl/brcm,bcm6362-pinctrl.txt      |  79 +++
 .../bindings/pinctrl/brcm,bcm6368-pinctrl.txt      |  67 ++
 MAINTAINERS                                        |   1 +
 drivers/pinctrl/Kconfig                            |   1 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/bcm63xx/Kconfig                    |  47 ++
 drivers/pinctrl/bcm63xx/Makefile                   |   7 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c         | 710 +++++++++++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c          | 456 +++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c          | 392 ++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c          | 393 ++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c          | 692 ++++++++++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c          | 573 +++++++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c          | 141 ++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h          |  14 +
 19 files changed, 3799 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt
 create mode 100644 drivers/pinctrl/bcm63xx/Kconfig
 create mode 100644 drivers/pinctrl/bcm63xx/Makefile
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h

-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH 01/13] pinctrl: add bcm63xx base code
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-19 10:53   ` Jonas Gorski
  2016-08-22 12:46     ` Linus Walleij
  2016-08-19 10:53   ` [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation Jonas Gorski
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Setup directory and add a helper for bcm63xx pinctrl support.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 MAINTAINERS                               |   1 +
 drivers/pinctrl/Kconfig                   |   1 +
 drivers/pinctrl/Makefile                  |   1 +
 drivers/pinctrl/bcm63xx/Kconfig           |   3 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | 141 ++++++++++++++++++++++++++++++
 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h |  14 +++
 7 files changed, 162 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/Kconfig
 create mode 100644 drivers/pinctrl/bcm63xx/Makefile
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 20bb1d0..33c3026 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2604,6 +2604,7 @@ F:	arch/mips/boot/dts/brcm/bcm*.dts*
 F:	drivers/irqchip/irq-bcm63*
 F:	drivers/irqchip/irq-bcm7*
 F:	drivers/irqchip/irq-brcmstb*
+F:	drivers/pinctrl/bcm63xx/*
 F:	include/linux/bcm963xx_nvram.h
 F:	include/linux/bcm963xx_tag.h
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index b3fe1d3..13a2b29 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -255,6 +255,7 @@ config PINCTRL_ZYNQ
 	  This selects the pinctrl driver for Xilinx Zynq.
 
 source "drivers/pinctrl/bcm/Kconfig"
+source "drivers/pinctrl/bcm63xx/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
 source "drivers/pinctrl/freescale/Kconfig"
 source "drivers/pinctrl/intel/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 8ebd7b8..366e574 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
 obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o
 
 obj-y				+= bcm/
+obj-y				+= bcm63xx/
 obj-$(CONFIG_PINCTRL_BERLIN)	+= berlin/
 obj-y				+= freescale/
 obj-$(CONFIG_X86)		+= intel/
diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
new file mode 100644
index 0000000..dd58f95
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -0,0 +1,3 @@
+config PINCTRL_BCM63XX
+	bool
+	select GPIO_GENERIC
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
new file mode 100644
index 0000000..d16e74b
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
new file mode 100644
index 0000000..e118171
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
@@ -0,0 +1,141 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/gpio/driver.h>
+
+#include "pinctrl-bcm63xx.h"
+#include "../core.h"
+
+#define BANK_SIZE	sizeof(u32)
+#define PINS_PER_BANK	(BANK_SIZE * BITS_PER_BYTE)
+
+#ifdef CONFIG_OF
+static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc,
+				 const struct of_phandle_args *gpiospec,
+				 u32 *flags)
+{
+	struct gpio_chip *base = gpiochip_get_data(gc);
+	int pin = gpiospec->args[0];
+
+	if (gc != &base[pin / PINS_PER_BANK])
+		return -EINVAL;
+
+	pin = pin % PINS_PER_BANK;
+
+	if (pin >= gc->ngpio)
+		return -EINVAL;
+
+	if (flags)
+		*flags = gpiospec->args[1];
+
+	return pin;
+}
+#endif
+
+static int bcm63xx_setup_gpio(struct device *dev, struct gpio_chip *gc,
+			      void __iomem *dirout, void __iomem *data,
+			      size_t sz, int ngpio)
+
+{
+	int banks, chips, i, ret = -EINVAL;
+
+	chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
+	banks = sz / BANK_SIZE;
+
+	for (i = 0; i < chips; i++) {
+		int offset, pins;
+		int reg_offset;
+		char *label;
+
+		label = devm_kasprintf(dev, GFP_KERNEL, "bcm63xx-gpio.%i", i);
+		if (!label)
+			return -ENOMEM;
+
+		offset = i * PINS_PER_BANK;
+		pins = min_t(int, ngpio - offset, PINS_PER_BANK);
+
+		/* the registers are treated like a huge big endian register */
+		reg_offset = (banks - i - 1) * BANK_SIZE;
+
+		ret = bgpio_init(&gc[i], dev, BANK_SIZE, data + reg_offset,
+				 NULL, NULL, dirout + reg_offset, NULL,
+				 BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+		if (ret)
+			return ret;
+
+		gc[i].request = gpiochip_generic_request;
+		gc[i].free = gpiochip_generic_free;
+
+#ifdef CONFIG_OF
+		gc[i].of_gpio_n_cells = 2;
+		gc[i].of_xlate = bcm63xx_gpio_of_xlate;
+#endif
+
+		gc[i].label = label;
+		gc[i].ngpio = pins;
+
+		devm_gpiochip_add_data(dev, &gc[i], gc);
+	}
+
+	return 0;
+}
+
+static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name,
+				    int ngpio)
+{
+	int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
+
+	for (i = 0; i < chips; i++) {
+		int offset, pins;
+
+		offset = i * PINS_PER_BANK;
+		pins = min_t(int, ngpio - offset, PINS_PER_BANK);
+
+		gpiochip_add_pin_range(&gc[i], name, 0, offset, pins);
+	}
+}
+
+struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev,
+					     struct pinctrl_desc *desc,
+					     void *priv, struct gpio_chip *gc,
+					     int ngpio)
+{
+	struct pinctrl_dev *pctldev;
+	struct resource *res;
+	void __iomem *dirout, *data;
+	size_t sz;
+	int ret;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout");
+	dirout = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dirout))
+		return ERR_CAST(dirout);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
+	data = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data))
+		return ERR_CAST(data);
+
+	sz = resource_size(res);
+
+	ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio);
+	if (ret)
+		return ERR_PTR(ret);
+
+	pctldev = devm_pinctrl_register(&pdev->dev, desc, priv);
+	if (IS_ERR(pctldev))
+		return pctldev;
+
+	bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio);
+
+	dev_info(&pdev->dev, "registered at mmio %p\n", dirout);
+
+	return pctldev;
+}
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h
new file mode 100644
index 0000000..9bfe1d0
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h
@@ -0,0 +1,14 @@
+#ifndef __PINCTRL_BCM63XX
+#define __PINCTRL_BCM63XX
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+
+struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev,
+					     struct pinctrl_desc *desc,
+					     void *priv, struct gpio_chip *gc,
+					     int ngpio);
+
+#endif
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53   ` [PATCH 01/13] pinctrl: add bcm63xx base code Jonas Gorski
@ 2016-08-19 10:53   ` Jonas Gorski
  2016-08-19 14:14     ` Rob Herring
  2016-08-19 10:53   ` [PATCH 05/13] pinctrl: add a pincontrol driver for BCM6348 Jonas Gorski
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in BCM6328 SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      | 61 ++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
new file mode 100644
index 0000000..401224e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
@@ -0,0 +1,61 @@
+* Broadcom BCM6328 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6328-pinctrl".
+- reg: Register specifies of dirout, dat, mode, mux registers.
+- reg-names: Must be "dirout", "dat", "mode", "mux".
+- gpio-controller: Identifies this node as a GPIO controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@10000080 {
+	compatible = "brcm,bcm6328-pinctrl";
+	reg = <0x10000080 0x8>,
+	      <0x10000088 0x8>,
+	      <0x10000098 0x4>,
+	      <0x1000009c 0xc>;
+	reg-names = "dirout", "dat", "mode", "mux";
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+Available pins/groups and functions:
+
+name		pins	functions
+-----------------------------------------------------------
+gpio0		0	led
+gpio1		1	led
+gpio2		2	led
+gpio3		3	led
+gpio4		4	led
+gpio5		5	led
+gpio6		6	led, serial_led_data
+gpio7		7	led, serial_led_clk
+gpio8		8	led
+gpio9		9	led
+gpio10		10	led
+gpio11		11	led
+gpio12		12	led
+gpio13		13	led
+gpio14		14	led
+gpio15		15	led
+gpio16		16	led, pcie_clkreq
+gpio17		17	led
+gpio18		18	led
+gpio19		19	led
+gpio20		20	led
+gpio21		21	led
+gpio22		22	led
+gpio23		23	led
+gpio24		24	-
+gpio25		25	ephy0_act_led
+gpio26		26	ephy1_act_led
+gpio27		27	ephy2_act_led
+gpio28		28	ephy3_act_led
+gpio29		29	-
+gpio30		30	-
+gpio31		31	-
+hsspi_cs1	-	hsspi_cs1
+usb_port1	-	usb_host_port, usb_device_port
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
  2016-08-22 13:15   ` Linus Walleij
  2016-08-19 10:53 ` [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation Jonas Gorski
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as
GPIOs, as LEDs for the integrated LED controller, or various other
functions. Its pincontrol mux registers also control other aspects, like
switching the second USB port between host and device mode.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 drivers/pinctrl/bcm63xx/Kconfig           |   7 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | 456 ++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c

diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
index dd58f95..5084f66 100644
--- a/drivers/pinctrl/bcm63xx/Kconfig
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -1,3 +1,10 @@
 config PINCTRL_BCM63XX
 	bool
 	select GPIO_GENERIC
+
+config PINCTRL_BCM6328
+	bool "BCM6328 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index d16e74b..8b2472e 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
+obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c
new file mode 100644
index 0000000..d8ff842
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c
@@ -0,0 +1,456 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6328_MUX_LO_REG	0x4
+#define BCM6328_MUX_HI_REG	0x0
+#define BCM6328_MUX_OTHER_REG	0xc
+
+#define BCM6328_NGPIO		32
+
+struct bcm6328_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6328_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	unsigned mode_val:1;
+	unsigned mux_val:2;
+};
+
+struct bcm6328_pinctrl {
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	void __iomem *mode;
+	void __iomem *mux[3];
+
+	/* register access lock */
+	spinlock_t lock;
+
+	struct gpio_chip gpio;
+};
+
+static const struct pinctrl_pin_desc bcm6328_pins[] = {
+	PINCTRL_PIN(0, "gpio0"),
+	PINCTRL_PIN(1, "gpio1"),
+	PINCTRL_PIN(2, "gpio2"),
+	PINCTRL_PIN(3, "gpio3"),
+	PINCTRL_PIN(4, "gpio4"),
+	PINCTRL_PIN(5, "gpio5"),
+	PINCTRL_PIN(6, "gpio6"),
+	PINCTRL_PIN(7, "gpio7"),
+	PINCTRL_PIN(8, "gpio8"),
+	PINCTRL_PIN(9, "gpio9"),
+	PINCTRL_PIN(10, "gpio10"),
+	PINCTRL_PIN(11, "gpio11"),
+	PINCTRL_PIN(12, "gpio12"),
+	PINCTRL_PIN(13, "gpio13"),
+	PINCTRL_PIN(14, "gpio14"),
+	PINCTRL_PIN(15, "gpio15"),
+	PINCTRL_PIN(16, "gpio16"),
+	PINCTRL_PIN(17, "gpio17"),
+	PINCTRL_PIN(18, "gpio18"),
+	PINCTRL_PIN(19, "gpio19"),
+	PINCTRL_PIN(20, "gpio20"),
+	PINCTRL_PIN(21, "gpio21"),
+	PINCTRL_PIN(22, "gpio22"),
+	PINCTRL_PIN(23, "gpio23"),
+	PINCTRL_PIN(24, "gpio24"),
+	PINCTRL_PIN(25, "gpio25"),
+	PINCTRL_PIN(26, "gpio26"),
+	PINCTRL_PIN(27, "gpio27"),
+	PINCTRL_PIN(28, "gpio28"),
+	PINCTRL_PIN(29, "gpio29"),
+	PINCTRL_PIN(30, "gpio30"),
+	PINCTRL_PIN(31, "gpio31"),
+
+	/*
+	 * No idea where they really are; so let's put them according
+	 * to their mux offsets.
+	 */
+	PINCTRL_PIN(36, "hsspi_cs1"),
+	PINCTRL_PIN(38, "usb_p2"),
+};
+
+static unsigned gpio0_pins[] = { 0 };
+static unsigned gpio1_pins[] = { 1 };
+static unsigned gpio2_pins[] = { 2 };
+static unsigned gpio3_pins[] = { 3 };
+static unsigned gpio4_pins[] = { 4 };
+static unsigned gpio5_pins[] = { 5 };
+static unsigned gpio6_pins[] = { 6 };
+static unsigned gpio7_pins[] = { 7 };
+static unsigned gpio8_pins[] = { 8 };
+static unsigned gpio9_pins[] = { 9 };
+static unsigned gpio10_pins[] = { 10 };
+static unsigned gpio11_pins[] = { 11 };
+static unsigned gpio12_pins[] = { 12 };
+static unsigned gpio13_pins[] = { 13 };
+static unsigned gpio14_pins[] = { 14 };
+static unsigned gpio15_pins[] = { 15 };
+static unsigned gpio16_pins[] = { 16 };
+static unsigned gpio17_pins[] = { 17 };
+static unsigned gpio18_pins[] = { 18 };
+static unsigned gpio19_pins[] = { 19 };
+static unsigned gpio20_pins[] = { 20 };
+static unsigned gpio21_pins[] = { 21 };
+static unsigned gpio22_pins[] = { 22 };
+static unsigned gpio23_pins[] = { 23 };
+static unsigned gpio24_pins[] = { 24 };
+static unsigned gpio25_pins[] = { 25 };
+static unsigned gpio26_pins[] = { 26 };
+static unsigned gpio27_pins[] = { 27 };
+static unsigned gpio28_pins[] = { 28 };
+static unsigned gpio29_pins[] = { 29 };
+static unsigned gpio30_pins[] = { 30 };
+static unsigned gpio31_pins[] = { 31 };
+
+static unsigned hsspi_cs1_pins[] = { 36 };
+static unsigned usb_port1_pins[] = { 38 };
+
+#define BCM6328_GROUP(n)					\
+	{							\
+		.name = #n,					\
+		.pins = n##_pins,				\
+		.num_pins = ARRAY_SIZE(n##_pins),		\
+	}
+
+static struct bcm6328_pingroup bcm6328_groups[] = {
+	BCM6328_GROUP(gpio0),
+	BCM6328_GROUP(gpio1),
+	BCM6328_GROUP(gpio2),
+	BCM6328_GROUP(gpio3),
+	BCM6328_GROUP(gpio4),
+	BCM6328_GROUP(gpio5),
+	BCM6328_GROUP(gpio6),
+	BCM6328_GROUP(gpio7),
+	BCM6328_GROUP(gpio8),
+	BCM6328_GROUP(gpio9),
+	BCM6328_GROUP(gpio10),
+	BCM6328_GROUP(gpio11),
+	BCM6328_GROUP(gpio12),
+	BCM6328_GROUP(gpio13),
+	BCM6328_GROUP(gpio14),
+	BCM6328_GROUP(gpio15),
+	BCM6328_GROUP(gpio16),
+	BCM6328_GROUP(gpio17),
+	BCM6328_GROUP(gpio18),
+	BCM6328_GROUP(gpio19),
+	BCM6328_GROUP(gpio20),
+	BCM6328_GROUP(gpio21),
+	BCM6328_GROUP(gpio22),
+	BCM6328_GROUP(gpio23),
+	BCM6328_GROUP(gpio24),
+	BCM6328_GROUP(gpio25),
+	BCM6328_GROUP(gpio26),
+	BCM6328_GROUP(gpio27),
+	BCM6328_GROUP(gpio28),
+	BCM6328_GROUP(gpio29),
+	BCM6328_GROUP(gpio30),
+	BCM6328_GROUP(gpio31),
+
+	BCM6328_GROUP(hsspi_cs1),
+	BCM6328_GROUP(usb_port1),
+};
+
+/* GPIO_MODE */
+static const char * const led_groups[] = {
+	"gpio0",
+	"gpio1",
+	"gpio2",
+	"gpio3",
+	"gpio4",
+	"gpio5",
+	"gpio6",
+	"gpio7",
+	"gpio8",
+	"gpio9",
+	"gpio10",
+	"gpio11",
+	"gpio12",
+	"gpio13",
+	"gpio14",
+	"gpio15",
+	"gpio16",
+	"gpio17",
+	"gpio18",
+	"gpio19",
+	"gpio20",
+	"gpio21",
+	"gpio22",
+	"gpio23",
+};
+
+/* PINMUX_SEL */
+static const char * const serial_led_data_groups[] = {
+	"gpio6",
+};
+
+static const char * const serial_led_clk_groups[] = {
+	"gpio7",
+};
+
+static const char * const inet_act_led_groups[] = {
+	"gpio11",
+};
+
+static const char * const pcie_clkreq_groups[] = {
+	"gpio16",
+};
+
+static const char * const ephy0_act_led_groups[] = {
+	"gpio25",
+};
+
+static const char * const ephy1_act_led_groups[] = {
+	"gpio26",
+};
+
+static const char * const ephy2_act_led_groups[] = {
+	"gpio27",
+};
+
+static const char * const ephy3_act_led_groups[] = {
+	"gpio28",
+};
+
+static const char * const hsspi_cs1_groups[] = {
+	"hsspi_cs1"
+};
+
+static const char * const usb_host_port_groups[] = {
+	"usb_port1",
+};
+
+static const char * const usb_device_port_groups[] = {
+	"usb_port1",
+};
+
+#define BCM6328_MODE_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mode_val = 1,				\
+	}
+
+#define BCM6328_MUX_FUN(n, mux)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mux_val = mux,				\
+	}
+
+static const struct bcm6328_function bcm6328_funcs[] = {
+	BCM6328_MODE_FUN(led),
+	BCM6328_MUX_FUN(serial_led_data, 2),
+	BCM6328_MUX_FUN(serial_led_clk, 2),
+	BCM6328_MUX_FUN(inet_act_led, 1),
+	BCM6328_MUX_FUN(pcie_clkreq, 2),
+	BCM6328_MUX_FUN(ephy0_act_led, 1),
+	BCM6328_MUX_FUN(ephy1_act_led, 1),
+	BCM6328_MUX_FUN(ephy2_act_led, 1),
+	BCM6328_MUX_FUN(ephy3_act_led, 1),
+	BCM6328_MUX_FUN(hsspi_cs1, 2),
+	BCM6328_MUX_FUN(usb_host_port, 1),
+	BCM6328_MUX_FUN(usb_device_port, 2),
+};
+
+static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6328_groups);
+}
+
+static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6328_groups[group].name;
+}
+
+static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6328_groups[group].pins;
+	*num_pins = bcm6328_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6328_funcs);
+}
+
+static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6328_funcs[selector].name;
+}
+
+static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6328_funcs[selector].groups;
+	*num_groups = bcm6328_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pctl, unsigned pin,
+			    u32 mode, u32 mux)
+{
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	if (pin < 32) {
+		reg = __raw_readl(pctl->mode);
+		reg &= ~BIT(pin);
+		if (mode)
+			reg |= BIT(pin);
+		__raw_writel(reg, pctl->mode);
+	}
+
+	reg = __raw_readl(pctl->mux[pin / 16]);
+	reg &= ~(3UL << (pin % 16));
+	reg |= mux << (pin % 16);
+	__raw_writel(reg, pctl->mux[pin / 16]);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6328_pingroup *grp = &bcm6328_groups[group];
+	const struct bcm6328_function *f = &bcm6328_funcs[selector];
+
+	bcm6328_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val);
+
+	return 0;
+}
+
+static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6328_rmw_mux(pctl, offset, 0, 0);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6328_pctl_ops = {
+	.get_groups_count	= bcm6328_pinctrl_get_group_count,
+	.get_group_name		= bcm6328_pinctrl_get_group_name,
+	.get_group_pins		= bcm6328_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm6328_pmx_ops = {
+	.get_functions_count	= bcm6328_pinctrl_get_func_count,
+	.get_function_name	= bcm6328_pinctrl_get_func_name,
+	.get_function_groups	= bcm6328_pinctrl_get_groups,
+	.set_mux		= bcm6328_pinctrl_set_mux,
+	.gpio_request_enable	= bcm6328_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm6328_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm6328_pinctrl *pctl;
+	struct resource *res;
+	void __iomem *mode, *mux;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
+	mode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
+	mux = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mux))
+		return PTR_ERR(mux);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	spin_lock_init(&pctl->lock);
+
+	pctl->mode = mode;
+	pctl->mux[0] = mux + BCM6328_MUX_LO_REG;
+	pctl->mux[1] = mux + BCM6328_MUX_HI_REG;
+	pctl->mux[2] = mux + BCM6328_MUX_OTHER_REG;
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm6328_pctl_ops;
+	pctl->desc.pmxops = &bcm6328_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm6328_pins);
+	pctl->desc.pins = bcm6328_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 &pctl->gpio, BCM6328_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6328_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6328-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm6328_pinctrl_driver = {
+	.probe = bcm6328_pinctrl_probe,
+	.driver = {
+		.name = "bcm6328-pinctrl",
+		.of_match_table = bcm6328_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6328_pinctrl_driver);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
  2016-08-19 10:53 ` [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328 Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
  2016-08-22 13:17   ` Linus Walleij
  2016-08-19 10:53 ` [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358 Jonas Gorski
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in BCM6348 SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 .../bindings/pinctrl/brcm,bcm6348-pinctrl.txt      | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt
new file mode 100644
index 0000000..3df7f30
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt
@@ -0,0 +1,32 @@
+* Broadcom BCM6348 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6348-pinctrl".
+- reg: register Specifiers of dirout, dat, mode registers.
+- reg-names: Must be "dirout", "dat", "mode".
+- gpio-controller: Identifies this node as a GPIO controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@fffe0080 {
+	compatible = "brcm,bcm6348-pinctrl";
+	reg = <0xfffe0080 0x8>,
+	      <0xfffe0088 0x8>,
+	      <0xfffe0098 0x4>;
+	reg-names = "dirout", "dat", "mode";
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+Available pins/groups and functions:
+
+name		pins	functions
+-----------------------------------------------------------
+group0		32-36	ext_mii, utopia, diag
+group1		22-31	ext_ephy, mii_snoop, mii_pccard,
+			spi_master_uart, utopia, diag
+group2		16-21	pci, diag
+group3		8-15	ext_mii, utopia
+group4		0-7	ext_ephy, mii_snoop, legacy_led, diag
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 05/13] pinctrl: add a pincontrol driver for BCM6348
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53   ` [PATCH 01/13] pinctrl: add bcm63xx base code Jonas Gorski
  2016-08-19 10:53   ` [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation Jonas Gorski
@ 2016-08-19 10:53   ` Jonas Gorski
       [not found]     ` <1471604025-21575-6-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53   ` [PATCH 06/13] Documentation: add BCM6358 pincontroller binding documentation Jonas Gorski
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincotrol driver for BCM6348. BCM6348 allow muxing five groups of
up to ten gpios into fourteen potential functions. It does not allow
muxing individual pins. Some functions require more than one group to be
muxed to the same function.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pinctrl/bcm63xx/Kconfig           |   7 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c | 392 ++++++++++++++++++++++++++++++
 3 files changed, 400 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c

diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
index 5084f66..5e19cfc 100644
--- a/drivers/pinctrl/bcm63xx/Kconfig
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -8,3 +8,10 @@ config PINCTRL_BCM6328
 	select PINCONF
 	select PINCTRL_BCM63XX
 	select GENERIC_PINCONF
+
+config PINCTRL_BCM6348
+	bool "BCM6348 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index 8b2472e..4dcfb10 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
+obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c
new file mode 100644
index 0000000..3040550
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c
@@ -0,0 +1,392 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6348_NGPIO		37
+
+#define MAX_GROUP		4
+#define PINS_PER_GROUP		8
+#define PIN_TO_GROUP(pin)	(MAX_GROUP - ((pin) / PINS_PER_GROUP))
+#define GROUP_SHIFT(pin)	(PIN_TO_GROUP(pin) * 4)
+#define GROUP_MASK(pin)		(0xf << GROUP_SHIFT(pin))
+
+struct bcm6348_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6348_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+	unsigned int value;
+};
+
+struct bcm6348_pinctrl {
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	void __iomem *mode;
+
+	/* register access lock */
+	spinlock_t lock;
+
+	struct gpio_chip gpio[2];
+};
+
+#define BCM6348_PIN(a, b, group)		\
+	{					\
+		.number = a,			\
+		.name = b,			\
+		.drv_data = (void *)(group),	\
+	}
+
+static const struct pinctrl_pin_desc bcm6348_pins[] = {
+	BCM6348_PIN(0, "gpio0", 4),
+	BCM6348_PIN(1, "gpio1", 4),
+	BCM6348_PIN(2, "gpio2", 4),
+	BCM6348_PIN(3, "gpio3", 4),
+	BCM6348_PIN(4, "gpio4", 4),
+	BCM6348_PIN(5, "gpio5", 4),
+	BCM6348_PIN(6, "gpio6", 4),
+	BCM6348_PIN(7, "gpio7", 4),
+	BCM6348_PIN(8, "gpio8", 3),
+	BCM6348_PIN(9, "gpio9", 3),
+	BCM6348_PIN(10, "gpio10", 3),
+	BCM6348_PIN(11, "gpio11", 3),
+	BCM6348_PIN(12, "gpio12", 3),
+	BCM6348_PIN(13, "gpio13", 3),
+	BCM6348_PIN(14, "gpio14", 3),
+	BCM6348_PIN(15, "gpio15", 3),
+	BCM6348_PIN(16, "gpio16", 2),
+	BCM6348_PIN(17, "gpio17", 2),
+	BCM6348_PIN(18, "gpio18", 2),
+	BCM6348_PIN(19, "gpio19", 2),
+	BCM6348_PIN(20, "gpio20", 2),
+	BCM6348_PIN(21, "gpio21", 2),
+	BCM6348_PIN(22, "gpio22", 1),
+	BCM6348_PIN(23, "gpio23", 1),
+	BCM6348_PIN(24, "gpio24", 1),
+	BCM6348_PIN(25, "gpio25", 1),
+	BCM6348_PIN(26, "gpio26", 1),
+	BCM6348_PIN(27, "gpio27", 1),
+	BCM6348_PIN(28, "gpio28", 1),
+	BCM6348_PIN(29, "gpio29", 1),
+	BCM6348_PIN(30, "gpio30", 1),
+	BCM6348_PIN(31, "gpio31", 1),
+	BCM6348_PIN(32, "gpio32", 0),
+	BCM6348_PIN(33, "gpio33", 0),
+	BCM6348_PIN(34, "gpio34", 0),
+	BCM6348_PIN(35, "gpio35", 0),
+	BCM6348_PIN(36, "gpio36", 0),
+};
+
+enum bcm6348_muxes {
+	BCM6348_MUX_GPIO = 0,
+	BCM6348_MUX_EXT_EPHY,
+	BCM6348_MUX_MII_SNOOP,
+	BCM6348_MUX_LEGACY_LED,
+	BCM6348_MUX_MII_PCCARD,
+	BCM6348_MUX_PCI,
+	BCM6348_MUX_SPI_MASTER_UART,
+	BCM6348_MUX_EXT_MII,
+	BCM6348_MUX_UTOPIA,
+	BCM6348_MUX_DIAG,
+};
+
+static unsigned group0_pins[] = {
+	32, 33, 34, 35, 36,
+};
+
+static unsigned group1_pins[] = {
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+static unsigned group2_pins[] = {
+	16, 17, 18, 19, 20, 21,
+};
+
+static unsigned group3_pins[] = {
+	8, 9, 10, 11, 12, 13, 14, 15,
+};
+
+static unsigned group4_pins[] = {
+	0, 1, 2, 3, 4, 5, 6, 7,
+};
+
+#define BCM6348_GROUP(n)				\
+	{						\
+		.name = #n,				\
+		.pins = n##_pins,			\
+		.num_pins = ARRAY_SIZE(n##_pins),	\
+	} \
+
+static struct bcm6348_pingroup bcm6348_groups[] = {
+	BCM6348_GROUP(group0),
+	BCM6348_GROUP(group1),
+	BCM6348_GROUP(group2),
+	BCM6348_GROUP(group3),
+	BCM6348_GROUP(group4),
+};
+
+static const char * const ext_mii_groups[] = {
+	"group0",
+	"group3",
+};
+
+static const char * const ext_ephy_groups[] = {
+	"group1",
+	"group4"
+};
+
+static const char * const mii_snoop_groups[] = {
+	"group1",
+	"group4",
+};
+
+static const char * const legacy_led_groups[] = {
+	"group4",
+};
+
+static const char * const mii_pccard_groups[] = {
+	"group1",
+};
+
+static const char * const pci_groups[] = {
+	"group2",
+};
+
+static const char * const spi_master_uart_groups[] = {
+	"group1",
+};
+
+static const char * const utopia_groups[] = {
+	"group0",
+	"group1",
+	"group3",
+};
+
+static const char * const diag_groups[] = {
+	"group0",
+	"group1",
+	"group2",
+	"group4",
+};
+
+#define BCM6348_FUN(n, f)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.value = BCM6348_MUX_##f,		\
+	}
+
+static const struct bcm6348_function bcm6348_funcs[] = {
+	BCM6348_FUN(ext_mii, EXT_MII),
+	BCM6348_FUN(ext_ephy, EXT_EPHY),
+	BCM6348_FUN(mii_snoop, MII_SNOOP),
+	BCM6348_FUN(legacy_led, LEGACY_LED),
+	BCM6348_FUN(mii_pccard, MII_PCCARD),
+	BCM6348_FUN(pci, PCI),
+	BCM6348_FUN(spi_master_uart, SPI_MASTER_UART),
+	BCM6348_FUN(utopia, UTOPIA),
+	BCM6348_FUN(diag, DIAG),
+};
+
+static int bcm6348_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6348_groups);
+}
+
+static const char *bcm6348_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6348_groups[group].name;
+}
+
+static int bcm6348_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6348_groups[group].pins;
+	*num_pins = bcm6348_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6348_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6348_funcs);
+}
+
+static const char *bcm6348_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6348_funcs[selector].name;
+}
+
+static int bcm6348_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6348_funcs[selector].groups;
+	*num_groups = bcm6348_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static void bcm6348_rmw_mux(struct bcm6348_pinctrl *pctl, u32 mask, u32 val)
+{
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	reg = __raw_readl(pctl->mode);
+	reg &= ~mask;
+	reg |= val & mask;
+	__raw_writel(reg, pctl->mode);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static int bcm6348_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm6348_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6348_pingroup *grp = &bcm6348_groups[group];
+	const struct bcm6348_function *f = &bcm6348_funcs[selector];
+	u32 group_num, mask, val;
+
+	/*
+	 * pins n..(n+7) share the same group, so we only need to look at
+	 * the first pin.
+	 */
+	group_num = (unsigned long)bcm6348_pins[grp->pins[0]].drv_data;
+	mask = GROUP_MASK(group_num);
+	val = f->value << GROUP_SHIFT(group_num);
+
+	bcm6348_rmw_mux(pctl, mask, val);
+
+	return 0;
+}
+
+static int bcm6348_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm6348_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct pin_desc *desc;
+	u32 mask;
+
+	/* don't reconfigure if already muxed */
+	desc = pin_desc_get(pctldev, offset);
+	if (desc->mux_usecount)
+		return 0;
+
+	mask = GROUP_MASK(offset);
+
+	/* disable all functions using this pin */
+	bcm6348_rmw_mux(pctl, mask, 0);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6348_pctl_ops = {
+	.get_groups_count	= bcm6348_pinctrl_get_group_count,
+	.get_group_name		= bcm6348_pinctrl_get_group_name,
+	.get_group_pins		= bcm6348_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm6348_pmx_ops = {
+	.get_functions_count	= bcm6348_pinctrl_get_func_count,
+	.get_function_name	= bcm6348_pinctrl_get_func_name,
+	.get_function_groups	= bcm6348_pinctrl_get_groups,
+	.set_mux		= bcm6348_pinctrl_set_mux,
+	.gpio_request_enable	= bcm6348_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm6348_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm6348_pinctrl *pctl;
+	struct resource *res;
+	void __iomem *mode;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
+	mode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	spin_lock_init(&pctl->lock);
+
+	pctl->mode = mode;
+
+	/* disable all muxes by default */
+	__raw_writel(0, pctl->mode);
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm6348_pctl_ops;
+	pctl->desc.pmxops = &bcm6348_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm6348_pins);
+	pctl->desc.pins = bcm6348_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 pctl->gpio, BCM6348_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6348_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6348-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm6348_pinctrl_driver = {
+	.probe = bcm6348_pinctrl_probe,
+	.driver = {
+		.name = "bcm6348-pinctrl",
+		.of_match_table = bcm6348_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6348_pinctrl_driver);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 06/13] Documentation: add BCM6358 pincontroller binding documentation
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-08-19 10:53   ` [PATCH 05/13] pinctrl: add a pincontrol driver for BCM6348 Jonas Gorski
@ 2016-08-19 10:53   ` Jonas Gorski
       [not found]     ` <1471604025-21575-7-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53   ` [PATCH 11/13] pinctrl: add a pincontrol driver for BCM6368 Jonas Gorski
  2016-08-19 10:53   ` [PATCH 13/13] pinctrl: add a pincontrol driver for BCM63268 Jonas Gorski
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in BCM6358 SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../bindings/pinctrl/brcm,bcm6358-pinctrl.txt      | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt
new file mode 100644
index 0000000..d1e1874
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt
@@ -0,0 +1,44 @@
+* Broadcom BCM6358 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6358-pinctrl".
+- reg: Register specifiers of dirout, dat registers.
+- reg-names: Must be "dirout", "dat".
+- brcm,gpiomode: Phandle to the shared gpiomode register.
+- gpio-controller: Identifies this node as a gpio-controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@fffe0080 {
+	compatible = "brcm,bcm6358-pinctrl";
+	reg = <0xfffe0080 0x8>,
+	      <0xfffe0088 0x8>,
+	      <0xfffe0098 0x4>;
+	reg-names = "dirout", "dat";
+	brcm,gpiomode = <&gpiomode>;
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+gpiomode: syscon@fffe0098 {
+	compatible = "brcm,bcm6358-gpiomode", "syscon";
+	reg = <0xfffe0098 0x4>;
+	native-endian;
+};
+
+Available pins/groups and functions:
+
+name		pins		functions
+-----------------------------------------------------------
+ebi_cs_grp	30-31		ebi_cs
+uart1_grp	28-31		uart1
+spi_cs_grp	32-33		spi_cs
+async_modem_grp	12-15		async_modem
+legacy_led_grp	9-15		legacy_led
+serial_led_grp	6-7		serial_led
+led_grp		0-3		led
+utopia_grp	12-15, 22-31	utopia
+pwm_syn_clk_grp	8		pwm_syn_clk
+sys_irq_grp	5		sys_irq
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
  2016-08-19 10:53 ` [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328 Jonas Gorski
  2016-08-19 10:53 ` [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
  2016-08-22 13:21   ` Linus Walleij
  2016-08-19 10:53 ` [PATCH 08/13] Documentation: add BCM6362 pincontroller binding documentation Jonas Gorski
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different
functions onto the GPIO pins. It does not support configuring individual
pins but only whole groups. These groups may overlap, and still require
the directions to be set correctly in the GPIO register. In addition the
functions register controls other, not directly mux related functions.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 drivers/pinctrl/bcm63xx/Kconfig           |   8 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | 393 ++++++++++++++++++++++++++++++
 3 files changed, 402 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c

diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
index 5e19cfc..ef7b182 100644
--- a/drivers/pinctrl/bcm63xx/Kconfig
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -15,3 +15,11 @@ config PINCTRL_BCM6348
 	select PINCONF
 	select PINCTRL_BCM63XX
 	select GENERIC_PINCONF
+
+config PINCTRL_BCM6358
+	bool "BCM6358 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
+	select MFD_SYSCON
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index 4dcfb10..181504c 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
+obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
new file mode 100644
index 0000000..f8a9c5e
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
@@ -0,0 +1,393 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+/* GPIO_MODE register */
+#define BCM6358_MODE_MUX_NONE		0
+
+/* overlays on gpio pins */
+#define BCM6358_MODE_MUX_EBI_CS		BIT(5)
+#define BCM6358_MODE_MUX_UART1		BIT(6)
+#define BCM6358_MODE_MUX_SPI_CS		BIT(7)
+#define BCM6358_MODE_MUX_ASYNC_MODEM	BIT(8)
+#define BCM6358_MODE_MUX_LEGACY_LED	BIT(9)
+#define BCM6358_MODE_MUX_SERIAL_LED	BIT(10)
+#define BCM6358_MODE_MUX_LED		BIT(11)
+#define BCM6358_MODE_MUX_UTOPIA		BIT(12)
+#define BCM6358_MODE_MUX_CLKRST		BIT(13)
+#define BCM6358_MODE_MUX_PWM_SYN_CLK	BIT(14)
+#define BCM6358_MODE_MUX_SYS_IRQ	BIT(15)
+
+#define BCM6358_NGPIO			40
+
+struct bcm6358_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+
+	const u16 mode_val;
+
+	/* non-GPIO function muxes require the gpio direction to be set */
+	const u16 direction;
+};
+
+struct bcm6358_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+};
+
+struct bcm6358_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	struct regmap_field *overlays;
+
+	struct gpio_chip gpio[2];
+};
+
+#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3)		\
+	{							\
+		.number = a,					\
+		.name = b,					\
+		.drv_data = (void *)(BCM6358_MODE_MUX_##bit1 |	\
+				     BCM6358_MODE_MUX_##bit2 |	\
+				     BCM6358_MODE_MUX_##bit3),	\
+	}
+
+static const struct pinctrl_pin_desc bcm6358_pins[] = {
+	BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE),
+	BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE),
+	BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE),
+	BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE),
+	PINCTRL_PIN(4, "gpio4"),
+	BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE),
+	BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE),
+	BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE),
+	BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE),
+	BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE),
+	BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE),
+	BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE),
+	BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA),
+	BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA),
+	BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA),
+	BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA),
+	PINCTRL_PIN(16, "gpio16"),
+	PINCTRL_PIN(17, "gpio17"),
+	PINCTRL_PIN(18, "gpio18"),
+	PINCTRL_PIN(19, "gpio19"),
+	PINCTRL_PIN(20, "gpio20"),
+	PINCTRL_PIN(21, "gpio21"),
+	BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE),
+	BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE),
+	BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE),
+	BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS),
+	BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS),
+	BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE),
+	BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE),
+	PINCTRL_PIN(34, "gpio34"),
+	PINCTRL_PIN(35, "gpio35"),
+	PINCTRL_PIN(36, "gpio36"),
+	PINCTRL_PIN(37, "gpio37"),
+	PINCTRL_PIN(38, "gpio38"),
+	PINCTRL_PIN(39, "gpio39"),
+};
+
+static unsigned ebi_cs_grp_pins[] = { 30, 31 };
+
+static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 };
+
+static unsigned spi_cs_grp_pins[] = { 32, 33 };
+
+static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 };
+
+static unsigned serial_led_grp_pins[] = { 6, 7 };
+
+static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 };
+
+static unsigned led_grp_pins[] = { 0, 1, 2, 3 };
+
+static unsigned utopia_grp_pins[] = {
+	12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+static unsigned pwm_syn_clk_grp_pins[] = { 8 };
+
+static unsigned sys_irq_grp_pins[] = { 5 };
+
+#define BCM6358_GPIO_MUX_GROUP(n, bit, dir)			\
+	{							\
+		.name = #n,					\
+		.pins = n##_pins,				\
+		.num_pins = ARRAY_SIZE(n##_pins),		\
+		.mode_val = BCM6358_MODE_MUX_##bit,		\
+		.direction = dir,				\
+	}
+
+static const struct bcm6358_pingroup bcm6358_groups[] = {
+	BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3),
+	BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2),
+	BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6),
+	BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6),
+	BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f),
+	BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3),
+	BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf),
+	BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f),
+	BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1),
+	BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1),
+};
+
+static const char * const ebi_cs_groups[] = {
+	"ebi_cs_grp"
+};
+
+static const char * const uart1_groups[] = {
+	"uart1_grp"
+};
+
+static const char * const spi_cs_2_3_groups[] = {
+	"spi_cs_2_3_grp"
+};
+
+static const char * const async_modem_groups[] = {
+	"async_modem_grp"
+};
+
+static const char * const legacy_led_groups[] = {
+	"legacy_led_grp",
+};
+
+static const char * const serial_led_groups[] = {
+	"serial_led_grp",
+};
+
+static const char * const led_groups[] = {
+	"led_grp",
+};
+
+static const char * const clkrst_groups[] = {
+	"clkrst_grp",
+};
+
+static const char * const pwm_syn_clk_groups[] = {
+	"pwm_syn_clk_grp",
+};
+
+static const char * const sys_irq_groups[] = {
+	"sys_irq_grp",
+};
+
+#define BCM6358_FUN(n)					\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+	}
+
+static const struct bcm6358_function bcm6358_funcs[] = {
+	BCM6358_FUN(ebi_cs),
+	BCM6358_FUN(uart1),
+	BCM6358_FUN(spi_cs_2_3),
+	BCM6358_FUN(async_modem),
+	BCM6358_FUN(legacy_led),
+	BCM6358_FUN(serial_led),
+	BCM6358_FUN(led),
+	BCM6358_FUN(clkrst),
+	BCM6358_FUN(pwm_syn_clk),
+	BCM6358_FUN(sys_irq),
+};
+
+static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6358_groups);
+}
+
+static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6358_groups[group].name;
+}
+
+static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6358_groups[group].pins;
+	*num_pins = bcm6358_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6358_funcs);
+}
+
+static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6358_funcs[selector].name;
+}
+
+static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6358_funcs[selector].groups;
+	*num_groups = bcm6358_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6358_pingroup *grp = &bcm6358_groups[group];
+	u32 val = grp->mode_val;
+	u32 mask = val;
+	unsigned pin;
+
+	for (pin = 0; pin < grp->num_pins; pin++)
+		mask |= (unsigned long)bcm6358_pins[pin].drv_data;
+
+	regmap_field_update_bits(pctl->overlays, mask, val);
+
+	for (pin = 0; pin < grp->num_pins; pin++) {
+		int hw_gpio = bcm6358_pins[pin].number;
+		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32];
+
+		if (grp->direction & BIT(pin))
+			gc->direction_output(gc, hw_gpio % 32, 0);
+		else
+			gc->direction_input(gc, hw_gpio % 32);
+	}
+
+	return 0;
+}
+
+static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	u32 mask;
+
+	mask = (unsigned long)bcm6358_pins[offset].drv_data;
+	if (!mask)
+		return 0;
+
+	/* disable all functions using this pin */
+	return regmap_field_update_bits(pctl->overlays, mask, 0);
+}
+
+static struct pinctrl_ops bcm6358_pctl_ops = {
+	.get_groups_count	= bcm6358_pinctrl_get_group_count,
+	.get_group_name		= bcm6358_pinctrl_get_group_name,
+	.get_group_pins		= bcm6358_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm6358_pmx_ops = {
+	.get_functions_count	= bcm6358_pinctrl_get_func_count,
+	.get_function_name	= bcm6358_pinctrl_get_func_name,
+	.get_function_groups	= bcm6358_pinctrl_get_groups,
+	.set_mux		= bcm6358_pinctrl_set_mux,
+	.gpio_request_enable	= bcm6358_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm6358_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm6358_pinctrl *pctl;
+	struct regmap *mode;
+	struct reg_field overlays = REG_FIELD(0, 0, 15);
+
+	if (pdev->dev.of_node)
+		mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+						       "brcm,gpiomode");
+	else
+		mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");
+
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	pctl->overlays = devm_regmap_field_alloc(&pdev->dev, mode, overlays);
+	if (IS_ERR(pctl->overlays))
+		return PTR_ERR(pctl->overlays);
+
+	/* disable all muxes by default */
+	regmap_field_write(pctl->overlays, 0);
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm6358_pctl_ops;
+	pctl->desc.pmxops = &bcm6358_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm6358_pins);
+	pctl->desc.pins = bcm6358_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 pctl->gpio, BCM6358_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6358_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6358-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm6358_pinctrl_driver = {
+	.probe = bcm6358_pinctrl_probe,
+	.driver = {
+		.name = "bcm6358-pinctrl",
+		.of_match_table = bcm6358_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6358_pinctrl_driver);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 08/13] Documentation: add BCM6362 pincontroller binding documentation
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
                   ` (2 preceding siblings ...)
  2016-08-19 10:53 ` [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358 Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
       [not found]   ` <1471604025-21575-9-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53 ` [PATCH 09/13] pinctrl: add a pincontrol driver for BCM6362 Jonas Gorski
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in BCM6362 SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 .../bindings/pinctrl/brcm,bcm6362-pinctrl.txt      | 79 ++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt
new file mode 100644
index 0000000..c7bbf1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt
@@ -0,0 +1,79 @@
+* Broadcom BCM6362 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6362-pinctrl"
+- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers.
+- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode".
+- gpio-controller: Identifies this node as a GPIO controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@10000080 {
+	compatible = "brcm,bcm6362-pinctrl";
+	reg = <0x10000080 0x8>,
+	      <0x10000088 0x8>,
+	      <0x10000090 0x4>,
+	      <0x10000098 0x4>,
+	      <0x1000009c 0x4>,
+	      <0x100000b8 0x4>;
+	reg-names = "dirout", "dat", "led",
+		    "mode", "ctrl", "basemode";
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+Available pins/groups and functions:
+
+name		pins		functions
+-----------------------------------------------------------
+gpio0		0		led, usb_device_led
+gpio1		1		led, sys_irq
+gpio2		2		led, serial_led_clk
+gpio3		3		led, serial_led_data
+gpio4		4		led, robosw_led_data
+gpio5		5		led, robosw_led_clk
+gpio6		6		led, robosw_led0
+gpio7		7		led, robosw_led1
+gpio8		8		led, inet_led
+gpio9		9		led, spi_cs2
+gpio10		10		led, spi_cs3
+gpio11		11		led, ntr_pulse
+gpio12		12		led, uart1_scts
+gpio13		13		led, uart1_srts
+gpio14		14		led, uart1_sdin
+gpio15		15		led, uart1_sdout
+gpio16		16		led, adsl_spi_miso
+gpio17		17		led, adsl_spi_mosi
+gpio18		18		led, adsl_spi_clk
+gpio19		19		led, adsl_spi_cs
+gpio20		20		led, ephy0_led
+gpio21		21		led, ephy1_led
+gpio22		22		led, ephy2_led
+gpio23		23		led, ephy3_led
+gpio24		24		ext_irq0
+gpio25		25		ext_irq1
+gpio26		26		ext_irq2
+gpio27		27		ext_irq3
+gpio28		28		-
+gpio29		29		-
+gpio30		30		-
+gpio31		31		-
+gpio32		32		wifi
+gpio33		33		wifi
+gpio34		34		wifi
+gpio35		35		wifi
+gpio36		36		wifi
+gpio37		37		wifi
+gpio38		38		wifi
+gpio39		39		wifi
+gpio40		40		wifi
+gpio41		41		wifi
+gpio42		42		wifi
+gpio43		43		wifi
+gpio44		44		wifi
+gpio45		45		wifi
+gpio46		46		wifi
+gpio47		47		wifi
+nand_grp	8, 12-23, 27	nand
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 09/13] pinctrl: add a pincontrol driver for BCM6362
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
                   ` (3 preceding siblings ...)
  2016-08-19 10:53 ` [PATCH 08/13] Documentation: add BCM6362 pincontroller binding documentation Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
       [not found]   ` <1471604025-21575-10-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53 ` [PATCH 10/13] Documentation: add BCM6368 pincontroller binding documentation Jonas Gorski
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual
GPIO pins to the LED controller, to be available by the integrated
wifi, or other functions. It also supports overlay groups, of which
only NAND is documented.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 drivers/pinctrl/bcm63xx/Kconfig           |   7 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | 692 ++++++++++++++++++++++++++++++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c

diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
index ef7b182..621fe73 100644
--- a/drivers/pinctrl/bcm63xx/Kconfig
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -23,3 +23,10 @@ config PINCTRL_BCM6358
 	select PINCTRL_BCM63XX
 	select GENERIC_PINCONF
 	select MFD_SYSCON
+
+config PINCTRL_BCM6362
+	bool "BCM6362 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index 181504c..799a8dd 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
 obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
+obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c
new file mode 100644
index 0000000..e317797
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c
@@ -0,0 +1,692 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6362_NGPIO	48
+
+/* GPIO_BASEMODE register */
+#define BASEMODE_NAND	BIT(2)
+
+enum bcm6362_pinctrl_reg {
+	BCM6362_LEDCTRL,
+	BCM6362_MODE,
+	BCM6362_CTRL,
+	BCM6362_BASEMODE,
+};
+
+struct bcm6362_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6362_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	enum bcm6362_pinctrl_reg reg;
+	u32 basemode_mask;
+};
+
+struct bcm6362_pinctrl {
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	void __iomem *led;
+	void __iomem *mode;
+	void __iomem *ctrl;
+	void __iomem *basemode;
+
+	/* register access lock */
+	spinlock_t lock;
+
+	struct gpio_chip gpio[2];
+};
+
+#define BCM6362_PIN(a, b, mask)			\
+	{					\
+		.number = a,			\
+		.name = b,			\
+		.drv_data = (void *)(mask),	\
+	}
+
+static const struct pinctrl_pin_desc bcm6362_pins[] = {
+	PINCTRL_PIN(0, "gpio0"),
+	PINCTRL_PIN(1, "gpio1"),
+	PINCTRL_PIN(2, "gpio2"),
+	PINCTRL_PIN(3, "gpio3"),
+	PINCTRL_PIN(4, "gpio4"),
+	PINCTRL_PIN(5, "gpio5"),
+	PINCTRL_PIN(6, "gpio6"),
+	PINCTRL_PIN(7, "gpio7"),
+	BCM6362_PIN(8, "gpio8", BASEMODE_NAND),
+	PINCTRL_PIN(9, "gpio9"),
+	PINCTRL_PIN(10, "gpio10"),
+	PINCTRL_PIN(11, "gpio11"),
+	BCM6362_PIN(12, "gpio12", BASEMODE_NAND),
+	BCM6362_PIN(13, "gpio13", BASEMODE_NAND),
+	BCM6362_PIN(14, "gpio14", BASEMODE_NAND),
+	BCM6362_PIN(15, "gpio15", BASEMODE_NAND),
+	BCM6362_PIN(16, "gpio16", BASEMODE_NAND),
+	BCM6362_PIN(17, "gpio17", BASEMODE_NAND),
+	BCM6362_PIN(18, "gpio18", BASEMODE_NAND),
+	BCM6362_PIN(19, "gpio19", BASEMODE_NAND),
+	BCM6362_PIN(20, "gpio20", BASEMODE_NAND),
+	BCM6362_PIN(21, "gpio21", BASEMODE_NAND),
+	BCM6362_PIN(22, "gpio22", BASEMODE_NAND),
+	BCM6362_PIN(23, "gpio23", BASEMODE_NAND),
+	PINCTRL_PIN(24, "gpio24"),
+	PINCTRL_PIN(25, "gpio25"),
+	PINCTRL_PIN(26, "gpio26"),
+	BCM6362_PIN(27, "gpio27", BASEMODE_NAND),
+	PINCTRL_PIN(28, "gpio28"),
+	PINCTRL_PIN(29, "gpio29"),
+	PINCTRL_PIN(30, "gpio30"),
+	PINCTRL_PIN(31, "gpio31"),
+	PINCTRL_PIN(32, "gpio32"),
+	PINCTRL_PIN(33, "gpio33"),
+	PINCTRL_PIN(34, "gpio34"),
+	PINCTRL_PIN(35, "gpio35"),
+	PINCTRL_PIN(36, "gpio36"),
+	PINCTRL_PIN(37, "gpio37"),
+	PINCTRL_PIN(38, "gpio38"),
+	PINCTRL_PIN(39, "gpio39"),
+	PINCTRL_PIN(40, "gpio40"),
+	PINCTRL_PIN(41, "gpio41"),
+	PINCTRL_PIN(42, "gpio42"),
+	PINCTRL_PIN(43, "gpio43"),
+	PINCTRL_PIN(44, "gpio44"),
+	PINCTRL_PIN(45, "gpio45"),
+	PINCTRL_PIN(46, "gpio46"),
+	PINCTRL_PIN(47, "gpio47"),
+};
+
+static unsigned gpio0_pins[] = { 0 };
+static unsigned gpio1_pins[] = { 1 };
+static unsigned gpio2_pins[] = { 2 };
+static unsigned gpio3_pins[] = { 3 };
+static unsigned gpio4_pins[] = { 4 };
+static unsigned gpio5_pins[] = { 5 };
+static unsigned gpio6_pins[] = { 6 };
+static unsigned gpio7_pins[] = { 7 };
+static unsigned gpio8_pins[] = { 8 };
+static unsigned gpio9_pins[] = { 9 };
+static unsigned gpio10_pins[] = { 10 };
+static unsigned gpio11_pins[] = { 11 };
+static unsigned gpio12_pins[] = { 12 };
+static unsigned gpio13_pins[] = { 13 };
+static unsigned gpio14_pins[] = { 14 };
+static unsigned gpio15_pins[] = { 15 };
+static unsigned gpio16_pins[] = { 16 };
+static unsigned gpio17_pins[] = { 17 };
+static unsigned gpio18_pins[] = { 18 };
+static unsigned gpio19_pins[] = { 19 };
+static unsigned gpio20_pins[] = { 20 };
+static unsigned gpio21_pins[] = { 21 };
+static unsigned gpio22_pins[] = { 22 };
+static unsigned gpio23_pins[] = { 23 };
+static unsigned gpio24_pins[] = { 24 };
+static unsigned gpio25_pins[] = { 25 };
+static unsigned gpio26_pins[] = { 26 };
+static unsigned gpio27_pins[] = { 27 };
+static unsigned gpio28_pins[] = { 28 };
+static unsigned gpio29_pins[] = { 29 };
+static unsigned gpio30_pins[] = { 30 };
+static unsigned gpio31_pins[] = { 31 };
+static unsigned gpio32_pins[] = { 32 };
+static unsigned gpio33_pins[] = { 33 };
+static unsigned gpio34_pins[] = { 34 };
+static unsigned gpio35_pins[] = { 35 };
+static unsigned gpio36_pins[] = { 36 };
+static unsigned gpio37_pins[] = { 37 };
+static unsigned gpio38_pins[] = { 38 };
+static unsigned gpio39_pins[] = { 39 };
+static unsigned gpio40_pins[] = { 40 };
+static unsigned gpio41_pins[] = { 41 };
+static unsigned gpio42_pins[] = { 42 };
+static unsigned gpio43_pins[] = { 43 };
+static unsigned gpio44_pins[] = { 44 };
+static unsigned gpio45_pins[] = { 45 };
+static unsigned gpio46_pins[] = { 46 };
+static unsigned gpio47_pins[] = { 47 };
+
+static unsigned nand_grp_pins[] = {
+	8, 12, 13, 14, 15, 16, 17,
+	18, 19, 20, 21, 22, 23, 27,
+};
+
+#define BCM6362_GROUP(n)				\
+	{						\
+		.name = #n,				\
+		.pins = n##_pins,			\
+		.num_pins = ARRAY_SIZE(n##_pins),	\
+	}
+
+static struct bcm6362_pingroup bcm6362_groups[] = {
+	BCM6362_GROUP(gpio0),
+	BCM6362_GROUP(gpio1),
+	BCM6362_GROUP(gpio2),
+	BCM6362_GROUP(gpio3),
+	BCM6362_GROUP(gpio4),
+	BCM6362_GROUP(gpio5),
+	BCM6362_GROUP(gpio6),
+	BCM6362_GROUP(gpio7),
+	BCM6362_GROUP(gpio8),
+	BCM6362_GROUP(gpio9),
+	BCM6362_GROUP(gpio10),
+	BCM6362_GROUP(gpio11),
+	BCM6362_GROUP(gpio12),
+	BCM6362_GROUP(gpio13),
+	BCM6362_GROUP(gpio14),
+	BCM6362_GROUP(gpio15),
+	BCM6362_GROUP(gpio16),
+	BCM6362_GROUP(gpio17),
+	BCM6362_GROUP(gpio18),
+	BCM6362_GROUP(gpio19),
+	BCM6362_GROUP(gpio20),
+	BCM6362_GROUP(gpio21),
+	BCM6362_GROUP(gpio22),
+	BCM6362_GROUP(gpio23),
+	BCM6362_GROUP(gpio24),
+	BCM6362_GROUP(gpio25),
+	BCM6362_GROUP(gpio26),
+	BCM6362_GROUP(gpio27),
+	BCM6362_GROUP(gpio28),
+	BCM6362_GROUP(gpio29),
+	BCM6362_GROUP(gpio30),
+	BCM6362_GROUP(gpio31),
+	BCM6362_GROUP(gpio32),
+	BCM6362_GROUP(gpio33),
+	BCM6362_GROUP(gpio34),
+	BCM6362_GROUP(gpio35),
+	BCM6362_GROUP(gpio36),
+	BCM6362_GROUP(gpio37),
+	BCM6362_GROUP(gpio38),
+	BCM6362_GROUP(gpio39),
+	BCM6362_GROUP(gpio40),
+	BCM6362_GROUP(gpio41),
+	BCM6362_GROUP(gpio42),
+	BCM6362_GROUP(gpio43),
+	BCM6362_GROUP(gpio44),
+	BCM6362_GROUP(gpio45),
+	BCM6362_GROUP(gpio46),
+	BCM6362_GROUP(gpio47),
+	BCM6362_GROUP(nand_grp),
+};
+
+static const char * const led_groups[] = {
+	"gpio0",
+	"gpio1",
+	"gpio2",
+	"gpio3",
+	"gpio4",
+	"gpio5",
+	"gpio6",
+	"gpio7",
+	"gpio8",
+	"gpio9",
+	"gpio10",
+	"gpio11",
+	"gpio12",
+	"gpio13",
+	"gpio14",
+	"gpio15",
+	"gpio16",
+	"gpio17",
+	"gpio18",
+	"gpio19",
+	"gpio20",
+	"gpio21",
+	"gpio22",
+	"gpio23",
+};
+
+static const char * const usb_device_led_groups[] = {
+	"gpio0",
+};
+
+static const char * const sys_irq_groups[] = {
+	"gpio1",
+};
+
+static const char * const serial_led_clk_groups[] = {
+	"gpio2",
+};
+
+static const char * const serial_led_data_groups[] = {
+	"gpio3",
+};
+
+static const char * const robosw_led_data_groups[] = {
+	"gpio4",
+};
+
+static const char * const robosw_led_clk_groups[] = {
+	"gpio5",
+};
+
+static const char * const robosw_led0_groups[] = {
+	"gpio6",
+};
+
+static const char * const robosw_led1_groups[] = {
+	"gpio7",
+};
+
+static const char * const inet_led_groups[] = {
+	"gpio8",
+};
+
+static const char * const spi_cs2_groups[] = {
+	"gpio9",
+};
+
+static const char * const spi_cs3_groups[] = {
+	"gpio10",
+};
+
+static const char * const ntr_pulse_groups[] = {
+	"gpio11",
+};
+
+static const char * const uart1_scts_groups[] = {
+	"gpio12",
+};
+
+static const char * const uart1_srts_groups[] = {
+	"gpio13",
+};
+
+static const char * const uart1_sdin_groups[] = {
+	"gpio14",
+};
+
+static const char * const uart1_sdout_groups[] = {
+	"gpio15",
+};
+
+static const char * const adsl_spi_miso_groups[] = {
+	"gpio16",
+};
+
+static const char * const adsl_spi_mosi_groups[] = {
+	"gpio17",
+};
+
+static const char * const adsl_spi_clk_groups[] = {
+	"gpio18",
+};
+
+static const char * const adsl_spi_cs_groups[] = {
+	"gpio19",
+};
+
+static const char * const ephy0_led_groups[] = {
+	"gpio20",
+};
+
+static const char * const ephy1_led_groups[] = {
+	"gpio21",
+};
+
+static const char * const ephy2_led_groups[] = {
+	"gpio22",
+};
+
+static const char * const ephy3_led_groups[] = {
+	"gpio23",
+};
+
+static const char * const ext_irq0_groups[] = {
+	"gpio24",
+};
+
+static const char * const ext_irq1_groups[] = {
+	"gpio25",
+};
+
+static const char * const ext_irq2_groups[] = {
+	"gpio26",
+};
+
+static const char * const ext_irq3_groups[] = {
+	"gpio27",
+};
+
+static const char * const wifi_groups[] = {
+	"gpio32",
+	"gpio33",
+	"gpio34",
+	"gpio35",
+	"gpio36",
+	"gpio37",
+	"gpio38",
+	"gpio39",
+	"gpio40",
+	"gpio41",
+	"gpio42",
+	"gpio43",
+	"gpio44",
+	"gpio45",
+	"gpio46",
+	"gpio47",
+};
+
+static const char * const nand_groups[] = {
+	"nand_grp",
+};
+
+#define BCM6362_LED_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM6362_LEDCTRL,			\
+	}
+
+#define BCM6362_MODE_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM6362_MODE,			\
+	}
+
+#define BCM6362_CTRL_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM6362_CTRL,			\
+	}
+
+#define BCM6362_BASEMODE_FUN(n, mask)			\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM6362_BASEMODE,		\
+		.basemode_mask = (mask),		\
+	}
+
+static const struct bcm6362_function bcm6362_funcs[] = {
+	BCM6362_LED_FUN(led),
+	BCM6362_MODE_FUN(usb_device_led),
+	BCM6362_MODE_FUN(sys_irq),
+	BCM6362_MODE_FUN(serial_led_clk),
+	BCM6362_MODE_FUN(serial_led_data),
+	BCM6362_MODE_FUN(robosw_led_data),
+	BCM6362_MODE_FUN(robosw_led_clk),
+	BCM6362_MODE_FUN(robosw_led0),
+	BCM6362_MODE_FUN(robosw_led1),
+	BCM6362_MODE_FUN(inet_led),
+	BCM6362_MODE_FUN(spi_cs2),
+	BCM6362_MODE_FUN(spi_cs3),
+	BCM6362_MODE_FUN(ntr_pulse),
+	BCM6362_MODE_FUN(uart1_scts),
+	BCM6362_MODE_FUN(uart1_srts),
+	BCM6362_MODE_FUN(uart1_sdin),
+	BCM6362_MODE_FUN(uart1_sdout),
+	BCM6362_MODE_FUN(adsl_spi_miso),
+	BCM6362_MODE_FUN(adsl_spi_mosi),
+	BCM6362_MODE_FUN(adsl_spi_clk),
+	BCM6362_MODE_FUN(adsl_spi_cs),
+	BCM6362_MODE_FUN(ephy0_led),
+	BCM6362_MODE_FUN(ephy1_led),
+	BCM6362_MODE_FUN(ephy2_led),
+	BCM6362_MODE_FUN(ephy3_led),
+	BCM6362_MODE_FUN(ext_irq0),
+	BCM6362_MODE_FUN(ext_irq1),
+	BCM6362_MODE_FUN(ext_irq2),
+	BCM6362_MODE_FUN(ext_irq3),
+	BCM6362_CTRL_FUN(wifi),
+	BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND),
+};
+
+static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6362_groups);
+}
+
+static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6362_groups[group].name;
+}
+
+static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6362_groups[group].pins;
+	*num_pins = bcm6362_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6362_funcs);
+}
+
+static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6362_funcs[selector].name;
+}
+
+static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6362_funcs[selector].groups;
+	*num_groups = bcm6362_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static void bcm6362_rmw_mux(struct bcm6362_pinctrl *pctl, void __iomem *reg,
+			    u32 mask, u32 val)
+{
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	tmp = __raw_readl(reg);
+	tmp &= ~mask;
+	tmp |= val & mask;
+	__raw_writel(tmp, reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static void bcm6362_set_gpio(struct bcm6362_pinctrl *pctl, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
+	u32 mask = BIT(pin % 32);
+
+	if (desc->drv_data)
+		bcm6362_rmw_mux(pctl, pctl->basemode, (u32)desc->drv_data, 0);
+
+	if (pin < 32) {
+		/* base mode 0 => gpio 1 => mux function */
+		bcm6362_rmw_mux(pctl, pctl->mode, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < 24)
+			bcm6362_rmw_mux(pctl, pctl->led, mask, 0);
+	} else {
+		/* ctrl reg 0 => wifi function 1 => gpio */
+		bcm6362_rmw_mux(pctl, pctl->ctrl, mask, mask);
+	}
+}
+
+static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6362_pingroup *grp = &bcm6362_groups[group];
+	const struct bcm6362_function *f = &bcm6362_funcs[selector];
+	unsigned i;
+	void __iomem *reg;
+	u32 val, mask;
+
+	for (i = 0; i < grp->num_pins; i++)
+		bcm6362_set_gpio(pctl, grp->pins[i]);
+
+	switch (f->reg) {
+	case BCM6362_LEDCTRL:
+		reg = pctl->led;
+		mask = BIT(grp->pins[0]);
+		val = BIT(grp->pins[0]);
+		break;
+	case BCM6362_MODE:
+		reg = pctl->ctrl;
+		mask = BIT(grp->pins[0]);
+		val = BIT(grp->pins[0]);
+		break;
+	case BCM6362_CTRL:
+		reg = pctl->ctrl;
+		mask = BIT(grp->pins[0]);
+		val = 0;
+		break;
+	case BCM6362_BASEMODE:
+		reg = pctl->basemode;
+		mask = f->basemode_mask;
+		val = f->basemode_mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	bcm6362_rmw_mux(pctl, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6362_set_gpio(pctl, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6362_pctl_ops = {
+	.get_groups_count	= bcm6362_pinctrl_get_group_count,
+	.get_group_name		= bcm6362_pinctrl_get_group_name,
+	.get_group_pins		= bcm6362_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm6362_pmx_ops = {
+	.get_functions_count	= bcm6362_pinctrl_get_func_count,
+	.get_function_name	= bcm6362_pinctrl_get_func_name,
+	.get_function_groups	= bcm6362_pinctrl_get_groups,
+	.set_mux		= bcm6362_pinctrl_set_mux,
+	.gpio_request_enable	= bcm6362_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm6362_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm6362_pinctrl *pctl;
+	struct resource *res;
+	void __iomem *led, *mode, *ctrl, *basemode;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led");
+	led = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(led))
+		return PTR_ERR(led);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
+	mode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+	ctrl = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode");
+	basemode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(basemode))
+		return PTR_ERR(basemode);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	spin_lock_init(&pctl->lock);
+
+	pctl->led = led;
+	pctl->mode = mode;
+	pctl->ctrl = ctrl;
+	pctl->basemode = basemode;
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm6362_pctl_ops;
+	pctl->desc.pmxops = &bcm6362_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm6362_pins);
+	pctl->desc.pins = bcm6362_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 pctl->gpio, BCM6362_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6362_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6362-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm6362_pinctrl_driver = {
+	.probe = bcm6362_pinctrl_probe,
+	.driver = {
+		.name = "bcm6362-pinctrl",
+		.of_match_table = bcm6362_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6362_pinctrl_driver);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 10/13] Documentation: add BCM6368 pincontroller binding documentation
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
                   ` (4 preceding siblings ...)
  2016-08-19 10:53 ` [PATCH 09/13] pinctrl: add a pincontrol driver for BCM6362 Jonas Gorski
@ 2016-08-19 10:53 ` Jonas Gorski
       [not found]   ` <1471604025-21575-11-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53 ` [PATCH 12/13] Documentation: add BCM63268 pincontroller binding documentation Jonas Gorski
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in BCM6368 SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 .../bindings/pinctrl/brcm,bcm6368-pinctrl.txt      | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt
new file mode 100644
index 0000000..59c466e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt
@@ -0,0 +1,67 @@
+* Broadcom BCM6368 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6368-pinctrl".
+- reg: Register specifiers of dirout, dat, mode registers.
+- reg-names: Must be "dirout", "dat", "mode".
+- brcm,gpiobasemode: Phandle to the gpio basemode register.
+- gpio-controller: Identifies this node as a GPIO controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@10000080 {
+	compatible = "brcm,bcm6368-pinctrl";
+	reg = <0x10000080 0x08>,
+	      <0x10000088 0x08>,
+	      <0x10000098 0x04>;
+	reg-names = "dirout", "dat", "mode";
+	brcm,gpiobasemode = <&gpiobasemode>;
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+gpiobasemode: syscon@100000b8 {
+	compatible = "brcm,bcm6368-gpiobasemode", "syscon";
+	reg = <0x100000b8 4>;
+	native-endian;
+};
+
+Available pins/groups and functions:
+
+name		pins	functions
+-----------------------------------------------------------
+gpio0		0	analog_afe0
+gpio1		1	analog_afe1
+gpio2		2	sys_irq
+gpio3		3	serial_led_data
+gpio4		4	serial_led_clk
+gpio5		5	inet_led
+gpio6		6	ephy0_led
+gpio7		7	ephy1_led
+gpio8		8	ephy2_led
+gpio9		9	ephy3_led
+gpio10		10	robosw_led_data
+gpio11		11	robosw_led_clk
+gpio12		12	robosw_led0
+gpio13		13	robosw_led1
+gpio14		14	usb_device_led
+gpio15		15	-
+gpio16		16	pci_req1
+gpio17		17	pci_gnt1
+gpio18		18	pci_intb
+gpio19		19	pci_req0
+gpio20		20	pci_gnt0
+gpio21		21	-
+gpio22		22	pcmcia_cd1
+gpio23		23	pcmcia_cd2
+gpio24		24	pcmcia_vs1
+gpio25		25	pcmcia_vs2
+gpio26		26	ebi_cs2
+gpio27		27	ebi_cs3
+gpio28		28	spi_cs2
+gpio29		29	spi_cs3
+gpio30		30	spi_cs4
+gpio31		31	spi_cs5
+uart1_grp	30-33	uart1
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 11/13] pinctrl: add a pincontrol driver for BCM6368
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-08-19 10:53   ` [PATCH 06/13] Documentation: add BCM6358 pincontroller binding documentation Jonas Gorski
@ 2016-08-19 10:53   ` Jonas Gorski
       [not found]     ` <1471604025-21575-12-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2016-08-19 10:53   ` [PATCH 13/13] pinctrl: add a pincontrol driver for BCM63268 Jonas Gorski
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32
GPIOs onto alternative functions. Not all are documented.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pinctrl/bcm63xx/Kconfig           |  15 +
 drivers/pinctrl/bcm63xx/Makefile          |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | 573 ++++++++++++++++++++++++++++++
 3 files changed, 589 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c

diff --git a/drivers/pinctrl/bcm63xx/Kconfig b/drivers/pinctrl/bcm63xx/Kconfig
index 621fe73..868cc6c 100644
--- a/drivers/pinctrl/bcm63xx/Kconfig
+++ b/drivers/pinctrl/bcm63xx/Kconfig
@@ -30,3 +30,18 @@ config PINCTRL_BCM6362
 	select PINCONF
 	select PINCTRL_BCM63XX
 	select GENERIC_PINCONF
+
+config PINCTRL_BCM6368
+	bool "BCM6368 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
+	select MFD_SYSCON
+
+config PINCTRL_BCM63268
+	bool "BCM63268 pincontrol driver" if COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select PINCTRL_BCM63XX
+	select GENERIC_PINCONF
diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index 799a8dd..94f9c6b 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
 obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
+obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c
new file mode 100644
index 0000000..77d9a70
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c
@@ -0,0 +1,573 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6368_NGPIO	38
+
+#define BCM6368_BASEMODE_MASK	0x7
+#define BCM6368_BASEMODE_GPIO	0x0
+#define BCM6368_BASEMODE_UART1	0x1
+
+struct bcm6368_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6368_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	unsigned dir_out:16;
+	unsigned basemode:3;
+};
+
+struct bcm6368_pinctrl {
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	void __iomem *mode;
+	struct regmap_field *overlay;
+
+	/* register access lock */
+	spinlock_t lock;
+
+	struct gpio_chip gpio[2];
+};
+
+#define BCM6368_BASEMODE_PIN(a, b)		\
+	{					\
+		.number = a,			\
+		.name = b,			\
+		.drv_data = (void *)true	\
+	}
+
+static const struct pinctrl_pin_desc bcm6368_pins[] = {
+	PINCTRL_PIN(0, "gpio0"),
+	PINCTRL_PIN(1, "gpio1"),
+	PINCTRL_PIN(2, "gpio2"),
+	PINCTRL_PIN(3, "gpio3"),
+	PINCTRL_PIN(4, "gpio4"),
+	PINCTRL_PIN(5, "gpio5"),
+	PINCTRL_PIN(6, "gpio6"),
+	PINCTRL_PIN(7, "gpio7"),
+	PINCTRL_PIN(8, "gpio8"),
+	PINCTRL_PIN(9, "gpio9"),
+	PINCTRL_PIN(10, "gpio10"),
+	PINCTRL_PIN(11, "gpio11"),
+	PINCTRL_PIN(12, "gpio12"),
+	PINCTRL_PIN(13, "gpio13"),
+	PINCTRL_PIN(14, "gpio14"),
+	PINCTRL_PIN(15, "gpio15"),
+	PINCTRL_PIN(16, "gpio16"),
+	PINCTRL_PIN(17, "gpio17"),
+	PINCTRL_PIN(18, "gpio18"),
+	PINCTRL_PIN(19, "gpio19"),
+	PINCTRL_PIN(20, "gpio20"),
+	PINCTRL_PIN(21, "gpio21"),
+	PINCTRL_PIN(22, "gpio22"),
+	PINCTRL_PIN(23, "gpio23"),
+	PINCTRL_PIN(24, "gpio24"),
+	PINCTRL_PIN(25, "gpio25"),
+	PINCTRL_PIN(26, "gpio26"),
+	PINCTRL_PIN(27, "gpio27"),
+	PINCTRL_PIN(28, "gpio28"),
+	PINCTRL_PIN(29, "gpio29"),
+	BCM6368_BASEMODE_PIN(30, "gpio30"),
+	BCM6368_BASEMODE_PIN(31, "gpio31"),
+	BCM6368_BASEMODE_PIN(32, "gpio32"),
+	BCM6368_BASEMODE_PIN(33, "gpio33"),
+	PINCTRL_PIN(34, "gpio34"),
+	PINCTRL_PIN(35, "gpio35"),
+	PINCTRL_PIN(36, "gpio36"),
+	PINCTRL_PIN(37, "gpio37"),
+};
+
+static unsigned gpio0_pins[] = { 0 };
+static unsigned gpio1_pins[] = { 1 };
+static unsigned gpio2_pins[] = { 2 };
+static unsigned gpio3_pins[] = { 3 };
+static unsigned gpio4_pins[] = { 4 };
+static unsigned gpio5_pins[] = { 5 };
+static unsigned gpio6_pins[] = { 6 };
+static unsigned gpio7_pins[] = { 7 };
+static unsigned gpio8_pins[] = { 8 };
+static unsigned gpio9_pins[] = { 9 };
+static unsigned gpio10_pins[] = { 10 };
+static unsigned gpio11_pins[] = { 11 };
+static unsigned gpio12_pins[] = { 12 };
+static unsigned gpio13_pins[] = { 13 };
+static unsigned gpio14_pins[] = { 14 };
+static unsigned gpio15_pins[] = { 15 };
+static unsigned gpio16_pins[] = { 16 };
+static unsigned gpio17_pins[] = { 17 };
+static unsigned gpio18_pins[] = { 18 };
+static unsigned gpio19_pins[] = { 19 };
+static unsigned gpio20_pins[] = { 20 };
+static unsigned gpio21_pins[] = { 21 };
+static unsigned gpio22_pins[] = { 22 };
+static unsigned gpio23_pins[] = { 23 };
+static unsigned gpio24_pins[] = { 24 };
+static unsigned gpio25_pins[] = { 25 };
+static unsigned gpio26_pins[] = { 26 };
+static unsigned gpio27_pins[] = { 27 };
+static unsigned gpio28_pins[] = { 28 };
+static unsigned gpio29_pins[] = { 29 };
+static unsigned gpio30_pins[] = { 30 };
+static unsigned gpio31_pins[] = { 31 };
+static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 };
+
+#define BCM6368_GROUP(n)				\
+	{						\
+		.name = #n,				\
+		.pins = n##_pins,			\
+		.num_pins = ARRAY_SIZE(n##_pins),	\
+	}
+
+static struct bcm6368_pingroup bcm6368_groups[] = {
+	BCM6368_GROUP(gpio0),
+	BCM6368_GROUP(gpio1),
+	BCM6368_GROUP(gpio2),
+	BCM6368_GROUP(gpio3),
+	BCM6368_GROUP(gpio4),
+	BCM6368_GROUP(gpio5),
+	BCM6368_GROUP(gpio6),
+	BCM6368_GROUP(gpio7),
+	BCM6368_GROUP(gpio8),
+	BCM6368_GROUP(gpio9),
+	BCM6368_GROUP(gpio10),
+	BCM6368_GROUP(gpio11),
+	BCM6368_GROUP(gpio12),
+	BCM6368_GROUP(gpio13),
+	BCM6368_GROUP(gpio14),
+	BCM6368_GROUP(gpio15),
+	BCM6368_GROUP(gpio16),
+	BCM6368_GROUP(gpio17),
+	BCM6368_GROUP(gpio18),
+	BCM6368_GROUP(gpio19),
+	BCM6368_GROUP(gpio20),
+	BCM6368_GROUP(gpio21),
+	BCM6368_GROUP(gpio22),
+	BCM6368_GROUP(gpio23),
+	BCM6368_GROUP(gpio24),
+	BCM6368_GROUP(gpio25),
+	BCM6368_GROUP(gpio26),
+	BCM6368_GROUP(gpio27),
+	BCM6368_GROUP(gpio28),
+	BCM6368_GROUP(gpio29),
+	BCM6368_GROUP(gpio30),
+	BCM6368_GROUP(gpio31),
+	BCM6368_GROUP(uart1_grp),
+};
+
+static const char * const analog_afe_0_groups[] = {
+	"gpio0",
+};
+
+static const char * const analog_afe_1_groups[] = {
+	"gpio1",
+};
+
+static const char * const sys_irq_groups[] = {
+	"gpio2",
+};
+
+static const char * const serial_led_data_groups[] = {
+	"gpio3",
+};
+
+static const char * const serial_led_clk_groups[] = {
+	"gpio4",
+};
+
+static const char * const inet_led_groups[] = {
+	"gpio5",
+};
+
+static const char * const ephy0_led_groups[] = {
+	"gpio6",
+};
+
+static const char * const ephy1_led_groups[] = {
+	"gpio7",
+};
+
+static const char * const ephy2_led_groups[] = {
+	"gpio8",
+};
+
+static const char * const ephy3_led_groups[] = {
+	"gpio9",
+};
+
+static const char * const robosw_led_data_groups[] = {
+	"gpio10",
+};
+
+static const char * const robosw_led_clk_groups[] = {
+	"gpio11",
+};
+
+static const char * const robosw_led0_groups[] = {
+	"gpio12",
+};
+
+static const char * const robosw_led1_groups[] = {
+	"gpio13",
+};
+
+static const char * const usb_device_led_groups[] = {
+	"gpio14",
+};
+
+static const char * const pci_req1_groups[] = {
+	"gpio16",
+};
+
+static const char * const pci_gnt1_groups[] = {
+	"gpio17",
+};
+
+static const char * const pci_intb_groups[] = {
+	"gpio18",
+};
+
+static const char * const pci_req0_groups[] = {
+	"gpio19",
+};
+
+static const char * const pci_gnt0_groups[] = {
+	"gpio20",
+};
+
+static const char * const pcmcia_cd1_groups[] = {
+	"gpio22",
+};
+
+static const char * const pcmcia_cd2_groups[] = {
+	"gpio23",
+};
+
+static const char * const pcmcia_vs1_groups[] = {
+	"gpio24",
+};
+
+static const char * const pcmcia_vs2_groups[] = {
+	"gpio25",
+};
+
+static const char * const ebi_cs2_groups[] = {
+	"gpio26",
+};
+
+static const char * const ebi_cs3_groups[] = {
+	"gpio27",
+};
+
+static const char * const spi_cs2_groups[] = {
+	"gpio28",
+};
+
+static const char * const spi_cs3_groups[] = {
+	"gpio29",
+};
+
+static const char * const spi_cs4_groups[] = {
+	"gpio30",
+};
+
+static const char * const spi_cs5_groups[] = {
+	"gpio31",
+};
+
+static const char * const uart1_groups[] = {
+	"uart1_grp",
+};
+
+#define BCM6368_FUN(n, out)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.dir_out = out,				\
+	}
+
+#define BCM6368_BASEMODE_FUN(n, val, out)		\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.basemode = BCM6368_BASEMODE_##val,	\
+		.dir_out = out,				\
+	}
+
+static const struct bcm6368_function bcm6368_funcs[] = {
+	BCM6368_FUN(analog_afe_0, 1),
+	BCM6368_FUN(analog_afe_1, 1),
+	BCM6368_FUN(sys_irq, 1),
+	BCM6368_FUN(serial_led_data, 1),
+	BCM6368_FUN(serial_led_clk, 1),
+	BCM6368_FUN(inet_led, 1),
+	BCM6368_FUN(ephy0_led, 1),
+	BCM6368_FUN(ephy1_led, 1),
+	BCM6368_FUN(ephy2_led, 1),
+	BCM6368_FUN(ephy3_led, 1),
+	BCM6368_FUN(robosw_led_data, 1),
+	BCM6368_FUN(robosw_led_clk, 1),
+	BCM6368_FUN(robosw_led0, 1),
+	BCM6368_FUN(robosw_led1, 1),
+	BCM6368_FUN(usb_device_led, 1),
+	BCM6368_FUN(pci_req1, 0),
+	BCM6368_FUN(pci_gnt1, 0),
+	BCM6368_FUN(pci_intb, 0),
+	BCM6368_FUN(pci_req0, 0),
+	BCM6368_FUN(pci_gnt0, 0),
+	BCM6368_FUN(pcmcia_cd1, 0),
+	BCM6368_FUN(pcmcia_cd2, 0),
+	BCM6368_FUN(pcmcia_vs1, 0),
+	BCM6368_FUN(pcmcia_vs2, 0),
+	BCM6368_FUN(ebi_cs2, 1),
+	BCM6368_FUN(ebi_cs3, 1),
+	BCM6368_FUN(spi_cs2, 1),
+	BCM6368_FUN(spi_cs3, 1),
+	BCM6368_FUN(spi_cs4, 1),
+	BCM6368_FUN(spi_cs5, 1),
+	BCM6368_BASEMODE_FUN(uart1, UART1, 0x6),
+};
+
+static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6368_groups);
+}
+
+static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6368_groups[group].name;
+}
+
+static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6368_groups[group].pins;
+	*num_pins = bcm6368_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6368_funcs);
+}
+
+static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6368_funcs[selector].name;
+}
+
+static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6368_funcs[selector].groups;
+	*num_groups = bcm6368_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static void bcm6368_rmw_mux(struct bcm6368_pinctrl *pctl, void __iomem *reg,
+			    u32 mask, u32 val)
+{
+	u32 tmp;
+
+	tmp = __raw_readl(reg);
+	tmp &= ~mask;
+	tmp |= (val & mask);
+	__raw_writel(tmp, reg);
+}
+
+static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6368_pingroup *grp = &bcm6368_groups[group];
+	const struct bcm6368_function *fun = &bcm6368_funcs[selector];
+	unsigned long flags;
+	int i, pin;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	if (fun->basemode) {
+		u32 mask = 0;
+
+		for (i = 0; i < grp->num_pins; i++) {
+			pin = grp->pins[i];
+			if (pin < 32)
+				mask |= BIT(pin);
+		}
+
+		bcm6368_rmw_mux(pctl, pctl->mode, mask, 0);
+		regmap_field_write(pctl->overlay, fun->basemode);
+	} else {
+		pin = grp->pins[0];
+
+		if (bcm6368_pins[pin].drv_data)
+			regmap_field_write(pctl->overlay,
+					   BCM6368_BASEMODE_GPIO);
+
+		bcm6368_rmw_mux(pctl, pctl->mode, BIT(pin), BIT(pin));
+	}
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	for (pin = 0; pin < grp->num_pins; pin++) {
+		int hw_gpio = bcm6368_pins[pin].number;
+		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32];
+
+		if (fun->dir_out & BIT(pin))
+			gc->direction_output(gc, hw_gpio % 32, 0);
+		else
+			gc->direction_input(gc, hw_gpio % 32);
+	}
+
+	return 0;
+}
+
+static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+
+	if (offset >= 32 && !bcm6368_pins[offset].drv_data)
+		return 0;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	/* disable all functions using this pin */
+	if (offset < 32)
+		bcm6368_rmw_mux(pctl, pctl->mode, BIT(offset), 0);
+
+	if (bcm6368_pins[offset].drv_data)
+		regmap_field_write(pctl->overlay, BCM6368_BASEMODE_GPIO);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6368_pctl_ops = {
+	.get_groups_count	= bcm6368_pinctrl_get_group_count,
+	.get_group_name		= bcm6368_pinctrl_get_group_name,
+	.get_group_pins		= bcm6368_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm6368_pmx_ops = {
+	.get_functions_count	= bcm6368_pinctrl_get_func_count,
+	.get_function_name	= bcm6368_pinctrl_get_func_name,
+	.get_function_groups	= bcm6368_pinctrl_get_groups,
+	.set_mux		= bcm6368_pinctrl_set_mux,
+	.gpio_request_enable	= bcm6368_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm6368_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm6368_pinctrl *pctl;
+	struct resource *res;
+	void __iomem *mode;
+	struct regmap *basemode;
+	struct reg_field overlay = REG_FIELD(0, 0, 3);
+
+	if (pdev->dev.of_node)
+		basemode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+							   "brcm,gpiobasemode");
+	else
+		basemode = syscon_regmap_lookup_by_pdevname("syscon.b00000b8");
+
+	if (IS_ERR(basemode))
+		return PTR_ERR(basemode);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
+	mode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	pctl->overlay = devm_regmap_field_alloc(&pdev->dev, mode, overlay);
+	if (IS_ERR(pctl->overlay))
+		return PTR_ERR(pctl->overlay);
+
+	spin_lock_init(&pctl->lock);
+
+	pctl->mode = mode;
+
+	/* disable all muxes by default */
+	__raw_writel(0, pctl->mode);
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm6368_pctl_ops;
+	pctl->desc.pmxops = &bcm6368_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm6368_pins);
+	pctl->desc.pins = bcm6368_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 pctl->gpio, BCM6368_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6368_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6368-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm6368_pinctrl_driver = {
+	.probe = bcm6368_pinctrl_probe,
+	.driver = {
+		.name = "bcm6368-pinctrl",
+		.of_match_table = bcm6368_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6368_pinctrl_driver);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 12/13] Documentation: add BCM63268 pincontroller binding documentation
  2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
                   ` (6 preceding siblings ...)
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-19 10:53 ` Jonas Gorski
  2016-08-22 13:25   ` Linus Walleij
  7 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio
  Cc: Linus Walleij, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add binding documentation for the pincontrol core found in the BCM63268
family SoCs.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 .../bindings/pinctrl/brcm,bcm63268-pinctrl.txt     | 88 ++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt
new file mode 100644
index 0000000..781d5fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt
@@ -0,0 +1,88 @@
+* Broadcom BCM63268 pin controller
+
+Required properties:
+- compatible: Must be "brcm,bcm6362-pinctrl".
+- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers.
+- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode".
+- gpio-controller: Identifies this node as a GPIO controller.
+- #gpio-cells: Must be <2>.
+
+Example:
+
+pinctrl: pin-controller@100000c0 {
+	compatible = "brcm,bcm63268-pinctrl";
+	reg = <0x100000c0 0x8>,
+	      <0x100000c8 0x8>,
+	      <0x100000d0 0x4>,
+	      <0x100000d8 0x4>,
+	      <0x100000dc 0x4>,
+	      <0x100000f8 0x4>;
+	reg-names = "dirout", "dat", "led", "mode",
+		    "ctrl", "basemode";
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
+
+Available pins/groups and functions:
+
+name		pins		functions
+-----------------------------------------------------------
+gpio0		0		led, serial_led_clk
+gpio1		1		led, serial_led_data
+gpio2		2		led,
+gpio3		3		led,
+gpio4		4		led,
+gpio5		5		led,
+gpio6		6		led,
+gpio7		7		led,
+gpio8		8		led, hsspi_cs6
+gpio9		9		led, hsspi_cs7
+gpio10		10		led, uart1_scts
+gpio11		11		led, uart1_srts
+gpio12		12		led, uart1_sdin
+gpio13		13		led, uart1_sdout
+gpio14		14		led, ntr_pulse_in
+gpio15		15		led, dsl_ntr_pulse_out
+gpio16		16		led, hsspi_cs4
+gpio17		17		led, hsspi_cs5
+gpio18		18		led, adsl_spi_miso
+gpio19		19		led, adsl_spi_mosi
+gpio20		20		led,
+gpio21		21		led,
+gpio22		22		led, vreg_clk
+gpio23		23		led, pcie_clkreq_b
+gpio24		24		uart1_scts
+gpio25		25		uart1_srts
+gpio26		26		uart1_sdin
+gpio27		27		uart1_sdout
+gpio28		28		ntr_pulse_in
+gpio29		29		dsl_ntr_pulse_out
+gpio30		30		switch_led_clk
+gpio31		31		switch_led_data
+gpio32		32		wifi
+gpio33		33		wifi
+gpio34		34		wifi
+gpio35		35		wifi
+gpio36		36		wifi
+gpio37		37		wifi
+gpio38		38		wifi
+gpio39		39		wifi
+gpio40		40		wifi
+gpio41		41		wifi
+gpio42		42		wifi
+gpio43		43		wifi
+gpio44		44		wifi
+gpio45		45		wifi
+gpio46		46		wifi
+gpio47		47		wifi
+gpio48		48		wifi
+gpio49		49		wifi
+gpio50		50		wifi
+gpio51		51		wifi
+nand_grp	2-7,24-31	nand
+dect_pd_grp	8-9		dect_pd
+vdsl_phy0_grp	10-11		vdsl_phy0
+vdsl_phy1_grp	12-13		vdsl_phy1
+vdsl_phy2_grp	24-25		vdsl_phy2
+vdsl_phy3_grp	26-27		vdsl_phy3
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 13/13] pinctrl: add a pincontrol driver for BCM63268
       [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-08-19 10:53   ` [PATCH 11/13] pinctrl: add a pincontrol driver for BCM6368 Jonas Gorski
@ 2016-08-19 10:53   ` Jonas Gorski
       [not found]     ` <1471604025-21575-14-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  5 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 10:53 UTC (permalink / raw)
  To: linux-gpio-u79uwXL29TY76Z2rM5mHXA
  Cc: Linus Walleij, devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	Mark Rutland, Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs
to different functions. Depending on the mux, these are either single
pin configurations or whole pin groups.

Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pinctrl/bcm63xx/Makefile           |   1 +
 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | 710 +++++++++++++++++++++++++++++
 2 files changed, 711 insertions(+)
 create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c

diff --git a/drivers/pinctrl/bcm63xx/Makefile b/drivers/pinctrl/bcm63xx/Makefile
index 94f9c6b..78cd5af 100644
--- a/drivers/pinctrl/bcm63xx/Makefile
+++ b/drivers/pinctrl/bcm63xx/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
 obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
 obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o
+obj-$(CONFIG_PINCTRL_BCM63268)	+= pinctrl-bcm63268.o
diff --git a/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c b/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c
new file mode 100644
index 0000000..f9eee89
--- /dev/null
+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c
@@ -0,0 +1,710 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/machine.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM63268_NGPIO			52
+
+/* GPIO_BASEMODE register */
+#define BASEMODE_NAND			BIT(2) /* GPIOs 2-7, 24-31 */
+#define BASEMODE_GPIO35			BIT(4) /* GPIO 35 */
+#define BASEMODE_DECTPD			BIT(5) /* GPIOs 8/9 */
+#define BASEMODE_VDSL_PHY_0		BIT(6) /* GPIOs 10/11 */
+#define BASEMODE_VDSL_PHY_1		BIT(7) /* GPIOs 12/13 */
+#define BASEMODE_VDSL_PHY_2		BIT(8) /* GPIOs 24/25 */
+#define BASEMODE_VDSL_PHY_3		BIT(9) /* GPIOs 26/27 */
+
+enum bcm63268_pinctrl_reg {
+	BCM63268_LEDCTRL,
+	BCM63268_MODE,
+	BCM63268_CTRL,
+	BCM63268_BASEMODE,
+};
+
+struct bcm63268_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm63268_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	enum bcm63268_pinctrl_reg reg;
+	u32 mask;
+};
+
+struct bcm63268_pinctrl {
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc desc;
+
+	void __iomem *led;
+	void __iomem *mode;
+	void __iomem *ctrl;
+	void __iomem *basemode;
+
+	/* register access lock */
+	spinlock_t lock;
+
+	struct gpio_chip gpio[2];
+};
+
+#define BCM63268_PIN(a, b, basemode)			\
+	{						\
+		.number = a,				\
+		.name = b,				\
+		.drv_data = (void *)(basemode)		\
+	}
+
+static const struct pinctrl_pin_desc bcm63268_pins[] = {
+	PINCTRL_PIN(0, "gpio0"),
+	PINCTRL_PIN(1, "gpio1"),
+	BCM63268_PIN(2, "gpio2", BASEMODE_NAND),
+	BCM63268_PIN(3, "gpio3", BASEMODE_NAND),
+	BCM63268_PIN(4, "gpio4", BASEMODE_NAND),
+	BCM63268_PIN(5, "gpio5", BASEMODE_NAND),
+	BCM63268_PIN(6, "gpio6", BASEMODE_NAND),
+	BCM63268_PIN(7, "gpio7", BASEMODE_NAND),
+	BCM63268_PIN(8, "gpio8", BASEMODE_DECTPD),
+	BCM63268_PIN(9, "gpio9", BASEMODE_DECTPD),
+	BCM63268_PIN(10, "gpio10", BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(11, "gpio11", BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(12, "gpio12", BASEMODE_VDSL_PHY_1),
+	BCM63268_PIN(13, "gpio13", BASEMODE_VDSL_PHY_1),
+	PINCTRL_PIN(14, "gpio14"),
+	PINCTRL_PIN(15, "gpio15"),
+	PINCTRL_PIN(16, "gpio16"),
+	PINCTRL_PIN(17, "gpio17"),
+	PINCTRL_PIN(18, "gpio18"),
+	PINCTRL_PIN(19, "gpio19"),
+	PINCTRL_PIN(20, "gpio20"),
+	PINCTRL_PIN(21, "gpio21"),
+	PINCTRL_PIN(22, "gpio22"),
+	PINCTRL_PIN(23, "gpio23"),
+	BCM63268_PIN(24, "gpio24", BASEMODE_NAND | BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(25, "gpio25", BASEMODE_NAND | BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(26, "gpio26", BASEMODE_NAND | BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(27, "gpio27", BASEMODE_NAND | BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(28, "gpio28", BASEMODE_NAND),
+	BCM63268_PIN(29, "gpio29", BASEMODE_NAND),
+	BCM63268_PIN(30, "gpio30", BASEMODE_NAND),
+	BCM63268_PIN(31, "gpio31", BASEMODE_NAND),
+	PINCTRL_PIN(32, "gpio32"),
+	PINCTRL_PIN(33, "gpio33"),
+	PINCTRL_PIN(34, "gpio34"),
+	PINCTRL_PIN(35, "gpio35"),
+	PINCTRL_PIN(36, "gpio36"),
+	PINCTRL_PIN(37, "gpio37"),
+	PINCTRL_PIN(38, "gpio38"),
+	PINCTRL_PIN(39, "gpio39"),
+	PINCTRL_PIN(40, "gpio40"),
+	PINCTRL_PIN(41, "gpio41"),
+	PINCTRL_PIN(42, "gpio42"),
+	PINCTRL_PIN(43, "gpio43"),
+	PINCTRL_PIN(44, "gpio44"),
+	PINCTRL_PIN(45, "gpio45"),
+	PINCTRL_PIN(46, "gpio46"),
+	PINCTRL_PIN(47, "gpio47"),
+	PINCTRL_PIN(48, "gpio48"),
+	PINCTRL_PIN(49, "gpio49"),
+	PINCTRL_PIN(50, "gpio50"),
+	PINCTRL_PIN(51, "gpio51"),
+};
+
+static unsigned gpio0_pins[] = { 0 };
+static unsigned gpio1_pins[] = { 1 };
+static unsigned gpio2_pins[] = { 2 };
+static unsigned gpio3_pins[] = { 3 };
+static unsigned gpio4_pins[] = { 4 };
+static unsigned gpio5_pins[] = { 5 };
+static unsigned gpio6_pins[] = { 6 };
+static unsigned gpio7_pins[] = { 7 };
+static unsigned gpio8_pins[] = { 8 };
+static unsigned gpio9_pins[] = { 9 };
+static unsigned gpio10_pins[] = { 10 };
+static unsigned gpio11_pins[] = { 11 };
+static unsigned gpio12_pins[] = { 12 };
+static unsigned gpio13_pins[] = { 13 };
+static unsigned gpio14_pins[] = { 14 };
+static unsigned gpio15_pins[] = { 15 };
+static unsigned gpio16_pins[] = { 16 };
+static unsigned gpio17_pins[] = { 17 };
+static unsigned gpio18_pins[] = { 18 };
+static unsigned gpio19_pins[] = { 19 };
+static unsigned gpio20_pins[] = { 20 };
+static unsigned gpio21_pins[] = { 21 };
+static unsigned gpio22_pins[] = { 22 };
+static unsigned gpio23_pins[] = { 23 };
+static unsigned gpio24_pins[] = { 24 };
+static unsigned gpio25_pins[] = { 25 };
+static unsigned gpio26_pins[] = { 26 };
+static unsigned gpio27_pins[] = { 27 };
+static unsigned gpio28_pins[] = { 28 };
+static unsigned gpio29_pins[] = { 29 };
+static unsigned gpio30_pins[] = { 30 };
+static unsigned gpio31_pins[] = { 31 };
+static unsigned gpio32_pins[] = { 32 };
+static unsigned gpio33_pins[] = { 33 };
+static unsigned gpio34_pins[] = { 34 };
+static unsigned gpio35_pins[] = { 35 };
+static unsigned gpio36_pins[] = { 36 };
+static unsigned gpio37_pins[] = { 37 };
+static unsigned gpio38_pins[] = { 38 };
+static unsigned gpio39_pins[] = { 39 };
+static unsigned gpio40_pins[] = { 40 };
+static unsigned gpio41_pins[] = { 41 };
+static unsigned gpio42_pins[] = { 42 };
+static unsigned gpio43_pins[] = { 43 };
+static unsigned gpio44_pins[] = { 44 };
+static unsigned gpio45_pins[] = { 45 };
+static unsigned gpio46_pins[] = { 46 };
+static unsigned gpio47_pins[] = { 47 };
+static unsigned gpio48_pins[] = { 48 };
+static unsigned gpio49_pins[] = { 49 };
+static unsigned gpio50_pins[] = { 50 };
+static unsigned gpio51_pins[] = { 51 };
+
+static unsigned nand_grp_pins[] = {
+	2, 3, 4, 5, 6, 7, 24,
+	25, 26, 27, 28, 29, 30, 31,
+};
+
+static unsigned dectpd_grp_pins[] = { 8, 9 };
+static unsigned vdsl_phy0_grp_pins[] = { 10, 11 };
+static unsigned vdsl_phy1_grp_pins[] = { 12, 13 };
+static unsigned vdsl_phy2_grp_pins[] = { 24, 25 };
+static unsigned vdsl_phy3_grp_pins[] = { 26, 27 };
+
+#define BCM63268_GROUP(n)					\
+	{							\
+		.name = #n,					\
+		.pins = n##_pins,				\
+		.num_pins = ARRAY_SIZE(n##_pins),		\
+	}
+
+static struct bcm63268_pingroup bcm63268_groups[] = {
+	BCM63268_GROUP(gpio0),
+	BCM63268_GROUP(gpio1),
+	BCM63268_GROUP(gpio2),
+	BCM63268_GROUP(gpio3),
+	BCM63268_GROUP(gpio4),
+	BCM63268_GROUP(gpio5),
+	BCM63268_GROUP(gpio6),
+	BCM63268_GROUP(gpio7),
+	BCM63268_GROUP(gpio8),
+	BCM63268_GROUP(gpio9),
+	BCM63268_GROUP(gpio10),
+	BCM63268_GROUP(gpio11),
+	BCM63268_GROUP(gpio12),
+	BCM63268_GROUP(gpio13),
+	BCM63268_GROUP(gpio14),
+	BCM63268_GROUP(gpio15),
+	BCM63268_GROUP(gpio16),
+	BCM63268_GROUP(gpio17),
+	BCM63268_GROUP(gpio18),
+	BCM63268_GROUP(gpio19),
+	BCM63268_GROUP(gpio20),
+	BCM63268_GROUP(gpio21),
+	BCM63268_GROUP(gpio22),
+	BCM63268_GROUP(gpio23),
+	BCM63268_GROUP(gpio24),
+	BCM63268_GROUP(gpio25),
+	BCM63268_GROUP(gpio26),
+	BCM63268_GROUP(gpio27),
+	BCM63268_GROUP(gpio28),
+	BCM63268_GROUP(gpio29),
+	BCM63268_GROUP(gpio30),
+	BCM63268_GROUP(gpio31),
+	BCM63268_GROUP(gpio32),
+	BCM63268_GROUP(gpio33),
+	BCM63268_GROUP(gpio34),
+	BCM63268_GROUP(gpio35),
+	BCM63268_GROUP(gpio36),
+	BCM63268_GROUP(gpio37),
+	BCM63268_GROUP(gpio38),
+	BCM63268_GROUP(gpio39),
+	BCM63268_GROUP(gpio40),
+	BCM63268_GROUP(gpio41),
+	BCM63268_GROUP(gpio42),
+	BCM63268_GROUP(gpio43),
+	BCM63268_GROUP(gpio44),
+	BCM63268_GROUP(gpio45),
+	BCM63268_GROUP(gpio46),
+	BCM63268_GROUP(gpio47),
+	BCM63268_GROUP(gpio48),
+	BCM63268_GROUP(gpio49),
+	BCM63268_GROUP(gpio50),
+	BCM63268_GROUP(gpio51),
+
+	/* multi pin groups */
+	BCM63268_GROUP(nand_grp),
+	BCM63268_GROUP(dectpd_grp),
+	BCM63268_GROUP(vdsl_phy0_grp),
+	BCM63268_GROUP(vdsl_phy1_grp),
+	BCM63268_GROUP(vdsl_phy2_grp),
+	BCM63268_GROUP(vdsl_phy3_grp),
+};
+
+static const char * const led_groups[] = {
+	"gpio0",
+	"gpio1",
+	"gpio2",
+	"gpio3",
+	"gpio4",
+	"gpio5",
+	"gpio6",
+	"gpio7",
+	"gpio8",
+	"gpio9",
+	"gpio10",
+	"gpio11",
+	"gpio12",
+	"gpio13",
+	"gpio14",
+	"gpio15",
+	"gpio16",
+	"gpio17",
+	"gpio18",
+	"gpio19",
+	"gpio20",
+	"gpio21",
+	"gpio22",
+	"gpio23",
+};
+
+static const char * const serial_led_clk_groups[] = {
+	"gpio0",
+};
+
+static const char * const serial_led_data_groups[] = {
+	"gpio1",
+};
+
+static const char * const hsspi_cs4_groups[] = {
+	"gpio16",
+};
+
+static const char * const hsspi_cs5_groups[] = {
+	"gpio17",
+};
+
+static const char * const hsspi_cs6_groups[] = {
+	"gpio8",
+};
+
+static const char * const hsspi_cs7_groups[] = {
+	"gpio9",
+};
+
+static const char * const uart1_scts_groups[] = {
+	"gpio10",
+	"gpio24",
+};
+
+static const char * const uart1_srts_groups[] = {
+	"gpio11",
+	"gpio25",
+};
+
+static const char * const uart1_sdin_groups[] = {
+	"gpio12",
+	"gpio26",
+};
+
+static const char * const uart1_sdout_groups[] = {
+	"gpio13",
+	"gpio27",
+};
+
+static const char * const ntr_pulse_in_groups[] = {
+	"gpio14",
+	"gpio28",
+};
+
+static const char * const dsl_ntr_pulse_out_groups[] = {
+	"gpio15",
+	"gpio29",
+};
+
+static const char * const adsl_spi_miso_groups[] = {
+	"gpio18",
+};
+
+static const char * const adsl_spi_mosi_groups[] = {
+	"gpio19",
+};
+
+static const char * const vreg_clk_groups[] = {
+	"gpio22",
+};
+
+static const char * const pcie_clkreq_b_groups[] = {
+	"gpio23",
+};
+
+static const char * const switch_led_clk_groups[] = {
+	"gpio30",
+};
+
+static const char * const switch_led_data_groups[] = {
+	"gpio31",
+};
+
+static const char * const wifi_groups[] = {
+	"gpio32",
+	"gpio33",
+	"gpio34",
+	"gpio35",
+	"gpio36",
+	"gpio37",
+	"gpio38",
+	"gpio39",
+	"gpio40",
+	"gpio41",
+	"gpio42",
+	"gpio43",
+	"gpio44",
+	"gpio45",
+	"gpio46",
+	"gpio47",
+	"gpio48",
+	"gpio49",
+	"gpio50",
+	"gpio51",
+};
+
+static const char * const nand_groups[] = {
+	"nand_grp",
+};
+
+static const char * const dectpd_groups[] = {
+	"dectpd_grp",
+};
+
+static const char * const vdsl_phy_override_0_groups[] = {
+	"vdsl_phy_override_0_grp",
+};
+
+static const char * const vdsl_phy_override_1_groups[] = {
+	"vdsl_phy_override_1_grp",
+};
+
+static const char * const vdsl_phy_override_2_groups[] = {
+	"vdsl_phy_override_2_grp",
+};
+
+static const char * const vdsl_phy_override_3_groups[] = {
+	"vdsl_phy_override_3_grp",
+};
+
+#define BCM63268_LED_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM63268_LEDCTRL,		\
+	}
+
+#define BCM63268_MODE_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM63268_MODE,			\
+	}
+
+#define BCM63268_CTRL_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM63268_CTRL,			\
+	}
+
+#define BCM63268_BASEMODE_FUN(n, val)			\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.reg = BCM63268_BASEMODE,		\
+		.mask = val,				\
+	}
+
+static const struct bcm63268_function bcm63268_funcs[] = {
+	BCM63268_LED_FUN(led),
+	BCM63268_MODE_FUN(serial_led_clk),
+	BCM63268_MODE_FUN(serial_led_data),
+	BCM63268_MODE_FUN(hsspi_cs6),
+	BCM63268_MODE_FUN(hsspi_cs7),
+	BCM63268_MODE_FUN(uart1_scts),
+	BCM63268_MODE_FUN(uart1_srts),
+	BCM63268_MODE_FUN(uart1_sdin),
+	BCM63268_MODE_FUN(uart1_sdout),
+	BCM63268_MODE_FUN(ntr_pulse_in),
+	BCM63268_MODE_FUN(dsl_ntr_pulse_out),
+	BCM63268_MODE_FUN(hsspi_cs4),
+	BCM63268_MODE_FUN(hsspi_cs5),
+	BCM63268_MODE_FUN(adsl_spi_miso),
+	BCM63268_MODE_FUN(adsl_spi_mosi),
+	BCM63268_MODE_FUN(vreg_clk),
+	BCM63268_MODE_FUN(pcie_clkreq_b),
+	BCM63268_MODE_FUN(switch_led_clk),
+	BCM63268_MODE_FUN(switch_led_data),
+	BCM63268_CTRL_FUN(wifi),
+	BCM63268_BASEMODE_FUN(nand, BASEMODE_NAND),
+	BCM63268_BASEMODE_FUN(dectpd, BASEMODE_DECTPD),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_0, BASEMODE_VDSL_PHY_0),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_1, BASEMODE_VDSL_PHY_1),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_2, BASEMODE_VDSL_PHY_2),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_3, BASEMODE_VDSL_PHY_3),
+};
+
+static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm63268_groups);
+}
+
+static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						   unsigned group)
+{
+	return bcm63268_groups[group].name;
+}
+
+static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					   unsigned group,
+					   const unsigned **pins,
+					   unsigned *num_pins)
+{
+	*pins = bcm63268_groups[group].pins;
+	*num_pins = bcm63268_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm63268_funcs);
+}
+
+static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						  unsigned selector)
+{
+	return bcm63268_funcs[selector].name;
+}
+
+static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				       unsigned selector,
+				       const char * const **groups,
+				       unsigned * const num_groups)
+{
+	*groups = bcm63268_funcs[selector].groups;
+	*num_groups = bcm63268_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static void bcm63268_rmw_mux(struct bcm63268_pinctrl *pctl, void __iomem *reg,
+			     u32 mask, u32 val)
+{
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+	tmp = __raw_readl(reg);
+	tmp &= ~mask;
+	tmp |= val;
+	__raw_writel(tmp, reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static void bcm63268_set_gpio(struct bcm63268_pinctrl *pctl, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
+	u32 basemode = (unsigned long)desc->drv_data;
+	u32 mask = BIT(pin % 32);
+
+	if (basemode)
+		bcm63268_rmw_mux(pctl, pctl->basemode, basemode, 0);
+
+	if (pin < 32) {
+		/* base mode: 0 => gpio, 1 => mux function */
+		bcm63268_rmw_mux(pctl, pctl->mode, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < 24)
+			bcm63268_rmw_mux(pctl, pctl->led, mask, 0);
+	} else if (pin < 52) {
+		/* ctrl reg: 0 => wifi function, 1 => gpio */
+		bcm63268_rmw_mux(pctl, pctl->ctrl, mask, mask);
+	}
+}
+
+static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				    unsigned selector, unsigned group)
+{
+	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm63268_pingroup *grp = &bcm63268_groups[group];
+	const struct bcm63268_function *f = &bcm63268_funcs[selector];
+	unsigned i;
+	void __iomem *reg;
+	u32 val, mask;
+
+	for (i = 0; i < grp->num_pins; i++)
+		bcm63268_set_gpio(pctl, grp->pins[i]);
+
+	switch (f->reg) {
+	case BCM63268_LEDCTRL:
+		reg = pctl->led;
+		mask = BIT(grp->pins[0]);
+		val = BIT(grp->pins[0]);
+		break;
+	case BCM63268_MODE:
+		reg = pctl->mode;
+		mask = BIT(grp->pins[0]);
+		val = BIT(grp->pins[0]);
+		break;
+	case BCM63268_CTRL:
+		reg = pctl->ctrl;
+		mask = BIT(grp->pins[0]);
+		val = 0;
+		break;
+	case BCM63268_BASEMODE:
+		reg = pctl->basemode;
+		mask = f->mask;
+		val = f->mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	bcm63268_rmw_mux(pctl, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned offset)
+{
+	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm63268_set_gpio(pctl, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm63268_pctl_ops = {
+	.get_groups_count	= bcm63268_pinctrl_get_group_count,
+	.get_group_name		= bcm63268_pinctrl_get_group_name,
+	.get_group_pins		= bcm63268_pinctrl_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map		= pinctrl_utils_free_map,
+#endif
+};
+
+static struct pinmux_ops bcm63268_pmx_ops = {
+	.get_functions_count	= bcm63268_pinctrl_get_func_count,
+	.get_function_name	= bcm63268_pinctrl_get_func_name,
+	.get_function_groups	= bcm63268_pinctrl_get_groups,
+	.set_mux		= bcm63268_pinctrl_set_mux,
+	.gpio_request_enable	= bcm63268_gpio_request_enable,
+	.strict			= true,
+};
+
+static int bcm63268_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm63268_pinctrl *pctl;
+	struct resource *res;
+	void __iomem *led, *mode, *ctrl, *basemode;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led");
+	led = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(led))
+		return PTR_ERR(led);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
+	mode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mode))
+		return PTR_ERR(mode);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+	ctrl = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode");
+	basemode = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(basemode))
+		return PTR_ERR(basemode);
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	spin_lock_init(&pctl->lock);
+
+	pctl->led = led;
+	pctl->mode = mode;
+	pctl->ctrl = ctrl;
+	pctl->basemode = basemode;
+
+	pctl->desc.name = dev_name(&pdev->dev);
+	pctl->desc.owner = THIS_MODULE;
+	pctl->desc.pctlops = &bcm63268_pctl_ops;
+	pctl->desc.pmxops = &bcm63268_pmx_ops;
+
+	pctl->desc.npins = ARRAY_SIZE(bcm63268_pins);
+	pctl->desc.pins = bcm63268_pins;
+
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
+						 pctl->gpio, BCM63268_NGPIO);
+	if (IS_ERR(pctl->pctldev))
+		return PTR_ERR(pctl->pctldev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm63268_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm63268-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm63268_pinctrl_driver = {
+	.probe = bcm63268_pinctrl_probe,
+	.driver = {
+		.name = "bcm63268-pinctrl",
+		.of_match_table = bcm63268_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm63268_pinctrl_driver);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation
  2016-08-19 10:53   ` [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation Jonas Gorski
@ 2016-08-19 14:14     ` Rob Herring
  2016-08-19 14:30       ` Jonas Gorski
  0 siblings, 1 reply; 36+ messages in thread
From: Rob Herring @ 2016-08-19 14:14 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, Linus Walleij, devicetree, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53:34PM +0200, Jonas Gorski wrote:
> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> 
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> ---
>  .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      | 61 ++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
> new file mode 100644
> index 0000000..401224e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
> @@ -0,0 +1,61 @@
> +* Broadcom BCM6328 pin controller
> +
> +Required properties:
> +- compatible: Must be "brcm,bcm6328-pinctrl".
> +- reg: Register specifies of dirout, dat, mode, mux registers.
> +- reg-names: Must be "dirout", "dat", "mode", "mux".
> +- gpio-controller: Identifies this node as a GPIO controller.
> +- #gpio-cells: Must be <2>.
> +
> +Example:
> +
> +pinctrl: pin-controller@10000080 {
> +	compatible = "brcm,bcm6328-pinctrl";
> +	reg = <0x10000080 0x8>,
> +	      <0x10000088 0x8>,
> +	      <0x10000098 0x4>,
> +	      <0x1000009c 0xc>;
> +	reg-names = "dirout", "dat", "mode", "mux";

What's in the holes? Just do one range or perhaps this should be part of 
some larger block.

Rob

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation
  2016-08-19 14:14     ` Rob Herring
@ 2016-08-19 14:30       ` Jonas Gorski
       [not found]         ` <CAOiHx=mLgZ6Q3tBY3zYkCpMX09Kv54OQQoAXAdP16D_xoXO3mg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-19 14:30 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-gpio, Linus Walleij, devicetree, Mark Rutland,
	Kevin Cernekee, Florian Fainelli, Álvaro Fernández

Hi

On 19 August 2016 at 16:14, Rob Herring <robh@kernel.org> wrote:
> On Fri, Aug 19, 2016 at 12:53:34PM +0200, Jonas Gorski wrote:
>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>
>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>> ---
>>  .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      | 61 ++++++++++++++++++++++
>>  1 file changed, 61 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
>> new file mode 100644
>> index 0000000..401224e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
>> @@ -0,0 +1,61 @@
>> +* Broadcom BCM6328 pin controller
>> +
>> +Required properties:
>> +- compatible: Must be "brcm,bcm6328-pinctrl".
>> +- reg: Register specifies of dirout, dat, mode, mux registers.
>> +- reg-names: Must be "dirout", "dat", "mode", "mux".
>> +- gpio-controller: Identifies this node as a GPIO controller.
>> +- #gpio-cells: Must be <2>.
>> +
>> +Example:
>> +
>> +pinctrl: pin-controller@10000080 {
>> +     compatible = "brcm,bcm6328-pinctrl";
>> +     reg = <0x10000080 0x8>,
>> +           <0x10000088 0x8>,
>> +           <0x10000098 0x4>,
>> +           <0x1000009c 0xc>;
>> +     reg-names = "dirout", "dat", "mode", "mux";
>
> What's in the holes? Just do one range or perhaps this should be part of
> some larger block.

For this particular SoC it's SPI Slave Config; Registers found in the
holes on other SoCs:

* TestControl
* OscControl (just the name, no other documentation what it does)
* Switch LED control (for integrated switches)
* Legacy LED controller
* Reset Controller for the VDSL PHY

And there are also usually quite a few other registers on this block.
This seems to have been treated as a "GPIO and everything else that
isn't large enough for its own block" by Broadcom - with BCM6328/6362
they even introduced a "MISC" block then.


Jonas

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 01/13] pinctrl: add bcm63xx base code
  2016-08-19 10:53   ` [PATCH 01/13] pinctrl: add bcm63xx base code Jonas Gorski
@ 2016-08-22 12:46     ` Linus Walleij
       [not found]       ` <CACRpkdbAWJruB=4rv_SoPZ5D5XgWjebK_Qmv2GLgOOrSyqXcDA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 12:46 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:

> Setup directory and add a helper for bcm63xx pinctrl support.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>

>  drivers/pinctrl/bcm63xx/Kconfig           |   3 +
>  drivers/pinctrl/bcm63xx/Makefile          |   1 +

Why not just put it in the existing pinctrl/bcm directory?

The drivers in there share nothing but being Broadcom
anyways. And when you're at it, do take a look at the
other Broadcom drivers to check if they would
happen to share something with your hardware, I find
it dazzling that hardware engineers repeatedly reinvents
pin controllers but what can I do.

> +config PINCTRL_BCM63XX
> +       bool
> +       select GPIO_GENERIC

depends on ARCH_****?

depends on OF_GPIO?

Will it really be used on non-DT systems?

> +#define BANK_SIZE      sizeof(u32)
> +#define PINS_PER_BANK  (BANK_SIZE * BITS_PER_BYTE)
> +
> +#ifdef CONFIG_OF
> +static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc,
> +                                const struct of_phandle_args *gpiospec,
> +                                u32 *flags)
> +{
> +       struct gpio_chip *base = gpiochip_get_data(gc);
> +       int pin = gpiospec->args[0];
> +
> +       if (gc != &base[pin / PINS_PER_BANK])
> +               return -EINVAL;
> +
> +       pin = pin % PINS_PER_BANK;
> +
> +       if (pin >= gc->ngpio)
> +               return -EINVAL;
> +
> +       if (flags)
> +               *flags = gpiospec->args[1];
> +
> +       return pin;
> +}
> +#endif

- Do you really have to support the !OF_GPIO case? (depend in Kconfig,
  get rid of #ifdef)

- The only reason for not using of_gpio_simple_xlate() seems to be that
  you have several GPIO banks. So why not model every bank as a
  separate device? Or did you consider this already?

> +               gc[i].request = gpiochip_generic_request;
> +               gc[i].free = gpiochip_generic_free;
> +
> +#ifdef CONFIG_OF
> +               gc[i].of_gpio_n_cells = 2;
> +               gc[i].of_xlate = bcm63xx_gpio_of_xlate;
> +#endif
> +
> +               gc[i].label = label;
> +               gc[i].ngpio = pins;
> +
> +               devm_gpiochip_add_data(dev, &gc[i], gc);

Because this also gets pretty hairy... since you don't have one device
per gpiochip.

> +static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name,
> +                                   int ngpio)
> +{
> +       int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
> +
> +       for (i = 0; i < chips; i++) {
> +               int offset, pins;
> +
> +               offset = i * PINS_PER_BANK;
> +               pins = min_t(int, ngpio - offset, PINS_PER_BANK);
> +
> +               gpiochip_add_pin_range(&gc[i], name, 0, offset, pins);
> +       }
> +}

And this, same thing. Could be so much easier if it was just the same
driver instantiated twice for two banks.

> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout");
> +       dirout = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(dirout))
> +               return ERR_CAST(dirout);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
> +       data = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(data))
> +               return ERR_CAST(data);
> +
> +       sz = resource_size(res);
> +
> +       ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       pctldev = devm_pinctrl_register(&pdev->dev, desc, priv);
> +       if (IS_ERR(pctldev))
> +               return pctldev;
> +
> +       bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio);
> +
> +       dev_info(&pdev->dev, "registered at mmio %p\n", dirout);
> +
> +       return pctldev;

A current trend in simple MMIO devices is to simply add themselves as a
compatible string in drivers/gpio/gpio-mmio.c. Example:

https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-gpio.git/commit/drivers/gpio/gpio-mmio.c?h=devel&id=05cc995f4d44c2b14a1f15f3271cc9715cb81099

This could be a viable approach if you find a way to flag that such a GPIO
has a pin control backend.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation
       [not found]         ` <CAOiHx=mLgZ6Q3tBY3zYkCpMX09Kv54OQQoAXAdP16D_xoXO3mg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-08-22 12:51           ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 12:51 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Rutland, Kevin Cernekee,
	Florian Fainelli, Álvaro Fernández

On Fri, Aug 19, 2016 at 4:30 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On 19 August 2016 at 16:14, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

>>> +pinctrl: pin-controller@10000080 {
>>> +     compatible = "brcm,bcm6328-pinctrl";
>>> +     reg = <0x10000080 0x8>,
>>> +           <0x10000088 0x8>,
>>> +           <0x10000098 0x4>,
>>> +           <0x1000009c 0xc>;
>>> +     reg-names = "dirout", "dat", "mode", "mux";
>>
>> What's in the holes? Just do one range or perhaps this should be part of
>> some larger block.
>
> For this particular SoC it's SPI Slave Config; Registers found in the
> holes on other SoCs:
>
> * TestControl
> * OscControl (just the name, no other documentation what it does)
> * Switch LED control (for integrated switches)
> * Legacy LED controller
> * Reset Controller for the VDSL PHY
>
> And there are also usually quite a few other registers on this block.
> This seems to have been treated as a "GPIO and everything else that
> isn't large enough for its own block" by Broadcom - with BCM6328/6362
> they even introduced a "MISC" block then.

What I would do myself is to put a syscon over this node.

syscon: syscon@10000080 {
    compatible = "broadcom,foo", "syscon";
    reg = <0x10000000 0x100>;
(...)

Or however that looks.

Then use the generic GPIO syscon driver on top of this,
see drivers/gpio/gpio-syscon.c

That driver does not support any pincontrol/muxing but
is a good candidate to handle the GPIO portions.

Syscons are there to handle these composite "misc sys
regs" devices.

You can even spawn subdevices to it by adding the
compatible-string "mfd-simple".

The rest of the subdevices would also have to be syscon
children.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328
  2016-08-19 10:53 ` [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328 Jonas Gorski
@ 2016-08-22 13:15   ` Linus Walleij
       [not found]     ` <CACRpkdbZDmHimo9K1rUcs-4MyOSZH5SHUD3kuSYANppLUU0WwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:15 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:

> Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as
> GPIOs, as LEDs for the integrated LED controller, or various other
> functions. Its pincontrol mux registers also control other aspects, like
> switching the second USB port between host and device mode.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>

This looks good. Just thinking following the other patches
that maybe this should be a syscon child driver.

> +#define BCM6328_NGPIO          32

I wonder why the pin control driver cares about that?

> +struct bcm6328_pinctrl {
> +       struct pinctrl_dev *pctldev;
> +       struct pinctrl_desc desc;
> +
> +       void __iomem *mode;
> +       void __iomem *mux[3];
> +
> +       /* register access lock */
> +       spinlock_t lock;
> +
> +       struct gpio_chip gpio;

Usually this should be the other way around: the gpio_chip
knows about the pin controller, the pin controller does not
know about the gpio_chip.

I don't see it used in the code either? Artifact?

> +static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pctl, unsigned pin,
> +                           u32 mode, u32 mux)
> +{
> +       unsigned long flags;
> +       u32 reg;
> +
> +       spin_lock_irqsave(&pctl->lock, flags);
> +       if (pin < 32) {
> +               reg = __raw_readl(pctl->mode);
> +               reg &= ~BIT(pin);
> +               if (mode)
> +                       reg |= BIT(pin);
> +               __raw_writel(reg, pctl->mode);
> +       }
> +
> +       reg = __raw_readl(pctl->mux[pin / 16]);
> +       reg &= ~(3UL << (pin % 16));
> +       reg |= mux << (pin % 16);
> +       __raw_writel(reg, pctl->mux[pin / 16]);
> +
> +       spin_unlock_irqrestore(&pctl->lock, flags);
> +}

Why all this __raw_* accessors? What is wrong with readl_relaxed()
and writel_relaxed()? Or MIPS doesn't have them?

> +#ifdef CONFIG_OF
> +       .dt_node_to_map         = pinconf_generic_dt_node_to_map_pin,
> +       .dt_free_map            = pinctrl_utils_free_map,
> +#endif

Nice, but why not just add
depends on OF
to the Kconfig and get rid of the #ifdef?

> +static int bcm6328_pinctrl_probe(struct platform_device *pdev)
> +{
> +       struct bcm6328_pinctrl *pctl;
> +       struct resource *res;
> +       void __iomem *mode, *mux;
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
> +       mode = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(mode))
> +               return PTR_ERR(mode);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
> +       mux = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(mux))
> +               return PTR_ERR(mux);

This mishmash of remap windows makes me prefer the syscon
design pattern.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation
  2016-08-19 10:53 ` [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation Jonas Gorski
@ 2016-08-22 13:17   ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:17 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:

> Add binding documentation for the pincontrol core found in BCM6348 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>

(...)
> +pinctrl: pin-controller@fffe0080 {
> +       compatible = "brcm,bcm6348-pinctrl";
> +       reg = <0xfffe0080 0x8>,
> +             <0xfffe0088 0x8>,
> +             <0xfffe0098 0x4>;
> +       reg-names = "dirout", "dat", "mode";
> +
> +       gpio-controller;
> +       #gpio-cells = <2>;
> +};

So I would prefer if you create a syscon with two
children: the pin controller and the GPIO(s) as
separate devices using "syscon", "mfd-simple" as
compatible on the top node.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 05/13] pinctrl: add a pincontrol driver for BCM6348
       [not found]     ` <1471604025-21575-6-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:19       ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:19 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add a pincotrol driver for BCM6348. BCM6348 allow muxing five groups of
> up to ten gpios into fourteen potential functions. It does not allow
> muxing individual pins. Some functions require more than one group to be
> muxed to the same function.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
(...)

> +#define BCM6348_NGPIO          37
(...)
> +       struct gpio_chip gpio[2];

Seems unused.

> +static void bcm6348_rmw_mux(struct bcm6348_pinctrl *pctl, u32 mask, u32 val)
> +{
> +       unsigned long flags;
> +       u32 reg;
> +
> +       spin_lock_irqsave(&pctl->lock, flags);
> +
> +       reg = __raw_readl(pctl->mode);
> +       reg &= ~mask;
> +       reg |= val & mask;
> +       __raw_writel(reg, pctl->mode);
> +
> +       spin_unlock_irqrestore(&pctl->lock, flags);
> +}

Same comment as before on readl/writel_relaxed() to
be used rather than __raw_*.

> +#ifdef CONFIG_OF
> +       .dt_node_to_map         = pinconf_generic_dt_node_to_map_pin,
> +       .dt_free_map            = pinctrl_utils_free_map,
> +#endif

Same comment about depending on OF.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 06/13] Documentation: add BCM6358 pincontroller binding documentation
       [not found]     ` <1471604025-21575-7-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:20       ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:20 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add binding documentation for the pincontrol core found in BCM6358 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comment as other binding patch.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358
  2016-08-19 10:53 ` [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358 Jonas Gorski
@ 2016-08-22 13:21   ` Linus Walleij
  2016-08-22 13:57     ` Jonas Gorski
  0 siblings, 1 reply; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:21 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:

> Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different
> functions onto the GPIO pins. It does not support configuring individual
> pins but only whole groups. These groups may overlap, and still require
> the directions to be set correctly in the GPIO register. In addition the
> functions register controls other, not directly mux related functions.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>

> +       if (pdev->dev.of_node)
> +               mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> +                                                      "brcm,gpiomode");


This seems to be using syscon, albeit for something else.

> +       else
> +               mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");

That looks very very fragile.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 08/13] Documentation: add BCM6362 pincontroller binding documentation
       [not found]   ` <1471604025-21575-9-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:22     ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:22 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add binding documentation for the pincontrol core found in BCM6362 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comments as the other bindings.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 09/13] pinctrl: add a pincontrol driver for BCM6362
       [not found]   ` <1471604025-21575-10-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:23     ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:23 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual
> GPIO pins to the LED controller, to be available by the integrated
> wifi, or other functions. It also supports overlay groups, of which
> only NAND is documented.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comments as the other driver patches.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 10/13] Documentation: add BCM6368 pincontroller binding documentation
       [not found]   ` <1471604025-21575-11-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:24     ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:24 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add binding documentation for the pincontrol core found in BCM6368 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comments as other binding patches.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 11/13] pinctrl: add a pincontrol driver for BCM6368
       [not found]     ` <1471604025-21575-12-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:25       ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:25 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32
> GPIOs onto alternative functions. Not all are documented.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comments as other driver patches.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 12/13] Documentation: add BCM63268 pincontroller binding documentation
  2016-08-19 10:53 ` [PATCH 12/13] Documentation: add BCM63268 pincontroller binding documentation Jonas Gorski
@ 2016-08-22 13:25   ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:25 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:

> Add binding documentation for the pincontrol core found in the BCM63268
> family SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>

Same comments as the other binding patches.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 13/13] pinctrl: add a pincontrol driver for BCM63268
       [not found]     ` <1471604025-21575-14-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2016-08-22 13:26       ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-22 13:26 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs
> to different functions. Depending on the mux, these are either single
> pin configurations or whole pin groups.
>
> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Same comments as the other driver patches.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 01/13] pinctrl: add bcm63xx base code
       [not found]       ` <CACRpkdbAWJruB=4rv_SoPZ5D5XgWjebK_Qmv2GLgOOrSyqXcDA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-08-22 13:44         ` Jonas Gorski
  2016-08-23  9:15           ` Linus Walleij
  0 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-22 13:44 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Hi,

On 22 August 2016 at 14:46, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> Setup directory and add a helper for bcm63xx pinctrl support.
>>
>> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
>>  drivers/pinctrl/bcm63xx/Kconfig           |   3 +
>>  drivers/pinctrl/bcm63xx/Makefile          |   1 +
>
> Why not just put it in the existing pinctrl/bcm directory?

Because at the time I started writing these drivers it was still
exclusive for ARCH_BCM, will move them there.

> The drivers in there share nothing but being Broadcom
> anyways. And when you're at it, do take a look at the
> other Broadcom drivers to check if they would
> happen to share something with your hardware, I find
> it dazzling that hardware engineers repeatedly reinvents
> pin controllers but what can I do.
>
>> +config PINCTRL_BCM63XX
>> +       bool
>> +       select GPIO_GENERIC
>
> depends on ARCH_****?

This isn't a user selectable symbol so I don't see the need for that.

>
> depends on OF_GPIO?
>
> Will it really be used on non-DT systems?

I plan to use it on both mips/bcm63xx (no dts support) and bmips (dts
support), so yes.

>
>> +#define BANK_SIZE      sizeof(u32)
>> +#define PINS_PER_BANK  (BANK_SIZE * BITS_PER_BYTE)
>> +
>> +#ifdef CONFIG_OF
>> +static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc,
>> +                                const struct of_phandle_args *gpiospec,
>> +                                u32 *flags)
>> +{
>> +       struct gpio_chip *base = gpiochip_get_data(gc);
>> +       int pin = gpiospec->args[0];
>> +
>> +       if (gc != &base[pin / PINS_PER_BANK])
>> +               return -EINVAL;
>> +
>> +       pin = pin % PINS_PER_BANK;
>> +
>> +       if (pin >= gc->ngpio)
>> +               return -EINVAL;
>> +
>> +       if (flags)
>> +               *flags = gpiospec->args[1];
>> +
>> +       return pin;
>> +}
>> +#endif
>
> - Do you really have to support the !OF_GPIO case? (depend in Kconfig,
>   get rid of #ifdef)

See above.

>
> - The only reason for not using of_gpio_simple_xlate() seems to be that
>   you have several GPIO banks. So why not model every bank as a
>   separate device? Or did you consider this already?

I did consider it, but it makes the !OF case more complicated, and the
current of_gpio base code requires changing for it.

That's because some of the pinctrl chips need to set the
gpio-direction for muxes, and for that need to have a reference to the
gpio-controller(s). Since any muxes directly tied to the controller
node will get applied as soon as the controller is registered, it
needs to aquire the gpio-controller references first.

On the gpio-controller side, to flag these a requiring pinctrl those
would then have a gpio-range property, which will cause the probe
being deferred until the reference to the controller can be resolved.
Which waits for the gpio-controller to be registered, so it can
resolve its references to it. A true catch 22 ;-)

This could probably resolved by deferring resolving node-to-pincontrol
devices to gpio request time. Not sure if this then would conflict
which gpio-hogs on such a gpio-controller node?

I haven't really thought how much work it would be for the !OF case,
but would probably mean I need to acquire references based on their
pdev names.

>> +               gc[i].request = gpiochip_generic_request;
>> +               gc[i].free = gpiochip_generic_free;
>> +
>> +#ifdef CONFIG_OF
>> +               gc[i].of_gpio_n_cells = 2;
>> +               gc[i].of_xlate = bcm63xx_gpio_of_xlate;
>> +#endif
>> +
>> +               gc[i].label = label;
>> +               gc[i].ngpio = pins;
>> +
>> +               devm_gpiochip_add_data(dev, &gc[i], gc);
>
> Because this also gets pretty hairy... since you don't have one device
> per gpiochip.
>
>> +static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name,
>> +                                   int ngpio)
>> +{
>> +       int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
>> +
>> +       for (i = 0; i < chips; i++) {
>> +               int offset, pins;
>> +
>> +               offset = i * PINS_PER_BANK;
>> +               pins = min_t(int, ngpio - offset, PINS_PER_BANK);
>> +
>> +               gpiochip_add_pin_range(&gc[i], name, 0, offset, pins);
>> +       }
>> +}
>
> And this, same thing. Could be so much easier if it was just the same
> driver instantiated twice for two banks.
>
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout");
>> +       dirout = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(dirout))
>> +               return ERR_CAST(dirout);
>> +
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
>> +       data = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(data))
>> +               return ERR_CAST(data);
>> +
>> +       sz = resource_size(res);
>> +
>> +       ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio);
>> +       if (ret)
>> +               return ERR_PTR(ret);
>> +
>> +       pctldev = devm_pinctrl_register(&pdev->dev, desc, priv);
>> +       if (IS_ERR(pctldev))
>> +               return pctldev;
>> +
>> +       bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio);
>> +
>> +       dev_info(&pdev->dev, "registered at mmio %p\n", dirout);
>> +
>> +       return pctldev;
>
> A current trend in simple MMIO devices is to simply add themselves as a
> compatible string in drivers/gpio/gpio-mmio.c. Example:
>
> https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-gpio.git/commit/drivers/gpio/gpio-mmio.c?h=devel&id=05cc995f4d44c2b14a1f15f3271cc9715cb81099
>
> This could be a viable approach if you find a way to flag that such a GPIO
> has a pin control backend.

The most obvious would be having a gpio-ranges property, but this
leads to issues mentioned above. And only works for OF.


Regards
Jonas
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328
       [not found]     ` <CACRpkdbZDmHimo9K1rUcs-4MyOSZH5SHUD3kuSYANppLUU0WwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-08-22 13:54       ` Jonas Gorski
  2016-08-23  8:57         ` Linus Walleij
  0 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-22 13:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On 22 August 2016 at 15:15, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as
>> GPIOs, as LEDs for the integrated LED controller, or various other
>> functions. Its pincontrol mux registers also control other aspects, like
>> switching the second USB port between host and device mode.
>>
>> Signed-off-by: Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> This looks good. Just thinking following the other patches
> that maybe this should be a syscon child driver.
>
>> +#define BCM6328_NGPIO          32
>
> I wonder why the pin control driver cares about that?
>
>> +struct bcm6328_pinctrl {
>> +       struct pinctrl_dev *pctldev;
>> +       struct pinctrl_desc desc;
>> +
>> +       void __iomem *mode;
>> +       void __iomem *mux[3];
>> +
>> +       /* register access lock */
>> +       spinlock_t lock;
>> +
>> +       struct gpio_chip gpio;
>
> Usually this should be the other way around: the gpio_chip
> knows about the pin controller, the pin controller does not
> know about the gpio_chip.
>
> I don't see it used in the code either? Artifact?

That's because some of the drivers require it, and kept it here so to
keep the drivers as similar as possible.

>> +static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pctl, unsigned pin,
>> +                           u32 mode, u32 mux)
>> +{
>> +       unsigned long flags;
>> +       u32 reg;
>> +
>> +       spin_lock_irqsave(&pctl->lock, flags);
>> +       if (pin < 32) {
>> +               reg = __raw_readl(pctl->mode);
>> +               reg &= ~BIT(pin);
>> +               if (mode)
>> +                       reg |= BIT(pin);
>> +               __raw_writel(reg, pctl->mode);
>> +       }
>> +
>> +       reg = __raw_readl(pctl->mux[pin / 16]);
>> +       reg &= ~(3UL << (pin % 16));
>> +       reg |= mux << (pin % 16);
>> +       __raw_writel(reg, pctl->mux[pin / 16]);
>> +
>> +       spin_unlock_irqrestore(&pctl->lock, flags);
>> +}
>
> Why all this __raw_* accessors? What is wrong with readl_relaxed()
> and writel_relaxed()? Or MIPS doesn't have them?

BCM63XX is one of those weird targets that are usually big endian, and
there are no native endian / big endian *_relaxed() accessors.

>
>> +#ifdef CONFIG_OF
>> +       .dt_node_to_map         = pinconf_generic_dt_node_to_map_pin,
>> +       .dt_free_map            = pinctrl_utils_free_map,
>> +#endif
>
> Nice, but why not just add
> depends on OF
> to the Kconfig and get rid of the #ifdef?

As mentioned for the generic part, I want to use it on a !OF target as well.

>
>> +static int bcm6328_pinctrl_probe(struct platform_device *pdev)
>> +{
>> +       struct bcm6328_pinctrl *pctl;
>> +       struct resource *res;
>> +       void __iomem *mode, *mux;
>> +
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
>> +       mode = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(mode))
>> +               return PTR_ERR(mode);
>> +
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
>> +       mux = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(mux))
>> +               return PTR_ERR(mux);
>
> This mishmash of remap windows makes me prefer the syscon
> design pattern.

At least for this one I would still need to have multiple syscons
because there already is one OF enabled driver that uses a non-syscon
access to drivers within this range.


Regards
Jonas
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358
  2016-08-22 13:21   ` Linus Walleij
@ 2016-08-22 13:57     ` Jonas Gorski
  2016-08-23  9:18       ` Linus Walleij
  0 siblings, 1 reply; 36+ messages in thread
From: Jonas Gorski @ 2016-08-22 13:57 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

Hi

On 22 August 2016 at 15:21, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
>
>> Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different
>> functions onto the GPIO pins. It does not support configuring individual
>> pins but only whole groups. These groups may overlap, and still require
>> the directions to be set correctly in the GPIO register. In addition the
>> functions register controls other, not directly mux related functions.
>>
>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>
>> +       if (pdev->dev.of_node)
>> +               mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
>> +                                                      "brcm,gpiomode");
>
>
> This seems to be using syscon, albeit for something else.
>
>> +       else
>> +               mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");
>
> That looks very very fragile.

For !OF I need to use the pdevname, so I need to "guess" the right
one, and using the scheme of "syscon.<address>" seemed to be the one
most likely not conflicting with anything else.


Regards
Jonas

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328
  2016-08-22 13:54       ` Jonas Gorski
@ 2016-08-23  8:57         ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-23  8:57 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Mon, Aug 22, 2016 at 3:54 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
> On 22 August 2016 at 15:15, Linus Walleij <linus.walleij@linaro.org> wrote:
>> On Fri, Aug 19, 2016 at 12:53 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
>>
>>> Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as
>>> GPIOs, as LEDs for the integrated LED controller, or various other
>>> functions. Its pincontrol mux registers also control other aspects, like
>>> switching the second USB port between host and device mode.
>>>
>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>
>> This looks good. Just thinking following the other patches
>> that maybe this should be a syscon child driver.
>>
>>> +#define BCM6328_NGPIO          32
>>
>> I wonder why the pin control driver cares about that?
>>
>>> +struct bcm6328_pinctrl {
>>> +       struct pinctrl_dev *pctldev;
>>> +       struct pinctrl_desc desc;
>>> +
>>> +       void __iomem *mode;
>>> +       void __iomem *mux[3];
>>> +
>>> +       /* register access lock */
>>> +       spinlock_t lock;
>>> +
>>> +       struct gpio_chip gpio;
>>
>> Usually this should be the other way around: the gpio_chip
>> knows about the pin controller, the pin controller does not
>> know about the gpio_chip.
>>
>> I don't see it used in the code either? Artifact?
>
> That's because some of the drivers require it, and kept it here so to
> keep the drivers as similar as possible.

No dead code please. I think that is just confusing.

>> Why all this __raw_* accessors? What is wrong with readl_relaxed()
>> and writel_relaxed()? Or MIPS doesn't have them?
>
> BCM63XX is one of those weird targets that are usually big endian, and
> there are no native endian / big endian *_relaxed() accessors.

Aha OK.

>> Nice, but why not just add
>> depends on OF
>> to the Kconfig and get rid of the #ifdef?
>
> As mentioned for the generic part, I want to use it on a !OF target as well.

OK.

>>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
>>> +       mode = devm_ioremap_resource(&pdev->dev, res);
>>> +       if (IS_ERR(mode))
>>> +               return PTR_ERR(mode);
>>> +
>>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
>>> +       mux = devm_ioremap_resource(&pdev->dev, res);
>>> +       if (IS_ERR(mux))
>>> +               return PTR_ERR(mux);
>>
>> This mishmash of remap windows makes me prefer the syscon
>> design pattern.
>
> At least for this one I would still need to have multiple syscons

Having multiple syscons is not a problem.

> because there already is one OF enabled driver that uses a non-syscon
> access to drivers within this range.

I don't understand this. Can you explain? If another driver is using
a non-syscon pattern then surely it can be refactored due to being
done the wrong way in the first place. I have done so myself when
running into similar issues.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 01/13] pinctrl: add bcm63xx base code
  2016-08-22 13:44         ` Jonas Gorski
@ 2016-08-23  9:15           ` Linus Walleij
  0 siblings, 0 replies; 36+ messages in thread
From: Linus Walleij @ 2016-08-23  9:15 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Mon, Aug 22, 2016 at 3:44 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
> On 22 August 2016 at 14:46, Linus Walleij <linus.walleij@linaro.org> wrote:

>> Why not just put it in the existing pinctrl/bcm directory?
>
> Because at the time I started writing these drivers it was still
> exclusive for ARCH_BCM, will move them there.

OK thanks.

>> The drivers in there share nothing but being Broadcom
>> anyways. And when you're at it, do take a look at the
>> other Broadcom drivers to check if they would
>> happen to share something with your hardware, I find
>> it dazzling that hardware engineers repeatedly reinvents
>> pin controllers but what can I do.
>>
>>> +config PINCTRL_BCM63XX
>>> +       bool
>>> +       select GPIO_GENERIC
>>
>> depends on ARCH_****?
>
> This isn't a user selectable symbol so I don't see the need for that.

This is usually used to narrow the compile coverage to an arch so
that the autobuilders do not explode on the driver when they try
to enable and compile it for every arch in the world using randconfig.

>> depends on OF_GPIO?
>>
>> Will it really be used on non-DT systems?
>
> I plan to use it on both mips/bcm63xx (no dts support) and bmips (dts
> support), so yes.

Tentatively OK. If you are sure it will actually happen, generally
I don't like "design for the future" I prefer "design for here and now".

>> - The only reason for not using of_gpio_simple_xlate() seems to be that
>>   you have several GPIO banks. So why not model every bank as a
>>   separate device? Or did you consider this already?
>
> I did consider it, but it makes the !OF case more complicated, and the
> current of_gpio base code requires changing for it.
>
> That's because some of the pinctrl chips need to set the
> gpio-direction for muxes, and for that need to have a reference to the
> gpio-controller(s). Since any muxes directly tied to the controller
> node will get applied as soon as the controller is registered, it
> needs to aquire the gpio-controller references first.

If you were using syscon to access the register instead of remapping
then this problem would go away, because then the pin control
and the GPIO driver can simply just write into the same registers
to change the direction, because regmap provides marshalling
(serialization) and locking of register access so you don't even
need a spinlock or anything to share: you're already sharing the
regmap abstraction.

This is part of the beauty of doing this with syscon+regmap and
makes me even more convinced that it is the right solution for these
drivers.

If you're worried about the pin controller changing the direction of
the GPIOs behind the back of the GPIO driver: that is what the
.get_direction() callback in the gpio_chip is for, i.e. it is not a
problem.

> On the gpio-controller side, to flag these a requiring pinctrl those
> would then have a gpio-range property, which will cause the probe
> being deferred until the reference to the controller can be resolved.
> Which waits for the gpio-controller to be registered, so it can
> resolve its references to it. A true catch 22 ;-)

So avoid that entire dilemma by removing the entire
cross-dependency. Use syscon+regmap and just write into
the direction registers from the pin controller driver.

>>> +#ifdef CONFIG_OF
>>> +               gc[i].of_gpio_n_cells = 2;
>>> +               gc[i].of_xlate = bcm63xx_gpio_of_xlate;
>>> +#endif
>>> +
>>> +               gc[i].label = label;
>>> +               gc[i].ngpio = pins;
>>> +
>>> +               devm_gpiochip_add_data(dev, &gc[i], gc);
>>
>> Because this also gets pretty hairy... since you don't have one device
>> per gpiochip.

And I'm not convinced that having several gpiochips spawn from one
device is a good idea.


>> A current trend in simple MMIO devices is to simply add themselves as a
>> compatible string in drivers/gpio/gpio-mmio.c. Example:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-gpio.git/commit/drivers/gpio/gpio-mmio.c?h=devel&id=05cc995f4d44c2b14a1f15f3271cc9715cb81099
>>
>> This could be a viable approach if you find a way to flag that such a GPIO
>> has a pin control backend.
>
> The most obvious would be having a gpio-ranges property, but this
> leads to issues mentioned above. And only works for OF.

Ranges can be registered from boardfiles. In fact that was how
it was devised from the beginning, OF ranges were added later.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358
  2016-08-22 13:57     ` Jonas Gorski
@ 2016-08-23  9:18       ` Linus Walleij
  2016-08-23 15:43         ` Re[2]: " Alexander Shiyan
  0 siblings, 1 reply; 36+ messages in thread
From: Linus Walleij @ 2016-08-23  9:18 UTC (permalink / raw)
  To: Jonas Gorski, Alexander Shiyan
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas

On Mon, Aug 22, 2016 at 3:57 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
> On 22 August 2016 at 15:21, Linus Walleij <linus.walleij@linaro.org> wrote:

>>> +       else
>>> +               mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");
>>
>> That looks very very fragile.
>
> For !OF I need to use the pdevname, so I need to "guess" the right
> one, and using the scheme of "syscon.<address>" seemed to be the one
> most likely not conflicting with anything else.

OK from my side, I can live with that.

CC:ing the syscon pdev support author: Alexander what is your
thoughts about this? Is there a good convention to follow for
pdev lookups?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re[2]: [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358
  2016-08-23  9:18       ` Linus Walleij
@ 2016-08-23 15:43         ` Alexander Shiyan
  0 siblings, 0 replies; 36+ messages in thread
From: Alexander Shiyan @ 2016-08-23 15:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio, devicetree, Rob Herring, Mark Rutland,
	Kevin Cernekee, Florian Fainelli,
	Álvaro Fernández Rojas, Jonas Gorski

>Вторник, 23 августа 2016, 12:18 +03:00 от Linus Walleij <linus.walleij@linaro.org>:
>
>On Mon, Aug 22, 2016 at 3:57 PM, Jonas Gorski < jonas.gorski@gmail.com > wrote:
>> On 22 August 2016 at 15:21, Linus Walleij < linus.walleij@linaro.org > wrote:
>
>>>> +       else
>>>> +               mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");
>>>
>>> That looks very very fragile.
>>
>> For !OF I need to use the pdevname, so I need to "guess" the right
>> one, and using the scheme of "syscon.<address>" seemed to be the one
>> most likely not conflicting with anything else.
>
>OK from my side, I can live with that.
>
>CC:ing the syscon pdev support author: Alexander what is your
>thoughts about this? Is there a good convention to follow for
>pdev lookups?

Because the platform on which this feature was used is fully converted  to DT,
I was planning to send a patch to remove this function :)

Such usage is in my view perfectly acceptable for the period until the
platform is gradually being converted to DT, but the best way, of course,
is using syscon_regmap_lookup_by_compatible() or syscon_regmap_lookup_by_phandle().

---


^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2016-08-23 16:49 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-19 10:53 [PATCH 00/13] pinctrl: add BCM63XX pincontrol support Jonas Gorski
2016-08-19 10:53 ` [PATCH 03/13] pinctrl: add a pincontrol driver for BCM6328 Jonas Gorski
2016-08-22 13:15   ` Linus Walleij
     [not found]     ` <CACRpkdbZDmHimo9K1rUcs-4MyOSZH5SHUD3kuSYANppLUU0WwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-22 13:54       ` Jonas Gorski
2016-08-23  8:57         ` Linus Walleij
2016-08-19 10:53 ` [PATCH 04/13] Documentation: add BCM6348 pincontroller binding documentation Jonas Gorski
2016-08-22 13:17   ` Linus Walleij
2016-08-19 10:53 ` [PATCH 07/13] pinctrl: add a pincontrol driver for BCM6358 Jonas Gorski
2016-08-22 13:21   ` Linus Walleij
2016-08-22 13:57     ` Jonas Gorski
2016-08-23  9:18       ` Linus Walleij
2016-08-23 15:43         ` Re[2]: " Alexander Shiyan
2016-08-19 10:53 ` [PATCH 08/13] Documentation: add BCM6362 pincontroller binding documentation Jonas Gorski
     [not found]   ` <1471604025-21575-9-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:22     ` Linus Walleij
2016-08-19 10:53 ` [PATCH 09/13] pinctrl: add a pincontrol driver for BCM6362 Jonas Gorski
     [not found]   ` <1471604025-21575-10-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:23     ` Linus Walleij
2016-08-19 10:53 ` [PATCH 10/13] Documentation: add BCM6368 pincontroller binding documentation Jonas Gorski
     [not found]   ` <1471604025-21575-11-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:24     ` Linus Walleij
     [not found] ` <1471604025-21575-1-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-19 10:53   ` [PATCH 01/13] pinctrl: add bcm63xx base code Jonas Gorski
2016-08-22 12:46     ` Linus Walleij
     [not found]       ` <CACRpkdbAWJruB=4rv_SoPZ5D5XgWjebK_Qmv2GLgOOrSyqXcDA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-22 13:44         ` Jonas Gorski
2016-08-23  9:15           ` Linus Walleij
2016-08-19 10:53   ` [PATCH 02/13] Documentation: add BCM6328 pincontroller binding documentation Jonas Gorski
2016-08-19 14:14     ` Rob Herring
2016-08-19 14:30       ` Jonas Gorski
     [not found]         ` <CAOiHx=mLgZ6Q3tBY3zYkCpMX09Kv54OQQoAXAdP16D_xoXO3mg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-22 12:51           ` Linus Walleij
2016-08-19 10:53   ` [PATCH 05/13] pinctrl: add a pincontrol driver for BCM6348 Jonas Gorski
     [not found]     ` <1471604025-21575-6-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:19       ` Linus Walleij
2016-08-19 10:53   ` [PATCH 06/13] Documentation: add BCM6358 pincontroller binding documentation Jonas Gorski
     [not found]     ` <1471604025-21575-7-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:20       ` Linus Walleij
2016-08-19 10:53   ` [PATCH 11/13] pinctrl: add a pincontrol driver for BCM6368 Jonas Gorski
     [not found]     ` <1471604025-21575-12-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:25       ` Linus Walleij
2016-08-19 10:53   ` [PATCH 13/13] pinctrl: add a pincontrol driver for BCM63268 Jonas Gorski
     [not found]     ` <1471604025-21575-14-git-send-email-jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-22 13:26       ` Linus Walleij
2016-08-19 10:53 ` [PATCH 12/13] Documentation: add BCM63268 pincontroller binding documentation Jonas Gorski
2016-08-22 13:25   ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.