linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
@ 2025-09-30 12:02 Linus Walleij
  2025-09-30 12:02 ` [PATCH 1/6] pinctrl: bcm: Rename bcm4908 to bcmbca Linus Walleij
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

This refactors the BCM4908 pin control driver into a generic
BCMBCA driver and adds the BCM6846 SoC.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Linus Walleij (6):
      pinctrl: bcm: Rename bcm4908 to bcmbca
      pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs
      pinctrl: bcm: bcmbca: Prefix all BCM4908 data
      pinctrl: bcm: bcmbca: Use a guarded mutex
      dt-bindings: pinctrl: Add binding for BCM6846 pinctrl
      pinctrl: bcm: bcmbca: Add support for BCM6846

 .../bindings/pinctrl/brcm,bcm6846-pinctrl.yaml     |   82 ++
 drivers/pinctrl/bcm/Kconfig                        |    9 +-
 drivers/pinctrl/bcm/Makefile                       |    2 +-
 drivers/pinctrl/bcm/pinctrl-bcm4908.c              |  564 ----------
 drivers/pinctrl/bcm/pinctrl-bcmbca.c               | 1114 ++++++++++++++++++++
 5 files changed, 1202 insertions(+), 569 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250930-bcmbca-pinctrl-deb82d571e13

Best regards,
-- 
Linus Walleij <linus.walleij@linaro.org>


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

* [PATCH 1/6] pinctrl: bcm: Rename bcm4908 to bcmbca
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-09-30 12:02 ` [PATCH 2/6] pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs Linus Walleij
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

The basic structure and the hardware of all BCA SoCs are the
same as for BCM4908 so rename all symbols to BCMBCA.

This makes for a good base to isolate/parameterize and split
out BCM4908 and add other SoCs.

The driver is unconditionally selected for all ARCH_BCMBCA
anyway so renaming the symbol should be pretty painless.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/bcm/Kconfig                        |   9 +-
 drivers/pinctrl/bcm/Makefile                       |   2 +-
 .../bcm/{pinctrl-bcm4908.c => pinctrl-bcmbca.c}    | 208 ++++++++++-----------
 3 files changed, 110 insertions(+), 109 deletions(-)

diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index 35b51ce4298e2588d0ae9dbda95749858e75dba8..18619aa6c17f0794801fa55e4448c664588aa641 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -29,8 +29,8 @@ config PINCTRL_BCM2835
 	help
 	   Say Y here to enable the Broadcom BCM2835 GPIO driver.
 
-config PINCTRL_BCM4908
-	tristate "Broadcom BCM4908 pinmux driver"
+config PINCTRL_BCMBCA
+	tristate "Broadcom BCMBCA pinmux driver"
 	depends on OF && (ARCH_BCMBCA || COMPILE_TEST)
 	select PINMUX
 	select PINCONF
@@ -39,9 +39,10 @@ config PINCTRL_BCM4908
 	select GENERIC_PINMUX_FUNCTIONS
 	default ARCH_BCMBCA
 	help
-	  Driver for BCM4908 family SoCs with integrated pin controller.
+	  Driver for BCMBCA (Broadcom Broadband Carrier Access) family
+	  SoCs with integrated pin controller.
 
-	  If compiled as module it will be called pinctrl-bcm4908.
+	  If compiled as module it will be called pinctrl-bcmbca.
 
 config PINCTRL_BCM63XX
 	bool
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 82b868ec14716dc80711d0fcfd9ddd1ee61c9f72..bd7d1762fc12b3736954600dcd78e224bf51e36c 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -3,7 +3,6 @@
 
 obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
-obj-$(CONFIG_PINCTRL_BCM4908)		+= pinctrl-bcm4908.o
 obj-$(CONFIG_PINCTRL_BCM63XX)		+= pinctrl-bcm63xx.o
 obj-$(CONFIG_PINCTRL_BCM6318)		+= pinctrl-bcm6318.o
 obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
@@ -11,6 +10,7 @@ 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_BCMBCA)		+= pinctrl-bcmbca.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-bcm4908.c b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
similarity index 66%
rename from drivers/pinctrl/bcm/pinctrl-bcm4908.c
rename to drivers/pinctrl/bcm/pinctrl-bcmbca.c
index 12f7a253ea4d5bd0af5dbabc320fc2df32172e4f..834241103b5452836aea9fe817f7e5d143893985 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm4908.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
@@ -17,14 +17,14 @@
 
 #define BCM4908_NUM_PINS			86
 
