Skip to contentSkip to conversation

mfd: add Airoha AN8855 switch support

PATCH RESEND Superseded Christian Marangi 3 participants 6 messages Oct 21

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover mfd: add Airoha AN8855 switch support

This is a subset only specific for MFD changes for Airoha AN8855 switch support.

The old series with all the patches can be reached here [1] Changelog is included in the same link

[1] https://lore.kernel.org/all/[email protected]/

Christian Marangi (2):
dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
mfd: an8855: Add support for Airoha AN8855 Switch

 .../bindings/mfd/airoha,an8855.yaml           | 176 ++++++
 drivers/mfd/Kconfig                           |  14 +
 drivers/mfd/Makefile                          |   1 +
 drivers/mfd/airoha-an8855.c                   | 579 ++++++++++++++++++
 4 files changed, 770 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855.yaml
 create mode 100644 drivers/mfd/airoha-an8855.c
Signature · 1 line
2.55.0
#1 lore raw

PATCH RESEND 1/2 dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC

Document support for Airoha AN8855 Switch SoC. This SoC expose various peripherals like an Ethernet Switch, a NVMEM provider and Ethernet PHYs.

It does also support i2c and timers but those are not currently supported/used.

---
 .../bindings/mfd/airoha,an8855.yaml           | 176 ++++++++++++++++++
 1 file changed, 176 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855.yaml
Documentation/devicetree/bindings/mfd/airoha,an8855.yaml new file +176 -0
new file mode 100644
index 000000000000..48127e956c96
@@ -0,0 +1,176 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/airoha,an8855.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN8855 Switch SoC
+
+maintainers:
+  - Christian Marangi <[email protected]>
+
+description: >
+  Airoha AN8855 Switch is a SoC that expose various peripherals like an
+  Ethernet Switch, a NVMEM provider and Ethernet PHYs.
+
+  It does also support i2c and timers but those are not currently
+  supported/used.
+
+properties:
+  compatible:
+    const: airoha,an8855
+
+  reg:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  efuse:
+    type: object
+    $ref: /schemas/nvmem/airoha,an8855-efuse.yaml
+    description: EFUSE exposed by the Airoha AN8855 SoC
+
+  ethernet-switch:
+    type: object
+    $ref: /schemas/net/dsa/airoha,an8855-switch.yaml
+    description: Switch exposed by the Airoha AN8855 SoC
+
+  mdio:
+    type: object
+    $ref: /schemas/net/mdio.yaml#
+    description: MDIO exposed by the Airoha AN8855 SoC
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - mdio
+  - ethernet-switch
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        soc@1 {
+            compatible = "airoha,an8855";
+            reg = <1>;
+
+            reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
+
+            efuse {
+                compatible = "airoha,an8855-efuse";
+
+                #nvmem-cell-cells = <0>;
+
+                nvmem-layout {
+                    compatible = "fixed-layout";
+                    #address-cells = <1>;
+                    #size-cells = <1>;
+
+                    shift_sel_port0_tx_a: shift-sel-port0-tx-a@c {
+                       reg = <0xc 0x4>;
+                    };
+
+                    shift_sel_port0_tx_b: shift-sel-port0-tx-b@10 {
+                        reg = <0x10 0x4>;
+                    };
+
+                    shift_sel_port0_tx_c: shift-sel-port0-tx-c@14 {
+                        reg = <0x14 0x4>;
+                    };
+
+                    shift_sel_port0_tx_d: shift-sel-port0-tx-d@18 {
+                       reg = <0x18 0x4>;
+                    };
+
+                    shift_sel_port1_tx_a: shift-sel-port1-tx-a@1c {
+                        reg = <0x1c 0x4>;
+                    };
+
+                    shift_sel_port1_tx_b: shift-sel-port1-tx-b@20 {
+                        reg = <0x20 0x4>;
+                    };
+
+                    shift_sel_port1_tx_c: shift-sel-port1-tx-c@24 {
+                       reg = <0x24 0x4>;
+                    };
+
+                    shift_sel_port1_tx_d: shift-sel-port1-tx-d@28 {
+                        reg = <0x28 0x4>;
+                    };
+                };
+            };
+
+            ethernet-switch {
+                compatible = "airoha,an8855-switch";
+
+                ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port@0 {
+                        reg = <0>;
+                        label = "lan1";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy1>;
+                    };
+
+                    port@1 {
+                        reg = <1>;
+                        label = "lan2";
+                        phy-mode = "internal";
+                        phy-handle = <&internal_phy2>;
+                    };
+
+                    port@5 {
+                        reg = <5>;
+                        label = "cpu";
+                        ethernet = <&gmac0>;
+                        phy-mode = "2500base-x";
+
+                        fixed-link {
+                            speed = <2500>;
+                            full-duplex;
+                            pause;
+                        };
+                    };
+                };
+            };
+
+            mdio {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                internal_phy1: ethernet-phy@1 {
+                  compatible = "ethernet-phy-idc0ff.0410",
+                               "ethernet-phy-ieee802.3-c22";
+                  reg = <1>;
+
+                  nvmem-cells = <&shift_sel_port0_tx_a>,
+                      <&shift_sel_port0_tx_b>,
+                      <&shift_sel_port0_tx_c>,
+                      <&shift_sel_port0_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+
+                internal_phy2: ethernet-phy@2 {
+                  compatible = "ethernet-phy-idc0ff.0410",
+                               "ethernet-phy-ieee802.3-c22";
+                  reg = <2>;
+
+                  nvmem-cells = <&shift_sel_port1_tx_a>,
+                      <&shift_sel_port1_tx_b>,
+                      <&shift_sel_port1_tx_c>,
+                      <&shift_sel_port1_tx_d>;
+                  nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
+                };
+            };
+        };
+    };
Signature · 1 line
2.55.0
#2 lore raw

