linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] pinctrl: zynqmp: Support muxing individual pins
@ 2024-05-20 15:04 Sean Anderson
  2024-05-20 15:04 ` [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins Sean Anderson
  2024-05-20 15:04 ` [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
  0 siblings, 2 replies; 6+ messages in thread
From: Sean Anderson @ 2024-05-20 15:04 UTC (permalink / raw)
  To: Linus Walleij, Michal Simek, linux-gpio
  Cc: Krishna Potthuri, linux-kernel, Andy Shevchenko, linux-arm-kernel,
	Sean Anderson, Conor Dooley, Krzysztof Kozlowski, Rob Herring,
	devicetree

This series adds support for muxing individual pins, instead of
requiring groups to be muxed together. See [1] for additional
discussion.

[1] https://lore.kernel.org/linux-arm-kernel/5bb0dc7e-4c89-4f3d-abc6-41ae9ded5ae9@linux.dev/

Changes in v2:
- Use __set_bit instead of set_bit
- Use size_add when calculating the number of kcalloc members
- Expand commit message with some more motivation

Sean Anderson (2):
  dt-bindings: pinctrl: xilinx: Add support for function with pins
  pinctrl: zynqmp: Support muxing individual pins

 .../bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml | 344 +++++++++---------
 drivers/pinctrl/pinctrl-zynqmp.c              |  61 +++-
 2 files changed, 219 insertions(+), 186 deletions(-)

-- 
2.35.1.1320.gc452695387.dirty


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

* [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins
  2024-05-20 15:04 [PATCH v2 0/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
@ 2024-05-20 15:04 ` Sean Anderson
  2024-05-22 14:48   ` Rob Herring
  2024-05-20 15:04 ` [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
  1 sibling, 1 reply; 6+ messages in thread
From: Sean Anderson @ 2024-05-20 15:04 UTC (permalink / raw)
  To: Linus Walleij, Michal Simek, linux-gpio
  Cc: Krishna Potthuri, linux-kernel, Andy Shevchenko, linux-arm-kernel,
	Sean Anderson, Conor Dooley, Krzysztof Kozlowski, Rob Herring,
	devicetree

Support specifying the function per-pin. The driver doesn't care
whethern you use pins or groups for this purpose.

Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

(no changes since v1)

 .../bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml | 344 +++++++++---------
 1 file changed, 176 insertions(+), 168 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
index f13d315b5d5e..d3b258245e28 100644
--- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
@@ -42,179 +42,187 @@ patternProperties:
         $ref: pinmux-node.yaml#
 
         properties:
+          pins:
+            description:
+              List of pins to select (either this or "groups" must be specified)
+            items:
+              pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$'
+
           groups:
             description:
               List of groups to select (either this or "pins" must be
               specified), available groups for this subnode.
             items:
-              enum: [ethernet0_0_grp, ethernet1_0_grp, ethernet2_0_grp,
-                     ethernet3_0_grp, gemtsu0_0_grp, gemtsu0_1_grp,
-                     gemtsu0_2_grp, mdio0_0_grp, mdio1_0_grp,
-                     mdio1_1_grp, mdio2_0_grp, mdio3_0_grp,
-                     qspi0_0_grp, qspi_ss_0_grp, qspi_fbclk_0_grp,
-                     spi0_0_grp, spi0_ss_0_grp, spi0_ss_1_grp,
-                     spi0_ss_2_grp, spi0_1_grp, spi0_ss_3_grp,
-                     spi0_ss_4_grp, spi0_ss_5_grp, spi0_2_grp,
-                     spi0_ss_6_grp, spi0_ss_7_grp, spi0_ss_8_grp,
-                     spi0_3_grp, spi0_ss_9_grp, spi0_ss_10_grp,
-                     spi0_ss_11_grp, spi0_4_grp, spi0_ss_12_grp,
-                     spi0_ss_13_grp, spi0_ss_14_grp, spi0_5_grp,
-                     spi0_ss_15_grp, spi0_ss_16_grp, spi0_ss_17_grp,
-                     spi1_0_grp, spi1_ss_0_grp, spi1_ss_1_grp,
-                     spi1_ss_2_grp, spi1_1_grp, spi1_ss_3_grp,
-                     spi1_ss_4_grp, spi1_ss_5_grp, spi1_2_grp,
-                     spi1_ss_6_grp, spi1_ss_7_grp, spi1_ss_8_grp,
-                     spi1_3_grp, spi1_ss_9_grp, spi1_ss_10_grp,
-                     spi1_ss_11_grp, spi1_4_grp, spi1_ss_12_grp,
-                     spi1_ss_13_grp, spi1_ss_14_grp, spi1_5_grp,
-                     spi1_ss_15_grp, spi1_ss_16_grp, spi1_ss_17_grp,
-                     sdio0_0_grp, sdio0_1_grp, sdio0_2_grp,
-                     sdio0_3_grp, sdio0_4_grp, sdio0_5_grp,
-                     sdio0_6_grp, sdio0_7_grp, sdio0_8_grp,
-                     sdio0_9_grp, sdio0_10_grp, sdio0_11_grp,
-                     sdio0_12_grp, sdio0_13_grp, sdio0_14_grp,
-                     sdio0_15_grp, sdio0_16_grp, sdio0_17_grp,
-                     sdio0_18_grp, sdio0_19_grp, sdio0_20_grp,
-                     sdio0_21_grp, sdio0_22_grp, sdio0_23_grp,
-                     sdio0_24_grp, sdio0_25_grp, sdio0_26_grp,
-                     sdio0_27_grp, sdio0_28_grp, sdio0_29_grp,
-                     sdio0_30_grp, sdio0_31_grp, sdio0_32_grp,
-                     sdio0_pc_0_grp, sdio0_cd_0_grp, sdio0_wp_0_grp,
-                     sdio0_pc_1_grp, sdio0_cd_1_grp, sdio0_wp_1_grp,
-                     sdio0_pc_2_grp, sdio0_cd_2_grp, sdio0_wp_2_grp,
-                     sdio1_0_grp, sdio1_1_grp, sdio1_2_grp,
-                     sdio1_3_grp, sdio1_4_grp, sdio1_5_grp,
-                     sdio1_6_grp, sdio1_7_grp, sdio1_8_grp,
-                     sdio1_9_grp, sdio1_10_grp, sdio1_11_grp,
-                     sdio1_12_grp, sdio1_13_grp, sdio1_14_grp,
-                     sdio1_15_grp, sdio1_pc_0_grp, sdio1_cd_0_grp,
-                     sdio1_wp_0_grp, sdio1_pc_1_grp, sdio1_cd_1_grp,
-                     sdio1_wp_1_grp, nand0_0_grp, nand0_ce_0_grp,
-                     nand0_rb_0_grp, nand0_dqs_0_grp, nand0_ce_1_grp,
-                     nand0_rb_1_grp, nand0_dqs_1_grp, can0_0_grp,
-                     can0_1_grp, can0_2_grp, can0_3_grp,
-                     can0_4_grp, can0_5_grp, can0_6_grp,
-                     can0_7_grp, can0_8_grp, can0_9_grp,
-                     can0_10_grp, can0_11_grp, can0_12_grp,
-                     can0_13_grp, can0_14_grp, can0_15_grp,
-                     can0_16_grp, can0_17_grp, can0_18_grp,
-                     can1_0_grp, can1_1_grp, can1_2_grp,
-                     can1_3_grp, can1_4_grp, can1_5_grp,
-                     can1_6_grp, can1_7_grp, can1_8_grp,
-                     can1_9_grp, can1_10_grp, can1_11_grp,
-                     can1_12_grp, can1_13_grp, can1_14_grp,
-                     can1_15_grp, can1_16_grp, can1_17_grp,
-                     can1_18_grp, can1_19_grp, uart0_0_grp,
-                     uart0_1_grp, uart0_2_grp, uart0_3_grp,
-                     uart0_4_grp, uart0_5_grp, uart0_6_grp,
-                     uart0_7_grp, uart0_8_grp, uart0_9_grp,
-                     uart0_10_grp, uart0_11_grp, uart0_12_grp,
-                     uart0_13_grp, uart0_14_grp, uart0_15_grp,
-                     uart0_16_grp, uart0_17_grp, uart0_18_grp,
-                     uart1_0_grp, uart1_1_grp, uart1_2_grp,
-                     uart1_3_grp, uart1_4_grp, uart1_5_grp,
-                     uart1_6_grp, uart1_7_grp, uart1_8_grp,
-                     uart1_9_grp, uart1_10_grp, uart1_11_grp,
-                     uart1_12_grp, uart1_13_grp, uart1_14_grp,
-                     uart1_15_grp, uart1_16_grp, uart1_17_grp,
-                     uart1_18_grp, i2c0_0_grp, i2c0_1_grp,
-                     i2c0_2_grp, i2c0_3_grp, i2c0_4_grp,
-                     i2c0_5_grp, i2c0_6_grp, i2c0_7_grp,
-                     i2c0_8_grp, i2c0_9_grp, i2c0_10_grp,
-                     i2c0_11_grp, i2c0_12_grp, i2c0_13_grp,
-                     i2c0_14_grp, i2c0_15_grp, i2c0_16_grp,
-                     i2c0_17_grp, i2c0_18_grp, i2c1_0_grp,
-                     i2c1_1_grp, i2c1_2_grp, i2c1_3_grp,
-                     i2c1_4_grp, i2c1_5_grp, i2c1_6_grp,
-                     i2c1_7_grp, i2c1_8_grp, i2c1_9_grp,
-                     i2c1_10_grp, i2c1_11_grp, i2c1_12_grp,
-                     i2c1_13_grp, i2c1_14_grp, i2c1_15_grp,
-                     i2c1_16_grp, i2c1_17_grp, i2c1_18_grp,
-                     i2c1_19_grp, ttc0_clk_0_grp, ttc0_wav_0_grp,
-                     ttc0_clk_1_grp, ttc0_wav_1_grp, ttc0_clk_2_grp,
-                     ttc0_wav_2_grp, ttc0_clk_3_grp, ttc0_wav_3_grp,
-                     ttc0_clk_4_grp, ttc0_wav_4_grp, ttc0_clk_5_grp,
-                     ttc0_wav_5_grp, ttc0_clk_6_grp, ttc0_wav_6_grp,
-                     ttc0_clk_7_grp, ttc0_wav_7_grp, ttc0_clk_8_grp,
-                     ttc0_wav_8_grp, ttc1_clk_0_grp, ttc1_wav_0_grp,
-                     ttc1_clk_1_grp, ttc1_wav_1_grp, ttc1_clk_2_grp,
-                     ttc1_wav_2_grp, ttc1_clk_3_grp, ttc1_wav_3_grp,
-                     ttc1_clk_4_grp, ttc1_wav_4_grp, ttc1_clk_5_grp,
-                     ttc1_wav_5_grp, ttc1_clk_6_grp, ttc1_wav_6_grp,
-                     ttc1_clk_7_grp, ttc1_wav_7_grp, ttc1_clk_8_grp,
-                     ttc1_wav_8_grp, ttc2_clk_0_grp, ttc2_wav_0_grp,
-                     ttc2_clk_1_grp, ttc2_wav_1_grp, ttc2_clk_2_grp,
-                     ttc2_wav_2_grp, ttc2_clk_3_grp, ttc2_wav_3_grp,
-                     ttc2_clk_4_grp, ttc2_wav_4_grp, ttc2_clk_5_grp,
-                     ttc2_wav_5_grp, ttc2_clk_6_grp, ttc2_wav_6_grp,
-                     ttc2_clk_7_grp, ttc2_wav_7_grp, ttc2_clk_8_grp,
-                     ttc2_wav_8_grp, ttc3_clk_0_grp, ttc3_wav_0_grp,
-                     ttc3_clk_1_grp, ttc3_wav_1_grp, ttc3_clk_2_grp,
-                     ttc3_wav_2_grp, ttc3_clk_3_grp, ttc3_wav_3_grp,
-                     ttc3_clk_4_grp, ttc3_wav_4_grp, ttc3_clk_5_grp,
-                     ttc3_wav_5_grp, ttc3_clk_6_grp, ttc3_wav_6_grp,
-                     ttc3_clk_7_grp, ttc3_wav_7_grp, ttc3_clk_8_grp,
-                     ttc3_wav_8_grp, swdt0_clk_0_grp, swdt0_rst_0_grp,
-                     swdt0_clk_1_grp, swdt0_rst_1_grp, swdt0_clk_2_grp,
-                     swdt0_rst_2_grp, swdt0_clk_3_grp, swdt0_rst_3_grp,
-                     swdt0_clk_4_grp, swdt0_rst_4_grp, swdt0_clk_5_grp,
-                     swdt0_rst_5_grp, swdt0_clk_6_grp, swdt0_rst_6_grp,
-                     swdt0_clk_7_grp, swdt0_rst_7_grp, swdt0_clk_8_grp,
-                     swdt0_rst_8_grp, swdt0_clk_9_grp, swdt0_rst_9_grp,
-                     swdt0_clk_10_grp, swdt0_rst_10_grp, swdt0_clk_11_grp,
-                     swdt0_rst_11_grp, swdt0_clk_12_grp, swdt0_rst_12_grp,
-                     swdt1_clk_0_grp, swdt1_rst_0_grp, swdt1_clk_1_grp,
-                     swdt1_rst_1_grp, swdt1_clk_2_grp, swdt1_rst_2_grp,
-                     swdt1_clk_3_grp, swdt1_rst_3_grp, swdt1_clk_4_grp,
-                     swdt1_rst_4_grp, swdt1_clk_5_grp, swdt1_rst_5_grp,
-                     swdt1_clk_6_grp, swdt1_rst_6_grp, swdt1_clk_7_grp,
-                     swdt1_rst_7_grp, swdt1_clk_8_grp, swdt1_rst_8_grp,
-                     swdt1_clk_9_grp, swdt1_rst_9_grp, swdt1_clk_10_grp,
-                     swdt1_rst_10_grp, swdt1_clk_11_grp, swdt1_rst_11_grp,
-                     swdt1_clk_12_grp, swdt1_rst_12_grp, gpio0_0_grp,
-                     gpio0_1_grp, gpio0_2_grp, gpio0_3_grp,
-                     gpio0_4_grp, gpio0_5_grp, gpio0_6_grp,
-                     gpio0_7_grp, gpio0_8_grp, gpio0_9_grp,
-                     gpio0_10_grp, gpio0_11_grp, gpio0_12_grp,
-                     gpio0_13_grp, gpio0_14_grp, gpio0_15_grp,
-                     gpio0_16_grp, gpio0_17_grp, gpio0_18_grp,
-                     gpio0_19_grp, gpio0_20_grp, gpio0_21_grp,
-                     gpio0_22_grp, gpio0_23_grp, gpio0_24_grp,
-                     gpio0_25_grp, gpio0_26_grp, gpio0_27_grp,
-                     gpio0_28_grp, gpio0_29_grp, gpio0_30_grp,
-                     gpio0_31_grp, gpio0_32_grp, gpio0_33_grp,
-                     gpio0_34_grp, gpio0_35_grp, gpio0_36_grp,
-                     gpio0_37_grp, gpio0_38_grp, gpio0_39_grp,
-                     gpio0_40_grp, gpio0_41_grp, gpio0_42_grp,
-                     gpio0_43_grp, gpio0_44_grp, gpio0_45_grp,
-                     gpio0_46_grp, gpio0_47_grp, gpio0_48_grp,
-                     gpio0_49_grp, gpio0_50_grp, gpio0_51_grp,
-                     gpio0_52_grp, gpio0_53_grp, gpio0_54_grp,
-                     gpio0_55_grp, gpio0_56_grp, gpio0_57_grp,
-                     gpio0_58_grp, gpio0_59_grp, gpio0_60_grp,
-                     gpio0_61_grp, gpio0_62_grp, gpio0_63_grp,
-                     gpio0_64_grp, gpio0_65_grp, gpio0_66_grp,
-                     gpio0_67_grp, gpio0_68_grp, gpio0_69_grp,
-                     gpio0_70_grp, gpio0_71_grp, gpio0_72_grp,
-                     gpio0_73_grp, gpio0_74_grp, gpio0_75_grp,
-                     gpio0_76_grp, gpio0_77_grp, usb0_0_grp,
-                     usb1_0_grp, pmu0_0_grp, pmu0_1_grp,
-                     pmu0_2_grp, pmu0_3_grp, pmu0_4_grp,
-                     pmu0_5_grp, pmu0_6_grp, pmu0_7_grp,
-                     pmu0_8_grp, pmu0_9_grp, pmu0_10_grp,
-                     pmu0_11_grp, pcie0_0_grp, pcie0_1_grp,
-                     pcie0_2_grp, pcie0_3_grp, pcie0_4_grp,
-                     pcie0_5_grp, pcie0_6_grp, pcie0_7_grp,
-                     csu0_0_grp, csu0_1_grp, csu0_2_grp,
-                     csu0_3_grp, csu0_4_grp, csu0_5_grp,
-                     csu0_6_grp, csu0_7_grp, csu0_8_grp,
-                     csu0_9_grp, csu0_10_grp, csu0_11_grp,
-                     dpaux0_0_grp, dpaux0_1_grp, dpaux0_2_grp,
-                     dpaux0_3_grp, pjtag0_0_grp, pjtag0_1_grp,
-                     pjtag0_2_grp, pjtag0_3_grp, pjtag0_4_grp,
-                     pjtag0_5_grp, trace0_0_grp, trace0_clk_0_grp,
-                     trace0_1_grp, trace0_clk_1_grp, trace0_2_grp,
-                     trace0_clk_2_grp, testscan0_0_grp]
+              anyOf:
+                - pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$'
+                - enum: [ethernet0_0_grp, ethernet1_0_grp, ethernet2_0_grp,
+                         ethernet3_0_grp, gemtsu0_0_grp, gemtsu0_1_grp,
+                         gemtsu0_2_grp, mdio0_0_grp, mdio1_0_grp,
+                         mdio1_1_grp, mdio2_0_grp, mdio3_0_grp,
+                         qspi0_0_grp, qspi_ss_0_grp, qspi_fbclk_0_grp,
+                         spi0_0_grp, spi0_ss_0_grp, spi0_ss_1_grp,
+                         spi0_ss_2_grp, spi0_1_grp, spi0_ss_3_grp,
+                         spi0_ss_4_grp, spi0_ss_5_grp, spi0_2_grp,
+                         spi0_ss_6_grp, spi0_ss_7_grp, spi0_ss_8_grp,
+                         spi0_3_grp, spi0_ss_9_grp, spi0_ss_10_grp,
+                         spi0_ss_11_grp, spi0_4_grp, spi0_ss_12_grp,
+                         spi0_ss_13_grp, spi0_ss_14_grp, spi0_5_grp,
+                         spi0_ss_15_grp, spi0_ss_16_grp, spi0_ss_17_grp,
+                         spi1_0_grp, spi1_ss_0_grp, spi1_ss_1_grp,
+                         spi1_ss_2_grp, spi1_1_grp, spi1_ss_3_grp,
+                         spi1_ss_4_grp, spi1_ss_5_grp, spi1_2_grp,
+                         spi1_ss_6_grp, spi1_ss_7_grp, spi1_ss_8_grp,
+                         spi1_3_grp, spi1_ss_9_grp, spi1_ss_10_grp,
+                         spi1_ss_11_grp, spi1_4_grp, spi1_ss_12_grp,
+                         spi1_ss_13_grp, spi1_ss_14_grp, spi1_5_grp,
+                         spi1_ss_15_grp, spi1_ss_16_grp, spi1_ss_17_grp,
+                         sdio0_0_grp, sdio0_1_grp, sdio0_2_grp,
+                         sdio0_3_grp, sdio0_4_grp, sdio0_5_grp,
+                         sdio0_6_grp, sdio0_7_grp, sdio0_8_grp,
+                         sdio0_9_grp, sdio0_10_grp, sdio0_11_grp,
+                         sdio0_12_grp, sdio0_13_grp, sdio0_14_grp,
+                         sdio0_15_grp, sdio0_16_grp, sdio0_17_grp,
+                         sdio0_18_grp, sdio0_19_grp, sdio0_20_grp,
+                         sdio0_21_grp, sdio0_22_grp, sdio0_23_grp,
+                         sdio0_24_grp, sdio0_25_grp, sdio0_26_grp,
+                         sdio0_27_grp, sdio0_28_grp, sdio0_29_grp,
+                         sdio0_30_grp, sdio0_31_grp, sdio0_32_grp,
+                         sdio0_pc_0_grp, sdio0_cd_0_grp, sdio0_wp_0_grp,
+                         sdio0_pc_1_grp, sdio0_cd_1_grp, sdio0_wp_1_grp,
+                         sdio0_pc_2_grp, sdio0_cd_2_grp, sdio0_wp_2_grp,
+                         sdio1_0_grp, sdio1_1_grp, sdio1_2_grp,
+                         sdio1_3_grp, sdio1_4_grp, sdio1_5_grp,
+                         sdio1_6_grp, sdio1_7_grp, sdio1_8_grp,
+                         sdio1_9_grp, sdio1_10_grp, sdio1_11_grp,
+                         sdio1_12_grp, sdio1_13_grp, sdio1_14_grp,
+                         sdio1_15_grp, sdio1_pc_0_grp, sdio1_cd_0_grp,
+                         sdio1_wp_0_grp, sdio1_pc_1_grp, sdio1_cd_1_grp,
+                         sdio1_wp_1_grp, nand0_0_grp, nand0_ce_0_grp,
+                         nand0_rb_0_grp, nand0_dqs_0_grp, nand0_ce_1_grp,
+                         nand0_rb_1_grp, nand0_dqs_1_grp, can0_0_grp,
+                         can0_1_grp, can0_2_grp, can0_3_grp,
+                         can0_4_grp, can0_5_grp, can0_6_grp,
+                         can0_7_grp, can0_8_grp, can0_9_grp,
+                         can0_10_grp, can0_11_grp, can0_12_grp,
+                         can0_13_grp, can0_14_grp, can0_15_grp,
+                         can0_16_grp, can0_17_grp, can0_18_grp,
+                         can1_0_grp, can1_1_grp, can1_2_grp,
+                         can1_3_grp, can1_4_grp, can1_5_grp,
+                         can1_6_grp, can1_7_grp, can1_8_grp,
+                         can1_9_grp, can1_10_grp, can1_11_grp,
+                         can1_12_grp, can1_13_grp, can1_14_grp,
+                         can1_15_grp, can1_16_grp, can1_17_grp,
+                         can1_18_grp, can1_19_grp, uart0_0_grp,
+                         uart0_1_grp, uart0_2_grp, uart0_3_grp,
+                         uart0_4_grp, uart0_5_grp, uart0_6_grp,
+                         uart0_7_grp, uart0_8_grp, uart0_9_grp,
+                         uart0_10_grp, uart0_11_grp, uart0_12_grp,
+                         uart0_13_grp, uart0_14_grp, uart0_15_grp,
+                         uart0_16_grp, uart0_17_grp, uart0_18_grp,
+                         uart1_0_grp, uart1_1_grp, uart1_2_grp,
+                         uart1_3_grp, uart1_4_grp, uart1_5_grp,
+                         uart1_6_grp, uart1_7_grp, uart1_8_grp,
+                         uart1_9_grp, uart1_10_grp, uart1_11_grp,
+                         uart1_12_grp, uart1_13_grp, uart1_14_grp,
+                         uart1_15_grp, uart1_16_grp, uart1_17_grp,
+                         uart1_18_grp, i2c0_0_grp, i2c0_1_grp,
+                         i2c0_2_grp, i2c0_3_grp, i2c0_4_grp,
+                         i2c0_5_grp, i2c0_6_grp, i2c0_7_grp,
+                         i2c0_8_grp, i2c0_9_grp, i2c0_10_grp,
+                         i2c0_11_grp, i2c0_12_grp, i2c0_13_grp,
+                         i2c0_14_grp, i2c0_15_grp, i2c0_16_grp,
+                         i2c0_17_grp, i2c0_18_grp, i2c1_0_grp,
+                         i2c1_1_grp, i2c1_2_grp, i2c1_3_grp,
+                         i2c1_4_grp, i2c1_5_grp, i2c1_6_grp,
+                         i2c1_7_grp, i2c1_8_grp, i2c1_9_grp,
+                         i2c1_10_grp, i2c1_11_grp, i2c1_12_grp,
+                         i2c1_13_grp, i2c1_14_grp, i2c1_15_grp,
+                         i2c1_16_grp, i2c1_17_grp, i2c1_18_grp,
+                         i2c1_19_grp, ttc0_clk_0_grp, ttc0_wav_0_grp,
+                         ttc0_clk_1_grp, ttc0_wav_1_grp, ttc0_clk_2_grp,
+                         ttc0_wav_2_grp, ttc0_clk_3_grp, ttc0_wav_3_grp,
+                         ttc0_clk_4_grp, ttc0_wav_4_grp, ttc0_clk_5_grp,
+                         ttc0_wav_5_grp, ttc0_clk_6_grp, ttc0_wav_6_grp,
+                         ttc0_clk_7_grp, ttc0_wav_7_grp, ttc0_clk_8_grp,
+                         ttc0_wav_8_grp, ttc1_clk_0_grp, ttc1_wav_0_grp,
+                         ttc1_clk_1_grp, ttc1_wav_1_grp, ttc1_clk_2_grp,
+                         ttc1_wav_2_grp, ttc1_clk_3_grp, ttc1_wav_3_grp,
+                         ttc1_clk_4_grp, ttc1_wav_4_grp, ttc1_clk_5_grp,
+                         ttc1_wav_5_grp, ttc1_clk_6_grp, ttc1_wav_6_grp,
+                         ttc1_clk_7_grp, ttc1_wav_7_grp, ttc1_clk_8_grp,
+                         ttc1_wav_8_grp, ttc2_clk_0_grp, ttc2_wav_0_grp,
+                         ttc2_clk_1_grp, ttc2_wav_1_grp, ttc2_clk_2_grp,
+                         ttc2_wav_2_grp, ttc2_clk_3_grp, ttc2_wav_3_grp,
+                         ttc2_clk_4_grp, ttc2_wav_4_grp, ttc2_clk_5_grp,
+                         ttc2_wav_5_grp, ttc2_clk_6_grp, ttc2_wav_6_grp,
+                         ttc2_clk_7_grp, ttc2_wav_7_grp, ttc2_clk_8_grp,
+                         ttc2_wav_8_grp, ttc3_clk_0_grp, ttc3_wav_0_grp,
+                         ttc3_clk_1_grp, ttc3_wav_1_grp, ttc3_clk_2_grp,
+                         ttc3_wav_2_grp, ttc3_clk_3_grp, ttc3_wav_3_grp,
+                         ttc3_clk_4_grp, ttc3_wav_4_grp, ttc3_clk_5_grp,
+                         ttc3_wav_5_grp, ttc3_clk_6_grp, ttc3_wav_6_grp,
+                         ttc3_clk_7_grp, ttc3_wav_7_grp, ttc3_clk_8_grp,
+                         ttc3_wav_8_grp, swdt0_clk_0_grp, swdt0_rst_0_grp,
+                         swdt0_clk_1_grp, swdt0_rst_1_grp, swdt0_clk_2_grp,
+                         swdt0_rst_2_grp, swdt0_clk_3_grp, swdt0_rst_3_grp,
+                         swdt0_clk_4_grp, swdt0_rst_4_grp, swdt0_clk_5_grp,
+                         swdt0_rst_5_grp, swdt0_clk_6_grp, swdt0_rst_6_grp,
+                         swdt0_clk_7_grp, swdt0_rst_7_grp, swdt0_clk_8_grp,
+                         swdt0_rst_8_grp, swdt0_clk_9_grp, swdt0_rst_9_grp,
+                         swdt0_clk_10_grp, swdt0_rst_10_grp, swdt0_clk_11_grp,
+                         swdt0_rst_11_grp, swdt0_clk_12_grp, swdt0_rst_12_grp,
+                         swdt1_clk_0_grp, swdt1_rst_0_grp, swdt1_clk_1_grp,
+                         swdt1_rst_1_grp, swdt1_clk_2_grp, swdt1_rst_2_grp,
+                         swdt1_clk_3_grp, swdt1_rst_3_grp, swdt1_clk_4_grp,
+                         swdt1_rst_4_grp, swdt1_clk_5_grp, swdt1_rst_5_grp,
+                         swdt1_clk_6_grp, swdt1_rst_6_grp, swdt1_clk_7_grp,
+                         swdt1_rst_7_grp, swdt1_clk_8_grp, swdt1_rst_8_grp,
+                         swdt1_clk_9_grp, swdt1_rst_9_grp, swdt1_clk_10_grp,
+                         swdt1_rst_10_grp, swdt1_clk_11_grp, swdt1_rst_11_grp,
+                         swdt1_clk_12_grp, swdt1_rst_12_grp, gpio0_0_grp,
+                         gpio0_1_grp, gpio0_2_grp, gpio0_3_grp,
+                         gpio0_4_grp, gpio0_5_grp, gpio0_6_grp,
+                         gpio0_7_grp, gpio0_8_grp, gpio0_9_grp,
+                         gpio0_10_grp, gpio0_11_grp, gpio0_12_grp,
+                         gpio0_13_grp, gpio0_14_grp, gpio0_15_grp,
+                         gpio0_16_grp, gpio0_17_grp, gpio0_18_grp,
+                         gpio0_19_grp, gpio0_20_grp, gpio0_21_grp,
+                         gpio0_22_grp, gpio0_23_grp, gpio0_24_grp,
+                         gpio0_25_grp, gpio0_26_grp, gpio0_27_grp,
+                         gpio0_28_grp, gpio0_29_grp, gpio0_30_grp,
+                         gpio0_31_grp, gpio0_32_grp, gpio0_33_grp,
+                         gpio0_34_grp, gpio0_35_grp, gpio0_36_grp,
+                         gpio0_37_grp, gpio0_38_grp, gpio0_39_grp,
+                         gpio0_40_grp, gpio0_41_grp, gpio0_42_grp,
+                         gpio0_43_grp, gpio0_44_grp, gpio0_45_grp,
+                         gpio0_46_grp, gpio0_47_grp, gpio0_48_grp,
+                         gpio0_49_grp, gpio0_50_grp, gpio0_51_grp,
+                         gpio0_52_grp, gpio0_53_grp, gpio0_54_grp,
+                         gpio0_55_grp, gpio0_56_grp, gpio0_57_grp,
+                         gpio0_58_grp, gpio0_59_grp, gpio0_60_grp,
+                         gpio0_61_grp, gpio0_62_grp, gpio0_63_grp,
+                         gpio0_64_grp, gpio0_65_grp, gpio0_66_grp,
+                         gpio0_67_grp, gpio0_68_grp, gpio0_69_grp,
+                         gpio0_70_grp, gpio0_71_grp, gpio0_72_grp,
+                         gpio0_73_grp, gpio0_74_grp, gpio0_75_grp,
+                         gpio0_76_grp, gpio0_77_grp, usb0_0_grp,
+                         usb1_0_grp, pmu0_0_grp, pmu0_1_grp,
+                         pmu0_2_grp, pmu0_3_grp, pmu0_4_grp,
+                         pmu0_5_grp, pmu0_6_grp, pmu0_7_grp,
+                         pmu0_8_grp, pmu0_9_grp, pmu0_10_grp,
+                         pmu0_11_grp, pcie0_0_grp, pcie0_1_grp,
+                         pcie0_2_grp, pcie0_3_grp, pcie0_4_grp,
+                         pcie0_5_grp, pcie0_6_grp, pcie0_7_grp,
+                         csu0_0_grp, csu0_1_grp, csu0_2_grp,
+                         csu0_3_grp, csu0_4_grp, csu0_5_grp,
+                         csu0_6_grp, csu0_7_grp, csu0_8_grp,
+                         csu0_9_grp, csu0_10_grp, csu0_11_grp,
+                         dpaux0_0_grp, dpaux0_1_grp, dpaux0_2_grp,
+                         dpaux0_3_grp, pjtag0_0_grp, pjtag0_1_grp,
+                         pjtag0_2_grp, pjtag0_3_grp, pjtag0_4_grp,
+                         pjtag0_5_grp, trace0_0_grp, trace0_clk_0_grp,
+                         trace0_1_grp, trace0_clk_1_grp, trace0_2_grp,
+                         trace0_clk_2_grp, testscan0_0_grp]
             maxItems: 78
 
           function:
-- 
2.35.1.1320.gc452695387.dirty


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

* [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins
  2024-05-20 15:04 [PATCH v2 0/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
  2024-05-20 15:04 ` [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins Sean Anderson
@ 2024-05-20 15:04 ` Sean Anderson
  2024-06-10 12:16   ` Potthuri, Sai Krishna
  1 sibling, 1 reply; 6+ messages in thread
From: Sean Anderson @ 2024-05-20 15:04 UTC (permalink / raw)
  To: Linus Walleij, Michal Simek, linux-gpio
  Cc: Krishna Potthuri, linux-kernel, Andy Shevchenko, linux-arm-kernel,
	Sean Anderson

While muxing groups of pins at once can be convenient for large
interfaces, it can also be rigid. This is because the group is set to
all pins which support a particular function, even though not all pins
may be used. For example, the sdhci0 function may be used with a 8-bit
eMMC, 4-bit SD card, or even a 1-bit SD card. In these cases, the extra
pins may be repurposed for other uses, but this is not currently
allowed.

There is not too much point in pin "groups" when there are not actual
pin groups at the hardware level. The pins can all be muxed
individually, so there's no point in adding artificial groups on top.
Just mux the pins like the hardware allows.

To this effect, add a new group for each pin which can be muxed. These
groups are part of each function the pin can be muxed to. We treat group
selectors beyond the number of groups as "pin" groups. To set this up,
we initialize groups before functions, and then create a bitmap of used
pins for each function. These used pins are appended to the function's
list of groups.

Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

Changes in v2:
- Use __set_bit instead of set_bit
- Use size_add when calculating the number of kcalloc members
- Expand commit message with some more motivation

 drivers/pinctrl/pinctrl-zynqmp.c | 61 ++++++++++++++++++++++----------
 1 file changed, 43 insertions(+), 18 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
index 5c46b7d7ebcb..7cc1e43fb07c 100644
--- a/drivers/pinctrl/pinctrl-zynqmp.c
+++ b/drivers/pinctrl/pinctrl-zynqmp.c
@@ -10,6 +10,7 @@
 
 #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
 
+#include <linux/bitmap.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -97,7 +98,7 @@ static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
 {
 	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 
-	return pctrl->ngroups;
+	return pctrl->ngroups + zynqmp_desc.npins;
 }
 
 static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,
@@ -105,7 +106,10 @@ static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,
 {
 	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 
-	return pctrl->groups[selector].name;
+	if (selector < pctrl->ngroups)
+		return pctrl->groups[selector].name;
+
+	return zynqmp_desc.pins[selector - pctrl->ngroups].name;
 }
 
 static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
@@ -115,8 +119,13 @@ static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
 {
 	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 
-	*pins = pctrl->groups[selector].pins;
-	*npins = pctrl->groups[selector].npins;
+	if (selector < pctrl->ngroups) {
+		*pins = pctrl->groups[selector].pins;
+		*npins = pctrl->groups[selector].npins;
+	} else {
+		*pins = &zynqmp_desc.pins[selector - pctrl->ngroups].number;
+		*npins = 1;
+	}
 
 	return 0;
 }
@@ -560,10 +569,12 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
 {
 	u16 resp[NUM_GROUPS_PER_RESP] = {0};
 	const char **fgroups;
-	int ret, index, i;
+	int ret, index, i, pin;
+	unsigned int npins;
+	unsigned long *used_pins __free(bitmap) =
+		bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL);
 
-	fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups), GFP_KERNEL);
-	if (!fgroups)
+	if (!used_pins)
 		return -ENOMEM;
 
 	for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) {
@@ -578,23 +589,37 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
 			if (resp[i] == RESERVED_GROUP)
 				continue;
 
-			fgroups[index + i] = devm_kasprintf(dev, GFP_KERNEL,
-							    "%s_%d_grp",
-							    func->name,
-							    index + i);
-			if (!fgroups[index + i])
-				return -ENOMEM;
-
 			groups[resp[i]].name = devm_kasprintf(dev, GFP_KERNEL,
 							      "%s_%d_grp",
 							      func->name,
 							      index + i);
 			if (!groups[resp[i]].name)
 				return -ENOMEM;
+
+			for (pin = 0; pin < groups[resp[i]].npins; pin++)
+				__set_bit(groups[resp[i]].pins[pin], used_pins);
 		}
 	}
 done:
