All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/15] pinctrl: add BCM63XX pincontrol support
@ 2021-03-10 12:54 ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

First of all, I've based this on the patches sent by Jonas Gorski back in
2016:
https://www.spinics.net/lists/linux-gpio/msg15983.html
http://patchwork.ozlabs.org/project/linux-gpio/patch/1471604025-21575-2-git-send-email-jonas.gorski@gmail.com/

I've tried to address all coments from Linus Walleij, but I know that
this may still need some other modifications

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.

v6: introduce changes suggested by Rob Herring and Andy Shevchenko.
v5: introduce changes suggested by Andy Shevchenko.
v4: fix gpiochip_irqchip_add_domain(), remove IRQ Kconfig selections and add
 missing of_node_put().
v3: introduce new files for shared code and add more changes suggested by
 Linus Walleij. Also add a new patch needed for properly parsing gpio-ranges.
v2: introduce changes suggested by Linus Walleij and remove interrupts
 - In order to use GPIO_REGMAP, the need to get gpio_chip from gpio_regmap
 and use it for pinctrl_add_gpio_range() and gpio_chip.direction_input()
 and gpio_chip.direction_output().

Álvaro Fernández Rojas (15):
  gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
  gpio: regmap: set gpio_chip of_node
  pinctrl: bcm: add bcm63xx base code
  dt-bindings: add BCM6328 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6328
  dt-bindings: add BCM6358 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6358
  dt-bindings: add BCM6362 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6362
  dt-bindings: add BCM6368 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6368
  dt-bindings: add BCM63268 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM63268
  dt-bindings: add BCM6318 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6318

 .../pinctrl/brcm,bcm6318-pinctrl.yaml         | 190 ++++++
 .../pinctrl/brcm,bcm63268-pinctrl.yaml        | 211 ++++++
 .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 +++++
 .../pinctrl/brcm,bcm6358-pinctrl.yaml         | 140 ++++
 .../pinctrl/brcm,bcm6362-pinctrl.yaml         | 253 +++++++
 .../pinctrl/brcm,bcm6368-pinctrl.yaml         | 264 +++++++
 drivers/gpio/gpio-regmap.c                    |   1 +
 drivers/pinctrl/bcm/Kconfig                   |  55 ++
 drivers/pinctrl/bcm/Makefile                  |   7 +
 drivers/pinctrl/bcm/pinctrl-bcm6318.c         | 498 ++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63268.c        | 643 ++++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6328.c         | 404 +++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6358.c         | 369 ++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6362.c         | 617 +++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6368.c         | 523 ++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.c         | 113 +++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.h         |  43 ++
 include/linux/gpio/driver.h                   |   9 +
 include/linux/gpio/regmap.h                   |   4 +
 19 files changed, 4518 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h

-- 
2.20.1


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

* [PATCH v6 00/15] pinctrl: add BCM63XX pincontrol support
@ 2021-03-10 12:54 ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

First of all, I've based this on the patches sent by Jonas Gorski back in
2016:
https://www.spinics.net/lists/linux-gpio/msg15983.html
http://patchwork.ozlabs.org/project/linux-gpio/patch/1471604025-21575-2-git-send-email-jonas.gorski@gmail.com/

I've tried to address all coments from Linus Walleij, but I know that
this may still need some other modifications

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.

v6: introduce changes suggested by Rob Herring and Andy Shevchenko.
v5: introduce changes suggested by Andy Shevchenko.
v4: fix gpiochip_irqchip_add_domain(), remove IRQ Kconfig selections and add
 missing of_node_put().
v3: introduce new files for shared code and add more changes suggested by
 Linus Walleij. Also add a new patch needed for properly parsing gpio-ranges.
v2: introduce changes suggested by Linus Walleij and remove interrupts
 - In order to use GPIO_REGMAP, the need to get gpio_chip from gpio_regmap
 and use it for pinctrl_add_gpio_range() and gpio_chip.direction_input()
 and gpio_chip.direction_output().

Álvaro Fernández Rojas (15):
  gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
  gpio: regmap: set gpio_chip of_node
  pinctrl: bcm: add bcm63xx base code
  dt-bindings: add BCM6328 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6328
  dt-bindings: add BCM6358 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6358
  dt-bindings: add BCM6362 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6362
  dt-bindings: add BCM6368 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6368
  dt-bindings: add BCM63268 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM63268
  dt-bindings: add BCM6318 pincontroller binding documentation
  pinctrl: add a pincontrol driver for BCM6318

 .../pinctrl/brcm,bcm6318-pinctrl.yaml         | 190 ++++++
 .../pinctrl/brcm,bcm63268-pinctrl.yaml        | 211 ++++++
 .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 +++++
 .../pinctrl/brcm,bcm6358-pinctrl.yaml         | 140 ++++
 .../pinctrl/brcm,bcm6362-pinctrl.yaml         | 253 +++++++
 .../pinctrl/brcm,bcm6368-pinctrl.yaml         | 264 +++++++
 drivers/gpio/gpio-regmap.c                    |   1 +
 drivers/pinctrl/bcm/Kconfig                   |  55 ++
 drivers/pinctrl/bcm/Makefile                  |   7 +
 drivers/pinctrl/bcm/pinctrl-bcm6318.c         | 498 ++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63268.c        | 643 ++++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6328.c         | 404 +++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6358.c         | 369 ++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6362.c         | 617 +++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm6368.c         | 523 ++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.c         | 113 +++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.h         |  43 ++
 include/linux/gpio/driver.h                   |   9 +
 include/linux/gpio/regmap.h                   |   4 +
 19 files changed, 4518 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 01/15] gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in
a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP
isn't enabled.

Fixes: 6a45b0e2589f ("gpiolib: Introduce gpiochip_irqchip_add_domain()")
Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Michael Walle <michael@walle.cc>
---
 v6: no changes
 v5: add missing Suggested-by tag
 v4: add patch (fix include instead of gpio-regmap.c)

 include/linux/gpio/driver.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 286de0520574..ecf0032a0995 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -624,8 +624,17 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain,
 bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc,
 				unsigned int offset);
 
+#ifdef CONFIG_GPIOLIB_IRQCHIP
 int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
 				struct irq_domain *domain);
+#else
+static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
+					      struct irq_domain *domain)
+{
+	WARN_ON(1);
+	return -EINVAL;
+}
+#endif
 
 int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset);
 void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset);
-- 
2.20.1


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

* [PATCH v6 01/15] gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in
a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP
isn't enabled.

Fixes: 6a45b0e2589f ("gpiolib: Introduce gpiochip_irqchip_add_domain()")
Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Michael Walle <michael@walle.cc>
---
 v6: no changes
 v5: add missing Suggested-by tag
 v4: add patch (fix include instead of gpio-regmap.c)

 include/linux/gpio/driver.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 286de0520574..ecf0032a0995 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -624,8 +624,17 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain,
 bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc,
 				unsigned int offset);
 
+#ifdef CONFIG_GPIOLIB_IRQCHIP
 int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
 				struct irq_domain *domain);
+#else
+static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
+					      struct irq_domain *domain)
+{
+	WARN_ON(1);
+	return -EINVAL;
+}
+#endif
 
 int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset);
 void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

This is needed for properly registering GPIO regmap as a child of a regmap
pin controller.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Michael Walle <michael@walle.cc>
---
 v6: add comment and simplify of_node assignment
 v5: switch to fwnode
 v4: fix documentation
 v3: introduce patch needed for properly parsing gpio-range

 drivers/gpio/gpio-regmap.c  | 1 +
 include/linux/gpio/regmap.h | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
index 5412cb3b0b2a..d4fc656e70b0 100644
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
 
 	chip = &gpio->gpio_chip;
 	chip->parent = config->parent;
+	chip->of_node = to_of_node(config->fwnode);
 	chip->base = -1;
 	chip->ngpio = config->ngpio;
 	chip->names = config->names;
diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
index ad76f3d0a6ba..334dd928042b 100644
--- a/include/linux/gpio/regmap.h
+++ b/include/linux/gpio/regmap.h
@@ -4,6 +4,7 @@
 #define _LINUX_GPIO_REGMAP_H
 
 struct device;
+struct fwnode_handle;
 struct gpio_regmap;
 struct irq_domain;
 struct regmap;
@@ -16,6 +17,8 @@ struct regmap;
  * @parent:		The parent device
  * @regmap:		The regmap used to access the registers
  *			given, the name of the device is used
+ * @fwnode:		(Optional) The firmware node.
+ *			If not given, the fwnode of the parent is used.
  * @label:		(Optional) Descriptive name for GPIO controller.
  *			If not given, the name of the device is used.
  * @ngpio:		Number of GPIOs
@@ -57,6 +60,7 @@ struct regmap;
 struct gpio_regmap_config {
 	struct device *parent;
 	struct regmap *regmap;
+	struct fwnode_handle *fwnode;
 
 	const char *label;
 	int ngpio;
-- 
2.20.1


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

* [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

This is needed for properly registering GPIO regmap as a child of a regmap
pin controller.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Michael Walle <michael@walle.cc>
---
 v6: add comment and simplify of_node assignment
 v5: switch to fwnode
 v4: fix documentation
 v3: introduce patch needed for properly parsing gpio-range

 drivers/gpio/gpio-regmap.c  | 1 +
 include/linux/gpio/regmap.h | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
index 5412cb3b0b2a..d4fc656e70b0 100644
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
 
 	chip = &gpio->gpio_chip;
 	chip->parent = config->parent;
+	chip->of_node = to_of_node(config->fwnode);
 	chip->base = -1;
 	chip->ngpio = config->ngpio;
 	chip->names = config->names;
diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
index ad76f3d0a6ba..334dd928042b 100644
--- a/include/linux/gpio/regmap.h
+++ b/include/linux/gpio/regmap.h
@@ -4,6 +4,7 @@
 #define _LINUX_GPIO_REGMAP_H
 
 struct device;
+struct fwnode_handle;
 struct gpio_regmap;
 struct irq_domain;
 struct regmap;
@@ -16,6 +17,8 @@ struct regmap;
  * @parent:		The parent device
  * @regmap:		The regmap used to access the registers
  *			given, the name of the device is used
+ * @fwnode:		(Optional) The firmware node.
+ *			If not given, the fwnode of the parent is used.
  * @label:		(Optional) Descriptive name for GPIO controller.
  *			If not given, the name of the device is used.
  * @ngpio:		Number of GPIOs
@@ -57,6 +60,7 @@ struct regmap;
 struct gpio_regmap_config {
 	struct device *parent;
 	struct regmap *regmap;
+	struct fwnode_handle *fwnode;
 
 	const char *label;
 	int ngpio;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a helper for registering BCM63XX pin controllers.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Andy Shevchenko
 v5: add changes suggested by Andy Shevchenko
 v4: drop IRQ selects from Kconfig and add missing of_node_put()
 v3: add new patch with shared code

 drivers/pinctrl/bcm/Kconfig           |   7 ++
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
 4 files changed, 164 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 0ed14de0134c..882f19bdc243 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -29,6 +29,13 @@ config PINCTRL_BCM2835
 	help
 	   Say Y here to enable the Broadcom BCM2835 GPIO driver.
 
+config PINCTRL_BCM63XX
+	bool
+	select GENERIC_PINCONF
+	select GPIO_REGMAP
+	select PINCONF
+	select PINMUX
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 79d5e49fdd9a..0e3cf9b15c65 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -3,6 +3,7 @@
 
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
+obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
new file mode 100644
index 000000000000..2eaac8e6f79f
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/gpio/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM63XX_BANK_SIZE	4
+
+#define BCM63XX_DIROUT_REG	0x04
+#define BCM63XX_DATA_REG	0x0c
+
+static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
+				  unsigned int base, unsigned int offset,
+				  unsigned int *reg, unsigned int *mask)
+{
+	unsigned int line = offset % BCM63XX_BANK_GPIOS;
+	unsigned int stride = offset / BCM63XX_BANK_GPIOS;
+
+	*reg = base - stride * BCM63XX_BANK_SIZE;
+	*mask = BIT(line);
+
+	return 0;
+}
+
+static const struct of_device_id bcm63xx_gpio_of_match[] = {
+	{ .compatible = "brcm,bcm6318-gpio", },
+	{ .compatible = "brcm,bcm6328-gpio", },
+	{ .compatible = "brcm,bcm6358-gpio", },
+	{ .compatible = "brcm,bcm6362-gpio", },
+	{ .compatible = "brcm,bcm6368-gpio", },
+	{ .compatible = "brcm,bcm63268-gpio", },
+	{ /* sentinel */ }
+};
+
+static int bcm63xx_gpio_probe(struct device *dev,
+			      struct fwnode_handle *node,
+			      const struct bcm63xx_pinctrl_soc *soc,
+			      struct bcm63xx_pinctrl *pc)
+{
+	struct gpio_regmap_config grc = {0};
+
+	grc.parent = dev;
+	grc.fwnode = node;
+	grc.ngpio = soc->ngpios;
+	grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
+	grc.regmap = pc->regs;
+	grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
+
+	if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
+		grc.reg_dat_base = BCM63XX_DATA_REG;
+	grc.reg_set_base = grc.reg_dat_base;
+
+	if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
+		grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
+
+	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
+}
+
+int bcm63xx_pinctrl_probe(struct platform_device *pdev,
+			  const struct bcm63xx_pinctrl_soc *soc,
+			  void *driver_data)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct fwnode_handle *node;
+	int err;
+
+	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+	if (!pc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pc);
+
+	pc->dev = dev;
+	pc->driver_data = driver_data;
+
+	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(pc->regs))
+		return PTR_ERR(pc->regs);
+
+	pc->pctl_desc.name = dev_name(dev);
+	pc->pctl_desc.pins = soc->pins;
+	pc->pctl_desc.npins = soc->npins;
+	pc->pctl_desc.pctlops = soc->pctl_ops;
+	pc->pctl_desc.pmxops = soc->pmx_ops;
+	pc->pctl_desc.owner = THIS_MODULE;
+
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+	if (IS_ERR(pc->pctl_dev))
+		return PTR_ERR(pc->pctl_dev);
+
+	device_for_each_child_node(dev, node) {
+		if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
+			err = bcm63xx_gpio_probe(dev, node, soc, pc);
+			if (err) {
+				dev_err(dev, "could not add GPIO chip\n");
+				fwnode_handle_put(node);
+				return err;
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
new file mode 100644
index 000000000000..3bdb50021f1b
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#ifndef __PINCTRL_BCM63XX_H__
+#define __PINCTRL_BCM63XX_H__
+
+#include <linux/pinctrl/pinctrl.h>
+
+#define BCM63XX_BANK_GPIOS 32
+
+struct bcm63xx_pinctrl_soc {
+	struct pinctrl_ops *pctl_ops;
+	struct pinmux_ops *pmx_ops;
+
+	const struct pinctrl_pin_desc *pins;
+	unsigned npins;
+
+	unsigned int ngpios;
+};
+
+struct bcm63xx_pinctrl {
+	struct device *dev;
+	struct regmap *regs;
+
+	struct pinctrl_desc pctl_desc;
+	struct pinctrl_dev *pctl_dev;
+
+	void *driver_data;
+};
+
+static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
+{
+	return pin % BCM63XX_BANK_GPIOS;
+}
+
+int bcm63xx_pinctrl_probe(struct platform_device *pdev,
+			  const struct bcm63xx_pinctrl_soc *soc,
+			  void *driver_data);
+
+#endif /* __PINCTRL_BCM63XX_H__ */
-- 
2.20.1


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

* [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a helper for registering BCM63XX pin controllers.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Andy Shevchenko
 v5: add changes suggested by Andy Shevchenko
 v4: drop IRQ selects from Kconfig and add missing of_node_put()
 v3: add new patch with shared code

 drivers/pinctrl/bcm/Kconfig           |   7 ++
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
 drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
 4 files changed, 164 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 0ed14de0134c..882f19bdc243 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -29,6 +29,13 @@ config PINCTRL_BCM2835
 	help
 	   Say Y here to enable the Broadcom BCM2835 GPIO driver.
 
+config PINCTRL_BCM63XX
+	bool
+	select GENERIC_PINCONF
+	select GPIO_REGMAP
+	select PINCONF
+	select PINMUX
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 79d5e49fdd9a..0e3cf9b15c65 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -3,6 +3,7 @@
 
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
+obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
new file mode 100644
index 000000000000..2eaac8e6f79f
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/gpio/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM63XX_BANK_SIZE	4
+
+#define BCM63XX_DIROUT_REG	0x04
+#define BCM63XX_DATA_REG	0x0c
+
+static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
+				  unsigned int base, unsigned int offset,
+				  unsigned int *reg, unsigned int *mask)
+{
+	unsigned int line = offset % BCM63XX_BANK_GPIOS;
+	unsigned int stride = offset / BCM63XX_BANK_GPIOS;
+
+	*reg = base - stride * BCM63XX_BANK_SIZE;
+	*mask = BIT(line);
+
+	return 0;
+}
+
+static const struct of_device_id bcm63xx_gpio_of_match[] = {
+	{ .compatible = "brcm,bcm6318-gpio", },
+	{ .compatible = "brcm,bcm6328-gpio", },
+	{ .compatible = "brcm,bcm6358-gpio", },
+	{ .compatible = "brcm,bcm6362-gpio", },
+	{ .compatible = "brcm,bcm6368-gpio", },
+	{ .compatible = "brcm,bcm63268-gpio", },
+	{ /* sentinel */ }
+};
+
+static int bcm63xx_gpio_probe(struct device *dev,
+			      struct fwnode_handle *node,
+			      const struct bcm63xx_pinctrl_soc *soc,
+			      struct bcm63xx_pinctrl *pc)
+{
+	struct gpio_regmap_config grc = {0};
+
+	grc.parent = dev;
+	grc.fwnode = node;
+	grc.ngpio = soc->ngpios;
+	grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
+	grc.regmap = pc->regs;
+	grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
+
+	if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
+		grc.reg_dat_base = BCM63XX_DATA_REG;
+	grc.reg_set_base = grc.reg_dat_base;
+
+	if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
+		grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
+
+	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
+}
+
+int bcm63xx_pinctrl_probe(struct platform_device *pdev,
+			  const struct bcm63xx_pinctrl_soc *soc,
+			  void *driver_data)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct fwnode_handle *node;
+	int err;
+
+	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
+	if (!pc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pc);
+
+	pc->dev = dev;
+	pc->driver_data = driver_data;
+
+	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(pc->regs))
+		return PTR_ERR(pc->regs);
+
+	pc->pctl_desc.name = dev_name(dev);
+	pc->pctl_desc.pins = soc->pins;
+	pc->pctl_desc.npins = soc->npins;
+	pc->pctl_desc.pctlops = soc->pctl_ops;
+	pc->pctl_desc.pmxops = soc->pmx_ops;
+	pc->pctl_desc.owner = THIS_MODULE;
+
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+	if (IS_ERR(pc->pctl_dev))
+		return PTR_ERR(pc->pctl_dev);
+
+	device_for_each_child_node(dev, node) {
+		if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
+			err = bcm63xx_gpio_probe(dev, node, soc, pc);
+			if (err) {
+				dev_err(dev, "could not add GPIO chip\n");
+				fwnode_handle_put(node);
+				return err;
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
new file mode 100644
index 000000000000..3bdb50021f1b
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#ifndef __PINCTRL_BCM63XX_H__
+#define __PINCTRL_BCM63XX_H__
+
+#include <linux/pinctrl/pinctrl.h>
+
+#define BCM63XX_BANK_GPIOS 32
+
+struct bcm63xx_pinctrl_soc {
+	struct pinctrl_ops *pctl_ops;
+	struct pinmux_ops *pmx_ops;
+
+	const struct pinctrl_pin_desc *pins;
+	unsigned npins;
+
+	unsigned int ngpios;
+};
+
+struct bcm63xx_pinctrl {
+	struct device *dev;
+	struct regmap *regs;
+
+	struct pinctrl_desc pctl_desc;
+	struct pinctrl_dev *pctl_dev;
+
+	void *driver_data;
+};
+
+static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
+{
+	return pin % BCM63XX_BANK_GPIOS;
+}
+
+int bcm63xx_pinctrl_probe(struct platform_device *pdev,
+			  const struct bcm63xx_pinctrl_soc *soc,
+			  void *driver_data);
+
+#endif /* __PINCTRL_BCM63XX_H__ */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
new file mode 100644
index 000000000000..471f6efa1754
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6328 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6328-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6328-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
+                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
+                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
+                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
+                  usb_port1 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6328-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6328-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 32>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio6";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio7";
+          };
+        };
+
+        pinctrl_inet_act_led: inet_act_led-pins {
+          function = "inet_act_led";
+          pins = "gpio11";
+        };
+
+        pinctrl_pcie_clkreq: pcie_clkreq-pins {
+          function = "pcie_clkreq";
+          pins = "gpio16";
+        };
+
+        pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
+          function = "led";
+          pins = "gpio17";
+        };
+
+        pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
+          function = "led";
+          pins = "gpio18";
+        };
+
+        pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
+          function = "led";
+          pins = "gpio19";
+        };
+
+        pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
+          function = "led";
+          pins = "gpio20";
+        };
+
+        pinctrl_ephy0_act_led: ephy0_act_led-pins {
+          function = "ephy0_act_led";
+          pins = "gpio25";
+        };
+
+        pinctrl_ephy1_act_led: ephy1_act_led-pins {
+          function = "ephy1_act_led";
+          pins = "gpio26";
+        };
+
+        pinctrl_ephy2_act_led: ephy2_act_led-pins {
+          function = "ephy2_act_led";
+          pins = "gpio27";
+        };
+
+        pinctrl_ephy3_act_led: ephy3_act_led-pins {
+          function = "ephy3_act_led";
+          pins = "gpio28";
+        };
+
+        pinctrl_hsspi_cs1: hsspi_cs1-pins {
+          function = "hsspi_cs1";
+          pins = "hsspi_cs1";
+        };
+
+        pinctrl_usb_port1_device: usb_port1_device-pins {
+          function = "usb_device_port";
+          pins = "usb_port1";
+        };
+
+        pinctrl_usb_port1_host: usb_port1_host-pins {
+          function = "usb_host_port";
+          pins = "usb_port1";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
 1 file changed, 174 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
new file mode 100644
index 000000000000..471f6efa1754
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6328 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6328-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6328-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
+                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
+                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
+                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
+                  usb_port1 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6328-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6328-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 32>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio6";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio7";
+          };
+        };
+
+        pinctrl_inet_act_led: inet_act_led-pins {
+          function = "inet_act_led";
+          pins = "gpio11";
+        };
+
+        pinctrl_pcie_clkreq: pcie_clkreq-pins {
+          function = "pcie_clkreq";
+          pins = "gpio16";
+        };
+
+        pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
+          function = "led";
+          pins = "gpio17";
+        };
+
+        pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
+          function = "led";
+          pins = "gpio18";
+        };
+
+        pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
+          function = "led";
+          pins = "gpio19";
+        };
+
+        pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
+          function = "led";
+          pins = "gpio20";
+        };
+
+        pinctrl_ephy0_act_led: ephy0_act_led-pins {
+          function = "ephy0_act_led";
+          pins = "gpio25";
+        };
+
+        pinctrl_ephy1_act_led: ephy1_act_led-pins {
+          function = "ephy1_act_led";
+          pins = "gpio26";
+        };
+
+        pinctrl_ephy2_act_led: ephy2_act_led-pins {
+          function = "ephy2_act_led";
+          pins = "gpio27";
+        };
+
+        pinctrl_ephy3_act_led: ephy3_act_led-pins {
+          function = "ephy3_act_led";
+          pins = "gpio28";
+        };
+
+        pinctrl_hsspi_cs1: hsspi_cs1-pins {
+          function = "hsspi_cs1";
+          pins = "hsspi_cs1";
+        };
+
+        pinctrl_usb_port1_device: usb_port1_device-pins {
+          function = "usb_device_port";
+          pins = "usb_port1";
+        };
+
+        pinctrl_usb_port1_host: usb_port1_host-pins {
+          function = "usb_host_port";
+          pins = "usb_port1";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 05/15] pinctrl: add a pincontrol driver for BCM6328
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a pincontrol driver for BCM6328. BCM6328 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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6328.c | 404 ++++++++++++++++++++++++++
 3 files changed, 413 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 882f19bdc243..d35e5d3fe26f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
 	select PINCONF
 	select PINMUX
 
+config PINCTRL_BCM6328
+	bool "Broadcom BCM6328 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 0e3cf9b15c65..57e5434a6db6 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
+obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c
new file mode 100644
index 000000000000..c9efce600550
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6328 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6328_NUM_GPIOS	32
+
+#define BCM6328_MODE_REG	0x18
+#define BCM6328_MUX_HI_REG	0x1c
+#define BCM6328_MUX_LO_REG	0x20
+#define BCM6328_MUX_OTHER_REG	0x24
+#define  BCM6328_MUX_MASK	GENMASK(1, 0)
+
+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;
+};
+
+static const unsigned int bcm6328_mux[] = {
+	BCM6328_MUX_LO_REG,
+	BCM6328_MUX_HI_REG,
+	BCM6328_MUX_OTHER_REG
+};
+
+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 inline unsigned int bcm6328_mux_off(unsigned int pin)
+{
+	return bcm6328_mux[pin / 16];
+}
+
+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 bcm63xx_pinctrl *pc, unsigned pin,
+			    unsigned int mode, unsigned int mux)
+{
+	if (pin < BCM6328_NUM_GPIOS)
+		regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
+				   mode ? BIT(pin) : 0);
+
+	regmap_update_bits(pc->regs, bcm6328_mux_off(pin),
+			   BCM6328_MUX_MASK << ((pin % 16) * 2),
+			   mux << ((pin % 16) * 2));
+}
+
+static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6328_pingroup *pg = &bcm6328_groups[group];
+	const struct bcm6328_function *f = &bcm6328_funcs[selector];
+
+	bcm6328_rmw_mux(pc, pg->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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6328_rmw_mux(pc, offset, 0, 0);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6328_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6328_pinctrl_get_group_name,
+	.get_group_pins = bcm6328_pinctrl_get_group_pins,
+	.get_groups_count = bcm6328_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6328_pmx_ops = {
+	.get_function_groups = bcm6328_pinctrl_get_groups,
+	.get_function_name = bcm6328_pinctrl_get_func_name,
+	.get_functions_count = bcm6328_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6328_gpio_request_enable,
+	.set_mux = bcm6328_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
+	.ngpios = BCM6328_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6328_pins),
+	.pctl_ops = &bcm6328_pctl_ops,
+	.pins = bcm6328_pins,
+	.pmx_ops = &bcm6328_pmx_ops,
+};
+
+static int bcm6328_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
+}
+
+static const struct of_device_id bcm6328_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6328-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


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

* [PATCH v6 05/15] pinctrl: add a pincontrol driver for BCM6328
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a pincontrol driver for BCM6328. BCM6328 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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6328.c | 404 ++++++++++++++++++++++++++
 3 files changed, 413 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 882f19bdc243..d35e5d3fe26f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
 	select PINCONF
 	select PINMUX
 
+config PINCTRL_BCM6328
+	bool "Broadcom BCM6328 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 0e3cf9b15c65..57e5434a6db6 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
+obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c
new file mode 100644
index 000000000000..c9efce600550
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6328 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6328_NUM_GPIOS	32
+
+#define BCM6328_MODE_REG	0x18
+#define BCM6328_MUX_HI_REG	0x1c
+#define BCM6328_MUX_LO_REG	0x20
+#define BCM6328_MUX_OTHER_REG	0x24
+#define  BCM6328_MUX_MASK	GENMASK(1, 0)
+
+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;
+};
+
+static const unsigned int bcm6328_mux[] = {
+	BCM6328_MUX_LO_REG,
+	BCM6328_MUX_HI_REG,
+	BCM6328_MUX_OTHER_REG
+};
+
+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 inline unsigned int bcm6328_mux_off(unsigned int pin)
+{
+	return bcm6328_mux[pin / 16];
+}
+
+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 bcm63xx_pinctrl *pc, unsigned pin,
+			    unsigned int mode, unsigned int mux)
+{
+	if (pin < BCM6328_NUM_GPIOS)
+		regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
+				   mode ? BIT(pin) : 0);
+
+	regmap_update_bits(pc->regs, bcm6328_mux_off(pin),
+			   BCM6328_MUX_MASK << ((pin % 16) * 2),
+			   mux << ((pin % 16) * 2));
+}
+
+static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6328_pingroup *pg = &bcm6328_groups[group];
+	const struct bcm6328_function *f = &bcm6328_funcs[selector];
+
+	bcm6328_rmw_mux(pc, pg->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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6328_rmw_mux(pc, offset, 0, 0);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6328_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6328_pinctrl_get_group_name,
+	.get_group_pins = bcm6328_pinctrl_get_group_pins,
+	.get_groups_count = bcm6328_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6328_pmx_ops = {
+	.get_function_groups = bcm6328_pinctrl_get_groups,
+	.get_function_name = bcm6328_pinctrl_get_func_name,
+	.get_functions_count = bcm6328_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6328_gpio_request_enable,
+	.set_mux = bcm6328_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
+	.ngpios = BCM6328_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6328_pins),
+	.pctl_ops = &bcm6328_pctl_ops,
+	.pins = bcm6328_pins,
+	.pmx_ops = &bcm6328_pmx_ops,
+};
+
+static int bcm6328_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
+}
+
+static const struct of_device_id bcm6328_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6328-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 06/15] dt-bindings: add BCM6358 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6358-pinctrl.yaml         | 140 ++++++++++++++++++
 1 file changed, 140 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
new file mode 100644
index 000000000000..a04fc445c761
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6358 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6358-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6358-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia,
+                  pwm_syn_clk, sys_irq ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp,
+                  led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@fffe0080 {
+      compatible = "brcm,bcm6358-gpio-controller", "syscon", "simple-mfd";
+      reg = <0xfffe0080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6358-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6358-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 40>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_ebi_cs: ebi_cs-pins {
+          function = "ebi_cs";
+          groups = "ebi_cs_grp";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          function = "uart1";
+          groups = "uart1_grp";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          function = "serial_led";
+          groups = "serial_led_grp";
+        };
+
+        pinctrl_legacy_led: legacy_led-pins {
+          function = "legacy_led";
+          groups = "legacy_led_grp";
+        };
+
+        pinctrl_led: led-pins {
+          function = "led";
+          groups = "led_grp";
+        };
+
+        pinctrl_spi_cs_23: spi_cs-pins {
+          function = "spi_cs";
+          groups = "spi_cs_grp";
+        };
+
+        pinctrl_utopia: utopia-pins {
+          function = "utopia";
+          groups = "utopia_grp";
+        };
+
+        pinctrl_pwm_syn_clk: pwm_syn_clk-pins {
+          function = "pwm_syn_clk";
+          groups = "pwm_syn_clk_grp";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          groups = "sys_irq_grp";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 06/15] dt-bindings: add BCM6358 pincontroller binding documentation
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6358-pinctrl.yaml         | 140 ++++++++++++++++++
 1 file changed, 140 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
new file mode 100644
index 000000000000..a04fc445c761
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6358 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6358-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6358-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia,
+                  pwm_syn_clk, sys_irq ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp,
+                  led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@fffe0080 {
+      compatible = "brcm,bcm6358-gpio-controller", "syscon", "simple-mfd";
+      reg = <0xfffe0080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6358-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6358-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 40>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_ebi_cs: ebi_cs-pins {
+          function = "ebi_cs";
+          groups = "ebi_cs_grp";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          function = "uart1";
+          groups = "uart1_grp";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          function = "serial_led";
+          groups = "serial_led_grp";
+        };
+
+        pinctrl_legacy_led: legacy_led-pins {
+          function = "legacy_led";
+          groups = "legacy_led_grp";
+        };
+
+        pinctrl_led: led-pins {
+          function = "led";
+          groups = "led_grp";
+        };
+
+        pinctrl_spi_cs_23: spi_cs-pins {
+          function = "spi_cs";
+          groups = "spi_cs_grp";
+        };
+
+        pinctrl_utopia: utopia-pins {
+          function = "utopia";
+          groups = "utopia_grp";
+        };
+
+        pinctrl_pwm_syn_clk: pwm_syn_clk-pins {
+          function = "pwm_syn_clk";
+          groups = "pwm_syn_clk_grp";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          groups = "sys_irq_grp";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 07/15] pinctrl: add a pincontrol driver for BCM6358
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6358.c | 369 ++++++++++++++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index d35e5d3fe26f..ced7cc6ab44f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -44,6 +44,14 @@ config PINCTRL_BCM6328
 	help
 	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
 
+config PINCTRL_BCM6358
+	bool "Broadcom BCM6358 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 57e5434a6db6..c3f5b7b2f2f0 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c
new file mode 100644
index 000000000000..d638578727f3
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6358 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6358_NUM_GPIOS		40
+
+#define BCM6358_MODE_REG		0x18
+#define  BCM6358_MODE_MUX_NONE		0
+#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)
+
+struct bcm6358_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+
+	const uint16_t mode_val;
+
+	/* non-GPIO function muxes require the gpio direction to be set */
+	const uint16_t direction;
+};
+
+struct bcm6358_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+};
+
+struct bcm6358_priv {
+	struct regmap_field *overlays;
+};
+
+#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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6358_priv *priv = pc->driver_data;
+	const struct bcm6358_pingroup *pg = &bcm6358_groups[group];
+	unsigned int val = pg->mode_val;
+	unsigned int mask = val;
+	unsigned pin;
+
+	for (pin = 0; pin < pg->num_pins; pin++)
+		mask |= (unsigned long)bcm6358_pins[pin].drv_data;
+
+	regmap_field_update_bits(priv->overlays, mask, val);
+
+	for (pin = 0; pin < pg->num_pins; pin++) {
+		struct pinctrl_gpio_range *range;
+		unsigned int hw_gpio = bcm6358_pins[pin].number;
+
+		range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
+		if (range) {
+			struct gpio_chip *gc = range->gc;
+
+			if (pg->direction & BIT(pin))
+				gc->direction_output(gc, hw_gpio, 0);
+			else
+				gc->direction_input(gc, hw_gpio);
+		}
+	}
+
+	return 0;
+}
+
+static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6358_priv *priv = pc->driver_data;
+	unsigned int mask;
+
+	mask = (unsigned long) bcm6358_pins[offset].drv_data;
+	if (!mask)
+		return 0;
+
+	/* disable all functions using this pin */
+	return regmap_field_update_bits(priv->overlays, mask, 0);
+}
+
+static struct pinctrl_ops bcm6358_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6358_pinctrl_get_group_name,
+	.get_group_pins = bcm6358_pinctrl_get_group_pins,
+	.get_groups_count = bcm6358_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6358_pmx_ops = {
+	.get_function_groups = bcm6358_pinctrl_get_groups,
+	.get_function_name = bcm6358_pinctrl_get_func_name,
+	.get_functions_count = bcm6358_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6358_gpio_request_enable,
+	.set_mux = bcm6358_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6358_soc = {
+	.ngpios = BCM6358_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6358_pins),
+	.pctl_ops = &bcm6358_pctl_ops,
+	.pins = bcm6358_pins,
+	.pmx_ops = &bcm6358_pmx_ops,
+};
+
+static int bcm6358_pinctrl_probe(struct platform_device *pdev)
+{
+	struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15);
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct bcm6358_priv *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv);
+	if (err)
+		return err;
+
+	pc = platform_get_drvdata(pdev);
+
+	priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
+	if (IS_ERR(priv->overlays))
+		return PTR_ERR(priv->overlays);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6358_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6358-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


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

* [PATCH v6 07/15] pinctrl: add a pincontrol driver for BCM6358
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6358.c | 369 ++++++++++++++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index d35e5d3fe26f..ced7cc6ab44f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -44,6 +44,14 @@ config PINCTRL_BCM6328
 	help
 	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
 
+config PINCTRL_BCM6358
+	bool "Broadcom BCM6358 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 57e5434a6db6..c3f5b7b2f2f0 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c
new file mode 100644
index 000000000000..d638578727f3
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6358 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6358_NUM_GPIOS		40
+
+#define BCM6358_MODE_REG		0x18
+#define  BCM6358_MODE_MUX_NONE		0
+#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)
+
+struct bcm6358_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+
+	const uint16_t mode_val;
+
+	/* non-GPIO function muxes require the gpio direction to be set */
+	const uint16_t direction;
+};
+
+struct bcm6358_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+};
+
+struct bcm6358_priv {
+	struct regmap_field *overlays;
+};
+
+#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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6358_priv *priv = pc->driver_data;
+	const struct bcm6358_pingroup *pg = &bcm6358_groups[group];
+	unsigned int val = pg->mode_val;
+	unsigned int mask = val;
+	unsigned pin;
+
+	for (pin = 0; pin < pg->num_pins; pin++)
+		mask |= (unsigned long)bcm6358_pins[pin].drv_data;
+
+	regmap_field_update_bits(priv->overlays, mask, val);
+
+	for (pin = 0; pin < pg->num_pins; pin++) {
+		struct pinctrl_gpio_range *range;
+		unsigned int hw_gpio = bcm6358_pins[pin].number;
+
+		range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
+		if (range) {
+			struct gpio_chip *gc = range->gc;
+
+			if (pg->direction & BIT(pin))
+				gc->direction_output(gc, hw_gpio, 0);
+			else
+				gc->direction_input(gc, hw_gpio);
+		}
+	}
+
+	return 0;
+}
+
+static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6358_priv *priv = pc->driver_data;
+	unsigned int mask;
+
+	mask = (unsigned long) bcm6358_pins[offset].drv_data;
+	if (!mask)
+		return 0;
+
+	/* disable all functions using this pin */
+	return regmap_field_update_bits(priv->overlays, mask, 0);
+}
+
+static struct pinctrl_ops bcm6358_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6358_pinctrl_get_group_name,
+	.get_group_pins = bcm6358_pinctrl_get_group_pins,
+	.get_groups_count = bcm6358_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6358_pmx_ops = {
+	.get_function_groups = bcm6358_pinctrl_get_groups,
+	.get_function_name = bcm6358_pinctrl_get_func_name,
+	.get_functions_count = bcm6358_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6358_gpio_request_enable,
+	.set_mux = bcm6358_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6358_soc = {
+	.ngpios = BCM6358_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6358_pins),
+	.pctl_ops = &bcm6358_pctl_ops,
+	.pins = bcm6358_pins,
+	.pmx_ops = &bcm6358_pmx_ops,
+};
+
+static int bcm6358_pinctrl_probe(struct platform_device *pdev)
+{
+	struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15);
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct bcm6358_priv *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv);
+	if (err)
+		return err;
+
+	pc = platform_get_drvdata(pdev);
+
+	priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
+	if (IS_ERR(priv->overlays))
+		return PTR_ERR(priv->overlays);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6358_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6358-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 08/15] dt-bindings: add BCM6362 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6362-pinctrl.yaml         | 253 ++++++++++++++++++
 1 file changed, 253 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