Re: [RESEND PATCH 1/2] dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Low] dt-bindings: mfd: reference to missing schema airoha,an8855-switch.yaml --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] dt-bindings: mfd: reference to missing schema airoha,an8855-switch.yaml --

commit 8973f67919d9fd3d92a5417e6a75e38e2eb9cc42
Author: Christian Marangi <[email protected]>

dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC

This commit adds the devicetree binding schema for the Airoha AN8855 switch multi-function device, including its efuse, ethernet-switch, and mdio subnodes.

Quoted 5 lines
Documentation/devicetree/bindings/mfd/airoha,an8855.yaml new file +0 -0
new file mode 100644
index 0000000000000..48127e956c965

[ ... ]

Documentation/devicetree/bindings/mfd/airoha,an8855.yaml line 37

Quoted 9 lines
Documentation/devicetree/bindings/mfd/airoha,an8855.yaml new file +9 -0
+  efuse:
+    type: object
+    $ref: /schemas/nvmem/airoha,an8855-efuse.yaml
+    description: EFUSE exposed by the Airoha AN8855 SoC
+
+  ethernet-switch:
+    type: object
+    $ref: /schemas/net/dsa/airoha,an8855-switch.yaml
+    description: Switch exposed by the Airoha AN8855 SoC

[Severity: Low]
Does this break make dt_binding_check?