-#define BCM4908_TEST_PORT_BLOCK_EN_LSB			0x00
-#define BCM4908_TEST_PORT_BLOCK_DATA_MSB		0x04
-#define BCM4908_TEST_PORT_BLOCK_DATA_LSB		0x08
-#define  BCM4908_TEST_PORT_LSB_PINMUX_DATA_SHIFT	12
-#define BCM4908_TEST_PORT_COMMAND			0x0c
-#define  BCM4908_TEST_PORT_CMD_LOAD_MUX_REG		0x00000021
-
-struct bcm4908_pinctrl {
+#define BCMBCA_TEST_PORT_BLOCK_EN_LSB			0x00
+#define BCMBCA_TEST_PORT_BLOCK_DATA_MSB			0x04
+#define BCMBCA_TEST_PORT_BLOCK_DATA_LSB			0x08
+#define  BCMBCA_TEST_PORT_LSB_PINMUX_DATA_SHIFT		12
+#define BCMBCA_TEST_PORT_COMMAND			0x0c
+#define  BCMBCA_TEST_PORT_CMD_LOAD_MUX_REG		0x00000021
+
+struct bcmbca_pinctrl {
 	struct device *dev;
 	void __iomem *base;
 	struct mutex mutex;
@@ -36,184 +36,184 @@ struct bcm4908_pinctrl {
  * Groups
  */
 
-struct bcm4908_pinctrl_pin_setup {
+struct bcmbca_pinctrl_pin_setup {
 	unsigned int number;
 	unsigned int function;
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_0_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_0_pins_a[] = {
 	{ 0, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_1_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_1_pins_a[] = {
 	{ 1, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_2_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_2_pins_a[] = {
 	{ 2, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_3_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_3_pins_a[] = {
 	{ 3, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_4_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_4_pins_a[] = {
 	{ 4, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_5_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_5_pins_a[] = {
 	{ 5, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_6_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_6_pins_a[] = {
 	{ 6, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_7_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_7_pins_a[] = {
 	{ 7, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_8_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_8_pins_a[] = {
 	{ 8, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_9_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_9_pins_a[] = {
 	{ 9, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_10_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_10_pins_a[] = {
 	{ 10, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_11_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_11_pins_a[] = {
 	{ 11, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_12_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_12_pins_a[] = {
 	{ 12, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_13_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_13_pins_a[] = {
 	{ 13, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_14_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_14_pins_a[] = {
 	{ 14, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_15_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_15_pins_a[] = {
 	{ 15, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_16_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_16_pins_a[] = {
 	{ 16, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_17_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_17_pins_a[] = {
 	{ 17, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_18_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_18_pins_a[] = {
 	{ 18, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_19_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_19_pins_a[] = {
 	{ 19, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_20_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_20_pins_a[] = {
 	{ 20, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_21_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_21_pins_a[] = {
 	{ 21, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_22_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_22_pins_a[] = {
 	{ 22, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_23_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_23_pins_a[] = {
 	{ 23, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_24_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_24_pins_a[] = {
 	{ 24, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_25_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_25_pins_a[] = {
 	{ 25, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_26_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_26_pins_a[] = {
 	{ 26, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_27_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_27_pins_a[] = {
 	{ 27, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_28_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_28_pins_a[] = {
 	{ 28, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_29_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_29_pins_a[] = {
 	{ 29, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_30_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_30_pins_a[] = {
 	{ 30, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_31_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup led_31_pins_a[] = {
 	{ 31, 3 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_10_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup led_10_pins_b[] = {
 	{ 8, 2 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_11_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup led_11_pins_b[] = {
 	{ 9, 2 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_12_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup led_12_pins_b[] = {
 	{ 0, 2 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_13_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup led_13_pins_b[] = {
 	{ 1, 2 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup led_31_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup led_31_pins_b[] = {
 	{ 30, 2 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup hs_uart_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup hs_uart_pins[] = {
 	{ 10, 0 },	/* CTS */
 	{ 11, 0 },	/* RTS */
 	{ 12, 0 },	/* RXD */
 	{ 13, 0 },	/* TXD */
 };
 
-static const struct bcm4908_pinctrl_pin_setup i2c_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup i2c_pins_a[] = {
 	{ 18, 0 },	/* SDA */
 	{ 19, 0 },	/* SCL */
 };
 
-static const struct bcm4908_pinctrl_pin_setup i2c_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup i2c_pins_b[] = {
 	{ 22, 0 },	/* SDA */
 	{ 23, 0 },	/* SCL */
 };
 
-static const struct bcm4908_pinctrl_pin_setup i2s_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup i2s_pins[] = {
 	{ 27, 0 },	/* MCLK */
 	{ 28, 0 },	/* LRCK */
 	{ 29, 0 },	/* SDATA */
 	{ 30, 0 },	/* SCLK */
 };
 
-static const struct bcm4908_pinctrl_pin_setup nand_ctrl_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup nand_ctrl_pins[] = {
 	{ 32, 0 },
 	{ 33, 0 },
 	{ 34, 0 },
@@ -223,7 +223,7 @@ static const struct bcm4908_pinctrl_pin_setup nand_ctrl_pins[] = {
 	{ 56, 1 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup nand_data_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup nand_data_pins[] = {
 	{ 35, 0 },
 	{ 36, 0 },
 	{ 37, 0 },
@@ -234,28 +234,28 @@ static const struct bcm4908_pinctrl_pin_setup nand_data_pins[] = {
 	{ 42, 0 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup emmc_ctrl_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup emmc_ctrl_pins[] = {
 	{ 46, 0 },
 	{ 47, 0 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup usb0_pwr_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup usb0_pwr_pins[] = {
 	{ 63, 0 },
 	{ 64, 0 },
 };
 
-static const struct bcm4908_pinctrl_pin_setup usb1_pwr_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup usb1_pwr_pins[] = {
 	{ 66, 0 },
 	{ 67, 0 },
 };
 
-struct bcm4908_pinctrl_grp {
+struct bcmbca_pinctrl_grp {
 	const char *name;
-	const struct bcm4908_pinctrl_pin_setup *pins;
+	const struct bcmbca_pinctrl_pin_setup *pins;
 	const unsigned int num_pins;
 };
 
-static const struct bcm4908_pinctrl_grp bcm4908_pinctrl_grps[] = {
+static const struct bcmbca_pinctrl_grp bcm4908_pinctrl_grps[] = {
 	{ "led_0_grp_a", led_0_pins_a, ARRAY_SIZE(led_0_pins_a) },
 	{ "led_1_grp_a", led_1_pins_a, ARRAY_SIZE(led_1_pins_a) },
 	{ "led_2_grp_a", led_2_pins_a, ARRAY_SIZE(led_2_pins_a) },
@@ -308,7 +308,7 @@ static const struct bcm4908_pinctrl_grp bcm4908_pinctrl_grps[] = {
  * Functions
  */
 
-struct bcm4908_pinctrl_function {
+struct bcmbca_pinctrl_function {
 	const char *name;
 	const char * const *groups;
 	const unsigned int num_groups;
@@ -355,7 +355,7 @@ static const char * const emmc_ctrl_groups[] = { "emmc_ctrl_grp" };
 static const char * const usb0_pwr_groups[] = { "usb0_pwr_grp" };
 static const char * const usb1_pwr_groups[] = { "usb1_pwr_grp" };
 
-static const struct bcm4908_pinctrl_function bcm4908_pinctrl_functions[] = {
+static const struct bcmbca_pinctrl_function bcm4908_pinctrl_functions[] = {
 	{ "led_0", led_0_groups, ARRAY_SIZE(led_0_groups) },
 	{ "led_1", led_1_groups, ARRAY_SIZE(led_1_groups) },
 	{ "led_2", led_2_groups, ARRAY_SIZE(led_2_groups) },
@@ -402,7 +402,7 @@ static const struct bcm4908_pinctrl_function bcm4908_pinctrl_functions[] = {
  * Groups code
  */
 
-static const struct pinctrl_ops bcm4908_pinctrl_ops = {
+static const struct pinctrl_ops bcmbca_pinctrl_ops = {
 	.get_groups_count = pinctrl_generic_get_group_count,
 	.get_group_name = pinctrl_generic_get_group_name,
 	.get_group_pins = pinctrl_generic_get_group_pins,
@@ -414,12 +414,12 @@ static const struct pinctrl_ops bcm4908_pinctrl_ops = {
  * Functions code
  */
 
-static int bcm4908_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
+static int bcmbca_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
 			      unsigned int func_selector,
 			      unsigned int group_selector)
 {
-	struct bcm4908_pinctrl *bcm4908_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
-	const struct bcm4908_pinctrl_grp *group;
+	struct bcmbca_pinctrl *bcmbca_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+	const struct bcmbca_pinctrl_grp *group;
 	struct group_desc *group_desc;
 	int i;
 
@@ -428,71 +428,71 @@ static int bcm4908_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
 		return -EINVAL;
 	group = group_desc->data;
 
-	mutex_lock(&bcm4908_pinctrl->mutex);
+	mutex_lock(&bcmbca_pinctrl->mutex);
 	for (i = 0; i < group->num_pins; i++) {
 		u32 lsb = 0;
 
 		lsb |= group->pins[i].number;
-		lsb |= group->pins[i].function << BCM4908_TEST_PORT_LSB_PINMUX_DATA_SHIFT;
+		lsb |= group->pins[i].function << BCMBCA_TEST_PORT_LSB_PINMUX_DATA_SHIFT;
 
-		writel(0x0, bcm4908_pinctrl->base + BCM4908_TEST_PORT_BLOCK_DATA_MSB);
-		writel(lsb, bcm4908_pinctrl->base + BCM4908_TEST_PORT_BLOCK_DATA_LSB);
-		writel(BCM4908_TEST_PORT_CMD_LOAD_MUX_REG,
-		       bcm4908_pinctrl->base + BCM4908_TEST_PORT_COMMAND);
+		writel(0x0, bcmbca_pinctrl->base + BCMBCA_TEST_PORT_BLOCK_DATA_MSB);
+		writel(lsb, bcmbca_pinctrl->base + BCMBCA_TEST_PORT_BLOCK_DATA_LSB);
+		writel(BCMBCA_TEST_PORT_CMD_LOAD_MUX_REG,
+		       bcmbca_pinctrl->base + BCMBCA_TEST_PORT_COMMAND);
 	}
-	mutex_unlock(&bcm4908_pinctrl->mutex);
+	mutex_unlock(&bcmbca_pinctrl->mutex);
 
 	return 0;
 }
 
-static const struct pinmux_ops bcm4908_pinctrl_pmxops = {
+static const struct pinmux_ops bcmbca_pinctrl_pmxops = {
 	.get_functions_count = pinmux_generic_get_function_count,
 	.get_function_name = pinmux_generic_get_function_name,
 	.get_function_groups = pinmux_generic_get_function_groups,
-	.set_mux = bcm4908_pinctrl_set_mux,
+	.set_mux = bcmbca_pinctrl_set_mux,
 };
 
 /*
  * Controller code
  */
 
-static const struct pinctrl_desc bcm4908_pinctrl_desc = {
-	.name = "bcm4908-pinctrl",
-	.pctlops = &bcm4908_pinctrl_ops,
-	.pmxops = &bcm4908_pinctrl_pmxops,
+static const struct pinctrl_desc bcmbca_pinctrl_desc = {
+	.name = "bcmbca-pinctrl",
+	.pctlops = &bcmbca_pinctrl_ops,
+	.pmxops = &bcmbca_pinctrl_pmxops,
 };
 
-static const struct of_device_id bcm4908_pinctrl_of_match_table[] = {
+static const struct of_device_id bcmbca_pinctrl_of_match_table[] = {
 	{ .compatible = "brcm,bcm4908-pinctrl", },
 	{ }
 };
 
-static int bcm4908_pinctrl_probe(struct platform_device *pdev)
+static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct bcm4908_pinctrl *bcm4908_pinctrl;
+	struct bcmbca_pinctrl *bcmbca_pinctrl;
 	struct pinctrl_desc *pctldesc;
 	struct pinctrl_pin_desc *pins;
 	char **pin_names;
 	int i;
 
-	bcm4908_pinctrl = devm_kzalloc(dev, sizeof(*bcm4908_pinctrl), GFP_KERNEL);
-	if (!bcm4908_pinctrl)
+	bcmbca_pinctrl = devm_kzalloc(dev, sizeof(*bcmbca_pinctrl), GFP_KERNEL);
+	if (!bcmbca_pinctrl)
 		return -ENOMEM;
-	pctldesc = &bcm4908_pinctrl->pctldesc;
-	platform_set_drvdata(pdev, bcm4908_pinctrl);
+	pctldesc = &bcmbca_pinctrl->pctldesc;
+	platform_set_drvdata(pdev, bcmbca_pinctrl);
 
 	/* Set basic properties */
 
-	bcm4908_pinctrl->dev = dev;
+	bcmbca_pinctrl->dev = dev;
 
-	bcm4908_pinctrl->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(bcm4908_pinctrl->base))
-		return PTR_ERR(bcm4908_pinctrl->base);
+	bcmbca_pinctrl->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(bcmbca_pinctrl->base))
+		return PTR_ERR(bcmbca_pinctrl->base);
 
-	mutex_init(&bcm4908_pinctrl->mutex);
+	mutex_init(&bcmbca_pinctrl->mutex);
 
-	memcpy(pctldesc, &bcm4908_pinctrl_desc, sizeof(*pctldesc));
+	memcpy(pctldesc, &bcmbca_pinctrl_desc, sizeof(*pctldesc));
 
 	/* Set pinctrl properties */
 
@@ -512,15 +512,15 @@ static int bcm4908_pinctrl_probe(struct platform_device *pdev)
 
 	/* Register */
 
-	bcm4908_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, bcm4908_pinctrl);
-	if (IS_ERR(bcm4908_pinctrl->pctldev))
-		return dev_err_probe(dev, PTR_ERR(bcm4908_pinctrl->pctldev),
+	bcmbca_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, bcmbca_pinctrl);
+	if (IS_ERR(bcmbca_pinctrl->pctldev))
+		return dev_err_probe(dev, PTR_ERR(bcmbca_pinctrl->pctldev),
 				     "Failed to register pinctrl\n");
 
 	/* Groups */
 
 	for (i = 0; i < ARRAY_SIZE(bcm4908_pinctrl_grps); i++) {
-		const struct bcm4908_pinctrl_grp *group = &bcm4908_pinctrl_grps[i];
+		const struct bcmbca_pinctrl_grp *group = &bcm4908_pinctrl_grps[i];
 		int *pins;
 		int j;
 
@@ -530,16 +530,16 @@ static int bcm4908_pinctrl_probe(struct platform_device *pdev)
 		for (j = 0; j < group->num_pins; j++)
 			pins[j] = group->pins[j].number;
 
-		pinctrl_generic_add_group(bcm4908_pinctrl->pctldev, group->name,
+		pinctrl_generic_add_group(bcmbca_pinctrl->pctldev, group->name,
 					  pins, group->num_pins, (void *)group);
 	}
 
 	/* Functions */
 
 	for (i = 0; i < ARRAY_SIZE(bcm4908_pinctrl_functions); i++) {
-		const struct bcm4908_pinctrl_function *function = &bcm4908_pinctrl_functions[i];
+		const struct bcmbca_pinctrl_function *function = &bcm4908_pinctrl_functions[i];
 
-		pinmux_generic_add_function(bcm4908_pinctrl->pctldev,
+		pinmux_generic_add_function(bcmbca_pinctrl->pctldev,
 					    function->name,
 					    function->groups,
 					    function->num_groups, NULL);
@@ -548,17 +548,17 @@ static int bcm4908_pinctrl_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver bcm4908_pinctrl_driver = {
-	.probe = bcm4908_pinctrl_probe,
+static struct platform_driver bcmbca_pinctrl_driver = {
+	.probe = bcmbca_pinctrl_probe,
 	.driver = {
-		.name = "bcm4908-pinctrl",
-		.of_match_table = bcm4908_pinctrl_of_match_table,
+		.name = "bcmbca-pinctrl",
+		.of_match_table = bcmbca_pinctrl_of_match_table,
 	},
 };
 
-module_platform_driver(bcm4908_pinctrl_driver);
+module_platform_driver(bcmbca_pinctrl_driver);
 
 MODULE_AUTHOR("Rafał Miłecki");
-MODULE_DESCRIPTION("Broadcom BCM4908 pinmux driver");
+MODULE_DESCRIPTION("Broadcom BCMBCA pinmux driver");
 MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, bcm4908_pinctrl_of_match_table);
+MODULE_DEVICE_TABLE(of, bcmbca_pinctrl_of_match_table);

-- 
2.51.0


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

* [PATCH 2/6] pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
  2025-09-30 12:02 ` [PATCH 1/6] pinctrl: bcm: Rename bcm4908 to bcmbca Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-09-30 12:02 ` [PATCH 3/6] pinctrl: bcm: bcmbca: Prefix all BCM4908 data Linus Walleij
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

This will make all pins, groups and functions depend of data
associated with the compatible string that is matched on
probe.

This makes it possible to add support for other BCMBCA SoC:s
than BCM4908.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/bcm/pinctrl-bcmbca.c | 67 +++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcmbca.c b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
index 834241103b5452836aea9fe817f7e5d143893985..5a18a5fadd94ddb5f237f2dca560f1d4b8186dad 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcmbca.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
@@ -9,6 +9,7 @@
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/string_helpers.h>
 
@@ -24,6 +25,26 @@
 #define BCMBCA_TEST_PORT_COMMAND			0x0c
 #define  BCMBCA_TEST_PORT_CMD_LOAD_MUX_REG		0x00000021
 
+struct bcmbca_pinctrl_grp {
+	const char *name;
+	const struct bcmbca_pinctrl_pin_setup *pins;
+	const unsigned int num_pins;
+};
+
+struct bcmbca_pinctrl_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned int num_groups;
+};
+
+struct bcmbca_soc_info {
+	unsigned int num_pins;
+	const struct bcmbca_pinctrl_grp *groups;
+	unsigned int num_groups;
+	const struct bcmbca_pinctrl_function *functions;
+	unsigned int num_functions;
+};
+
 struct bcmbca_pinctrl {
 	struct device *dev;
 	void __iomem *base;
@@ -249,12 +270,6 @@ static const struct bcmbca_pinctrl_pin_setup usb1_pwr_pins[] = {
 	{ 67, 0 },
 };
 
-struct bcmbca_pinctrl_grp {
-	const char *name;
-	const struct bcmbca_pinctrl_pin_setup *pins;
-	const unsigned int num_pins;
-};
-
 static const struct bcmbca_pinctrl_grp bcm4908_pinctrl_grps[] = {
 	{ "led_0_grp_a", led_0_pins_a, ARRAY_SIZE(led_0_pins_a) },
 	{ "led_1_grp_a", led_1_pins_a, ARRAY_SIZE(led_1_pins_a) },
@@ -308,12 +323,6 @@ static const struct bcmbca_pinctrl_grp bcm4908_pinctrl_grps[] = {
  * Functions
  */
 
-struct bcmbca_pinctrl_function {
-	const char *name;
-	const char * const *groups;
-	const unsigned int num_groups;
-};
-
 static const char * const led_0_groups[] = { "led_0_grp_a" };
 static const char * const led_1_groups[] = { "led_1_grp_a" };
 static const char * const led_2_groups[] = { "led_2_grp_a" };
@@ -462,13 +471,25 @@ static const struct pinctrl_desc bcmbca_pinctrl_desc = {
 	.pmxops = &bcmbca_pinctrl_pmxops,
 };
 
+static const struct bcmbca_soc_info bcm4908_pinctrl_soc_info = {
+	.num_pins = BCM4908_NUM_PINS,
+	.groups = bcm4908_pinctrl_grps,
+	.num_groups = ARRAY_SIZE(bcm4908_pinctrl_grps),
+	.functions = bcm4908_pinctrl_functions,
+	.num_functions = ARRAY_SIZE(bcm4908_pinctrl_functions),
+};
+
 static const struct of_device_id bcmbca_pinctrl_of_match_table[] = {
-	{ .compatible = "brcm,bcm4908-pinctrl", },
+	{
+		.compatible = "brcm,bcm4908-pinctrl",
+		.data = &bcm4908_pinctrl_soc_info,
+	},
 	{ }
 };
 
 static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 {
+	const struct bcmbca_soc_info *info;
 	struct device *dev = &pdev->dev;
 	struct bcmbca_pinctrl *bcmbca_pinctrl;
 	struct pinctrl_desc *pctldesc;
@@ -476,6 +497,10 @@ static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 	char **pin_names;
 	int i;
 
+	info = device_get_match_data(dev);
+	if (!info)
+		return dev_err_probe(dev, -EINVAL, "No match data\n");
+
 	bcmbca_pinctrl = devm_kzalloc(dev, sizeof(*bcmbca_pinctrl), GFP_KERNEL);
 	if (!bcmbca_pinctrl)
 		return -ENOMEM;
@@ -496,19 +521,19 @@ static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 
 	/* Set pinctrl properties */
 
-	pin_names = devm_kasprintf_strarray(dev, "pin", BCM4908_NUM_PINS);
+	pin_names = devm_kasprintf_strarray(dev, "pin", info->num_pins);
 	if (IS_ERR(pin_names))
 		return PTR_ERR(pin_names);
 
-	pins = devm_kcalloc(dev, BCM4908_NUM_PINS, sizeof(*pins), GFP_KERNEL);
+	pins = devm_kcalloc(dev, info->num_pins, sizeof(*pins), GFP_KERNEL);
 	if (!pins)
 		return -ENOMEM;
-	for (i = 0; i < BCM4908_NUM_PINS; i++) {
+	for (i = 0; i < info->num_pins; i++) {
 		pins[i].number = i;
 		pins[i].name = pin_names[i];
 	}
 	pctldesc->pins = pins;
-	pctldesc->npins = BCM4908_NUM_PINS;
+	pctldesc->npins = info->num_pins;
 
 	/* Register */
 
@@ -519,8 +544,8 @@ static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 
 	/* Groups */
 
-	for (i = 0; i < ARRAY_SIZE(bcm4908_pinctrl_grps); i++) {
-		const struct bcmbca_pinctrl_grp *group = &bcm4908_pinctrl_grps[i];
+	for (i = 0; i < info->num_groups; i++) {
+		const struct bcmbca_pinctrl_grp *group = &info->groups[i];
 		int *pins;
 		int j;
 
@@ -536,8 +561,8 @@ static int bcmbca_pinctrl_probe(struct platform_device *pdev)
 
 	/* Functions */
 
-	for (i = 0; i < ARRAY_SIZE(bcm4908_pinctrl_functions); i++) {
-		const struct bcmbca_pinctrl_function *function = &bcm4908_pinctrl_functions[i];
+	for (i = 0; i < info->num_functions; i++) {
+		const struct bcmbca_pinctrl_function *function = &info->functions[i];
 
 		pinmux_generic_add_function(bcmbca_pinctrl->pctldev,
 					    function->name,

-- 
2.51.0


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

* [PATCH 3/6] pinctrl: bcm: bcmbca: Prefix all BCM4908 data
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
  2025-09-30 12:02 ` [PATCH 1/6] pinctrl: bcm: Rename bcm4908 to bcmbca Linus Walleij
  2025-09-30 12:02 ` [PATCH 2/6] pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-09-30 12:02 ` [PATCH 4/6] pinctrl: bcm: bcmbca: Use a guarded mutex Linus Walleij
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

Prefix all the BCM4908 groups and functions with bcm4908_*
and move the SoC info together with the pins, groups and
functions.

This is needed to namespace the different BCMBCA SoC:s
we add to this driver.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/bcm/pinctrl-bcmbca.c | 378 +++++++++++++++++------------------
 1 file changed, 186 insertions(+), 192 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcmbca.c b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
index 5a18a5fadd94ddb5f237f2dca560f1d4b8186dad..b7b2552fd48227b2d318bb37f81a58e03656b954 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcmbca.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
@@ -16,8 +16,6 @@
 #include "../core.h"
 #include "../pinmux.h"
 
-#define BCM4908_NUM_PINS			86
-
 #define BCMBCA_TEST_PORT_BLOCK_EN_LSB			0x00
 #define BCMBCA_TEST_PORT_BLOCK_DATA_MSB			0x04
 #define BCMBCA_TEST_PORT_BLOCK_DATA_LSB			0x08
@@ -53,188 +51,188 @@ struct bcmbca_pinctrl {
 	struct pinctrl_desc pctldesc;
 };
 
-/*
- * Groups
- */
-
 struct bcmbca_pinctrl_pin_setup {
 	unsigned int number;
 	unsigned int function;
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_0_pins_a[] = {
+/* BCM4908 groups and functions */
+
+#define BCM4908_NUM_PINS 86
+
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_0_pins_a[] = {
 	{ 0, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_1_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_1_pins_a[] = {
 	{ 1, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_2_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_2_pins_a[] = {
 	{ 2, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_3_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_3_pins_a[] = {
 	{ 3, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_4_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_4_pins_a[] = {
 	{ 4, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_5_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_5_pins_a[] = {
 	{ 5, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_6_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_6_pins_a[] = {
 	{ 6, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_7_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_7_pins_a[] = {
 	{ 7, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_8_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_8_pins_a[] = {
 	{ 8, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_9_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_9_pins_a[] = {
 	{ 9, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_10_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_10_pins_a[] = {
 	{ 10, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_11_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_11_pins_a[] = {
 	{ 11, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_12_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_12_pins_a[] = {
 	{ 12, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_13_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_13_pins_a[] = {
 	{ 13, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_14_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_14_pins_a[] = {
 	{ 14, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_15_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_15_pins_a[] = {
 	{ 15, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_16_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_16_pins_a[] = {
 	{ 16, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_17_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_17_pins_a[] = {
 	{ 17, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_18_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_18_pins_a[] = {
 	{ 18, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_19_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_19_pins_a[] = {
 	{ 19, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_20_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_20_pins_a[] = {
 	{ 20, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_21_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_21_pins_a[] = {
 	{ 21, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_22_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_22_pins_a[] = {
 	{ 22, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_23_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_23_pins_a[] = {
 	{ 23, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_24_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_24_pins_a[] = {
 	{ 24, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_25_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_25_pins_a[] = {
 	{ 25, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_26_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_26_pins_a[] = {
 	{ 26, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_27_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_27_pins_a[] = {
 	{ 27, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_28_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_28_pins_a[] = {
 	{ 28, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_29_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_29_pins_a[] = {
 	{ 29, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_30_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_30_pins_a[] = {
 	{ 30, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_31_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_31_pins_a[] = {
 	{ 31, 3 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_10_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_10_pins_b[] = {
 	{ 8, 2 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_11_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_11_pins_b[] = {
 	{ 9, 2 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_12_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_12_pins_b[] = {
 	{ 0, 2 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_13_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_13_pins_b[] = {
 	{ 1, 2 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup led_31_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_led_31_pins_b[] = {
 	{ 30, 2 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup hs_uart_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_hs_uart_pins[] = {
 	{ 10, 0 },	/* CTS */
 	{ 11, 0 },	/* RTS */
 	{ 12, 0 },	/* RXD */
 	{ 13, 0 },	/* TXD */
 };
 
-static const struct bcmbca_pinctrl_pin_setup i2c_pins_a[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_i2c_pins_a[] = {
 	{ 18, 0 },	/* SDA */
 	{ 19, 0 },	/* SCL */
 };
 
-static const struct bcmbca_pinctrl_pin_setup i2c_pins_b[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_i2c_pins_b[] = {
 	{ 22, 0 },	/* SDA */
 	{ 23, 0 },	/* SCL */
 };
 
-static const struct bcmbca_pinctrl_pin_setup i2s_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_i2s_pins[] = {
 	{ 27, 0 },	/* MCLK */
 	{ 28, 0 },	/* LRCK */
 	{ 29, 0 },	/* SDATA */
 	{ 30, 0 },	/* SCLK */
 };
 
-static const struct bcmbca_pinctrl_pin_setup nand_ctrl_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_nand_ctrl_pins[] = {
 	{ 32, 0 },
 	{ 33, 0 },
 	{ 34, 0 },
@@ -244,7 +242,7 @@ static const struct bcmbca_pinctrl_pin_setup nand_ctrl_pins[] = {
 	{ 56, 1 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup nand_data_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_nand_data_pins[] = {
 	{ 35, 0 },
 	{ 36, 0 },
 	{ 37, 0 },
@@ -255,156 +253,160 @@ static const struct bcmbca_pinctrl_pin_setup nand_data_pins[] = {
 	{ 42, 0 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup emmc_ctrl_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_emmc_ctrl_pins[] = {
 	{ 46, 0 },
 	{ 47, 0 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup usb0_pwr_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_usb0_pwr_pins[] = {
 	{ 63, 0 },
 	{ 64, 0 },
 };
 
-static const struct bcmbca_pinctrl_pin_setup usb1_pwr_pins[] = {
+static const struct bcmbca_pinctrl_pin_setup bcm4908_usb1_pwr_pins[] = {
 	{ 66, 0 },
 	{ 67, 0 },
 };
 
 static const struct bcmbca_pinctrl_grp bcm4908_pinctrl_grps[] = {
-	{ "led_0_grp_a", led_0_pins_a, ARRAY_SIZE(led_0_pins_a) },
-	{ "led_1_grp_a", led_1_pins_a, ARRAY_SIZE(led_1_pins_a) },
-	{ "led_2_grp_a", led_2_pins_a, ARRAY_SIZE(led_2_pins_a) },
-	{ "led_3_grp_a", led_3_pins_a, ARRAY_SIZE(led_3_pins_a) },
-	{ "led_4_grp_a", led_4_pins_a, ARRAY_SIZE(led_4_pins_a) },
-	{ "led_5_grp_a", led_5_pins_a, ARRAY_SIZE(led_5_pins_a) },
-	{ "led_6_grp_a", led_6_pins_a, ARRAY_SIZE(led_6_pins_a) },
-	{ "led_7_grp_a", led_7_pins_a, ARRAY_SIZE(led_7_pins_a) },
-	{ "led_8_grp_a", led_8_pins_a, ARRAY_SIZE(led_8_pins_a) },
-	{ "led_9_grp_a", led_9_pins_a, ARRAY_SIZE(led_9_pins_a) },
-	{ "led_10_grp_a", led_10_pins_a, ARRAY_SIZE(led_10_pins_a) },
-	{ "led_11_grp_a", led_11_pins_a, ARRAY_SIZE(led_11_pins_a) },
-	{ "led_12_grp_a", led_12_pins_a, ARRAY_SIZE(led_12_pins_a) },
-	{ "led_13_grp_a", led_13_pins_a, ARRAY_SIZE(led_13_pins_a) },
-	{ "led_14_grp_a", led_14_pins_a, ARRAY_SIZE(led_14_pins_a) },
-	{ "led_15_grp_a", led_15_pins_a, ARRAY_SIZE(led_15_pins_a) },
-	{ "led_16_grp_a", led_16_pins_a, ARRAY_SIZE(led_16_pins_a) },
-	{ "led_17_grp_a", led_17_pins_a, ARRAY_SIZE(led_17_pins_a) },
-	{ "led_18_grp_a", led_18_pins_a, ARRAY_SIZE(led_18_pins_a) },
-	{ "led_19_grp_a", led_19_pins_a, ARRAY_SIZE(led_19_pins_a) },
-	{ "led_20_grp_a", led_20_pins_a, ARRAY_SIZE(led_20_pins_a) },
-	{ "led_21_grp_a", led_21_pins_a, ARRAY_SIZE(led_21_pins_a) },
-	{ "led_22_grp_a", led_22_pins_a, ARRAY_SIZE(led_22_pins_a) },
-	{ "led_23_grp_a", led_23_pins_a, ARRAY_SIZE(led_23_pins_a) },
-	{ "led_24_grp_a", led_24_pins_a, ARRAY_SIZE(led_24_pins_a) },
-	{ "led_25_grp_a", led_25_pins_a, ARRAY_SIZE(led_25_pins_a) },
-	{ "led_26_grp_a", led_26_pins_a, ARRAY_SIZE(led_26_pins_a) },
-	{ "led_27_grp_a", led_27_pins_a, ARRAY_SIZE(led_27_pins_a) },
-	{ "led_28_grp_a", led_28_pins_a, ARRAY_SIZE(led_28_pins_a) },
-	{ "led_29_grp_a", led_29_pins_a, ARRAY_SIZE(led_29_pins_a) },
-	{ "led_30_grp_a", led_30_pins_a, ARRAY_SIZE(led_30_pins_a) },
-	{ "led_31_grp_a", led_31_pins_a, ARRAY_SIZE(led_31_pins_a) },
-	{ "led_10_grp_b", led_10_pins_b, ARRAY_SIZE(led_10_pins_b) },
-	{ "led_11_grp_b", led_11_pins_b, ARRAY_SIZE(led_11_pins_b) },
-	{ "led_12_grp_b", led_12_pins_b, ARRAY_SIZE(led_12_pins_b) },
-	{ "led_13_grp_b", led_13_pins_b, ARRAY_SIZE(led_13_pins_b) },
-	{ "led_31_grp_b", led_31_pins_b, ARRAY_SIZE(led_31_pins_b) },
-	{ "hs_uart_grp", hs_uart_pins, ARRAY_SIZE(hs_uart_pins) },
-	{ "i2c_grp_a", i2c_pins_a, ARRAY_SIZE(i2c_pins_a) },
-	{ "i2c_grp_b", i2c_pins_b, ARRAY_SIZE(i2c_pins_b) },
-	{ "i2s_grp", i2s_pins, ARRAY_SIZE(i2s_pins) },
-	{ "nand_ctrl_grp", nand_ctrl_pins, ARRAY_SIZE(nand_ctrl_pins) },
-	{ "nand_data_grp", nand_data_pins, ARRAY_SIZE(nand_data_pins) },
-	{ "emmc_ctrl_grp", emmc_ctrl_pins, ARRAY_SIZE(emmc_ctrl_pins) },
-	{ "usb0_pwr_grp", usb0_pwr_pins, ARRAY_SIZE(usb0_pwr_pins) },
-	{ "usb1_pwr_grp", usb1_pwr_pins, ARRAY_SIZE(usb1_pwr_pins) },
-};
-
-/*
- * Functions
- */
-
-static const char * const led_0_groups[] = { "led_0_grp_a" };
-static const char * const led_1_groups[] = { "led_1_grp_a" };
-static const char * const led_2_groups[] = { "led_2_grp_a" };
-static const char * const led_3_groups[] = { "led_3_grp_a" };
-static const char * const led_4_groups[] = { "led_4_grp_a" };
-static const char * const led_5_groups[] = { "led_5_grp_a" };
-static const char * const led_6_groups[] = { "led_6_grp_a" };
-static const char * const led_7_groups[] = { "led_7_grp_a" };
-static const char * const led_8_groups[] = { "led_8_grp_a" };
-static const char * const led_9_groups[] = { "led_9_grp_a" };
-static const char * const led_10_groups[] = { "led_10_grp_a", "led_10_grp_b" };
-static const char * const led_11_groups[] = { "led_11_grp_a", "led_11_grp_b" };
-static const char * const led_12_groups[] = { "led_12_grp_a", "led_12_grp_b" };
-static const char * const led_13_groups[] = { "led_13_grp_a", "led_13_grp_b" };
-static const char * const led_14_groups[] = { "led_14_grp_a" };
-static const char * const led_15_groups[] = { "led_15_grp_a" };
-static const char * const led_16_groups[] = { "led_16_grp_a" };
-static const char * const led_17_groups[] = { "led_17_grp_a" };
-static const char * const led_18_groups[] = { "led_18_grp_a" };
-static const char * const led_19_groups[] = { "led_19_grp_a" };
-static const char * const led_20_groups[] = { "led_20_grp_a" };
-static const char * const led_21_groups[] = { "led_21_grp_a" };
-static const char * const led_22_groups[] = { "led_22_grp_a" };
-static const char * const led_23_groups[] = { "led_23_grp_a" };
-static const char * const led_24_groups[] = { "led_24_grp_a" };
-static const char * const led_25_groups[] = { "led_25_grp_a" };
-static const char * const led_26_groups[] = { "led_26_grp_a" };
-static const char * const led_27_groups[] = { "led_27_grp_a" };
-static const char * const led_28_groups[] = { "led_28_grp_a" };
-static const char * const led_29_groups[] = { "led_29_grp_a" };
-static const char * const led_30_groups[] = { "led_30_grp_a" };
-static const char * const led_31_groups[] = { "led_31_grp_a", "led_31_grp_b" };
-static const char * const hs_uart_groups[] = { "hs_uart_grp" };
-static const char * const i2c_groups[] = { "i2c_grp_a", "i2c_grp_b" };
-static const char * const i2s_groups[] = { "i2s_grp" };
-static const char * const nand_ctrl_groups[] = { "nand_ctrl_grp" };
-static const char * const nand_data_groups[] = { "nand_data_grp" };
-static const char * const emmc_ctrl_groups[] = { "emmc_ctrl_grp" };
-static const char * const usb0_pwr_groups[] = { "usb0_pwr_grp" };
-static const char * const usb1_pwr_groups[] = { "usb1_pwr_grp" };
+	{ "led_0_grp_a", bcm4908_led_0_pins_a, ARRAY_SIZE(bcm4908_led_0_pins_a) },
+	{ "led_1_grp_a", bcm4908_led_1_pins_a, ARRAY_SIZE(bcm4908_led_1_pins_a) },
+	{ "led_2_grp_a", bcm4908_led_2_pins_a, ARRAY_SIZE(bcm4908_led_2_pins_a) },
+	{ "led_3_grp_a", bcm4908_led_3_pins_a, ARRAY_SIZE(bcm4908_led_3_pins_a) },
+	{ "led_4_grp_a", bcm4908_led_4_pins_a, ARRAY_SIZE(bcm4908_led_4_pins_a) },
+	{ "led_5_grp_a", bcm4908_led_5_pins_a, ARRAY_SIZE(bcm4908_led_5_pins_a) },
+	{ "led_6_grp_a", bcm4908_led_6_pins_a, ARRAY_SIZE(bcm4908_led_6_pins_a) },
+	{ "led_7_grp_a", bcm4908_led_7_pins_a, ARRAY_SIZE(bcm4908_led_7_pins_a) },
+	{ "led_8_grp_a", bcm4908_led_8_pins_a, ARRAY_SIZE(bcm4908_led_8_pins_a) },
+	{ "led_9_grp_a", bcm4908_led_9_pins_a, ARRAY_SIZE(bcm4908_led_9_pins_a) },
+	{ "led_10_grp_a", bcm4908_led_10_pins_a, ARRAY_SIZE(bcm4908_led_10_pins_a) },
+	{ "led_11_grp_a", bcm4908_led_11_pins_a, ARRAY_SIZE(bcm4908_led_11_pins_a) },
+	{ "led_12_grp_a", bcm4908_led_12_pins_a, ARRAY_SIZE(bcm4908_led_12_pins_a) },
+	{ "led_13_grp_a", bcm4908_led_13_pins_a, ARRAY_SIZE(bcm4908_led_13_pins_a) },
+	{ "led_14_grp_a", bcm4908_led_14_pins_a, ARRAY_SIZE(bcm4908_led_14_pins_a) },
+	{ "led_15_grp_a", bcm4908_led_15_pins_a, ARRAY_SIZE(bcm4908_led_15_pins_a) },
+	{ "led_16_grp_a", bcm4908_led_16_pins_a, ARRAY_SIZE(bcm4908_led_16_pins_a) },
+	{ "led_17_grp_a", bcm4908_led_17_pins_a, ARRAY_SIZE(bcm4908_led_17_pins_a) },
+	{ "led_18_grp_a", bcm4908_led_18_pins_a, ARRAY_SIZE(bcm4908_led_18_pins_a) },
+	{ "led_19_grp_a", bcm4908_led_19_pins_a, ARRAY_SIZE(bcm4908_led_19_pins_a) },
+	{ "led_20_grp_a", bcm4908_led_20_pins_a, ARRAY_SIZE(bcm4908_led_20_pins_a) },
+	{ "led_21_grp_a", bcm4908_led_21_pins_a, ARRAY_SIZE(bcm4908_led_21_pins_a) },
+	{ "led_22_grp_a", bcm4908_led_22_pins_a, ARRAY_SIZE(bcm4908_led_22_pins_a) },
+	{ "led_23_grp_a", bcm4908_led_23_pins_a, ARRAY_SIZE(bcm4908_led_23_pins_a) },
+	{ "led_24_grp_a", bcm4908_led_24_pins_a, ARRAY_SIZE(bcm4908_led_24_pins_a) },
+	{ "led_25_grp_a", bcm4908_led_25_pins_a, ARRAY_SIZE(bcm4908_led_25_pins_a) },
+	{ "led_26_grp_a", bcm4908_led_26_pins_a, ARRAY_SIZE(bcm4908_led_26_pins_a) },
+	{ "led_27_grp_a", bcm4908_led_27_pins_a, ARRAY_SIZE(bcm4908_led_27_pins_a) },
+	{ "led_28_grp_a", bcm4908_led_28_pins_a, ARRAY_SIZE(bcm4908_led_28_pins_a) },
+	{ "led_29_grp_a", bcm4908_led_29_pins_a, ARRAY_SIZE(bcm4908_led_29_pins_a) },
+	{ "led_30_grp_a", bcm4908_led_30_pins_a, ARRAY_SIZE(bcm4908_led_30_pins_a) },
+	{ "led_31_grp_a", bcm4908_led_31_pins_a, ARRAY_SIZE(bcm4908_led_31_pins_a) },
+	{ "led_10_grp_b", bcm4908_led_10_pins_b, ARRAY_SIZE(bcm4908_led_10_pins_b) },
+	{ "led_11_grp_b", bcm4908_led_11_pins_b, ARRAY_SIZE(bcm4908_led_11_pins_b) },
+	{ "led_12_grp_b", bcm4908_led_12_pins_b, ARRAY_SIZE(bcm4908_led_12_pins_b) },
+	{ "led_13_grp_b", bcm4908_led_13_pins_b, ARRAY_SIZE(bcm4908_led_13_pins_b) },
+	{ "led_31_grp_b", bcm4908_led_31_pins_b, ARRAY_SIZE(bcm4908_led_31_pins_b) },
+	{ "hs_uart_grp", bcm4908_hs_uart_pins, ARRAY_SIZE(bcm4908_hs_uart_pins) },
+	{ "i2c_grp_a", bcm4908_i2c_pins_a, ARRAY_SIZE(bcm4908_i2c_pins_a) },
+	{ "i2c_grp_b", bcm4908_i2c_pins_b, ARRAY_SIZE(bcm4908_i2c_pins_b) },
+	{ "i2s_grp", bcm4908_i2s_pins, ARRAY_SIZE(bcm4908_i2s_pins) },
+	{ "nand_ctrl_grp", bcm4908_nand_ctrl_pins, ARRAY_SIZE(bcm4908_nand_ctrl_pins) },
+	{ "nand_data_grp", bcm4908_nand_data_pins, ARRAY_SIZE(bcm4908_nand_data_pins) },
+	{ "emmc_ctrl_grp", bcm4908_emmc_ctrl_pins, ARRAY_SIZE(bcm4908_emmc_ctrl_pins) },
+	{ "usb0_pwr_grp", bcm4908_usb0_pwr_pins, ARRAY_SIZE(bcm4908_usb0_pwr_pins) },
+	{ "usb1_pwr_grp", bcm4908_usb1_pwr_pins, ARRAY_SIZE(bcm4908_usb1_pwr_pins) },
+};
+
+static const char * const bcm4908_led_0_groups[] = { "led_0_grp_a" };
+static const char * const bcm4908_led_1_groups[] = { "led_1_grp_a" };
+static const char * const bcm4908_led_2_groups[] = { "led_2_grp_a" };
+static const char * const bcm4908_led_3_groups[] = { "led_3_grp_a" };
+static const char * const bcm4908_led_4_groups[] = { "led_4_grp_a" };
+static const char * const bcm4908_led_5_groups[] = { "led_5_grp_a" };
+static const char * const bcm4908_led_6_groups[] = { "led_6_grp_a" };
+static const char * const bcm4908_led_7_groups[] = { "led_7_grp_a" };
+static const char * const bcm4908_led_8_groups[] = { "led_8_grp_a" };
+static const char * const bcm4908_led_9_groups[] = { "led_9_grp_a" };
+static const char * const bcm4908_led_10_groups[] = { "led_10_grp_a", "led_10_grp_b" };
+static const char * const bcm4908_led_11_groups[] = { "led_11_grp_a", "led_11_grp_b" };
+static const char * const bcm4908_led_12_groups[] = { "led_12_grp_a", "led_12_grp_b" };
+static const char * const bcm4908_led_13_groups[] = { "led_13_grp_a", "led_13_grp_b" };
+static const char * const bcm4908_led_14_groups[] = { "led_14_grp_a" };
+static const char * const bcm4908_led_15_groups[] = { "led_15_grp_a" };
+static const char * const bcm4908_led_16_groups[] = { "led_16_grp_a" };
+static const char * const bcm4908_led_17_groups[] = { "led_17_grp_a" };
+static const char * const bcm4908_led_18_groups[] = { "led_18_grp_a" };
+static const char * const bcm4908_led_19_groups[] = { "led_19_grp_a" };
+static const char * const bcm4908_led_20_groups[] = { "led_20_grp_a" };
+static const char * const bcm4908_led_21_groups[] = { "led_21_grp_a" };
+static const char * const bcm4908_led_22_groups[] = { "led_22_grp_a" };
+static const char * const bcm4908_led_23_groups[] = { "led_23_grp_a" };
+static const char * const bcm4908_led_24_groups[] = { "led_24_grp_a" };
+static const char * const bcm4908_led_25_groups[] = { "led_25_grp_a" };
+static const char * const bcm4908_led_26_groups[] = { "led_26_grp_a" };
+static const char * const bcm4908_led_27_groups[] = { "led_27_grp_a" };
+static const char * const bcm4908_led_28_groups[] = { "led_28_grp_a" };
+static const char * const bcm4908_led_29_groups[] = { "led_29_grp_a" };
+static const char * const bcm4908_led_30_groups[] = { "led_30_grp_a" };
+static const char * const bcm4908_led_31_groups[] = { "led_31_grp_a", "led_31_grp_b" };
+static const char * const bcm4908_hs_uart_groups[] = { "hs_uart_grp" };
+static const char * const bcm4908_i2c_groups[] = { "i2c_grp_a", "i2c_grp_b" };
+static const char * const bcm4908_i2s_groups[] = { "i2s_grp" };
+static const char * const bcm4908_nand_ctrl_groups[] = { "nand_ctrl_grp" };
+static const char * const bcm4908_nand_data_groups[] = { "nand_data_grp" };
+static const char * const bcm4908_emmc_ctrl_groups[] = { "emmc_ctrl_grp" };
+static const char * const bcm4908_usb0_pwr_groups[] = { "usb0_pwr_grp" };
+static const char * const bcm4908_usb1_pwr_groups[] = { "usb1_pwr_grp" };
 
 static const struct bcmbca_pinctrl_function bcm4908_pinctrl_functions[] = {
-	{ "led_0", led_0_groups, ARRAY_SIZE(led_0_groups) },
-	{ "led_1", led_1_groups, ARRAY_SIZE(led_1_groups) },
-	{ "led_2", led_2_groups, ARRAY_SIZE(led_2_groups) },
-	{ "led_3", led_3_groups, ARRAY_SIZE(led_3_groups) },
-	{ "led_4", led_4_groups, ARRAY_SIZE(led_4_groups) },
-	{ "led_5", led_5_groups, ARRAY_SIZE(led_5_groups) },
-	{ "led_6", led_6_groups, ARRAY_SIZE(led_6_groups) },
-	{ "led_7", led_7_groups, ARRAY_SIZE(led_7_groups) },
-	{ "led_8", led_8_groups, ARRAY_SIZE(led_8_groups) },
-	{ "led_9", led_9_groups, ARRAY_SIZE(led_9_groups) },
-	{ "led_10", led_10_groups, ARRAY_SIZE(led_10_groups) },
-	{ "led_11", led_11_groups, ARRAY_SIZE(led_11_groups) },
-	{ "led_12", led_12_groups, ARRAY_SIZE(led_12_groups) },
-	{ "led_13", led_13_groups, ARRAY_SIZE(led_13_groups) },
-	{ "led_14", led_14_groups, ARRAY_SIZE(led_14_groups) },
-	{ "led_15", led_15_groups, ARRAY_SIZE(led_15_groups) },
-	{ "led_16", led_16_groups, ARRAY_SIZE(led_16_groups) },
-	{ "led_17", led_17_groups, ARRAY_SIZE(led_17_groups) },
-	{ "led_18", led_18_groups, ARRAY_SIZE(led_18_groups) },
-	{ "led_19", led_19_groups, ARRAY_SIZE(led_19_groups) },
-	{ "led_20", led_20_groups, ARRAY_SIZE(led_20_groups) },
-	{ "led_21", led_21_groups, ARRAY_SIZE(led_21_groups) },
-	{ "led_22", led_22_groups, ARRAY_SIZE(led_22_groups) },
-	{ "led_23", led_23_groups, ARRAY_SIZE(led_23_groups) },
-	{ "led_24", led_24_groups, ARRAY_SIZE(led_24_groups) },
-	{ "led_25", led_25_groups, ARRAY_SIZE(led_25_groups) },
-	{ "led_26", led_26_groups, ARRAY_SIZE(led_26_groups) },
-	{ "led_27", led_27_groups, ARRAY_SIZE(led_27_groups) },
-	{ "led_28", led_28_groups, ARRAY_SIZE(led_28_groups) },
-	{ "led_29", led_29_groups, ARRAY_SIZE(led_29_groups) },
-	{ "led_30", led_30_groups, ARRAY_SIZE(led_30_groups) },
-	{ "led_31", led_31_groups, ARRAY_SIZE(led_31_groups) },
-	{ "hs_uart", hs_uart_groups, ARRAY_SIZE(hs_uart_groups) },
-	{ "i2c", i2c_groups, ARRAY_SIZE(i2c_groups) },
-	{ "i2s", i2s_groups, ARRAY_SIZE(i2s_groups) },
-	{ "nand_ctrl", nand_ctrl_groups, ARRAY_SIZE(nand_ctrl_groups) },
-	{ "nand_data", nand_data_groups, ARRAY_SIZE(nand_data_groups) },
-	{ "emmc_ctrl", emmc_ctrl_groups, ARRAY_SIZE(emmc_ctrl_groups) },
-	{ "usb0_pwr", usb0_pwr_groups, ARRAY_SIZE(usb0_pwr_groups) },
-	{ "usb1_pwr", usb1_pwr_groups, ARRAY_SIZE(usb1_pwr_groups) },
+	{ "led_0", bcm4908_led_0_groups, ARRAY_SIZE(bcm4908_led_0_groups) },
+	{ "led_1", bcm4908_led_1_groups, ARRAY_SIZE(bcm4908_led_1_groups) },
+	{ "led_2", bcm4908_led_2_groups, ARRAY_SIZE(bcm4908_led_2_groups) },
+	{ "led_3", bcm4908_led_3_groups, ARRAY_SIZE(bcm4908_led_3_groups) },
+	{ "led_4", bcm4908_led_4_groups, ARRAY_SIZE(bcm4908_led_4_groups) },
+	{ "led_5", bcm4908_led_5_groups, ARRAY_SIZE(bcm4908_led_5_groups) },
+	{ "led_6", bcm4908_led_6_groups, ARRAY_SIZE(bcm4908_led_6_groups) },
+	{ "led_7", bcm4908_led_7_groups, ARRAY_SIZE(bcm4908_led_7_groups) },
+	{ "led_8", bcm4908_led_8_groups, ARRAY_SIZE(bcm4908_led_8_groups) },
+	{ "led_9", bcm4908_led_9_groups, ARRAY_SIZE(bcm4908_led_9_groups) },
+	{ "led_10", bcm4908_led_10_groups, ARRAY_SIZE(bcm4908_led_10_groups) },
+	{ "led_11", bcm4908_led_11_groups, ARRAY_SIZE(bcm4908_led_11_groups) },
+	{ "led_12", bcm4908_led_12_groups, ARRAY_SIZE(bcm4908_led_12_groups) },
+	{ "led_13", bcm4908_led_13_groups, ARRAY_SIZE(bcm4908_led_13_groups) },
+	{ "led_14", bcm4908_led_14_groups, ARRAY_SIZE(bcm4908_led_14_groups) },
+	{ "led_15", bcm4908_led_15_groups, ARRAY_SIZE(bcm4908_led_15_groups) },
+	{ "led_16", bcm4908_led_16_groups, ARRAY_SIZE(bcm4908_led_16_groups) },
+	{ "led_17", bcm4908_led_17_groups, ARRAY_SIZE(bcm4908_led_17_groups) },
+	{ "led_18", bcm4908_led_18_groups, ARRAY_SIZE(bcm4908_led_18_groups) },
+	{ "led_19", bcm4908_led_19_groups, ARRAY_SIZE(bcm4908_led_19_groups) },
+	{ "led_20", bcm4908_led_20_groups, ARRAY_SIZE(bcm4908_led_20_groups) },
+	{ "led_21", bcm4908_led_21_groups, ARRAY_SIZE(bcm4908_led_21_groups) },
+	{ "led_22", bcm4908_led_22_groups, ARRAY_SIZE(bcm4908_led_22_groups) },
+	{ "led_23", bcm4908_led_23_groups, ARRAY_SIZE(bcm4908_led_23_groups) },
+	{ "led_24", bcm4908_led_24_groups, ARRAY_SIZE(bcm4908_led_24_groups) },
+	{ "led_25", bcm4908_led_25_groups, ARRAY_SIZE(bcm4908_led_25_groups) },
+	{ "led_26", bcm4908_led_26_groups, ARRAY_SIZE(bcm4908_led_26_groups) },
+	{ "led_27", bcm4908_led_27_groups, ARRAY_SIZE(bcm4908_led_27_groups) },
+	{ "led_28", bcm4908_led_28_groups, ARRAY_SIZE(bcm4908_led_28_groups) },
+	{ "led_29", bcm4908_led_29_groups, ARRAY_SIZE(bcm4908_led_29_groups) },
+	{ "led_30", bcm4908_led_30_groups, ARRAY_SIZE(bcm4908_led_30_groups) },
+	{ "led_31", bcm4908_led_31_groups, ARRAY_SIZE(bcm4908_led_31_groups) },
+	{ "hs_uart", bcm4908_hs_uart_groups, ARRAY_SIZE(bcm4908_hs_uart_groups) },
+	{ "i2c", bcm4908_i2c_groups, ARRAY_SIZE(bcm4908_i2c_groups) },
+	{ "i2s", bcm4908_i2s_groups, ARRAY_SIZE(bcm4908_i2s_groups) },
+	{ "nand_ctrl", bcm4908_nand_ctrl_groups, ARRAY_SIZE(bcm4908_nand_ctrl_groups) },
+	{ "nand_data", bcm4908_nand_data_groups, ARRAY_SIZE(bcm4908_nand_data_groups) },
+	{ "emmc_ctrl", bcm4908_emmc_ctrl_groups, ARRAY_SIZE(bcm4908_emmc_ctrl_groups) },
+	{ "usb0_pwr", bcm4908_usb0_pwr_groups, ARRAY_SIZE(bcm4908_usb0_pwr_groups) },
+	{ "usb1_pwr", bcm4908_usb1_pwr_groups, ARRAY_SIZE(bcm4908_usb1_pwr_groups) },
+};
+
+static const struct bcmbca_soc_info bcm4908_pinctrl_soc_info = {
+	.num_pins = BCM4908_NUM_PINS,
+	.groups = bcm4908_pinctrl_grps,
+	.num_groups = ARRAY_SIZE(bcm4908_pinctrl_grps),
+	.functions = bcm4908_pinctrl_functions,
+	.num_functions = ARRAY_SIZE(bcm4908_pinctrl_functions),
 };
 
 /*
@@ -471,14 +473,6 @@ static const struct pinctrl_desc bcmbca_pinctrl_desc = {
 	.pmxops = &bcmbca_pinctrl_pmxops,
 };
 
-static const struct bcmbca_soc_info bcm4908_pinctrl_soc_info = {
-	.num_pins = BCM4908_NUM_PINS,
-	.groups = bcm4908_pinctrl_grps,
-	.num_groups = ARRAY_SIZE(bcm4908_pinctrl_grps),
-	.functions = bcm4908_pinctrl_functions,
-	.num_functions = ARRAY_SIZE(bcm4908_pinctrl_functions),
-};
-
 static const struct of_device_id bcmbca_pinctrl_of_match_table[] = {
 	{
 		.compatible = "brcm,bcm4908-pinctrl",

-- 
2.51.0


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

* [PATCH 4/6] pinctrl: bcm: bcmbca: Use a guarded mutex
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
                   ` (2 preceding siblings ...)
  2025-09-30 12:02 ` [PATCH 3/6] pinctrl: bcm: bcmbca: Prefix all BCM4908 data Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-09-30 12:02 ` [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl Linus Walleij
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

Let the scoped guard handle the mutex in this driver.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/bcm/pinctrl-bcmbca.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcmbca.c b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
index b7b2552fd48227b2d318bb37f81a58e03656b954..dba25b453507300aa1435c2eb0326f5ef9694c0a 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcmbca.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl> */
 
+#include <linux/cleanup.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
@@ -439,7 +440,7 @@ static int bcmbca_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
 		return -EINVAL;
 	group = group_desc->data;
 
-	mutex_lock(&bcmbca_pinctrl->mutex);
+	guard(mutex)(&bcmbca_pinctrl->mutex);
 	for (i = 0; i < group->num_pins; i++) {
 		u32 lsb = 0;
 
@@ -451,7 +452,6 @@ static int bcmbca_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
 		writel(BCMBCA_TEST_PORT_CMD_LOAD_MUX_REG,
 		       bcmbca_pinctrl->base + BCMBCA_TEST_PORT_COMMAND);
 	}
-	mutex_unlock(&bcmbca_pinctrl->mutex);
 
 	return 0;
 }

-- 
2.51.0


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

* [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
                   ` (3 preceding siblings ...)
  2025-09-30 12:02 ` [PATCH 4/6] pinctrl: bcm: bcmbca: Use a guarded mutex Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-10-01 12:54   ` Rob Herring
  2025-09-30 12:02 ` [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846 Linus Walleij
  2025-10-01  6:42 ` [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 William Zhang
  6 siblings, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

This SoC is part of the Broadcom Broadband Carrier Access (BCA)
series. The BCM6846 has 79 muxable pins, these bindings define
functions and groups for these.

The bindings are inspired by the other BCA pin control bindings
for the BCM4908.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../bindings/pinctrl/brcm,bcm6846-pinctrl.yaml     | 82 ++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e9c3b1e9ae0501574b5c15d4adfc5421f535c306
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6846-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6846 pin controller
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description:
+  Binding for pin controller present on BCM6846 family SoCs.
+
+properties:
+  compatible:
+    const: brcm,bcm6846-pinctrl
+
+  reg:
+    maxItems: 1
+
+patternProperties:
+  '-pins$':
+    type: object
+    $ref: pinmux-node.yaml#
+    additionalProperties: false
+
+    properties:
+      function:
+        enum: [ led_0, led_1, led_2, led_3, led_4, led_5, led_6, led_7, led_8,
+                led_9, led_10, led_11, led_12, led_13, led_14, led_15, led_16,
+                led_17, ser_led, nand, emmc, spim, usb0_pwr, usb1_pwr, i2c,
+                rgmii, mii, signal_detect, one_sec_pls, rogue_onu, wan, uart0,
+                uart2 ]
+
+      groups:
+        minItems: 1
+        # SPIM uses up to 5 groups for different select signals
+        maxItems: 5
+        items:
+          enum: [ led_0_grp_a, led_0_grp_b, led_1_grp_a, led_1_grp_b,
+                  led_2_grp_a, led_2_grp_b, led_3_grp_a, led_3_grp_b,
+                  led_4_grp_a, led_4_grp_b, led_5_grp_a, led_5_grp_b,
+                  led_6_grp_a, led_6_grp_b, led_7_grp_a, led_7_grp_b,
+                  led_8_grp_a, led_8_grp_b, led_9_grp_a, led_9_grp_b,
+                  led_10_grp_a, led_10_grp_b, led_11_grp_a, led_11_grp_b,
+                  led_12_grp_a, led_12_grp_b, led_13_grp,
+                  led_14_grp, led_15_grp, led_16_grp, led_17_grp,
+                  ser_led_grp_a, ser_led_grp_b, nand_ctrl_grp, nand_data_grp,
+                  nand_wp_grp, emmc_ctrl_grp, spim_grp_a, spim_ss0_grp_a,
+                  spim_ss1_grp_a, spim_ss2_grp_a, spim_ss3_grp_a, spim_grp_b,
+                  spim_ss0_grp_b, spim_ss1_grp_b, spim_ss2_grp_b, spim_ss3_grp_b,
+                  spim_grp_c, spim_ss0_grp_c, spim_ss1_grp_c, spis_grp_a,
+                  spis_ss_grp_a, spis_grp_b, spis_ss_grp_b, usb0_pwr_grp
+                  usb1_pwr_grp, i2c_grp, rgmii_grp, rgmii_rx_ok_grp,
+                  rgmii_start_stop_grp, mii_grp,
+                  signal_detect_grp_a, signal_detect_grp_b, one_sec_pls_grp_a,
+                  one_sec_pls_grp_b, rogue_onu_grp_a, rogue_onu_grp_b,
+                  wan_mdio_grp, wan_nco_grp, wan_early_txen_grp_a,
+                  wan_early_txen_grp_b, wan_nco_1pps_sig_grp_a,
+                  wan_nco_1pps_sig_grp_b, uart0_grp, uart2_grp ]
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    pinctrl@ff800550 {
+        compatible = "brcm,bcm6846-pinctrl";
+        reg = <0xff800550 0x10>;
+
+        led-0-a-pins {
+            function = "led_0";
+            groups = "led_0_grp_a";
+        };
+    };

-- 
2.51.0


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

* [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
                   ` (4 preceding siblings ...)
  2025-09-30 12:02 ` [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl Linus Walleij
@ 2025-09-30 12:02 ` Linus Walleij
  2025-10-01  0:44   ` kernel test robot
  2025-10-01  6:42 ` [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 William Zhang
  6 siblings, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2025-09-30 12:02 UTC (permalink / raw)
  To: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-gpio, devicetree, Linus Walleij

This adds groups and functions required to support the BCM6846
BCA SoC in the BCMBCA pin control driver.

Group and function definitions are based on the vendor code
drop which stuff all groups and functions into the device tree:
linux-4.19.183/arch/arm/boot/dts/brcm/6846/inc/6846_pinctrl.dtsi

The groups and functions have been adjusted to what I believe
is generally useful along the lines of the BCM4908 driver:
for example I2C has two pins SCL/SDA that can be muxed out
in one position the two pins are not muxed individually but
as a group of (SDA,SCL), and the NAND control and data pins
are handled in groups as well.

No all groups and functions are defined, like with the BCM4908
I stopped short from implementing "everything", because I
do not foresee that it would be useful to add all JTAG
scan chains etc.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/pinctrl/bcm/pinctrl-bcmbca.c | 531 +++++++++++++++++++++++++++++++++++
 1 file changed, 531 insertions(+)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcmbca.c b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
index dba25b453507300aa1435c2eb0326f5ef9694c0a..394aea544cf746f96e4563e2f5040b671620398b 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcmbca.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcmbca.c
@@ -57,6 +57,533 @@ struct bcmbca_pinctrl_pin_setup {
 	unsigned int function;
 };
 
+/* BCM6846 groups and functions */
+
+#define BCM6846_NUM_PINS 79
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_0_pins_a[] = {
+	{ 18, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_0_pins_b[] = {
+	{ 52, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_1_pins_a[] = {
+	{ 19, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_1_pins_b[] = {
+	{ 53, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_2_pins_a[] = {
+	{ 22, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_2_pins_b[] = {
+	{ 49, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_3_pins_a[] = {
+	{ 24, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_3_pins_b[] = {
+	{ 44, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_4_pins_a[] = {
+	{ 9, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_4_pins_b[] = {
+	{ 44, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_5_pins_a[] = {
+	{ 10, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_5_pins_b[] = {
+	{ 43, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_6_pins_a[] = {
+	{ 11, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_6_pins_b[] = {
+	{ 47, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_7_pins_a[] = {
+	{ 12, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_7_pins_b[] = {
+	{ 45, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_8_pins_a[] = {
+	{ 13, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_8_pins_b[] = {
+	{ 5, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_9_pins_a[] = {
+	{ 16, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_9_pins_b[] = {
+	{ 18, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_10_pins_a[] = {
+	{ 17, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_10_pins_b[] = {
+	{ 50, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_11_pins_a[] = {
+	{ 20, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_11_pins_b[] = {
+	{ 51, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_12_pins_a[] = {
+	{ 21, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_12_pins_b[] = {
+	{ 56, 2 },
+};
+
+/* LEDs 13 thru 17 can apparently only be muxed in one place */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_13_pins[] = {
+	{ 74, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_14_pins[] = {
+	{ 56, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_15_pins[] = {
+	{ 57, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_16_pins[] = {
+	{ 58, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_led_17_pins[] = {
+	{ 59, 0 },
+};
+
+/* Pins used for serial LED control can come out in two places */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_ser_led_pins_a[] = {
+	{ 18, 3 }, /* CLK */
+	{ 23, 3 }, /* DATA */
+	{ 25, 3 }, /* MASK */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_ser_led_pins_b[] = {
+	{ 43, 3 }, /* CLK */
+	{ 45, 3 }, /* DATA */
+	{ 44, 3 }, /* MASK */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_nand_ctrl_pins[] = {
+	{ 26, 1 },
+	{ 27, 1 },
+	{ 28, 1 },
+	{ 29, 1 },
+	{ 30, 1 },
+	{ 31, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_nand_data_pins[] = {
+	{ 32, 1 },
+	{ 33, 1 },
+	{ 34, 1 },
+	{ 35, 1 },
+	{ 36, 1 },
+	{ 37, 1 },
+	{ 38, 1 },
+	{ 39, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_nand_wp_pins[] = {
+	{ 8, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_emmc_ctrl_pins[] = {
+	{ 20, 1 },
+	{ 21, 1 },
+};
+
+/* SPI port "M" can be muxed in three different places */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_pins_a[] = {
+	{ 62, 1 }, /* CLK */
+	{ 63, 1 }, /* MOSI */
+	{ 64, 1 }, /* MISO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss0_pins_a[] = {
+	{ 65, 1 }, /* SPI Select 0, Chip select 0 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss1_pins_a[] = {
+	{ 66, 1 }, /* SPI Select 1, Chip select 1 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss2_pins_a[] = {
+	{ 9, 1 }, /* SPI Select 2, Chip select 2 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss3_pins_a[] = {
+	{ 12, 1 }, /* SPI Select 3, Chip select 3 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_pins_b[] = {
+	{ 49, 0 }, /* CLK */
+	{ 50, 0 }, /* MOSI */
+	{ 51, 0 }, /* MISO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss0_pins_b[] = {
+	{ 52, 0 }, /* SPI Select 0, Chip select 0 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss1_pins_b[] = {
+	{ 53, 0 }, /* SPI Select 1, Chip select 1 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss2_pins_b[] = {
+	{ 5, 0 }, /* SPI Select 2, Chip select 2 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss3_pins_b[] = {
+	{ 7, 1 }, /* SPI Select 3, Chip select 3 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_pins_c[] = {
+	{ 24, 0 }, /* CLK */
+	{ 6, 0 }, /* MOSI */
+	{ 7, 0 }, /* MISO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss0_pins_c[] = {
+	{ 8, 0 }, /* SPI Select 0, Chip select 0 */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spim_ss1_pins_c[] = {
+	{ 73, 1 }, /* SPI Select 1, Chip select 1 */
+};
+
+/* SPI port "S", this has just one optional select pin but can be in two places */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spis_pins_a[] = {
+	{ 56, 1 }, /* CLK */
+	{ 57, 1 }, /* MOSI */
+	{ 58, 1 }, /* MISO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spis_ss_pins_a[] = {
+	{ 59, 1 }, /* SPI S Select, Chip select */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spis_pins_b[] = {
+	{ 0, 2 }, /* CLK */
+	{ 1, 2 }, /* MOSI */
+	{ 2, 2 }, /* MISO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_spis_ss_pins_b[] = {
+	{ 3, 2 }, /* SPI S Select, Chip select */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_usb0_pwr_pins[] = {
+	{ 74, 1 },
+	{ 75, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_usb1_pwr_pins[] = {
+	{ 76, 1 },
+	{ 77, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_i2c_pins[] = {
+	{ 68, 0 },	/* SCL */
+	{ 69, 0 },	/* SDA */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_rgmii_pins[] = {
+	{ 42, 1 },
+	{ 43, 1 },
+	{ 44, 1 },
+	{ 45, 1 },
+	{ 46, 1 },
+	{ 47, 1 },
+	{ 48, 1 },
+	{ 49, 1 },
+	{ 50, 1 },
+	{ 51, 1 },
+	{ 52, 1 },
+	{ 53, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_rgmii_rx_ok_pins[] = {
+	{ 7, 3 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_rgmii_start_stop_pins[] = {
+	{ 6, 3 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_mii_pins[] = {
+	{ 8, 3 }, /* RX ER */
+	{ 5, 3 }, /* TX ER */
+};
+
+/* "signal detect" pin can be in two positions */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_signal_detect_pins_a[] = {
+	{ 58, 3 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_signal_detect_pins_b[] = {
+	{ 15, 3 },
+};
+
+/* "one sec pls" pin can be in two positions */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_one_sec_pls_pins_a[] = {
+	{ 40, 0 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_one_sec_pls_pins_b[] = {
+	{ 6, 1 },
+};
+
+/* "Rogue onu" pin, presumably a misspelling of "rogue one" */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_rogue_onu_pins_a[] = {
+	{ 56, 3 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_rogue_onu_pins_b[] = {
+	{ 14, 3 },
+};
+
+/* WAN extra pins for SynchE and PTP */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_mdio_pins[] = {
+	{ 54, 1 }, /* MDC */
+	{ 55, 1 }, /* MDIO */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_nco_pins[] = {
+	{ 16, 3 }, /* 10 MHz NCO clock output */
+	{ 5, 1 }, /* 8 kHz NCO clock output */
+	{ 20, 3 }, /* NCO programmable clock output */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_early_txen_pins_a[] = {
+	{ 10, 3 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_early_txen_pins_b[] = {
+	{ 4, 1 },
+};
+
+/* 1PPS pin for IEEE 1588 PTP */
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_nco_1pps_sig_pins_a[] = {
+	{ 40, 1 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_wan_nco_1pps_sig_pins_b[] = {
+	{ 6, 2 },
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_uart0_pins[] = {
+	{ 60, 1 }, /* SDIN (RX) */
+	{ 61, 1 }, /* SDOUT (TX) */
+};
+
+static const struct bcmbca_pinctrl_pin_setup bcm6846_uart2_pins[] = {
+	{ 13, 1 }, /* CTS */
+	{ 16, 1 }, /* RTS */
+	{ 14, 1 }, /* SIN (RX) */
+	{ 15, 1 }, /* SOUT (TX) */
+};
+
+static const struct bcmbca_pinctrl_grp bcm6846_pinctrl_grps[] = {
+	{ "led_0_grp_a", bcm6846_led_0_pins_a, ARRAY_SIZE(bcm6846_led_0_pins_a) },
+	{ "led_0_grp_b", bcm6846_led_0_pins_b, ARRAY_SIZE(bcm6846_led_0_pins_b) },
+	{ "led_1_grp_a", bcm6846_led_1_pins_a, ARRAY_SIZE(bcm6846_led_1_pins_a) },
+	{ "led_1_grp_b", bcm6846_led_1_pins_b, ARRAY_SIZE(bcm6846_led_1_pins_b) },
+	{ "led_2_grp_a", bcm6846_led_2_pins_a, ARRAY_SIZE(bcm6846_led_2_pins_a) },
+	{ "led_2_grp_b", bcm6846_led_2_pins_b, ARRAY_SIZE(bcm6846_led_2_pins_b) },
+	{ "led_3_grp_a", bcm6846_led_3_pins_a, ARRAY_SIZE(bcm6846_led_3_pins_a) },
+	{ "led_3_grp_b", bcm6846_led_3_pins_b, ARRAY_SIZE(bcm6846_led_3_pins_b) },
+	{ "led_4_grp_a", bcm6846_led_4_pins_a, ARRAY_SIZE(bcm6846_led_4_pins_a) },
+	{ "led_4_grp_b", bcm6846_led_4_pins_b, ARRAY_SIZE(bcm6846_led_4_pins_b) },
+	{ "led_5_grp_a", bcm6846_led_5_pins_a, ARRAY_SIZE(bcm6846_led_5_pins_a) },
+	{ "led_5_grp_b", bcm6846_led_5_pins_b, ARRAY_SIZE(bcm6846_led_5_pins_b) },
+	{ "led_6_grp_a", bcm6846_led_6_pins_a, ARRAY_SIZE(bcm6846_led_6_pins_a) },
+	{ "led_6_grp_b", bcm6846_led_6_pins_b, ARRAY_SIZE(bcm6846_led_6_pins_b) },
+	{ "led_7_grp_a", bcm6846_led_7_pins_a, ARRAY_SIZE(bcm6846_led_7_pins_a) },
+	{ "led_7_grp_b", bcm6846_led_7_pins_b, ARRAY_SIZE(bcm6846_led_7_pins_b) },
+	{ "led_8_grp_a", bcm6846_led_8_pins_a, ARRAY_SIZE(bcm6846_led_8_pins_a) },
+	{ "led_8_grp_b", bcm6846_led_8_pins_b, ARRAY_SIZE(bcm6846_led_8_pins_b) },
+	{ "led_9_grp_a", bcm6846_led_9_pins_a, ARRAY_SIZE(bcm6846_led_9_pins_a) },
+	{ "led_9_grp_b", bcm6846_led_9_pins_b, ARRAY_SIZE(bcm6846_led_9_pins_b) },
+	{ "led_10_grp_a", bcm6846_led_10_pins_a, ARRAY_SIZE(bcm6846_led_10_pins_a) },
+	{ "led_10_grp_b", bcm6846_led_10_pins_b, ARRAY_SIZE(bcm6846_led_10_pins_b) },
+	{ "led_11_grp_a", bcm6846_led_11_pins_a, ARRAY_SIZE(bcm6846_led_11_pins_a) },
+	{ "led_11_grp_b", bcm6846_led_11_pins_b, ARRAY_SIZE(bcm6846_led_11_pins_b) },
+	{ "led_12_grp_a", bcm6846_led_12_pins_a, ARRAY_SIZE(bcm6846_led_12_pins_a) },
+	{ "led_12_grp_b", bcm6846_led_12_pins_b, ARRAY_SIZE(bcm6846_led_12_pins_b) },
+	{ "led_13_grp", bcm6846_led_13_pins, ARRAY_SIZE(bcm6846_led_13_pins) },
+	{ "led_14_grp", bcm6846_led_14_pins, ARRAY_SIZE(bcm6846_led_14_pins) },
+	{ "led_15_grp", bcm6846_led_15_pins, ARRAY_SIZE(bcm6846_led_15_pins) },
+	{ "led_16_grp", bcm6846_led_16_pins, ARRAY_SIZE(bcm6846_led_16_pins) },
+	{ "led_17_grp", bcm6846_led_17_pins, ARRAY_SIZE(bcm6846_led_17_pins) },
+	{ "ser_led_grp_a", bcm6846_ser_led_pins_a, ARRAY_SIZE(bcm6846_ser_led_pins_a) },
+	{ "ser_led_grp_b", bcm6846_ser_led_pins_b, ARRAY_SIZE(bcm6846_ser_led_pins_b) },
+	{ "nand_ctrl_grp", bcm6846_nand_ctrl_pins, ARRAY_SIZE(bcm6846_nand_ctrl_pins) },
+	{ "nand_data_grp", bcm6846_nand_data_pins, ARRAY_SIZE(bcm6846_nand_data_pins) },
+	{ "nand_wp_grp", bcm6846_nand_wp_pins, ARRAY_SIZE(bcm6846_nand_wp_pins) },
+	{ "emmc_ctrl_grp", bcm6846_emmc_ctrl_pins, ARRAY_SIZE(bcm6846_emmc_ctrl_pins) },
+	{ "spim_grp_a", bcm6846_spim_pins_a, ARRAY_SIZE(bcm6846_spim_pins_a) },
+	{ "spim_ss0_grp_a", bcm6846_spim_ss0_pins_a, ARRAY_SIZE(bcm6846_spim_ss0_pins_a) },
+	{ "spim_ss1_grp_a", bcm6846_spim_ss1_pins_a, ARRAY_SIZE(bcm6846_spim_ss1_pins_a) },
+	{ "spim_ss2_grp_a", bcm6846_spim_ss2_pins_a, ARRAY_SIZE(bcm6846_spim_ss2_pins_a) },
+	{ "spim_ss3_grp_a", bcm6846_spim_ss3_pins_a, ARRAY_SIZE(bcm6846_spim_ss3_pins_a) },
+	{ "spim_grp_b", bcm6846_spim_pins_b, ARRAY_SIZE(bcm6846_spim_pins_b) },
+	{ "spim_ss0_grp_b", bcm6846_spim_ss0_pins_b, ARRAY_SIZE(bcm6846_spim_ss0_pins_b) },
+	{ "spim_ss1_grp_b", bcm6846_spim_ss1_pins_b, ARRAY_SIZE(bcm6846_spim_ss1_pins_b) },
+	{ "spim_ss2_grp_b", bcm6846_spim_ss2_pins_b, ARRAY_SIZE(bcm6846_spim_ss2_pins_b) },
+	{ "spim_ss3_grp_b", bcm6846_spim_ss3_pins_b, ARRAY_SIZE(bcm6846_spim_ss3_pins_b) },
+	{ "spim_grp_c", bcm6846_spim_pins_c, ARRAY_SIZE(bcm6846_spim_pins_c) },
+	{ "spim_ss0_grp_c", bcm6846_spim_ss0_pins_c, ARRAY_SIZE(bcm6846_spim_ss0_pins_c) },
+	{ "spim_ss1_grp_c", bcm6846_spim_ss1_pins_c, ARRAY_SIZE(bcm6846_spim_ss1_pins_c) },
+	{ "spis_grp_a", bcm6846_spis_pins_a, ARRAY_SIZE(bcm6846_spis_pins_a) },
+	{ "spis_ss_grp_a", bcm6846_spis_ss_pins_a, ARRAY_SIZE(bcm6846_spis_ss_pins_a) },
+	{ "spis_grp_b", bcm6846_spis_pins_b, ARRAY_SIZE(bcm6846_spis_pins_b) },
+	{ "spis_ss_grp_b", bcm6846_spis_ss_pins_b, ARRAY_SIZE(bcm6846_spis_ss_pins_b) },
+	{ "usb0_pwr_grp", bcm6846_usb0_pwr_pins, ARRAY_SIZE(bcm6846_usb0_pwr_pins) },
+	{ "usb1_pwr_grp", bcm6846_usb1_pwr_pins, ARRAY_SIZE(bcm6846_usb1_pwr_pins) },
+	{ "i2c_grp", bcm6846_i2c_pins, ARRAY_SIZE(bcm6846_i2c_pins) },
+	{ "rgmii_grp", bcm6846_rgmii_pins, ARRAY_SIZE(bcm6846_rgmii_pins) },
+	{ "rgmii_rx_ok_grp", bcm6846_rgmii_rx_ok_pins, ARRAY_SIZE(bcm6846_rgmii_rx_ok_pins) },
+	{ "rgmii_start_stop_grp", bcm6846_rgmii_start_stop_pins, ARRAY_SIZE(bcm6846_rgmii_start_stop_pins) },
+	{ "mii_grp", bcm6846_mii_pins, ARRAY_SIZE(bcm6846_mii_pins) },
+	{ "signal_detect_grp_a", bcm6846_signal_detect_pins_a, ARRAY_SIZE(bcm6846_signal_detect_pins_a) },
+	{ "signal_detect_grp_b", bcm6846_signal_detect_pins_b, ARRAY_SIZE(bcm6846_signal_detect_pins_b) },
+	{ "one_sec_pls_grp_a", bcm6846_one_sec_pls_pins_a, ARRAY_SIZE(bcm6846_one_sec_pls_pins_a) },
+	{ "one_sec_pls_grp_b", bcm6846_one_sec_pls_pins_b, ARRAY_SIZE(bcm6846_one_sec_pls_pins_b) },
+	{ "rogue_onu_grp_a", bcm6846_rogue_onu_pins_a, ARRAY_SIZE(bcm6846_rogue_onu_pins_a) },
+	{ "rogue_onu_grp_b", bcm6846_rogue_onu_pins_b, ARRAY_SIZE(bcm6846_rogue_onu_pins_b) },
+	{ "wan_mdio_grp", bcm6846_wan_mdio_pins, ARRAY_SIZE(bcm6846_wan_mdio_pins) },
+	{ "wan_nco_grp", bcm6846_wan_nco_pins, ARRAY_SIZE(bcm6846_wan_nco_pins) },
+	{ "wan_early_txen_grp_a", bcm6846_wan_early_txen_pins_a, ARRAY_SIZE(bcm6846_wan_early_txen_pins_a) },
+	{ "wan_early_txen_grp_b", bcm6846_wan_early_txen_pins_b, ARRAY_SIZE(bcm6846_wan_early_txen_pins_b) },
+	{ "wan_nco_1pps_sig_grp_a", bcm6846_wan_nco_1pps_sig_pins_a, ARRAY_SIZE(bcm6846_wan_nco_1pps_sig_pins_a) },
+	{ "wan_nco_1pps_sig_grp_b", bcm6846_wan_nco_1pps_sig_pins_b, ARRAY_SIZE(bcm6846_wan_nco_1pps_sig_pins_b) },
+	{ "uart0_grp", bcm6846_uart0_pins, ARRAY_SIZE(bcm6846_uart0_pins) },
+	{ "uart2_grp", bcm6846_uart2_pins, ARRAY_SIZE(bcm6846_uart2_pins) },
+};
+
+static const char * const bcm6846_led_0_groups[] = { "led_0_grp_a", "led_0_grp_b" };
+static const char * const bcm6846_led_1_groups[] = { "led_1_grp_a", "led_1_grp_b" };
+static const char * const bcm6846_led_2_groups[] = { "led_2_grp_a", "led_2_grp_b" };
+static const char * const bcm6846_led_3_groups[] = { "led_3_grp_a", "led_3_grp_b" };
+static const char * const bcm6846_led_4_groups[] = { "led_4_grp_a", "led_4_grp_b" };
+static const char * const bcm6846_led_5_groups[] = { "led_5_grp_a", "led_5_grp_b" };
+static const char * const bcm6846_led_6_groups[] = { "led_6_grp_a", "led_6_grp_b" };
+static const char * const bcm6846_led_7_groups[] = { "led_7_grp_a", "led_7_grp_b" };
+static const char * const bcm6846_led_8_groups[] = { "led_8_grp_a", "led_8_grp_b" };
+static const char * const bcm6846_led_9_groups[] = { "led_9_grp_a", "led_9_grp_b" };
+static const char * const bcm6846_led_10_groups[] = { "led_10_grp_a", "led_10_grp_b" };
+static const char * const bcm6846_led_11_groups[] = { "led_11_grp_a", "led_11_grp_b" };
+static const char * const bcm6846_led_12_groups[] = { "led_12_grp_a", "led_12_grp_b" };
+static const char * const bcm6846_led_13_groups[] = { "led_13_grp" };
+static const char * const bcm6846_led_14_groups[] = { "led_14_grp" };
+static const char * const bcm6846_led_15_groups[] = { "led_15_grp" };
+static const char * const bcm6846_led_16_groups[] = { "led_16_grp" };
+static const char * const bcm6846_led_17_groups[] = { "led_17_grp" };
+static const char * const bcm6846_ser_led_groups[] = { "ser_led_grp_a", "ser_led_grp_b" };
+/* We use these three groups with the NAND function to get as many pins as we want */
+static const char * const bcm6846_nand_groups[] = { "nand_ctrl_grp", "nand_data_grp", "nand_wp_grp" };
+static const char * const bcm6846_emmc_groups[] = { "emmc_ctrl_grp" };
+/* Activate SPIM with "spim_grp" and then as many selects as used with "spim_ssN_grp" groups */
+static const char * const bcm6846_spim_groups[] = {
+	"spim_grp_a", "spim_ss0_grp_a",	"spim_ss1_grp_a", "spim_ss2_grp_a", "spim_ss3_grp_a",
+	"spim_grp_b", "spim_ss0_grp_b",	"spim_ss1_grp_b", "spim_ss2_grp_b", "spim_ss3_grp_b",
+	"spim_grp_c", "spim_ss0_grp_c",	"spim_ss1_grp_c" };
+static const char * const bcm6846_spis_groups[] = {
+	"spis_grp_a", "spim_ss_grp_a",
+	"spis_grp_b", "spis_ss_grp_b" };
+static const char * const bcm6846_usb0_pwr_groups[] = { "usb0_pwr_grp" };
+static const char * const bcm6846_usb1_pwr_groups[] = { "usb1_pwr_grp" };
+static const char * const bcm6846_i2c_groups[] = { "i2c_grp" };
+static const char * const bcm6846_rgmii_groups[] = { "rgmii_grp", "rgmii_rx_ok_grp", "rgmii_start_stop_grp" };
+static const char * const bcm6846_mii_groups[] = { "mii_grp" };
+static const char * const bcm6846_signal_detect_groups[] = { "signal_detect_grp_a", "signal_detect_grp_b" };
+static const char * const bcm6846_one_sec_pls_groups[] = { "one_sec_pls_grp_a", "one_sec_pls_grp_b" };
+static const char * const bcm6846_rogue_onu_groups[] = { "rogue_onu_grp_a", "rogue_onu_grp_b" };
+static const char * const bcm6846_wan_groups[] = { "wan_mdio_grp", "wan_nco_grp",
+	"wan_early_txen_grp_a", "wan_early_txen_grp_b", "wan_nco_1pps_sig_grp_a", "wan_nco_1pps_sig_grp_b" };
+static const char * const bcm6846_uart0_groups[] = { "uart0_grp" };
+static const char * const bcm6846_uart2_groups[] = { "uart2_grp" };
+
+static const struct bcmbca_pinctrl_function bcm6846_pinctrl_functions[] = {
+	{ "led_0", bcm6846_led_0_groups, ARRAY_SIZE(bcm6846_led_0_groups) },
+	{ "led_1", bcm6846_led_1_groups, ARRAY_SIZE(bcm6846_led_1_groups) },
+	{ "led_2", bcm6846_led_2_groups, ARRAY_SIZE(bcm6846_led_2_groups) },
+	{ "led_3", bcm6846_led_3_groups, ARRAY_SIZE(bcm6846_led_3_groups) },
+	{ "led_4", bcm6846_led_4_groups, ARRAY_SIZE(bcm6846_led_4_groups) },
+	{ "led_5", bcm6846_led_5_groups, ARRAY_SIZE(bcm6846_led_5_groups) },
+	{ "led_6", bcm6846_led_6_groups, ARRAY_SIZE(bcm6846_led_6_groups) },
+	{ "led_7", bcm6846_led_7_groups, ARRAY_SIZE(bcm6846_led_7_groups) },
+	{ "led_8", bcm6846_led_8_groups, ARRAY_SIZE(bcm6846_led_8_groups) },
+	{ "led_9", bcm6846_led_9_groups, ARRAY_SIZE(bcm6846_led_9_groups) },
+	{ "led_10", bcm6846_led_10_groups, ARRAY_SIZE(bcm6846_led_10_groups) },
+	{ "led_11", bcm6846_led_11_groups, ARRAY_SIZE(bcm6846_led_11_groups) },
+	{ "led_12", bcm6846_led_12_groups, ARRAY_SIZE(bcm6846_led_12_groups) },
+	{ "led_13", bcm6846_led_13_groups, ARRAY_SIZE(bcm6846_led_13_groups) },
+	{ "led_14", bcm6846_led_14_groups, ARRAY_SIZE(bcm6846_led_14_groups) },
+	{ "led_15", bcm6846_led_15_groups, ARRAY_SIZE(bcm6846_led_15_groups) },
+	{ "led_16", bcm6846_led_16_groups, ARRAY_SIZE(bcm6846_led_16_groups) },
+	{ "led_17", bcm6846_led_17_groups, ARRAY_SIZE(bcm6846_led_17_groups) },
+	{ "ser_led", bcm6846_ser_led_groups, ARRAY_SIZE(bcm6846_ser_led_groups) },
+	{ "nand", bcm6846_nand_groups, ARRAY_SIZE(bcm6846_nand_groups) },
+	{ "emmc", bcm6846_emmc_groups, ARRAY_SIZE(bcm6846_emmc_groups) },
+	{ "spim", bcm6846_spim_groups, ARRAY_SIZE(bcm6846_spim_groups) },
+	{ "usb0_pwr", bcm6846_usb0_pwr_groups, ARRAY_SIZE(bcm6846_usb0_pwr_groups) },
+	{ "usb1_pwr", bcm6846_usb1_pwr_groups, ARRAY_SIZE(bcm6846_usb1_pwr_groups) },
+	{ "i2c", bcm6846_i2c_groups, ARRAY_SIZE(bcm6846_i2c_groups) },
+	{ "rgmii", bcm6846_rgmii_groups, ARRAY_SIZE(bcm6846_rgmii_groups) },
+	{ "mii", bcm6846_mii_groups, ARRAY_SIZE(bcm6846_mii_groups) },
+	{ "signal_detect", bcm6846_signal_detect_groups, ARRAY_SIZE(bcm6846_signal_detect_groups) },
+	{ "one_sec_pls", bcm6846_one_sec_pls_groups, ARRAY_SIZE(bcm6846_one_sec_pls_groups) },
+	{ "rogue_onu", bcm6846_rogue_onu_groups, ARRAY_SIZE(bcm6846_rogue_onu_groups) },
+	{ "wan", bcm6846_wan_groups, ARRAY_SIZE(bcm6846_wan_groups) },
+	{ "uart0", bcm6846_uart0_groups, ARRAY_SIZE(bcm6846_uart0_groups) },
+	{ "uart2", bcm6846_uart2_groups, ARRAY_SIZE(bcm6846_uart2_groups) },
+};
+
+static const struct bcmbca_soc_info bcm6846_pinctrl_soc_info = {
+	.num_pins = BCM6846_NUM_PINS,
+	.groups = bcm6846_pinctrl_grps,
+	.num_groups = ARRAY_SIZE(bcm6846_pinctrl_grps),
+	.functions = bcm6846_pinctrl_functions,
+	.num_functions = ARRAY_SIZE(bcm6846_pinctrl_functions),
+};
+
 /* BCM4908 groups and functions */
 
 #define BCM4908_NUM_PINS 86
@@ -474,6 +1001,10 @@ static const struct pinctrl_desc bcmbca_pinctrl_desc = {
 };
 
 static const struct of_device_id bcmbca_pinctrl_of_match_table[] = {
+	{
+		.compatible = "brcm,bcm6846-pinctrl",
+		.data = &bcm6846_pinctrl_soc_info,
+	},
 	{
 		.compatible = "brcm,bcm4908-pinctrl",
 		.data = &bcm4908_pinctrl_soc_info,

-- 
2.51.0


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

* Re: [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846
  2025-09-30 12:02 ` [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846 Linus Walleij
@ 2025-10-01  0:44   ` kernel test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2025-10-01  0:44 UTC (permalink / raw)
  To: Linus Walleij, Rafał Miłecki,
	Broadcom internal kernel review list, William Zhang, Anand Gore,
	Kursad Oney, Florian Fainelli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: oe-kbuild-all, linux-gpio, devicetree, Linus Walleij

Hi Linus,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8f5ae30d69d7543eee0d70083daf4de8fe15d585]

url:    https://github.com/intel-lab-lkp/linux/commits/Linus-Walleij/pinctrl-bcm-Rename-bcm4908-to-bcmbca/20250930-200534
base:   8f5ae30d69d7543eee0d70083daf4de8fe15d585
patch link:    https://lore.kernel.org/r/20250930-bcmbca-pinctrl-v1-6-73218459a094%40linaro.org
patch subject: [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846
config: loongarch-allyesconfig (https://download.01.org/0day-ci/archive/20251001/202510010811.0pbFyQ24-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 39f292ffa13d7ca0d1edff27ac8fd55024bb4d19)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251001/202510010811.0pbFyQ24-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510010811.0pbFyQ24-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from <built-in>:3:
   In file included from include/linux/compiler_types.h:171:
   include/linux/compiler-clang.h:28:9: warning: '__SANITIZE_ADDRESS__' macro redefined [-Wmacro-redefined]
      28 | #define __SANITIZE_ADDRESS__
         |         ^
   <built-in>:371:9: note: previous definition is here
     371 | #define __SANITIZE_ADDRESS__ 1
         |         ^
>> drivers/pinctrl/bcm/pinctrl-bcmbca.c:527:27: warning: unused variable 'bcm6846_spis_groups' [-Wunused-const-variable]
     527 | static const char * const bcm6846_spis_groups[] = {
         |                           ^~~~~~~~~~~~~~~~~~~
   2 warnings generated.


vim +/bcm6846_spis_groups +527 drivers/pinctrl/bcm/pinctrl-bcmbca.c

   499	
   500	static const char * const bcm6846_led_0_groups[] = { "led_0_grp_a", "led_0_grp_b" };
   501	static const char * const bcm6846_led_1_groups[] = { "led_1_grp_a", "led_1_grp_b" };
   502	static const char * const bcm6846_led_2_groups[] = { "led_2_grp_a", "led_2_grp_b" };
   503	static const char * const bcm6846_led_3_groups[] = { "led_3_grp_a", "led_3_grp_b" };
   504	static const char * const bcm6846_led_4_groups[] = { "led_4_grp_a", "led_4_grp_b" };
   505	static const char * const bcm6846_led_5_groups[] = { "led_5_grp_a", "led_5_grp_b" };
   506	static const char * const bcm6846_led_6_groups[] = { "led_6_grp_a", "led_6_grp_b" };
   507	static const char * const bcm6846_led_7_groups[] = { "led_7_grp_a", "led_7_grp_b" };
   508	static const char * const bcm6846_led_8_groups[] = { "led_8_grp_a", "led_8_grp_b" };
   509	static const char * const bcm6846_led_9_groups[] = { "led_9_grp_a", "led_9_grp_b" };
   510	static const char * const bcm6846_led_10_groups[] = { "led_10_grp_a", "led_10_grp_b" };
   511	static const char * const bcm6846_led_11_groups[] = { "led_11_grp_a", "led_11_grp_b" };
   512	static const char * const bcm6846_led_12_groups[] = { "led_12_grp_a", "led_12_grp_b" };
   513	static const char * const bcm6846_led_13_groups[] = { "led_13_grp" };
   514	static const char * const bcm6846_led_14_groups[] = { "led_14_grp" };
   515	static const char * const bcm6846_led_15_groups[] = { "led_15_grp" };
   516	static const char * const bcm6846_led_16_groups[] = { "led_16_grp" };
   517	static const char * const bcm6846_led_17_groups[] = { "led_17_grp" };
   518	static const char * const bcm6846_ser_led_groups[] = { "ser_led_grp_a", "ser_led_grp_b" };
   519	/* We use these three groups with the NAND function to get as many pins as we want */
   520	static const char * const bcm6846_nand_groups[] = { "nand_ctrl_grp", "nand_data_grp", "nand_wp_grp" };
   521	static const char * const bcm6846_emmc_groups[] = { "emmc_ctrl_grp" };
   522	/* Activate SPIM with "spim_grp" and then as many selects as used with "spim_ssN_grp" groups */
   523	static const char * const bcm6846_spim_groups[] = {
   524		"spim_grp_a", "spim_ss0_grp_a",	"spim_ss1_grp_a", "spim_ss2_grp_a", "spim_ss3_grp_a",
   525		"spim_grp_b", "spim_ss0_grp_b",	"spim_ss1_grp_b", "spim_ss2_grp_b", "spim_ss3_grp_b",
   526		"spim_grp_c", "spim_ss0_grp_c",	"spim_ss1_grp_c" };
 > 527	static const char * const bcm6846_spis_groups[] = {
   528		"spis_grp_a", "spim_ss_grp_a",
   529		"spis_grp_b", "spis_ss_grp_b" };
   530	static const char * const bcm6846_usb0_pwr_groups[] = { "usb0_pwr_grp" };
   531	static const char * const bcm6846_usb1_pwr_groups[] = { "usb1_pwr_grp" };
   532	static const char * const bcm6846_i2c_groups[] = { "i2c_grp" };
   533	static const char * const bcm6846_rgmii_groups[] = { "rgmii_grp", "rgmii_rx_ok_grp", "rgmii_start_stop_grp" };
   534	static const char * const bcm6846_mii_groups[] = { "mii_grp" };
   535	static const char * const bcm6846_signal_detect_groups[] = { "signal_detect_grp_a", "signal_detect_grp_b" };
   536	static const char * const bcm6846_one_sec_pls_groups[] = { "one_sec_pls_grp_a", "one_sec_pls_grp_b" };
   537	static const char * const bcm6846_rogue_onu_groups[] = { "rogue_onu_grp_a", "rogue_onu_grp_b" };
   538	static const char * const bcm6846_wan_groups[] = { "wan_mdio_grp", "wan_nco_grp",
   539		"wan_early_txen_grp_a", "wan_early_txen_grp_b", "wan_nco_1pps_sig_grp_a", "wan_nco_1pps_sig_grp_b" };
   540	static const char * const bcm6846_uart0_groups[] = { "uart0_grp" };
   541	static const char * const bcm6846_uart2_groups[] = { "uart2_grp" };
   542	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
  2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
                   ` (5 preceding siblings ...)
  2025-09-30 12:02 ` [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846 Linus Walleij
@ 2025-10-01  6:42 ` William Zhang
  2025-10-01  7:59   ` Linus Walleij
  6 siblings, 1 reply; 14+ messages in thread
From: William Zhang @ 2025-10-01  6:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafał Miłecki, Broadcom internal kernel review list,
	Anand Gore, Kursad Oney, Florian Fainelli, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree

[-- Attachment #1: Type: text/plain, Size: 2797 bytes --]

Hi Linus,

Thank you for posting this series.  It is really good to refactor and
use the bcmbca generic driver for the same chip family which I always
wanted to do but never got the chance to actually do it.   I
understand you are based on the existing 4908 pinmux driver design and
want to use the same type pinmux dts binding.   But the current
implementation requires manually entering all the pin,function,group
arrays in pinctrl driver source code, binding yaml and chip.dtsi(which
I don't see the update of 6846.dtsi in your series).  This is quite
some work and can be error prone.

I believe you have the access to Broadcom reference software and there
is a pinctrl driver we
use(bcmdrivers/opensource/misc/bca_pinctrl/impl1/pinctrl-bcmbca.c) in
ref sw.  The advantage of that driver is that we automatically
generate all the pinmux pin and function info into the
<soc>_pinctrl.dtsi and the pinctrl driver is designed in very generic
way and does not have per chip pinmux function/group info in the
driver code but rather from the device tree.  So for every chip, all
we need to do is just generating the pinctrl.dtsi and no source code
change is needed.  I understand this is not what a typical upstream
pinctrl driver does but it does the job.   Have you looked into that
ref sw driver and what do you think that approach versus the current
upstream driver?  Do you see any issue with that driver?  As far as I
can tell,  it should work but we may have to leave 4908 with the
existing driver and pinmux binding.

Thanks,
William




On Tue, Sep 30, 2025 at 5:03 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> This refactors the BCM4908 pin control driver into a generic
> BCMBCA driver and adds the BCM6846 SoC.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Linus Walleij (6):
>       pinctrl: bcm: Rename bcm4908 to bcmbca
>       pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs
>       pinctrl: bcm: bcmbca: Prefix all BCM4908 data
>       pinctrl: bcm: bcmbca: Use a guarded mutex
>       dt-bindings: pinctrl: Add binding for BCM6846 pinctrl
>       pinctrl: bcm: bcmbca: Add support for BCM6846
>
>  .../bindings/pinctrl/brcm,bcm6846-pinctrl.yaml     |   82 ++
>  drivers/pinctrl/bcm/Kconfig                        |    9 +-
>  drivers/pinctrl/bcm/Makefile                       |    2 +-
>  drivers/pinctrl/bcm/pinctrl-bcm4908.c              |  564 ----------
>  drivers/pinctrl/bcm/pinctrl-bcmbca.c               | 1114 ++++++++++++++++++++
>  5 files changed, 1202 insertions(+), 569 deletions(-)
> ---
> base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
> change-id: 20250930-bcmbca-pinctrl-deb82d571e13
>
> Best regards,
> --
> Linus Walleij <linus.walleij@linaro.org>
>

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5473 bytes --]

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

* Re: [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
  2025-10-01  6:42 ` [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 William Zhang
@ 2025-10-01  7:59   ` Linus Walleij
  2025-10-01 17:37     ` William Zhang
  0 siblings, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2025-10-01  7:59 UTC (permalink / raw)
  To: William Zhang, Rafał Miłecki
  Cc: Broadcom internal kernel review list, Anand Gore, Kursad Oney,
	Florian Fainelli, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-gpio, devicetree

On Wed, Oct 1, 2025 at 8:43 AM William Zhang <william.zhang@broadcom.com> wrote:

> I believe you have the access to Broadcom reference software and there
> is a pinctrl driver we
> use(bcmdrivers/opensource/misc/bca_pinctrl/impl1/pinctrl-bcmbca.c) in
> ref sw.

Yes I have looked at it, I generated the pin control groups from the
device tree used with this driver.

That driver is in a very bad shape, e.g. (just as an example):
static int bcmbca_pmx_set(struct pinctrl_dev *pctldev, unsigned
func_selector, unsigned group_selector)
{
#define LOAD_MUX_REG_CMD        0x21
#define PINMUX_DATA_SHIFT       12

    struct bcmbca_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
    volatile u32 __iomem *test_port_block_data_msb = pc->base;
    volatile u32 __iomem *test_port_block_data_lsb =
test_port_block_data_msb + 1;
    volatile u32 __iomem *test_port_cmd            =
test_port_block_data_lsb + 1;
    u32 tp_blk_data_lsb;

    tp_blk_data_lsb = group_selector;
    tp_blk_data_lsb |= (func_selector << PINMUX_DATA_SHIFT);
    *test_port_block_data_msb = 0;
    *test_port_block_data_lsb = tp_blk_data_lsb;
    *test_port_cmd = LOAD_MUX_REG_CMD;

    return 0;
}

This is not using writel() macros etc. Essentially the same code is found
in the bcm4908 driver, but cleaned up.

> The advantage of that driver is that we automatically
> generate all the pinmux pin and function info into the
> <soc>_pinctrl.dtsi and the pinctrl driver is designed in very generic
> way and does not have per chip pinmux function/group info in the
> driver code but rather from the device tree.  So for every chip, all
> we need to do is just generating the pinctrl.dtsi and no source code
> change is needed.

But if you can generate say 6846_pinctrl.dtsi, I guess from some
HW data that the public has no access to, then why can't you
generate bcm6846.c with the same contents as C structs?

> I understand this is not what a typical upstream
> pinctrl driver does but it does the job. Have you looked into that
> ref sw driver and what do you think that approach versus the current
> upstream driver?  Do you see any issue with that driver?  As far as I
> can tell,  it should work but we may have to leave 4908 with the
> existing driver and pinmux binding.

The downstream pinctrl-bcmbca.c driver is mostly using a
"one group per pin" approach.

This is very convenient for people doing development from HW
descriptions and thinking about pins as being muxable on an
individual basis.

Some drivers use this approach, the most notorious being
pinctrl-single.c.

But it has some real downsides, because it totally ignores
the fact that the hardware is *clearly* designed to mux pins
in groups and not individually.

This is one example from 6846_pinctrl.dtsi:

        i2c_scl_pin_68: i2c_scl_pinmux {
            pins = <68>;
            function = <0>;
        };

        i2c_sda_pin_69: i2c_sda_pinmux {
            pins = <69>;
            function = <0>;
        };

Why would you want to mux these two pins individually? They
are clearly not meant to be muxed individually, especially given
that they can only be muxed out on pins (68, 69), nowhere
else! If you want SCL then you want SDA as well and it's clearly
thought to be muxed in a pair by the HW designer.

But the DTSI description, from wherever it is generated, does not
create a group out of this.

In other cases, it is done properly:

        rgmii_pins: rgmii_pinmux {
            pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
            function = <1>;
        };

OK so this muxes all the pins for RGMII into function 1 in one go.

In my driver this becomes:

        pins_rgmii: rgmii-pins {
                function = "rgmii";
                groups = "rgmii_grp";
        };

The contents of rgmii_grp is contained in the driver, and this is
roughly equivalent to just putting the data in C instead of in a DTSI.

If all pins were properly grouped in the DTSI file such as
the RGMII pins, I could generate my .c file from the DTSI
file, but right now I can't,

So clearly the DTSI generator is either not entirely sound or
using dubious HW info. Information has been lost in the design
system. Someone had a good vision of how this should work but
it is broken somewhere in the design information flow process.

I understand why Rafal went with the group-oriented approach because
clearly there are groups in the hardware, but the generated .dtsi is in
most cases not properly describing these groups.

If someone in Broadcom is interested in right now starting to actively
work on all the BCA drivers using automatic generation of groups
and include files, perhaps C files as suggested, I'm happy to help
out and integrate this with my driver. But then that needs to be
active and seeking advice from the actual HW designer on
what the grouping should actually be, so this is properly
reflected all the way, not just giving the illusion of a generated
HW description flow which in practice loses all the group
information.

I personally can't work with your HW data generator which is
clearly faulty and I need this supported now, so for me the best
approach is currently to do the BCM4908 approach and encode the
groups manually by inspecting this bogus DTSI file and correct it to
what was probably the HW designers intention, such as
the I2C pins being muxed together as a group. Reverse-engineering
is sometimes necessary.

Yours,
Linus Walleij

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

* Re: [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl
  2025-09-30 12:02 ` [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl Linus Walleij
@ 2025-10-01 12:54   ` Rob Herring
  0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring @ 2025-10-01 12:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafał Miłecki, Broadcom internal kernel review list,
	William Zhang, Anand Gore, Kursad Oney, Florian Fainelli,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree

On Tue, Sep 30, 2025 at 02:02:52PM +0200, Linus Walleij wrote:
> This SoC is part of the Broadcom Broadband Carrier Access (BCA)
> series. The BCM6846 has 79 muxable pins, these bindings define
> functions and groups for these.
> 
> The bindings are inspired by the other BCA pin control bindings
> for the BCM4908.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../bindings/pinctrl/brcm,bcm6846-pinctrl.yaml     | 82 ++++++++++++++++++++++
>  1 file changed, 82 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..e9c3b1e9ae0501574b5c15d4adfc5421f535c306
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6846-pinctrl.yaml
> @@ -0,0 +1,82 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6846-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BCM6846 pin controller
> +
> +maintainers:
> +  - Linus Walleij <linus.walleij@linaro.org>
> +
> +description:
> +  Binding for pin controller present on BCM6846 family SoCs.

This doesn't add any more than what 'title' says, so just drop.

> +
> +properties:
> +  compatible:
> +    const: brcm,bcm6846-pinctrl
> +
> +  reg:
> +    maxItems: 1
> +
> +patternProperties:
> +  '-pins$':
> +    type: object
> +    $ref: pinmux-node.yaml#
> +    additionalProperties: false
> +
> +    properties:
> +      function:
> +        enum: [ led_0, led_1, led_2, led_3, led_4, led_5, led_6, led_7, led_8,
> +                led_9, led_10, led_11, led_12, led_13, led_14, led_15, led_16,
> +                led_17, ser_led, nand, emmc, spim, usb0_pwr, usb1_pwr, i2c,
> +                rgmii, mii, signal_detect, one_sec_pls, rogue_onu, wan, uart0,
> +                uart2 ]
> +
> +      groups:
> +        minItems: 1
> +        # SPIM uses up to 5 groups for different select signals
> +        maxItems: 5
> +        items:
> +          enum: [ led_0_grp_a, led_0_grp_b, led_1_grp_a, led_1_grp_b,
> +                  led_2_grp_a, led_2_grp_b, led_3_grp_a, led_3_grp_b,
> +                  led_4_grp_a, led_4_grp_b, led_5_grp_a, led_5_grp_b,
> +                  led_6_grp_a, led_6_grp_b, led_7_grp_a, led_7_grp_b,
> +                  led_8_grp_a, led_8_grp_b, led_9_grp_a, led_9_grp_b,
> +                  led_10_grp_a, led_10_grp_b, led_11_grp_a, led_11_grp_b,
> +                  led_12_grp_a, led_12_grp_b, led_13_grp,
> +                  led_14_grp, led_15_grp, led_16_grp, led_17_grp,
> +                  ser_led_grp_a, ser_led_grp_b, nand_ctrl_grp, nand_data_grp,
> +                  nand_wp_grp, emmc_ctrl_grp, spim_grp_a, spim_ss0_grp_a,
> +                  spim_ss1_grp_a, spim_ss2_grp_a, spim_ss3_grp_a, spim_grp_b,
> +                  spim_ss0_grp_b, spim_ss1_grp_b, spim_ss2_grp_b, spim_ss3_grp_b,
> +                  spim_grp_c, spim_ss0_grp_c, spim_ss1_grp_c, spis_grp_a,
> +                  spis_ss_grp_a, spis_grp_b, spis_ss_grp_b, usb0_pwr_grp
> +                  usb1_pwr_grp, i2c_grp, rgmii_grp, rgmii_rx_ok_grp,
> +                  rgmii_start_stop_grp, mii_grp,
> +                  signal_detect_grp_a, signal_detect_grp_b, one_sec_pls_grp_a,
> +                  one_sec_pls_grp_b, rogue_onu_grp_a, rogue_onu_grp_b,
> +                  wan_mdio_grp, wan_nco_grp, wan_early_txen_grp_a,
> +                  wan_early_txen_grp_b, wan_nco_1pps_sig_grp_a,
> +                  wan_nco_1pps_sig_grp_b, uart0_grp, uart2_grp ]

Nothing required?

> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    pinctrl@ff800550 {
> +        compatible = "brcm,bcm6846-pinctrl";
> +        reg = <0xff800550 0x10>;
> +
> +        led-0-a-pins {
> +            function = "led_0";
> +            groups = "led_0_grp_a";
> +        };
> +    };
> 
> -- 
> 2.51.0
> 

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

* Re: [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
  2025-10-01  7:59   ` Linus Walleij
@ 2025-10-01 17:37     ` William Zhang
  2025-10-01 22:43       ` Linus Walleij
  0 siblings, 1 reply; 14+ messages in thread
From: William Zhang @ 2025-10-01 17:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafał Miłecki, Broadcom internal kernel review list,
	Anand Gore, Kursad Oney, Florian Fainelli, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree

[-- Attachment #1: Type: text/plain, Size: 6634 bytes --]

On Wed, Oct 1, 2025 at 12:59 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Wed, Oct 1, 2025 at 8:43 AM William Zhang <william.zhang@broadcom.com> wrote:
>
> > I believe you have the access to Broadcom reference software and there
> > is a pinctrl driver we
> > use(bcmdrivers/opensource/misc/bca_pinctrl/impl1/pinctrl-bcmbca.c) in
> > ref sw.
>
> Yes I have looked at it, I generated the pin control groups from the
> device tree used with this driver.
>
> That driver is in a very bad shape, e.g. (just as an example):
> static int bcmbca_pmx_set(struct pinctrl_dev *pctldev, unsigned
> func_selector, unsigned group_selector)
> {
> #define LOAD_MUX_REG_CMD        0x21
> #define PINMUX_DATA_SHIFT       12
>
>     struct bcmbca_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
>     volatile u32 __iomem *test_port_block_data_msb = pc->base;
>     volatile u32 __iomem *test_port_block_data_lsb =
> test_port_block_data_msb + 1;
>     volatile u32 __iomem *test_port_cmd            =
> test_port_block_data_lsb + 1;
>     u32 tp_blk_data_lsb;
>
>     tp_blk_data_lsb = group_selector;
>     tp_blk_data_lsb |= (func_selector << PINMUX_DATA_SHIFT);
>     *test_port_block_data_msb = 0;
>     *test_port_block_data_lsb = tp_blk_data_lsb;
>     *test_port_cmd = LOAD_MUX_REG_CMD;
>
>     return 0;
> }
>
> This is not using writel() macros etc. Essentially the same code is found
> in the bcm4908 driver, but cleaned up.
Obviously a few places need clean-up and fix-up to meet the upstream standard.

>
> > The advantage of that driver is that we automatically
> > generate all the pinmux pin and function info into the
> > <soc>_pinctrl.dtsi and the pinctrl driver is designed in very generic
> > way and does not have per chip pinmux function/group info in the
> > driver code but rather from the device tree.  So for every chip, all
> > we need to do is just generating the pinctrl.dtsi and no source code
> > change is needed.
>
> But if you can generate say 6846_pinctrl.dtsi, I guess from some
> HW data that the public has no access to, then why can't you
> generate bcm6846.c with the same contents as C structs?
>
We could but we don't prefer to do that because we want the driver to
be generic and not requiring any change to support a new chip

> > I understand this is not what a typical upstream
> > pinctrl driver does but it does the job. Have you looked into that
> > ref sw driver and what do you think that approach versus the current
> > upstream driver?  Do you see any issue with that driver?  As far as I
> > can tell,  it should work but we may have to leave 4908 with the
> > existing driver and pinmux binding.
>
> The downstream pinctrl-bcmbca.c driver is mostly using a
> "one group per pin" approach.
>
> This is very convenient for people doing development from HW
> descriptions and thinking about pins as being muxable on an
> individual basis.
>
> Some drivers use this approach, the most notorious being
> pinctrl-single.c.
>
> But it has some real downsides, because it totally ignores
> the fact that the hardware is *clearly* designed to mux pins
> in groups and not individually.
>
> This is one example from 6846_pinctrl.dtsi:
>
>         i2c_scl_pin_68: i2c_scl_pinmux {
>             pins = <68>;
>             function = <0>;
>         };
>
>         i2c_sda_pin_69: i2c_sda_pinmux {
>             pins = <69>;
>             function = <0>;
>         };
>
> Why would you want to mux these two pins individually? They
> are clearly not meant to be muxed individually, especially given
> that they can only be muxed out on pins (68, 69), nowhere
> else! If you want SCL then you want SDA as well and it's clearly
> thought to be muxed in a pair by the HW designer.
>
> But the DTSI description, from wherever it is generated, does not
> create a group out of this.
>
> In other cases, it is done properly:
>
>         rgmii_pins: rgmii_pinmux {
>             pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
>             function = <1>;
>         };
>
> OK so this muxes all the pins for RGMII into function 1 in one go.
>
> In my driver this becomes:
>
>         pins_rgmii: rgmii-pins {
>                 function = "rgmii";
>                 groups = "rgmii_grp";
>         };
>
> The contents of rgmii_grp is contained in the driver, and this is
> roughly equivalent to just putting the data in C instead of in a DTSI.
>
> If all pins were properly grouped in the DTSI file such as
> the RGMII pins, I could generate my .c file from the DTSI
> file, but right now I can't,
>
> So clearly the DTSI generator is either not entirely sound or
> using dubious HW info. Information has been lost in the design
> system. Someone had a good vision of how this should work but
> it is broken somewhere in the design information flow process.
>
> I understand why Rafal went with the group-oriented approach because
> clearly there are groups in the hardware, but the generated .dtsi is in
> most cases not properly describing these groups.
>
> If someone in Broadcom is interested in right now starting to actively
> work on all the BCA drivers using automatic generation of groups
> and include files, perhaps C files as suggested, I'm happy to help
> out and integrate this with my driver. But then that needs to be
> active and seeking advice from the actual HW designer on
> what the grouping should actually be, so this is properly
> reflected all the way, not just giving the illusion of a generated
> HW description flow which in practice loses all the group
> information.
>
> I personally can't work with your HW data generator which is
> clearly faulty and I need this supported now, so for me the best
> approach is currently to do the BCM4908 approach and encode the
> groups manually by inspecting this bogus DTSI file and correct it to
> what was probably the HW designers intention, such as
> the I2C pins being muxed together as a group. Reverse-engineering
> is sometimes necessary.
>
You are absolutely right that the current dtsi does not group the pin
properly for certain interfaces such as i2c. The tool has the same
goal to combine interfaces in the group whenever possible. It is just
we don't have the correct group config for certain interface when
generating the dtsi.   If I fix all these group issues and provide the
new dtsi files and I will be the contact if you have any question
regarding generator files,  would it be possible for you to use and
upstream that driver?

> Yours,
> Linus Walleij

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5473 bytes --]

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

* Re: [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
  2025-10-01 17:37     ` William Zhang
@ 2025-10-01 22:43       ` Linus Walleij
  2025-10-02  6:34         ` William Zhang
  0 siblings, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2025-10-01 22:43 UTC (permalink / raw)
  To: William Zhang
  Cc: Rafał Miłecki, Broadcom internal kernel review list,
	Anand Gore, Kursad Oney, Florian Fainelli, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree

On Wed, Oct 1, 2025 at 7:38 PM William Zhang <william.zhang@broadcom.com> wrote:

> > But if you can generate say 6846_pinctrl.dtsi, I guess from some
> > HW data that the public has no access to, then why can't you
> > generate bcm6846.c with the same contents as C structs?
> >
> We could but we don't prefer to do that because we want the driver to
> be generic and not requiring any change to support a new chip

But you will be generating big DTSI files.

And it is not really the ambition of the device tree to be used as a hardware
abstraction layer containing a lot of per-SoC information. The device
tree is supposed to describe and configure the hardware, not
abstract it. There is a difference.

(The DT maintainers can hit me in the head about this but I have
certainly heard things like this before.)

Alas, there is no hard definition of what this means and indeed
some drivers in the kernel does define groups and functions
in the device tree instead of using C files. So that happens too.

> You are absolutely right that the current dtsi does not group the pin
> properly for certain interfaces such as i2c. The tool has the same
> goal to combine interfaces in the group whenever possible. It is just
> we don't have the correct group config for certain interface when
> generating the dtsi.   If I fix all these group issues and provide the
> new dtsi files and I will be the contact if you have any question
> regarding generator files,  would it be possible for you to use and
> upstream that driver?

I assume you fear having to follow the pattern and hand-code
a C file for every BCA SoC and never get done. I understand that.
Also I try to live by the stance "rough consensus and running
code" and not be too strong in pushing things my way.

We can do this if the files follows some basic process.
You still need to use proper bindings.
This:

>         rgmii_pins: rgmii_pinmux {
>             pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
>             function = <1>;
>         };

This isn't proper bindings.
Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml
describe the bindings you can use.

properties:
  function:
    $ref: /schemas/types.yaml#/definitions/string
    description: The mux function to select

  pins:
    oneOf:
      - $ref: /schemas/types.yaml#/definitions/uint32-array
      - $ref: /schemas/types.yaml#/definitions/string-array
    description:
      The list of pin identifiers that properties in the node apply to. The
      specific binding for the hardware defines whether the entries are integers
      or strings, and their meaning.

  groups:
    $ref: /schemas/types.yaml#/definitions/string-array
    description:
      the group to apply the properties to, if the driver supports
      configuration of whole groups rather than individual pins (either
      this, "pins" or "pinmux" has to be specified)

  pinmux:
    description:
      The list of numeric pin ids and their mux settings that properties in the
      node apply to (either this, "pins" or "groups" have to be specified)
    $ref: /schemas/types.yaml#/definitions/uint32-array

  pinctrl-pin-array:
    $ref: /schemas/types.yaml#/definitions/uint32-array

function cannot be a number like that, it is intended to be string such as
"spi" or "uart0".

E.g.

         rgmii_pins: rgmii_pinmux {
             pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
             function = "rgmii";
         };

This also makes sense for at least BCM6846 because the include file
have things like this:

        b_wan_early_txen_pin_4: b_wan_early_txen_pinmux {
            pins = <4>;
            function = <1>;
        };

        b_wan_nco_1pps_sig_pin_6: b_wan_nco_1pps_sig_pinmux {
            pins = <6>;
            function = <2>;
        };

Completely different function numbers, still both are related to WAN,
which is what pin control refers to as a function.

I do understand that the "function" number is actually just a mux setting
for that pin. But this isn't very standardized or very helpful.

Also, we don't really want to see more custom properties such as
brcm,function  = <2>; here either.

What you can do, if you insist to just use magic numbers is to combine
them.

#define BCA_PINMUX(function,pin) ((function << 16)|pin)

         rgmii_pins: rgmii-pinmux-pins {
             pinmux = <BCA_PINMUX(1,42), BCA_PINMUX(1, 43),
BCA_PINMUX(1, 44) ....>;
         };

This type of pattern in creating per-pin 32bit values in the pinmux
attribute is acceptable and found in other drivers, and the driver
can then decompose this and use it to poke the registers.

If your tool can output something like that then it can be done.

Yours,
Linus Walleij

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

* Re: [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846
  2025-10-01 22:43       ` Linus Walleij
@ 2025-10-02  6:34         ` William Zhang
  0 siblings, 0 replies; 14+ messages in thread
From: William Zhang @ 2025-10-02  6:34 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafał Miłecki, Broadcom internal kernel review list,
	Anand Gore, Kursad Oney, Florian Fainelli, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree

[-- Attachment #1: Type: text/plain, Size: 6316 bytes --]

On Wed, Oct 1, 2025 at 3:43 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Wed, Oct 1, 2025 at 7:38 PM William Zhang <william.zhang@broadcom.com> wrote:
>
> > > But if you can generate say 6846_pinctrl.dtsi, I guess from some
> > > HW data that the public has no access to, then why can't you
> > > generate bcm6846.c with the same contents as C structs?
> > >
> > We could but we don't prefer to do that because we want the driver to
> > be generic and not requiring any change to support a new chip
>
> But you will be generating big DTSI files.
>
The current DTSI files include many pins that are not really used and
it can be cleaned up to reduce the size for sure.

> And it is not really the ambition of the device tree to be used as a hardware
> abstraction layer containing a lot of per-SoC information. The device
> tree is supposed to describe and configure the hardware, not
> abstract it. There is a difference.
>
> (The DT maintainers can hit me in the head about this but I have
> certainly heard things like this before.)
>
> Alas, there is no hard definition of what this means and indeed
> some drivers in the kernel does define groups and functions
> in the device tree instead of using C files. So that happens too.
>
> > You are absolutely right that the current dtsi does not group the pin
> > properly for certain interfaces such as i2c. The tool has the same
> > goal to combine interfaces in the group whenever possible. It is just
> > we don't have the correct group config for certain interface when
> > generating the dtsi.   If I fix all these group issues and provide the
> > new dtsi files and I will be the contact if you have any question
> > regarding generator files,  would it be possible for you to use and
> > upstream that driver?
>
> I assume you fear having to follow the pattern and hand-code
> a C file for every BCA SoC and never get done. I understand that.
> Also I try to live by the stance "rough consensus and running
> code" and not be too strong in pushing things my way.
>
> We can do this if the files follows some basic process.
> You still need to use proper bindings.
> This:
>
> >         rgmii_pins: rgmii_pinmux {
> >             pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
> >             function = <1>;
> >         };
>
> This isn't proper bindings.
> Documentation/devicetree/bindings/pinctrl/pinmux-node.yaml
> describe the bindings you can use.
>
> properties:
>   function:
>     $ref: /schemas/types.yaml#/definitions/string
>     description: The mux function to select
>
>   pins:
>     oneOf:
>       - $ref: /schemas/types.yaml#/definitions/uint32-array
>       - $ref: /schemas/types.yaml#/definitions/string-array
>     description:
>       The list of pin identifiers that properties in the node apply to. The
>       specific binding for the hardware defines whether the entries are integers
>       or strings, and their meaning.
>
>   groups:
>     $ref: /schemas/types.yaml#/definitions/string-array
>     description:
>       the group to apply the properties to, if the driver supports
>       configuration of whole groups rather than individual pins (either
>       this, "pins" or "pinmux" has to be specified)
>
>   pinmux:
>     description:
>       The list of numeric pin ids and their mux settings that properties in the
>       node apply to (either this, "pins" or "groups" have to be specified)
>     $ref: /schemas/types.yaml#/definitions/uint32-array
>
>   pinctrl-pin-array:
>     $ref: /schemas/types.yaml#/definitions/uint32-array
>
> function cannot be a number like that, it is intended to be string such as
> "spi" or "uart0".
>
> E.g.
>
>          rgmii_pins: rgmii_pinmux {
>              pins = <42 43 44 45 46 47 48 49 50 51 52 53>;
>              function = "rgmii";
>          };
>
Thanks for pointing this out.  I didn't realize that function has to
be a string.  But I did see some other vendor use something like
<vendor>,func = <1> but I guess it is not encouraged any more.
But using a string for the function also means we have to add the
table/mapping in the driver code to translate the string to the
function number.  Then this defeats the goal of not changing the code.

> This also makes sense for at least BCM6846 because the include file
> have things like this:
>
>         b_wan_early_txen_pin_4: b_wan_early_txen_pinmux {
>             pins = <4>;
>             function = <1>;
>         };
>
>         b_wan_nco_1pps_sig_pin_6: b_wan_nco_1pps_sig_pinmux {
>             pins = <6>;
>             function = <2>;
>         };
>
> Completely different function numbers, still both are related to WAN,
> which is what pin control refers to as a function.
>
Well this is just how the SoC assigns the pin and its internal
function.  Although they both are related WAN block, they serve
completely different purposes and probably for different type of WAN
interface and may not be used at the same time.  So different function
numbers seems reasonable to me.

> I do understand that the "function" number is actually just a mux setting
> for that pin. But this isn't very standardized or very helpful.
>
> Also, we don't really want to see more custom properties such as
> brcm,function  = <2>; here either.
>
> What you can do, if you insist to just use magic numbers is to combine
> them.
>
> #define BCA_PINMUX(function,pin) ((function << 16)|pin)
>
>          rgmii_pins: rgmii-pinmux-pins {
>              pinmux = <BCA_PINMUX(1,42), BCA_PINMUX(1, 43),
> BCA_PINMUX(1, 44) ....>;
>          };
>
> This type of pattern in creating per-pin 32bit values in the pinmux
> attribute is acceptable and found in other drivers, and the driver
> can then decompose this and use it to poke the registers.
>
> If your tool can output something like that then it can be done.
>
Yes I can certainly enhance the tool to generate this format of pinmux
info.  It seems to be a viable path to make the pinmux driver generic
while still meeting pinctrl dts binding requirement.   I can provide
you with an updated the 6846_pinctrl.dtsi file as soon as I can,
hopefully tomorrow.   Would you be willing to try it out?

> Yours,
> Linus Walleij

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5473 bytes --]

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

end of thread, other threads:[~2025-10-02  6:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-30 12:02 [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 Linus Walleij
2025-09-30 12:02 ` [PATCH 1/6] pinctrl: bcm: Rename bcm4908 to bcmbca Linus Walleij
2025-09-30 12:02 ` [PATCH 2/6] pinctrl: bcm: bcmbca: Parameterize pins, groups, funcs Linus Walleij
2025-09-30 12:02 ` [PATCH 3/6] pinctrl: bcm: bcmbca: Prefix all BCM4908 data Linus Walleij
2025-09-30 12:02 ` [PATCH 4/6] pinctrl: bcm: bcmbca: Use a guarded mutex Linus Walleij
2025-09-30 12:02 ` [PATCH 5/6] dt-bindings: pinctrl: Add binding for BCM6846 pinctrl Linus Walleij
2025-10-01 12:54   ` Rob Herring
2025-09-30 12:02 ` [PATCH 6/6] pinctrl: bcm: bcmbca: Add support for BCM6846 Linus Walleij
2025-10-01  0:44   ` kernel test robot
2025-10-01  6:42 ` [PATCH 0/6] pinctrl: bcmbca: Refactor and add BCM6846 William Zhang
2025-10-01  7:59   ` Linus Walleij
2025-10-01 17:37     ` William Zhang
2025-10-01 22:43       ` Linus Walleij
2025-10-02  6:34         ` William Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).