new file mode 100644
index 000000000000..b8be37f06673
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
@@ -0,0 +1,253 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6362 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6362-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6362-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data,
+                  robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1,
+                  inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts,
+                  uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso,
+                  adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led,
+                  ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1,
+                  ext_irq2, ext_irq3, nand ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
+                  gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21,
+                  gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6362-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6362-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6362-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 48>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio0";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          pins = "gpio1";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio2";
+          };
+
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio3";
+          };
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio4";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio5";
+        };
+
+        pinctrl_robosw_led0: robosw_led0-pins {
+          function = "robosw_led0";
+          pins = "gpio6";
+        };
+
+        pinctrl_robosw_led1: robosw_led1-pins {
+          function = "robosw_led1";
+          pins = "gpio7";
+        };
+
+        pinctrl_inet_led: inet_led-pins {
+          function = "inet_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_spi_cs2: spi_cs2-pins {
+          function = "spi_cs2";
+          pins = "gpio9";
+        };
+
+        pinctrl_spi_cs3: spi_cs3-pins {
+          function = "spi_cs3";
+          pins = "gpio10";
+        };
+
+        pinctrl_ntr_pulse: ntr_pulse-pins {
+          function = "ntr_pulse";
+          pins = "gpio11";
+        };
+
+        pinctrl_uart1_scts: uart1_scts-pins {
+          function = "uart1_scts";
+          pins = "gpio12";
+        };
+
+        pinctrl_uart1_srts: uart1_srts-pins {
+          function = "uart1_srts";
+          pins = "gpio13";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          pinctrl_uart1_sdin: uart1_sdin-pins {
+            function = "uart1_sdin";
+            pins = "gpio14";
+          };
+
+          pinctrl_uart1_sdout: uart1_sdout-pins {
+            function = "uart1_sdout";
+            pins = "gpio15";
+          };
+        };
+
+        pinctrl_adsl_spi: adsl_spi-pins {
+          pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
+            function = "adsl_spi_miso";
+            pins = "gpio16";
+          };
+
+          pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
+            function = "adsl_spi_mosi";
+            pins = "gpio17";
+          };
+
+          pinctrl_adsl_spi_clk: adsl_spi_clk-pins {
+            function = "adsl_spi_clk";
+            pins = "gpio18";
+          };
+
+          pinctrl_adsl_spi_cs: adsl_spi_cs-pins {
+            function = "adsl_spi_cs";
+            pins = "gpio19";
+          };
+        };
+
+        pinctrl_ephy0_led: ephy0_led-pins {
+          function = "ephy0_led";
+          pins = "gpio20";
+        };
+
+        pinctrl_ephy1_led: ephy1_led-pins {
+          function = "ephy1_led";
+          pins = "gpio21";
+        };
+
+        pinctrl_ephy2_led: ephy2_led-pins {
+          function = "ephy2_led";
+          pins = "gpio22";
+        };
+
+        pinctrl_ephy3_led: ephy3_led-pins {
+          function = "ephy3_led";
+          pins = "gpio23";
+        };
+
+        pinctrl_ext_irq0: ext_irq0-pins {
+          function = "ext_irq0";
+          pins = "gpio24";
+        };
+
+        pinctrl_ext_irq1: ext_irq1-pins {
+          function = "ext_irq1";
+          pins = "gpio25";
+        };
+
+        pinctrl_ext_irq2: ext_irq2-pins {
+          function = "ext_irq2";
+          pins = "gpio26";
+        };
+
+        pinctrl_ext_irq3: ext_irq3-pins {
+          function = "ext_irq3";
+          pins = "gpio27";
+        };
+
+        pinctrl_nand: nand-pins {
+          function = "nand";
+          group = "nand_grp";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 08/15] dt-bindings: add BCM6362 pincontroller binding documentation
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6362-pinctrl.yaml         | 253 ++++++++++++++++++
 1 file changed, 253 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
new file mode 100644
index 000000000000..b8be37f06673
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
@@ -0,0 +1,253 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6362 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6362-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6362-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data,
+                  robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1,
+                  inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts,
+                  uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso,
+                  adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led,
+                  ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1,
+                  ext_irq2, ext_irq3, nand ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
+                  gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21,
+                  gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6362-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6362-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6362-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 48>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio0";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          pins = "gpio1";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio2";
+          };
+
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio3";
+          };
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio4";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio5";
+        };
+
+        pinctrl_robosw_led0: robosw_led0-pins {
+          function = "robosw_led0";
+          pins = "gpio6";
+        };
+
+        pinctrl_robosw_led1: robosw_led1-pins {
+          function = "robosw_led1";
+          pins = "gpio7";
+        };
+
+        pinctrl_inet_led: inet_led-pins {
+          function = "inet_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_spi_cs2: spi_cs2-pins {
+          function = "spi_cs2";
+          pins = "gpio9";
+        };
+
+        pinctrl_spi_cs3: spi_cs3-pins {
+          function = "spi_cs3";
+          pins = "gpio10";
+        };
+
+        pinctrl_ntr_pulse: ntr_pulse-pins {
+          function = "ntr_pulse";
+          pins = "gpio11";
+        };
+
+        pinctrl_uart1_scts: uart1_scts-pins {
+          function = "uart1_scts";
+          pins = "gpio12";
+        };
+
+        pinctrl_uart1_srts: uart1_srts-pins {
+          function = "uart1_srts";
+          pins = "gpio13";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          pinctrl_uart1_sdin: uart1_sdin-pins {
+            function = "uart1_sdin";
+            pins = "gpio14";
+          };
+
+          pinctrl_uart1_sdout: uart1_sdout-pins {
+            function = "uart1_sdout";
+            pins = "gpio15";
+          };
+        };
+
+        pinctrl_adsl_spi: adsl_spi-pins {
+          pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
+            function = "adsl_spi_miso";
+            pins = "gpio16";
+          };
+
+          pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
+            function = "adsl_spi_mosi";
+            pins = "gpio17";
+          };
+
+          pinctrl_adsl_spi_clk: adsl_spi_clk-pins {
+            function = "adsl_spi_clk";
+            pins = "gpio18";
+          };
+
+          pinctrl_adsl_spi_cs: adsl_spi_cs-pins {
+            function = "adsl_spi_cs";
+            pins = "gpio19";
+          };
+        };
+
+        pinctrl_ephy0_led: ephy0_led-pins {
+          function = "ephy0_led";
+          pins = "gpio20";
+        };
+
+        pinctrl_ephy1_led: ephy1_led-pins {
+          function = "ephy1_led";
+          pins = "gpio21";
+        };
+
+        pinctrl_ephy2_led: ephy2_led-pins {
+          function = "ephy2_led";
+          pins = "gpio22";
+        };
+
+        pinctrl_ephy3_led: ephy3_led-pins {
+          function = "ephy3_led";
+          pins = "gpio23";
+        };
+
+        pinctrl_ext_irq0: ext_irq0-pins {
+          function = "ext_irq0";
+          pins = "gpio24";
+        };
+
+        pinctrl_ext_irq1: ext_irq1-pins {
+          function = "ext_irq1";
+          pins = "gpio25";
+        };
+
+        pinctrl_ext_irq2: ext_irq2-pins {
+          function = "ext_irq2";
+          pins = "gpio26";
+        };
+
+        pinctrl_ext_irq3: ext_irq3-pins {
+          function = "ext_irq3";
+          pins = "gpio27";
+        };
+
+        pinctrl_nand: nand-pins {
+          function = "nand";
+          group = "nand_grp";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 09/15] pinctrl: add a pincontrol driver for BCM6362
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6362.c | 617 ++++++++++++++++++++++++++
 3 files changed, 626 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index ced7cc6ab44f..d3101d5e750f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -52,6 +52,14 @@ config PINCTRL_BCM6358
 	help
 	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
 
+config PINCTRL_BCM6362
+	bool "Broadcom BCM6362 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index c3f5b7b2f2f0..b9b09e5b914c 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
+obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c
new file mode 100644
index 000000000000..eb7ec80353e9
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c
@@ -0,0 +1,617 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6362_BANK_GPIOS	32
+#define BCM6362_NUM_GPIOS	48
+#define BCM6362_NUM_LEDS	24
+
+#define BCM6362_LED_REG		0x10
+#define BCM6362_MODE_REG	0x18
+#define BCM6362_CTRL_REG	0x1c
+#define BCM6362_BASEMODE_REG	0x38
+#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;
+	uint32_t basemode_mask;
+};
+
+#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_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
+	unsigned int mask = bcm63xx_bank_pin(pin);
+
+	if (desc->drv_data)
+		regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG,
+				   (uint32_t) desc->drv_data, 0);
+
+	if (pin < BCM63XX_BANK_GPIOS) {
+		/* base mode 0 => gpio 1 => mux function */
+		regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < BCM6362_NUM_LEDS)
+			regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
+	} else {
+		/* ctrl reg 0 => wifi function 1 => gpio */
+		regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
+	}
+}
+
+static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
+	const struct bcm6362_function *f = &bcm6362_funcs[selector];
+	unsigned i;
+	unsigned int reg;
+	unsigned int val, mask;
+
+	for (i = 0; i < pg->num_pins; i++)
+		bcm6362_set_gpio(pc, pg->pins[i]);
+
+	switch (f->reg) {
+	case BCM6362_LEDCTRL:
+		reg = BCM6362_LED_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM6362_MODE:
+		reg = BCM6362_MODE_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM6362_CTRL:
+		reg = BCM6362_CTRL_REG;
+		mask = BIT(pg->pins[0]);
+		val = 0;
+		break;
+	case BCM6362_BASEMODE:
+		reg = BCM6362_BASEMODE_REG;
+		mask = f->basemode_mask;
+		val = f->basemode_mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(pc->regs, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6362_set_gpio(pc, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6362_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6362_pinctrl_get_group_name,
+	.get_group_pins = bcm6362_pinctrl_get_group_pins,
+	.get_groups_count = bcm6362_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6362_pmx_ops = {
+	.get_function_groups = bcm6362_pinctrl_get_groups,
+	.get_function_name = bcm6362_pinctrl_get_func_name,
+	.get_functions_count = bcm6362_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6362_gpio_request_enable,
+	.set_mux = bcm6362_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
+	.ngpios = BCM6362_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6362_pins),
+	.pctl_ops = &bcm6362_pctl_ops,
+	.pins = bcm6362_pins,
+	.pmx_ops = &bcm6362_pmx_ops,
+};
+
+static int bcm6362_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
+}
+
+static const struct of_device_id bcm6362_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6362-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


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

* [PATCH v6 09/15] pinctrl: add a pincontrol driver for BCM6362
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6362.c | 617 ++++++++++++++++++++++++++
 3 files changed, 626 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index ced7cc6ab44f..d3101d5e750f 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -52,6 +52,14 @@ config PINCTRL_BCM6358
 	help
 	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
 
+config PINCTRL_BCM6362
+	bool "Broadcom BCM6362 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index c3f5b7b2f2f0..b9b09e5b914c 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
+obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c
new file mode 100644
index 000000000000..eb7ec80353e9
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c
@@ -0,0 +1,617 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6362_BANK_GPIOS	32
+#define BCM6362_NUM_GPIOS	48
+#define BCM6362_NUM_LEDS	24
+
+#define BCM6362_LED_REG		0x10
+#define BCM6362_MODE_REG	0x18
+#define BCM6362_CTRL_REG	0x1c
+#define BCM6362_BASEMODE_REG	0x38
+#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;
+	uint32_t basemode_mask;
+};
+
+#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_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
+	unsigned int mask = bcm63xx_bank_pin(pin);
+
+	if (desc->drv_data)
+		regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG,
+				   (uint32_t) desc->drv_data, 0);
+
+	if (pin < BCM63XX_BANK_GPIOS) {
+		/* base mode 0 => gpio 1 => mux function */
+		regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < BCM6362_NUM_LEDS)
+			regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
+	} else {
+		/* ctrl reg 0 => wifi function 1 => gpio */
+		regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
+	}
+}
+
+static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
+	const struct bcm6362_function *f = &bcm6362_funcs[selector];
+	unsigned i;
+	unsigned int reg;
+	unsigned int val, mask;
+
+	for (i = 0; i < pg->num_pins; i++)
+		bcm6362_set_gpio(pc, pg->pins[i]);
+
+	switch (f->reg) {
+	case BCM6362_LEDCTRL:
+		reg = BCM6362_LED_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM6362_MODE:
+		reg = BCM6362_MODE_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM6362_CTRL:
+		reg = BCM6362_CTRL_REG;
+		mask = BIT(pg->pins[0]);
+		val = 0;
+		break;
+	case BCM6362_BASEMODE:
+		reg = BCM6362_BASEMODE_REG;
+		mask = f->basemode_mask;
+		val = f->basemode_mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(pc->regs, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm6362_set_gpio(pc, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6362_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6362_pinctrl_get_group_name,
+	.get_group_pins = bcm6362_pinctrl_get_group_pins,
+	.get_groups_count = bcm6362_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6362_pmx_ops = {
+	.get_function_groups = bcm6362_pinctrl_get_groups,
+	.get_function_name = bcm6362_pinctrl_get_func_name,
+	.get_functions_count = bcm6362_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6362_gpio_request_enable,
+	.set_mux = bcm6362_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
+	.ngpios = BCM6362_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6362_pins),
+	.pctl_ops = &bcm6362_pctl_ops,
+	.pins = bcm6362_pins,
+	.pmx_ops = &bcm6362_pmx_ops,
+};
+
+static int bcm6362_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
+}
+
+static const struct of_device_id bcm6362_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6362-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 10/15] dt-bindings: add BCM6368 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6368-pinctrl.yaml         | 264 ++++++++++++++++++
 1 file changed, 264 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
new file mode 100644
index 000000000000..de0e4e549f9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
@@ -0,0 +1,264 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6368 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6368-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6368-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data,
+                  serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led,
+                  ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0,
+                  robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb,
+                  pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1,
+                  pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4,
+                  spi_cs5, uart1 ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
+                  gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23,
+                  gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30,
+                  gpio31, uart1_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6368-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6368-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6368-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 38>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_analog_afe_0: analog_afe_0-pins {
+          function = "analog_afe_0";
+          pins = "gpio0";
+        };
+
+        pinctrl_analog_afe_1: analog_afe_1-pins {
+          function = "analog_afe_1";
+          pins = "gpio1";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          pins = "gpio2";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio3";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio4";
+          };
+        };
+
+        pinctrl_inet_led: inet_led-pins {
+          function = "inet_led";
+          pins = "gpio5";
+        };
+
+        pinctrl_ephy0_led: ephy0_led-pins {
+          function = "ephy0_led";
+          pins = "gpio6";
+        };
+
+        pinctrl_ephy1_led: ephy1_led-pins {
+          function = "ephy1_led";
+          pins = "gpio7";
+        };
+
+        pinctrl_ephy2_led: ephy2_led-pins {
+          function = "ephy2_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_ephy3_led: ephy3_led-pins {
+          function = "ephy3_led";
+          pins = "gpio9";
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio10";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio11";
+        };
+
+        pinctrl_robosw_led0: robosw_led0-pins {
+          function = "robosw_led0";
+          pins = "gpio12";
+        };
+
+        pinctrl_robosw_led1: robosw_led1-pins {
+          function = "robosw_led1";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio14";
+        };
+
+        pinctrl_pci: pci-pins {
+          pinctrl_pci_req1: pci_req1-pins {
+            function = "pci_req1";
+            pins = "gpio16";
+          };
+
+          pinctrl_pci_gnt1: pci_gnt1-pins {
+            function = "pci_gnt1";
+            pins = "gpio17";
+          };
+
+          pinctrl_pci_intb: pci_intb-pins {
+            function = "pci_intb";
+            pins = "gpio18";
+          };
+
+          pinctrl_pci_req0: pci_req0-pins {
+            function = "pci_req0";
+            pins = "gpio19";
+          };
+
+          pinctrl_pci_gnt0: pci_gnt0-pins {
+            function = "pci_gnt0";
+            pins = "gpio20";
+          };
+        };
+
+        pinctrl_pcmcia: pcmcia-pins {
+          pinctrl_pcmcia_cd1: pcmcia_cd1-pins {
+            function = "pcmcia_cd1";
+            pins = "gpio22";
+          };
+
+          pinctrl_pcmcia_cd2: pcmcia_cd2-pins {
+            function = "pcmcia_cd2";
+            pins = "gpio23";
+          };
+
+          pinctrl_pcmcia_vs1: pcmcia_vs1-pins {
+            function = "pcmcia_vs1";
+            pins = "gpio24";
+          };
+
+          pinctrl_pcmcia_vs2: pcmcia_vs2-pins {
+            function = "pcmcia_vs2";
+            pins = "gpio25";
+          };
+        };
+
+        pinctrl_ebi_cs2: ebi_cs2-pins {
+          function = "ebi_cs2";
+          pins = "gpio26";
+        };
+
+        pinctrl_ebi_cs3: ebi_cs3-pins {
+          function = "ebi_cs3";
+          pins = "gpio27";
+        };
+
+        pinctrl_spi_cs2: spi_cs2-pins {
+          function = "spi_cs2";
+          pins = "gpio28";
+        };
+
+        pinctrl_spi_cs3: spi_cs3-pins {
+          function = "spi_cs3";
+          pins = "gpio29";
+        };
+
+        pinctrl_spi_cs4: spi_cs4-pins {
+          function = "spi_cs4";
+          pins = "gpio30";
+        };
+
+        pinctrl_spi_cs5: spi_cs5-pins {
+          function = "spi_cs5";
+          pins = "gpio31";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          function = "uart1";
+          group = "uart1_grp";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 10/15] dt-bindings: add BCM6368 pincontroller binding documentation
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6368-pinctrl.yaml         | 264 ++++++++++++++++++
 1 file changed, 264 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
new file mode 100644
index 000000000000..de0e4e549f9e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
@@ -0,0 +1,264 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6368 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6368-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6368-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data,
+                  serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led,
+                  ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0,
+                  robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb,
+                  pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1,
+                  pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4,
+                  spi_cs5, uart1 ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
+                  gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23,
+                  gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30,
+                  gpio31, uart1_grp ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6368-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6368-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6368-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 38>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_analog_afe_0: analog_afe_0-pins {
+          function = "analog_afe_0";
+          pins = "gpio0";
+        };
+
+        pinctrl_analog_afe_1: analog_afe_1-pins {
+          function = "analog_afe_1";
+          pins = "gpio1";
+        };
+
+        pinctrl_sys_irq: sys_irq-pins {
+          function = "sys_irq";
+          pins = "gpio2";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio3";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio4";
+          };
+        };
+
+        pinctrl_inet_led: inet_led-pins {
+          function = "inet_led";
+          pins = "gpio5";
+        };
+
+        pinctrl_ephy0_led: ephy0_led-pins {
+          function = "ephy0_led";
+          pins = "gpio6";
+        };
+
+        pinctrl_ephy1_led: ephy1_led-pins {
+          function = "ephy1_led";
+          pins = "gpio7";
+        };
+
+        pinctrl_ephy2_led: ephy2_led-pins {
+          function = "ephy2_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_ephy3_led: ephy3_led-pins {
+          function = "ephy3_led";
+          pins = "gpio9";
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio10";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio11";
+        };
+
+        pinctrl_robosw_led0: robosw_led0-pins {
+          function = "robosw_led0";
+          pins = "gpio12";
+        };
+
+        pinctrl_robosw_led1: robosw_led1-pins {
+          function = "robosw_led1";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio14";
+        };
+
+        pinctrl_pci: pci-pins {
+          pinctrl_pci_req1: pci_req1-pins {
+            function = "pci_req1";
+            pins = "gpio16";
+          };
+
+          pinctrl_pci_gnt1: pci_gnt1-pins {
+            function = "pci_gnt1";
+            pins = "gpio17";
+          };
+
+          pinctrl_pci_intb: pci_intb-pins {
+            function = "pci_intb";
+            pins = "gpio18";
+          };
+
+          pinctrl_pci_req0: pci_req0-pins {
+            function = "pci_req0";
+            pins = "gpio19";
+          };
+
+          pinctrl_pci_gnt0: pci_gnt0-pins {
+            function = "pci_gnt0";
+            pins = "gpio20";
+          };
+        };
+
+        pinctrl_pcmcia: pcmcia-pins {
+          pinctrl_pcmcia_cd1: pcmcia_cd1-pins {
+            function = "pcmcia_cd1";
+            pins = "gpio22";
+          };
+
+          pinctrl_pcmcia_cd2: pcmcia_cd2-pins {
+            function = "pcmcia_cd2";
+            pins = "gpio23";
+          };
+
+          pinctrl_pcmcia_vs1: pcmcia_vs1-pins {
+            function = "pcmcia_vs1";
+            pins = "gpio24";
+          };
+
+          pinctrl_pcmcia_vs2: pcmcia_vs2-pins {
+            function = "pcmcia_vs2";
+            pins = "gpio25";
+          };
+        };
+
+        pinctrl_ebi_cs2: ebi_cs2-pins {
+          function = "ebi_cs2";
+          pins = "gpio26";
+        };
+
+        pinctrl_ebi_cs3: ebi_cs3-pins {
+          function = "ebi_cs3";
+          pins = "gpio27";
+        };
+
+        pinctrl_spi_cs2: spi_cs2-pins {
+          function = "spi_cs2";
+          pins = "gpio28";
+        };
+
+        pinctrl_spi_cs3: spi_cs3-pins {
+          function = "spi_cs3";
+          pins = "gpio29";
+        };
+
+        pinctrl_spi_cs4: spi_cs4-pins {
+          function = "spi_cs4";
+          pins = "gpio30";
+        };
+
+        pinctrl_spi_cs5: spi_cs5-pins {
+          function = "spi_cs5";
+          pins = "gpio31";
+        };
+
+        pinctrl_uart1: uart1-pins {
+          function = "uart1";
+          group = "uart1_grp";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 11/15] pinctrl: add a pincontrol driver for BCM6368
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6368.c | 523 ++++++++++++++++++++++++++
 3 files changed, 532 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index d3101d5e750f..aabd4b762aed 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -60,6 +60,14 @@ config PINCTRL_BCM6362
 	help
 	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
 
+config PINCTRL_BCM6368
+	bool "Broadcom BCM6368 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index b9b09e5b914c..a1331bb9680e 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.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_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c
new file mode 100644
index 000000000000..838095f9e890
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6368 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6368_NUM_GPIOS	38
+
+#define BCM6368_MODE_REG	0x18
+#define BCM6368_BASEMODE_REG	0x38
+#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_priv {
+	struct regmap_field *overlays;
+};
+
+#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 int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6368_priv *priv = pc->driver_data;
+	const struct bcm6368_pingroup *pg = &bcm6368_groups[group];
+	const struct bcm6368_function *fun = &bcm6368_funcs[selector];
+	int i, pin;
+
+	if (fun->basemode) {
+		unsigned int mask = 0;
+
+		for (i = 0; i < pg->num_pins; i++) {
+			pin = pg->pins[i];
+			if (pin < BCM63XX_BANK_GPIOS)
+				mask |= BIT(pin);
+		}
+
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0);
+		regmap_field_write(priv->overlays, fun->basemode);
+	} else {
+		pin = pg->pins[0];
+
+		if (bcm6368_pins[pin].drv_data)
+			regmap_field_write(priv->overlays,
+					   BCM6368_BASEMODE_GPIO);
+
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin),
+				   BIT(pin));
+	}
+
+	for (pin = 0; pin < pg->num_pins; pin++) {
+		struct pinctrl_gpio_range *range;
+		int hw_gpio = bcm6368_pins[pin].number;
+
+		range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
+		if (range) {
+			struct gpio_chip *gc = range->gc;
+
+			if (fun->dir_out & BIT(pin))
+				gc->direction_output(gc, hw_gpio, 0);
+			else
+				gc->direction_input(gc, hw_gpio);
+		}
+	}
+
+	return 0;
+}
+
+static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6368_priv *priv = pc->driver_data;
+
+	if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data)
+		return 0;
+
+	/* disable all functions using this pin */
+	if (offset < BCM63XX_BANK_GPIOS)
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0);
+
+	if (bcm6368_pins[offset].drv_data)
+		regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6368_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6368_pinctrl_get_group_name,
+	.get_group_pins = bcm6368_pinctrl_get_group_pins,
+	.get_groups_count = bcm6368_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6368_pmx_ops = {
+	.get_function_groups = bcm6368_pinctrl_get_groups,
+	.get_function_name = bcm6368_pinctrl_get_func_name,
+	.get_functions_count = bcm6368_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6368_gpio_request_enable,
+	.set_mux = bcm6368_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6368_soc = {
+	.ngpios = BCM6368_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6368_pins),
+	.pctl_ops = &bcm6368_pctl_ops,
+	.pins = bcm6368_pins,
+	.pmx_ops = &bcm6368_pmx_ops,
+};
+
+static int bcm6368_pinctrl_probe(struct platform_device *pdev)
+{
+	struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15);
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct bcm6368_priv *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv);
+	if (err)
+		return err;
+
+	pc = platform_get_drvdata(pdev);
+
+	priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
+	if (IS_ERR(priv->overlays))
+		return PTR_ERR(priv->overlays);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6368_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6368-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


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

* [PATCH v6 11/15] pinctrl: add a pincontrol driver for BCM6368
@ 2021-03-10 12:54   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:54 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6368.c | 523 ++++++++++++++++++++++++++
 3 files changed, 532 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index d3101d5e750f..aabd4b762aed 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -60,6 +60,14 @@ config PINCTRL_BCM6362
 	help
 	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
 
+config PINCTRL_BCM6368
+	bool "Broadcom BCM6368 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index b9b09e5b914c..a1331bb9680e 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.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_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c
new file mode 100644
index 000000000000..838095f9e890
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6368 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6368_NUM_GPIOS	38
+
+#define BCM6368_MODE_REG	0x18
+#define BCM6368_BASEMODE_REG	0x38
+#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_priv {
+	struct regmap_field *overlays;
+};
+
+#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 int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6368_priv *priv = pc->driver_data;
+	const struct bcm6368_pingroup *pg = &bcm6368_groups[group];
+	const struct bcm6368_function *fun = &bcm6368_funcs[selector];
+	int i, pin;
+
+	if (fun->basemode) {
+		unsigned int mask = 0;
+
+		for (i = 0; i < pg->num_pins; i++) {
+			pin = pg->pins[i];
+			if (pin < BCM63XX_BANK_GPIOS)
+				mask |= BIT(pin);
+		}
+
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0);
+		regmap_field_write(priv->overlays, fun->basemode);
+	} else {
+		pin = pg->pins[0];
+
+		if (bcm6368_pins[pin].drv_data)
+			regmap_field_write(priv->overlays,
+					   BCM6368_BASEMODE_GPIO);
+
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin),
+				   BIT(pin));
+	}
+
+	for (pin = 0; pin < pg->num_pins; pin++) {
+		struct pinctrl_gpio_range *range;
+		int hw_gpio = bcm6368_pins[pin].number;
+
+		range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
+		if (range) {
+			struct gpio_chip *gc = range->gc;
+
+			if (fun->dir_out & BIT(pin))
+				gc->direction_output(gc, hw_gpio, 0);
+			else
+				gc->direction_input(gc, hw_gpio);
+		}
+	}
+
+	return 0;
+}
+
+static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	struct bcm6368_priv *priv = pc->driver_data;
+
+	if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data)
+		return 0;
+
+	/* disable all functions using this pin */
+	if (offset < BCM63XX_BANK_GPIOS)
+		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0);
+
+	if (bcm6368_pins[offset].drv_data)
+		regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6368_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6368_pinctrl_get_group_name,
+	.get_group_pins = bcm6368_pinctrl_get_group_pins,
+	.get_groups_count = bcm6368_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6368_pmx_ops = {
+	.get_function_groups = bcm6368_pinctrl_get_groups,
+	.get_function_name = bcm6368_pinctrl_get_func_name,
+	.get_functions_count = bcm6368_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6368_gpio_request_enable,
+	.set_mux = bcm6368_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6368_soc = {
+	.ngpios = BCM6368_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6368_pins),
+	.pctl_ops = &bcm6368_pctl_ops,
+	.pins = bcm6368_pins,
+	.pmx_ops = &bcm6368_pmx_ops,
+};
+
+static int bcm6368_pinctrl_probe(struct platform_device *pdev)
+{
+	struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15);
+	struct device *dev = &pdev->dev;
+	struct bcm63xx_pinctrl *pc;
+	struct bcm6368_priv *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv);
+	if (err)
+		return err;
+
+	pc = platform_get_drvdata(pdev);
+
+	priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
+	if (IS_ERR(priv->overlays))
+		return PTR_ERR(priv->overlays);
+
+	return 0;
+}
+
+static const struct of_device_id bcm6368_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6368-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 12/15] dt-bindings: add BCM63268 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm63268-pinctrl.yaml        | 211 ++++++++++++++++++
 1 file changed, 211 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
new file mode 100644
index 000000000000..9ff91ea96aef
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
@@ -0,0 +1,211 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM63268 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm63268-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm63268-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5,
+                  hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi,
+                  vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data,
+                  nand, gpio35_alt, dectpd, vdsl_phy_override_0,
+                  vdsl_phy_override_1, vdsl_phy_override_2,
+                  vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19,
+                  gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35
+                  dectpd_grp, vdsl_phy_override_0_grp,
+                  vdsl_phy_override_1_grp, vdsl_phy_override_2_grp,
+                  vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@100000c0 {
+      compatible = "brcm,bcm63268-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x100000c0 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm63268-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm63268-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 52>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio0";
+          };
+
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio1";
+          };
+        };
+
+        pinctrl_hsspi_cs4: hsspi_cs4-pins {
+          function = "hsspi_cs4";
+          pins = "gpio16";
+        };
+
+        pinctrl_hsspi_cs5: hsspi_cs5-pins {
+          function = "hsspi_cs5";
+          pins = "gpio17";
+        };
+
+        pinctrl_hsspi_cs6: hsspi_cs6-pins {
+          function = "hsspi_cs6";
+          pins = "gpio8";
+        };
+
+        pinctrl_hsspi_cs7: hsspi_cs7-pins {
+          function = "hsspi_cs7";
+          pins = "gpio9";
+        };
+
+        pinctrl_adsl_spi: adsl_spi-pins {
+          pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
+            function = "adsl_spi_miso";
+            pins = "gpio18";
+          };
+
+          pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
+            function = "adsl_spi_mosi";
+            pins = "gpio19";
+          };
+        };
+
+        pinctrl_vreq_clk: vreq_clk-pins {
+          function = "vreq_clk";
+          pins = "gpio22";
+        };
+
+        pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins {
+          function = "pcie_clkreq_b";
+          pins = "gpio23";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio30";
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio31";
+        };
+
+        pinctrl_nand: nand-pins {
+          function = "nand";
+          group = "nand_grp";
+        };
+
+        pinctrl_gpio35_alt: gpio35_alt-pins {
+          function = "gpio35_alt";
+          pin = "gpio35";
+        };
+
+        pinctrl_dectpd: dectpd-pins {
+          function = "dectpd";
+          group = "dectpd_grp";
+        };
+
+        pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins {
+          function = "vdsl_phy_override_0";
+          group = "vdsl_phy_override_0_grp";
+        };
+
+        pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins {
+          function = "vdsl_phy_override_1";
+          group = "vdsl_phy_override_1_grp";
+        };
+
+        pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins {
+          function = "vdsl_phy_override_2";
+          group = "vdsl_phy_override_2_grp";
+        };
+
+        pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins {
+          function = "vdsl_phy_override_3";
+          group = "vdsl_phy_override_3_grp";
+        };
+
+        pinctrl_dsl_gpio8: dsl_gpio8-pins {
+          function = "dsl_gpio8";
+          group = "dsl_gpio8";
+        };
+
+        pinctrl_dsl_gpio9: dsl_gpio9-pins {
+          function = "dsl_gpio9";
+          group = "dsl_gpio9";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 12/15] dt-bindings: add BCM63268 pincontroller binding documentation
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm63268-pinctrl.yaml        | 211 ++++++++++++++++++
 1 file changed, 211 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
new file mode 100644
index 000000000000..9ff91ea96aef
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
@@ -0,0 +1,211 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM63268 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm63268-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm63268-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5,
+                  hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi,
+                  vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data,
+                  nand, gpio35_alt, dectpd, vdsl_phy_override_0,
+                  vdsl_phy_override_1, vdsl_phy_override_2,
+                  vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19,
+                  gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35
+                  dectpd_grp, vdsl_phy_override_0_grp,
+                  vdsl_phy_override_1_grp, vdsl_phy_override_2_grp,
+                  vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@100000c0 {
+      compatible = "brcm,bcm63268-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x100000c0 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm63268-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm63268-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 52>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio0";
+          };
+
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio1";
+          };
+        };
+
+        pinctrl_hsspi_cs4: hsspi_cs4-pins {
+          function = "hsspi_cs4";
+          pins = "gpio16";
+        };
+
+        pinctrl_hsspi_cs5: hsspi_cs5-pins {
+          function = "hsspi_cs5";
+          pins = "gpio17";
+        };
+
+        pinctrl_hsspi_cs6: hsspi_cs6-pins {
+          function = "hsspi_cs6";
+          pins = "gpio8";
+        };
+
+        pinctrl_hsspi_cs7: hsspi_cs7-pins {
+          function = "hsspi_cs7";
+          pins = "gpio9";
+        };
+
+        pinctrl_adsl_spi: adsl_spi-pins {
+          pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
+            function = "adsl_spi_miso";
+            pins = "gpio18";
+          };
+
+          pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
+            function = "adsl_spi_mosi";
+            pins = "gpio19";
+          };
+        };
+
+        pinctrl_vreq_clk: vreq_clk-pins {
+          function = "vreq_clk";
+          pins = "gpio22";
+        };
+
+        pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins {
+          function = "pcie_clkreq_b";
+          pins = "gpio23";
+        };
+
+        pinctrl_robosw_led_clk: robosw_led_clk-pins {
+          function = "robosw_led_clk";
+          pins = "gpio30";
+        };
+
+        pinctrl_robosw_led_data: robosw_led_data-pins {
+          function = "robosw_led_data";
+          pins = "gpio31";
+        };
+
+        pinctrl_nand: nand-pins {
+          function = "nand";
+          group = "nand_grp";
+        };
+
+        pinctrl_gpio35_alt: gpio35_alt-pins {
+          function = "gpio35_alt";
+          pin = "gpio35";
+        };
+
+        pinctrl_dectpd: dectpd-pins {
+          function = "dectpd";
+          group = "dectpd_grp";
+        };
+
+        pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins {
+          function = "vdsl_phy_override_0";
+          group = "vdsl_phy_override_0_grp";
+        };
+
+        pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins {
+          function = "vdsl_phy_override_1";
+          group = "vdsl_phy_override_1_grp";
+        };
+
+        pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins {
+          function = "vdsl_phy_override_2";
+          group = "vdsl_phy_override_2_grp";
+        };
+
+        pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins {
+          function = "vdsl_phy_override_3";
+          group = "vdsl_phy_override_3_grp";
+        };
+
+        pinctrl_dsl_gpio8: dsl_gpio8-pins {
+          function = "dsl_gpio8";
+          group = "dsl_gpio8";
+        };
+
+        pinctrl_dsl_gpio9: dsl_gpio9-pins {
+          function = "dsl_gpio9";
+          group = "dsl_gpio9";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 13/15] pinctrl: add a pincontrol driver for BCM63268
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig            |   8 +
 drivers/pinctrl/bcm/Makefile           |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm63268.c | 643 +++++++++++++++++++++++++
 3 files changed, 652 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index aabd4b762aed..186985846120 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -68,6 +68,14 @@ config PINCTRL_BCM6368
 	help
 	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
 