+	npins = bitmap_weight(used_pins, zynqmp_desc.npins);
+	fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins),
+			       sizeof(*fgroups), GFP_KERNEL);
+	if (!fgroups)
+		return -ENOMEM;
+
+	for (i = 0; i < func->ngroups; i++) {
+		fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp",
+					    func->name, i);
+		if (!fgroups[i])
+			return -ENOMEM;
+	}
+
+	pin = 0;
+	for_each_set_bit(pin, used_pins, zynqmp_desc.npins)
+		fgroups[i++] = zynqmp_desc.pins[pin].name;
+
 	func->groups = fgroups;
+	func->ngroups += npins;
 
 	return 0;
 }
@@ -772,6 +797,10 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev,
 	if (!groups)
 		return -ENOMEM;
 
+	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups);
+	if (ret)
+		return ret;
+
 	for (i = 0; i < pctrl->nfuncs; i++) {
 		ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i],
 							 groups);
@@ -779,10 +808,6 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev,
 			return ret;
 	}
 
-	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups);
-	if (ret)
-		return ret;
-
 	pctrl->funcs = funcs;
 	pctrl->groups = groups;
 
-- 
2.35.1.1320.gc452695387.dirty


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

* Re: [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins
  2024-05-20 15:04 ` [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins Sean Anderson
@ 2024-05-22 14:48   ` Rob Herring
  0 siblings, 0 replies; 6+ messages in thread
From: Rob Herring @ 2024-05-22 14:48 UTC (permalink / raw)
  To: Sean Anderson
  Cc: Linus Walleij, Michal Simek, linux-gpio, Krishna Potthuri,
	linux-kernel, Andy Shevchenko, linux-arm-kernel, Conor Dooley,
	Krzysztof Kozlowski, devicetree

On Mon, May 20, 2024 at 11:04:23AM -0400, Sean Anderson wrote:
> Support specifying the function per-pin. The driver doesn't care
> whethern you use pins or groups for this purpose.
> 
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
> 
> (no changes since v1)
> 
>  .../bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml | 344 +++++++++---------
>  1 file changed, 176 insertions(+), 168 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
> index f13d315b5d5e..d3b258245e28 100644
> --- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
> @@ -42,179 +42,187 @@ patternProperties:
>          $ref: pinmux-node.yaml#
>  
>          properties:
> +          pins:
> +            description:
> +              List of pins to select (either this or "groups" must be specified)

Express as a schema:

oneOf:
  - required: [pins]
  - required: [groups]


> +            items:
> +              pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$'
> +
>            groups:
>              description:
>                List of groups to select (either this or "pins" must be
>                specified), available groups for this subnode.
>              items:

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

* RE: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins
  2024-05-20 15:04 ` [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
@ 2024-06-10 12:16   ` Potthuri, Sai Krishna
  2024-06-10 16:59     ` Sean Anderson
  0 siblings, 1 reply; 6+ messages in thread
From: Potthuri, Sai Krishna @ 2024-06-10 12:16 UTC (permalink / raw)
  To: Sean Anderson
  Cc: Linus Walleij, Simek, Michal, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org, Andy Shevchenko,
	linux-arm-kernel@lists.infradead.org, Goud, Srinivas

Hi Sean,

> -----Original Message-----
> From: Sean Anderson <sean.anderson@linux.dev>
> Sent: Monday, May 20, 2024 8:34 PM
> To: Linus Walleij <linus.walleij@linaro.org>; Simek, Michal
> <michal.simek@amd.com>; linux-gpio@vger.kernel.org
> Cc: Potthuri, Sai Krishna <sai.krishna.potthuri@amd.com>; linux-
> kernel@vger.kernel.org; Andy Shevchenko <andy.shevchenko@gmail.com>;
> linux-arm-kernel@lists.infradead.org; Sean Anderson
> <sean.anderson@linux.dev>
> Subject: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins
> 
> While muxing groups of pins at once can be convenient for large interfaces,
> it can also be rigid. This is because the group is set to all pins which support
> a particular function, even though not all pins may be used. For example,
> the sdhci0 function may be used with a 8-bit eMMC, 4-bit SD card, or even a
> 1-bit SD card. In these cases, the extra pins may be repurposed for other
> uses, but this is not currently allowed.
> 
> There is not too much point in pin "groups" when there are not actual pin
> groups at the hardware level. The pins can all be muxed individually, so
> there's no point in adding artificial groups on top.
> Just mux the pins like the hardware allows.
> 
> To this effect, add a new group for each pin which can be muxed. These
> groups are part of each function the pin can be muxed to. We treat group
> selectors beyond the number of groups as "pin" groups. To set this up, we
> initialize groups before functions, and then create a bitmap of used pins for
> each function. These used pins are appended to the function's list of
> groups.
> 
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
> 
> Changes in v2:
> - Use __set_bit instead of set_bit
> - Use size_add when calculating the number of kcalloc members
> - Expand commit message with some more motivation
> 
>  drivers/pinctrl/pinctrl-zynqmp.c | 61 ++++++++++++++++++++++----------
>  1 file changed, 43 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-
> zynqmp.c
> index 5c46b7d7ebcb..7cc1e43fb07c 100644
> --- a/drivers/pinctrl/pinctrl-zynqmp.c
> +++ b/drivers/pinctrl/pinctrl-zynqmp.c
> @@ -10,6 +10,7 @@
> 
>  #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
> 
> +#include <linux/bitmap.h>
>  #include <linux/init.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
> @@ -97,7 +98,7 @@ static int zynqmp_pctrl_get_groups_count(struct
> pinctrl_dev *pctldev)  {
>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> 
> -	return pctrl->ngroups;
> +	return pctrl->ngroups + zynqmp_desc.npins;
>  }
> 
>  static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev
> *pctldev, @@ -105,7 +106,10 @@ static const char
> *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,  {
>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> 
> -	return pctrl->groups[selector].name;
> +	if (selector < pctrl->ngroups)
> +		return pctrl->groups[selector].name;
> +
> +	return zynqmp_desc.pins[selector - pctrl->ngroups].name;
>  }
> 
>  static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev, @@ -
> 115,8 +119,13 @@ static int zynqmp_pctrl_get_group_pins(struct
> pinctrl_dev *pctldev,  {
>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> 
> -	*pins = pctrl->groups[selector].pins;
> -	*npins = pctrl->groups[selector].npins;
> +	if (selector < pctrl->ngroups) {
> +		*pins = pctrl->groups[selector].pins;
> +		*npins = pctrl->groups[selector].npins;
> +	} else {
> +		*pins = &zynqmp_desc.pins[selector - pctrl-
> >ngroups].number;
> +		*npins = 1;
> +	}
> 
>  	return 0;
>  }
> @@ -560,10 +569,12 @@ static int
> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,  {
>  	u16 resp[NUM_GROUPS_PER_RESP] = {0};
>  	const char **fgroups;
> -	int ret, index, i;
> +	int ret, index, i, pin;
> +	unsigned int npins;
> +	unsigned long *used_pins __free(bitmap) =
> +		bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL);
> 
> -	fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups),
> GFP_KERNEL);
> -	if (!fgroups)
> +	if (!used_pins)
>  		return -ENOMEM;
> 
>  	for (index = 0; index < func->ngroups; index +=
> NUM_GROUPS_PER_RESP) { @@ -578,23 +589,37 @@ static int
> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
>  			if (resp[i] == RESERVED_GROUP)
>  				continue;
> 
> -			fgroups[index + i] = devm_kasprintf(dev,
> GFP_KERNEL,
> -							    "%s_%d_grp",
> -							    func->name,
> -							    index + i);
> -			if (!fgroups[index + i])
> -				return -ENOMEM;
> -
>  			groups[resp[i]].name = devm_kasprintf(dev,
> GFP_KERNEL,
>  							      "%s_%d_grp",
>  							      func->name,
>  							      index + i);
>  			if (!groups[resp[i]].name)
>  				return -ENOMEM;
> +
> +			for (pin = 0; pin < groups[resp[i]].npins; pin++)
> +				__set_bit(groups[resp[i]].pins[pin],
> used_pins);
>  		}
>  	}
>  done:
> +	npins = bitmap_weight(used_pins, zynqmp_desc.npins);
> +	fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins),
> +			       sizeof(*fgroups), GFP_KERNEL);
> +	if (!fgroups)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < func->ngroups; i++) {
> +		fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp",
> +					    func->name, i);
> +		if (!fgroups[i])
> +			return -ENOMEM;
> +	}
> +
> +	pin = 0;
> +	for_each_set_bit(pin, used_pins, zynqmp_desc.npins)
> +		fgroups[i++] = zynqmp_desc.pins[pin].name;
> +
>  	func->groups = fgroups;
> +	func->ngroups += npins;
> 
>  	return 0;
>  }
> @@ -772,6 +797,10 @@ static int
> zynqmp_pinctrl_prepare_function_info(struct device *dev,
>  	if (!groups)
>  		return -ENOMEM;
> 
> +	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl-
> >ngroups);
> +	if (ret)
> +		return ret;
> +
>  	for (i = 0; i < pctrl->nfuncs; i++) {
>  		ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i],
>  							 groups);
> @@ -779,10 +808,6 @@ static int
> zynqmp_pinctrl_prepare_function_info(struct device *dev,
>  			return ret;
>  	}
> 
> -	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl-
> >ngroups);
> -	if (ret)
> -		return ret;
> -
>  	pctrl->funcs = funcs;
>  	pctrl->groups = groups;
> 
While testing this patch, observed that some more changes required in the 
other functions like set_mux, pin_config_group_set. Pasted the diff below.


diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
index 636e56f7cd92..c82074819be3 100644
--- a/drivers/pinctrl/pinctrl-zynqmp.c
+++ b/drivers/pinctrl/pinctrl-zynqmp.c
@@ -206,12 +206,18 @@ static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev,
                                 unsigned int function,
                                 unsigned int group)
 {
-       struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group];
+       const unsigned *pins;
+       unsigned npins;
        int ret, i;
 
-       for (i = 0; i < pgrp->npins; i++) {
-               unsigned int pin = pgrp->pins[i];
+       ret = zynqmp_pctrl_get_group_pins(pctldev, group, &pins, &npins);
+       if (ret) {
+               dev_err(pctldev->dev, "Get group pins failed for group %u\n", group);
+               return ret;
+       }
+
+       for (i = 0; i < npins; i++) {
+               unsigned int pin = pins[i];
 
                ret = zynqmp_pm_pinctrl_set_function(pin, function);
                if (ret) {
@@ -476,13 +482,18 @@ static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev,
                                    unsigned long *configs,
                                    unsigned int num_configs)
 {
-       int i, ret;
-       struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector];
-
-       for (i = 0; i < pgrp->npins; i++) {
-               ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs,
-                                            num_configs);
+       const unsigned *pins;
+        unsigned npins;
+        int i, ret;
+
+        ret = zynqmp_pctrl_get_group_pins(pctldev, selector, &pins, &npins);
+        if (ret) {
+                dev_err(pctldev->dev, "Get group pins failed for group %u\n", selector);
+                return ret;
+        }
+
+       for (i = 0; i < npins; i++) {
+               ret = zynqmp_pinconf_cfg_set(pctldev, pins[i], configs, num_configs);
                if (ret)
                        return ret;
        }

Regards
Sai Krishna

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

* Re: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins
  2024-06-10 12:16   ` Potthuri, Sai Krishna
@ 2024-06-10 16:59     ` Sean Anderson
  0 siblings, 0 replies; 6+ messages in thread
From: Sean Anderson @ 2024-06-10 16:59 UTC (permalink / raw)
  To: Potthuri, Sai Krishna
  Cc: Linus Walleij, Simek, Michal, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org, Andy Shevchenko,
	linux-arm-kernel@lists.infradead.org, Goud, Srinivas

Hi Sai Krishna,

On 6/10/24 08:16, Potthuri, Sai Krishna wrote:
> Hi Sean,
> 
>> -----Original Message-----
>> From: Sean Anderson <sean.anderson@linux.dev>
>> Sent: Monday, May 20, 2024 8:34 PM
>> To: Linus Walleij <linus.walleij@linaro.org>; Simek, Michal
>> <michal.simek@amd.com>; linux-gpio@vger.kernel.org
>> Cc: Potthuri, Sai Krishna <sai.krishna.potthuri@amd.com>; linux-
>> kernel@vger.kernel.org; Andy Shevchenko <andy.shevchenko@gmail.com>;
>> linux-arm-kernel@lists.infradead.org; Sean Anderson
>> <sean.anderson@linux.dev>
>> Subject: [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins
>> 
>> While muxing groups of pins at once can be convenient for large interfaces,
>> it can also be rigid. This is because the group is set to all pins which support
>> a particular function, even though not all pins may be used. For example,
>> the sdhci0 function may be used with a 8-bit eMMC, 4-bit SD card, or even a
>> 1-bit SD card. In these cases, the extra pins may be repurposed for other
>> uses, but this is not currently allowed.
>> 
>> There is not too much point in pin "groups" when there are not actual pin
>> groups at the hardware level. The pins can all be muxed individually, so
>> there's no point in adding artificial groups on top.
>> Just mux the pins like the hardware allows.
>> 
>> To this effect, add a new group for each pin which can be muxed. These
>> groups are part of each function the pin can be muxed to. We treat group
>> selectors beyond the number of groups as "pin" groups. To set this up, we
>> initialize groups before functions, and then create a bitmap of used pins for
>> each function. These used pins are appended to the function's list of
>> groups.
>> 
>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>> ---
>> 
>> Changes in v2:
>> - Use __set_bit instead of set_bit
>> - Use size_add when calculating the number of kcalloc members
>> - Expand commit message with some more motivation
>> 
>>  drivers/pinctrl/pinctrl-zynqmp.c | 61 ++++++++++++++++++++++----------
>>  1 file changed, 43 insertions(+), 18 deletions(-)
>> 
>> diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-
>> zynqmp.c
>> index 5c46b7d7ebcb..7cc1e43fb07c 100644
>> --- a/drivers/pinctrl/pinctrl-zynqmp.c
>> +++ b/drivers/pinctrl/pinctrl-zynqmp.c
>> @@ -10,6 +10,7 @@
>> 
>>  #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
>> 
>> +#include <linux/bitmap.h>
>>  #include <linux/init.h>
>>  #include <linux/module.h>
>>  #include <linux/of_address.h>
>> @@ -97,7 +98,7 @@ static int zynqmp_pctrl_get_groups_count(struct
>> pinctrl_dev *pctldev)  {
>>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
>> 
>> -	return pctrl->ngroups;
>> +	return pctrl->ngroups + zynqmp_desc.npins;
>>  }
>> 
>>  static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev
>> *pctldev, @@ -105,7 +106,10 @@ static const char
>> *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,  {
>>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
>> 
>> -	return pctrl->groups[selector].name;
>> +	if (selector < pctrl->ngroups)
>> +		return pctrl->groups[selector].name;
>> +
>> +	return zynqmp_desc.pins[selector - pctrl->ngroups].name;
>>  }
>> 
>>  static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev, @@ -
>> 115,8 +119,13 @@ static int zynqmp_pctrl_get_group_pins(struct
>> pinctrl_dev *pctldev,  {
>>  	struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
>> 
>> -	*pins = pctrl->groups[selector].pins;
>> -	*npins = pctrl->groups[selector].npins;
>> +	if (selector < pctrl->ngroups) {
>> +		*pins = pctrl->groups[selector].pins;
>> +		*npins = pctrl->groups[selector].npins;
>> +	} else {
>> +		*pins = &zynqmp_desc.pins[selector - pctrl-
>> >ngroups].number;
>> +		*npins = 1;
>> +	}
>> 
>>  	return 0;
>>  }
>> @@ -560,10 +569,12 @@ static int
>> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,  {
>>  	u16 resp[NUM_GROUPS_PER_RESP] = {0};
>>  	const char **fgroups;
>> -	int ret, index, i;
>> +	int ret, index, i, pin;
>> +	unsigned int npins;
>> +	unsigned long *used_pins __free(bitmap) =
>> +		bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL);
>> 
>> -	fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups),
>> GFP_KERNEL);
>> -	if (!fgroups)
>> +	if (!used_pins)
>>  		return -ENOMEM;
>> 
>>  	for (index = 0; index < func->ngroups; index +=
>> NUM_GROUPS_PER_RESP) { @@ -578,23 +589,37 @@ static int
>> zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
>>  			if (resp[i] == RESERVED_GROUP)
>>  				continue;
>> 
>> -			fgroups[index + i] = devm_kasprintf(dev,
>> GFP_KERNEL,
>> -							    "%s_%d_grp",
>> -							    func->name,
>> -							    index + i);
>> -			if (!fgroups[index + i])
>> -				return -ENOMEM;
>> -
>>  			groups[resp[i]].name = devm_kasprintf(dev,
>> GFP_KERNEL,
>>  							      "%s_%d_grp",
>>  							      func->name,
>>  							      index + i);
>>  			if (!groups[resp[i]].name)
>>  				return -ENOMEM;
>> +
>> +			for (pin = 0; pin < groups[resp[i]].npins; pin++)
>> +				__set_bit(groups[resp[i]].pins[pin],
>> used_pins);
>>  		}
>>  	}
>>  done:
>> +	npins = bitmap_weight(used_pins, zynqmp_desc.npins);
>> +	fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins),
>> +			       sizeof(*fgroups), GFP_KERNEL);
>> +	if (!fgroups)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < func->ngroups; i++) {
>> +		fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp",
>> +					    func->name, i);
>> +		if (!fgroups[i])
>> +			return -ENOMEM;
>> +	}
>> +
>> +	pin = 0;
>> +	for_each_set_bit(pin, used_pins, zynqmp_desc.npins)
>> +		fgroups[i++] = zynqmp_desc.pins[pin].name;
>> +
>>  	func->groups = fgroups;
>> +	func->ngroups += npins;
>> 
>>  	return 0;
>>  }
>> @@ -772,6 +797,10 @@ static int
>> zynqmp_pinctrl_prepare_function_info(struct device *dev,
>>  	if (!groups)
>>  		return -ENOMEM;
>> 
>> +	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl-
>> >ngroups);
>> +	if (ret)
>> +		return ret;
>> +
>>  	for (i = 0; i < pctrl->nfuncs; i++) {
>>  		ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i],
>>  							 groups);
>> @@ -779,10 +808,6 @@ static int
>> zynqmp_pinctrl_prepare_function_info(struct device *dev,
>>  			return ret;
>>  	}
>> 
>> -	ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl-
>> >ngroups);
>> -	if (ret)
>> -		return ret;
>> -
>>  	pctrl->funcs = funcs;
>>  	pctrl->groups = groups;
>> 
> While testing this patch, observed that some more changes required in the 
> other functions like set_mux, pin_config_group_set. Pasted the diff below.

Thanks for catching this. I will incorporate these changes into v3.

> diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
> index 636e56f7cd92..c82074819be3 100644
> --- a/drivers/pinctrl/pinctrl-zynqmp.c
> +++ b/drivers/pinctrl/pinctrl-zynqmp.c
> @@ -206,12 +206,18 @@ static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev,
>                                  unsigned int function,
>                                  unsigned int group)
>  {
> -       struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> -       const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group];
> +       const unsigned *pins;
> +       unsigned npins;
>         int ret, i;
>  
> -       for (i = 0; i < pgrp->npins; i++) {
> -               unsigned int pin = pgrp->pins[i];
> +       ret = zynqmp_pctrl_get_group_pins(pctldev, group, &pins, &npins);
> +       if (ret) {

This function cannot fail, so we don't need to check the return.

> +               dev_err(pctldev->dev, "Get group pins failed for group %u\n", group);
> +               return ret;
> +       }
> +
> +       for (i = 0; i < npins; i++) {
> +               unsigned int pin = pins[i];
>  
>                 ret = zynqmp_pm_pinctrl_set_function(pin, function);
>                 if (ret) {
> @@ -476,13 +482,18 @@ static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev,
>                                     unsigned long *configs,
>                                     unsigned int num_configs)
>  {
> -       int i, ret;
> -       struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
> -       const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector];
> -
> -       for (i = 0; i < pgrp->npins; i++) {
> -               ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs,
> -                                            num_configs);
> +       const unsigned *pins;
> +        unsigned npins;
> +        int i, ret;
> +
> +        ret = zynqmp_pctrl_get_group_pins(pctldev, selector, &pins, &npins);
> +        if (ret) {

ditto

> +                dev_err(pctldev->dev, "Get group pins failed for group %u\n", selector);
> +                return ret;
> +        }
> +
> +       for (i = 0; i < npins; i++) {
> +               ret = zynqmp_pinconf_cfg_set(pctldev, pins[i], configs, num_configs);
>                 if (ret)
>                         return ret;
>         }
> 
> Regards
> Sai Krishna

--Sean

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

end of thread, other threads:[~2024-06-10 16:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-20 15:04 [PATCH v2 0/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
2024-05-20 15:04 ` [PATCH v2 1/2] dt-bindings: pinctrl: xilinx: Add support for function with pins Sean Anderson
2024-05-22 14:48   ` Rob Herring
2024-05-20 15:04 ` [PATCH v2 2/2] pinctrl: zynqmp: Support muxing individual pins Sean Anderson
2024-06-10 12:16   ` Potthuri, Sai Krishna
2024-06-10 16:59     ` Sean Anderson

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).