In Documentation/devicetree/bindings/mfd/airoha,an8855.yaml, properties:ethernet-switch references /schemas/net/dsa/airoha,an8855-switch.yaml, and the examples section instantiates an ethernet-switch child node with:

    ethernet-switch {
        compatible = "airoha,an8855-switch";

However, Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml does not exist in the repository, causing dt-doc-validate, dt-mk-schema, and dt-validate to fail on the unresolved $ref and the undocumented airoha,an8855-switch compatible string.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#3 lore raw

Re: [RESEND PATCH 1/2] dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC

In reply to Christian Marangi
Quoted 6 lines · Christian Marangi

Document support for Airoha AN8855 Switch SoC. This SoC expose various peripherals like an Ethernet Switch, a NVMEM provider and Ethernet PHYs.

It does also support i2c and timers but those are not currently supported/used.

Quoted 7 lines
---
 .../bindings/mfd/airoha,an8855.yaml           | 176 ++++++++++++++++++
 1 file changed, 176 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855.yaml

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/airoha,an8855.yaml: Unresolvable reference: /schemas/net/dsa/airoha,an8855-switch.yaml
Documentation/devicetree/bindings/mfd/airoha,an8855.example.dtb: soc@1 (airoha,an8855): ethernet-switch: False schema does not allow {'compatible': ['airoha,an8855-switch'], 'ports': {'#address-cells': 1, '#size-cells': 0, 'port@0': {'reg': [[0]], 'label': ['lan1'], 'phy-mode': ['internal'], 'phy-handle': [[1]]}, 'port@1': {'reg': [[1]], 'label': ['lan2'], 'phy-mode': ['internal'], 'phy-handle': [[2]]}, 'port@5': {'reg': [[5]], 'label': ['cpu'], 'ethernet': [[4294967295]], 'phy-mode': ['2500base-x'], 'fixed-link': {'speed': 2500, 'full-duplex': True, 'pause': True}}}}
from schema $id: http://devicetree.org/schemas/mfd/airoha,an8855.yaml
Documentation/devicetree/bindings/mfd/airoha,an8855.example.dtb: /example-0/mdio/soc@1/ethernet-switch: failed to match any schema with compatible: ['airoha,an8855-switch']

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/[email protected]

The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema.

#4 lore raw

PATCH RESEND 2/2 mfd: an8855: Add support for Airoha AN8855 Switch

In reply to Christian Marangi

Add support for Airoha AN8855 Switch that provide support for a DSA switch and a NVMEM provider.

Also make use of the mdio-regmap driver and register a regmap for each internal PHY of the switch.
This is needed to handle the double usage of the PHYs as both PHY and Switch accessor.

---
 drivers/mfd/Kconfig         |  14 +
 drivers/mfd/Makefile        |   1 +
 drivers/mfd/airoha-an8855.c | 579 ++++++++++++++++++++++++++++++++++++
 3 files changed, 594 insertions(+)
 create mode 100644 drivers/mfd/airoha-an8855.c
drivers/mfd/Kconfig +14 -0
index 87ed55c155f0..653a81435b20 100644
@@ -54,6 +54,20 @@ config MFD_ALTERA_SYSMGR
 	  using regmap_mmio accesses for ARM32 parts and SMC calls to
 	  EL3 for ARM64 parts.
 
+config MFD_AIROHA_AN8855
+	tristate "Airoha AN8855 Switch Core"
+	select MFD_CORE
+	select REGMAP
+	select PHYLIB
+	select MDIO_REGMAP
+	depends on NETDEVICES && OF
+	help
+	  Support for the Airoha AN8855 Switch Core. This is an SoC
+	  that provides various peripherals, to count, i2c, an Ethrnet
+	  Switch, a CPU timer, GPIO, eFUSE.
+
+	  Currently it provides a DSA switch and a NVMEM provider.
+
 config MFD_ACT8945A
 	tristate "Active-semi ACT8945A"
 	select MFD_CORE
drivers/mfd/Makefile +1 -0
index f8101d2a9ce9..96bbe3fad736 100644
@@ -8,6 +8,7 @@ obj-$(CONFIG_MFD_88PM860X)	+= 88pm860x.o
 obj-$(CONFIG_MFD_88PM800)	+= 88pm800.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)	+= 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM886_PMIC)	+= 88pm886.o
+obj-$(CONFIG_MFD_AIROHA_AN8855)	+= airoha-an8855.o
 obj-$(CONFIG_MFD_ACT8945A)	+= act8945a.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835-pm.o
drivers/mfd/airoha-an8855.c new file +579 -0

579 lines not on this page · raw message

Signature · 1 line
2.55.0
#5 lore raw