+config PINCTRL_BCM63268
+	bool "Broadcom BCM63268 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM63268 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index a1331bb9680e..4117847fd279 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.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
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
new file mode 100644
index 000000000000..d4c5fad7fb7d
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
@@ -0,0 +1,643 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM63268 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM63268_NUM_GPIOS		52
+#define BCM63268_NUM_LEDS		24
+
+#define BCM63268_LED_REG		0x10
+#define BCM63268_MODE_REG		0x18
+#define BCM63268_CTRL_REG		0x1c
+#define BCM63268_BASEMODE_REG		0x38
+#define  BCM63268_BASEMODE_NAND		BIT(2) /* GPIOs 2-7, 24-31 */
+#define  BCM63268_BASEMODE_GPIO35	BIT(4) /* GPIO 35 */
+#define  BCM63268_BASEMODE_DECTPD	BIT(5) /* GPIOs 8/9 */
+#define  BCM63268_BASEMODE_VDSL_PHY_0	BIT(6) /* GPIOs 10/11 */
+#define  BCM63268_BASEMODE_VDSL_PHY_1	BIT(7) /* GPIOs 12/13 */
+#define  BCM63268_BASEMODE_VDSL_PHY_2	BIT(8) /* GPIOs 24/25 */
+#define  BCM63268_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;
+	uint32_t mask;
+};
+
+#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", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD),
+	BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD),
+	BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1),
+	BCM63268_PIN(13, "gpio13", BCM63268_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",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(25, "gpio25",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(26, "gpio26",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(27, "gpio27",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(31, "gpio31", BCM63268_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, BCM63268_BASEMODE_NAND),
+	BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_0,
+			      BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_1,
+			      BCM63268_BASEMODE_VDSL_PHY_1),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_2,
+			      BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_3,
+			      BCM63268_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_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
+	unsigned int basemode = (unsigned long) desc->drv_data;
+	unsigned int mask = BIT(bcm63xx_bank_pin(pin));
+
+	if (basemode)
+		regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
+				   0);
+
+	if (pin < BCM63XX_BANK_GPIOS) {
+		/* base mode: 0 => gpio, 1 => mux function */
+		regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < BCM63268_NUM_LEDS)
+			regmap_update_bits(pc->regs, BCM63268_LED_REG, mask,
+					   0);
+	} else if (pin < BCM63268_NUM_GPIOS) {
+		/* ctrl reg: 0 => wifi function, 1 => gpio */
+		regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask);
+	}
+}
+
+static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				    unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm63268_pingroup *pg = &bcm63268_groups[group];
+	const struct bcm63268_function *f = &bcm63268_funcs[selector];
+	unsigned i;
+	unsigned int reg;
+	unsigned int val, mask;
+
+	for (i = 0; i < pg->num_pins; i++)
+		bcm63268_set_gpio(pc, pg->pins[i]);
+
+	switch (f->reg) {
+	case BCM63268_LEDCTRL:
+		reg = BCM63268_LED_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM63268_MODE:
+		reg = BCM63268_MODE_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM63268_CTRL:
+		reg = BCM63268_CTRL_REG;
+		mask = BIT(pg->pins[0]);
+		val = 0;
+		break;
+	case BCM63268_BASEMODE:
+		reg = BCM63268_BASEMODE_REG;
+		mask = f->mask;
+		val = f->mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(pc->regs, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm63268_set_gpio(pc, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm63268_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm63268_pinctrl_get_group_name,
+	.get_group_pins = bcm63268_pinctrl_get_group_pins,
+	.get_groups_count = bcm63268_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm63268_pmx_ops = {
+	.get_function_groups = bcm63268_pinctrl_get_groups,
+	.get_function_name = bcm63268_pinctrl_get_func_name,
+	.get_functions_count = bcm63268_pinctrl_get_func_count,
+	.gpio_request_enable = bcm63268_gpio_request_enable,
+	.set_mux = bcm63268_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm63268_soc = {
+	.ngpios = BCM63268_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm63268_pins),
+	.pctl_ops = &bcm63268_pctl_ops,
+	.pins = bcm63268_pins,
+	.pmx_ops = &bcm63268_pmx_ops,
+};
+
+static int bcm63268_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL);
+}
+
+static const struct of_device_id bcm63268_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm63268-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


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

* [PATCH v6 13/15] pinctrl: add a pincontrol driver for BCM63268
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig            |   8 +
 drivers/pinctrl/bcm/Makefile           |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm63268.c | 643 +++++++++++++++++++++++++
 3 files changed, 652 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index aabd4b762aed..186985846120 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -68,6 +68,14 @@ config PINCTRL_BCM6368
 	help
 	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
 
+config PINCTRL_BCM63268
+	bool "Broadcom BCM63268 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM63268 GPIO driver.
+
 config PINCTRL_IPROC_GPIO
 	bool "Broadcom iProc GPIO (with PINCONF) driver"
 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index a1331bb9680e..4117847fd279 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.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
 obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
 obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
 obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
new file mode 100644
index 000000000000..d4c5fad7fb7d
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
@@ -0,0 +1,643 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM63268 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM63268_NUM_GPIOS		52
+#define BCM63268_NUM_LEDS		24
+
+#define BCM63268_LED_REG		0x10
+#define BCM63268_MODE_REG		0x18
+#define BCM63268_CTRL_REG		0x1c
+#define BCM63268_BASEMODE_REG		0x38
+#define  BCM63268_BASEMODE_NAND		BIT(2) /* GPIOs 2-7, 24-31 */
+#define  BCM63268_BASEMODE_GPIO35	BIT(4) /* GPIO 35 */
+#define  BCM63268_BASEMODE_DECTPD	BIT(5) /* GPIOs 8/9 */
+#define  BCM63268_BASEMODE_VDSL_PHY_0	BIT(6) /* GPIOs 10/11 */
+#define  BCM63268_BASEMODE_VDSL_PHY_1	BIT(7) /* GPIOs 12/13 */
+#define  BCM63268_BASEMODE_VDSL_PHY_2	BIT(8) /* GPIOs 24/25 */
+#define  BCM63268_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;
+	uint32_t mask;
+};
+
+#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", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD),
+	BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD),
+	BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1),
+	BCM63268_PIN(13, "gpio13", BCM63268_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",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(25, "gpio25",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_PIN(26, "gpio26",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(27, "gpio27",
+		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
+	BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND),
+	BCM63268_PIN(31, "gpio31", BCM63268_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, BCM63268_BASEMODE_NAND),
+	BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_0,
+			      BCM63268_BASEMODE_VDSL_PHY_0),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_1,
+			      BCM63268_BASEMODE_VDSL_PHY_1),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_2,
+			      BCM63268_BASEMODE_VDSL_PHY_2),
+	BCM63268_BASEMODE_FUN(vdsl_phy_override_3,
+			      BCM63268_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_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
+{
+	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
+	unsigned int basemode = (unsigned long) desc->drv_data;
+	unsigned int mask = BIT(bcm63xx_bank_pin(pin));
+
+	if (basemode)
+		regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
+				   0);
+
+	if (pin < BCM63XX_BANK_GPIOS) {
+		/* base mode: 0 => gpio, 1 => mux function */
+		regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0);
+
+		/* pins 0-23 might be muxed to led */
+		if (pin < BCM63268_NUM_LEDS)
+			regmap_update_bits(pc->regs, BCM63268_LED_REG, mask,
+					   0);
+	} else if (pin < BCM63268_NUM_GPIOS) {
+		/* ctrl reg: 0 => wifi function, 1 => gpio */
+		regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask);
+	}
+}
+
+static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				    unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm63268_pingroup *pg = &bcm63268_groups[group];
+	const struct bcm63268_function *f = &bcm63268_funcs[selector];
+	unsigned i;
+	unsigned int reg;
+	unsigned int val, mask;
+
+	for (i = 0; i < pg->num_pins; i++)
+		bcm63268_set_gpio(pc, pg->pins[i]);
+
+	switch (f->reg) {
+	case BCM63268_LEDCTRL:
+		reg = BCM63268_LED_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM63268_MODE:
+		reg = BCM63268_MODE_REG;
+		mask = BIT(pg->pins[0]);
+		val = BIT(pg->pins[0]);
+		break;
+	case BCM63268_CTRL:
+		reg = BCM63268_CTRL_REG;
+		mask = BIT(pg->pins[0]);
+		val = 0;
+		break;
+	case BCM63268_BASEMODE:
+		reg = BCM63268_BASEMODE_REG;
+		mask = f->mask;
+		val = f->mask;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	regmap_update_bits(pc->regs, reg, mask, val);
+
+	return 0;
+}
+
+static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	bcm63268_set_gpio(pc, offset);
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm63268_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm63268_pinctrl_get_group_name,
+	.get_group_pins = bcm63268_pinctrl_get_group_pins,
+	.get_groups_count = bcm63268_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm63268_pmx_ops = {
+	.get_function_groups = bcm63268_pinctrl_get_groups,
+	.get_function_name = bcm63268_pinctrl_get_func_name,
+	.get_functions_count = bcm63268_pinctrl_get_func_count,
+	.gpio_request_enable = bcm63268_gpio_request_enable,
+	.set_mux = bcm63268_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm63268_soc = {
+	.ngpios = BCM63268_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm63268_pins),
+	.pctl_ops = &bcm63268_pctl_ops,
+	.pins = bcm63268_pins,
+	.pmx_ops = &bcm63268_pmx_ops,
+};
+
+static int bcm63268_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL);
+}
+
+static const struct of_device_id bcm63268_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm63268-pinctrl", },
+	{ /* sentinel */ }
+};
+
+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.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 14/15] dt-bindings: add BCM6318 pincontroller binding documentation
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6318-pinctrl.yaml         | 190 ++++++++++++++++++
 1 file changed, 190 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
new file mode 100644
index 000000000000..6b607bd8d003
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
@@ -0,0 +1,190 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6318 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6318-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6318-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led,
+                  ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led,
+                  serial_led_data, serial_led_clk, inet_act_led, inet_fail_led,
+                  dsl_led, post_fail_led, wlan_wps_led, usb_pwron,
+                  usb_device_led, usb_active ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6318-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6318-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6318-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 50>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
+          function = "ephy0_spd_led";
+          pins = "gpio0";
+        };
+
+        pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
+          function = "ephy1_spd_led";
+          pins = "gpio1";
+        };
+
+        pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
+          function = "ephy2_spd_led";
+          pins = "gpio2";
+        };
+
+        pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
+          function = "ephy3_spd_led";
+          pins = "gpio3";
+        };
+
+        pinctrl_ephy0_act_led: ephy0_act_led-pins {
+          function = "ephy0_act_led";
+          pins = "gpio4";
+        };
+
+        pinctrl_ephy1_act_led: ephy1_act_led-pins {
+          function = "ephy1_act_led";
+          pins = "gpio5";
+        };
+
+        pinctrl_ephy2_act_led: ephy2_act_led-pins {
+          function = "ephy2_act_led";
+          pins = "gpio6";
+        };
+
+        pinctrl_ephy3_act_led: ephy3_act_led-pins {
+          function = "ephy3_act_led";
+          pins = "gpio7";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio6";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio7";
+          };
+        };
+
+        pinctrl_inet_act_led: inet_act_led-pins {
+          function = "inet_act_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_inet_fail_led: inet_fail_led-pins {
+          function = "inet_fail_led";
+          pins = "gpio9";
+        };
+
+        pinctrl_dsl_led: dsl_led-pins {
+          function = "dsl_led";
+          pins = "gpio10";
+        };
+
+        pinctrl_post_fail_led: post_fail_led-pins {
+          function = "post_fail_led";
+          pins = "gpio11";
+        };
+
+        pinctrl_wlan_wps_led: wlan_wps_led-pins {
+          function = "wlan_wps_led";
+          pins = "gpio12";
+        };
+
+        pinctrl_usb_pwron: usb_pwron-pins {
+          function = "usb_pwron";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_active: usb_active-pins {
+          function = "usb_active";
+          pins = "gpio40";
+        };
+      };
+    };
-- 
2.20.1


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

* [PATCH v6 14/15] dt-bindings: add BCM6318 pincontroller binding documentation
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

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

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: add changes suggested by Rob Herring
 v5: change Documentation to dt-bindings in commit title
 v4: no changes
 v3: add new gpio node
 v2: remove interrupts

 .../pinctrl/brcm,bcm6318-pinctrl.yaml         | 190 ++++++++++++++++++
 1 file changed, 190 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
new file mode 100644
index 000000000000..6b607bd8d003
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
@@ -0,0 +1,190 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6318 pin controller
+
+maintainers:
+  - Álvaro Fernández Rojas <noltari@gmail.com>
+  - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |+
+  The pin controller node should be the child of a syscon node.
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.yaml
+
+properties:
+  compatible:
+    const: brcm,bcm6318-pinctrl
+
+  gpio:
+    type: object
+    properties:
+      compatible:
+        const: brcm,bcm6318-gpio
+
+      data:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the data register (in bytes).
+
+      dirout:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          Offset in the register map for the dirout register (in bytes).
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+      gpio-ranges:
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - gpio-ranges
+      - '#gpio-cells'
+
+    additionalProperties: false
+
+patternProperties:
+  '^.*-pins$':
+    if:
+      type: object
+    then:
+      properties:
+        function:
+          $ref: "pinmux-node.yaml#/properties/function"
+          enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led,
+                  ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led,
+                  serial_led_data, serial_led_clk, inet_act_led, inet_fail_led,
+                  dsl_led, post_fail_led, wlan_wps_led, usb_pwron,
+                  usb_device_led, usb_active ]
+
+        pins:
+          $ref: "pinmux-node.yaml#/properties/pins"
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
+                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ]
+
+required:
+  - compatible
+  - gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio_cntl@10000080 {
+      compatible = "brcm,bcm6318-gpio-controller", "syscon", "simple-mfd";
+      reg = <0x10000080 0x80>;
+
+      pinctrl: pinctrl {
+        compatible = "brcm,bcm6318-pinctrl";
+
+        gpio {
+          compatible = "brcm,bcm6318-gpio";
+          data = <0xc>;
+          dirout = <0x4>;
+
+          gpio-controller;
+          gpio-ranges = <&pinctrl 0 0 50>;
+          #gpio-cells = <2>;
+        };
+
+        pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
+          function = "ephy0_spd_led";
+          pins = "gpio0";
+        };
+
+        pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
+          function = "ephy1_spd_led";
+          pins = "gpio1";
+        };
+
+        pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
+          function = "ephy2_spd_led";
+          pins = "gpio2";
+        };
+
+        pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
+          function = "ephy3_spd_led";
+          pins = "gpio3";
+        };
+
+        pinctrl_ephy0_act_led: ephy0_act_led-pins {
+          function = "ephy0_act_led";
+          pins = "gpio4";
+        };
+
+        pinctrl_ephy1_act_led: ephy1_act_led-pins {
+          function = "ephy1_act_led";
+          pins = "gpio5";
+        };
+
+        pinctrl_ephy2_act_led: ephy2_act_led-pins {
+          function = "ephy2_act_led";
+          pins = "gpio6";
+        };
+
+        pinctrl_ephy3_act_led: ephy3_act_led-pins {
+          function = "ephy3_act_led";
+          pins = "gpio7";
+        };
+
+        pinctrl_serial_led: serial_led-pins {
+          pinctrl_serial_led_data: serial_led_data-pins {
+            function = "serial_led_data";
+            pins = "gpio6";
+          };
+
+          pinctrl_serial_led_clk: serial_led_clk-pins {
+            function = "serial_led_clk";
+            pins = "gpio7";
+          };
+        };
+
+        pinctrl_inet_act_led: inet_act_led-pins {
+          function = "inet_act_led";
+          pins = "gpio8";
+        };
+
+        pinctrl_inet_fail_led: inet_fail_led-pins {
+          function = "inet_fail_led";
+          pins = "gpio9";
+        };
+
+        pinctrl_dsl_led: dsl_led-pins {
+          function = "dsl_led";
+          pins = "gpio10";
+        };
+
+        pinctrl_post_fail_led: post_fail_led-pins {
+          function = "post_fail_led";
+          pins = "gpio11";
+        };
+
+        pinctrl_wlan_wps_led: wlan_wps_led-pins {
+          function = "wlan_wps_led";
+          pins = "gpio12";
+        };
+
+        pinctrl_usb_pwron: usb_pwron-pins {
+          function = "usb_pwron";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_device_led: usb_device_led-pins {
+          function = "usb_device_led";
+          pins = "gpio13";
+        };
+
+        pinctrl_usb_active: usb_active-pins {
+          function = "usb_active";
+          pins = "gpio40";
+        };
+      };
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6 15/15] pinctrl: add a pincontrol driver for BCM6318
  2021-03-10 12:54 ` Álvaro Fernández Rojas
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs
to different functions. BCM6318 is similar to BCM6328 with the addition
of a pad register, and the GPIO meaning of the mux register changes
based on the GPIO number.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6318.c | 498 ++++++++++++++++++++++++++
 3 files changed, 507 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 186985846120..33660e8fec05 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
 	select PINCONF
 	select PINMUX
 
+config PINCTRL_BCM6318
+	bool "Broadcom BCM6318 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6318 GPIO driver.
+
 config PINCTRL_BCM6328
 	bool "Broadcom BCM6328 GPIO driver"
 	depends on (BMIPS_GENERIC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 4117847fd279..00c7b7775e63 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
+obj-$(CONFIG_PINCTRL_BCM6318)		+= pinctrl-bcm6318.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c
new file mode 100644
index 000000000000..77fd9b58067d
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c
@@ -0,0 +1,498 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6318 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6318_NUM_GPIOS	50
+#define BCM6318_NUM_MUX		48
+
+#define BCM6318_MODE_REG	0x18
+#define BCM6318_MUX_REG		0x1c
+#define  BCM6328_MUX_MASK	GENMASK(1, 0)
+#define BCM6318_PAD_REG		0x54
+#define  BCM6328_PAD_MASK	GENMASK(3, 0)
+
+struct bcm6318_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6318_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	unsigned mode_val:1;
+	unsigned mux_val:2;
+};
+
+static const struct pinctrl_pin_desc bcm6318_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"),
+	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"),
+};
+
+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 };
+
+#define BCM6318_GROUP(n)					\
+	{							\
+		.name = #n,					\
+		.pins = n##_pins,				\
+		.num_pins = ARRAY_SIZE(n##_pins),		\
+	}
+
+static struct bcm6318_pingroup bcm6318_groups[] = {
+	BCM6318_GROUP(gpio0),
+	BCM6318_GROUP(gpio1),
+	BCM6318_GROUP(gpio2),
+	BCM6318_GROUP(gpio3),
+	BCM6318_GROUP(gpio4),
+	BCM6318_GROUP(gpio5),
+	BCM6318_GROUP(gpio6),
+	BCM6318_GROUP(gpio7),
+	BCM6318_GROUP(gpio8),
+	BCM6318_GROUP(gpio9),
+	BCM6318_GROUP(gpio10),
+	BCM6318_GROUP(gpio11),
+	BCM6318_GROUP(gpio12),
+	BCM6318_GROUP(gpio13),
+	BCM6318_GROUP(gpio14),
+	BCM6318_GROUP(gpio15),
+	BCM6318_GROUP(gpio16),
+	BCM6318_GROUP(gpio17),
+	BCM6318_GROUP(gpio18),
+	BCM6318_GROUP(gpio19),
+	BCM6318_GROUP(gpio20),
+	BCM6318_GROUP(gpio21),
+	BCM6318_GROUP(gpio22),
+	BCM6318_GROUP(gpio23),
+	BCM6318_GROUP(gpio24),
+	BCM6318_GROUP(gpio25),
+	BCM6318_GROUP(gpio26),
+	BCM6318_GROUP(gpio27),
+	BCM6318_GROUP(gpio28),
+	BCM6318_GROUP(gpio29),
+	BCM6318_GROUP(gpio30),
+	BCM6318_GROUP(gpio31),
+	BCM6318_GROUP(gpio32),
+	BCM6318_GROUP(gpio33),
+	BCM6318_GROUP(gpio34),
+	BCM6318_GROUP(gpio35),
+	BCM6318_GROUP(gpio36),
+	BCM6318_GROUP(gpio37),
+	BCM6318_GROUP(gpio38),
+	BCM6318_GROUP(gpio39),
+	BCM6318_GROUP(gpio40),
+	BCM6318_GROUP(gpio41),
+	BCM6318_GROUP(gpio42),
+	BCM6318_GROUP(gpio43),
+	BCM6318_GROUP(gpio44),
+	BCM6318_GROUP(gpio45),
+	BCM6318_GROUP(gpio46),
+	BCM6318_GROUP(gpio47),
+	BCM6318_GROUP(gpio48),
+	BCM6318_GROUP(gpio49),
+};
+
+/* 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 ephy0_spd_led_groups[] = {
+	"gpio0",
+};
+
+static const char * const ephy1_spd_led_groups[] = {
+	"gpio1",
+};
+
+static const char * const ephy2_spd_led_groups[] = {
+	"gpio2",
+};
+
+static const char * const ephy3_spd_led_groups[] = {
+	"gpio3",
+};
+
+static const char * const ephy0_act_led_groups[] = {
+	"gpio4",
+};
+
+static const char * const ephy1_act_led_groups[] = {
+	"gpio5",
+};
+
+static const char * const ephy2_act_led_groups[] = {
+	"gpio6",
+};
+
+static const char * const ephy3_act_led_groups[] = {
+	"gpio7",
+};
+
+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[] = {
+	"gpio8",
+};
+
+static const char * const inet_fail_led_groups[] = {
+	"gpio9",
+};
+
+static const char * const dsl_led_groups[] = {
+	"gpio10",
+};
+
+static const char * const post_fail_led_groups[] = {
+	"gpio11",
+};
+
+static const char * const wlan_wps_led_groups[] = {
+	"gpio12",
+};
+
+static const char * const usb_pwron_groups[] = {
+	"gpio13",
+};
+
+static const char * const usb_device_led_groups[] = {
+	"gpio13",
+};
+
+static const char * const usb_active_groups[] = {
+	"gpio40",
+};
+
+#define BCM6318_MODE_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mode_val = 1,				\
+	}
+
+#define BCM6318_MUX_FUN(n, mux)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mux_val = mux,				\
+	}
+
+static const struct bcm6318_function bcm6318_funcs[] = {
+	BCM6318_MODE_FUN(led),
+	BCM6318_MUX_FUN(ephy0_spd_led, 1),
+	BCM6318_MUX_FUN(ephy1_spd_led, 1),
+	BCM6318_MUX_FUN(ephy2_spd_led, 1),
+	BCM6318_MUX_FUN(ephy3_spd_led, 1),
+	BCM6318_MUX_FUN(ephy0_act_led, 1),
+	BCM6318_MUX_FUN(ephy1_act_led, 1),
+	BCM6318_MUX_FUN(ephy2_act_led, 1),
+	BCM6318_MUX_FUN(ephy3_act_led, 1),
+	BCM6318_MUX_FUN(serial_led_data, 3),
+	BCM6318_MUX_FUN(serial_led_clk, 3),
+	BCM6318_MUX_FUN(inet_act_led, 1),
+	BCM6318_MUX_FUN(inet_fail_led, 1),
+	BCM6318_MUX_FUN(dsl_led, 1),
+	BCM6318_MUX_FUN(post_fail_led, 1),
+	BCM6318_MUX_FUN(wlan_wps_led, 1),
+	BCM6318_MUX_FUN(usb_pwron, 1),
+	BCM6318_MUX_FUN(usb_device_led, 2),
+	BCM6318_MUX_FUN(usb_active, 2),
+};
+
+static inline unsigned int bcm6318_mux_off(unsigned int pin)
+{
+	return BCM6318_MUX_REG + (pin / 16) * 4;
+}
+
+static inline unsigned int bcm6318_pad_off(unsigned int pin)
+{
+	return BCM6318_PAD_REG + (pin / 8) * 4;
+}
+
+static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6318_groups);
+}
+
+static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6318_groups[group].name;
+}
+
+static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6318_groups[group].pins;
+	*num_pins = bcm6318_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6318_funcs);
+}
+
+static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6318_funcs[selector].name;
+}
+
+static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6318_funcs[selector].groups;
+	*num_groups = bcm6318_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
+				   unsigned int mode, unsigned int mux)
+{
+	if (pin < BCM63XX_BANK_GPIOS)
+		regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
+				   mode ? BIT(pin) : 0);
+
+	if (pin < BCM6318_NUM_MUX)
+		regmap_update_bits(pc->regs,
+				   bcm6318_mux_off(pin),
+				   BCM6328_MUX_MASK << ((pin % 16) * 2),
+				   mux << ((pin % 16) * 2));
+}
+
+static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
+				   uint8_t val)
+{
+	regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
+			   BCM6328_PAD_MASK << ((pin % 8) * 4),
+			   val << ((pin % 8) * 4));
+}
+
+static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6318_pingroup *pg = &bcm6318_groups[group];
+	const struct bcm6318_function *f = &bcm6318_funcs[selector];
+
+	bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
+
+	return 0;
+}
+
+static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	if (offset < 13) {
+		/* GPIOs 0-12 use mux 0 as GPIO function */
+		bcm6318_rmw_mux(pc, offset, 0, 0);
+	} else if (offset < 42) {
+		/* GPIOs 13-41 use mux 3 as GPIO function */
+		bcm6318_rmw_mux(pc, offset, 0, 3);
+
+		bcm6318_set_pad(pc, offset, 0);
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6318_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6318_pinctrl_get_group_name,
+	.get_group_pins = bcm6318_pinctrl_get_group_pins,
+	.get_groups_count = bcm6318_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6318_pmx_ops = {
+	.get_function_groups = bcm6318_pinctrl_get_groups,
+	.get_function_name = bcm6318_pinctrl_get_func_name,
+	.get_functions_count = bcm6318_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6318_gpio_request_enable,
+	.set_mux = bcm6318_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
+	.ngpios = BCM6318_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6318_pins),
+	.pctl_ops = &bcm6318_pctl_ops,
+	.pins = bcm6318_pins,
+	.pmx_ops = &bcm6318_pmx_ops,
+};
+
+static int bcm6318_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
+}
+
+static const struct of_device_id bcm6318_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6318-pinctrl", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver bcm6318_pinctrl_driver = {
+	.probe = bcm6318_pinctrl_probe,
+	.driver = {
+		.name = "bcm6318-pinctrl",
+		.of_match_table = bcm6318_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6318_pinctrl_driver);
-- 
2.20.1


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

* [PATCH v6 15/15] pinctrl: add a pincontrol driver for BCM6318
@ 2021-03-10 12:55   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 12:55 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Álvaro Fernández Rojas, Necip Fazil Yildiran,
	Andy Shevchenko, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel

Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs
to different functions. BCM6318 is similar to BCM6328 with the addition
of a pad register, and the GPIO meaning of the mux register changes
based on the GPIO number.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
 v6: no changes
 v5: add changes suggested by Andy Shevchenko
 v4: no changes
 v3: use new shared code
 v2: switch to GPIO_REGMAP

 drivers/pinctrl/bcm/Kconfig           |   8 +
 drivers/pinctrl/bcm/Makefile          |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm6318.c | 498 ++++++++++++++++++++++++++
 3 files changed, 507 insertions(+)
 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 186985846120..33660e8fec05 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
 	select PINCONF
 	select PINMUX
 
+config PINCTRL_BCM6318
+	bool "Broadcom BCM6318 GPIO driver"
+	depends on (BMIPS_GENERIC || COMPILE_TEST)
+	select PINCTRL_BCM63XX
+	default BMIPS_GENERIC
+	help
+	   Say Y here to enable the Broadcom BCM6318 GPIO driver.
+
 config PINCTRL_BCM6328
 	bool "Broadcom BCM6328 GPIO driver"
 	depends on (BMIPS_GENERIC || COMPILE_TEST)
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 4117847fd279..00c7b7775e63 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -4,6 +4,7 @@
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
+obj-$(CONFIG_PINCTRL_BCM6318)		+= pinctrl-bcm6318.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
 obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
 obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c
new file mode 100644
index 000000000000..77fd9b58067d
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c
@@ -0,0 +1,498 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for BCM6318 GPIO unit (pinctrl + GPIO)
+ *
+ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../pinctrl-utils.h"
+
+#include "pinctrl-bcm63xx.h"
+
+#define BCM6318_NUM_GPIOS	50
+#define BCM6318_NUM_MUX		48
+
+#define BCM6318_MODE_REG	0x18
+#define BCM6318_MUX_REG		0x1c
+#define  BCM6328_MUX_MASK	GENMASK(1, 0)
+#define BCM6318_PAD_REG		0x54
+#define  BCM6328_PAD_MASK	GENMASK(3, 0)
+
+struct bcm6318_pingroup {
+	const char *name;
+	const unsigned * const pins;
+	const unsigned num_pins;
+};
+
+struct bcm6318_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+
+	unsigned mode_val:1;
+	unsigned mux_val:2;
+};
+
+static const struct pinctrl_pin_desc bcm6318_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"),
+	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"),
+};
+
+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 };
+
+#define BCM6318_GROUP(n)					\
+	{							\
+		.name = #n,					\
+		.pins = n##_pins,				\
+		.num_pins = ARRAY_SIZE(n##_pins),		\
+	}
+
+static struct bcm6318_pingroup bcm6318_groups[] = {
+	BCM6318_GROUP(gpio0),
+	BCM6318_GROUP(gpio1),
+	BCM6318_GROUP(gpio2),
+	BCM6318_GROUP(gpio3),
+	BCM6318_GROUP(gpio4),
+	BCM6318_GROUP(gpio5),
+	BCM6318_GROUP(gpio6),
+	BCM6318_GROUP(gpio7),
+	BCM6318_GROUP(gpio8),
+	BCM6318_GROUP(gpio9),
+	BCM6318_GROUP(gpio10),
+	BCM6318_GROUP(gpio11),
+	BCM6318_GROUP(gpio12),
+	BCM6318_GROUP(gpio13),
+	BCM6318_GROUP(gpio14),
+	BCM6318_GROUP(gpio15),
+	BCM6318_GROUP(gpio16),
+	BCM6318_GROUP(gpio17),
+	BCM6318_GROUP(gpio18),
+	BCM6318_GROUP(gpio19),
+	BCM6318_GROUP(gpio20),
+	BCM6318_GROUP(gpio21),
+	BCM6318_GROUP(gpio22),
+	BCM6318_GROUP(gpio23),
+	BCM6318_GROUP(gpio24),
+	BCM6318_GROUP(gpio25),
+	BCM6318_GROUP(gpio26),
+	BCM6318_GROUP(gpio27),
+	BCM6318_GROUP(gpio28),
+	BCM6318_GROUP(gpio29),
+	BCM6318_GROUP(gpio30),
+	BCM6318_GROUP(gpio31),
+	BCM6318_GROUP(gpio32),
+	BCM6318_GROUP(gpio33),
+	BCM6318_GROUP(gpio34),
+	BCM6318_GROUP(gpio35),
+	BCM6318_GROUP(gpio36),
+	BCM6318_GROUP(gpio37),
+	BCM6318_GROUP(gpio38),
+	BCM6318_GROUP(gpio39),
+	BCM6318_GROUP(gpio40),
+	BCM6318_GROUP(gpio41),
+	BCM6318_GROUP(gpio42),
+	BCM6318_GROUP(gpio43),
+	BCM6318_GROUP(gpio44),
+	BCM6318_GROUP(gpio45),
+	BCM6318_GROUP(gpio46),
+	BCM6318_GROUP(gpio47),
+	BCM6318_GROUP(gpio48),
+	BCM6318_GROUP(gpio49),
+};
+
+/* 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 ephy0_spd_led_groups[] = {
+	"gpio0",
+};
+
+static const char * const ephy1_spd_led_groups[] = {
+	"gpio1",
+};
+
+static const char * const ephy2_spd_led_groups[] = {
+	"gpio2",
+};
+
+static const char * const ephy3_spd_led_groups[] = {
+	"gpio3",
+};
+
+static const char * const ephy0_act_led_groups[] = {
+	"gpio4",
+};
+
+static const char * const ephy1_act_led_groups[] = {
+	"gpio5",
+};
+
+static const char * const ephy2_act_led_groups[] = {
+	"gpio6",
+};
+
+static const char * const ephy3_act_led_groups[] = {
+	"gpio7",
+};
+
+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[] = {
+	"gpio8",
+};
+
+static const char * const inet_fail_led_groups[] = {
+	"gpio9",
+};
+
+static const char * const dsl_led_groups[] = {
+	"gpio10",
+};
+
+static const char * const post_fail_led_groups[] = {
+	"gpio11",
+};
+
+static const char * const wlan_wps_led_groups[] = {
+	"gpio12",
+};
+
+static const char * const usb_pwron_groups[] = {
+	"gpio13",
+};
+
+static const char * const usb_device_led_groups[] = {
+	"gpio13",
+};
+
+static const char * const usb_active_groups[] = {
+	"gpio40",
+};
+
+#define BCM6318_MODE_FUN(n)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mode_val = 1,				\
+	}
+
+#define BCM6318_MUX_FUN(n, mux)				\
+	{						\
+		.name = #n,				\
+		.groups = n##_groups,			\
+		.num_groups = ARRAY_SIZE(n##_groups),	\
+		.mux_val = mux,				\
+	}
+
+static const struct bcm6318_function bcm6318_funcs[] = {
+	BCM6318_MODE_FUN(led),
+	BCM6318_MUX_FUN(ephy0_spd_led, 1),
+	BCM6318_MUX_FUN(ephy1_spd_led, 1),
+	BCM6318_MUX_FUN(ephy2_spd_led, 1),
+	BCM6318_MUX_FUN(ephy3_spd_led, 1),
+	BCM6318_MUX_FUN(ephy0_act_led, 1),
+	BCM6318_MUX_FUN(ephy1_act_led, 1),
+	BCM6318_MUX_FUN(ephy2_act_led, 1),
+	BCM6318_MUX_FUN(ephy3_act_led, 1),
+	BCM6318_MUX_FUN(serial_led_data, 3),
+	BCM6318_MUX_FUN(serial_led_clk, 3),
+	BCM6318_MUX_FUN(inet_act_led, 1),
+	BCM6318_MUX_FUN(inet_fail_led, 1),
+	BCM6318_MUX_FUN(dsl_led, 1),
+	BCM6318_MUX_FUN(post_fail_led, 1),
+	BCM6318_MUX_FUN(wlan_wps_led, 1),
+	BCM6318_MUX_FUN(usb_pwron, 1),
+	BCM6318_MUX_FUN(usb_device_led, 2),
+	BCM6318_MUX_FUN(usb_active, 2),
+};
+
+static inline unsigned int bcm6318_mux_off(unsigned int pin)
+{
+	return BCM6318_MUX_REG + (pin / 16) * 4;
+}
+
+static inline unsigned int bcm6318_pad_off(unsigned int pin)
+{
+	return BCM6318_PAD_REG + (pin / 8) * 4;
+}
+
+static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6318_groups);
+}
+
+static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						  unsigned group)
+{
+	return bcm6318_groups[group].name;
+}
+
+static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					  unsigned group, const unsigned **pins,
+					  unsigned *num_pins)
+{
+	*pins = bcm6318_groups[group].pins;
+	*num_pins = bcm6318_groups[group].num_pins;
+
+	return 0;
+}
+
+static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(bcm6318_funcs);
+}
+
+static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						 unsigned selector)
+{
+	return bcm6318_funcs[selector].name;
+}
+
+static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
+				      unsigned selector,
+				      const char * const **groups,
+				      unsigned * const num_groups)
+{
+	*groups = bcm6318_funcs[selector].groups;
+	*num_groups = bcm6318_funcs[selector].num_groups;
+
+	return 0;
+}
+
+static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
+				   unsigned int mode, unsigned int mux)
+{
+	if (pin < BCM63XX_BANK_GPIOS)
+		regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
+				   mode ? BIT(pin) : 0);
+
+	if (pin < BCM6318_NUM_MUX)
+		regmap_update_bits(pc->regs,
+				   bcm6318_mux_off(pin),
+				   BCM6328_MUX_MASK << ((pin % 16) * 2),
+				   mux << ((pin % 16) * 2));
+}
+
+static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
+				   uint8_t val)
+{
+	regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
+			   BCM6328_PAD_MASK << ((pin % 8) * 4),
+			   val << ((pin % 8) * 4));
+}
+
+static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+				   unsigned selector, unsigned group)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm6318_pingroup *pg = &bcm6318_groups[group];
+	const struct bcm6318_function *f = &bcm6318_funcs[selector];
+
+	bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
+
+	return 0;
+}
+
+static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
+				       struct pinctrl_gpio_range *range,
+				       unsigned offset)
+{
+	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+
+	/* disable all functions using this pin */
+	if (offset < 13) {
+		/* GPIOs 0-12 use mux 0 as GPIO function */
+		bcm6318_rmw_mux(pc, offset, 0, 0);
+	} else if (offset < 42) {
+		/* GPIOs 13-41 use mux 3 as GPIO function */
+		bcm6318_rmw_mux(pc, offset, 0, 3);
+
+		bcm6318_set_pad(pc, offset, 0);
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops bcm6318_pctl_ops = {
+	.dt_free_map = pinctrl_utils_free_map,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.get_group_name = bcm6318_pinctrl_get_group_name,
+	.get_group_pins = bcm6318_pinctrl_get_group_pins,
+	.get_groups_count = bcm6318_pinctrl_get_group_count,
+};
+
+static struct pinmux_ops bcm6318_pmx_ops = {
+	.get_function_groups = bcm6318_pinctrl_get_groups,
+	.get_function_name = bcm6318_pinctrl_get_func_name,
+	.get_functions_count = bcm6318_pinctrl_get_func_count,
+	.gpio_request_enable = bcm6318_gpio_request_enable,
+	.set_mux = bcm6318_pinctrl_set_mux,
+	.strict = true,
+};
+
+static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
+	.ngpios = BCM6318_NUM_GPIOS,
+	.npins = ARRAY_SIZE(bcm6318_pins),
+	.pctl_ops = &bcm6318_pctl_ops,
+	.pins = bcm6318_pins,
+	.pmx_ops = &bcm6318_pmx_ops,
+};
+
+static int bcm6318_pinctrl_probe(struct platform_device *pdev)
+{
+	return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
+}
+
+static const struct of_device_id bcm6318_pinctrl_match[] = {
+	{ .compatible = "brcm,bcm6318-pinctrl", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver bcm6318_pinctrl_driver = {
+	.probe = bcm6318_pinctrl_probe,
+	.driver = {
+		.name = "bcm6318-pinctrl",
+		.of_match_table = bcm6318_pinctrl_match,
+	},
+};
+
+builtin_platform_driver(bcm6318_pinctrl_driver);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
  2021-03-10 12:54   ` Álvaro Fernández Rojas
@ 2021-03-10 14:01     ` Andy Shevchenko
  -1 siblings, 0 replies; 76+ messages in thread
From: Andy Shevchenko @ 2021-03-10 14:01 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, open list:GPIO SUBSYSTEM, devicetree,
	Linux Kernel Mailing List, linux-arm Mailing List

On Wed, Mar 10, 2021 at 2:55 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> This is needed for properly registering GPIO regmap as a child of a regmap
> pin controller.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Thanks!

> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> Reviewed-by: Michael Walle <michael@walle.cc>
> ---
>  v6: add comment and simplify of_node assignment
>  v5: switch to fwnode
>  v4: fix documentation
>  v3: introduce patch needed for properly parsing gpio-range
>
>  drivers/gpio/gpio-regmap.c  | 1 +
>  include/linux/gpio/regmap.h | 4 ++++
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> index 5412cb3b0b2a..d4fc656e70b0 100644
> --- a/drivers/gpio/gpio-regmap.c
> +++ b/drivers/gpio/gpio-regmap.c
> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
>
>         chip = &gpio->gpio_chip;
>         chip->parent = config->parent;
> +       chip->of_node = to_of_node(config->fwnode);
>         chip->base = -1;
>         chip->ngpio = config->ngpio;
>         chip->names = config->names;
> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
> index ad76f3d0a6ba..334dd928042b 100644
> --- a/include/linux/gpio/regmap.h
> +++ b/include/linux/gpio/regmap.h
> @@ -4,6 +4,7 @@
>  #define _LINUX_GPIO_REGMAP_H
>
>  struct device;
> +struct fwnode_handle;
>  struct gpio_regmap;
>  struct irq_domain;
>  struct regmap;
> @@ -16,6 +17,8 @@ struct regmap;
>   * @parent:            The parent device
>   * @regmap:            The regmap used to access the registers
>   *                     given, the name of the device is used
> + * @fwnode:            (Optional) The firmware node.
> + *                     If not given, the fwnode of the parent is used.
>   * @label:             (Optional) Descriptive name for GPIO controller.
>   *                     If not given, the name of the device is used.
>   * @ngpio:             Number of GPIOs
> @@ -57,6 +60,7 @@ struct regmap;
>  struct gpio_regmap_config {
>         struct device *parent;
>         struct regmap *regmap;
> +       struct fwnode_handle *fwnode;
>
>         const char *label;
>         int ngpio;
> --
> 2.20.1
>


-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
@ 2021-03-10 14:01     ` Andy Shevchenko
  0 siblings, 0 replies; 76+ messages in thread
From: Andy Shevchenko @ 2021-03-10 14:01 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, open list:GPIO SUBSYSTEM, devicetree,
	Linux Kernel Mailing List, linux-arm Mailing List

On Wed, Mar 10, 2021 at 2:55 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> This is needed for properly registering GPIO regmap as a child of a regmap
> pin controller.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Thanks!

> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> Reviewed-by: Michael Walle <michael@walle.cc>
> ---
>  v6: add comment and simplify of_node assignment
>  v5: switch to fwnode
>  v4: fix documentation
>  v3: introduce patch needed for properly parsing gpio-range
>
>  drivers/gpio/gpio-regmap.c  | 1 +
>  include/linux/gpio/regmap.h | 4 ++++
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> index 5412cb3b0b2a..d4fc656e70b0 100644
> --- a/drivers/gpio/gpio-regmap.c
> +++ b/drivers/gpio/gpio-regmap.c
> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
>
>         chip = &gpio->gpio_chip;
>         chip->parent = config->parent;
> +       chip->of_node = to_of_node(config->fwnode);
>         chip->base = -1;
>         chip->ngpio = config->ngpio;
>         chip->names = config->names;
> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
> index ad76f3d0a6ba..334dd928042b 100644
> --- a/include/linux/gpio/regmap.h
> +++ b/include/linux/gpio/regmap.h
> @@ -4,6 +4,7 @@
>  #define _LINUX_GPIO_REGMAP_H
>
>  struct device;
> +struct fwnode_handle;
>  struct gpio_regmap;
>  struct irq_domain;
>  struct regmap;
> @@ -16,6 +17,8 @@ struct regmap;
>   * @parent:            The parent device
>   * @regmap:            The regmap used to access the registers
>   *                     given, the name of the device is used
> + * @fwnode:            (Optional) The firmware node.
> + *                     If not given, the fwnode of the parent is used.
>   * @label:             (Optional) Descriptive name for GPIO controller.
>   *                     If not given, the name of the device is used.
>   * @ngpio:             Number of GPIOs
> @@ -57,6 +60,7 @@ struct regmap;
>  struct gpio_regmap_config {
>         struct device *parent;
>         struct regmap *regmap;
> +       struct fwnode_handle *fwnode;
>
>         const char *label;
>         int ngpio;
> --
> 2.20.1
>


-- 
With Best Regards,
Andy Shevchenko

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-10 12:54   ` Álvaro Fernández Rojas
@ 2021-03-10 14:07     ` Andy Shevchenko
  -1 siblings, 0 replies; 76+ messages in thread
From: Andy Shevchenko @ 2021-03-10 14:07 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, open list:GPIO SUBSYSTEM, devicetree,
	Linux Kernel Mailing List, linux-arm Mailing List

On Wed, Mar 10, 2021 at 2:55 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add a helper for registering BCM63XX pin controllers.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
(from use of the fwnode API perspective)

I'll think about of_match_node() case and perhaps come up with
corresponding fwnode API solution.

> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>

Other way around (Co-DB followed by SoB), but this is minor thingy

> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Andy Shevchenko
>  v5: add changes suggested by Andy Shevchenko
>  v4: drop IRQ selects from Kconfig and add missing of_node_put()
>  v3: add new patch with shared code
>
>  drivers/pinctrl/bcm/Kconfig           |   7 ++
>  drivers/pinctrl/bcm/Makefile          |   1 +
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
>  4 files changed, 164 insertions(+)
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h
>
> diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
> index 0ed14de0134c..882f19bdc243 100644
> --- a/drivers/pinctrl/bcm/Kconfig
> +++ b/drivers/pinctrl/bcm/Kconfig
> @@ -29,6 +29,13 @@ config PINCTRL_BCM2835
>         help
>            Say Y here to enable the Broadcom BCM2835 GPIO driver.
>
> +config PINCTRL_BCM63XX
> +       bool
> +       select GENERIC_PINCONF
> +       select GPIO_REGMAP
> +       select PINCONF
> +       select PINMUX
> +
>  config PINCTRL_IPROC_GPIO
>         bool "Broadcom iProc GPIO (with PINCONF) driver"
>         depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
> diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
> index 79d5e49fdd9a..0e3cf9b15c65 100644
> --- a/drivers/pinctrl/bcm/Makefile
> +++ b/drivers/pinctrl/bcm/Makefile
> @@ -3,6 +3,7 @@
>
>  obj-$(CONFIG_PINCTRL_BCM281XX)         += pinctrl-bcm281xx.o
>  obj-$(CONFIG_PINCTRL_BCM2835)          += pinctrl-bcm2835.o
> +obj-$(CONFIG_PINCTRL_BCM63XX)          += pinctrl-bcm63xx.o
>  obj-$(CONFIG_PINCTRL_IPROC_GPIO)       += pinctrl-iproc-gpio.o
>  obj-$(CONFIG_PINCTRL_CYGNUS_MUX)       += pinctrl-cygnus-mux.o
>  obj-$(CONFIG_PINCTRL_NS)               += pinctrl-ns.o
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> new file mode 100644
> index 000000000000..2eaac8e6f79f
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
> + *
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#include <linux/gpio/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "pinctrl-bcm63xx.h"
> +
> +#define BCM63XX_BANK_SIZE      4
> +
> +#define BCM63XX_DIROUT_REG     0x04
> +#define BCM63XX_DATA_REG       0x0c
> +
> +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
> +                                 unsigned int base, unsigned int offset,
> +                                 unsigned int *reg, unsigned int *mask)
> +{
> +       unsigned int line = offset % BCM63XX_BANK_GPIOS;
> +       unsigned int stride = offset / BCM63XX_BANK_GPIOS;
> +
> +       *reg = base - stride * BCM63XX_BANK_SIZE;
> +       *mask = BIT(line);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> +       { .compatible = "brcm,bcm6318-gpio", },
> +       { .compatible = "brcm,bcm6328-gpio", },
> +       { .compatible = "brcm,bcm6358-gpio", },
> +       { .compatible = "brcm,bcm6362-gpio", },
> +       { .compatible = "brcm,bcm6368-gpio", },
> +       { .compatible = "brcm,bcm63268-gpio", },
> +       { /* sentinel */ }
> +};
> +
> +static int bcm63xx_gpio_probe(struct device *dev,
> +                             struct fwnode_handle *node,
> +                             const struct bcm63xx_pinctrl_soc *soc,
> +                             struct bcm63xx_pinctrl *pc)
> +{
> +       struct gpio_regmap_config grc = {0};
> +
> +       grc.parent = dev;
> +       grc.fwnode = node;
> +       grc.ngpio = soc->ngpios;
> +       grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
> +       grc.regmap = pc->regs;
> +       grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
> +
> +       if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
> +               grc.reg_dat_base = BCM63XX_DATA_REG;
> +       grc.reg_set_base = grc.reg_dat_base;
> +
> +       if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
> +               grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
> +
> +       return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct bcm63xx_pinctrl *pc;
> +       struct fwnode_handle *node;
> +       int err;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
> +       if (!pc)
> +               return -ENOMEM;
> +
> +       platform_set_drvdata(pdev, pc);
> +
> +       pc->dev = dev;
> +       pc->driver_data = driver_data;
> +
> +       pc->regs = syscon_node_to_regmap(dev->parent->of_node);
> +       if (IS_ERR(pc->regs))
> +               return PTR_ERR(pc->regs);
> +
> +       pc->pctl_desc.name = dev_name(dev);
> +       pc->pctl_desc.pins = soc->pins;
> +       pc->pctl_desc.npins = soc->npins;
> +       pc->pctl_desc.pctlops = soc->pctl_ops;
> +       pc->pctl_desc.pmxops = soc->pmx_ops;
> +       pc->pctl_desc.owner = THIS_MODULE;
> +
> +       pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
> +       if (IS_ERR(pc->pctl_dev))
> +               return PTR_ERR(pc->pctl_dev);
> +
> +       device_for_each_child_node(dev, node) {
> +               if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
> +                       err = bcm63xx_gpio_probe(dev, node, soc, pc);
> +                       if (err) {
> +                               dev_err(dev, "could not add GPIO chip\n");
> +                               fwnode_handle_put(node);
> +                               return err;
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> new file mode 100644
> index 000000000000..3bdb50021f1b
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#ifndef __PINCTRL_BCM63XX_H__
> +#define __PINCTRL_BCM63XX_H__
> +
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#define BCM63XX_BANK_GPIOS 32
> +
> +struct bcm63xx_pinctrl_soc {
> +       struct pinctrl_ops *pctl_ops;
> +       struct pinmux_ops *pmx_ops;
> +
> +       const struct pinctrl_pin_desc *pins;
> +       unsigned npins;
> +
> +       unsigned int ngpios;
> +};
> +
> +struct bcm63xx_pinctrl {
> +       struct device *dev;
> +       struct regmap *regs;
> +
> +       struct pinctrl_desc pctl_desc;
> +       struct pinctrl_dev *pctl_dev;
> +
> +       void *driver_data;
> +};
> +
> +static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
> +{
> +       return pin % BCM63XX_BANK_GPIOS;
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data);
> +
> +#endif /* __PINCTRL_BCM63XX_H__ */
> --
> 2.20.1
>


-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-10 14:07     ` Andy Shevchenko
  0 siblings, 0 replies; 76+ messages in thread
From: Andy Shevchenko @ 2021-03-10 14:07 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, open list:GPIO SUBSYSTEM, devicetree,
	Linux Kernel Mailing List, linux-arm Mailing List

On Wed, Mar 10, 2021 at 2:55 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add a helper for registering BCM63XX pin controllers.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
(from use of the fwnode API perspective)

I'll think about of_match_node() case and perhaps come up with
corresponding fwnode API solution.

> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>

Other way around (Co-DB followed by SoB), but this is minor thingy

> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Andy Shevchenko
>  v5: add changes suggested by Andy Shevchenko
>  v4: drop IRQ selects from Kconfig and add missing of_node_put()
>  v3: add new patch with shared code
>
>  drivers/pinctrl/bcm/Kconfig           |   7 ++
>  drivers/pinctrl/bcm/Makefile          |   1 +
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
>  4 files changed, 164 insertions(+)
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h
>
> diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
> index 0ed14de0134c..882f19bdc243 100644
> --- a/drivers/pinctrl/bcm/Kconfig
> +++ b/drivers/pinctrl/bcm/Kconfig
> @@ -29,6 +29,13 @@ config PINCTRL_BCM2835
>         help
>            Say Y here to enable the Broadcom BCM2835 GPIO driver.
>
> +config PINCTRL_BCM63XX
> +       bool
> +       select GENERIC_PINCONF
> +       select GPIO_REGMAP
> +       select PINCONF
> +       select PINMUX
> +
>  config PINCTRL_IPROC_GPIO
>         bool "Broadcom iProc GPIO (with PINCONF) driver"
>         depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
> diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
> index 79d5e49fdd9a..0e3cf9b15c65 100644
> --- a/drivers/pinctrl/bcm/Makefile
> +++ b/drivers/pinctrl/bcm/Makefile
> @@ -3,6 +3,7 @@
>
>  obj-$(CONFIG_PINCTRL_BCM281XX)         += pinctrl-bcm281xx.o
>  obj-$(CONFIG_PINCTRL_BCM2835)          += pinctrl-bcm2835.o
> +obj-$(CONFIG_PINCTRL_BCM63XX)          += pinctrl-bcm63xx.o
>  obj-$(CONFIG_PINCTRL_IPROC_GPIO)       += pinctrl-iproc-gpio.o
>  obj-$(CONFIG_PINCTRL_CYGNUS_MUX)       += pinctrl-cygnus-mux.o
>  obj-$(CONFIG_PINCTRL_NS)               += pinctrl-ns.o
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> new file mode 100644
> index 000000000000..2eaac8e6f79f
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
> + *
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#include <linux/gpio/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "pinctrl-bcm63xx.h"
> +
> +#define BCM63XX_BANK_SIZE      4
> +
> +#define BCM63XX_DIROUT_REG     0x04
> +#define BCM63XX_DATA_REG       0x0c
> +
> +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
> +                                 unsigned int base, unsigned int offset,
> +                                 unsigned int *reg, unsigned int *mask)
> +{
> +       unsigned int line = offset % BCM63XX_BANK_GPIOS;
> +       unsigned int stride = offset / BCM63XX_BANK_GPIOS;
> +
> +       *reg = base - stride * BCM63XX_BANK_SIZE;
> +       *mask = BIT(line);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> +       { .compatible = "brcm,bcm6318-gpio", },
> +       { .compatible = "brcm,bcm6328-gpio", },
> +       { .compatible = "brcm,bcm6358-gpio", },
> +       { .compatible = "brcm,bcm6362-gpio", },
> +       { .compatible = "brcm,bcm6368-gpio", },
> +       { .compatible = "brcm,bcm63268-gpio", },
> +       { /* sentinel */ }
> +};
> +
> +static int bcm63xx_gpio_probe(struct device *dev,
> +                             struct fwnode_handle *node,
> +                             const struct bcm63xx_pinctrl_soc *soc,
> +                             struct bcm63xx_pinctrl *pc)
> +{
> +       struct gpio_regmap_config grc = {0};
> +
> +       grc.parent = dev;
> +       grc.fwnode = node;
> +       grc.ngpio = soc->ngpios;
> +       grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
> +       grc.regmap = pc->regs;
> +       grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
> +
> +       if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
> +               grc.reg_dat_base = BCM63XX_DATA_REG;
> +       grc.reg_set_base = grc.reg_dat_base;
> +
> +       if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
> +               grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
> +
> +       return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct bcm63xx_pinctrl *pc;
> +       struct fwnode_handle *node;
> +       int err;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
> +       if (!pc)
> +               return -ENOMEM;
> +
> +       platform_set_drvdata(pdev, pc);
> +
> +       pc->dev = dev;
> +       pc->driver_data = driver_data;
> +
> +       pc->regs = syscon_node_to_regmap(dev->parent->of_node);
> +       if (IS_ERR(pc->regs))
> +               return PTR_ERR(pc->regs);
> +
> +       pc->pctl_desc.name = dev_name(dev);
> +       pc->pctl_desc.pins = soc->pins;
> +       pc->pctl_desc.npins = soc->npins;
> +       pc->pctl_desc.pctlops = soc->pctl_ops;
> +       pc->pctl_desc.pmxops = soc->pmx_ops;
> +       pc->pctl_desc.owner = THIS_MODULE;
> +
> +       pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
> +       if (IS_ERR(pc->pctl_dev))
> +               return PTR_ERR(pc->pctl_dev);
> +
> +       device_for_each_child_node(dev, node) {
> +               if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
> +                       err = bcm63xx_gpio_probe(dev, node, soc, pc);
> +                       if (err) {
> +                               dev_err(dev, "could not add GPIO chip\n");
> +                               fwnode_handle_put(node);
> +                               return err;
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> new file mode 100644
> index 000000000000..3bdb50021f1b
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#ifndef __PINCTRL_BCM63XX_H__
> +#define __PINCTRL_BCM63XX_H__
> +
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#define BCM63XX_BANK_GPIOS 32
> +
> +struct bcm63xx_pinctrl_soc {
> +       struct pinctrl_ops *pctl_ops;
> +       struct pinmux_ops *pmx_ops;
> +
> +       const struct pinctrl_pin_desc *pins;
> +       unsigned npins;
> +
> +       unsigned int ngpios;
> +};
> +
> +struct bcm63xx_pinctrl {
> +       struct device *dev;
> +       struct regmap *regs;
> +
> +       struct pinctrl_desc pctl_desc;
> +       struct pinctrl_dev *pctl_dev;
> +
> +       void *driver_data;
> +};
> +
> +static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
> +{
> +       return pin % BCM63XX_BANK_GPIOS;
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data);
> +
> +#endif /* __PINCTRL_BCM63XX_H__ */
> --
> 2.20.1
>


-- 
With Best Regards,
Andy Shevchenko

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 12:54   ` Álvaro Fernández Rojas
@ 2021-03-10 17:45     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 17:45 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM, devicetree, linux-kernel,
	linux-arm-kernel

On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Rob Herring
>  v5: change Documentation to dt-bindings in commit title
>  v4: no changes
>  v3: add new gpio node
>  v2: remove interrupts
>
>  .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>  1 file changed, 174 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> new file mode 100644
> index 000000000000..471f6efa1754
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> @@ -0,0 +1,174 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BCM6328 pin controller
> +
> +maintainers:
> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> +  - Jonas Gorski <jonas.gorski@gmail.com>
> +
> +description: |+
> +  The pin controller node should be the child of a syscon node.
> +
> +  Refer to the the bindings described in
> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> +
> +properties:
> +  compatible:
> +    const: brcm,bcm6328-pinctrl
> +
> +  gpio:
> +    type: object
> +    properties:
> +      compatible:
> +        const: brcm,bcm6328-gpio
> +
> +      data:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: |
> +          Offset in the register map for the data register (in bytes).
> +
> +      dirout:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: |
> +          Offset in the register map for the dirout register (in bytes).
> +
> +      gpio-controller: true
> +
> +      "#gpio-cells":
> +        const: 2
> +
> +      gpio-ranges:
> +        maxItems: 1
> +
> +    required:
> +      - gpio-controller
> +      - gpio-ranges
> +      - '#gpio-cells'
> +
> +    additionalProperties: false
> +
> +patternProperties:
> +  '^.*-pins$':
> +    if:
> +      type: object
> +    then:
> +      properties:
> +        function:
> +          $ref: "pinmux-node.yaml#/properties/function"
> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> +
> +        pins:
> +          $ref: "pinmux-node.yaml#/properties/pins"
> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> +                  usb_port1 ]
> +
> +required:
> +  - compatible
> +  - gpio
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    gpio_cntl@10000080 {
> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";

You just added "brcm,bcm6328-gpio-controller", it would need to be documented.

> +      reg = <0x10000080 0x80>;
> +
> +      pinctrl: pinctrl {
> +        compatible = "brcm,bcm6328-pinctrl";
> +
> +        gpio {
> +          compatible = "brcm,bcm6328-gpio";

I'm still trying to understand why you need 3 levels of nodes here?
The gpio controller contains a pin controller plus other undefined
functions (because of 'syscon') and the pin controller contains a gpio
controller?

I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
should be a single node.

> +          data = <0xc>;
> +          dirout = <0x4>;

This looks similar to the brcm,bcm6345-gpio.txt binding which then
uses the gpio-mmio driver. Defining addresses with 'reg' is much
preferred over custom properties. That binding also captures the bank
size.

Rob

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 17:45     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 17:45 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM, devicetree, linux-kernel,
	linux-arm-kernel

On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Rob Herring
>  v5: change Documentation to dt-bindings in commit title
>  v4: no changes
>  v3: add new gpio node
>  v2: remove interrupts
>
>  .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>  1 file changed, 174 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> new file mode 100644
> index 000000000000..471f6efa1754
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> @@ -0,0 +1,174 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BCM6328 pin controller
> +
> +maintainers:
> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> +  - Jonas Gorski <jonas.gorski@gmail.com>
> +
> +description: |+
> +  The pin controller node should be the child of a syscon node.
> +
> +  Refer to the the bindings described in
> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> +
> +properties:
> +  compatible:
> +    const: brcm,bcm6328-pinctrl
> +
> +  gpio:
> +    type: object
> +    properties:
> +      compatible:
> +        const: brcm,bcm6328-gpio
> +
> +      data:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: |
> +          Offset in the register map for the data register (in bytes).
> +
> +      dirout:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: |
> +          Offset in the register map for the dirout register (in bytes).
> +
> +      gpio-controller: true
> +
> +      "#gpio-cells":
> +        const: 2
> +
> +      gpio-ranges:
> +        maxItems: 1
> +
> +    required:
> +      - gpio-controller
> +      - gpio-ranges
> +      - '#gpio-cells'
> +
> +    additionalProperties: false
> +
> +patternProperties:
> +  '^.*-pins$':
> +    if:
> +      type: object
> +    then:
> +      properties:
> +        function:
> +          $ref: "pinmux-node.yaml#/properties/function"
> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> +
> +        pins:
> +          $ref: "pinmux-node.yaml#/properties/pins"
> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> +                  usb_port1 ]
> +
> +required:
> +  - compatible
> +  - gpio
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    gpio_cntl@10000080 {
> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";

You just added "brcm,bcm6328-gpio-controller", it would need to be documented.

> +      reg = <0x10000080 0x80>;
> +
> +      pinctrl: pinctrl {
> +        compatible = "brcm,bcm6328-pinctrl";
> +
> +        gpio {
> +          compatible = "brcm,bcm6328-gpio";

I'm still trying to understand why you need 3 levels of nodes here?
The gpio controller contains a pin controller plus other undefined
functions (because of 'syscon') and the pin controller contains a gpio
controller?

I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
should be a single node.

> +          data = <0xc>;
> +          dirout = <0x4>;

This looks similar to the brcm,bcm6345-gpio.txt binding which then
uses the gpio-mmio driver. Defining addresses with 'reg' is much
preferred over custom properties. That binding also captures the bank
size.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-10 12:54   ` Álvaro Fernández Rojas
@ 2021-03-10 17:50     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 17:50 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM, devicetree, linux-kernel,
	linux-arm-kernel

On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add a helper for registering BCM63XX pin controllers.

Comments below based on my binding changes suggested.

>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Andy Shevchenko
>  v5: add changes suggested by Andy Shevchenko
>  v4: drop IRQ selects from Kconfig and add missing of_node_put()
>  v3: add new patch with shared code
>
>  drivers/pinctrl/bcm/Kconfig           |   7 ++
>  drivers/pinctrl/bcm/Makefile          |   1 +
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
>  4 files changed, 164 insertions(+)
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h
>
> diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
> index 0ed14de0134c..882f19bdc243 100644
> --- a/drivers/pinctrl/bcm/Kconfig
> +++ b/drivers/pinctrl/bcm/Kconfig
> @@ -29,6 +29,13 @@ config PINCTRL_BCM2835
>         help
>            Say Y here to enable the Broadcom BCM2835 GPIO driver.
>
> +config PINCTRL_BCM63XX
> +       bool
> +       select GENERIC_PINCONF
> +       select GPIO_REGMAP
> +       select PINCONF
> +       select PINMUX
> +
>  config PINCTRL_IPROC_GPIO
>         bool "Broadcom iProc GPIO (with PINCONF) driver"
>         depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
> diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
> index 79d5e49fdd9a..0e3cf9b15c65 100644
> --- a/drivers/pinctrl/bcm/Makefile
> +++ b/drivers/pinctrl/bcm/Makefile
> @@ -3,6 +3,7 @@
>
>  obj-$(CONFIG_PINCTRL_BCM281XX)         += pinctrl-bcm281xx.o
>  obj-$(CONFIG_PINCTRL_BCM2835)          += pinctrl-bcm2835.o
> +obj-$(CONFIG_PINCTRL_BCM63XX)          += pinctrl-bcm63xx.o
>  obj-$(CONFIG_PINCTRL_IPROC_GPIO)       += pinctrl-iproc-gpio.o
>  obj-$(CONFIG_PINCTRL_CYGNUS_MUX)       += pinctrl-cygnus-mux.o
>  obj-$(CONFIG_PINCTRL_NS)               += pinctrl-ns.o
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> new file mode 100644
> index 000000000000..2eaac8e6f79f
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
> + *
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#include <linux/gpio/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "pinctrl-bcm63xx.h"
> +
> +#define BCM63XX_BANK_SIZE      4
> +
> +#define BCM63XX_DIROUT_REG     0x04
> +#define BCM63XX_DATA_REG       0x0c
> +
> +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
> +                                 unsigned int base, unsigned int offset,
> +                                 unsigned int *reg, unsigned int *mask)
> +{
> +       unsigned int line = offset % BCM63XX_BANK_GPIOS;
> +       unsigned int stride = offset / BCM63XX_BANK_GPIOS;
> +
> +       *reg = base - stride * BCM63XX_BANK_SIZE;
> +       *mask = BIT(line);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> +       { .compatible = "brcm,bcm6318-gpio", },
> +       { .compatible = "brcm,bcm6328-gpio", },
> +       { .compatible = "brcm,bcm6358-gpio", },
> +       { .compatible = "brcm,bcm6362-gpio", },
> +       { .compatible = "brcm,bcm6368-gpio", },
> +       { .compatible = "brcm,bcm63268-gpio", },

All these would be moved to gpio-mmio.c (or maybe that can have a
fallback compatible?).

> +       { /* sentinel */ }
> +};
> +
> +static int bcm63xx_gpio_probe(struct device *dev,
> +                             struct fwnode_handle *node,
> +                             const struct bcm63xx_pinctrl_soc *soc,
> +                             struct bcm63xx_pinctrl *pc)
> +{
> +       struct gpio_regmap_config grc = {0};
> +
> +       grc.parent = dev;
> +       grc.fwnode = node;
> +       grc.ngpio = soc->ngpios;
> +       grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
> +       grc.regmap = pc->regs;
> +       grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
> +
> +       if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
> +               grc.reg_dat_base = BCM63XX_DATA_REG;
> +       grc.reg_set_base = grc.reg_dat_base;
> +
> +       if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
> +               grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
> +
> +       return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
> +}

This function can go.

> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct bcm63xx_pinctrl *pc;
> +       struct fwnode_handle *node;
> +       int err;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
> +       if (!pc)
> +               return -ENOMEM;
> +
> +       platform_set_drvdata(pdev, pc);
> +
> +       pc->dev = dev;
> +       pc->driver_data = driver_data;
> +
> +       pc->regs = syscon_node_to_regmap(dev->parent->of_node);
> +       if (IS_ERR(pc->regs))
> +               return PTR_ERR(pc->regs);
> +
> +       pc->pctl_desc.name = dev_name(dev);
> +       pc->pctl_desc.pins = soc->pins;
> +       pc->pctl_desc.npins = soc->npins;
> +       pc->pctl_desc.pctlops = soc->pctl_ops;
> +       pc->pctl_desc.pmxops = soc->pmx_ops;
> +       pc->pctl_desc.owner = THIS_MODULE;
> +
> +       pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
> +       if (IS_ERR(pc->pctl_dev))
> +               return PTR_ERR(pc->pctl_dev);
> +
> +       device_for_each_child_node(dev, node) {
> +               if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
> +                       err = bcm63xx_gpio_probe(dev, node, soc, pc);

This would just need an of_platform_populate call.

> +                       if (err) {
> +                               dev_err(dev, "could not add GPIO chip\n");
> +                               fwnode_handle_put(node);
> +                               return err;
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> new file mode 100644
> index 000000000000..3bdb50021f1b
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#ifndef __PINCTRL_BCM63XX_H__
> +#define __PINCTRL_BCM63XX_H__
> +
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#define BCM63XX_BANK_GPIOS 32
> +
> +struct bcm63xx_pinctrl_soc {
> +       struct pinctrl_ops *pctl_ops;
> +       struct pinmux_ops *pmx_ops;
> +
> +       const struct pinctrl_pin_desc *pins;
> +       unsigned npins;
> +
> +       unsigned int ngpios;
> +};
> +
> +struct bcm63xx_pinctrl {
> +       struct device *dev;
> +       struct regmap *regs;
> +
> +       struct pinctrl_desc pctl_desc;
> +       struct pinctrl_dev *pctl_dev;
> +
> +       void *driver_data;
> +};
> +
> +static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
> +{
> +       return pin % BCM63XX_BANK_GPIOS;
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data);
> +
> +#endif /* __PINCTRL_BCM63XX_H__ */
> --
> 2.20.1
>

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-10 17:50     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 17:50 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM, devicetree, linux-kernel,
	linux-arm-kernel

On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Add a helper for registering BCM63XX pin controllers.

Comments below based on my binding changes suggested.

>
> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
>  v6: add changes suggested by Andy Shevchenko
>  v5: add changes suggested by Andy Shevchenko
>  v4: drop IRQ selects from Kconfig and add missing of_node_put()
>  v3: add new patch with shared code
>
>  drivers/pinctrl/bcm/Kconfig           |   7 ++
>  drivers/pinctrl/bcm/Makefile          |   1 +
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 113 ++++++++++++++++++++++++++
>  drivers/pinctrl/bcm/pinctrl-bcm63xx.h |  43 ++++++++++
>  4 files changed, 164 insertions(+)
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
>  create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h
>
> diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
> index 0ed14de0134c..882f19bdc243 100644
> --- a/drivers/pinctrl/bcm/Kconfig
> +++ b/drivers/pinctrl/bcm/Kconfig
> @@ -29,6 +29,13 @@ config PINCTRL_BCM2835
>         help
>            Say Y here to enable the Broadcom BCM2835 GPIO driver.
>
> +config PINCTRL_BCM63XX
> +       bool
> +       select GENERIC_PINCONF
> +       select GPIO_REGMAP
> +       select PINCONF
> +       select PINMUX
> +
>  config PINCTRL_IPROC_GPIO
>         bool "Broadcom iProc GPIO (with PINCONF) driver"
>         depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
> diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
> index 79d5e49fdd9a..0e3cf9b15c65 100644
> --- a/drivers/pinctrl/bcm/Makefile
> +++ b/drivers/pinctrl/bcm/Makefile
> @@ -3,6 +3,7 @@
>
>  obj-$(CONFIG_PINCTRL_BCM281XX)         += pinctrl-bcm281xx.o
>  obj-$(CONFIG_PINCTRL_BCM2835)          += pinctrl-bcm2835.o
> +obj-$(CONFIG_PINCTRL_BCM63XX)          += pinctrl-bcm63xx.o
>  obj-$(CONFIG_PINCTRL_IPROC_GPIO)       += pinctrl-iproc-gpio.o
>  obj-$(CONFIG_PINCTRL_CYGNUS_MUX)       += pinctrl-cygnus-mux.o
>  obj-$(CONFIG_PINCTRL_NS)               += pinctrl-ns.o
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.c b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> new file mode 100644
> index 000000000000..2eaac8e6f79f
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.c
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for BCM63xx GPIO unit (pinctrl + GPIO)
> + *
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#include <linux/gpio/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include "pinctrl-bcm63xx.h"
> +
> +#define BCM63XX_BANK_SIZE      4
> +
> +#define BCM63XX_DIROUT_REG     0x04
> +#define BCM63XX_DATA_REG       0x0c
> +
> +static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
> +                                 unsigned int base, unsigned int offset,
> +                                 unsigned int *reg, unsigned int *mask)
> +{
> +       unsigned int line = offset % BCM63XX_BANK_GPIOS;
> +       unsigned int stride = offset / BCM63XX_BANK_GPIOS;
> +
> +       *reg = base - stride * BCM63XX_BANK_SIZE;
> +       *mask = BIT(line);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> +       { .compatible = "brcm,bcm6318-gpio", },
> +       { .compatible = "brcm,bcm6328-gpio", },
> +       { .compatible = "brcm,bcm6358-gpio", },
> +       { .compatible = "brcm,bcm6362-gpio", },
> +       { .compatible = "brcm,bcm6368-gpio", },
> +       { .compatible = "brcm,bcm63268-gpio", },

All these would be moved to gpio-mmio.c (or maybe that can have a
fallback compatible?).

> +       { /* sentinel */ }
> +};
> +
> +static int bcm63xx_gpio_probe(struct device *dev,
> +                             struct fwnode_handle *node,
> +                             const struct bcm63xx_pinctrl_soc *soc,
> +                             struct bcm63xx_pinctrl *pc)
> +{
> +       struct gpio_regmap_config grc = {0};
> +
> +       grc.parent = dev;
> +       grc.fwnode = node;
> +       grc.ngpio = soc->ngpios;
> +       grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
> +       grc.regmap = pc->regs;
> +       grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
> +
> +       if (fwnode_property_read_u32(node, "data", &grc.reg_dat_base))
> +               grc.reg_dat_base = BCM63XX_DATA_REG;
> +       grc.reg_set_base = grc.reg_dat_base;
> +
> +       if (fwnode_property_read_u32(node, "dirout", &grc.reg_dir_out_base))
> +               grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
> +
> +       return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
> +}

This function can go.

> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct bcm63xx_pinctrl *pc;
> +       struct fwnode_handle *node;
> +       int err;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
> +       if (!pc)
> +               return -ENOMEM;
> +
> +       platform_set_drvdata(pdev, pc);
> +
> +       pc->dev = dev;
> +       pc->driver_data = driver_data;
> +
> +       pc->regs = syscon_node_to_regmap(dev->parent->of_node);
> +       if (IS_ERR(pc->regs))
> +               return PTR_ERR(pc->regs);
> +
> +       pc->pctl_desc.name = dev_name(dev);
> +       pc->pctl_desc.pins = soc->pins;
> +       pc->pctl_desc.npins = soc->npins;
> +       pc->pctl_desc.pctlops = soc->pctl_ops;
> +       pc->pctl_desc.pmxops = soc->pmx_ops;
> +       pc->pctl_desc.owner = THIS_MODULE;
> +
> +       pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
> +       if (IS_ERR(pc->pctl_dev))
> +               return PTR_ERR(pc->pctl_dev);
> +
> +       device_for_each_child_node(dev, node) {
> +               if (of_match_node(bcm63xx_gpio_of_match, to_of_node(node))) {
> +                       err = bcm63xx_gpio_probe(dev, node, soc, pc);

This would just need an of_platform_populate call.

> +                       if (err) {
> +                               dev_err(dev, "could not add GPIO chip\n");
> +                               fwnode_handle_put(node);
> +                               return err;
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> new file mode 100644
> index 000000000000..3bdb50021f1b
> --- /dev/null
> +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
> + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
> + */
> +
> +#ifndef __PINCTRL_BCM63XX_H__
> +#define __PINCTRL_BCM63XX_H__
> +
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#define BCM63XX_BANK_GPIOS 32
> +
> +struct bcm63xx_pinctrl_soc {
> +       struct pinctrl_ops *pctl_ops;
> +       struct pinmux_ops *pmx_ops;
> +
> +       const struct pinctrl_pin_desc *pins;
> +       unsigned npins;
> +
> +       unsigned int ngpios;
> +};
> +
> +struct bcm63xx_pinctrl {
> +       struct device *dev;
> +       struct regmap *regs;
> +
> +       struct pinctrl_desc pctl_desc;
> +       struct pinctrl_dev *pctl_dev;
> +
> +       void *driver_data;
> +};
> +
> +static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
> +{
> +       return pin % BCM63XX_BANK_GPIOS;
> +}
> +
> +int bcm63xx_pinctrl_probe(struct platform_device *pdev,
> +                         const struct bcm63xx_pinctrl_soc *soc,
> +                         void *driver_data);
> +
> +#endif /* __PINCTRL_BCM63XX_H__ */
> --
> 2.20.1
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 17:45     ` Rob Herring
@ 2021-03-10 18:03       ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 18:03 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>> 
>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> ---
>> v6: add changes suggested by Rob Herring
>> v5: change Documentation to dt-bindings in commit title
>> v4: no changes
>> v3: add new gpio node
>> v2: remove interrupts
>> 
>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>> 1 file changed, 174 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> 
>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> new file mode 100644
>> index 000000000000..471f6efa1754
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> @@ -0,0 +1,174 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Broadcom BCM6328 pin controller
>> +
>> +maintainers:
>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>> +
>> +description: |+
>> +  The pin controller node should be the child of a syscon node.
>> +
>> +  Refer to the the bindings described in
>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>> +
>> +properties:
>> +  compatible:
>> +    const: brcm,bcm6328-pinctrl
>> +
>> +  gpio:
>> +    type: object
>> +    properties:
>> +      compatible:
>> +        const: brcm,bcm6328-gpio
>> +
>> +      data:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        description: |
>> +          Offset in the register map for the data register (in bytes).
>> +
>> +      dirout:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        description: |
>> +          Offset in the register map for the dirout register (in bytes).
>> +
>> +      gpio-controller: true
>> +
>> +      "#gpio-cells":
>> +        const: 2
>> +
>> +      gpio-ranges:
>> +        maxItems: 1
>> +
>> +    required:
>> +      - gpio-controller
>> +      - gpio-ranges
>> +      - '#gpio-cells'
>> +
>> +    additionalProperties: false
>> +
>> +patternProperties:
>> +  '^.*-pins$':
>> +    if:
>> +      type: object
>> +    then:
>> +      properties:
>> +        function:
>> +          $ref: "pinmux-node.yaml#/properties/function"
>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>> +
>> +        pins:
>> +          $ref: "pinmux-node.yaml#/properties/pins"
>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>> +                  usb_port1 ]
>> +
>> +required:
>> +  - compatible
>> +  - gpio
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    gpio_cntl@10000080 {
>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> 
> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.

I just added that because you requested me to do it ¯\_(ツ)_/¯
What should I do to document it?
I still don’t get most of this .yaml stuff...

> 
>> +      reg = <0x10000080 0x80>;
>> +
>> +      pinctrl: pinctrl {
>> +        compatible = "brcm,bcm6328-pinctrl";
>> +
>> +        gpio {
>> +          compatible = "brcm,bcm6328-gpio";
> 
> I'm still trying to understand why you need 3 levels of nodes here?
> The gpio controller contains a pin controller plus other undefined
> functions (because of 'syscon') and the pin controller contains a gpio
> controller?

In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…

> 
> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> should be a single node.

I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
Something like:
syscon {
	pinctrl: pinctrl {
		compatible …

		gpio-controller;
		gpio-ranges = <&pinctrl 0 0 32>;
		#gpio-cells = <2>;

		…
	};
};

> 
>> +          data = <0xc>;
>> +          dirout = <0x4>;
> 
> This looks similar to the brcm,bcm6345-gpio.txt binding which then
> uses the gpio-mmio driver. Defining addresses with 'reg' is much
> preferred over custom properties. That binding also captures the bank
> size.

It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.

> 
> Rob

Best regards,
Álvaro.

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 18:03       ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 18:03 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>> 
>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> ---
>> v6: add changes suggested by Rob Herring
>> v5: change Documentation to dt-bindings in commit title
>> v4: no changes
>> v3: add new gpio node
>> v2: remove interrupts
>> 
>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>> 1 file changed, 174 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> 
>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> new file mode 100644
>> index 000000000000..471f6efa1754
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>> @@ -0,0 +1,174 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Broadcom BCM6328 pin controller
>> +
>> +maintainers:
>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>> +
>> +description: |+
>> +  The pin controller node should be the child of a syscon node.
>> +
>> +  Refer to the the bindings described in
>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>> +
>> +properties:
>> +  compatible:
>> +    const: brcm,bcm6328-pinctrl
>> +
>> +  gpio:
>> +    type: object
>> +    properties:
>> +      compatible:
>> +        const: brcm,bcm6328-gpio
>> +
>> +      data:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        description: |
>> +          Offset in the register map for the data register (in bytes).
>> +
>> +      dirout:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        description: |
>> +          Offset in the register map for the dirout register (in bytes).
>> +
>> +      gpio-controller: true
>> +
>> +      "#gpio-cells":
>> +        const: 2
>> +
>> +      gpio-ranges:
>> +        maxItems: 1
>> +
>> +    required:
>> +      - gpio-controller
>> +      - gpio-ranges
>> +      - '#gpio-cells'
>> +
>> +    additionalProperties: false
>> +
>> +patternProperties:
>> +  '^.*-pins$':
>> +    if:
>> +      type: object
>> +    then:
>> +      properties:
>> +        function:
>> +          $ref: "pinmux-node.yaml#/properties/function"
>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>> +
>> +        pins:
>> +          $ref: "pinmux-node.yaml#/properties/pins"
>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>> +                  usb_port1 ]
>> +
>> +required:
>> +  - compatible
>> +  - gpio
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    gpio_cntl@10000080 {
>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> 
> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.

I just added that because you requested me to do it ¯\_(ツ)_/¯
What should I do to document it?
I still don’t get most of this .yaml stuff...

> 
>> +      reg = <0x10000080 0x80>;
>> +
>> +      pinctrl: pinctrl {
>> +        compatible = "brcm,bcm6328-pinctrl";
>> +
>> +        gpio {
>> +          compatible = "brcm,bcm6328-gpio";
> 
> I'm still trying to understand why you need 3 levels of nodes here?
> The gpio controller contains a pin controller plus other undefined
> functions (because of 'syscon') and the pin controller contains a gpio
> controller?

In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…

> 
> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> should be a single node.

I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
Something like:
syscon {
	pinctrl: pinctrl {
		compatible …

		gpio-controller;
		gpio-ranges = <&pinctrl 0 0 32>;
		#gpio-cells = <2>;

		…
	};
};

> 
>> +          data = <0xc>;
>> +          dirout = <0x4>;
> 
> This looks similar to the brcm,bcm6345-gpio.txt binding which then
> uses the gpio-mmio driver. Defining addresses with 'reg' is much
> preferred over custom properties. That binding also captures the bank
> size.

It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.

> 
> Rob

Best regards,
Álvaro.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
  2021-03-10 12:54   ` Álvaro Fernández Rojas
@ 2021-03-10 18:27     ` Michael Walle
  -1 siblings, 0 replies; 76+ messages in thread
From: Michael Walle @ 2021-03-10 18:27 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel

Am 2021-03-10 13:54, schrieb Álvaro Fernández Rojas:
> This is needed for properly registering GPIO regmap as a child of a 
> regmap
> pin controller.
> 
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> Reviewed-by: Michael Walle <michael@walle.cc>
> ---
>  v6: add comment and simplify of_node assignment

Ah, I see you add the comment for the documentation. Nice. But I'd
like to see it in the code, too. See below.

>  v5: switch to fwnode
>  v4: fix documentation
>  v3: introduce patch needed for properly parsing gpio-range
> 
>  drivers/gpio/gpio-regmap.c  | 1 +
>  include/linux/gpio/regmap.h | 4 ++++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> index 5412cb3b0b2a..d4fc656e70b0 100644
> --- a/drivers/gpio/gpio-regmap.c
> +++ b/drivers/gpio/gpio-regmap.c
> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const
> struct gpio_regmap_config *config
> 
>  	chip = &gpio->gpio_chip;
>  	chip->parent = config->parent;

If there will be a new version, please add the following comment:

/* gpiolib will use of_node of the parent if chip->of_node is NULL */

>> +       chip->of_node = to_of_node(config->fwnode);

Otherwise, it is not obvious that config->fwnode is optional.

-michael

> +	chip->of_node = to_of_node(config->fwnode);
>  	chip->base = -1;
>  	chip->ngpio = config->ngpio;
>  	chip->names = config->names;
> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
> index ad76f3d0a6ba..334dd928042b 100644
> --- a/include/linux/gpio/regmap.h
> +++ b/include/linux/gpio/regmap.h
> @@ -4,6 +4,7 @@
>  #define _LINUX_GPIO_REGMAP_H
> 
>  struct device;
> +struct fwnode_handle;
>  struct gpio_regmap;
>  struct irq_domain;
>  struct regmap;
> @@ -16,6 +17,8 @@ struct regmap;
>   * @parent:		The parent device
>   * @regmap:		The regmap used to access the registers
>   *			given, the name of the device is used
> + * @fwnode:		(Optional) The firmware node.
> + *			If not given, the fwnode of the parent is used.
>   * @label:		(Optional) Descriptive name for GPIO controller.
>   *			If not given, the name of the device is used.
>   * @ngpio:		Number of GPIOs
> @@ -57,6 +60,7 @@ struct regmap;
>  struct gpio_regmap_config {
>  	struct device *parent;
>  	struct regmap *regmap;
> +	struct fwnode_handle *fwnode;
> 
>  	const char *label;
>  	int ngpio;

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
@ 2021-03-10 18:27     ` Michael Walle
  0 siblings, 0 replies; 76+ messages in thread
From: Michael Walle @ 2021-03-10 18:27 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel

Am 2021-03-10 13:54, schrieb Álvaro Fernández Rojas:
> This is needed for properly registering GPIO regmap as a child of a 
> regmap
> pin controller.
> 
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> Reviewed-by: Michael Walle <michael@walle.cc>
> ---
>  v6: add comment and simplify of_node assignment

Ah, I see you add the comment for the documentation. Nice. But I'd
like to see it in the code, too. See below.

>  v5: switch to fwnode
>  v4: fix documentation
>  v3: introduce patch needed for properly parsing gpio-range
> 
>  drivers/gpio/gpio-regmap.c  | 1 +
>  include/linux/gpio/regmap.h | 4 ++++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
> index 5412cb3b0b2a..d4fc656e70b0 100644
> --- a/drivers/gpio/gpio-regmap.c
> +++ b/drivers/gpio/gpio-regmap.c
> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const
> struct gpio_regmap_config *config
> 
>  	chip = &gpio->gpio_chip;
>  	chip->parent = config->parent;

If there will be a new version, please add the following comment:

/* gpiolib will use of_node of the parent if chip->of_node is NULL */

>> +       chip->of_node = to_of_node(config->fwnode);

Otherwise, it is not obvious that config->fwnode is optional.

-michael

> +	chip->of_node = to_of_node(config->fwnode);
>  	chip->base = -1;
>  	chip->ngpio = config->ngpio;
>  	chip->names = config->names;
> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
> index ad76f3d0a6ba..334dd928042b 100644
> --- a/include/linux/gpio/regmap.h
> +++ b/include/linux/gpio/regmap.h
> @@ -4,6 +4,7 @@
>  #define _LINUX_GPIO_REGMAP_H
> 
>  struct device;
> +struct fwnode_handle;
>  struct gpio_regmap;
>  struct irq_domain;
>  struct regmap;
> @@ -16,6 +17,8 @@ struct regmap;
>   * @parent:		The parent device
>   * @regmap:		The regmap used to access the registers
>   *			given, the name of the device is used
> + * @fwnode:		(Optional) The firmware node.
> + *			If not given, the fwnode of the parent is used.
>   * @label:		(Optional) Descriptive name for GPIO controller.
>   *			If not given, the name of the device is used.
>   * @ngpio:		Number of GPIOs
> @@ -57,6 +60,7 @@ struct regmap;
>  struct gpio_regmap_config {
>  	struct device *parent;
>  	struct regmap *regmap;
> +	struct fwnode_handle *fwnode;
> 
>  	const char *label;
>  	int ngpio;

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 18:03       ` Álvaro Fernández Rojas
@ 2021-03-10 18:45         ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 18:45 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> > El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >
> > On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>
> >> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >> ---
> >> v6: add changes suggested by Rob Herring
> >> v5: change Documentation to dt-bindings in commit title
> >> v4: no changes
> >> v3: add new gpio node
> >> v2: remove interrupts
> >>
> >> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >> 1 file changed, 174 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >> new file mode 100644
> >> index 000000000000..471f6efa1754
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >> @@ -0,0 +1,174 @@
> >> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Broadcom BCM6328 pin controller
> >> +
> >> +maintainers:
> >> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >> +
> >> +description: |+
> >> +  The pin controller node should be the child of a syscon node.
> >> +
> >> +  Refer to the the bindings described in
> >> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >> +
> >> +properties:
> >> +  compatible:
> >> +    const: brcm,bcm6328-pinctrl
> >> +
> >> +  gpio:
> >> +    type: object
> >> +    properties:
> >> +      compatible:
> >> +        const: brcm,bcm6328-gpio
> >> +
> >> +      data:
> >> +        $ref: /schemas/types.yaml#/definitions/uint32
> >> +        description: |
> >> +          Offset in the register map for the data register (in bytes).
> >> +
> >> +      dirout:
> >> +        $ref: /schemas/types.yaml#/definitions/uint32
> >> +        description: |
> >> +          Offset in the register map for the dirout register (in bytes).
> >> +
> >> +      gpio-controller: true
> >> +
> >> +      "#gpio-cells":
> >> +        const: 2
> >> +
> >> +      gpio-ranges:
> >> +        maxItems: 1
> >> +
> >> +    required:
> >> +      - gpio-controller
> >> +      - gpio-ranges
> >> +      - '#gpio-cells'
> >> +
> >> +    additionalProperties: false
> >> +
> >> +patternProperties:
> >> +  '^.*-pins$':
> >> +    if:
> >> +      type: object
> >> +    then:
> >> +      properties:
> >> +        function:
> >> +          $ref: "pinmux-node.yaml#/properties/function"
> >> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >> +
> >> +        pins:
> >> +          $ref: "pinmux-node.yaml#/properties/pins"
> >> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >> +                  usb_port1 ]
> >> +
> >> +required:
> >> +  - compatible
> >> +  - gpio
> >> +
> >> +additionalProperties: false
> >> +
> >> +examples:
> >> +  - |
> >> +    gpio_cntl@10000080 {
> >> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >
> > You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>
> I just added that because you requested me to do it ¯\_(ツ)_/¯

I said 'syscon' by itself was not allowed, then asked about the multiple levels.

> What should I do to document it?
> I still don’t get most of this .yaml stuff...
>
> >
> >> +      reg = <0x10000080 0x80>;
> >> +
> >> +      pinctrl: pinctrl {
> >> +        compatible = "brcm,bcm6328-pinctrl";
> >> +
> >> +        gpio {
> >> +          compatible = "brcm,bcm6328-gpio";
> >
> > I'm still trying to understand why you need 3 levels of nodes here?
> > The gpio controller contains a pin controller plus other undefined
> > functions (because of 'syscon') and the pin controller contains a gpio
> > controller?
>
> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>
> >
> > I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> > should be a single node.
>
> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?

It wouldn't be. I wasn't saying the pinctrl and gpio controller are
the same node. My suggestion was combining syscon and pinctrl.

> Something like:
> syscon {

Again with the syscon. If pinctrl and GPIO are the only functions
within this h/w block, then this is not a syscon. You are just abusing
that having 'syscon' compatible means you get a regmap created
automagically for you. Nothing here looks like a 'system controller'
to me. A 'system controller' is a random collection of register bits
with functions that don't fit anywhere else.

>         pinctrl: pinctrl {
>                 compatible …
>
>                 gpio-controller;
>                 gpio-ranges = <&pinctrl 0 0 32>;
>                 #gpio-cells = <2>;

I was assuming you have multiple GPIO controllers within 1 pinctlr?
The pinctrl and gpio could be a single node like above if there's only
1 GPIO controller. But I'm still somewhat guessing what the h/w looks
like because I have to go searching thru the driver to decipher.
Please describe the h/w in the binding.

If there's more than 1 GPIO controller, then I'd imagine you have
something like this:

pinctrl {
  ...
  reg = <base 0x80>;
  ranges = <0 base 0x80;
  gpio@4 {
    reg = <4 4>, <c 4>;
    reg-names = "dirout", "dat";
  };
  gpio@? {};

  foo-pins {};
};

>
>                 …
>         };
> };
>
> >
> >> +          data = <0xc>;
> >> +          dirout = <0x4>;
> >
> > This looks similar to the brcm,bcm6345-gpio.txt binding which then
> > uses the gpio-mmio driver. Defining addresses with 'reg' is much
> > preferred over custom properties. That binding also captures the bank
> > size.
>
> It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.

Looks like you have 2 registers to me.

Rob

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 18:45         ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 18:45 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> > El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >
> > On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>
> >> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >> ---
> >> v6: add changes suggested by Rob Herring
> >> v5: change Documentation to dt-bindings in commit title
> >> v4: no changes
> >> v3: add new gpio node
> >> v2: remove interrupts
> >>
> >> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >> 1 file changed, 174 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >> new file mode 100644
> >> index 000000000000..471f6efa1754
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >> @@ -0,0 +1,174 @@
> >> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Broadcom BCM6328 pin controller
> >> +
> >> +maintainers:
> >> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >> +
> >> +description: |+
> >> +  The pin controller node should be the child of a syscon node.
> >> +
> >> +  Refer to the the bindings described in
> >> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >> +
> >> +properties:
> >> +  compatible:
> >> +    const: brcm,bcm6328-pinctrl
> >> +
> >> +  gpio:
> >> +    type: object
> >> +    properties:
> >> +      compatible:
> >> +        const: brcm,bcm6328-gpio
> >> +
> >> +      data:
> >> +        $ref: /schemas/types.yaml#/definitions/uint32
> >> +        description: |
> >> +          Offset in the register map for the data register (in bytes).
> >> +
> >> +      dirout:
> >> +        $ref: /schemas/types.yaml#/definitions/uint32
> >> +        description: |
> >> +          Offset in the register map for the dirout register (in bytes).
> >> +
> >> +      gpio-controller: true
> >> +
> >> +      "#gpio-cells":
> >> +        const: 2
> >> +
> >> +      gpio-ranges:
> >> +        maxItems: 1
> >> +
> >> +    required:
> >> +      - gpio-controller
> >> +      - gpio-ranges
> >> +      - '#gpio-cells'
> >> +
> >> +    additionalProperties: false
> >> +
> >> +patternProperties:
> >> +  '^.*-pins$':
> >> +    if:
> >> +      type: object
> >> +    then:
> >> +      properties:
> >> +        function:
> >> +          $ref: "pinmux-node.yaml#/properties/function"
> >> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >> +
> >> +        pins:
> >> +          $ref: "pinmux-node.yaml#/properties/pins"
> >> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >> +                  usb_port1 ]
> >> +
> >> +required:
> >> +  - compatible
> >> +  - gpio
> >> +
> >> +additionalProperties: false
> >> +
> >> +examples:
> >> +  - |
> >> +    gpio_cntl@10000080 {
> >> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >
> > You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>
> I just added that because you requested me to do it ¯\_(ツ)_/¯

I said 'syscon' by itself was not allowed, then asked about the multiple levels.

> What should I do to document it?
> I still don’t get most of this .yaml stuff...
>
> >
> >> +      reg = <0x10000080 0x80>;
> >> +
> >> +      pinctrl: pinctrl {
> >> +        compatible = "brcm,bcm6328-pinctrl";
> >> +
> >> +        gpio {
> >> +          compatible = "brcm,bcm6328-gpio";
> >
> > I'm still trying to understand why you need 3 levels of nodes here?
> > The gpio controller contains a pin controller plus other undefined
> > functions (because of 'syscon') and the pin controller contains a gpio
> > controller?
>
> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>
> >
> > I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> > should be a single node.
>
> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?

It wouldn't be. I wasn't saying the pinctrl and gpio controller are
the same node. My suggestion was combining syscon and pinctrl.

> Something like:
> syscon {

Again with the syscon. If pinctrl and GPIO are the only functions
within this h/w block, then this is not a syscon. You are just abusing
that having 'syscon' compatible means you get a regmap created
automagically for you. Nothing here looks like a 'system controller'
to me. A 'system controller' is a random collection of register bits
with functions that don't fit anywhere else.

>         pinctrl: pinctrl {
>                 compatible …
>
>                 gpio-controller;
>                 gpio-ranges = <&pinctrl 0 0 32>;
>                 #gpio-cells = <2>;

I was assuming you have multiple GPIO controllers within 1 pinctlr?
The pinctrl and gpio could be a single node like above if there's only
1 GPIO controller. But I'm still somewhat guessing what the h/w looks
like because I have to go searching thru the driver to decipher.
Please describe the h/w in the binding.

If there's more than 1 GPIO controller, then I'd imagine you have
something like this:

pinctrl {
  ...
  reg = <base 0x80>;
  ranges = <0 base 0x80;
  gpio@4 {
    reg = <4 4>, <c 4>;
    reg-names = "dirout", "dat";
  };
  gpio@? {};

  foo-pins {};
};

>
>                 …
>         };
> };
>
> >
> >> +          data = <0xc>;
> >> +          dirout = <0x4>;
> >
> > This looks similar to the brcm,bcm6345-gpio.txt binding which then
> > uses the gpio-mmio driver. Defining addresses with 'reg' is much
> > preferred over custom properties. That binding also captures the bank
> > size.
>
> It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.

Looks like you have 2 registers to me.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 18:45         ` Rob Herring
@ 2021-03-10 19:10           ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 19:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob,
>> 
>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>> 
>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>> 
>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>> 
>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>> ---
>>>> v6: add changes suggested by Rob Herring
>>>> v5: change Documentation to dt-bindings in commit title
>>>> v4: no changes
>>>> v3: add new gpio node
>>>> v2: remove interrupts
>>>> 
>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>> 1 file changed, 174 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> 
>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> new file mode 100644
>>>> index 000000000000..471f6efa1754
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> @@ -0,0 +1,174 @@
>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Broadcom BCM6328 pin controller
>>>> +
>>>> +maintainers:
>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>> +
>>>> +description: |+
>>>> +  The pin controller node should be the child of a syscon node.
>>>> +
>>>> +  Refer to the the bindings described in
>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: brcm,bcm6328-pinctrl
>>>> +
>>>> +  gpio:
>>>> +    type: object
>>>> +    properties:
>>>> +      compatible:
>>>> +        const: brcm,bcm6328-gpio
>>>> +
>>>> +      data:
>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>> +        description: |
>>>> +          Offset in the register map for the data register (in bytes).
>>>> +
>>>> +      dirout:
>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>> +        description: |
>>>> +          Offset in the register map for the dirout register (in bytes).
>>>> +
>>>> +      gpio-controller: true
>>>> +
>>>> +      "#gpio-cells":
>>>> +        const: 2
>>>> +
>>>> +      gpio-ranges:
>>>> +        maxItems: 1
>>>> +
>>>> +    required:
>>>> +      - gpio-controller
>>>> +      - gpio-ranges
>>>> +      - '#gpio-cells'
>>>> +
>>>> +    additionalProperties: false
>>>> +
>>>> +patternProperties:
>>>> +  '^.*-pins$':
>>>> +    if:
>>>> +      type: object
>>>> +    then:
>>>> +      properties:
>>>> +        function:
>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>> +
>>>> +        pins:
>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>> +                  usb_port1 ]
>>>> +
>>>> +required:
>>>> +  - compatible
>>>> +  - gpio
>>>> +
>>>> +additionalProperties: false
>>>> +
>>>> +examples:
>>>> +  - |
>>>> +    gpio_cntl@10000080 {
>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>> 
>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>> 
>> I just added that because you requested me to do it ¯\_(ツ)_/¯
> 
> I said 'syscon' by itself was not allowed, then asked about the multiple levels.

Why not?
What if you have several controllers inside a syscon?
The root should also have “something" in it?

> 
>> What should I do to document it?
>> I still don’t get most of this .yaml stuff...
>> 
>>> 
>>>> +      reg = <0x10000080 0x80>;
>>>> +
>>>> +      pinctrl: pinctrl {
>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>> +
>>>> +        gpio {
>>>> +          compatible = "brcm,bcm6328-gpio";
>>> 
>>> I'm still trying to understand why you need 3 levels of nodes here?
>>> The gpio controller contains a pin controller plus other undefined
>>> functions (because of 'syscon') and the pin controller contains a gpio
>>> controller?
>> 
>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>> 
>>> 
>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>> should be a single node.
>> 
>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> 
> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> the same node. My suggestion was combining syscon and pinctrl.

But that wouldn’t be correct if there were more “things” inside the syscon, right?

> 
>> Something like:
>> syscon {
> 
> Again with the syscon. If pinctrl and GPIO are the only functions
> within this h/w block, then this is not a syscon. You are just abusing
> that having 'syscon' compatible means you get a regmap created
> automagically for you. Nothing here looks like a 'system controller'
> to me. A 'system controller' is a random collection of register bits
> with functions that don't fit anywhere else.

pinctrl and GPIO aren’t the only functions within this HW block.
Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
typedef struct GpioControl {
    uint32      GPIODirHi;                  /* 0 */
    uint32      GPIODir;                    /* 4 */
    uint32      GPIOioHi;                   /* 8 */
    uint32      GPIOio;                     /* C */
    uint32      unused0;                    /* 10 */
    uint32      SpiSlaveCfg;                /* 14 */
    uint32      GPIOMode;                   /* 18 */
    uint64      PinMuxSel;                  /* 1C */
    uint32      PinMuxSelOther;             /* 24 */
    uint32      TestControl;                /* 28 */
    uint32      unused2;                    /* 2C */
    uint32      RoboSWLEDControl;           /* 30 */
    uint32      RoboSWLEDLSR;               /* 34 */
    uint32      unused3;                    /* 38 */
    uint32      RoboswEphyCtrl;             /* 3C */
    uint32      RoboswSwitchCtrl;           /* 40 */
    uint32      RegFileTmCtl;               /* 44 */
    uint32      RingOscCtrl0;               /* 48 */
    uint32      RingOscCtrl1;               /* 4C */
    uint32      unused4[6];                 /* 50 - 64 */
    uint32      DieRevID;                   /* 68 */
    uint32      unused5;                    /* 6c */
    uint32      DiagSelControl;             /* 70 */
    uint32      DiagReadBack;               /* 74 */
    uint32      DiagReadBackHi;             /* 78 */
    uint32      DiagMiscControl;            /* 7c */
} GpioControl;

So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
And this is for BCM6328, but some of the other SoCs are even more scattered.

> 
>>        pinctrl: pinctrl {
>>                compatible …
>> 
>>                gpio-controller;
>>                gpio-ranges = <&pinctrl 0 0 32>;
>>                #gpio-cells = <2>;
> 
> I was assuming you have multiple GPIO controllers within 1 pinctlr?
> The pinctrl and gpio could be a single node like above if there's only
> 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
> like because I have to go searching thru the driver to decipher.
> Please describe the h/w in the binding.

GPIO dirout and data rely on 2x u32 registers or a single u64 register.
This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.

> 
> If there's more than 1 GPIO controller, then I'd imagine you have
> something like this:
> 
> pinctrl {
>  ...
>  reg = <base 0x80>;
>  ranges = <0 base 0x80;
>  gpio@4 {
>    reg = <4 4>, <c 4>;
>    reg-names = "dirout", "dat";
>  };
>  gpio@? {};
> 
>  foo-pins {};
> };
> 
>> 
>>                …
>>        };
>> };
>> 
>>> 
>>>> +          data = <0xc>;
>>>> +          dirout = <0x4>;
>>> 
>>> This looks similar to the brcm,bcm6345-gpio.txt binding which then
>>> uses the gpio-mmio driver. Defining addresses with 'reg' is much
>>> preferred over custom properties. That binding also captures the bank
>>> size.
>> 
>> It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.
> 
> Looks like you have 2 registers to me.

For the GPIO controller there are 4 registers (data high and low, and dirout high and low).
For the pinctrl there are 3 registers (Pinmux high, low and other).

> 
> Rob

Best regards,
Álvaro.

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 19:10           ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 19:10 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob,
>> 
>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>> 
>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>> 
>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>> 
>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>> ---
>>>> v6: add changes suggested by Rob Herring
>>>> v5: change Documentation to dt-bindings in commit title
>>>> v4: no changes
>>>> v3: add new gpio node
>>>> v2: remove interrupts
>>>> 
>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>> 1 file changed, 174 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> 
>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> new file mode 100644
>>>> index 000000000000..471f6efa1754
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>> @@ -0,0 +1,174 @@
>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Broadcom BCM6328 pin controller
>>>> +
>>>> +maintainers:
>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>> +
>>>> +description: |+
>>>> +  The pin controller node should be the child of a syscon node.
>>>> +
>>>> +  Refer to the the bindings described in
>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: brcm,bcm6328-pinctrl
>>>> +
>>>> +  gpio:
>>>> +    type: object
>>>> +    properties:
>>>> +      compatible:
>>>> +        const: brcm,bcm6328-gpio
>>>> +
>>>> +      data:
>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>> +        description: |
>>>> +          Offset in the register map for the data register (in bytes).
>>>> +
>>>> +      dirout:
>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>> +        description: |
>>>> +          Offset in the register map for the dirout register (in bytes).
>>>> +
>>>> +      gpio-controller: true
>>>> +
>>>> +      "#gpio-cells":
>>>> +        const: 2
>>>> +
>>>> +      gpio-ranges:
>>>> +        maxItems: 1
>>>> +
>>>> +    required:
>>>> +      - gpio-controller
>>>> +      - gpio-ranges
>>>> +      - '#gpio-cells'
>>>> +
>>>> +    additionalProperties: false
>>>> +
>>>> +patternProperties:
>>>> +  '^.*-pins$':
>>>> +    if:
>>>> +      type: object
>>>> +    then:
>>>> +      properties:
>>>> +        function:
>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>> +
>>>> +        pins:
>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>> +                  usb_port1 ]
>>>> +
>>>> +required:
>>>> +  - compatible
>>>> +  - gpio
>>>> +
>>>> +additionalProperties: false
>>>> +
>>>> +examples:
>>>> +  - |
>>>> +    gpio_cntl@10000080 {
>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>> 
>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>> 
>> I just added that because you requested me to do it ¯\_(ツ)_/¯
> 
> I said 'syscon' by itself was not allowed, then asked about the multiple levels.

Why not?
What if you have several controllers inside a syscon?
The root should also have “something" in it?

> 
>> What should I do to document it?
>> I still don’t get most of this .yaml stuff...
>> 
>>> 
>>>> +      reg = <0x10000080 0x80>;
>>>> +
>>>> +      pinctrl: pinctrl {
>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>> +
>>>> +        gpio {
>>>> +          compatible = "brcm,bcm6328-gpio";
>>> 
>>> I'm still trying to understand why you need 3 levels of nodes here?
>>> The gpio controller contains a pin controller plus other undefined
>>> functions (because of 'syscon') and the pin controller contains a gpio
>>> controller?
>> 
>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>> 
>>> 
>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>> should be a single node.
>> 
>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> 
> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> the same node. My suggestion was combining syscon and pinctrl.

But that wouldn’t be correct if there were more “things” inside the syscon, right?

> 
>> Something like:
>> syscon {
> 
> Again with the syscon. If pinctrl and GPIO are the only functions
> within this h/w block, then this is not a syscon. You are just abusing
> that having 'syscon' compatible means you get a regmap created
> automagically for you. Nothing here looks like a 'system controller'
> to me. A 'system controller' is a random collection of register bits
> with functions that don't fit anywhere else.

pinctrl and GPIO aren’t the only functions within this HW block.
Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
typedef struct GpioControl {
    uint32      GPIODirHi;                  /* 0 */
    uint32      GPIODir;                    /* 4 */
    uint32      GPIOioHi;                   /* 8 */
    uint32      GPIOio;                     /* C */
    uint32      unused0;                    /* 10 */
    uint32      SpiSlaveCfg;                /* 14 */
    uint32      GPIOMode;                   /* 18 */
    uint64      PinMuxSel;                  /* 1C */
    uint32      PinMuxSelOther;             /* 24 */
    uint32      TestControl;                /* 28 */
    uint32      unused2;                    /* 2C */
    uint32      RoboSWLEDControl;           /* 30 */
    uint32      RoboSWLEDLSR;               /* 34 */
    uint32      unused3;                    /* 38 */
    uint32      RoboswEphyCtrl;             /* 3C */
    uint32      RoboswSwitchCtrl;           /* 40 */
    uint32      RegFileTmCtl;               /* 44 */
    uint32      RingOscCtrl0;               /* 48 */
    uint32      RingOscCtrl1;               /* 4C */
    uint32      unused4[6];                 /* 50 - 64 */
    uint32      DieRevID;                   /* 68 */
    uint32      unused5;                    /* 6c */
    uint32      DiagSelControl;             /* 70 */
    uint32      DiagReadBack;               /* 74 */
    uint32      DiagReadBackHi;             /* 78 */
    uint32      DiagMiscControl;            /* 7c */
} GpioControl;

So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
And this is for BCM6328, but some of the other SoCs are even more scattered.

> 
>>        pinctrl: pinctrl {
>>                compatible …
>> 
>>                gpio-controller;
>>                gpio-ranges = <&pinctrl 0 0 32>;
>>                #gpio-cells = <2>;
> 
> I was assuming you have multiple GPIO controllers within 1 pinctlr?
> The pinctrl and gpio could be a single node like above if there's only
> 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
> like because I have to go searching thru the driver to decipher.
> Please describe the h/w in the binding.

GPIO dirout and data rely on 2x u32 registers or a single u64 register.
This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.

> 
> If there's more than 1 GPIO controller, then I'd imagine you have
> something like this:
> 
> pinctrl {
>  ...
>  reg = <base 0x80>;
>  ranges = <0 base 0x80;
>  gpio@4 {
>    reg = <4 4>, <c 4>;
>    reg-names = "dirout", "dat";
>  };
>  gpio@? {};
> 
>  foo-pins {};
> };
> 
>> 
>>                …
>>        };
>> };
>> 
>>> 
>>>> +          data = <0xc>;
>>>> +          dirout = <0x4>;
>>> 
>>> This looks similar to the brcm,bcm6345-gpio.txt binding which then
>>> uses the gpio-mmio driver. Defining addresses with 'reg' is much
>>> preferred over custom properties. That binding also captures the bank
>>> size.
>> 
>> It’s similar, but Linus requested to use gpio regmap because we had a large amount of registers, so we’re not using it.
> 
> Looks like you have 2 registers to me.

For the GPIO controller there are 4 registers (data high and low, and dirout high and low).
For the pinctrl there are 3 registers (Pinmux high, low and other).

> 
> Rob

Best regards,
Álvaro.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
  2021-03-10 18:27     ` Michael Walle
@ 2021-03-10 19:12       ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 19:12 UTC (permalink / raw)
  To: Michael Walle
  Cc: Linus Walleij, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel

Hi Michael,

> El 10 mar 2021, a las 19:27, Michael Walle <michael@walle.cc> escribió:
> 
> Am 2021-03-10 13:54, schrieb Álvaro Fernández Rojas:
>> This is needed for properly registering GPIO regmap as a child of a regmap
>> pin controller.
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> Reviewed-by: Michael Walle <michael@walle.cc>
>> ---
>> v6: add comment and simplify of_node assignment
> 
> Ah, I see you add the comment for the documentation. Nice. But I'd
> like to see it in the code, too. See below.

Ah, sorry for that, I thought you wanted it on the header.
Excuse me for that...

> 
>> v5: switch to fwnode
>> v4: fix documentation
>> v3: introduce patch needed for properly parsing gpio-range
>> drivers/gpio/gpio-regmap.c  | 1 +
>> include/linux/gpio/regmap.h | 4 ++++
>> 2 files changed, 5 insertions(+)
>> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
>> index 5412cb3b0b2a..d4fc656e70b0 100644
>> --- a/drivers/gpio/gpio-regmap.c
>> +++ b/drivers/gpio/gpio-regmap.c
>> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const
>> struct gpio_regmap_config *config
>> 	chip = &gpio->gpio_chip;
>> 	chip->parent = config->parent;
> 
> If there will be a new version, please add the following comment:

Right now I don’t know that either, because I’m honestly getting tired of this…

> 
> /* gpiolib will use of_node of the parent if chip->of_node is NULL */
> 
>>> +       chip->of_node = to_of_node(config->fwnode);
> 
> Otherwise, it is not obvious that config->fwnode is optional.

Yes, you’re right.

> 
> -michael
> 
>> +	chip->of_node = to_of_node(config->fwnode);
>> 	chip->base = -1;
>> 	chip->ngpio = config->ngpio;
>> 	chip->names = config->names;
>> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
>> index ad76f3d0a6ba..334dd928042b 100644
>> --- a/include/linux/gpio/regmap.h
>> +++ b/include/linux/gpio/regmap.h
>> @@ -4,6 +4,7 @@
>> #define _LINUX_GPIO_REGMAP_H
>> struct device;
>> +struct fwnode_handle;
>> struct gpio_regmap;
>> struct irq_domain;
>> struct regmap;
>> @@ -16,6 +17,8 @@ struct regmap;
>>  * @parent:		The parent device
>>  * @regmap:		The regmap used to access the registers
>>  *			given, the name of the device is used
>> + * @fwnode:		(Optional) The firmware node.
>> + *			If not given, the fwnode of the parent is used.
>>  * @label:		(Optional) Descriptive name for GPIO controller.
>>  *			If not given, the name of the device is used.
>>  * @ngpio:		Number of GPIOs
>> @@ -57,6 +60,7 @@ struct regmap;
>> struct gpio_regmap_config {
>> 	struct device *parent;
>> 	struct regmap *regmap;
>> +	struct fwnode_handle *fwnode;
>> 	const char *label;
>> 	int ngpio;


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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
@ 2021-03-10 19:12       ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-10 19:12 UTC (permalink / raw)
  To: Michael Walle
  Cc: Linus Walleij, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, linux-gpio, devicetree,
	linux-kernel, linux-arm-kernel

Hi Michael,

> El 10 mar 2021, a las 19:27, Michael Walle <michael@walle.cc> escribió:
> 
> Am 2021-03-10 13:54, schrieb Álvaro Fernández Rojas:
>> This is needed for properly registering GPIO regmap as a child of a regmap
>> pin controller.
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> Reviewed-by: Michael Walle <michael@walle.cc>
>> ---
>> v6: add comment and simplify of_node assignment
> 
> Ah, I see you add the comment for the documentation. Nice. But I'd
> like to see it in the code, too. See below.

Ah, sorry for that, I thought you wanted it on the header.
Excuse me for that...

> 
>> v5: switch to fwnode
>> v4: fix documentation
>> v3: introduce patch needed for properly parsing gpio-range
>> drivers/gpio/gpio-regmap.c  | 1 +
>> include/linux/gpio/regmap.h | 4 ++++
>> 2 files changed, 5 insertions(+)
>> diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
>> index 5412cb3b0b2a..d4fc656e70b0 100644
>> --- a/drivers/gpio/gpio-regmap.c
>> +++ b/drivers/gpio/gpio-regmap.c
>> @@ -249,6 +249,7 @@ struct gpio_regmap *gpio_regmap_register(const
>> struct gpio_regmap_config *config
>> 	chip = &gpio->gpio_chip;
>> 	chip->parent = config->parent;
> 
> If there will be a new version, please add the following comment:

Right now I don’t know that either, because I’m honestly getting tired of this…

> 
> /* gpiolib will use of_node of the parent if chip->of_node is NULL */
> 
>>> +       chip->of_node = to_of_node(config->fwnode);
> 
> Otherwise, it is not obvious that config->fwnode is optional.

Yes, you’re right.

> 
> -michael
> 
>> +	chip->of_node = to_of_node(config->fwnode);
>> 	chip->base = -1;
>> 	chip->ngpio = config->ngpio;
>> 	chip->names = config->names;
>> diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
>> index ad76f3d0a6ba..334dd928042b 100644
>> --- a/include/linux/gpio/regmap.h
>> +++ b/include/linux/gpio/regmap.h
>> @@ -4,6 +4,7 @@
>> #define _LINUX_GPIO_REGMAP_H
>> struct device;
>> +struct fwnode_handle;
>> struct gpio_regmap;
>> struct irq_domain;
>> struct regmap;
>> @@ -16,6 +17,8 @@ struct regmap;
>>  * @parent:		The parent device
>>  * @regmap:		The regmap used to access the registers
>>  *			given, the name of the device is used
>> + * @fwnode:		(Optional) The firmware node.
>> + *			If not given, the fwnode of the parent is used.
>>  * @label:		(Optional) Descriptive name for GPIO controller.
>>  *			If not given, the name of the device is used.
>>  * @ngpio:		Number of GPIOs
>> @@ -57,6 +60,7 @@ struct regmap;
>> struct gpio_regmap_config {
>> 	struct device *parent;
>> 	struct regmap *regmap;
>> +	struct fwnode_handle *fwnode;
>> 	const char *label;
>> 	int ngpio;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 19:10           ` Álvaro Fernández Rojas
@ 2021-03-10 20:52             ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 20:52 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> > El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> >
> > On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Hi Rob,
> >>
> >>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>
> >>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> >>> <noltari@gmail.com> wrote:
> >>>>
> >>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>>>
> >>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >>>> ---
> >>>> v6: add changes suggested by Rob Herring
> >>>> v5: change Documentation to dt-bindings in commit title
> >>>> v4: no changes
> >>>> v3: add new gpio node
> >>>> v2: remove interrupts
> >>>>
> >>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >>>> 1 file changed, 174 insertions(+)
> >>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>> new file mode 100644
> >>>> index 000000000000..471f6efa1754
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>> @@ -0,0 +1,174 @@
> >>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >>>> +%YAML 1.2
> >>>> +---
> >>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>> +
> >>>> +title: Broadcom BCM6328 pin controller
> >>>> +
> >>>> +maintainers:
> >>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >>>> +
> >>>> +description: |+
> >>>> +  The pin controller node should be the child of a syscon node.
> >>>> +
> >>>> +  Refer to the the bindings described in
> >>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >>>> +
> >>>> +properties:
> >>>> +  compatible:
> >>>> +    const: brcm,bcm6328-pinctrl
> >>>> +
> >>>> +  gpio:
> >>>> +    type: object
> >>>> +    properties:
> >>>> +      compatible:
> >>>> +        const: brcm,bcm6328-gpio
> >>>> +
> >>>> +      data:
> >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +        description: |
> >>>> +          Offset in the register map for the data register (in bytes).
> >>>> +
> >>>> +      dirout:
> >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +        description: |
> >>>> +          Offset in the register map for the dirout register (in bytes).
> >>>> +
> >>>> +      gpio-controller: true
> >>>> +
> >>>> +      "#gpio-cells":
> >>>> +        const: 2
> >>>> +
> >>>> +      gpio-ranges:
> >>>> +        maxItems: 1
> >>>> +
> >>>> +    required:
> >>>> +      - gpio-controller
> >>>> +      - gpio-ranges
> >>>> +      - '#gpio-cells'
> >>>> +
> >>>> +    additionalProperties: false
> >>>> +
> >>>> +patternProperties:
> >>>> +  '^.*-pins$':
> >>>> +    if:
> >>>> +      type: object
> >>>> +    then:
> >>>> +      properties:
> >>>> +        function:
> >>>> +          $ref: "pinmux-node.yaml#/properties/function"
> >>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >>>> +
> >>>> +        pins:
> >>>> +          $ref: "pinmux-node.yaml#/properties/pins"
> >>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >>>> +                  usb_port1 ]
> >>>> +
> >>>> +required:
> >>>> +  - compatible
> >>>> +  - gpio
> >>>> +
> >>>> +additionalProperties: false
> >>>> +
> >>>> +examples:
> >>>> +  - |
> >>>> +    gpio_cntl@10000080 {
> >>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >>>
> >>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
> >>
> >> I just added that because you requested me to do it ¯\_(ツ)_/¯
> >
> > I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>
> Why not?

Because 'syscon' alone doesn't mean anything and doesn't describe what
registers it contains. You need something that says this is the XYZ
block in the ABC SoC.

> What if you have several controllers inside a syscon?

You either just add properties (e.g. just add #clock-cells and it's a
clock provider) or you have child nodes. Which one you do generally
depends on if the providers have DT resources themselves.

> The root should also have “something" in it?
>
> >
> >> What should I do to document it?
> >> I still don’t get most of this .yaml stuff...
> >>
> >>>
> >>>> +      reg = <0x10000080 0x80>;
> >>>> +
> >>>> +      pinctrl: pinctrl {
> >>>> +        compatible = "brcm,bcm6328-pinctrl";
> >>>> +
> >>>> +        gpio {
> >>>> +          compatible = "brcm,bcm6328-gpio";
> >>>
> >>> I'm still trying to understand why you need 3 levels of nodes here?
> >>> The gpio controller contains a pin controller plus other undefined
> >>> functions (because of 'syscon') and the pin controller contains a gpio
> >>> controller?
> >>
> >> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> >> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
> >>
> >>>
> >>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> >>> should be a single node.
> >>
> >> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> >
> > It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> > the same node. My suggestion was combining syscon and pinctrl.
>
> But that wouldn’t be correct if there were more “things” inside the syscon, right?

Right.

> >> Something like:
> >> syscon {
> >
> > Again with the syscon. If pinctrl and GPIO are the only functions
> > within this h/w block, then this is not a syscon. You are just abusing
> > that having 'syscon' compatible means you get a regmap created
> > automagically for you. Nothing here looks like a 'system controller'
> > to me. A 'system controller' is a random collection of register bits
> > with functions that don't fit anywhere else.
>
> pinctrl and GPIO aren’t the only functions within this HW block.
> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.

Okay, that's the detail missing from this patch.

> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
> typedef struct GpioControl {
>     uint32      GPIODirHi;                  /* 0 */
>     uint32      GPIODir;                    /* 4 */
>     uint32      GPIOioHi;                   /* 8 */
>     uint32      GPIOio;                     /* C */
>     uint32      unused0;                    /* 10 */
>     uint32      SpiSlaveCfg;                /* 14 */
>     uint32      GPIOMode;                   /* 18 */
>     uint64      PinMuxSel;                  /* 1C */
>     uint32      PinMuxSelOther;             /* 24 */
>     uint32      TestControl;                /* 28 */
>     uint32      unused2;                    /* 2C */
>     uint32      RoboSWLEDControl;           /* 30 */
>     uint32      RoboSWLEDLSR;               /* 34 */
>     uint32      unused3;                    /* 38 */
>     uint32      RoboswEphyCtrl;             /* 3C */
>     uint32      RoboswSwitchCtrl;           /* 40 */
>     uint32      RegFileTmCtl;               /* 44 */
>     uint32      RingOscCtrl0;               /* 48 */
>     uint32      RingOscCtrl1;               /* 4C */
>     uint32      unused4[6];                 /* 50 - 64 */
>     uint32      DieRevID;                   /* 68 */
>     uint32      unused5;                    /* 6c */
>     uint32      DiagSelControl;             /* 70 */
>     uint32      DiagReadBack;               /* 74 */
>     uint32      DiagReadBackHi;             /* 78 */
>     uint32      DiagMiscControl;            /* 7c */
> } GpioControl;
>
> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
> And this is for BCM6328, but some of the other SoCs are even more scattered.

So based on this I'd do something like this:

syscon {
  reg = <base 0x80>;
  ranges = <0 base 0x80>;
  pinctrl@18 {
    reg = <0x18 0x10>;
    foo-pins {};
  gpio@0 {
    reg = <0x0 0x10>;
  };
};

If things are more scattered within gpio or pinctrl, then maybe you
need multiple reg entries. Whether the OS uses 'reg' and mmio or a
regmap from the syscon is up to you. That's independent of the
binding.

> >>        pinctrl: pinctrl {
> >>                compatible …
> >>
> >>                gpio-controller;
> >>                gpio-ranges = <&pinctrl 0 0 32>;
> >>                #gpio-cells = <2>;
> >
> > I was assuming you have multiple GPIO controllers within 1 pinctlr?
> > The pinctrl and gpio could be a single node like above if there's only
> > 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
> > like because I have to go searching thru the driver to decipher.
> > Please describe the h/w in the binding.
>
> GPIO dirout and data rely on 2x u32 registers or a single u64 register.
> This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
> However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.

I think 1 makes more sense.

Rob

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-10 20:52             ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-10 20:52 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> > El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> >
> > On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Hi Rob,
> >>
> >>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>
> >>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> >>> <noltari@gmail.com> wrote:
> >>>>
> >>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>>>
> >>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >>>> ---
> >>>> v6: add changes suggested by Rob Herring
> >>>> v5: change Documentation to dt-bindings in commit title
> >>>> v4: no changes
> >>>> v3: add new gpio node
> >>>> v2: remove interrupts
> >>>>
> >>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >>>> 1 file changed, 174 insertions(+)
> >>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>> new file mode 100644
> >>>> index 000000000000..471f6efa1754
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>> @@ -0,0 +1,174 @@
> >>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >>>> +%YAML 1.2
> >>>> +---
> >>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>> +
> >>>> +title: Broadcom BCM6328 pin controller
> >>>> +
> >>>> +maintainers:
> >>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >>>> +
> >>>> +description: |+
> >>>> +  The pin controller node should be the child of a syscon node.
> >>>> +
> >>>> +  Refer to the the bindings described in
> >>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >>>> +
> >>>> +properties:
> >>>> +  compatible:
> >>>> +    const: brcm,bcm6328-pinctrl
> >>>> +
> >>>> +  gpio:
> >>>> +    type: object
> >>>> +    properties:
> >>>> +      compatible:
> >>>> +        const: brcm,bcm6328-gpio
> >>>> +
> >>>> +      data:
> >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +        description: |
> >>>> +          Offset in the register map for the data register (in bytes).
> >>>> +
> >>>> +      dirout:
> >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +        description: |
> >>>> +          Offset in the register map for the dirout register (in bytes).
> >>>> +
> >>>> +      gpio-controller: true
> >>>> +
> >>>> +      "#gpio-cells":
> >>>> +        const: 2
> >>>> +
> >>>> +      gpio-ranges:
> >>>> +        maxItems: 1
> >>>> +
> >>>> +    required:
> >>>> +      - gpio-controller
> >>>> +      - gpio-ranges
> >>>> +      - '#gpio-cells'
> >>>> +
> >>>> +    additionalProperties: false
> >>>> +
> >>>> +patternProperties:
> >>>> +  '^.*-pins$':
> >>>> +    if:
> >>>> +      type: object
> >>>> +    then:
> >>>> +      properties:
> >>>> +        function:
> >>>> +          $ref: "pinmux-node.yaml#/properties/function"
> >>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >>>> +
> >>>> +        pins:
> >>>> +          $ref: "pinmux-node.yaml#/properties/pins"
> >>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >>>> +                  usb_port1 ]
> >>>> +
> >>>> +required:
> >>>> +  - compatible
> >>>> +  - gpio
> >>>> +
> >>>> +additionalProperties: false
> >>>> +
> >>>> +examples:
> >>>> +  - |
> >>>> +    gpio_cntl@10000080 {
> >>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >>>
> >>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
> >>
> >> I just added that because you requested me to do it ¯\_(ツ)_/¯
> >
> > I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>
> Why not?

Because 'syscon' alone doesn't mean anything and doesn't describe what
registers it contains. You need something that says this is the XYZ
block in the ABC SoC.

> What if you have several controllers inside a syscon?

You either just add properties (e.g. just add #clock-cells and it's a
clock provider) or you have child nodes. Which one you do generally
depends on if the providers have DT resources themselves.

> The root should also have “something" in it?
>
> >
> >> What should I do to document it?
> >> I still don’t get most of this .yaml stuff...
> >>
> >>>
> >>>> +      reg = <0x10000080 0x80>;
> >>>> +
> >>>> +      pinctrl: pinctrl {
> >>>> +        compatible = "brcm,bcm6328-pinctrl";
> >>>> +
> >>>> +        gpio {
> >>>> +          compatible = "brcm,bcm6328-gpio";
> >>>
> >>> I'm still trying to understand why you need 3 levels of nodes here?
> >>> The gpio controller contains a pin controller plus other undefined
> >>> functions (because of 'syscon') and the pin controller contains a gpio
> >>> controller?
> >>
> >> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> >> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
> >>
> >>>
> >>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> >>> should be a single node.
> >>
> >> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> >
> > It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> > the same node. My suggestion was combining syscon and pinctrl.
>
> But that wouldn’t be correct if there were more “things” inside the syscon, right?

Right.

> >> Something like:
> >> syscon {
> >
> > Again with the syscon. If pinctrl and GPIO are the only functions
> > within this h/w block, then this is not a syscon. You are just abusing
> > that having 'syscon' compatible means you get a regmap created
> > automagically for you. Nothing here looks like a 'system controller'
> > to me. A 'system controller' is a random collection of register bits
> > with functions that don't fit anywhere else.
>
> pinctrl and GPIO aren’t the only functions within this HW block.
> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.

Okay, that's the detail missing from this patch.

> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
> typedef struct GpioControl {
>     uint32      GPIODirHi;                  /* 0 */
>     uint32      GPIODir;                    /* 4 */
>     uint32      GPIOioHi;                   /* 8 */
>     uint32      GPIOio;                     /* C */
>     uint32      unused0;                    /* 10 */
>     uint32      SpiSlaveCfg;                /* 14 */
>     uint32      GPIOMode;                   /* 18 */
>     uint64      PinMuxSel;                  /* 1C */
>     uint32      PinMuxSelOther;             /* 24 */
>     uint32      TestControl;                /* 28 */
>     uint32      unused2;                    /* 2C */
>     uint32      RoboSWLEDControl;           /* 30 */
>     uint32      RoboSWLEDLSR;               /* 34 */
>     uint32      unused3;                    /* 38 */
>     uint32      RoboswEphyCtrl;             /* 3C */
>     uint32      RoboswSwitchCtrl;           /* 40 */
>     uint32      RegFileTmCtl;               /* 44 */
>     uint32      RingOscCtrl0;               /* 48 */
>     uint32      RingOscCtrl1;               /* 4C */
>     uint32      unused4[6];                 /* 50 - 64 */
>     uint32      DieRevID;                   /* 68 */
>     uint32      unused5;                    /* 6c */
>     uint32      DiagSelControl;             /* 70 */
>     uint32      DiagReadBack;               /* 74 */
>     uint32      DiagReadBackHi;             /* 78 */
>     uint32      DiagMiscControl;            /* 7c */
> } GpioControl;
>
> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
> And this is for BCM6328, but some of the other SoCs are even more scattered.

So based on this I'd do something like this:

syscon {
  reg = <base 0x80>;
  ranges = <0 base 0x80>;
  pinctrl@18 {
    reg = <0x18 0x10>;
    foo-pins {};
  gpio@0 {
    reg = <0x0 0x10>;
  };
};

If things are more scattered within gpio or pinctrl, then maybe you
need multiple reg entries. Whether the OS uses 'reg' and mmio or a
regmap from the syscon is up to you. That's independent of the
binding.

> >>        pinctrl: pinctrl {
> >>                compatible …
> >>
> >>                gpio-controller;
> >>                gpio-ranges = <&pinctrl 0 0 32>;
> >>                #gpio-cells = <2>;
> >
> > I was assuming you have multiple GPIO controllers within 1 pinctlr?
> > The pinctrl and gpio could be a single node like above if there's only
> > 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
> > like because I have to go searching thru the driver to decipher.
> > Please describe the h/w in the binding.
>
> GPIO dirout and data rely on 2x u32 registers or a single u64 register.
> This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
> However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.

I think 1 makes more sense.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-10 17:50     ` Rob Herring
@ 2021-03-11  1:09       ` Linus Walleij
  -1 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:

> > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > +       { .compatible = "brcm,bcm6318-gpio", },
> > +       { .compatible = "brcm,bcm6328-gpio", },
> > +       { .compatible = "brcm,bcm6358-gpio", },
> > +       { .compatible = "brcm,bcm6362-gpio", },
> > +       { .compatible = "brcm,bcm6368-gpio", },
> > +       { .compatible = "brcm,bcm63268-gpio", },
>
> All these would be moved to gpio-mmio.c (or maybe that can have a
> fallback compatible?).

This is gpio-regmap.c and it can only be used as a library
by a certain driver. gpio-mmio.c can be used stand-alone
for certain really simple hardware (though most use that
as a library as well).

Yours,
Linus Walleij

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11  1:09       ` Linus Walleij
  0 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:

> > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > +       { .compatible = "brcm,bcm6318-gpio", },
> > +       { .compatible = "brcm,bcm6328-gpio", },
> > +       { .compatible = "brcm,bcm6358-gpio", },
> > +       { .compatible = "brcm,bcm6362-gpio", },
> > +       { .compatible = "brcm,bcm6368-gpio", },
> > +       { .compatible = "brcm,bcm63268-gpio", },
>
> All these would be moved to gpio-mmio.c (or maybe that can have a
> fallback compatible?).

This is gpio-regmap.c and it can only be used as a library
by a certain driver. gpio-mmio.c can be used stand-alone
for certain really simple hardware (though most use that
as a library as well).

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
  2021-03-10 19:12       ` Álvaro Fernández Rojas
@ 2021-03-11  1:16         ` Linus Walleij
  -1 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:16 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Michael Walle, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Linux ARM

On Wed, Mar 10, 2021 at 8:12 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:

> > If there will be a new version, please add the following comment:
>
> Right now I don’t know that either, because I’m honestly getting tired of this…

IMO there is indeed such a thing as over-review when it comes
to migrating legacy platforms: as subsystem maintainer I ask the bigger
question: does the kernel look better after than before this patch? If the
author is stressed by too much review I tend to just apply it and say that
comments can be addressed by additional patches.

DT bindings are different because they are written in stone. We just need
to settle the DT bindings. Give the patch set some rest and come back and
poke me to apply it when the chatter stops.

Yours,
Linus Walleij

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

* Re: [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node
@ 2021-03-11  1:16         ` Linus Walleij
  0 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:16 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Michael Walle, Rob Herring, Bartosz Golaszewski,
	Florian Fainelli, bcm-kernel-feedback-list, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Linux ARM

On Wed, Mar 10, 2021 at 8:12 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:

> > If there will be a new version, please add the following comment:
>
> Right now I don’t know that either, because I’m honestly getting tired of this…

IMO there is indeed such a thing as over-review when it comes
to migrating legacy platforms: as subsystem maintainer I ask the bigger
question: does the kernel look better after than before this patch? If the
author is stressed by too much review I tend to just apply it and say that
comments can be addressed by additional patches.

DT bindings are different because they are written in stone. We just need
to settle the DT bindings. Give the patch set some rest and come back and
poke me to apply it when the chatter stops.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 18:03       ` Álvaro Fernández Rojas
@ 2021-03-11  1:22         ` Linus Walleij
  -1 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:22 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 7:03 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
> > El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:

> >> +      reg = <0x10000080 0x80>;
> >> +
> >> +      pinctrl: pinctrl {
> >> +        compatible = "brcm,bcm6328-pinctrl";
> >> +
> >> +        gpio {
> >> +          compatible = "brcm,bcm6328-gpio";
> >
> > I'm still trying to understand why you need 3 levels of nodes here?
> > The gpio controller contains a pin controller plus other undefined
> > functions (because of 'syscon') and the pin controller contains a gpio
> > controller?
>
> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…

I think the crucial point is that these hardwares (all patches in the series)
is very similar and some contain several GPIO blocks rather than just
one.

The structure needs to be seen as a common pattern. We are doing this
because it gives a common structure to all BCM SoCs in this
family, which is nice.

Yours,
Linus Walleij

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-11  1:22         ` Linus Walleij
  0 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11  1:22 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Rob Herring, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 7:03 PM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
> > El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:

> >> +      reg = <0x10000080 0x80>;
> >> +
> >> +      pinctrl: pinctrl {
> >> +        compatible = "brcm,bcm6328-pinctrl";
> >> +
> >> +        gpio {
> >> +          compatible = "brcm,bcm6328-gpio";
> >
> > I'm still trying to understand why you need 3 levels of nodes here?
> > The gpio controller contains a pin controller plus other undefined
> > functions (because of 'syscon') and the pin controller contains a gpio
> > controller?
>
> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…

I think the crucial point is that these hardwares (all patches in the series)
is very similar and some contain several GPIO blocks rather than just
one.

The structure needs to be seen as a common pattern. We are doing this
because it gives a common structure to all BCM SoCs in this
family, which is nice.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-11  1:09       ` Linus Walleij
@ 2021-03-11 14:57         ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 14:57 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> > > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > > +       { .compatible = "brcm,bcm6318-gpio", },
> > > +       { .compatible = "brcm,bcm6328-gpio", },
> > > +       { .compatible = "brcm,bcm6358-gpio", },
> > > +       { .compatible = "brcm,bcm6362-gpio", },
> > > +       { .compatible = "brcm,bcm6368-gpio", },
> > > +       { .compatible = "brcm,bcm63268-gpio", },
> >
> > All these would be moved to gpio-mmio.c (or maybe that can have a
> > fallback compatible?).
>
> This is gpio-regmap.c and it can only be used as a library
> by a certain driver. gpio-mmio.c can be used stand-alone
> for certain really simple hardware (though most use that
> as a library as well).

I don't really care which one is used, but the problem is that this
choice is leaking into the binding design. The primary problem here is
once someone uses regmap, then they think they must have a syscon and
can abandon using 'reg' and normal address properties as Linux happens
to not use them (currently). I think we really need some better regmap
vs. mmio handling to eliminate this duplication of foo-mmio and
foo-regmap drivers and difference in binding design. Not sure exactly
what that looks like, but basically some sort of 'reg' property to
regmap creation.

Given we already have a Broadcom GPIO binding for what looks to be
similar to this one, I'm left wondering what's the real difference
here?

Rob

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11 14:57         ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 14:57 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> > > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > > +       { .compatible = "brcm,bcm6318-gpio", },
> > > +       { .compatible = "brcm,bcm6328-gpio", },
> > > +       { .compatible = "brcm,bcm6358-gpio", },
> > > +       { .compatible = "brcm,bcm6362-gpio", },
> > > +       { .compatible = "brcm,bcm6368-gpio", },
> > > +       { .compatible = "brcm,bcm63268-gpio", },
> >
> > All these would be moved to gpio-mmio.c (or maybe that can have a
> > fallback compatible?).
>
> This is gpio-regmap.c and it can only be used as a library
> by a certain driver. gpio-mmio.c can be used stand-alone
> for certain really simple hardware (though most use that
> as a library as well).

I don't really care which one is used, but the problem is that this
choice is leaking into the binding design. The primary problem here is
once someone uses regmap, then they think they must have a syscon and
can abandon using 'reg' and normal address properties as Linux happens
to not use them (currently). I think we really need some better regmap
vs. mmio handling to eliminate this duplication of foo-mmio and
foo-regmap drivers and difference in binding design. Not sure exactly
what that looks like, but basically some sort of 'reg' property to
regmap creation.

Given we already have a Broadcom GPIO binding for what looks to be
similar to this one, I'm left wondering what's the real difference
here?

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-11 14:57         ` Rob Herring
@ 2021-03-11 16:13           ` Linus Walleij
  -1 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11 16:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > > > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > > > +       { .compatible = "brcm,bcm6318-gpio", },
> > > > +       { .compatible = "brcm,bcm6328-gpio", },
> > > > +       { .compatible = "brcm,bcm6358-gpio", },
> > > > +       { .compatible = "brcm,bcm6362-gpio", },
> > > > +       { .compatible = "brcm,bcm6368-gpio", },
> > > > +       { .compatible = "brcm,bcm63268-gpio", },
> > >
> > > All these would be moved to gpio-mmio.c (or maybe that can have a
> > > fallback compatible?).
> >
> > This is gpio-regmap.c and it can only be used as a library
> > by a certain driver. gpio-mmio.c can be used stand-alone
> > for certain really simple hardware (though most use that
> > as a library as well).
>
> I don't really care which one is used, but the problem is that this
> choice is leaking into the binding design.

Aha I guess I misunderstood your comment.

>The primary problem here is
> once someone uses regmap, then they think they must have a syscon and
> can abandon using 'reg' and normal address properties as Linux happens
> to not use them (currently). I think we really need some better regmap
> vs. mmio handling to eliminate this duplication of foo-mmio and
> foo-regmap drivers and difference in binding design. Not sure exactly
> what that looks like, but basically some sort of 'reg' property to
> regmap creation.

I see the problem. Yeah we should try to be more strict around
these things. To me there are syscons and "other regmaps",
where syscon is a real hurdle of registers while "other regmaps"
are just regmaps by convenience.

Documentation/devicetree/bindings/mfd/syscon.yaml
describes what a syscon really is so if everyone could
just read the documentation that would be great ...

> Given we already have a Broadcom GPIO binding for what looks to be
> similar to this one, I'm left wondering what's the real difference
> here?

Which one is similar? I can take a look.

We currently have four Broadcom GPIO bindings,
which are stand alone GPIO blocks and eight Broadcom
pin controllers that all do GPIO as well.

This family of pin controllers are (as per subject) is
the bcm63xx series which is a MIPS-based family of SoCs
found in routers, top bindings in
Documentation/devicetree/bindings/mips/brcm/soc.txt
These all have a GPIO block as part of the pin controller
and the GPIO block is a distinct sub-function of the
pin controller, and it has up to 32 GPIOs per block,
hence it has its own subnode inside the pin controller.

This driver follows the pattern of the Ingenic
pin controller, another MIPS SoC:
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml

Another SoC with several GPIO blocks inside the pin
controller is SparX5 and that also follows this pattern:
Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml
(This has an example with more than one GPIO block
inside the pin controller.)

Yours,
Linus Walleij

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11 16:13           ` Linus Walleij
  0 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-11 16:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > > > +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> > > > +       { .compatible = "brcm,bcm6318-gpio", },
> > > > +       { .compatible = "brcm,bcm6328-gpio", },
> > > > +       { .compatible = "brcm,bcm6358-gpio", },
> > > > +       { .compatible = "brcm,bcm6362-gpio", },
> > > > +       { .compatible = "brcm,bcm6368-gpio", },
> > > > +       { .compatible = "brcm,bcm63268-gpio", },
> > >
> > > All these would be moved to gpio-mmio.c (or maybe that can have a
> > > fallback compatible?).
> >
> > This is gpio-regmap.c and it can only be used as a library
> > by a certain driver. gpio-mmio.c can be used stand-alone
> > for certain really simple hardware (though most use that
> > as a library as well).
>
> I don't really care which one is used, but the problem is that this
> choice is leaking into the binding design.

Aha I guess I misunderstood your comment.

>The primary problem here is
> once someone uses regmap, then they think they must have a syscon and
> can abandon using 'reg' and normal address properties as Linux happens
> to not use them (currently). I think we really need some better regmap
> vs. mmio handling to eliminate this duplication of foo-mmio and
> foo-regmap drivers and difference in binding design. Not sure exactly
> what that looks like, but basically some sort of 'reg' property to
> regmap creation.

I see the problem. Yeah we should try to be more strict around
these things. To me there are syscons and "other regmaps",
where syscon is a real hurdle of registers while "other regmaps"
are just regmaps by convenience.

Documentation/devicetree/bindings/mfd/syscon.yaml
describes what a syscon really is so if everyone could
just read the documentation that would be great ...

> Given we already have a Broadcom GPIO binding for what looks to be
> similar to this one, I'm left wondering what's the real difference
> here?

Which one is similar? I can take a look.

We currently have four Broadcom GPIO bindings,
which are stand alone GPIO blocks and eight Broadcom
pin controllers that all do GPIO as well.

This family of pin controllers are (as per subject) is
the bcm63xx series which is a MIPS-based family of SoCs
found in routers, top bindings in
Documentation/devicetree/bindings/mips/brcm/soc.txt
These all have a GPIO block as part of the pin controller
and the GPIO block is a distinct sub-function of the
pin controller, and it has up to 32 GPIOs per block,
hence it has its own subnode inside the pin controller.

This driver follows the pattern of the Ingenic
pin controller, another MIPS SoC:
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml

Another SoC with several GPIO blocks inside the pin
controller is SparX5 and that also follows this pattern:
Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml
(This has an example with more than one GPIO block
inside the pin controller.)

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-11 16:13           ` Linus Walleij
@ 2021-03-11 17:00             ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 17:00 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob and Linus,

El 11/03/2021 a las 17:13, Linus Walleij escribió:
> On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
>> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>
>>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
>>>>> +       { .compatible = "brcm,bcm6318-gpio", },
>>>>> +       { .compatible = "brcm,bcm6328-gpio", },
>>>>> +       { .compatible = "brcm,bcm6358-gpio", },
>>>>> +       { .compatible = "brcm,bcm6362-gpio", },
>>>>> +       { .compatible = "brcm,bcm6368-gpio", },
>>>>> +       { .compatible = "brcm,bcm63268-gpio", },
>>>>
>>>> All these would be moved to gpio-mmio.c (or maybe that can have a
>>>> fallback compatible?).
>>>
>>> This is gpio-regmap.c and it can only be used as a library
>>> by a certain driver. gpio-mmio.c can be used stand-alone
>>> for certain really simple hardware (though most use that
>>> as a library as well).
>>
>> I don't really care which one is used, but the problem is that this
>> choice is leaking into the binding design.
> 
> Aha I guess I misunderstood your comment.
> 
>> The primary problem here is
>> once someone uses regmap, then they think they must have a syscon and
>> can abandon using 'reg' and normal address properties as Linux happens
>> to not use them (currently). I think we really need some better regmap
>> vs. mmio handling to eliminate this duplication of foo-mmio and
>> foo-regmap drivers and difference in binding design. Not sure exactly
>> what that looks like, but basically some sort of 'reg' property to
>> regmap creation.
> 
> I see the problem. Yeah we should try to be more strict around
> these things. To me there are syscons and "other regmaps",
> where syscon is a real hurdle of registers while "other regmaps"
> are just regmaps by convenience.
> 
> Documentation/devicetree/bindings/mfd/syscon.yaml
> describes what a syscon really is so if everyone could
> just read the documentation that would be great ...
> 
>> Given we already have a Broadcom GPIO binding for what looks to be
>> similar to this one, I'm left wondering what's the real difference
>> here?
> 
> Which one is similar? I can take a look.

@Linus I think @Rob is referring to brcm,bcm6345-gpio:
https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686

However, the real difference between BCM6345 (and BCM6338) is that these 
SoCs have no pin controller at all, only a GPIO controller:

BCM6345:
typedef struct GpioControl {
   uint16        unused0;
   byte          unused1;
   byte          TBusSel;
   uint16        unused2;
   uint16        GPIODir;
   byte          unused3;
   byte          Leds;
   uint16        GPIOio;
   uint32        UartCtl;
} GpioControl;

BCM6338:
typedef struct GpioControl {
   uint32        unused0;
   uint32        GPIODir;      /* bits 7:0 */
   uint32        unused1;
   uint32        GPIOio;       /* bits 7:0 */
   uint32        LEDCtrl;
   uint32        SpiSlaveCfg;
   uint32        vRegConfig;
} GpioControl;

BCM6348 and newer also have pinctrl.
That's the main difference between that driver @Rob's referring to and 
the ones in this patch series.

> 
> We currently have four Broadcom GPIO bindings,
> which are stand alone GPIO blocks and eight Broadcom
> pin controllers that all do GPIO as well.
> 
> This family of pin controllers are (as per subject) is
> the bcm63xx series which is a MIPS-based family of SoCs
> found in routers, top bindings in
> Documentation/devicetree/bindings/mips/brcm/soc.txt
> These all have a GPIO block as part of the pin controller
> and the GPIO block is a distinct sub-function of the
> pin controller, and it has up to 32 GPIOs per block,
> hence it has its own subnode inside the pin controller.
> 
> This driver follows the pattern of the Ingenic
> pin controller, another MIPS SoC:
> Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml
> 
> Another SoC with several GPIO blocks inside the pin
> controller is SparX5 and that also follows this pattern:
> Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml
> (This has an example with more than one GPIO block
> inside the pin controller.)
> 
> Yours,
> Linus Walleij
> 

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11 17:00             ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 17:00 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob and Linus,

El 11/03/2021 a las 17:13, Linus Walleij escribió:
> On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
>> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>
>>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
>>>>> +       { .compatible = "brcm,bcm6318-gpio", },
>>>>> +       { .compatible = "brcm,bcm6328-gpio", },
>>>>> +       { .compatible = "brcm,bcm6358-gpio", },
>>>>> +       { .compatible = "brcm,bcm6362-gpio", },
>>>>> +       { .compatible = "brcm,bcm6368-gpio", },
>>>>> +       { .compatible = "brcm,bcm63268-gpio", },
>>>>
>>>> All these would be moved to gpio-mmio.c (or maybe that can have a
>>>> fallback compatible?).
>>>
>>> This is gpio-regmap.c and it can only be used as a library
>>> by a certain driver. gpio-mmio.c can be used stand-alone
>>> for certain really simple hardware (though most use that
>>> as a library as well).
>>
>> I don't really care which one is used, but the problem is that this
>> choice is leaking into the binding design.
> 
> Aha I guess I misunderstood your comment.
> 
>> The primary problem here is
>> once someone uses regmap, then they think they must have a syscon and
>> can abandon using 'reg' and normal address properties as Linux happens
>> to not use them (currently). I think we really need some better regmap
>> vs. mmio handling to eliminate this duplication of foo-mmio and
>> foo-regmap drivers and difference in binding design. Not sure exactly
>> what that looks like, but basically some sort of 'reg' property to
>> regmap creation.
> 
> I see the problem. Yeah we should try to be more strict around
> these things. To me there are syscons and "other regmaps",
> where syscon is a real hurdle of registers while "other regmaps"
> are just regmaps by convenience.
> 
> Documentation/devicetree/bindings/mfd/syscon.yaml
> describes what a syscon really is so if everyone could
> just read the documentation that would be great ...
> 
>> Given we already have a Broadcom GPIO binding for what looks to be
>> similar to this one, I'm left wondering what's the real difference
>> here?
> 
> Which one is similar? I can take a look.

@Linus I think @Rob is referring to brcm,bcm6345-gpio:
https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686

However, the real difference between BCM6345 (and BCM6338) is that these 
SoCs have no pin controller at all, only a GPIO controller:

BCM6345:
typedef struct GpioControl {
   uint16        unused0;
   byte          unused1;
   byte          TBusSel;
   uint16        unused2;
   uint16        GPIODir;
   byte          unused3;
   byte          Leds;
   uint16        GPIOio;
   uint32        UartCtl;
} GpioControl;

BCM6338:
typedef struct GpioControl {
   uint32        unused0;
   uint32        GPIODir;      /* bits 7:0 */
   uint32        unused1;
   uint32        GPIOio;       /* bits 7:0 */
   uint32        LEDCtrl;
   uint32        SpiSlaveCfg;
   uint32        vRegConfig;
} GpioControl;

BCM6348 and newer also have pinctrl.
That's the main difference between that driver @Rob's referring to and 
the ones in this patch series.

> 
> We currently have four Broadcom GPIO bindings,
> which are stand alone GPIO blocks and eight Broadcom
> pin controllers that all do GPIO as well.
> 
> This family of pin controllers are (as per subject) is
> the bcm63xx series which is a MIPS-based family of SoCs
> found in routers, top bindings in
> Documentation/devicetree/bindings/mips/brcm/soc.txt
> These all have a GPIO block as part of the pin controller
> and the GPIO block is a distinct sub-function of the
> pin controller, and it has up to 32 GPIOs per block,
> hence it has its own subnode inside the pin controller.
> 
> This driver follows the pattern of the Ingenic
> pin controller, another MIPS SoC:
> Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml
> 
> Another SoC with several GPIO blocks inside the pin
> controller is SparX5 and that also follows this pattern:
> Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml
> (This has an example with more than one GPIO block
> inside the pin controller.)
> 
> Yours,
> Linus Walleij
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-10 20:52             ` Rob Herring
@ 2021-03-11 17:09               ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 17:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

El 10/03/2021 a las 21:52, Rob Herring escribió:
> On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>>
>> Hi Rob,
>>
>>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>
>>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>>
>>>> Hi Rob,
>>>>
>>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>>
>>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>>>> <noltari@gmail.com> wrote:
>>>>>>
>>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>>>>
>>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>> ---
>>>>>> v6: add changes suggested by Rob Herring
>>>>>> v5: change Documentation to dt-bindings in commit title
>>>>>> v4: no changes
>>>>>> v3: add new gpio node
>>>>>> v2: remove interrupts
>>>>>>
>>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>>>> 1 file changed, 174 insertions(+)
>>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>> new file mode 100644
>>>>>> index 000000000000..471f6efa1754
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>> @@ -0,0 +1,174 @@
>>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>>>> +%YAML 1.2
>>>>>> +---
>>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>>> +
>>>>>> +title: Broadcom BCM6328 pin controller
>>>>>> +
>>>>>> +maintainers:
>>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> +
>>>>>> +description: |+
>>>>>> +  The pin controller node should be the child of a syscon node.
>>>>>> +
>>>>>> +  Refer to the the bindings described in
>>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>>>> +
>>>>>> +properties:
>>>>>> +  compatible:
>>>>>> +    const: brcm,bcm6328-pinctrl
>>>>>> +
>>>>>> +  gpio:
>>>>>> +    type: object
>>>>>> +    properties:
>>>>>> +      compatible:
>>>>>> +        const: brcm,bcm6328-gpio
>>>>>> +
>>>>>> +      data:
>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +        description: |
>>>>>> +          Offset in the register map for the data register (in bytes).
>>>>>> +
>>>>>> +      dirout:
>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +        description: |
>>>>>> +          Offset in the register map for the dirout register (in bytes).
>>>>>> +
>>>>>> +      gpio-controller: true
>>>>>> +
>>>>>> +      "#gpio-cells":
>>>>>> +        const: 2
>>>>>> +
>>>>>> +      gpio-ranges:
>>>>>> +        maxItems: 1
>>>>>> +
>>>>>> +    required:
>>>>>> +      - gpio-controller
>>>>>> +      - gpio-ranges
>>>>>> +      - '#gpio-cells'
>>>>>> +
>>>>>> +    additionalProperties: false
>>>>>> +
>>>>>> +patternProperties:
>>>>>> +  '^.*-pins$':
>>>>>> +    if:
>>>>>> +      type: object
>>>>>> +    then:
>>>>>> +      properties:
>>>>>> +        function:
>>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>>>> +
>>>>>> +        pins:
>>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>>>> +                  usb_port1 ]
>>>>>> +
>>>>>> +required:
>>>>>> +  - compatible
>>>>>> +  - gpio
>>>>>> +
>>>>>> +additionalProperties: false
>>>>>> +
>>>>>> +examples:
>>>>>> +  - |
>>>>>> +    gpio_cntl@10000080 {
>>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>>>>
>>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>>>>
>>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
>>>
>>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>>
>> Why not?
> 
> Because 'syscon' alone doesn't mean anything and doesn't describe what
> registers it contains. You need something that says this is the XYZ
> block in the ABC SoC.
> 
>> What if you have several controllers inside a syscon?
> 
> You either just add properties (e.g. just add #clock-cells and it's a
> clock provider) or you have child nodes. Which one you do generally
> depends on if the providers have DT resources themselves.
> 
>> The root should also have “something" in it?
>>
>>>
>>>> What should I do to document it?

You didn't answer my question about adding documentation...

An example driver which adds a custom compatible string and doesn't 
document it:
https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90

>>>> I still don’t get most of this .yaml stuff...
>>>>
>>>>>
>>>>>> +      reg = <0x10000080 0x80>;
>>>>>> +
>>>>>> +      pinctrl: pinctrl {
>>>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>>>> +
>>>>>> +        gpio {
>>>>>> +          compatible = "brcm,bcm6328-gpio";
>>>>>
>>>>> I'm still trying to understand why you need 3 levels of nodes here?
>>>>> The gpio controller contains a pin controller plus other undefined
>>>>> functions (because of 'syscon') and the pin controller contains a gpio
>>>>> controller?
>>>>
>>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>>>>
>>>>>
>>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>>>> should be a single node.
>>>>
>>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
>>>
>>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
>>> the same node. My suggestion was combining syscon and pinctrl.
>>
>> But that wouldn’t be correct if there were more “things” inside the syscon, right?
> 
> Right.
> 
>>>> Something like:
>>>> syscon {
>>>
>>> Again with the syscon. If pinctrl and GPIO are the only functions
>>> within this h/w block, then this is not a syscon. You are just abusing
>>> that having 'syscon' compatible means you get a regmap created
>>> automagically for you. Nothing here looks like a 'system controller'
>>> to me. A 'system controller' is a random collection of register bits
>>> with functions that don't fit anywhere else.
>>
>> pinctrl and GPIO aren’t the only functions within this HW block.
>> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
> 
> Okay, that's the detail missing from this patch.
> 
>> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
>> typedef struct GpioControl {
>>      uint32      GPIODirHi;                  /* 0 */
>>      uint32      GPIODir;                    /* 4 */
>>      uint32      GPIOioHi;                   /* 8 */
>>      uint32      GPIOio;                     /* C */
>>      uint32      unused0;                    /* 10 */
>>      uint32      SpiSlaveCfg;                /* 14 */
>>      uint32      GPIOMode;                   /* 18 */
>>      uint64      PinMuxSel;                  /* 1C */
>>      uint32      PinMuxSelOther;             /* 24 */
>>      uint32      TestControl;                /* 28 */
>>      uint32      unused2;                    /* 2C */
>>      uint32      RoboSWLEDControl;           /* 30 */
>>      uint32      RoboSWLEDLSR;               /* 34 */
>>      uint32      unused3;                    /* 38 */
>>      uint32      RoboswEphyCtrl;             /* 3C */
>>      uint32      RoboswSwitchCtrl;           /* 40 */
>>      uint32      RegFileTmCtl;               /* 44 */
>>      uint32      RingOscCtrl0;               /* 48 */
>>      uint32      RingOscCtrl1;               /* 4C */
>>      uint32      unused4[6];                 /* 50 - 64 */
>>      uint32      DieRevID;                   /* 68 */
>>      uint32      unused5;                    /* 6c */
>>      uint32      DiagSelControl;             /* 70 */
>>      uint32      DiagReadBack;               /* 74 */
>>      uint32      DiagReadBackHi;             /* 78 */
>>      uint32      DiagMiscControl;            /* 7c */
>> } GpioControl;
>>
>> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
>> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
>> And this is for BCM6328, but some of the other SoCs are even more scattered.
> 
> So based on this I'd do something like this:
> 
> syscon {
>    reg = <base 0x80>;
>    ranges = <0 base 0x80>;
>    pinctrl@18 {
>      reg = <0x18 0x10>;
>      foo-pins {};
>    gpio@0 {
>      reg = <0x0 0x10>;
>    };
> };

You're missing a "};", so I'm not sure if you want me to go this way (1):
syscon {
	compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
	reg = <0x10000080 0x80>;
	ranges = <0 0x10000080 0x80>;

	gpio: gpio@0 {
		compatible = "brcm,bcm6328-gpio";
		reg = <0x0 0x10>;

		data = <0xc>;
		dirout = <0x4>;

		gpio-controller;
		gpio-ranges = <&pinctrl 0 0 32>;
		#gpio-cells = <2>;
	};

	pinctrl: pinctrl@18 {
		compatible = "brcm,bcm6328-pinctrl";
		reg = <0x18 0x10>;

		foo-pins {};
		...
	};
};

Or this way (2):
syscon {
	compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
	reg = <0x10000080 0x80>;
	ranges = <0 0x10000080 0x80>;

	pinctrl: pinctrl@18 {
		compatible = "brcm,bcm6328-pinctrl";
		reg = <0x0 0x28>;

		gpio: gpio@0 {
			compatible = "brcm,bcm6328-gpio";
			reg = <0x0 0x10>;

			data = <0xc>;
			dirout = <0x4>;

			gpio-controller;
			gpio-ranges = <&pinctrl 0 0 32>;
			#gpio-cells = <2>;
		};

		foo-pins {};
		...
	};
};

> 
> If things are more scattered within gpio or pinctrl, then maybe you
> need multiple reg entries. Whether the OS uses 'reg' and mmio or a
> regmap from the syscon is up to you. That's independent of the
> binding.
> 
>>>>         pinctrl: pinctrl {
>>>>                 compatible …
>>>>
>>>>                 gpio-controller;
>>>>                 gpio-ranges = <&pinctrl 0 0 32>;
>>>>                 #gpio-cells = <2>;
>>>
>>> I was assuming you have multiple GPIO controllers within 1 pinctlr?
>>> The pinctrl and gpio could be a single node like above if there's only
>>> 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
>>> like because I have to go searching thru the driver to decipher.
>>> Please describe the h/w in the binding.
>>
>> GPIO dirout and data rely on 2x u32 registers or a single u64 register.
>> This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
>> However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.
> 
> I think 1 makes more sense.
> 
> Rob
> 

Best regards,
Álvaro.

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-11 17:09               ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 17:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

El 10/03/2021 a las 21:52, Rob Herring escribió:
> On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>>
>> Hi Rob,
>>
>>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>
>>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>>
>>>> Hi Rob,
>>>>
>>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>>
>>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>>>> <noltari@gmail.com> wrote:
>>>>>>
>>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>>>>
>>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>> ---
>>>>>> v6: add changes suggested by Rob Herring
>>>>>> v5: change Documentation to dt-bindings in commit title
>>>>>> v4: no changes
>>>>>> v3: add new gpio node
>>>>>> v2: remove interrupts
>>>>>>
>>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>>>> 1 file changed, 174 insertions(+)
>>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>> new file mode 100644
>>>>>> index 000000000000..471f6efa1754
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>> @@ -0,0 +1,174 @@
>>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>>>> +%YAML 1.2
>>>>>> +---
>>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>>> +
>>>>>> +title: Broadcom BCM6328 pin controller
>>>>>> +
>>>>>> +maintainers:
>>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>>>> +
>>>>>> +description: |+
>>>>>> +  The pin controller node should be the child of a syscon node.
>>>>>> +
>>>>>> +  Refer to the the bindings described in
>>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>>>> +
>>>>>> +properties:
>>>>>> +  compatible:
>>>>>> +    const: brcm,bcm6328-pinctrl
>>>>>> +
>>>>>> +  gpio:
>>>>>> +    type: object
>>>>>> +    properties:
>>>>>> +      compatible:
>>>>>> +        const: brcm,bcm6328-gpio
>>>>>> +
>>>>>> +      data:
>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +        description: |
>>>>>> +          Offset in the register map for the data register (in bytes).
>>>>>> +
>>>>>> +      dirout:
>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +        description: |
>>>>>> +          Offset in the register map for the dirout register (in bytes).
>>>>>> +
>>>>>> +      gpio-controller: true
>>>>>> +
>>>>>> +      "#gpio-cells":
>>>>>> +        const: 2
>>>>>> +
>>>>>> +      gpio-ranges:
>>>>>> +        maxItems: 1
>>>>>> +
>>>>>> +    required:
>>>>>> +      - gpio-controller
>>>>>> +      - gpio-ranges
>>>>>> +      - '#gpio-cells'
>>>>>> +
>>>>>> +    additionalProperties: false
>>>>>> +
>>>>>> +patternProperties:
>>>>>> +  '^.*-pins$':
>>>>>> +    if:
>>>>>> +      type: object
>>>>>> +    then:
>>>>>> +      properties:
>>>>>> +        function:
>>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>>>> +
>>>>>> +        pins:
>>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>>>> +                  usb_port1 ]
>>>>>> +
>>>>>> +required:
>>>>>> +  - compatible
>>>>>> +  - gpio
>>>>>> +
>>>>>> +additionalProperties: false
>>>>>> +
>>>>>> +examples:
>>>>>> +  - |
>>>>>> +    gpio_cntl@10000080 {
>>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>>>>
>>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>>>>
>>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
>>>
>>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>>
>> Why not?
> 
> Because 'syscon' alone doesn't mean anything and doesn't describe what
> registers it contains. You need something that says this is the XYZ
> block in the ABC SoC.
> 
>> What if you have several controllers inside a syscon?
> 
> You either just add properties (e.g. just add #clock-cells and it's a
> clock provider) or you have child nodes. Which one you do generally
> depends on if the providers have DT resources themselves.
> 
>> The root should also have “something" in it?
>>
>>>
>>>> What should I do to document it?

You didn't answer my question about adding documentation...

An example driver which adds a custom compatible string and doesn't 
document it:
https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90

>>>> I still don’t get most of this .yaml stuff...
>>>>
>>>>>
>>>>>> +      reg = <0x10000080 0x80>;
>>>>>> +
>>>>>> +      pinctrl: pinctrl {
>>>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>>>> +
>>>>>> +        gpio {
>>>>>> +          compatible = "brcm,bcm6328-gpio";
>>>>>
>>>>> I'm still trying to understand why you need 3 levels of nodes here?
>>>>> The gpio controller contains a pin controller plus other undefined
>>>>> functions (because of 'syscon') and the pin controller contains a gpio
>>>>> controller?
>>>>
>>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>>>>
>>>>>
>>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>>>> should be a single node.
>>>>
>>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
>>>
>>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
>>> the same node. My suggestion was combining syscon and pinctrl.
>>
>> But that wouldn’t be correct if there were more “things” inside the syscon, right?
> 
> Right.
> 
>>>> Something like:
>>>> syscon {
>>>
>>> Again with the syscon. If pinctrl and GPIO are the only functions
>>> within this h/w block, then this is not a syscon. You are just abusing
>>> that having 'syscon' compatible means you get a regmap created
>>> automagically for you. Nothing here looks like a 'system controller'
>>> to me. A 'system controller' is a random collection of register bits
>>> with functions that don't fit anywhere else.
>>
>> pinctrl and GPIO aren’t the only functions within this HW block.
>> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
> 
> Okay, that's the detail missing from this patch.
> 
>> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
>> typedef struct GpioControl {
>>      uint32      GPIODirHi;                  /* 0 */
>>      uint32      GPIODir;                    /* 4 */
>>      uint32      GPIOioHi;                   /* 8 */
>>      uint32      GPIOio;                     /* C */
>>      uint32      unused0;                    /* 10 */
>>      uint32      SpiSlaveCfg;                /* 14 */
>>      uint32      GPIOMode;                   /* 18 */
>>      uint64      PinMuxSel;                  /* 1C */
>>      uint32      PinMuxSelOther;             /* 24 */
>>      uint32      TestControl;                /* 28 */
>>      uint32      unused2;                    /* 2C */
>>      uint32      RoboSWLEDControl;           /* 30 */
>>      uint32      RoboSWLEDLSR;               /* 34 */
>>      uint32      unused3;                    /* 38 */
>>      uint32      RoboswEphyCtrl;             /* 3C */
>>      uint32      RoboswSwitchCtrl;           /* 40 */
>>      uint32      RegFileTmCtl;               /* 44 */
>>      uint32      RingOscCtrl0;               /* 48 */
>>      uint32      RingOscCtrl1;               /* 4C */
>>      uint32      unused4[6];                 /* 50 - 64 */
>>      uint32      DieRevID;                   /* 68 */
>>      uint32      unused5;                    /* 6c */
>>      uint32      DiagSelControl;             /* 70 */
>>      uint32      DiagReadBack;               /* 74 */
>>      uint32      DiagReadBackHi;             /* 78 */
>>      uint32      DiagMiscControl;            /* 7c */
>> } GpioControl;
>>
>> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
>> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
>> And this is for BCM6328, but some of the other SoCs are even more scattered.
> 
> So based on this I'd do something like this:
> 
> syscon {
>    reg = <base 0x80>;
>    ranges = <0 base 0x80>;
>    pinctrl@18 {
>      reg = <0x18 0x10>;
>      foo-pins {};
>    gpio@0 {
>      reg = <0x0 0x10>;
>    };
> };

You're missing a "};", so I'm not sure if you want me to go this way (1):
syscon {
	compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
	reg = <0x10000080 0x80>;
	ranges = <0 0x10000080 0x80>;

	gpio: gpio@0 {
		compatible = "brcm,bcm6328-gpio";
		reg = <0x0 0x10>;

		data = <0xc>;
		dirout = <0x4>;

		gpio-controller;
		gpio-ranges = <&pinctrl 0 0 32>;
		#gpio-cells = <2>;
	};

	pinctrl: pinctrl@18 {
		compatible = "brcm,bcm6328-pinctrl";
		reg = <0x18 0x10>;

		foo-pins {};
		...
	};
};

Or this way (2):
syscon {
	compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
	reg = <0x10000080 0x80>;
	ranges = <0 0x10000080 0x80>;

	pinctrl: pinctrl@18 {
		compatible = "brcm,bcm6328-pinctrl";
		reg = <0x0 0x28>;

		gpio: gpio@0 {
			compatible = "brcm,bcm6328-gpio";
			reg = <0x0 0x10>;

			data = <0xc>;
			dirout = <0x4>;

			gpio-controller;
			gpio-ranges = <&pinctrl 0 0 32>;
			#gpio-cells = <2>;
		};

		foo-pins {};
		...
	};
};

> 
> If things are more scattered within gpio or pinctrl, then maybe you
> need multiple reg entries. Whether the OS uses 'reg' and mmio or a
> regmap from the syscon is up to you. That's independent of the
> binding.
> 
>>>>         pinctrl: pinctrl {
>>>>                 compatible …
>>>>
>>>>                 gpio-controller;
>>>>                 gpio-ranges = <&pinctrl 0 0 32>;
>>>>                 #gpio-cells = <2>;
>>>
>>> I was assuming you have multiple GPIO controllers within 1 pinctlr?
>>> The pinctrl and gpio could be a single node like above if there's only
>>> 1 GPIO controller. But I'm still somewhat guessing what the h/w looks
>>> like because I have to go searching thru the driver to decipher.
>>> Please describe the h/w in the binding.
>>
>> GPIO dirout and data rely on 2x u32 registers or a single u64 register.
>> This is can be either be implemented as a single GPIO controller, or as 2 separate GPIO controllers.
>> However, since I’m overriding reg_mask_xlate with bcm63xx_reg_mask_xlate I can register it as a single GPIO controller, which makes more sense to me.
> 
> I think 1 makes more sense.
> 
> Rob
> 

Best regards,
Álvaro.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-11 17:09               ` Álvaro Fernández Rojas
@ 2021-03-11 18:14                 ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 18:14 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 10:09 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> El 10/03/2021 a las 21:52, Rob Herring escribió:
> > On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Hi Rob,
> >>
> >>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>
> >>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> >>> <noltari@gmail.com> wrote:
> >>>>
> >>>> Hi Rob,
> >>>>
> >>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>>>
> >>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> >>>>> <noltari@gmail.com> wrote:
> >>>>>>
> >>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>>>>>
> >>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >>>>>> ---
> >>>>>> v6: add changes suggested by Rob Herring
> >>>>>> v5: change Documentation to dt-bindings in commit title
> >>>>>> v4: no changes
> >>>>>> v3: add new gpio node
> >>>>>> v2: remove interrupts
> >>>>>>
> >>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >>>>>> 1 file changed, 174 insertions(+)
> >>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>>
> >>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>> new file mode 100644
> >>>>>> index 000000000000..471f6efa1754
> >>>>>> --- /dev/null
> >>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>> @@ -0,0 +1,174 @@
> >>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >>>>>> +%YAML 1.2
> >>>>>> +---
> >>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>>>> +
> >>>>>> +title: Broadcom BCM6328 pin controller
> >>>>>> +
> >>>>>> +maintainers:
> >>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> +
> >>>>>> +description: |+
> >>>>>> +  The pin controller node should be the child of a syscon node.
> >>>>>> +
> >>>>>> +  Refer to the the bindings described in
> >>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >>>>>> +
> >>>>>> +properties:
> >>>>>> +  compatible:
> >>>>>> +    const: brcm,bcm6328-pinctrl
> >>>>>> +
> >>>>>> +  gpio:
> >>>>>> +    type: object
> >>>>>> +    properties:
> >>>>>> +      compatible:
> >>>>>> +        const: brcm,bcm6328-gpio
> >>>>>> +
> >>>>>> +      data:
> >>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>> +        description: |
> >>>>>> +          Offset in the register map for the data register (in bytes).
> >>>>>> +
> >>>>>> +      dirout:
> >>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>> +        description: |
> >>>>>> +          Offset in the register map for the dirout register (in bytes).
> >>>>>> +
> >>>>>> +      gpio-controller: true
> >>>>>> +
> >>>>>> +      "#gpio-cells":
> >>>>>> +        const: 2
> >>>>>> +
> >>>>>> +      gpio-ranges:
> >>>>>> +        maxItems: 1
> >>>>>> +
> >>>>>> +    required:
> >>>>>> +      - gpio-controller
> >>>>>> +      - gpio-ranges
> >>>>>> +      - '#gpio-cells'
> >>>>>> +
> >>>>>> +    additionalProperties: false
> >>>>>> +
> >>>>>> +patternProperties:
> >>>>>> +  '^.*-pins$':
> >>>>>> +    if:
> >>>>>> +      type: object
> >>>>>> +    then:
> >>>>>> +      properties:
> >>>>>> +        function:
> >>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
> >>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >>>>>> +
> >>>>>> +        pins:
> >>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
> >>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >>>>>> +                  usb_port1 ]
> >>>>>> +
> >>>>>> +required:
> >>>>>> +  - compatible
> >>>>>> +  - gpio
> >>>>>> +
> >>>>>> +additionalProperties: false
> >>>>>> +
> >>>>>> +examples:
> >>>>>> +  - |
> >>>>>> +    gpio_cntl@10000080 {
> >>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >>>>>
> >>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
> >>>>
> >>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
> >>>
> >>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
> >>
> >> Why not?
> >
> > Because 'syscon' alone doesn't mean anything and doesn't describe what
> > registers it contains. You need something that says this is the XYZ
> > block in the ABC SoC.
> >
> >> What if you have several controllers inside a syscon?
> >
> > You either just add properties (e.g. just add #clock-cells and it's a
> > clock provider) or you have child nodes. Which one you do generally
> > depends on if the providers have DT resources themselves.
> >
> >> The root should also have “something" in it?
> >>
> >>>
> >>>> What should I do to document it?
>
> You didn't answer my question about adding documentation...

You have to document it. Whether it's 1 or 3 schema files depends on
where we end up, but the top-level one should reference the others if
it's more than 1 file:

child-node:
  type: object
  $ref: "/schemas/foo/child-node.yaml#"

> An example driver which adds a custom compatible string and doesn't
> document it:
> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90

*it Happens.

Those cases are now blocking my adding a check that they are
undocumented. There's no shortage of examples of what not to do.

>
> >>>> I still don’t get most of this .yaml stuff...
> >>>>
> >>>>>
> >>>>>> +      reg = <0x10000080 0x80>;
> >>>>>> +
> >>>>>> +      pinctrl: pinctrl {
> >>>>>> +        compatible = "brcm,bcm6328-pinctrl";
> >>>>>> +
> >>>>>> +        gpio {
> >>>>>> +          compatible = "brcm,bcm6328-gpio";
> >>>>>
> >>>>> I'm still trying to understand why you need 3 levels of nodes here?
> >>>>> The gpio controller contains a pin controller plus other undefined
> >>>>> functions (because of 'syscon') and the pin controller contains a gpio
> >>>>> controller?
> >>>>
> >>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> >>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
> >>>>
> >>>>>
> >>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> >>>>> should be a single node.
> >>>>
> >>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> >>>
> >>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> >>> the same node. My suggestion was combining syscon and pinctrl.
> >>
> >> But that wouldn’t be correct if there were more “things” inside the syscon, right?
> >
> > Right.
> >
> >>>> Something like:
> >>>> syscon {
> >>>
> >>> Again with the syscon. If pinctrl and GPIO are the only functions
> >>> within this h/w block, then this is not a syscon. You are just abusing
> >>> that having 'syscon' compatible means you get a regmap created
> >>> automagically for you. Nothing here looks like a 'system controller'
> >>> to me. A 'system controller' is a random collection of register bits
> >>> with functions that don't fit anywhere else.
> >>
> >> pinctrl and GPIO aren’t the only functions within this HW block.
> >> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
> >
> > Okay, that's the detail missing from this patch.
> >
> >> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
> >> typedef struct GpioControl {
> >>      uint32      GPIODirHi;                  /* 0 */
> >>      uint32      GPIODir;                    /* 4 */
> >>      uint32      GPIOioHi;                   /* 8 */
> >>      uint32      GPIOio;                     /* C */
> >>      uint32      unused0;                    /* 10 */
> >>      uint32      SpiSlaveCfg;                /* 14 */
> >>      uint32      GPIOMode;                   /* 18 */
> >>      uint64      PinMuxSel;                  /* 1C */
> >>      uint32      PinMuxSelOther;             /* 24 */
> >>      uint32      TestControl;                /* 28 */
> >>      uint32      unused2;                    /* 2C */
> >>      uint32      RoboSWLEDControl;           /* 30 */
> >>      uint32      RoboSWLEDLSR;               /* 34 */
> >>      uint32      unused3;                    /* 38 */
> >>      uint32      RoboswEphyCtrl;             /* 3C */
> >>      uint32      RoboswSwitchCtrl;           /* 40 */
> >>      uint32      RegFileTmCtl;               /* 44 */
> >>      uint32      RingOscCtrl0;               /* 48 */
> >>      uint32      RingOscCtrl1;               /* 4C */
> >>      uint32      unused4[6];                 /* 50 - 64 */
> >>      uint32      DieRevID;                   /* 68 */
> >>      uint32      unused5;                    /* 6c */
> >>      uint32      DiagSelControl;             /* 70 */
> >>      uint32      DiagReadBack;               /* 74 */
> >>      uint32      DiagReadBackHi;             /* 78 */
> >>      uint32      DiagMiscControl;            /* 7c */
> >> } GpioControl;
> >>
> >> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
> >> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
> >> And this is for BCM6328, but some of the other SoCs are even more scattered.
> >
> > So based on this I'd do something like this:
> >
> > syscon {
> >    reg = <base 0x80>;
> >    ranges = <0 base 0x80>;
> >    pinctrl@18 {
> >      reg = <0x18 0x10>;
> >      foo-pins {};
> >    gpio@0 {
> >      reg = <0x0 0x10>;
> >    };
> > };
>
> You're missing a "};", so I'm not sure if you want me to go this way (1):
> syscon {
>         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>         reg = <0x10000080 0x80>;
>         ranges = <0 0x10000080 0x80>;
>
>         gpio: gpio@0 {
>                 compatible = "brcm,bcm6328-gpio";
>                 reg = <0x0 0x10>;
>
>                 data = <0xc>;
>                 dirout = <0x4>;
>
>                 gpio-controller;
>                 gpio-ranges = <&pinctrl 0 0 32>;
>                 #gpio-cells = <2>;
>         };
>
>         pinctrl: pinctrl@18 {
>                 compatible = "brcm,bcm6328-pinctrl";
>                 reg = <0x18 0x10>;
>
>                 foo-pins {};
>                 ...
>         };
> };

This way.

>
> Or this way (2):
> syscon {
>         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>         reg = <0x10000080 0x80>;
>         ranges = <0 0x10000080 0x80>;
>
>         pinctrl: pinctrl@18 {
>                 compatible = "brcm,bcm6328-pinctrl";
>                 reg = <0x0 0x28>;
>
>                 gpio: gpio@0 {

This doesn't make sense IMO because GPIO is not a sub-function of the
pinctrl h/w. They are peers.

>                         compatible = "brcm,bcm6328-gpio";
>                         reg = <0x0 0x10>;
>
>                         data = <0xc>;
>                         dirout = <0x4>;
>
>                         gpio-controller;
>                         gpio-ranges = <&pinctrl 0 0 32>;
>                         #gpio-cells = <2>;
>                 };
>
>                 foo-pins {};
>                 ...
>         };
> };

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-11 18:14                 ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 18:14 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 10:09 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob,
>
> El 10/03/2021 a las 21:52, Rob Herring escribió:
> > On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
> > <noltari@gmail.com> wrote:
> >>
> >> Hi Rob,
> >>
> >>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>
> >>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
> >>> <noltari@gmail.com> wrote:
> >>>>
> >>>> Hi Rob,
> >>>>
> >>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
> >>>>>
> >>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
> >>>>> <noltari@gmail.com> wrote:
> >>>>>>
> >>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
> >>>>>>
> >>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> >>>>>> ---
> >>>>>> v6: add changes suggested by Rob Herring
> >>>>>> v5: change Documentation to dt-bindings in commit title
> >>>>>> v4: no changes
> >>>>>> v3: add new gpio node
> >>>>>> v2: remove interrupts
> >>>>>>
> >>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
> >>>>>> 1 file changed, 174 insertions(+)
> >>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>>
> >>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>> new file mode 100644
> >>>>>> index 000000000000..471f6efa1754
> >>>>>> --- /dev/null
> >>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
> >>>>>> @@ -0,0 +1,174 @@
> >>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >>>>>> +%YAML 1.2
> >>>>>> +---
> >>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
> >>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>>>> +
> >>>>>> +title: Broadcom BCM6328 pin controller
> >>>>>> +
> >>>>>> +maintainers:
> >>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
> >>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
> >>>>>> +
> >>>>>> +description: |+
> >>>>>> +  The pin controller node should be the child of a syscon node.
> >>>>>> +
> >>>>>> +  Refer to the the bindings described in
> >>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
> >>>>>> +
> >>>>>> +properties:
> >>>>>> +  compatible:
> >>>>>> +    const: brcm,bcm6328-pinctrl
> >>>>>> +
> >>>>>> +  gpio:
> >>>>>> +    type: object
> >>>>>> +    properties:
> >>>>>> +      compatible:
> >>>>>> +        const: brcm,bcm6328-gpio
> >>>>>> +
> >>>>>> +      data:
> >>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>> +        description: |
> >>>>>> +          Offset in the register map for the data register (in bytes).
> >>>>>> +
> >>>>>> +      dirout:
> >>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>> +        description: |
> >>>>>> +          Offset in the register map for the dirout register (in bytes).
> >>>>>> +
> >>>>>> +      gpio-controller: true
> >>>>>> +
> >>>>>> +      "#gpio-cells":
> >>>>>> +        const: 2
> >>>>>> +
> >>>>>> +      gpio-ranges:
> >>>>>> +        maxItems: 1
> >>>>>> +
> >>>>>> +    required:
> >>>>>> +      - gpio-controller
> >>>>>> +      - gpio-ranges
> >>>>>> +      - '#gpio-cells'
> >>>>>> +
> >>>>>> +    additionalProperties: false
> >>>>>> +
> >>>>>> +patternProperties:
> >>>>>> +  '^.*-pins$':
> >>>>>> +    if:
> >>>>>> +      type: object
> >>>>>> +    then:
> >>>>>> +      properties:
> >>>>>> +        function:
> >>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
> >>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
> >>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
> >>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
> >>>>>> +
> >>>>>> +        pins:
> >>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
> >>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
> >>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
> >>>>>> +                  usb_port1 ]
> >>>>>> +
> >>>>>> +required:
> >>>>>> +  - compatible
> >>>>>> +  - gpio
> >>>>>> +
> >>>>>> +additionalProperties: false
> >>>>>> +
> >>>>>> +examples:
> >>>>>> +  - |
> >>>>>> +    gpio_cntl@10000080 {
> >>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
> >>>>>
> >>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
> >>>>
> >>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
> >>>
> >>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
> >>
> >> Why not?
> >
> > Because 'syscon' alone doesn't mean anything and doesn't describe what
> > registers it contains. You need something that says this is the XYZ
> > block in the ABC SoC.
> >
> >> What if you have several controllers inside a syscon?
> >
> > You either just add properties (e.g. just add #clock-cells and it's a
> > clock provider) or you have child nodes. Which one you do generally
> > depends on if the providers have DT resources themselves.
> >
> >> The root should also have “something" in it?
> >>
> >>>
> >>>> What should I do to document it?
>
> You didn't answer my question about adding documentation...

You have to document it. Whether it's 1 or 3 schema files depends on
where we end up, but the top-level one should reference the others if
it's more than 1 file:

child-node:
  type: object
  $ref: "/schemas/foo/child-node.yaml#"

> An example driver which adds a custom compatible string and doesn't
> document it:
> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90

*it Happens.

Those cases are now blocking my adding a check that they are
undocumented. There's no shortage of examples of what not to do.

>
> >>>> I still don’t get most of this .yaml stuff...
> >>>>
> >>>>>
> >>>>>> +      reg = <0x10000080 0x80>;
> >>>>>> +
> >>>>>> +      pinctrl: pinctrl {
> >>>>>> +        compatible = "brcm,bcm6328-pinctrl";
> >>>>>> +
> >>>>>> +        gpio {
> >>>>>> +          compatible = "brcm,bcm6328-gpio";
> >>>>>
> >>>>> I'm still trying to understand why you need 3 levels of nodes here?
> >>>>> The gpio controller contains a pin controller plus other undefined
> >>>>> functions (because of 'syscon') and the pin controller contains a gpio
> >>>>> controller?
> >>>>
> >>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
> >>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
> >>>>
> >>>>>
> >>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
> >>>>> should be a single node.
> >>>>
> >>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
> >>>
> >>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
> >>> the same node. My suggestion was combining syscon and pinctrl.
> >>
> >> But that wouldn’t be correct if there were more “things” inside the syscon, right?
> >
> > Right.
> >
> >>>> Something like:
> >>>> syscon {
> >>>
> >>> Again with the syscon. If pinctrl and GPIO are the only functions
> >>> within this h/w block, then this is not a syscon. You are just abusing
> >>> that having 'syscon' compatible means you get a regmap created
> >>> automagically for you. Nothing here looks like a 'system controller'
> >>> to me. A 'system controller' is a random collection of register bits
> >>> with functions that don't fit anywhere else.
> >>
> >> pinctrl and GPIO aren’t the only functions within this HW block.
> >> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
> >
> > Okay, that's the detail missing from this patch.
> >
> >> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
> >> typedef struct GpioControl {
> >>      uint32      GPIODirHi;                  /* 0 */
> >>      uint32      GPIODir;                    /* 4 */
> >>      uint32      GPIOioHi;                   /* 8 */
> >>      uint32      GPIOio;                     /* C */
> >>      uint32      unused0;                    /* 10 */
> >>      uint32      SpiSlaveCfg;                /* 14 */
> >>      uint32      GPIOMode;                   /* 18 */
> >>      uint64      PinMuxSel;                  /* 1C */
> >>      uint32      PinMuxSelOther;             /* 24 */
> >>      uint32      TestControl;                /* 28 */
> >>      uint32      unused2;                    /* 2C */
> >>      uint32      RoboSWLEDControl;           /* 30 */
> >>      uint32      RoboSWLEDLSR;               /* 34 */
> >>      uint32      unused3;                    /* 38 */
> >>      uint32      RoboswEphyCtrl;             /* 3C */
> >>      uint32      RoboswSwitchCtrl;           /* 40 */
> >>      uint32      RegFileTmCtl;               /* 44 */
> >>      uint32      RingOscCtrl0;               /* 48 */
> >>      uint32      RingOscCtrl1;               /* 4C */
> >>      uint32      unused4[6];                 /* 50 - 64 */
> >>      uint32      DieRevID;                   /* 68 */
> >>      uint32      unused5;                    /* 6c */
> >>      uint32      DiagSelControl;             /* 70 */
> >>      uint32      DiagReadBack;               /* 74 */
> >>      uint32      DiagReadBackHi;             /* 78 */
> >>      uint32      DiagMiscControl;            /* 7c */
> >> } GpioControl;
> >>
> >> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
> >> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
> >> And this is for BCM6328, but some of the other SoCs are even more scattered.
> >
> > So based on this I'd do something like this:
> >
> > syscon {
> >    reg = <base 0x80>;
> >    ranges = <0 base 0x80>;
> >    pinctrl@18 {
> >      reg = <0x18 0x10>;
> >      foo-pins {};
> >    gpio@0 {
> >      reg = <0x0 0x10>;
> >    };
> > };
>
> You're missing a "};", so I'm not sure if you want me to go this way (1):
> syscon {
>         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>         reg = <0x10000080 0x80>;
>         ranges = <0 0x10000080 0x80>;
>
>         gpio: gpio@0 {
>                 compatible = "brcm,bcm6328-gpio";
>                 reg = <0x0 0x10>;
>
>                 data = <0xc>;
>                 dirout = <0x4>;
>
>                 gpio-controller;
>                 gpio-ranges = <&pinctrl 0 0 32>;
>                 #gpio-cells = <2>;
>         };
>
>         pinctrl: pinctrl@18 {
>                 compatible = "brcm,bcm6328-pinctrl";
>                 reg = <0x18 0x10>;
>
>                 foo-pins {};
>                 ...
>         };
> };

This way.

>
> Or this way (2):
> syscon {
>         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>         reg = <0x10000080 0x80>;
>         ranges = <0 0x10000080 0x80>;
>
>         pinctrl: pinctrl@18 {
>                 compatible = "brcm,bcm6328-pinctrl";
>                 reg = <0x0 0x28>;
>
>                 gpio: gpio@0 {

This doesn't make sense IMO because GPIO is not a sub-function of the
pinctrl h/w. They are peers.

>                         compatible = "brcm,bcm6328-gpio";
>                         reg = <0x0 0x10>;
>
>                         data = <0xc>;
>                         dirout = <0x4>;
>
>                         gpio-controller;
>                         gpio-ranges = <&pinctrl 0 0 32>;
>                         #gpio-cells = <2>;
>                 };
>
>                 foo-pins {};
>                 ...
>         };
> };

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-11 17:00             ` Álvaro Fernández Rojas
@ 2021-03-11 18:24               ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 18:24 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 10:00 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob and Linus,
>
> El 11/03/2021 a las 17:13, Linus Walleij escribió:
> > On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
> >> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> >>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
> >>>
> >>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> >>>>> +       { .compatible = "brcm,bcm6318-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6328-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6358-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6362-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6368-gpio", },
> >>>>> +       { .compatible = "brcm,bcm63268-gpio", },
> >>>>
> >>>> All these would be moved to gpio-mmio.c (or maybe that can have a
> >>>> fallback compatible?).
> >>>
> >>> This is gpio-regmap.c and it can only be used as a library
> >>> by a certain driver. gpio-mmio.c can be used stand-alone
> >>> for certain really simple hardware (though most use that
> >>> as a library as well).
> >>
> >> I don't really care which one is used, but the problem is that this
> >> choice is leaking into the binding design.
> >
> > Aha I guess I misunderstood your comment.
> >
> >> The primary problem here is
> >> once someone uses regmap, then they think they must have a syscon and
> >> can abandon using 'reg' and normal address properties as Linux happens
> >> to not use them (currently). I think we really need some better regmap
> >> vs. mmio handling to eliminate this duplication of foo-mmio and
> >> foo-regmap drivers and difference in binding design. Not sure exactly
> >> what that looks like, but basically some sort of 'reg' property to
> >> regmap creation.
> >
> > I see the problem. Yeah we should try to be more strict around
> > these things. To me there are syscons and "other regmaps",
> > where syscon is a real hurdle of registers while "other regmaps"
> > are just regmaps by convenience.
> >
> > Documentation/devicetree/bindings/mfd/syscon.yaml
> > describes what a syscon really is so if everyone could
> > just read the documentation that would be great ...
> >
> >> Given we already have a Broadcom GPIO binding for what looks to be
> >> similar to this one, I'm left wondering what's the real difference
> >> here?
> >
> > Which one is similar? I can take a look.
>
> @Linus I think @Rob is referring to brcm,bcm6345-gpio:
> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686

Well, since it's the bindings we're talking about:
Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt

Which says this:
"These bindings can be used on any BCM63xx SoC. However, BCM6338 and
BCM6345 are the only ones which don't need a pinctrl driver."

Not that the 1 in tree user of this is perfect. Seems like it too
should be a child of a system controller if there's other registers.

>
> However, the real difference between BCM6345 (and BCM6338) is that these
> SoCs have no pin controller at all, only a GPIO controller:
>
> BCM6345:
> typedef struct GpioControl {
>    uint16        unused0;
>    byte          unused1;
>    byte          TBusSel;
>    uint16        unused2;
>    uint16        GPIODir;
>    byte          unused3;
>    byte          Leds;
>    uint16        GPIOio;
>    uint32        UartCtl;
> } GpioControl;
>
> BCM6338:
> typedef struct GpioControl {
>    uint32        unused0;
>    uint32        GPIODir;      /* bits 7:0 */
>    uint32        unused1;
>    uint32        GPIOio;       /* bits 7:0 */
>    uint32        LEDCtrl;
>    uint32        SpiSlaveCfg;
>    uint32        vRegConfig;
> } GpioControl;
>
> BCM6348 and newer also have pinctrl.
> That's the main difference between that driver @Rob's referring to and
> the ones in this patch series.

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11 18:24               ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2021-03-11 18:24 UTC (permalink / raw)
  To: Álvaro Fernández Rojas
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 10:00 AM Álvaro Fernández Rojas
<noltari@gmail.com> wrote:
>
> Hi Rob and Linus,
>
> El 11/03/2021 a las 17:13, Linus Walleij escribió:
> > On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
> >> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> >>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
> >>>
> >>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
> >>>>> +       { .compatible = "brcm,bcm6318-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6328-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6358-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6362-gpio", },
> >>>>> +       { .compatible = "brcm,bcm6368-gpio", },
> >>>>> +       { .compatible = "brcm,bcm63268-gpio", },
> >>>>
> >>>> All these would be moved to gpio-mmio.c (or maybe that can have a
> >>>> fallback compatible?).
> >>>
> >>> This is gpio-regmap.c and it can only be used as a library
> >>> by a certain driver. gpio-mmio.c can be used stand-alone
> >>> for certain really simple hardware (though most use that
> >>> as a library as well).
> >>
> >> I don't really care which one is used, but the problem is that this
> >> choice is leaking into the binding design.
> >
> > Aha I guess I misunderstood your comment.
> >
> >> The primary problem here is
> >> once someone uses regmap, then they think they must have a syscon and
> >> can abandon using 'reg' and normal address properties as Linux happens
> >> to not use them (currently). I think we really need some better regmap
> >> vs. mmio handling to eliminate this duplication of foo-mmio and
> >> foo-regmap drivers and difference in binding design. Not sure exactly
> >> what that looks like, but basically some sort of 'reg' property to
> >> regmap creation.
> >
> > I see the problem. Yeah we should try to be more strict around
> > these things. To me there are syscons and "other regmaps",
> > where syscon is a real hurdle of registers while "other regmaps"
> > are just regmaps by convenience.
> >
> > Documentation/devicetree/bindings/mfd/syscon.yaml
> > describes what a syscon really is so if everyone could
> > just read the documentation that would be great ...
> >
> >> Given we already have a Broadcom GPIO binding for what looks to be
> >> similar to this one, I'm left wondering what's the real difference
> >> here?
> >
> > Which one is similar? I can take a look.
>
> @Linus I think @Rob is referring to brcm,bcm6345-gpio:
> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686

Well, since it's the bindings we're talking about:
Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt

Which says this:
"These bindings can be used on any BCM63xx SoC. However, BCM6338 and
BCM6345 are the only ones which don't need a pinctrl driver."

Not that the 1 in tree user of this is perfect. Seems like it too
should be a child of a system controller if there's other registers.

>
> However, the real difference between BCM6345 (and BCM6338) is that these
> SoCs have no pin controller at all, only a GPIO controller:
>
> BCM6345:
> typedef struct GpioControl {
>    uint16        unused0;
>    byte          unused1;
>    byte          TBusSel;
>    uint16        unused2;
>    uint16        GPIODir;
>    byte          unused3;
>    byte          Leds;
>    uint16        GPIOio;
>    uint32        UartCtl;
> } GpioControl;
>
> BCM6338:
> typedef struct GpioControl {
>    uint32        unused0;
>    uint32        GPIODir;      /* bits 7:0 */
>    uint32        unused1;
>    uint32        GPIOio;       /* bits 7:0 */
>    uint32        LEDCtrl;
>    uint32        SpiSlaveCfg;
>    uint32        vRegConfig;
> } GpioControl;
>
> BCM6348 and newer also have pinctrl.
> That's the main difference between that driver @Rob's referring to and
> the ones in this patch series.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
  2021-03-11 18:24               ` Rob Herring
@ 2021-03-11 18:32                 ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 18:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 11 mar 2021, a las 19:24, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Thu, Mar 11, 2021 at 10:00 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob and Linus,
>> 
>> El 11/03/2021 a las 17:13, Linus Walleij escribió:
>>> On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>>>>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>>> 
>>>>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
>>>>>>> +       { .compatible = "brcm,bcm6318-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6328-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6358-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6362-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6368-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm63268-gpio", },
>>>>>> 
>>>>>> All these would be moved to gpio-mmio.c (or maybe that can have a
>>>>>> fallback compatible?).
>>>>> 
>>>>> This is gpio-regmap.c and it can only be used as a library
>>>>> by a certain driver. gpio-mmio.c can be used stand-alone
>>>>> for certain really simple hardware (though most use that
>>>>> as a library as well).
>>>> 
>>>> I don't really care which one is used, but the problem is that this
>>>> choice is leaking into the binding design.
>>> 
>>> Aha I guess I misunderstood your comment.
>>> 
>>>> The primary problem here is
>>>> once someone uses regmap, then they think they must have a syscon and
>>>> can abandon using 'reg' and normal address properties as Linux happens
>>>> to not use them (currently). I think we really need some better regmap
>>>> vs. mmio handling to eliminate this duplication of foo-mmio and
>>>> foo-regmap drivers and difference in binding design. Not sure exactly
>>>> what that looks like, but basically some sort of 'reg' property to
>>>> regmap creation.
>>> 
>>> I see the problem. Yeah we should try to be more strict around
>>> these things. To me there are syscons and "other regmaps",
>>> where syscon is a real hurdle of registers while "other regmaps"
>>> are just regmaps by convenience.
>>> 
>>> Documentation/devicetree/bindings/mfd/syscon.yaml
>>> describes what a syscon really is so if everyone could
>>> just read the documentation that would be great ...
>>> 
>>>> Given we already have a Broadcom GPIO binding for what looks to be
>>>> similar to this one, I'm left wondering what's the real difference
>>>> here?
>>> 
>>> Which one is similar? I can take a look.
>> 
>> @Linus I think @Rob is referring to brcm,bcm6345-gpio:
>> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686
> 
> Well, since it's the bindings we're talking about:
> Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt
> 
> Which says this:
> "These bindings can be used on any BCM63xx SoC. However, BCM6338 and
> BCM6345 are the only ones which don't need a pinctrl driver."

Yes, I know because I’m the author of that driver…
What I meant at that time is that it could be used temporarily until a proper “full” pinctrl driver was added.

> 
> Not that the 1 in tree user of this is perfect. Seems like it too
> should be a child of a system controller if there's other registers.

There are other registers, but dirout and data registers are contiguous and separate from the others.

> 
>> 
>> However, the real difference between BCM6345 (and BCM6338) is that these
>> SoCs have no pin controller at all, only a GPIO controller:
>> 
>> BCM6345:
>> typedef struct GpioControl {
>>   uint16        unused0;
>>   byte          unused1;
>>   byte          TBusSel;
>>   uint16        unused2;
>>   uint16        GPIODir;
>>   byte          unused3;
>>   byte          Leds;
>>   uint16        GPIOio;
>>   uint32        UartCtl;
>> } GpioControl;
>> 
>> BCM6338:
>> typedef struct GpioControl {
>>   uint32        unused0;
>>   uint32        GPIODir;      /* bits 7:0 */
>>   uint32        unused1;
>>   uint32        GPIOio;       /* bits 7:0 */
>>   uint32        LEDCtrl;
>>   uint32        SpiSlaveCfg;
>>   uint32        vRegConfig;
>> } GpioControl;
>> 
>> BCM6348 and newer also have pinctrl.
>> That's the main difference between that driver @Rob's referring to and
>> the ones in this patch series.

Best regards,
Álvaro.


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

* Re: [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code
@ 2021-03-11 18:32                 ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 18:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: Linus Walleij, Michael Walle, Bartosz Golaszewski,
	Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
	Jonas Gorski, Necip Fazil Yildiran, Andy Shevchenko,
	open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 11 mar 2021, a las 19:24, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Thu, Mar 11, 2021 at 10:00 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob and Linus,
>> 
>> El 11/03/2021 a las 17:13, Linus Walleij escribió:
>>> On Thu, Mar 11, 2021 at 3:58 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>> On Wed, Mar 10, 2021 at 6:09 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>>>>> On Wed, Mar 10, 2021 at 6:51 PM Rob Herring <robh+dt@kernel.org> wrote:
>>>>> 
>>>>>>> +static const struct of_device_id bcm63xx_gpio_of_match[] = {
>>>>>>> +       { .compatible = "brcm,bcm6318-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6328-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6358-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6362-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm6368-gpio", },
>>>>>>> +       { .compatible = "brcm,bcm63268-gpio", },
>>>>>> 
>>>>>> All these would be moved to gpio-mmio.c (or maybe that can have a
>>>>>> fallback compatible?).
>>>>> 
>>>>> This is gpio-regmap.c and it can only be used as a library
>>>>> by a certain driver. gpio-mmio.c can be used stand-alone
>>>>> for certain really simple hardware (though most use that
>>>>> as a library as well).
>>>> 
>>>> I don't really care which one is used, but the problem is that this
>>>> choice is leaking into the binding design.
>>> 
>>> Aha I guess I misunderstood your comment.
>>> 
>>>> The primary problem here is
>>>> once someone uses regmap, then they think they must have a syscon and
>>>> can abandon using 'reg' and normal address properties as Linux happens
>>>> to not use them (currently). I think we really need some better regmap
>>>> vs. mmio handling to eliminate this duplication of foo-mmio and
>>>> foo-regmap drivers and difference in binding design. Not sure exactly
>>>> what that looks like, but basically some sort of 'reg' property to
>>>> regmap creation.
>>> 
>>> I see the problem. Yeah we should try to be more strict around
>>> these things. To me there are syscons and "other regmaps",
>>> where syscon is a real hurdle of registers while "other regmaps"
>>> are just regmaps by convenience.
>>> 
>>> Documentation/devicetree/bindings/mfd/syscon.yaml
>>> describes what a syscon really is so if everyone could
>>> just read the documentation that would be great ...
>>> 
>>>> Given we already have a Broadcom GPIO binding for what looks to be
>>>> similar to this one, I'm left wondering what's the real difference
>>>> here?
>>> 
>>> Which one is similar? I can take a look.
>> 
>> @Linus I think @Rob is referring to brcm,bcm6345-gpio:
>> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/drivers/gpio/gpio-mmio.c#L686
> 
> Well, since it's the bindings we're talking about:
> Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt
> 
> Which says this:
> "These bindings can be used on any BCM63xx SoC. However, BCM6338 and
> BCM6345 are the only ones which don't need a pinctrl driver."

Yes, I know because I’m the author of that driver…
What I meant at that time is that it could be used temporarily until a proper “full” pinctrl driver was added.

> 
> Not that the 1 in tree user of this is perfect. Seems like it too
> should be a child of a system controller if there's other registers.

There are other registers, but dirout and data registers are contiguous and separate from the others.

> 
>> 
>> However, the real difference between BCM6345 (and BCM6338) is that these
>> SoCs have no pin controller at all, only a GPIO controller:
>> 
>> BCM6345:
>> typedef struct GpioControl {
>>   uint16        unused0;
>>   byte          unused1;
>>   byte          TBusSel;
>>   uint16        unused2;
>>   uint16        GPIODir;
>>   byte          unused3;
>>   byte          Leds;
>>   uint16        GPIOio;
>>   uint32        UartCtl;
>> } GpioControl;
>> 
>> BCM6338:
>> typedef struct GpioControl {
>>   uint32        unused0;
>>   uint32        GPIODir;      /* bits 7:0 */
>>   uint32        unused1;
>>   uint32        GPIOio;       /* bits 7:0 */
>>   uint32        LEDCtrl;
>>   uint32        SpiSlaveCfg;
>>   uint32        vRegConfig;
>> } GpioControl;
>> 
>> BCM6348 and newer also have pinctrl.
>> That's the main difference between that driver @Rob's referring to and
>> the ones in this patch series.

Best regards,
Álvaro.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-11 18:14                 ` Rob Herring
@ 2021-03-11 18:34                   ` Álvaro Fernández Rojas
  -1 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 18:34 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 11 mar 2021, a las 19:14, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Thu, Mar 11, 2021 at 10:09 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob,
>> 
>> El 10/03/2021 a las 21:52, Rob Herring escribió:
>>> On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>> 
>>>> Hi Rob,
>>>> 
>>>>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>> 
>>>>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
>>>>> <noltari@gmail.com> wrote:
>>>>>> 
>>>>>> Hi Rob,
>>>>>> 
>>>>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>>>> 
>>>>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>>>>>> <noltari@gmail.com> wrote:
>>>>>>>> 
>>>>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>>>>>> 
>>>>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>>>> ---
>>>>>>>> v6: add changes suggested by Rob Herring
>>>>>>>> v5: change Documentation to dt-bindings in commit title
>>>>>>>> v4: no changes
>>>>>>>> v3: add new gpio node
>>>>>>>> v2: remove interrupts
>>>>>>>> 
>>>>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>>>>>> 1 file changed, 174 insertions(+)
>>>>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> 
>>>>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..471f6efa1754
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> @@ -0,0 +1,174 @@
>>>>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>>>>>> +%YAML 1.2
>>>>>>>> +---
>>>>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>>>>> +
>>>>>>>> +title: Broadcom BCM6328 pin controller
>>>>>>>> +
>>>>>>>> +maintainers:
>>>>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> +
>>>>>>>> +description: |+
>>>>>>>> +  The pin controller node should be the child of a syscon node.
>>>>>>>> +
>>>>>>>> +  Refer to the the bindings described in
>>>>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>>>>>> +
>>>>>>>> +properties:
>>>>>>>> +  compatible:
>>>>>>>> +    const: brcm,bcm6328-pinctrl
>>>>>>>> +
>>>>>>>> +  gpio:
>>>>>>>> +    type: object
>>>>>>>> +    properties:
>>>>>>>> +      compatible:
>>>>>>>> +        const: brcm,bcm6328-gpio
>>>>>>>> +
>>>>>>>> +      data:
>>>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>>> +        description: |
>>>>>>>> +          Offset in the register map for the data register (in bytes).
>>>>>>>> +
>>>>>>>> +      dirout:
>>>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>>> +        description: |
>>>>>>>> +          Offset in the register map for the dirout register (in bytes).
>>>>>>>> +
>>>>>>>> +      gpio-controller: true
>>>>>>>> +
>>>>>>>> +      "#gpio-cells":
>>>>>>>> +        const: 2
>>>>>>>> +
>>>>>>>> +      gpio-ranges:
>>>>>>>> +        maxItems: 1
>>>>>>>> +
>>>>>>>> +    required:
>>>>>>>> +      - gpio-controller
>>>>>>>> +      - gpio-ranges
>>>>>>>> +      - '#gpio-cells'
>>>>>>>> +
>>>>>>>> +    additionalProperties: false
>>>>>>>> +
>>>>>>>> +patternProperties:
>>>>>>>> +  '^.*-pins$':
>>>>>>>> +    if:
>>>>>>>> +      type: object
>>>>>>>> +    then:
>>>>>>>> +      properties:
>>>>>>>> +        function:
>>>>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>>>>>> +
>>>>>>>> +        pins:
>>>>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>>>>>> +                  usb_port1 ]
>>>>>>>> +
>>>>>>>> +required:
>>>>>>>> +  - compatible
>>>>>>>> +  - gpio
>>>>>>>> +
>>>>>>>> +additionalProperties: false
>>>>>>>> +
>>>>>>>> +examples:
>>>>>>>> +  - |
>>>>>>>> +    gpio_cntl@10000080 {
>>>>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>>>>>> 
>>>>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>>>>>> 
>>>>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
>>>>> 
>>>>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>>>> 
>>>> Why not?
>>> 
>>> Because 'syscon' alone doesn't mean anything and doesn't describe what
>>> registers it contains. You need something that says this is the XYZ
>>> block in the ABC SoC.
>>> 
>>>> What if you have several controllers inside a syscon?
>>> 
>>> You either just add properties (e.g. just add #clock-cells and it's a
>>> clock provider) or you have child nodes. Which one you do generally
>>> depends on if the providers have DT resources themselves.
>>> 
>>>> The root should also have “something" in it?
>>>> 
>>>>> 
>>>>>> What should I do to document it?
>> 
>> You didn't answer my question about adding documentation...
> 
> You have to document it. Whether it's 1 or 3 schema files depends on
> where we end up, but the top-level one should reference the others if
> it's more than 1 file:
> 
> child-node:
>  type: object
>  $ref: "/schemas/foo/child-node.yaml#"

Can you give me an example of a driver which is documenting that?
I’m sorry, but I still don’t know how to do it properly...

> 
>> An example driver which adds a custom compatible string and doesn't
>> document it:
>> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90
> 
> *it Happens.
> 
> Those cases are now blocking my adding a check that they are
> undocumented. There's no shortage of examples of what not to do.
> 
>> 
>>>>>> I still don’t get most of this .yaml stuff...
>>>>>> 
>>>>>>> 
>>>>>>>> +      reg = <0x10000080 0x80>;
>>>>>>>> +
>>>>>>>> +      pinctrl: pinctrl {
>>>>>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>>>>>> +
>>>>>>>> +        gpio {
>>>>>>>> +          compatible = "brcm,bcm6328-gpio";
>>>>>>> 
>>>>>>> I'm still trying to understand why you need 3 levels of nodes here?
>>>>>>> The gpio controller contains a pin controller plus other undefined
>>>>>>> functions (because of 'syscon') and the pin controller contains a gpio
>>>>>>> controller?
>>>>>> 
>>>>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>>>>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>>>>>> 
>>>>>>> 
>>>>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>>>>>> should be a single node.
>>>>>> 
>>>>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
>>>>> 
>>>>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
>>>>> the same node. My suggestion was combining syscon and pinctrl.
>>>> 
>>>> But that wouldn’t be correct if there were more “things” inside the syscon, right?
>>> 
>>> Right.
>>> 
>>>>>> Something like:
>>>>>> syscon {
>>>>> 
>>>>> Again with the syscon. If pinctrl and GPIO are the only functions
>>>>> within this h/w block, then this is not a syscon. You are just abusing
>>>>> that having 'syscon' compatible means you get a regmap created
>>>>> automagically for you. Nothing here looks like a 'system controller'
>>>>> to me. A 'system controller' is a random collection of register bits
>>>>> with functions that don't fit anywhere else.
>>>> 
>>>> pinctrl and GPIO aren’t the only functions within this HW block.
>>>> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
>>> 
>>> Okay, that's the detail missing from this patch.
>>> 
>>>> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
>>>> typedef struct GpioControl {
>>>>     uint32      GPIODirHi;                  /* 0 */
>>>>     uint32      GPIODir;                    /* 4 */
>>>>     uint32      GPIOioHi;                   /* 8 */
>>>>     uint32      GPIOio;                     /* C */
>>>>     uint32      unused0;                    /* 10 */
>>>>     uint32      SpiSlaveCfg;                /* 14 */
>>>>     uint32      GPIOMode;                   /* 18 */
>>>>     uint64      PinMuxSel;                  /* 1C */
>>>>     uint32      PinMuxSelOther;             /* 24 */
>>>>     uint32      TestControl;                /* 28 */
>>>>     uint32      unused2;                    /* 2C */
>>>>     uint32      RoboSWLEDControl;           /* 30 */
>>>>     uint32      RoboSWLEDLSR;               /* 34 */
>>>>     uint32      unused3;                    /* 38 */
>>>>     uint32      RoboswEphyCtrl;             /* 3C */
>>>>     uint32      RoboswSwitchCtrl;           /* 40 */
>>>>     uint32      RegFileTmCtl;               /* 44 */
>>>>     uint32      RingOscCtrl0;               /* 48 */
>>>>     uint32      RingOscCtrl1;               /* 4C */
>>>>     uint32      unused4[6];                 /* 50 - 64 */
>>>>     uint32      DieRevID;                   /* 68 */
>>>>     uint32      unused5;                    /* 6c */
>>>>     uint32      DiagSelControl;             /* 70 */
>>>>     uint32      DiagReadBack;               /* 74 */
>>>>     uint32      DiagReadBackHi;             /* 78 */
>>>>     uint32      DiagMiscControl;            /* 7c */
>>>> } GpioControl;
>>>> 
>>>> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
>>>> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
>>>> And this is for BCM6328, but some of the other SoCs are even more scattered.
>>> 
>>> So based on this I'd do something like this:
>>> 
>>> syscon {
>>>   reg = <base 0x80>;
>>>   ranges = <0 base 0x80>;
>>>   pinctrl@18 {
>>>     reg = <0x18 0x10>;
>>>     foo-pins {};
>>>   gpio@0 {
>>>     reg = <0x0 0x10>;
>>>   };
>>> };
>> 
>> You're missing a "};", so I'm not sure if you want me to go this way (1):
>> syscon {
>>        compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>>        reg = <0x10000080 0x80>;
>>        ranges = <0 0x10000080 0x80>;
>> 
>>        gpio: gpio@0 {
>>                compatible = "brcm,bcm6328-gpio";
>>                reg = <0x0 0x10>;
>> 
>>                data = <0xc>;
>>                dirout = <0x4>;
>> 
>>                gpio-controller;
>>                gpio-ranges = <&pinctrl 0 0 32>;
>>                #gpio-cells = <2>;
>>        };
>> 
>>        pinctrl: pinctrl@18 {
>>                compatible = "brcm,bcm6328-pinctrl";
>>                reg = <0x18 0x10>;
>> 
>>                foo-pins {};
>>                ...
>>        };
>> };
> 
> This way.
> 
>> 
>> Or this way (2):
>> syscon {
>>        compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>>        reg = <0x10000080 0x80>;
>>        ranges = <0 0x10000080 0x80>;
>> 
>>        pinctrl: pinctrl@18 {
>>                compatible = "brcm,bcm6328-pinctrl";
>>                reg = <0x0 0x28>;
>> 
>>                gpio: gpio@0 {
> 
> This doesn't make sense IMO because GPIO is not a sub-function of the
> pinctrl h/w. They are peers.

Well, that’s where @Linus and I disagree...

> 
>>                        compatible = "brcm,bcm6328-gpio";
>>                        reg = <0x0 0x10>;
>> 
>>                        data = <0xc>;
>>                        dirout = <0x4>;
>> 
>>                        gpio-controller;
>>                        gpio-ranges = <&pinctrl 0 0 32>;
>>                        #gpio-cells = <2>;
>>                };
>> 
>>                foo-pins {};
>>                ...
>>        };
>> };


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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-11 18:34                   ` Álvaro Fernández Rojas
  0 siblings, 0 replies; 76+ messages in thread
From: Álvaro Fernández Rojas @ 2021-03-11 18:34 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij
  Cc: Michael Walle, Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

Hi Rob,

> El 11 mar 2021, a las 19:14, Rob Herring <robh+dt@kernel.org> escribió:
> 
> On Thu, Mar 11, 2021 at 10:09 AM Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> 
>> Hi Rob,
>> 
>> El 10/03/2021 a las 21:52, Rob Herring escribió:
>>> On Wed, Mar 10, 2021 at 12:10 PM Álvaro Fernández Rojas
>>> <noltari@gmail.com> wrote:
>>>> 
>>>> Hi Rob,
>>>> 
>>>>> El 10 mar 2021, a las 19:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>> 
>>>>> On Wed, Mar 10, 2021 at 11:03 AM Álvaro Fernández Rojas
>>>>> <noltari@gmail.com> wrote:
>>>>>> 
>>>>>> Hi Rob,
>>>>>> 
>>>>>>> El 10 mar 2021, a las 18:45, Rob Herring <robh+dt@kernel.org> escribió:
>>>>>>> 
>>>>>>> On Wed, Mar 10, 2021 at 5:55 AM Álvaro Fernández Rojas
>>>>>>> <noltari@gmail.com> wrote:
>>>>>>>> 
>>>>>>>> Add binding documentation for the pincontrol core found in BCM6328 SoCs.
>>>>>>>> 
>>>>>>>> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>>>> ---
>>>>>>>> v6: add changes suggested by Rob Herring
>>>>>>>> v5: change Documentation to dt-bindings in commit title
>>>>>>>> v4: no changes
>>>>>>>> v3: add new gpio node
>>>>>>>> v2: remove interrupts
>>>>>>>> 
>>>>>>>> .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 174 ++++++++++++++++++
>>>>>>>> 1 file changed, 174 insertions(+)
>>>>>>>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> 
>>>>>>>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..471f6efa1754
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
>>>>>>>> @@ -0,0 +1,174 @@
>>>>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>>>>>> +%YAML 1.2
>>>>>>>> +---
>>>>>>>> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
>>>>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>>>>> +
>>>>>>>> +title: Broadcom BCM6328 pin controller
>>>>>>>> +
>>>>>>>> +maintainers:
>>>>>>>> +  - Álvaro Fernández Rojas <noltari@gmail.com>
>>>>>>>> +  - Jonas Gorski <jonas.gorski@gmail.com>
>>>>>>>> +
>>>>>>>> +description: |+
>>>>>>>> +  The pin controller node should be the child of a syscon node.
>>>>>>>> +
>>>>>>>> +  Refer to the the bindings described in
>>>>>>>> +  Documentation/devicetree/bindings/mfd/syscon.yaml
>>>>>>>> +
>>>>>>>> +properties:
>>>>>>>> +  compatible:
>>>>>>>> +    const: brcm,bcm6328-pinctrl
>>>>>>>> +
>>>>>>>> +  gpio:
>>>>>>>> +    type: object
>>>>>>>> +    properties:
>>>>>>>> +      compatible:
>>>>>>>> +        const: brcm,bcm6328-gpio
>>>>>>>> +
>>>>>>>> +      data:
>>>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>>> +        description: |
>>>>>>>> +          Offset in the register map for the data register (in bytes).
>>>>>>>> +
>>>>>>>> +      dirout:
>>>>>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>>> +        description: |
>>>>>>>> +          Offset in the register map for the dirout register (in bytes).
>>>>>>>> +
>>>>>>>> +      gpio-controller: true
>>>>>>>> +
>>>>>>>> +      "#gpio-cells":
>>>>>>>> +        const: 2
>>>>>>>> +
>>>>>>>> +      gpio-ranges:
>>>>>>>> +        maxItems: 1
>>>>>>>> +
>>>>>>>> +    required:
>>>>>>>> +      - gpio-controller
>>>>>>>> +      - gpio-ranges
>>>>>>>> +      - '#gpio-cells'
>>>>>>>> +
>>>>>>>> +    additionalProperties: false
>>>>>>>> +
>>>>>>>> +patternProperties:
>>>>>>>> +  '^.*-pins$':
>>>>>>>> +    if:
>>>>>>>> +      type: object
>>>>>>>> +    then:
>>>>>>>> +      properties:
>>>>>>>> +        function:
>>>>>>>> +          $ref: "pinmux-node.yaml#/properties/function"
>>>>>>>> +          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
>>>>>>>> +                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
>>>>>>>> +                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
>>>>>>>> +
>>>>>>>> +        pins:
>>>>>>>> +          $ref: "pinmux-node.yaml#/properties/pins"
>>>>>>>> +          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
>>>>>>>> +                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
>>>>>>>> +                  usb_port1 ]
>>>>>>>> +
>>>>>>>> +required:
>>>>>>>> +  - compatible
>>>>>>>> +  - gpio
>>>>>>>> +
>>>>>>>> +additionalProperties: false
>>>>>>>> +
>>>>>>>> +examples:
>>>>>>>> +  - |
>>>>>>>> +    gpio_cntl@10000080 {
>>>>>>>> +      compatible = "brcm,bcm6328-gpio-controller", "syscon", "simple-mfd";
>>>>>>> 
>>>>>>> You just added "brcm,bcm6328-gpio-controller", it would need to be documented.
>>>>>> 
>>>>>> I just added that because you requested me to do it ¯\_(ツ)_/¯
>>>>> 
>>>>> I said 'syscon' by itself was not allowed, then asked about the multiple levels.
>>>> 
>>>> Why not?
>>> 
>>> Because 'syscon' alone doesn't mean anything and doesn't describe what
>>> registers it contains. You need something that says this is the XYZ
>>> block in the ABC SoC.
>>> 
>>>> What if you have several controllers inside a syscon?
>>> 
>>> You either just add properties (e.g. just add #clock-cells and it's a
>>> clock provider) or you have child nodes. Which one you do generally
>>> depends on if the providers have DT resources themselves.
>>> 
>>>> The root should also have “something" in it?
>>>> 
>>>>> 
>>>>>> What should I do to document it?
>> 
>> You didn't answer my question about adding documentation...
> 
> You have to document it. Whether it's 1 or 3 schema files depends on
> where we end up, but the top-level one should reference the others if
> it's more than 1 file:
> 
> child-node:
>  type: object
>  $ref: "/schemas/foo/child-node.yaml#"

Can you give me an example of a driver which is documenting that?
I’m sorry, but I still don’t know how to do it properly...

> 
>> An example driver which adds a custom compatible string and doesn't
>> document it:
>> https://github.com/torvalds/linux/blob/a74e6a014c9d4d4161061f770c9b4f98372ac778/Documentation/devicetree/bindings/clock/sprd%2Csc9863a-clk.yaml#L90
> 
> *it Happens.
> 
> Those cases are now blocking my adding a check that they are
> undocumented. There's no shortage of examples of what not to do.
> 
>> 
>>>>>> I still don’t get most of this .yaml stuff...
>>>>>> 
>>>>>>> 
>>>>>>>> +      reg = <0x10000080 0x80>;
>>>>>>>> +
>>>>>>>> +      pinctrl: pinctrl {
>>>>>>>> +        compatible = "brcm,bcm6328-pinctrl";
>>>>>>>> +
>>>>>>>> +        gpio {
>>>>>>>> +          compatible = "brcm,bcm6328-gpio";
>>>>>>> 
>>>>>>> I'm still trying to understand why you need 3 levels of nodes here?
>>>>>>> The gpio controller contains a pin controller plus other undefined
>>>>>>> functions (because of 'syscon') and the pin controller contains a gpio
>>>>>>> controller?
>>>>>> 
>>>>>> In previous versions the gpio controller was registered along with the pin controller, but @Linus requested me to register the gpio pin controller ranges through device tree by using gpio-ranges and I decided to use this approach, which was already used by other pin controllers.
>>>>>> However, there aren’t any pinctrl drivers using gpio-regmap, so this is kind of new…
>>>>>> 
>>>>>>> 
>>>>>>> I think "brcm,bcm6328-gpio-controller" and "brcm,bcm6328-pinctrl"
>>>>>>> should be a single node.
>>>>>> 
>>>>>> I agree, but does it make sense to add gpio-ranges to a pinctrl node referencing itself?
>>>>> 
>>>>> It wouldn't be. I wasn't saying the pinctrl and gpio controller are
>>>>> the same node. My suggestion was combining syscon and pinctrl.
>>>> 
>>>> But that wouldn’t be correct if there were more “things” inside the syscon, right?
>>> 
>>> Right.
>>> 
>>>>>> Something like:
>>>>>> syscon {
>>>>> 
>>>>> Again with the syscon. If pinctrl and GPIO are the only functions
>>>>> within this h/w block, then this is not a syscon. You are just abusing
>>>>> that having 'syscon' compatible means you get a regmap created
>>>>> automagically for you. Nothing here looks like a 'system controller'
>>>>> to me. A 'system controller' is a random collection of register bits
>>>>> with functions that don't fit anywhere else.
>>>> 
>>>> pinctrl and GPIO aren’t the only functions within this HW block.
>>>> Maybe I didn’t document/code it properly, but I’m sure I’m not abusing what a system controller is.
>>> 
>>> Okay, that's the detail missing from this patch.
>>> 
>>>> Please, take a look at http://www.datashed.science/misc/bcm/gpl/broadcom-sdk-416L05/shared/opensource/include/bcm963xx/6328_map_part.h:
>>>> typedef struct GpioControl {
>>>>     uint32      GPIODirHi;                  /* 0 */
>>>>     uint32      GPIODir;                    /* 4 */
>>>>     uint32      GPIOioHi;                   /* 8 */
>>>>     uint32      GPIOio;                     /* C */
>>>>     uint32      unused0;                    /* 10 */
>>>>     uint32      SpiSlaveCfg;                /* 14 */
>>>>     uint32      GPIOMode;                   /* 18 */
>>>>     uint64      PinMuxSel;                  /* 1C */
>>>>     uint32      PinMuxSelOther;             /* 24 */
>>>>     uint32      TestControl;                /* 28 */
>>>>     uint32      unused2;                    /* 2C */
>>>>     uint32      RoboSWLEDControl;           /* 30 */
>>>>     uint32      RoboSWLEDLSR;               /* 34 */
>>>>     uint32      unused3;                    /* 38 */
>>>>     uint32      RoboswEphyCtrl;             /* 3C */
>>>>     uint32      RoboswSwitchCtrl;           /* 40 */
>>>>     uint32      RegFileTmCtl;               /* 44 */
>>>>     uint32      RingOscCtrl0;               /* 48 */
>>>>     uint32      RingOscCtrl1;               /* 4C */
>>>>     uint32      unused4[6];                 /* 50 - 64 */
>>>>     uint32      DieRevID;                   /* 68 */
>>>>     uint32      unused5;                    /* 6c */
>>>>     uint32      DiagSelControl;             /* 70 */
>>>>     uint32      DiagReadBack;               /* 74 */
>>>>     uint32      DiagReadBackHi;             /* 78 */
>>>>     uint32      DiagMiscControl;            /* 7c */
>>>> } GpioControl;
>>>> 
>>>> So we’re using GPIODirHi, GPIODir, GPIOioHi and GPIOio registers for GPIO regmap driver.
>>>> And we’re using GPIOMode, PinMuxSel (u64 -> x2 u32), PinMuxSelOther for pinctrl driver.
>>>> And this is for BCM6328, but some of the other SoCs are even more scattered.
>>> 
>>> So based on this I'd do something like this:
>>> 
>>> syscon {
>>>   reg = <base 0x80>;
>>>   ranges = <0 base 0x80>;
>>>   pinctrl@18 {
>>>     reg = <0x18 0x10>;
>>>     foo-pins {};
>>>   gpio@0 {
>>>     reg = <0x0 0x10>;
>>>   };
>>> };
>> 
>> You're missing a "};", so I'm not sure if you want me to go this way (1):
>> syscon {
>>        compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>>        reg = <0x10000080 0x80>;
>>        ranges = <0 0x10000080 0x80>;
>> 
>>        gpio: gpio@0 {
>>                compatible = "brcm,bcm6328-gpio";
>>                reg = <0x0 0x10>;
>> 
>>                data = <0xc>;
>>                dirout = <0x4>;
>> 
>>                gpio-controller;
>>                gpio-ranges = <&pinctrl 0 0 32>;
>>                #gpio-cells = <2>;
>>        };
>> 
>>        pinctrl: pinctrl@18 {
>>                compatible = "brcm,bcm6328-pinctrl";
>>                reg = <0x18 0x10>;
>> 
>>                foo-pins {};
>>                ...
>>        };
>> };
> 
> This way.
> 
>> 
>> Or this way (2):
>> syscon {
>>        compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
>>        reg = <0x10000080 0x80>;
>>        ranges = <0 0x10000080 0x80>;
>> 
>>        pinctrl: pinctrl@18 {
>>                compatible = "brcm,bcm6328-pinctrl";
>>                reg = <0x0 0x28>;
>> 
>>                gpio: gpio@0 {
> 
> This doesn't make sense IMO because GPIO is not a sub-function of the
> pinctrl h/w. They are peers.

Well, that’s where @Linus and I disagree...

> 
>>                        compatible = "brcm,bcm6328-gpio";
>>                        reg = <0x0 0x10>;
>> 
>>                        data = <0xc>;
>>                        dirout = <0x4>;
>> 
>>                        gpio-controller;
>>                        gpio-ranges = <&pinctrl 0 0 32>;
>>                        #gpio-cells = <2>;
>>                };
>> 
>>                foo-pins {};
>>                ...
>>        };
>> };


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
  2021-03-11 18:14                 ` Rob Herring
@ 2021-03-15 15:57                   ` Linus Walleij
  -1 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-15 15:57 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 7:14 PM Rob Herring <robh+dt@kernel.org> wrote:

> > Or this way (2):
> > syscon {
> >         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
> >         reg = <0x10000080 0x80>;
> >         ranges = <0 0x10000080 0x80>;
> >
> >         pinctrl: pinctrl@18 {
> >                 compatible = "brcm,bcm6328-pinctrl";
> >                 reg = <0x0 0x28>;
> >
> >                 gpio: gpio@0 {
>
> This doesn't make sense IMO because GPIO is not a sub-function of the
> pinctrl h/w. They are peers.

This becomes an ontological discussion, as in "what does the world
consist of and what are the proper definitions of the
things in it".

A couple of years back I had this presentation:
https://dflund.se/~triad/papers/pincontrol.pdf
where I try to investigate how hardware engineers build
these blocks.

TL;DR: it depends on what the hardware engineer
did.

A HW block can be pin controller, GPIO controller
and interrupt chip at the same time, that case is
straight-forward. One compatible, lots of
properties.
.
A second case is when the pin controller and the
GPIO+irqchip are two completely different HW
entities, and then they also get two different
device nodes on the same level in the device tree.
(We usually see this when the different blocks
live in totally different memory locations.)

However in the third case HW can also be bolted
with a front-end pin controller (facing the pins) with
several GPIO+interrupt controller back-ends.
Then it gets the structure in this patch,
subnodes for each GPIO controller.

Our current bindings have all three examples
and it simply reflects the different ways HW
engineers have chosen to integrate their stuff.

Yours,
Linus Walleij

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

* Re: [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation
@ 2021-03-15 15:57                   ` Linus Walleij
  0 siblings, 0 replies; 76+ messages in thread
From: Linus Walleij @ 2021-03-15 15:57 UTC (permalink / raw)
  To: Rob Herring
  Cc: Álvaro Fernández Rojas, Michael Walle,
	Bartosz Golaszewski, Florian Fainelli,
	maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE, Jonas Gorski,
	Necip Fazil Yildiran, Andy Shevchenko, open list:GPIO SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, linux-arm-kernel

On Thu, Mar 11, 2021 at 7:14 PM Rob Herring <robh+dt@kernel.org> wrote:

> > Or this way (2):
> > syscon {
> >         compatible = "brcm,bcm6328-gpio-regs", "syscon", "simple-mfd";
> >         reg = <0x10000080 0x80>;
> >         ranges = <0 0x10000080 0x80>;
> >
> >         pinctrl: pinctrl@18 {
> >                 compatible = "brcm,bcm6328-pinctrl";
> >                 reg = <0x0 0x28>;
> >
> >                 gpio: gpio@0 {
>
> This doesn't make sense IMO because GPIO is not a sub-function of the
> pinctrl h/w. They are peers.

This becomes an ontological discussion, as in "what does the world
consist of and what are the proper definitions of the
things in it".

A couple of years back I had this presentation:
https://dflund.se/~triad/papers/pincontrol.pdf
where I try to investigate how hardware engineers build
these blocks.

TL;DR: it depends on what the hardware engineer
did.

A HW block can be pin controller, GPIO controller
and interrupt chip at the same time, that case is
straight-forward. One compatible, lots of
properties.
.
A second case is when the pin controller and the
GPIO+irqchip are two completely different HW
entities, and then they also get two different
device nodes on the same level in the device tree.
(We usually see this when the different blocks
live in totally different memory locations.)

However in the third case HW can also be bolted
with a front-end pin controller (facing the pins) with
several GPIO+interrupt controller back-ends.
Then it gets the structure in this patch,
subnodes for each GPIO controller.

Our current bindings have all three examples
and it simply reflects the different ways HW
engineers have chosen to integrate their stuff.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2021-03-15 15:59 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-10 12:54 [PATCH v6 00/15] pinctrl: add BCM63XX pincontrol support Álvaro Fernández Rojas
2021-03-10 12:54 ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 01/15] gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 02/15] gpio: regmap: set gpio_chip of_node Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 14:01   ` Andy Shevchenko
2021-03-10 14:01     ` Andy Shevchenko
2021-03-10 18:27   ` Michael Walle
2021-03-10 18:27     ` Michael Walle
2021-03-10 19:12     ` Álvaro Fernández Rojas
2021-03-10 19:12       ` Álvaro Fernández Rojas
2021-03-11  1:16       ` Linus Walleij
2021-03-11  1:16         ` Linus Walleij
2021-03-10 12:54 ` [PATCH v6 03/15] pinctrl: bcm: add bcm63xx base code Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 14:07   ` Andy Shevchenko
2021-03-10 14:07     ` Andy Shevchenko
2021-03-10 17:50   ` Rob Herring
2021-03-10 17:50     ` Rob Herring
2021-03-11  1:09     ` Linus Walleij
2021-03-11  1:09       ` Linus Walleij
2021-03-11 14:57       ` Rob Herring
2021-03-11 14:57         ` Rob Herring
2021-03-11 16:13         ` Linus Walleij
2021-03-11 16:13           ` Linus Walleij
2021-03-11 17:00           ` Álvaro Fernández Rojas
2021-03-11 17:00             ` Álvaro Fernández Rojas
2021-03-11 18:24             ` Rob Herring
2021-03-11 18:24               ` Rob Herring
2021-03-11 18:32               ` Álvaro Fernández Rojas
2021-03-11 18:32                 ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 04/15] dt-bindings: add BCM6328 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 17:45   ` Rob Herring
2021-03-10 17:45     ` Rob Herring
2021-03-10 18:03     ` Álvaro Fernández Rojas
2021-03-10 18:03       ` Álvaro Fernández Rojas
2021-03-10 18:45       ` Rob Herring
2021-03-10 18:45         ` Rob Herring
2021-03-10 19:10         ` Álvaro Fernández Rojas
2021-03-10 19:10           ` Álvaro Fernández Rojas
2021-03-10 20:52           ` Rob Herring
2021-03-10 20:52             ` Rob Herring
2021-03-11 17:09             ` Álvaro Fernández Rojas
2021-03-11 17:09               ` Álvaro Fernández Rojas
2021-03-11 18:14               ` Rob Herring
2021-03-11 18:14                 ` Rob Herring
2021-03-11 18:34                 ` Álvaro Fernández Rojas
2021-03-11 18:34                   ` Álvaro Fernández Rojas
2021-03-15 15:57                 ` Linus Walleij
2021-03-15 15:57                   ` Linus Walleij
2021-03-11  1:22       ` Linus Walleij
2021-03-11  1:22         ` Linus Walleij
2021-03-10 12:54 ` [PATCH v6 05/15] pinctrl: add a pincontrol driver for BCM6328 Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 06/15] dt-bindings: add BCM6358 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 07/15] pinctrl: add a pincontrol driver for BCM6358 Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 08/15] dt-bindings: add BCM6362 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 09/15] pinctrl: add a pincontrol driver for BCM6362 Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 10/15] dt-bindings: add BCM6368 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:54 ` [PATCH v6 11/15] pinctrl: add a pincontrol driver for BCM6368 Álvaro Fernández Rojas
2021-03-10 12:54   ` Álvaro Fernández Rojas
2021-03-10 12:55 ` [PATCH v6 12/15] dt-bindings: add BCM63268 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:55   ` Álvaro Fernández Rojas
2021-03-10 12:55 ` [PATCH v6 13/15] pinctrl: add a pincontrol driver for BCM63268 Álvaro Fernández Rojas
2021-03-10 12:55   ` Álvaro Fernández Rojas
2021-03-10 12:55 ` [PATCH v6 14/15] dt-bindings: add BCM6318 pincontroller binding documentation Álvaro Fernández Rojas
2021-03-10 12:55   ` Álvaro Fernández Rojas
2021-03-10 12:55 ` [PATCH v6 15/15] pinctrl: add a pincontrol driver for BCM6318 Álvaro Fernández Rojas
2021-03-10 12:55   ` Álvaro Fernández Rojas

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.