Re: [RESEND PATCH 2/2] mfd: an8855: Add support for Airoha AN8855 Switch

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] mfd: an8855: missing reset-gpios handling in an8855_probe() - [Medium] mfd: an8855: missing…

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] mfd: an8855: missing reset-gpios handling in an8855_probe()
- [Medium] mfd: an8855: missing MFD_AIROHA_AN8855 dependency on NVMEM_AN8855_EFUSE
- [Low] mfd: an8855: mixing __free() and goto cleanup in an8855_mdio_register() --

commit f927c03e4e8ef367f1a168337fd8954240810d42
Author: Christian Marangi <[email protected]>

mfd: an8855: Add support for Airoha AN8855 Switch

This commit adds the core driver for the Airoha an8855 switch, registering virtual mdio buses via mdio-regmap for the internal phys along with child devices for the nvmem efuse provider and dsa switch.

Quoted 12 lines
drivers/mfd/Kconfig +4 -0
index e4fd4572472f9..afbdcec0fce8f 100644
@@ -54,6 +54,20 @@ config MFD_ALTERA_SYSMGR
 	  using regmap_mmio accesses for ARM32 parts and SMC calls to
 	  EL3 for ARM64 parts.
 
+config MFD_AIROHA_AN8855
+	tristate "Airoha AN8855 Switch Core"
+	select MFD_CORE
+	select REGMAP

drivers/mfd/Kconfig config MFD_ALTERA_SYSMGR · line 70

Quoted 10 lines
drivers/mfd/Kconfig +10 -0
+	select PHYLIB
+	select MDIO_REGMAP
+	depends on NETDEVICES && OF
+	help
+	  Support for the Airoha AN8855 Switch Core. This is an SoC
+	  that provides various peripherals, to count, i2c, an Ethrnet
+	  Switch, a CPU timer, GPIO, eFUSE.
+
+	  Currently it provides a DSA switch and a NVMEM provider.
+

[Severity: Medium]
Should drivers/nvmem/Kconfig also be updated so NVMEM_AN8855_EFUSE depends on MFD_AIROHA_AN8855 || COMPILE_TEST?

When drivers/nvmem/an8855-efuse.c was added in commit e2258cfd9b98 ("nvmem:
an8855: Add support for Airoha AN8855 Switch EFUSE"), NVMEM_AN8855_EFUSE had depends on MFD_AIROHA_AN8855 || COMPILE_TEST, which was later narrowed by commit 4796eaafd6a1 ("nvmem: an8855: drop an unused Kconfig symbol") to:

drivers/nvmem/Kconfig:
config NVMEM_AN8855_EFUSE
tristate "Airoha AN8855 eFuse support"
depends on COMPILE_TEST

Without restoring MFD_AIROHA_AN8855 in that dependency, NVMEM_AN8855_EFUSE cannot be enabled in non-COMPILE_TEST builds for the an8855-efuse cell registered in an8855_cells.

[ ... ]

Quoted 6 lines
drivers/mfd/airoha-an8855.c new file +0 -0
new file mode 100644
index 0000000000000..6a270555db5cf
@@ -0,0 +1,579 @@

[ ... ]

Quoted 17 lines
drivers/mfd/airoha-an8855.c new file +17 -0
+static int an8855_mdio_register(struct device *dev, struct an8855 *ddata,
+				struct an8855_phy_bus *phy_bus_infos)
+{
+	struct device_node *mdio_np;
+	int ret = 0;
+	int i = 0;
+
+	mdio_np = of_get_child_by_name(dev->of_node, "mdio");
+	if (!mdio_np)
+		return -ENODEV;
+
+	for_each_available_child_of_node_scoped(mdio_np, phy_np) {
+		if (i >= AN8855_MAX_PHY_PORT) {
+			ret = -EINVAL;
+			goto exit;
+		}
+

drivers/mfd/airoha-an8855.c line 480

Quoted 10 lines
drivers/mfd/airoha-an8855.c new file +10 -0
+		ret = an8855_phy_bus_register(dev, ddata, phy_np,
+					      &phy_bus_infos[i]);
+		if (ret)
+			goto exit;
+
+		i++;
+	}
+
+exit:
+	of_node_put(mdio_np);

[Severity: Low]
Could mdio_np be declared with __free(device_node) or should the loop avoid mixing for_each_available_child_of_node_scoped() with goto cleanup labels?

an8855_mdio_register() uses for_each_available_child_of_node_scoped(), which declares phy_np with __free(device_node), while also jumping to the exit label with goto to clean up mdio_np and phy_bus_infos[i].node, which goes against the cleanup helper guidelines in include/linux/cleanup.h against mixing __free() and goto in the same function.

Quoted 46 lines
drivers/mfd/airoha-an8855.c new file +46 -0
+	if (ret) {
+		while (i--)
+			fwnode_handle_put(phy_bus_infos[i].node);
+
+		return ret;
+	}
+
+	return i;
+}
+
+static int an8855_probe(struct mdio_device *mdiodev)
+{
+	struct an8855_phy_bus phy_bus_infos[AN8855_MAX_PHY_PORT] = { };
+	struct device *dev = &mdiodev->dev;
+	struct regmap *regmap;
+	struct an8855 *ddata;
+	int num_phys;
+	int i, ret;
+
+	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+	if (!ddata)
+		return -ENOMEM;
+
+	ddata->bus = mdiodev->bus;
+	ddata->switch_addr = mdiodev->addr;
+	/* No DMA for mdiobus, mute warning for DMA mask not set */
+	dev->dma_mask = &dev->coherent_dma_mask;
+
+	/* Register virtual MDIO for each PHY */
+	num_phys = an8855_mdio_register(dev, ddata, phy_bus_infos);
+	if (num_phys < 0)
+		return num_phys;
+
+	regmap = devm_regmap_init(dev, NULL, ddata, &an8855_regmap_config);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		dev_err_probe(dev, ret, "regmap initialization failed\n");
+		goto err_put_fwnodes;
+	}
+
+	/* Reset PHY page for switch address */
+	mutex_lock_nested(&ddata->bus->mdio_lock, MDIO_MUTEX_NESTED);
+	ret = an8855_mii_set_page(ddata, ddata->switch_addr,
+				  AN8855_PHY_PAGE_STANDARD);
+	mutex_unlock(&ddata->bus->mdio_lock);
+	if (ret)

drivers/mfd/airoha-an8855.c line 536

Quoted 10 lines
drivers/mfd/airoha-an8855.c new file +10 -0
+		goto err_put_fwnodes;
+
+	ret = an8855_read_switch_id(dev, regmap);
+	if (ret)
+		goto err_put_fwnodes;
+
+	/* Release global PHY power down */
+	ret = regmap_write(regmap, AN8855_RG_GPHY_AFE_PWD, 0x0);
+	if (ret)
+		goto err_put_fwnodes;

[Severity: High]
How is reset-gpios deasserted before accessing the switch registers in an8855_probe()?

Documentation/devicetree/bindings/mfd/airoha,an8855.yaml defines reset-gpios on the top-level airoha,an8855 node, and drivers/mfd/airoha-an8855.c includes linux/gpio/consumer.h, but an8855_probe() never requests or deasserts the reset gpio.

Because airoha,an8855 is registered as a non-phy mdio_device without MDIO_DEVICE_FLAG_PHY, mdiobus_register_device() in drivers/net/phy/mdio_device.c skips mdio_device_register_reset():

	if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) {
		err = mdio_device_register_reset(mdiodev);
		if (err)
			return err;

		/* Assert the reset signal */
		mdio_device_reset(mdiodev, 1);
	}

If reset-gpios is asserted at boot, won't an8855_mii_set_page() and an8855_read_switch_id() fail to read AN8855_ID over mdio and cause an8855_probe() to fail with -ENODEV?

[ ... ]

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2