All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/28] DSA: Restructure probing
@ 2015-12-23 12:56 Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 01/28] component: remove old add_components method Andrew Lunn
                   ` (28 more replies)
  0 siblings, 29 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

As noted in Documentation/networking/dsa/dsa.txt, the current DSA
architecture has a few architecture problems:

DSA is implemented as a DSA platform device driver which is convenient because
it will register the entire DSA switch tree attached to a master network device
in one-shot, facilitating the device creation and simplifying the device driver
model a bit, this comes however with a number of limitations:

- building DSA and its switch drivers as modules is currently not working
- the device driver parenting does not necessarily reflect the original
  bus/device the switch can be created from
- supporting non-MDIO and non-MMIO (platform) switches is not possible

This RFC patchset attempts to address this. It allows the switch
device to be true Linux devices, and use of the device component
framework to bind the switch devices to the DSA framework, similar to
the way GPU engines are bound to the master GPU driver. The drivers
are now modules, which can be loaded and unloaded. Reloading however
currently causes an Opps, hence RFC.

The code remains backwards compatible with the old binding, and adds a
new property to facilitate the component framework. Switch drivers get
there own binding, allowing them to be probed independent of DSA.

Additionally, at this RFC stage, the DTS files for a development board
with three switches is included, to demonstrate the new binding, and
show that D in DSA is supported. At some point this DTS file will be
submitted to arm-soc.

Andrew Lunn (24):
  dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent
  net: dsa: Pass the dsa device to the switch drivers
  net: dsa: Have the switch driver allocate there own private memory
  net: dsa: Remove allocation of driver private memory
  net: dsa: Keep the mii bus and address in the private structure
  net: dsa: Add basic support for component master support
  net: dsa: Keep a reference to the switch device for component matching
  net: dsa: Add slave component matches based on a phandle to the slave.
  net: dsa: Make dsa,mii-bus optional
  net: dsa: Add register/unregister functions for switch drivers
  net: dsa: Rename DSA probe function.
  of_mdio: Add "mii-bus" and address property parser
  dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name()
  dsa: mv88e6xxx: Add shared code for binding/unbinding a switch driver.
  dsa: Add platform device support to Marvell switches
  vf610: Zii: Convert rev b to switches as individual devices
  net: dsa: Add some debug prints for error cases
  net: dsa: Setup the switches after all have been probed
  net: dsa: Only setup platform switches, not device switches
  net: dsa: If a switch fails to probe, defer probing
  Documentation: DSA: Describe how probe of DSA and switches work.
  dsa: Convert mv88e6xxx into a library allowing driver modules
  dsa: slave: Don't reference NULL pointer during phy_disconnect
  dsa: Destroy fixed link phys after the phy has been disconnected

Cory T. Tusar (1):
  ARM: VF610: Add Zodiac Inflight Innovations development boards.

Florian Fainelli (2):
  net: dsa: Move platform data allocation for OF
  net: dsa: bcm_sf2: make it a real platform driver

Russell King (1):
  component: remove old add_components method

 .../devicetree/bindings/net/dsa/broadcom.txt       |  48 +++
 Documentation/devicetree/bindings/net/dsa/dsa.txt  |   5 +-
 .../devicetree/bindings/net/dsa/marvell.txt        |  17 +
 Documentation/networking/dsa/dsa.txt               |  48 +++
 arch/arm/boot/dts/Makefile                         |   4 +-
 arch/arm/boot/dts/vf610-zii-dev-rev-a.dts          | 409 +++++++++++++++++++
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts          | 307 +++++++++++++++
 arch/arm/boot/dts/vf610-zii-dev.dtsi               | 436 +++++++++++++++++++++
 drivers/base/component.c                           |  31 +-
 drivers/net/dsa/Kconfig                            |   2 +-
 drivers/net/dsa/Makefile                           |  19 +-
 drivers/net/dsa/bcm_sf2.c                          | 249 +++++++-----
 drivers/net/dsa/mv88e6060.c                        | 130 +++++-
 drivers/net/dsa/mv88e6060.h                        |  11 +
 drivers/net/dsa/mv88e6123.c                        | 187 +++++++++
 drivers/net/dsa/mv88e6123_61_65.c                  | 124 ------
 drivers/net/dsa/mv88e6131.c                        |  83 +++-
 drivers/net/dsa/mv88e6171.c                        |  83 +++-
 drivers/net/dsa/mv88e6352.c                        |  83 +++-
 drivers/net/dsa/mv88e6xxx.c                        | 159 +++++---
 drivers/net/dsa/mv88e6xxx.h                        |  20 +-
 drivers/of/of_mdio.c                               |  38 ++
 include/linux/component.h                          |   5 -
 include/linux/of_mdio.h                            |  10 +
 include/net/dsa.h                                  |  17 +-
 net/dsa/dsa.c                                      | 262 ++++++++-----
 net/dsa/slave.c                                    |  12 +-
 27 files changed, 2329 insertions(+), 470 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/broadcom.txt
 create mode 100644 Documentation/devicetree/bindings/net/dsa/marvell.txt
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev-rev-a.dts
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev.dtsi
 create mode 100644 drivers/net/dsa/mv88e6123.c
 delete mode 100644 drivers/net/dsa/mv88e6123_61_65.c

-- 
2.6.3

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

* [PATCH RFC 01/28] component: remove old add_components method
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 13:21   ` Russell King - ARM Linux
  2015-12-23 12:56 ` [PATCH RFC 02/28] ARM: VF610: Add Zodiac Inflight Innovations development boards Andrew Lunn
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Russell King

From: Russell King <rmk+kernel@arm.linux.org.uk>

Now that drivers create an array of component matches at probe time, we
can retire the old methods.  This involves removing the add_components
master method, and removing component_master_add_child() from public
view.  We also remove component_add_master() as that interface is no
longer useful.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 31 +++++--------------------------
 include/linux/component.h |  5 -----
 2 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index f748430bb654..2ca22738ae92 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
  * function and compare data.  This is safe to call for duplicate matches
  * and will not result in the same component being added multiple times.
  */
-int component_master_add_child(struct master *master,
+static int component_master_add_child(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
 	struct component *c;
@@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(component_master_add_child);
 
 static int find_components(struct master *master)
 {
@@ -112,14 +111,6 @@ static int find_components(struct master *master)
 	size_t i;
 	int ret = 0;
 
-	if (!match) {
-		/*
-		 * Search the list of components, looking for components that
-		 * belong to this master, and attach them to the master.
-		 */
-		return master->ops->add_components(master->dev, master);
-	}
-
 	/*
 	 * Scan the array of match functions and attach
 	 * any components which are found to this master.
@@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
 	struct master *master;
 	int ret;
 
-	if (ops->add_components && match)
-		return -EINVAL;
-
-	if (match) {
-		/* Reallocate the match array for its true size */
-		match = component_match_realloc(dev, match, match->num);
-		if (IS_ERR(match))
-			return PTR_ERR(match);
-	}
+	/* Reallocate the match array for its true size */
+	match = component_match_realloc(dev, match, match->num);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
@@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(component_master_add_with_match);
 
-int component_master_add(struct device *dev,
-	const struct component_master_ops *ops)
-{
-	return component_master_add_with_match(dev, ops, NULL);
-}
-EXPORT_SYMBOL_GPL(component_master_add);
-
 void component_master_del(struct device *dev,
 	const struct component_master_ops *ops)
 {
diff --git a/include/linux/component.h b/include/linux/component.h
index c00dcc302611..71c434a6a5ee 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
 struct master;
 
 struct component_master_ops {
-	int (*add_components)(struct device *, struct master *);
 	int (*bind)(struct device *);
 	void (*unbind)(struct device *);
 };
 
-int component_master_add(struct device *, const struct component_master_ops *);
 void component_master_del(struct device *,
 	const struct component_master_ops *);
 
-int component_master_add_child(struct master *master,
-	int (*compare)(struct device *, void *), void *compare_data);
-
 struct component_match;
 
 int component_master_add_with_match(struct device *,
-- 
2.6.3

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

* [PATCH RFC 02/28] ARM: VF610: Add Zodiac Inflight Innovations development boards.
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 01/28] component: remove old add_components method Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 03/28] net: dsa: Move platform data allocation for OF Andrew Lunn
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot
  Cc: netdev, Cory T. Tusar, Andrew Lunn

From: "Cory T. Tusar" <cory.tusar@pid1solutions.com>

"rev a" was the first generation of the board, had has some
issues. Most of these issues are fixed in "Rev B". Put the common
parts in a .dtsi file, and add .dts files for "Rev A" and "Rev B".

Signed-off-by: Cory T. Tusar <cory.tusar@pid1solutions.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 arch/arm/boot/dts/Makefile                |   4 +-
 arch/arm/boot/dts/vf610-zii-dev-rev-a.dts | 409 ++++++++++++++++++++++++++++
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 287 ++++++++++++++++++++
 arch/arm/boot/dts/vf610-zii-dev.dtsi      | 436 ++++++++++++++++++++++++++++++
 4 files changed, 1135 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev-rev-a.dts
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
 create mode 100644 arch/arm/boot/dts/vf610-zii-dev.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 30bbc3746130..f462036d4ff8 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -359,7 +359,9 @@ dtb-$(CONFIG_SOC_VF610) += \
 	vf610-colibri-eval-v3.dtb \
 	vf610m4-colibri.dtb \
 	vf610-cosmic.dtb \
-	vf610-twr.dtb
+	vf610-twr.dtb \
+	vf610-zii-dev-rev-a.dtb \
+	vf610-zii-dev-rev-b.dtb
 dtb-$(CONFIG_ARCH_MXS) += \
 	imx23-evk.dtb \
 	imx23-olinuxino.dtb \
diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-a.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-a.dts
new file mode 100644
index 000000000000..08bec6bd869a
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-a.dts
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610-zii-dev.dtsi"
+
+/ {
+	model = "ZII VF610 Development Board, Rev A";
+	compatible = "zii,vf610dev-a", "zii,vf610dev", "fsl,vf610";
+
+	chosen {
+		bootargs = "console=ttyLP0,115200n8";
+		stdout-path = &uart0;
+	};
+
+	memory {
+		reg = <0x80000000 0x8000000>;
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pinctrl_leds_debug>;
+		pinctrl-names = "default";
+
+		debug_1 {
+			label = "zii:green:debug1";
+			gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	dsa@0 {
+		compatible = "marvell,dsa";
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		dsa,ethernet = <&fec1>;
+		dsa,mii-bus = <&mdio1>;
+
+		/* 6352 - Primary - 7 ports */
+		switch0: switch@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x02 0>;
+			eeprom-length = <512>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan0";
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan1";
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan2";
+			};
+
+			port@3 {
+				reg = <3>;
+				label = "lan3";
+			};
+
+			port@4 {
+				reg = <4>;
+				label = "lan4";
+			};
+
+			switch0port5: port@5 {
+				reg = <5>;
+				label = "dsa";
+				phy-mode = "rgmii-txid";
+				link = <&switch1port6
+					&switch2port9>;
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port@6 {
+				reg = <6>;
+				label = "cpu";
+				fixed-link {
+					speed = <100>;
+					full-duplex;
+				};
+			};
+
+		};
+
+		/* 6352 - Secondary - 7 ports */
+		switch1: switch@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x04 1>;
+			eeprom-length = <512>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan5";
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan6";
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan7";
+			};
+
+			port@3 {
+				reg = <3>;
+				label = "lan8";
+			};
+
+			switch1port4: port@4 {
+				reg = <4>;
+				label = "dsa";
+				link = <&switch2port9>;
+			};
+
+			switch1port6: port@6 {
+				reg = <6>;
+				label = "dsa";
+				phy-mode = "rgmii-txid";
+				link = <&switch0port5>;
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+		};
+
+		/* 6185 - 10 ports */
+		switch2: switch@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x06 2>;
+
+			port@1 {
+				reg = <1>;
+				label = "optical3";
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "optical4";
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			switch2port9: port@9 {
+				reg = <9>;
+				label = "dsa";
+				link = <&switch1port4
+					&switch0port5>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c_mux_reset>;
+
+	vf610-zii {
+		pinctrl_leds_debug: pinctrl-leds-debug {
+			fsl,pins = <
+				 VF610_PAD_PTE13__GPIO_118	0x31c2
+				 >;
+		};
+
+		pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
+			fsl,pins = <
+				 VF610_PAD_PTE14__GPIO_119	0x31c2
+				 >;
+		};
+
+		pinctrl_adc0_ad5: adc0ad5grp {
+			fsl,pins = <
+				VF610_PAD_PTC30__ADC0_SE5		0xa1
+			>;
+		};
+
+		pinctrl_esdhc1: esdhc1grp {
+			fsl,pins = <
+				VF610_PAD_PTA24__ESDHC1_CLK	0x31ef
+				VF610_PAD_PTA25__ESDHC1_CMD	0x31ef
+				VF610_PAD_PTA26__ESDHC1_DAT0	0x31ef
+				VF610_PAD_PTA27__ESDHC1_DAT1	0x31ef
+				VF610_PAD_PTA28__ESDHC1_DATA2	0x31ef
+				VF610_PAD_PTA29__ESDHC1_DAT3	0x31ef
+				VF610_PAD_PTA7__GPIO_134	0x219d
+			>;
+		};
+
+		pinctrl_fec1: fec1grp {
+			fsl,pins = <
+				VF610_PAD_PTA6__RMII_CLKIN		0x30d1
+				VF610_PAD_PTC9__ENET_RMII1_MDC		0x30d2
+				VF610_PAD_PTC10__ENET_RMII1_MDIO	0x30d3
+				VF610_PAD_PTC11__ENET_RMII1_CRS		0x30d1
+				VF610_PAD_PTC12__ENET_RMII1_RXD1	0x30d1
+				VF610_PAD_PTC13__ENET_RMII1_RXD0	0x30d1
+				VF610_PAD_PTC14__ENET_RMII1_RXER	0x30d1
+				VF610_PAD_PTC15__ENET_RMII1_TXD1	0x30d2
+				VF610_PAD_PTC16__ENET_RMII1_TXD0	0x30d2
+				VF610_PAD_PTC17__ENET_RMII1_TXEN	0x30d2
+			>;
+		};
+
+		/* -------------------------------------------------------------
+		 * speed:		  high (200 MHz)
+		 * slew rate:		  slow
+		 * open drain:		  enabled
+		 * hysteresis:		  Schmitt trigger
+		 * drive strength:	  20 Ohm
+		 * pull strength:	  22 kOhm pull-up
+		 * pull / keeper:	  enabled
+		 * pull / keeper select:  pull
+		 * output buffer:	  enabled
+		 * input buffer:	  enabled
+		 */
+		pinctrl_i2c0: i2c0grp {
+			fsl,pins = <
+				VF610_PAD_PTB14__I2C0_SCL		0x37ff
+				VF610_PAD_PTB15__I2C0_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				VF610_PAD_PTB16__I2C1_SCL		0x37ff
+				VF610_PAD_PTB17__I2C1_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c2: i2c2grp {
+			fsl,pins = <
+				VF610_PAD_PTA22__I2C2_SCL		0x37ff
+				VF610_PAD_PTA23__I2C2_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c3: i2c3grp {
+			fsl,pins = <
+				VF610_PAD_PTA30__I2C3_SCL		0x37ff
+				VF610_PAD_PTA31__I2C3_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_pwm0: pwm0grp {
+			fsl,pins = <
+				VF610_PAD_PTB0__FTM0_CH0		0x1582
+				VF610_PAD_PTB1__FTM0_CH1		0x1582
+				VF610_PAD_PTB2__FTM0_CH2		0x1582
+				VF610_PAD_PTB3__FTM0_CH3		0x1582
+			>;
+		};
+
+		pinctrl_uart0: uart0grp {
+			fsl,pins = <
+				VF610_PAD_PTB10__UART0_TX		0x21a2
+				VF610_PAD_PTB11__UART0_RX		0x21a1
+			>;
+		};
+
+		pinctrl_uart1: uart1grp {
+			fsl,pins = <
+				VF610_PAD_PTB23__UART1_TX		0x21a2
+				VF610_PAD_PTB24__UART1_RX		0x21a1
+			>;
+		};
+
+		pinctrl_uart2: uart2grp {
+			fsl,pins = <
+				VF610_PAD_PTD0__UART2_TX		0x21a2
+				VF610_PAD_PTD1__UART2_RX		0x21a1
+			>;
+		};
+
+		pinctrl_qspi0: qspi0grp {
+			fsl,pins = <
+				VF610_PAD_PTD7__QSPI0_B_QSCK		0x31c3
+				VF610_PAD_PTD8__QSPI0_B_CS0		0x31ff
+				VF610_PAD_PTD9__QSPI0_B_DATA3		0x31c3
+				VF610_PAD_PTD10__QSPI0_B_DATA2		0x31c3
+				VF610_PAD_PTD11__QSPI0_B_DATA1		0x31c3
+				VF610_PAD_PTD12__QSPI0_B_DATA0		0x31c3
+			>;
+		};
+
+		pinctrl_usb0_host: usb0-host-grp {
+			fsl,pins = <
+				VF610_PAD_PTD6__GPIO_85			0x62
+			>;
+		};
+	};
+};
+
+&L2 {
+	arm,data-latency = <2 1 2>;
+	arm,tag-latency = <3 2 3>;
+};
+
+&pwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm0>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&usbdev0 {
+	disable-over-current;
+	status = "okay";
+	vbus-supply = <&usb0_vbus>;
+	dr_mode = "host";
+};
+
+&usbh1 {
+	disable-over-current;
+	status = "okay";
+};
+
+&usbmisc0 {
+	status = "okay";
+};
+
+&usbmisc1 {
+	status = "okay";
+};
+
+&usbphy0 {
+	status = "okay";
+};
+
+&usbphy1 {
+	status = "okay";
+};
+
+&qspi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi0>;
+	fsl,nor-size = <0x10000000>;
+	fsl,spi-num-chipselects = <2>;
+	status = "okay";
+
+	flash0: mt25ql02gc@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,mt25ql02gc";
+		spi-max-frequency = <66000000>;
+		reg = <0>;
+
+		partition@0 {
+			label = "mt25ql02gc-0-uboot";
+			reg = <0x0 0x0100000>;
+		};
+
+		partition2@100000 {
+			label = "mt25ql02gc-0-dtb";
+			reg = <0x0100000 0x0100000>;
+		};
+
+		partition3@200000 {
+			label = "mt25ql02gc-0-kernel";
+			reg = <0x0200000 0x0500000>;
+		};
+
+		partition4@700000 {
+			label = "mt25ql02gc-0-rfs";
+			reg = <0x0600000 0x8000000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
new file mode 100644
index 000000000000..6e657a9312ce
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610-zii-dev.dtsi"
+
+/ {
+	model = "ZII VF610 Development Board, Rev B";
+	compatible = "zii,vf610dev-b", "zii,vf610dev", "fsl,vf610";
+
+	chosen {
+		bootargs = "console=ttyLP0,115200n8";
+		stdout-path = &uart0;
+	};
+
+	memory {
+		reg = <0x80000000 0x8000000>;
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pinctrl_leds_debug>;
+		pinctrl-names = "default";
+
+		debug_1 {
+			label = "zii:green:debug1";
+			gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	mdio-mux {
+		compatible = "mdio-mux-gpio";
+		pinctrl-0 = <&pinctrl_mdio_mux>;
+		pinctrl-names = "default";
+		gpios = <&gpio0 8  GPIO_ACTIVE_HIGH
+			 &gpio0 9  GPIO_ACTIVE_HIGH
+			 &gpio0 24 GPIO_ACTIVE_HIGH
+			 &gpio0 25 GPIO_ACTIVE_HIGH>;
+		mdio-parent-bus = <&mdio1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio_mux_1: mdio@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mdio_mux_2: mdio@2 {
+			reg = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mdio_mux_4: mdio@4 {
+			reg = <4>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mdio_mux_8: mdio@8 {
+			reg = <8>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	dsa@0 {
+		compatible = "marvell,dsa";
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		dsa,ethernet = <&fec1>;
+		dsa,mii-bus = <&mdio_mux_1>;
+
+		/* 6352 - Primary - 7 ports */
+		switch0: switch@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x00 0>;
+			eeprom-length = <512>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan0";
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan1";
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan2";
+			};
+
+			switch0port5: port@5 {
+				reg = <5>;
+				label = "dsa";
+				phy-mode = "rgmii-txid";
+				link = <&switch1port6
+					&switch2port9>;
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port@6 {
+				reg = <6>;
+				label = "cpu";
+				fixed-link {
+					speed = <100>;
+					full-duplex;
+				};
+			};
+
+		};
+
+		/* 6352 - Secondary - 7 ports */
+		switch1: switch@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x00 1>;
+			eeprom-length = <512>;
+			mii-bus = <&mdio_mux_2>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan3";
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan4";
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan5";
+			};
+
+			switch1port5: port@5 {
+				reg = <5>;
+				label = "dsa";
+				link = <&switch2port9>;
+				phy-mode = "rgmii-txid";
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			switch1port6: port@6 {
+				reg = <6>;
+				label = "dsa";
+				phy-mode = "rgmii-txid";
+				link = <&switch0port5>;
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+		};
+
+		/* 6185 - 10 ports */
+		switch2: switch@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x00 2>;
+			mii-bus = <&mdio_mux_4>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan6";
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan7";
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan8";
+			};
+
+			port@3 {
+				reg = <3>;
+				label = "optical3";
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+					link-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>;
+				};
+			};
+
+			port@4 {
+				reg = <4>;
+				label = "optical4";
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+					link-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>;
+
+				};
+			};
+
+			switch2port9: port@9 {
+				reg = <9>;
+				label = "dsa";
+				phy-mode = "rgmii-txid";
+				link = <&switch1port5
+					&switch0port5>;
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c_mux_reset>;
+
+	vf610-zii {
+		pinctrl_mdio_mux: pinctrl-mdio-mux {
+			fsl,pins = <
+				VF610_PAD_PTA18__GPIO_8	0x31c2
+				VF610_PAD_PTA19__GPIO_9	0x31c2
+				VF610_PAD_PTB2__GPIO_24	0x31c2
+				VF610_PAD_PTB3__GPIO_25	0x31c2
+			>;
+		};
+		pinctrl_fec0: fec0grp {
+			fsl,pins = <
+				VF610_PAD_PTC0__ENET_RMII0_MDC	0x30d2
+				VF610_PAD_PTC1__ENET_RMII0_MDIO	0x30d3
+				VF610_PAD_PTC2__ENET_RMII0_CRS	0x30d1
+				VF610_PAD_PTC3__ENET_RMII0_RXD1	0x30d1
+				VF610_PAD_PTC4__ENET_RMII0_RXD0	0x30d1
+				VF610_PAD_PTC5__ENET_RMII0_RXER	0x30d1
+				VF610_PAD_PTC6__ENET_RMII0_TXD1	0x30d2
+				VF610_PAD_PTC7__ENET_RMII0_TXD0	0x30d2
+				VF610_PAD_PTC8__ENET_RMII0_TXEN	0x30d2
+			>;
+		};
+
+		pinctrl_leds_debug: pinctrl-leds-debug {
+			fsl,pins = <
+				 VF610_PAD_PTD20__GPIO_74	0x31c2
+				 >;
+		};
+		pinctrl_pca9554_opt: pinctrl-pca95540-opt {
+			fsl,pins = <
+				VF610_PAD_PTB18__GPIO_40	0x219d
+			>;
+		};
+	};
+};
+
+&fec0 {
+	phy-mode = "rmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec0>;
+	status = "okay";
+};
+
+&i2c0 {
+	gpio6: pca9505@20 {
+		compatible = "nxp,pca9554";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pca9554_opt>;
+		reg = <0x22>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
diff --git a/arch/arm/boot/dts/vf610-zii-dev.dtsi b/arch/arm/boot/dts/vf610-zii-dev.dtsi
new file mode 100644
index 000000000000..9ff7abbbb36e
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-zii-dev.dtsi
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "vf610.dtsi"
+
+/ {
+	audio_ext: mclk-osc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24576000>;
+	};
+
+	enet_ext: eth-osc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		reg_3p3v: regulator@0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "3P3V";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		reg_vcc_3v3_mcu: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "vcc_3v3_mcu";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		usb0_vbus: regulator@2 {
+			compatible = "regulator-fixed";
+			pinctrl-0 = <&pinctrl_usb_vbus>;
+			reg = <2>;
+			regulator-name = "usb_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 6 0>;
+		};
+	};
+};
+
+&adc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc0_ad5>;
+	vref-supply = <&reg_vcc_3v3_mcu>;
+	status = "okay";
+};
+
+&edma0 {
+	status = "okay";
+};
+
+&esdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_esdhc1>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&fec1 {
+	phy-mode = "rmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec1>;
+	status = "okay";
+
+	fixed-link {
+		   speed = <100>;
+		   full-duplex;
+	};
+
+	mdio1: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+	};
+};
+
+&i2c0 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c0>;
+	status = "okay";
+
+	gpio5: pca9505@20 {
+		compatible = "nxp,pca9554";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	lm75@48 {
+		compatible = "national,lm75";
+		reg = <0x48>;
+	};
+
+	at24c04@50 {
+		compatible = "atmel,24c04";
+		reg = <0x50>;
+	};
+
+	at24c04@52 {
+		compatible = "atmel,24c04";
+		reg = <0x52>;
+	};
+
+	ds1682@6b {
+		compatible = "dallas,ds1682";
+		reg = <0x6b>;
+	};
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	tca9548@70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+
+		i2c2_0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			sfp1: at24c04@50 {
+				compatible = "atmel,24c02";
+				reg = <0x50>;
+			};
+		};
+
+		i2c2_1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			sfp2: at24c04@50 {
+				compatible = "atmel,24c02";
+				reg = <0x50>;
+			};
+		};
+
+		i2c2_2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+
+			sfp3: at24c04@50 {
+				compatible = "atmel,24c02";
+				reg = <0x50>;
+			};
+		};
+
+		i2c2_3:  i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+
+			sfp4: at24c04@50 {
+				compatible = "atmel,24c02";
+				reg = <0x50>;
+			};
+
+		};
+
+		i2c2_4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+	};
+};
+
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c_mux_reset>;
+
+	vf610-zii {
+		pinctrl_usb_vbus: pinctrl-usb-vbus {
+			fsl,pins = <
+				VF610_PAD_PTA16__GPIO_6	0x31c2
+			>;
+		};
+
+		pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
+			fsl,pins = <
+				 VF610_PAD_PTE14__GPIO_119	0x31c2
+				 >;
+		};
+
+		pinctrl_adc0_ad5: adc0ad5grp {
+			fsl,pins = <
+				VF610_PAD_PTC30__ADC0_SE5		0xa1
+			>;
+		};
+
+		pinctrl_esdhc1: esdhc1grp {
+			fsl,pins = <
+				VF610_PAD_PTA24__ESDHC1_CLK	0x31ef
+				VF610_PAD_PTA25__ESDHC1_CMD	0x31ef
+				VF610_PAD_PTA26__ESDHC1_DAT0	0x31ef
+				VF610_PAD_PTA27__ESDHC1_DAT1	0x31ef
+				VF610_PAD_PTA28__ESDHC1_DATA2	0x31ef
+				VF610_PAD_PTA29__ESDHC1_DAT3	0x31ef
+				VF610_PAD_PTA7__GPIO_134	0x219d
+			>;
+		};
+
+		pinctrl_fec1: fec1grp {
+			fsl,pins = <
+				VF610_PAD_PTA6__RMII_CLKIN		0x30d1
+				VF610_PAD_PTC9__ENET_RMII1_MDC		0x30d2
+				VF610_PAD_PTC10__ENET_RMII1_MDIO	0x30d3
+				VF610_PAD_PTC11__ENET_RMII1_CRS		0x30d1
+				VF610_PAD_PTC12__ENET_RMII1_RXD1	0x30d1
+				VF610_PAD_PTC13__ENET_RMII1_RXD0	0x30d1
+				VF610_PAD_PTC14__ENET_RMII1_RXER	0x30d1
+				VF610_PAD_PTC15__ENET_RMII1_TXD1	0x30d2
+				VF610_PAD_PTC16__ENET_RMII1_TXD0	0x30d2
+				VF610_PAD_PTC17__ENET_RMII1_TXEN	0x30d2
+			>;
+		};
+
+		/* -------------------------------------------------------------
+		 * speed:		  high (200 MHz)
+		 * slew rate:		  slow
+		 * open drain:		  enabled
+		 * hysteresis:		  Schmitt trigger
+		 * drive strength:	  20 Ohm
+		 * pull strength:	  22 kOhm pull-up
+		 * pull / keeper:	  enabled
+		 * pull / keeper select:  pull
+		 * output buffer:	  enabled
+		 * input buffer:	  enabled
+		 */
+		pinctrl_i2c0: i2c0grp {
+			fsl,pins = <
+				VF610_PAD_PTB14__I2C0_SCL		0x37ff
+				VF610_PAD_PTB15__I2C0_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				VF610_PAD_PTB16__I2C1_SCL		0x37ff
+				VF610_PAD_PTB17__I2C1_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c2: i2c2grp {
+			fsl,pins = <
+				VF610_PAD_PTA22__I2C2_SCL		0x37ff
+				VF610_PAD_PTA23__I2C2_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_i2c3: i2c3grp {
+			fsl,pins = <
+				VF610_PAD_PTA30__I2C3_SCL		0x37ff
+				VF610_PAD_PTA31__I2C3_SDA		0x37ff
+			>;
+		};
+
+		pinctrl_pwm0: pwm0grp {
+			fsl,pins = <
+				VF610_PAD_PTB0__FTM0_CH0		0x1582
+				VF610_PAD_PTB1__FTM0_CH1		0x1582
+				VF610_PAD_PTB2__FTM0_CH2		0x1582
+				VF610_PAD_PTB3__FTM0_CH3		0x1582
+			>;
+		};
+
+		pinctrl_uart0: uart0grp {
+			fsl,pins = <
+				VF610_PAD_PTB10__UART0_TX		0x21a2
+				VF610_PAD_PTB11__UART0_RX		0x21a1
+			>;
+		};
+
+		pinctrl_uart1: uart1grp {
+			fsl,pins = <
+				VF610_PAD_PTB23__UART1_TX		0x21a2
+				VF610_PAD_PTB24__UART1_RX		0x21a1
+			>;
+		};
+
+		pinctrl_uart2: uart2grp {
+			fsl,pins = <
+				VF610_PAD_PTD0__UART2_TX		0x21a2
+				VF610_PAD_PTD1__UART2_RX		0x21a1
+			>;
+		};
+
+		pinctrl_qspi0: qspi0grp {
+			fsl,pins = <
+				VF610_PAD_PTD7__QSPI0_B_QSCK		0x31c3
+				VF610_PAD_PTD8__QSPI0_B_CS0		0x31ff
+				VF610_PAD_PTD9__QSPI0_B_DATA3		0x31c3
+				VF610_PAD_PTD10__QSPI0_B_DATA2		0x31c3
+				VF610_PAD_PTD11__QSPI0_B_DATA1		0x31c3
+				VF610_PAD_PTD12__QSPI0_B_DATA0		0x31c3
+			>;
+		};
+
+		pinctrl_usb0_host: usb0-host-grp {
+			fsl,pins = <
+				VF610_PAD_PTD6__GPIO_85			0x62
+			>;
+		};
+	};
+};
+
+&L2 {
+	arm,data-latency = <2 1 2>;
+	arm,tag-latency = <3 2 3>;
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&usbdev0 {
+	disable-over-current;
+	status = "okay";
+	vbus-supply = <&usb0_vbus>;
+	dr_mode = "host";
+};
+
+&usbh1 {
+	disable-over-current;
+	status = "okay";
+};
+
+&usbmisc0 {
+	status = "okay";
+};
+
+&usbmisc1 {
+	status = "okay";
+};
+
+&usbphy0 {
+	status = "okay";
+};
+
+&usbphy1 {
+	status = "okay";
+};
+
+&qspi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi0>;
+	fsl,nor-size = <0x10000000>;
+	fsl,spi-num-chipselects = <2>;
+	status = "okay";
+
+	flash0: mt25ql02gc@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "micron,mt25ql02gc";
+		spi-max-frequency = <66000000>;
+		reg = <0>;
+
+		partition@0 {
+			label = "mt25ql02gc-0-uboot";
+			reg = <0x0 0x0100000>;
+		};
+
+		partition2@100000 {
+			label = "mt25ql02gc-0-dtb";
+			reg = <0x0100000 0x0100000>;
+		};
+
+		partition3@200000 {
+			label = "mt25ql02gc-0-kernel";
+			reg = <0x0200000 0x0500000>;
+		};
+
+		partition4@700000 {
+			label = "mt25ql02gc-0-rfs";
+			reg = <0x0600000 0x8000000>;
+		};
+	};
+};
-- 
2.6.3

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

* [PATCH RFC 03/28] net: dsa: Move platform data allocation for OF
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 01/28] component: remove old add_components method Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 02/28] ARM: VF610: Add Zodiac Inflight Innovations development boards Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 04/28] dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent Andrew Lunn
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev

From: Florian Fainelli <f.fainelli@gmail.com>

Do not have dsa_of_probe() allocate and assign struct dsa_platform_data,
but instead do this outside of this function such that we can control
exactly the storage of that data structure.

This is a preliminary change to allow multiple callers of dsa_of_probe()
not to clobber an existing dsa_platform_data and later, control where
this data structure is coming from.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 net/dsa/dsa.c | 48 +++++++++++++++++++-----------------------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 208d1b257194..704502c22306 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -651,13 +651,12 @@ static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
 	kfree(pd->chip);
 }
 
-static int dsa_of_probe(struct device *dev)
+static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 {
 	struct device_node *np = dev->of_node;
 	struct device_node *child, *mdio, *ethernet, *port;
 	struct mii_bus *mdio_bus, *mdio_bus_switch;
 	struct net_device *ethernet_dev;
-	struct dsa_platform_data *pd;
 	struct dsa_chip_data *cd;
 	const char *port_name;
 	int chip_index, port_index;
@@ -666,7 +665,7 @@ static int dsa_of_probe(struct device *dev)
 	enum of_gpio_flags of_flags;
 	unsigned long flags;
 	u32 eeprom_len;
-	int ret;
+	int ret = 0;
 
 	mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
 	if (!mdio)
@@ -688,13 +687,6 @@ static int dsa_of_probe(struct device *dev)
 		goto out_put_mdio;
 	}
 
-	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-	if (!pd) {
-		ret = -ENOMEM;
-		goto out_put_ethernet;
-	}
-
-	dev->platform_data = pd;
 	pd->of_netdev = ethernet_dev;
 	pd->nr_chips = of_get_available_child_count(np);
 	if (pd->nr_chips > DSA_MAX_SWITCHES)
@@ -702,10 +694,8 @@ static int dsa_of_probe(struct device *dev)
 
 	pd->chip = kcalloc(pd->nr_chips, sizeof(struct dsa_chip_data),
 			   GFP_KERNEL);
-	if (!pd->chip) {
-		ret = -ENOMEM;
-		goto out_free;
-	}
+	if (!pd->chip)
+		goto out_put_mdio;
 
 	chip_index = -1;
 	for_each_available_child_of_node(np, child) {
@@ -795,34 +785,29 @@ static int dsa_of_probe(struct device *dev)
 
 out_free_chip:
 	dsa_of_free_platform_data(pd);
-out_free:
-	kfree(pd);
-	dev->platform_data = NULL;
-out_put_ethernet:
-	put_device(&ethernet_dev->dev);
+
 out_put_mdio:
 	put_device(&mdio_bus->dev);
 	return ret;
 }
 
-static void dsa_of_remove(struct device *dev)
+static void dsa_of_remove(struct device *dev, struct dsa_platform_data *pd)
 {
-	struct dsa_platform_data *pd = dev->platform_data;
-
 	if (!dev->of_node)
 		return;
 
 	dsa_of_free_platform_data(pd);
 	put_device(&pd->of_netdev->dev);
-	kfree(pd);
 }
 #else
-static inline int dsa_of_probe(struct device *dev)
+static inline int dsa_of_probe(struct device *dev,
+			       struct dsa_platform_data *pd)
 {
 	return 0;
 }
 
-static inline void dsa_of_remove(struct device *dev)
+static inline void dsa_of_remove(struct device *dev,
+				 struct dsa_platform_data *pd)
 {
 }
 #endif
@@ -881,11 +866,15 @@ static int dsa_probe(struct platform_device *pdev)
 		       dsa_driver_version);
 
 	if (pdev->dev.of_node) {
-		ret = dsa_of_probe(&pdev->dev);
+		pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
+		if (!pd)
+			return -ENOMEM;
+
+		ret = dsa_of_probe(&pdev->dev, pd);
 		if (ret)
 			return ret;
 
-		pd = pdev->dev.platform_data;
+		pdev->dev.platform_data = pd;
 	}
 
 	if (pd == NULL || (pd->netdev == NULL && pd->of_netdev == NULL))
@@ -926,7 +915,7 @@ static int dsa_probe(struct platform_device *pdev)
 	return 0;
 
 out:
-	dsa_of_remove(&pdev->dev);
+	dsa_of_remove(&pdev->dev, pd);
 
 	return ret;
 }
@@ -948,9 +937,10 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
 static int dsa_remove(struct platform_device *pdev)
 {
 	struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
+	struct dsa_platform_data *pd = pdev->dev.platform_data;
 
 	dsa_remove_dst(dst);
-	dsa_of_remove(&pdev->dev);
+	dsa_of_remove(&pdev->dev, pd);
 
 	return 0;
 }
-- 
2.6.3

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

* [PATCH RFC 04/28] dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (2 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 03/28] net: dsa: Move platform data allocation for OF Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers Andrew Lunn
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

All the drivers support multiple chips, but mv88e6123_61_65 is the
only one that reflects this in its naming. Change it to be consistent
with the other drivers.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/Kconfig           |   2 +-
 drivers/net/dsa/Makefile          |   4 +-
 drivers/net/dsa/mv88e6123.c       | 124 ++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6123_61_65.c | 124 --------------------------------------
 drivers/net/dsa/mv88e6xxx.c       |   4 +-
 drivers/net/dsa/mv88e6xxx.h       |   2 +-
 6 files changed, 130 insertions(+), 130 deletions(-)
 create mode 100644 drivers/net/dsa/mv88e6123.c
 delete mode 100644 drivers/net/dsa/mv88e6123_61_65.c

diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4c483d937481..90ba003d8fdf 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -27,7 +27,7 @@ config NET_DSA_MV88E6131
 	  This enables support for the Marvell 88E6085/6095/6095F/6131
 	  ethernet switch chips.
 
-config NET_DSA_MV88E6123_61_65
+config NET_DSA_MV88E6123
 	tristate "Marvell 88E6123/6161/6165 ethernet switch chip support"
 	depends on NET_DSA
 	select NET_DSA_MV88E6XXX
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index e2d51c4b9382..a6e09939be65 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,8 +1,8 @@
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
 mv88e6xxx_drv-y += mv88e6xxx.o
-ifdef CONFIG_NET_DSA_MV88E6123_61_65
-mv88e6xxx_drv-y += mv88e6123_61_65.o
+ifdef CONFIG_NET_DSA_MV88E6123
+mv88e6xxx_drv-y += mv88e6123.o
 endif
 ifdef CONFIG_NET_DSA_MV88E6131
 mv88e6xxx_drv-y += mv88e6131.o
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
new file mode 100644
index 000000000000..69a6f79dcb10
--- /dev/null
+++ b/drivers/net/dsa/mv88e6123.c
@@ -0,0 +1,124 @@
+/*
+ * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
+ * Copyright (c) 2008-2009 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <net/dsa.h>
+#include "mv88e6xxx.h"
+
+static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
+	{ PORT_SWITCH_ID_6123, "Marvell 88E6123" },
+	{ PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)" },
+	{ PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)" },
+	{ PORT_SWITCH_ID_6161, "Marvell 88E6161" },
+	{ PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)" },
+	{ PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)" },
+	{ PORT_SWITCH_ID_6165, "Marvell 88E6165" },
+	{ PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)" },
+	{ PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
+};
+
+static char *mv88e6123_probe(struct device *host_dev, int sw_addr)
+{
+	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
+				     ARRAY_SIZE(mv88e6123_table));
+}
+
+static int mv88e6123_setup_global(struct dsa_switch *ds)
+{
+	u32 upstream_port = dsa_upstream_port(ds);
+	int ret;
+	u32 reg;
+
+	ret = mv88e6xxx_setup_global(ds);
+	if (ret)
+		return ret;
+
+	/* Disable the PHY polling unit (since there won't be any
+	 * external PHYs to poll), don't discard packets with
+	 * excessive collisions, and mask all interrupt sources.
+	 */
+	REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, 0x0000);
+
+	/* Configure the upstream port, and configure the upstream
+	 * port as the port to which ingress and egress monitor frames
+	 * are to be sent.
+	 */
+	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
+		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
+		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
+	REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
+
+	/* Disable remote management for now, and set the switch's
+	 * DSA device number.
+	 */
+	REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, ds->index & 0x1f);
+
+	return 0;
+}
+
+static int mv88e6123_setup(struct dsa_switch *ds)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
+	ret = mv88e6xxx_setup_common(ds);
+	if (ret < 0)
+		return ret;
+
+	switch (ps->id) {
+	case PORT_SWITCH_ID_6123:
+		ps->num_ports = 3;
+		break;
+	case PORT_SWITCH_ID_6161:
+	case PORT_SWITCH_ID_6165:
+		ps->num_ports = 6;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	ret = mv88e6xxx_switch_reset(ds, false);
+	if (ret < 0)
+		return ret;
+
+	ret = mv88e6123_setup_global(ds);
+	if (ret < 0)
+		return ret;
+
+	return mv88e6xxx_setup_ports(ds);
+}
+
+struct dsa_switch_driver mv88e6123_switch_driver = {
+	.tag_protocol		= DSA_TAG_PROTO_EDSA,
+	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
+	.probe			= mv88e6123_probe,
+	.setup			= mv88e6123_setup,
+	.set_addr		= mv88e6xxx_set_addr_indirect,
+	.phy_read		= mv88e6xxx_phy_read,
+	.phy_write		= mv88e6xxx_phy_write,
+	.get_strings		= mv88e6xxx_get_strings,
+	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
+	.get_sset_count		= mv88e6xxx_get_sset_count,
+	.adjust_link		= mv88e6xxx_adjust_link,
+#ifdef CONFIG_NET_DSA_HWMON
+	.get_temp		= mv88e6xxx_get_temp,
+#endif
+	.get_regs_len		= mv88e6xxx_get_regs_len,
+	.get_regs		= mv88e6xxx_get_regs,
+};
+
+MODULE_ALIAS("platform:mv88e6123");
+MODULE_ALIAS("platform:mv88e6161");
+MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
deleted file mode 100644
index d4fcf4570d95..000000000000
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_switch_id mv88e6123_61_65_table[] = {
-	{ PORT_SWITCH_ID_6123, "Marvell 88E6123" },
-	{ PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)" },
-	{ PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)" },
-	{ PORT_SWITCH_ID_6161, "Marvell 88E6161" },
-	{ PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)" },
-	{ PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)" },
-	{ PORT_SWITCH_ID_6165, "Marvell 88E6165" },
-	{ PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)" },
-	{ PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
-};
-
-static char *mv88e6123_61_65_probe(struct device *host_dev, int sw_addr)
-{
-	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_61_65_table,
-				     ARRAY_SIZE(mv88e6123_61_65_table));
-}
-
-static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
-{
-	u32 upstream_port = dsa_upstream_port(ds);
-	int ret;
-	u32 reg;
-
-	ret = mv88e6xxx_setup_global(ds);
-	if (ret)
-		return ret;
-
-	/* Disable the PHY polling unit (since there won't be any
-	 * external PHYs to poll), don't discard packets with
-	 * excessive collisions, and mask all interrupt sources.
-	 */
-	REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, 0x0000);
-
-	/* Configure the upstream port, and configure the upstream
-	 * port as the port to which ingress and egress monitor frames
-	 * are to be sent.
-	 */
-	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
-	REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
-
-	/* Disable remote management for now, and set the switch's
-	 * DSA device number.
-	 */
-	REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, ds->index & 0x1f);
-
-	return 0;
-}
-
-static int mv88e6123_61_65_setup(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ret = mv88e6xxx_setup_common(ds);
-	if (ret < 0)
-		return ret;
-
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6123:
-		ps->num_ports = 3;
-		break;
-	case PORT_SWITCH_ID_6161:
-	case PORT_SWITCH_ID_6165:
-		ps->num_ports = 6;
-		break;
-	default:
-		return -ENODEV;
-	}
-
-	ret = mv88e6xxx_switch_reset(ds, false);
-	if (ret < 0)
-		return ret;
-
-	ret = mv88e6123_61_65_setup_global(ds);
-	if (ret < 0)
-		return ret;
-
-	return mv88e6xxx_setup_ports(ds);
-}
-
-struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
-	.probe			= mv88e6123_61_65_probe,
-	.setup			= mv88e6123_61_65_setup,
-	.set_addr		= mv88e6xxx_set_addr_indirect,
-	.phy_read		= mv88e6xxx_phy_read,
-	.phy_write		= mv88e6xxx_phy_write,
-	.get_strings		= mv88e6xxx_get_strings,
-	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
-	.get_sset_count		= mv88e6xxx_get_sset_count,
-	.adjust_link		= mv88e6xxx_adjust_link,
-#ifdef CONFIG_NET_DSA_HWMON
-	.get_temp		= mv88e6xxx_get_temp,
-#endif
-	.get_regs_len		= mv88e6xxx_get_regs_len,
-	.get_regs		= mv88e6xxx_get_regs,
-};
-
-MODULE_ALIAS("platform:mv88e6123");
-MODULE_ALIAS("platform:mv88e6161");
-MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 75e245c4235e..529273676d36 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2640,8 +2640,8 @@ static int __init mv88e6xxx_init(void)
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
 	register_switch_driver(&mv88e6131_switch_driver);
 #endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
-	register_switch_driver(&mv88e6123_61_65_switch_driver);
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
+	register_switch_driver(&mv88e6123_switch_driver);
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
 	register_switch_driver(&mv88e6352_switch_driver);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 21c8daa03f78..9e5c56800b7b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -498,7 +498,7 @@ int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
 			     int reg, int val);
 
 extern struct dsa_switch_driver mv88e6131_switch_driver;
-extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
+extern struct dsa_switch_driver mv88e6123_switch_driver;
 extern struct dsa_switch_driver mv88e6352_switch_driver;
 extern struct dsa_switch_driver mv88e6171_switch_driver;
 
-- 
2.6.3

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

* [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (3 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 04/28] dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:36   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory Andrew Lunn
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

By passing a device structure to the switch devices, it allows them
to use devm_* methods for resource management.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/bcm_sf2.c   | 2 +-
 drivers/net/dsa/mv88e6060.c | 2 +-
 drivers/net/dsa/mv88e6123.c | 2 +-
 drivers/net/dsa/mv88e6131.c | 2 +-
 drivers/net/dsa/mv88e6171.c | 2 +-
 drivers/net/dsa/mv88e6352.c | 2 +-
 include/net/dsa.h           | 2 +-
 net/dsa/dsa.c               | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 6f946fedbb77..6925b3c13895 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -926,7 +926,7 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
 	}
 }
 
-static int bcm_sf2_sw_setup(struct dsa_switch *ds)
+static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
 {
 	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
 	struct bcm_sf2_priv *priv = ds_to_priv(ds);
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 0527f485c3dc..34bc374882c7 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -172,7 +172,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
 	return 0;
 }
 
-static int mv88e6060_setup(struct dsa_switch *ds)
+static int mv88e6060_setup(struct dsa_switch *ds, struct device *dev)
 {
 	int i;
 	int ret;
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 69a6f79dcb10..fab428bb7545 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -68,7 +68,7 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 	return 0;
 }
 
-static int mv88e6123_setup(struct dsa_switch *ds)
+static int mv88e6123_setup(struct dsa_switch *ds, struct device *dev)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index a92ca651c399..d82cf3d38455 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -86,7 +86,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 	return 0;
 }
 
-static int mv88e6131_setup(struct dsa_switch *ds)
+static int mv88e6131_setup(struct dsa_switch *ds, struct device *dev)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 6e18213b9c04..9635f14ec1fb 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -64,7 +64,7 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 	return 0;
 }
 
-static int mv88e6171_setup(struct dsa_switch *ds)
+static int mv88e6171_setup(struct dsa_switch *ds, struct device *dev)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index cc6c54553418..c2c4153e3423 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -75,7 +75,7 @@ static int mv88e6352_setup_global(struct dsa_switch *ds)
 	return 0;
 }
 
-static int mv88e6352_setup(struct dsa_switch *ds)
+static int mv88e6352_setup(struct dsa_switch *ds, struct device *dev)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 26a0e86e611e..f5b4f1bcfdf3 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -213,7 +213,7 @@ struct dsa_switch_driver {
 	 * Probing and setup.
 	 */
 	char	*(*probe)(struct device *host_dev, int sw_addr);
-	int	(*setup)(struct dsa_switch *ds);
+	int	(*setup)(struct dsa_switch *ds, struct device *dev);
 	int	(*set_addr)(struct dsa_switch *ds, u8 *addr);
 	u32	(*get_phy_flags)(struct dsa_switch *ds, int port);
 
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 704502c22306..7170c93637c8 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -300,7 +300,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 	/*
 	 * Do basic register setup.
 	 */
-	ret = drv->setup(ds);
+	ret = drv->setup(ds, parent);
 	if (ret < 0)
 		goto out;
 
-- 
2.6.3

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

* [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (4 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:39   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 07/28] net: dsa: Remove allocation of driver " Andrew Lunn
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Now the switch devices have a dev pointer, make use if it for allocating
the drivers private data structures using a devm_kzalloc().

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/bcm_sf2.c   |  7 +++++--
 drivers/net/dsa/mv88e6123.c |  6 +++---
 drivers/net/dsa/mv88e6131.c |  6 +++---
 drivers/net/dsa/mv88e6171.c |  6 +++---
 drivers/net/dsa/mv88e6352.c |  6 +++---
 drivers/net/dsa/mv88e6xxx.c | 13 ++++++++++---
 drivers/net/dsa/mv88e6xxx.h |  5 ++++-
 include/net/dsa.h           |  8 +++++++-
 8 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 6925b3c13895..23326c2a01b8 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -929,7 +929,7 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
 static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
 {
 	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
-	struct bcm_sf2_priv *priv = ds_to_priv(ds);
+	struct bcm_sf2_priv *priv;
 	struct device_node *dn;
 	void __iomem **base;
 	unsigned int port;
@@ -937,6 +937,10 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
 	u32 reg, rev;
 	int ret;
 
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	spin_lock_init(&priv->indir_lock);
 	mutex_init(&priv->stats_mutex);
 
@@ -1365,7 +1369,6 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
 
 static struct dsa_switch_driver bcm_sf2_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_BRCM,
-	.priv_size		= sizeof(struct bcm_sf2_priv),
 	.probe			= bcm_sf2_sw_probe,
 	.setup			= bcm_sf2_sw_setup,
 	.set_addr		= bcm_sf2_sw_set_addr,
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index fab428bb7545..9d39f108793b 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -70,13 +70,14 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 
 static int mv88e6123_setup(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct mv88e6xxx_priv_state *ps;
 	int ret;
 
-	ret = mv88e6xxx_setup_common(ds);
+	ret = mv88e6xxx_setup_common(ds, dev);
 	if (ret < 0)
 		return ret;
 
+	ps = ds_to_priv(ds);
 	switch (ps->id) {
 	case PORT_SWITCH_ID_6123:
 		ps->num_ports = 3;
@@ -102,7 +103,6 @@ static int mv88e6123_setup(struct dsa_switch *ds, struct device *dev)
 
 struct dsa_switch_driver mv88e6123_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
 	.probe			= mv88e6123_probe,
 	.setup			= mv88e6123_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index d82cf3d38455..3103b4953af4 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -88,13 +88,14 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 
 static int mv88e6131_setup(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct mv88e6xxx_priv_state *ps;
 	int ret;
 
-	ret = mv88e6xxx_setup_common(ds);
+	ret = mv88e6xxx_setup_common(ds, dev);
 	if (ret < 0)
 		return ret;
 
+	ps = ds_to_priv(ds);
 	mv88e6xxx_ppu_state_init(ds);
 
 	switch (ps->id) {
@@ -159,7 +160,6 @@ mv88e6131_phy_write(struct dsa_switch *ds,
 
 struct dsa_switch_driver mv88e6131_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_DSA,
-	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
 	.probe			= mv88e6131_probe,
 	.setup			= mv88e6131_setup,
 	.set_addr		= mv88e6xxx_set_addr_direct,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 9635f14ec1fb..29a77366afc6 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -66,13 +66,14 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 
 static int mv88e6171_setup(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct mv88e6xxx_priv_state *ps;
 	int ret;
 
-	ret = mv88e6xxx_setup_common(ds);
+	ret = mv88e6xxx_setup_common(ds, dev);
 	if (ret < 0)
 		return ret;
 
+	ps = ds_to_priv(ds);
 	ps->num_ports = 7;
 
 	ret = mv88e6xxx_switch_reset(ds, true);
@@ -88,7 +89,6 @@ static int mv88e6171_setup(struct dsa_switch *ds, struct device *dev)
 
 struct dsa_switch_driver mv88e6171_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
 	.probe			= mv88e6171_probe,
 	.setup			= mv88e6171_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index c2c4153e3423..eb57a379b9cc 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -77,13 +77,14 @@ static int mv88e6352_setup_global(struct dsa_switch *ds)
 
 static int mv88e6352_setup(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct mv88e6xxx_priv_state *ps;
 	int ret;
 
-	ret = mv88e6xxx_setup_common(ds);
+	ret = mv88e6xxx_setup_common(ds, dev);
 	if (ret < 0)
 		return ret;
 
+	ps = ds_to_priv(ds);
 	ps->num_ports = 7;
 
 	mutex_init(&ps->eeprom_mutex);
@@ -301,7 +302,6 @@ static int mv88e6352_set_eeprom(struct dsa_switch *ds,
 
 struct dsa_switch_driver mv88e6352_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
 	.probe			= mv88e6352_probe,
 	.setup			= mv88e6352_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 529273676d36..772adc7f9397 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -281,7 +281,7 @@ static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
 
 	ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
 	if (mutex_trylock(&ps->ppu_mutex)) {
-		struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
+		struct dsa_switch *ds = ps->ds;
 
 		if (mv88e6xxx_ppu_enable(ds) == 0)
 			ps->ppu_disabled = 0;
@@ -2187,9 +2187,16 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 	return 0;
 }
 
-int mv88e6xxx_setup_common(struct dsa_switch *ds)
+int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct mv88e6xxx_priv_state *ps;
+
+	ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
+	if (!ps)
+		return -ENOMEM;
+
+	ds->priv = ps;
+	ps->ds = ds;
 
 	mutex_init(&ps->smi_mutex);
 
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 9e5c56800b7b..72f7dbbce0e2 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -379,6 +379,9 @@ struct mv88e6xxx_vtu_stu_entry {
 };
 
 struct mv88e6xxx_priv_state {
+	/* The dsa_switch this private structure is related to */
+	struct dsa_switch *ds;
+
 	/* When using multi-chip addressing, this mutex protects
 	 * access to the indirect access registers.  (In single-chip
 	 * mode, this mutex is effectively useless.)
@@ -431,7 +434,7 @@ char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
 			    const struct mv88e6xxx_switch_id *table,
 			    unsigned int num);
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
-int mv88e6xxx_setup_common(struct dsa_switch *ds);
+int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev);
 int mv88e6xxx_setup_global(struct dsa_switch *ds);
 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
diff --git a/include/net/dsa.h b/include/net/dsa.h
index f5b4f1bcfdf3..05067b030962 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -130,6 +130,12 @@ struct dsa_switch {
 	int			index;
 
 	/*
+	 * Give the switch driver somewhere to hang its private data
+	 * structure.
+	 */
+	void *priv;
+
+	/*
 	 * Tagging protocol understood by this switch
 	 */
 	enum dsa_tag_protocol	tag_protocol;
@@ -340,7 +346,7 @@ struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
 
 static inline void *ds_to_priv(struct dsa_switch *ds)
 {
-	return (void *)(ds + 1);
+	return ds->priv;
 }
 
 static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst)
-- 
2.6.3

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

* [PATCH RFC 07/28] net: dsa: Remove allocation of driver private memory
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (5 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:39   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure Andrew Lunn
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

The drivers now allocate their own memory for private usage. Remove
the allocation from the core code.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/net/dsa.h | 1 -
 net/dsa/dsa.c     | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 05067b030962..f6b8001a500f 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -213,7 +213,6 @@ struct dsa_switch_driver {
 	struct list_head	list;
 
 	enum dsa_tag_protocol	tag_protocol;
-	int			priv_size;
 
 	/*
 	 * Probing and setup.
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 7170c93637c8..ee6177c602fb 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -400,7 +400,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 	/*
 	 * Allocate and initialise switch state.
 	 */
-	ds = devm_kzalloc(parent, sizeof(*ds) + drv->priv_size, GFP_KERNEL);
+	ds = devm_kzalloc(parent, sizeof(*ds), GFP_KERNEL);
 	if (ds == NULL)
 		return ERR_PTR(-ENOMEM);
 
-- 
2.6.3

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

* [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (6 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 07/28] net: dsa: Remove allocation of driver " Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:40   ` Florian Fainelli
  2016-01-21 20:41   ` Vivien Didelot
  2015-12-23 12:56 ` [PATCH RFC 09/28] net: dsa: Add basic support for component master support Andrew Lunn
                   ` (20 subsequent siblings)
  28 siblings, 2 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Rather than looking up the mii bus and address every time, do it once
and setup, and keep it in the private structure.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6060.c | 23 +++++++++++++----------
 drivers/net/dsa/mv88e6060.h | 11 +++++++++++
 drivers/net/dsa/mv88e6xxx.c | 16 ++++++----------
 drivers/net/dsa/mv88e6xxx.h |  6 ++++++
 4 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 34bc374882c7..d48708dfd963 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -19,12 +19,9 @@
 
 static int reg_read(struct dsa_switch *ds, int addr, int reg)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	struct mv88e6060_priv *priv = ds_to_priv(ds);
 
-	if (bus == NULL)
-		return -EINVAL;
-
-	return mdiobus_read_nested(bus, ds->pd->sw_addr + addr, reg);
+	return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
 }
 
 #define REG_READ(addr, reg)					\
@@ -40,12 +37,9 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)
 
 static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-
-	if (bus == NULL)
-		return -EINVAL;
+	struct mv88e6060_priv *priv = ds_to_priv(ds);
 
-	return mdiobus_write_nested(bus, ds->pd->sw_addr + addr, reg, val);
+	return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
 }
 
 #define REG_WRITE(addr, reg, val)				\
@@ -176,6 +170,15 @@ static int mv88e6060_setup(struct dsa_switch *ds, struct device *dev)
 {
 	int i;
 	int ret;
+	struct mv88e6060_priv *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	ds->priv = priv;
+	priv->bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	priv->sw_addr = ds->pd->sw_addr;
 
 	ret = mv88e6060_switch_reset(ds);
 	if (ret < 0)
diff --git a/drivers/net/dsa/mv88e6060.h b/drivers/net/dsa/mv88e6060.h
index cc9b2ed4aff4..10249bd16292 100644
--- a/drivers/net/dsa/mv88e6060.h
+++ b/drivers/net/dsa/mv88e6060.h
@@ -108,4 +108,15 @@
 #define GLOBAL_ATU_MAC_23	0x0e
 #define GLOBAL_ATU_MAC_45	0x0f
 
+struct mv88e6060_priv {
+	/* MDIO bus and address on bus to use. When in single chip
+	 * mode, address is 0, and the switch uses multiple addresses
+	 * on the bus.  When in multi-chip mode, the switch uses a
+	 * single address which contains two registers used for
+	 * indirect access to more registers.
+	 */
+	struct mii_bus *bus;
+	int sw_addr;
+};
+
 #endif
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 772adc7f9397..170b98f3acbe 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -94,15 +94,12 @@ static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,
 
 static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	assert_smi_lock(ds);
 
-	if (bus == NULL)
-		return -EINVAL;
-
-	ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg);
+	ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg);
 	if (ret < 0)
 		return ret;
 
@@ -159,17 +156,14 @@ static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
 				u16 val)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
 	assert_smi_lock(ds);
 
-	if (bus == NULL)
-		return -EINVAL;
-
 	dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
 		addr, reg, val);
 
-	return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
+	return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val);
 }
 
 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
@@ -2197,6 +2191,8 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
 
 	ds->priv = ps;
 	ps->ds = ds;
+	ps->bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	ps->sw_addr = ds->pd->sw_addr;
 
 	mutex_init(&ps->smi_mutex);
 
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 72f7dbbce0e2..62069b30f6e5 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -388,6 +388,12 @@ struct mv88e6xxx_priv_state {
 	 */
 	struct mutex	smi_mutex;
 
+	/* The MII bus and the address on the bus that is used to
+	 * communication with the switch
+	 */
+	struct mii_bus *bus;
+	int sw_addr;
+
 #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
 	/* Handles automatic disabling and re-enabling of the PHY
 	 * polling unit.
-- 
2.6.3

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

* [PATCH RFC 09/28] net: dsa: Add basic support for component master support
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (7 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 10/28] net: dsa: Keep a reference to the switch device for component matching Andrew Lunn
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Start using the component framework. The DSA device will be the
master, and the switch drivers will be slaves. Add basic component
master support to the DSA framework.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 48 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index ee6177c602fb..2558c11f73ce 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -9,6 +9,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
 #include <linux/hwmon.h>
@@ -28,7 +29,7 @@
 #include "dsa_priv.h"
 
 char dsa_driver_version[] = "0.1";
-
+static const struct component_master_ops dsa_ops;
 
 /* switch driver registration ***********************************************/
 static DEFINE_MUTEX(dsa_switch_drivers_mutex);
@@ -813,13 +814,12 @@ static inline void dsa_of_remove(struct device *dev,
 #endif
 
 static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
-			 struct device *parent, struct dsa_platform_data *pd)
+			 struct device *parent)
 {
 	int i;
 	unsigned configured = 0;
+	struct dsa_platform_data *pd = dst->pd;
 
-	dst->pd = pd;
-	dst->master_netdev = dev;
 	dst->cpu_switch = -1;
 	dst->cpu_port = -1;
 
@@ -855,9 +855,22 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 	return 0;
 }
 
+static int dsa_bind(struct device *dev)
+{
+	struct dsa_switch_tree *dst = dev_get_drvdata(dev);
+	int ret;
+
+	ret = component_bind_all(dev, dst);
+	if (ret)
+		return ret;
+
+	return dsa_setup_dst(dst, dst->master_netdev, dev);
+}
+
 static int dsa_probe(struct platform_device *pdev)
 {
 	struct dsa_platform_data *pd = pdev->dev.platform_data;
+	struct component_match *match = NULL;
 	struct net_device *dev;
 	struct dsa_switch_tree *dst;
 	int ret;
@@ -904,15 +917,13 @@ static int dsa_probe(struct platform_device *pdev)
 		goto out;
 	}
 
+	dst->pd = pd;
+	dst->master_netdev = dev;
+
 	platform_set_drvdata(pdev, dst);
 
-	ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
-	if (ret) {
-		dev_put(dev);
-		goto out;
-	}
 
-	return 0;
+	return component_master_add_with_match(&pdev->dev, &dsa_ops, match);
 
 out:
 	dsa_of_remove(&pdev->dev, pd);
@@ -934,21 +945,32 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
 	dev_put(dst->master_netdev);
 }
 
-static int dsa_remove(struct platform_device *pdev)
+static void dsa_unbind(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
 	struct dsa_platform_data *pd = pdev->dev.platform_data;
 
 	dsa_remove_dst(dst);
 	dsa_of_remove(&pdev->dev, pd);
-
-	return 0;
 }
 
+static const struct component_master_ops dsa_ops = {
+	.bind = dsa_bind,
+	.unbind = dsa_unbind,
+};
+
 static void dsa_shutdown(struct platform_device *pdev)
 {
 }
 
+static int dsa_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &dsa_ops);
+
+	return 0;
+}
+
 static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
 			  struct packet_type *pt, struct net_device *orig_dev)
 {
-- 
2.6.3

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

* [PATCH RFC 10/28] net: dsa: Keep a reference to the switch device for component matching
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (8 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 09/28] net: dsa: Add basic support for component master support Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 11/28] net: dsa: Add slave component matches based on a phandle to the slave Andrew Lunn
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

The switch devices are component slaves. Such devices have a "switch"
property in the DSA device tree which is a phandle to the switch
device. When the slaves bind they register to DSA. So the DSA can
match the switch to the correct switch instance in the device tree,
keep a reference to the device tree node during parsing of the device
tree.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/devicetree/bindings/net/dsa/dsa.txt | 2 ++
 include/net/dsa.h                                 | 3 +++
 net/dsa/dsa.c                                     | 6 +++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index 5fdbbcdf8c4b..f99e5694a61f 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -27,6 +27,8 @@ Each of these switch child nodes should have the following required properties:
 
 A switch child node has the following optional property:
 
+- switch		: A phandle to a switch device.
+
 - eeprom-length		: Set to the length of an EEPROM connected to the
 			  switch. Must be set if the switch can not detect
 			  the presence and/or size of a connected EEPROM,
diff --git a/include/net/dsa.h b/include/net/dsa.h
index f6b8001a500f..ea4cfdf1b549 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -48,6 +48,9 @@ struct dsa_chip_data {
 	 */
 	struct device_node *of_node;
 
+	/* Device tree node pointer for the switch chip device. */
+	struct device_node *of_chip;
+
 	/*
 	 * The names of the switch's ports.  Use "cpu" to
 	 * designate the switch port that the cpu is connected to,
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 2558c11f73ce..be8e181f161b 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -655,7 +655,7 @@ static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
 static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 {
 	struct device_node *np = dev->of_node;
-	struct device_node *child, *mdio, *ethernet, *port;
+	struct device_node *child, *chip, *mdio, *ethernet, *port;
 	struct mii_bus *mdio_bus, *mdio_bus_switch;
 	struct net_device *ethernet_dev;
 	struct dsa_chip_data *cd;
@@ -705,6 +705,10 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 
 		cd->of_node = child;
 
+		chip = of_parse_phandle(child, "switch", 0);
+		if (chip)
+			cd->of_chip = chip;
+
 		/* When assigning the host device, increment its refcount */
 		cd->host_dev = get_device(&mdio_bus->dev);
 
-- 
2.6.3

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

* [PATCH RFC 11/28] net: dsa: Add slave component matches based on a phandle to the slave.
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (9 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 10/28] net: dsa: Keep a reference to the switch device for component matching Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional Andrew Lunn
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Switch devices are component slaves. Such devices have a "switch"
property in the DSA device tree which is a phandle to the switch
device. Add a component match on the device node.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index be8e181f161b..8b89eece6b52 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -871,18 +871,25 @@ static int dsa_bind(struct device *dev)
 	return dsa_setup_dst(dst, dst->master_netdev, dev);
 }
 
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
 static int dsa_probe(struct platform_device *pdev)
 {
 	struct dsa_platform_data *pd = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	struct component_match *match = NULL;
+	struct device_node *chip;
 	struct net_device *dev;
 	struct dsa_switch_tree *dst;
-	int ret;
+	int i, ret;
 
 	pr_notice_once("Distributed Switch Architecture driver version %s\n",
 		       dsa_driver_version);
 
-	if (pdev->dev.of_node) {
+	if (np) {
 		pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
 		if (!pd)
 			return -ENOMEM;
@@ -926,6 +933,12 @@ static int dsa_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, dst);
 
+	for (i = 0; i < pd->nr_chips; i++) {
+		chip = pd->chip[i].of_chip;
+		if (chip)
+			component_match_add(&pdev->dev, &match, compare_of,
+					    chip);
+	}
 
 	return component_master_add_with_match(&pdev->dev, &dsa_ops, match);
 
-- 
2.6.3

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

* [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (10 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 11/28] net: dsa: Add slave component matches based on a phandle to the slave Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:42   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 13/28] net: dsa: Add register/unregister functions for switch drivers Andrew Lunn
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

When all the switches are devices and register to the DSA framework,
having a dsa,mii-bus property is not required.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/devicetree/bindings/net/dsa/dsa.txt |  3 ++-
 net/dsa/dsa.c                                     | 26 +++++++++++++----------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index f99e5694a61f..625b2e5d8ae2 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -8,11 +8,12 @@ Required properties:
 			  Second cell is used only when cascading/chaining.
 - #size-cells		: Must be 0
 - dsa,ethernet		: Should be a phandle to a valid Ethernet device node
-- dsa,mii-bus		: Should be a phandle to a valid MDIO bus device node
 
 Optional properties:
 - interrupts		: property with a value describing the switch
 			  interrupt number (not supported by the driver)
+- dsa,mii-bus		: Should be a phandle to a valid MDIO bus device node.
+			  Required when not all switches are devices.
 
 A DSA node can contain multiple switch chips which are therefore child nodes of
 the parent DSA node. The maximum number of allowed child nodes is 4
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 8b89eece6b52..eca487dcc9fe 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -656,7 +656,7 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 {
 	struct device_node *np = dev->of_node;
 	struct device_node *child, *chip, *mdio, *ethernet, *port;
-	struct mii_bus *mdio_bus, *mdio_bus_switch;
+	struct mii_bus *mdio_bus = NULL, *mdio_bus_switch;
 	struct net_device *ethernet_dev;
 	struct dsa_chip_data *cd;
 	const char *port_name;
@@ -669,12 +669,6 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 	int ret = 0;
 
 	mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
-	if (!mdio)
-		return -EINVAL;
-
-	mdio_bus = of_mdio_find_bus(mdio);
-	if (!mdio_bus)
-		return -EPROBE_DEFER;
 
 	ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
 	if (!ethernet) {
@@ -706,11 +700,20 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 		cd->of_node = child;
 
 		chip = of_parse_phandle(child, "switch", 0);
-		if (chip)
+		if (chip) {
 			cd->of_chip = chip;
+		} else {
+			if (!mdio)
+				return -EINVAL;
+
+			mdio_bus = of_mdio_find_bus(mdio);
+			if (!mdio_bus)
+				return -EPROBE_DEFER;
 
-		/* When assigning the host device, increment its refcount */
-		cd->host_dev = get_device(&mdio_bus->dev);
+			/* When assigning the host device, increment
+			 * its refcount */
+			cd->host_dev = get_device(&mdio_bus->dev);
+		}
 
 		sw_addr = of_get_property(child, "reg", NULL);
 		if (!sw_addr)
@@ -784,7 +787,8 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 
 	/* The individual chips hold their own refcount on the mdio bus,
 	 * so drop ours */
-	put_device(&mdio_bus->dev);
+	if (mdio_bus)
+		put_device(&mdio_bus->dev);
 
 	return 0;
 
-- 
2.6.3

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

* [PATCH RFC 13/28] net: dsa: Add register/unregister functions for switch drivers
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (11 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 14/28] net: dsa: Rename DSA probe function Andrew Lunn
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

A switch device driver registers with DSA as part of the component
slave bind and unregisters on component slave unbind.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/net/dsa.h |  3 +++
 net/dsa/dsa.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index ea4cfdf1b549..dbb90f2c475b 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -345,6 +345,9 @@ struct dsa_switch_driver {
 void register_switch_driver(struct dsa_switch_driver *type);
 void unregister_switch_driver(struct dsa_switch_driver *type);
 struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
+int dsa_switch_register(struct dsa_switch_tree *dst, struct dsa_switch *ds,
+			struct device_node *np, const char *name);
+void dsa_switch_unregister(struct dsa_switch *ds);
 
 static inline void *ds_to_priv(struct dsa_switch *ds)
 {
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index eca487dcc9fe..0658077f4e63 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -981,6 +981,55 @@ static const struct component_master_ops dsa_ops = {
 	.unbind = dsa_unbind,
 };
 
+static int dsa_find_chip_index(struct dsa_switch_tree *dst,
+			       struct device_node *np)
+{
+	struct dsa_platform_data *pd = dst->pd;
+	struct dsa_chip_data *cd;
+	int i;
+
+	for (i = 0; i < pd->nr_chips; i++) {
+		cd = &pd->chip[i];
+		if (cd->of_chip == np)
+			return i;
+	}
+	return -ENODEV;
+}
+
+int dsa_switch_register(struct dsa_switch_tree *dst, struct dsa_switch *ds,
+			struct device_node *np, const char *name)
+{
+	struct dsa_platform_data *pd = dst->pd;
+	int index = dsa_find_chip_index(dst, np);
+
+	if (index < 0)
+		return index;
+
+	netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", index, name);
+
+	if (dst->ds[index])
+		return -EINVAL;
+
+	ds->index = index;
+	ds->pd = &pd->chip[index];
+	ds->dst = dst;
+	dst->ds[index] = ds;
+	ds->tag_protocol = ds->drv->tag_protocol;
+	ds->master_dev = &dst->master_netdev->dev;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dsa_switch_register);
+
+void dsa_switch_unregister(struct dsa_switch *ds)
+{
+#ifdef CONFIG_PM_SLEEP
+	dsa_switch_suspend(ds);
+#endif
+	dsa_switch_destroy(ds);
+}
+EXPORT_SYMBOL_GPL(dsa_switch_unregister);
+
 static void dsa_shutdown(struct platform_device *pdev)
 {
 }
-- 
2.6.3

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

* [PATCH RFC 14/28] net: dsa: Rename DSA probe function.
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (12 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 13/28] net: dsa: Add register/unregister functions for switch drivers Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 15/28] of_mdio: Add "mii-bus" and address property parser Andrew Lunn
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Rename the function called from the DSA to perform a probe for the
switch. This makes the normal _probe() name available for a standard
Linux device driver probe function.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/bcm_sf2.c   | 4 ++--
 drivers/net/dsa/mv88e6060.c | 4 ++--
 drivers/net/dsa/mv88e6123.c | 4 ++--
 drivers/net/dsa/mv88e6131.c | 4 ++--
 drivers/net/dsa/mv88e6171.c | 4 ++--
 drivers/net/dsa/mv88e6352.c | 4 ++--
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 23326c2a01b8..a0222ebd31c6 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -135,7 +135,7 @@ static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds)
 	return BCM_SF2_STATS_SIZE;
 }
 
-static char *bcm_sf2_sw_probe(struct device *host_dev, int sw_addr)
+static char *bcm_sf2_sw_drv_probe(struct device *host_dev, int sw_addr)
 {
 	return "Broadcom Starfighter 2";
 }
@@ -1369,7 +1369,7 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
 
 static struct dsa_switch_driver bcm_sf2_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_BRCM,
-	.probe			= bcm_sf2_sw_probe,
+	.probe			= bcm_sf2_sw_drv_probe,
 	.setup			= bcm_sf2_sw_setup,
 	.set_addr		= bcm_sf2_sw_set_addr,
 	.get_phy_flags		= bcm_sf2_sw_get_phy_flags,
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index d48708dfd963..02810a50825b 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -51,7 +51,7 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 			return __ret;				\
 	})
 
-static char *mv88e6060_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6060_drv_probe(struct device *host_dev, int sw_addr)
 {
 	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
 	int ret;
@@ -241,7 +241,7 @@ mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 
 static struct dsa_switch_driver mv88e6060_switch_driver = {
 	.tag_protocol	= DSA_TAG_PROTO_TRAILER,
-	.probe		= mv88e6060_probe,
+	.probe		= mv88e6060_drv_probe,
 	.setup		= mv88e6060_setup,
 	.set_addr	= mv88e6060_set_addr,
 	.phy_read	= mv88e6060_phy_read,
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 9d39f108793b..6d6fca62e8b1 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -29,7 +29,7 @@ static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
 	{ PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
 };
 
-static char *mv88e6123_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6123_drv_probe(struct device *host_dev, int sw_addr)
 {
 	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
 				     ARRAY_SIZE(mv88e6123_table));
@@ -103,7 +103,7 @@ static int mv88e6123_setup(struct dsa_switch *ds, struct device *dev)
 
 struct dsa_switch_driver mv88e6123_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6123_probe,
+	.probe			= mv88e6123_drv_probe,
 	.setup			= mv88e6123_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
 	.phy_read		= mv88e6xxx_phy_read,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 3103b4953af4..e0aa3be7f5a9 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -25,7 +25,7 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
 	{ PORT_SWITCH_ID_6185, "Marvell 88E6185" },
 };
 
-static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6131_drv_probe(struct device *host_dev, int sw_addr)
 {
 	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
 				     ARRAY_SIZE(mv88e6131_table));
@@ -160,7 +160,7 @@ mv88e6131_phy_write(struct dsa_switch *ds,
 
 struct dsa_switch_driver mv88e6131_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_DSA,
-	.probe			= mv88e6131_probe,
+	.probe			= mv88e6131_drv_probe,
 	.setup			= mv88e6131_setup,
 	.set_addr		= mv88e6xxx_set_addr_direct,
 	.phy_read		= mv88e6131_phy_read,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 29a77366afc6..8fc4db23744e 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,7 +24,7 @@ static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
 	{ PORT_SWITCH_ID_6351, "Marvell 88E6351" },
 };
 
-static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6171_drv_probe(struct device *host_dev, int sw_addr)
 {
 	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table,
 				     ARRAY_SIZE(mv88e6171_table));
@@ -89,7 +89,7 @@ static int mv88e6171_setup(struct dsa_switch *ds, struct device *dev)
 
 struct dsa_switch_driver mv88e6171_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6171_probe,
+	.probe			= mv88e6171_drv_probe,
 	.setup			= mv88e6171_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
 	.phy_read		= mv88e6xxx_phy_read_indirect,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index eb57a379b9cc..2877ad8acefa 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -36,7 +36,7 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
 	{ PORT_SWITCH_ID_6352_A1, "Marvell 88E6352 (A1)" },
 };
 
-static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6352_drv_probe(struct device *host_dev, int sw_addr)
 {
 	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table,
 				     ARRAY_SIZE(mv88e6352_table));
@@ -302,7 +302,7 @@ static int mv88e6352_set_eeprom(struct dsa_switch *ds,
 
 struct dsa_switch_driver mv88e6352_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6352_probe,
+	.probe			= mv88e6352_drv_probe,
 	.setup			= mv88e6352_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
 	.phy_read		= mv88e6xxx_phy_read_indirect,
-- 
2.6.3

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

* [PATCH RFC 15/28] of_mdio: Add "mii-bus" and address property parser
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (13 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 14/28] net: dsa: Rename DSA probe function Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name() Andrew Lunn
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Add a helper function for parsing an mii-bus property, which should be
a phandle to an MDIO device, and an address of a device on that bus.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/of/of_mdio.c    | 38 ++++++++++++++++++++++++++++++++++++++
 include/linux/of_mdio.h | 10 ++++++++++
 2 files changed, 48 insertions(+)

diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index a87a868fed64..3b5c961b8746 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -114,6 +114,44 @@ int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
 }
 EXPORT_SYMBOL(of_mdio_parse_addr);
 
+int of_mdio_parse_bus_and_addr(struct device *dev, const struct device_node *np,
+			       struct mii_bus **mii_bus, int *addr)
+{
+	struct device_node *bus;
+	int ret;
+
+	bus = of_parse_phandle(np, "mii-bus", 0);
+	if (!bus) {
+		dev_err(dev, "%s has invalid mii-bus property",
+			np->full_name);
+		return -EINVAL;
+	}
+
+	*mii_bus = of_mdio_find_bus(bus);
+	if (!*mii_bus) {
+		ret = -EPROBE_DEFER;
+		goto out;
+	}
+
+	ret = of_property_read_u32(np, "addr", addr);
+	if (ret < 0) {
+		dev_err(dev, "%s has invalid PHY address\n", np->full_name);
+		goto out;
+	}
+
+	/* A PHY must have a reg property in the range [0-31] */
+	if (*addr >= PHY_MAX_ADDR) {
+		dev_err(dev, "%s PHY address %i is too large\n",
+			np->full_name, *addr);
+		ret = -EINVAL;
+	}
+out:
+	of_node_put(bus);
+
+	return ret;
+}
+EXPORT_SYMBOL(of_mdio_parse_bus_and_addr);
+
 /**
  * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
  * @mdio: pointer to mii_bus structure
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 8f2237eb3485..25f9440cbc49 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -25,6 +25,9 @@ struct phy_device *of_phy_attach(struct net_device *dev,
 
 extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
 extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
+extern int of_mdio_parse_bus_and_addr(struct device *dev,
+				      const struct device_node *np,
+				      struct mii_bus **mii_bus, int *addr);
 
 #else /* CONFIG_OF */
 static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
@@ -67,6 +70,13 @@ static inline int of_mdio_parse_addr(struct device *dev,
 {
 	return -ENOSYS;
 }
+
+static inline int of_mdio_parse_bus(struct device *dev,
+				    const struct device_node *np,
+				    struct mii_bus **mii_bus, int *addr)
+{
+	return -ENOSYS;
+}
 #endif /* CONFIG_OF */
 
 #if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY)
-- 
2.6.3

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

* [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name()
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (14 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 15/28] of_mdio: Add "mii-bus" and address property parser Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2016-01-21 20:54   ` Vivien Didelot
  2015-12-23 12:56 ` [PATCH RFC 17/28] dsa: mv88e6xxx: Add shared code for binding/unbinding a switch driver Andrew Lunn
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

mv88e6xxx_lookup_name() returns the model name of a switch at a given
address on an MII bus. Using mii_bus it identify the bus rather than
the host device is more logical, so change the parameter.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6123.c | 4 +++-
 drivers/net/dsa/mv88e6131.c | 4 +++-
 drivers/net/dsa/mv88e6171.c | 4 +++-
 drivers/net/dsa/mv88e6352.c | 4 +++-
 drivers/net/dsa/mv88e6xxx.c | 9 +++------
 drivers/net/dsa/mv88e6xxx.h | 2 +-
 6 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 6d6fca62e8b1..2c23762cbed8 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -31,7 +31,9 @@ static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
 
 static char *mv88e6123_drv_probe(struct device *host_dev, int sw_addr)
 {
-	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+
+	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6123_table,
 				     ARRAY_SIZE(mv88e6123_table));
 }
 
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index e0aa3be7f5a9..02d2bca095af 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -27,7 +27,9 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
 
 static char *mv88e6131_drv_probe(struct device *host_dev, int sw_addr)
 {
-	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+
+	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6131_table,
 				     ARRAY_SIZE(mv88e6131_table));
 }
 
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 8fc4db23744e..d557be12feb7 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -26,7 +26,9 @@ static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
 
 static char *mv88e6171_drv_probe(struct device *host_dev, int sw_addr)
 {
-	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table,
+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+
+	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6171_table,
 				     ARRAY_SIZE(mv88e6171_table));
 }
 
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 2877ad8acefa..959835d69af6 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -38,7 +38,9 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
 
 static char *mv88e6352_drv_probe(struct device *host_dev, int sw_addr)
 {
-	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table,
+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+
+	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6352_table,
 				     ARRAY_SIZE(mv88e6352_table));
 }
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 170b98f3acbe..23b0ff9f0154 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2606,16 +2606,12 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 }
 #endif /* CONFIG_NET_DSA_HWMON */
 
-char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
+char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 			    const struct mv88e6xxx_switch_id *table,
 			    unsigned int num)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
 	int i, ret;
 
-	if (!bus)
-		return NULL;
-
 	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
 	if (ret < 0)
 		return NULL;
@@ -2628,7 +2624,8 @@ char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
 	/* Look up only the product number */
 	for (i = 0; i < num; ++i) {
 		if (table[i].id == (ret & PORT_SWITCH_ID_PROD_NUM_MASK)) {
-			dev_warn(host_dev, "unknown revision %d, using base switch 0x%x\n",
+			dev_warn(&bus->dev,
+				 "unknown revision %d, using base switch 0x%x\n",
 				 ret & PORT_SWITCH_ID_REV_MASK,
 				 ret & PORT_SWITCH_ID_PROD_NUM_MASK);
 			return table[i].name;
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 62069b30f6e5..441aec066294 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -436,7 +436,7 @@ struct mv88e6xxx_hw_stat {
 };
 
 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
-char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
+char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 			    const struct mv88e6xxx_switch_id *table,
 			    unsigned int num);
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
-- 
2.6.3

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

* [PATCH RFC 17/28] dsa: mv88e6xxx: Add shared code for binding/unbinding a switch driver.
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (15 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name() Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches Andrew Lunn
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Switch drivers are component slaves. When they are bound to a master
component, the bind function is called and resources can be reserved.
Add the shared code.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx.c | 72 +++++++++++++++++++++++++++++++++++++++------
 drivers/net/dsa/mv88e6xxx.h |  5 ++++
 2 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 23b0ff9f0154..36921c3a1cf0 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2015 CMC Electronics, Inc.
  *	Added support for VLAN Table Unit operations
+ * Copyright (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -12,14 +13,16 @@
  */
 
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/gpio/consumer.h>
 #include <linux/if_bridge.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/gpio/consumer.h>
+#include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <net/dsa.h>
 #include <net/switchdev.h>
@@ -2183,16 +2186,18 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 
 int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
 {
-	struct mv88e6xxx_priv_state *ps;
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
-	if (!ps)
-		return -ENOMEM;
+	if (!ps) {
+		ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
+		if (!ps)
+			return -ENOMEM;
 
-	ds->priv = ps;
-	ps->ds = ds;
-	ps->bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-	ps->sw_addr = ds->pd->sw_addr;
+		ds->priv = ps;
+		ps->ds = ds;
+		ps->bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+		ps->sw_addr = ds->pd->sw_addr;
+	}
 
 	mutex_init(&ps->smi_mutex);
 
@@ -2635,6 +2640,55 @@ char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 	return NULL;
 }
 
+int mv88e6xxx_bind(struct device *dev,
+		   struct dsa_switch_tree *dst,
+		   struct dsa_switch_driver *ops,
+		   const struct mv88e6xxx_switch_id *table,
+		   unsigned int table_size)
+{
+	struct mv88e6xxx_priv_state *ps;
+	struct device_node *np = dev->of_node;
+	struct dsa_switch *ds;
+	const char *name;
+	int ret = 0;
+
+	ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*ps), GFP_KERNEL);
+	if (!ds)
+		return -ENOMEM;
+
+	ps = (struct mv88e6xxx_priv_state *)(ds + 1);
+	ds->priv = ps;
+	ps->ds = ds;
+
+	ret = of_mdio_parse_bus_and_addr(dev, np, &ps->bus, &ps->sw_addr);
+	if (ret)
+		return ret;
+
+	get_device(&ps->bus->dev);
+
+	ds->drv = ops;
+
+	name = mv88e6xxx_lookup_name(ps->bus, ps->sw_addr, table, table_size);
+	if (!name) {
+		dev_err(dev, "Failed to find switch");
+		return -ENODEV;
+	}
+
+	dev_set_drvdata(dev, ds);
+	dsa_switch_register(dst, ds, np, name);
+
+	return 0;
+}
+
+void mv88e6xxx_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct dsa_switch *ds = dev_get_drvdata(dev);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	dsa_switch_unregister(ds);
+	put_device(&ps->bus->dev);
+}
+
 static int __init mv88e6xxx_init(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 441aec066294..376b1b78c80c 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -439,6 +439,11 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
 char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 			    const struct mv88e6xxx_switch_id *table,
 			    unsigned int num);
+int mv88e6xxx_bind(struct device *dev, struct dsa_switch_tree *dst,
+		   struct dsa_switch_driver *ops,
+		   const struct mv88e6xxx_switch_id *table,
+		   unsigned int table_size);
+void mv88e6xxx_unbind(struct device *dev, struct device *master, void *data);
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
 int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev);
 int mv88e6xxx_setup_global(struct dsa_switch *ds);
-- 
2.6.3

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

* [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (16 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 17/28] dsa: mv88e6xxx: Add shared code for binding/unbinding a switch driver Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2016-01-21 21:05   ` Vivien Didelot
  2015-12-23 12:56 ` [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver Andrew Lunn
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Allow Marvell switches to be platform devices, which probe and then
register with the DSA framework, as component slaves.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 .../devicetree/bindings/net/dsa/marvell.txt        |  17 ++++
 drivers/net/dsa/mv88e6060.c                        | 103 +++++++++++++++++++--
 drivers/net/dsa/mv88e6123.c                        |  51 +++++++++-
 drivers/net/dsa/mv88e6131.c                        |  52 ++++++++++-
 drivers/net/dsa/mv88e6171.c                        |  52 ++++++++++-
 drivers/net/dsa/mv88e6352.c                        |  52 ++++++++++-
 6 files changed, 309 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/marvell.txt

diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt
new file mode 100644
index 000000000000..9e91db9ef663
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt
@@ -0,0 +1,17 @@
+Marvell DSA Switch Device Tree Bindings
+---------------------------------------
+
+Required properties:
+- compatible		: Should be one of "marvell,mv88e6123",
+			  "marvell,mv88e6131", "marvell,mv88e6171",
+			  "marvell,mv88e6352" or "marvell,mv88e6060"
+- mii-bus		: phandle to MII bus the switch is on
+- addr			: Address on the MII bus for the switch
+
+Example:
+
+	switchdev0: switchdev0 {
+		compatible = "marvell,mv88e6352";
+		mii-bus = <&mdio_mux_1>;
+		addr = <0>;
+	};
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 02810a50825b..41472dc409ce 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -1,6 +1,7 @@
 /*
  * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
  * Copyright (c) 2008-2009 Marvell Semiconductor
+ * Copywrite (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -8,12 +9,15 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/of_mdio.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
 #include <net/dsa.h>
 #include "mv88e6060.h"
 
@@ -51,14 +55,10 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 			return __ret;				\
 	})
 
-static char *mv88e6060_drv_probe(struct device *host_dev, int sw_addr)
+static char *mv88e6060_name(struct mii_bus *bus, int sw_addr)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
 	int ret;
 
-	if (bus == NULL)
-		return NULL;
-
 	ret = mdiobus_read(bus, sw_addr + REG_PORT(0), PORT_SWITCH_ID);
 	if (ret >= 0) {
 		if (ret == PORT_SWITCH_ID_6060)
@@ -73,6 +73,16 @@ static char *mv88e6060_drv_probe(struct device *host_dev, int sw_addr)
 	return NULL;
 }
 
+static char *mv88e6060_drv_probe(struct device *host_dev, int sw_addr)
+{
+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
+
+	if (!bus)
+		return NULL;
+
+	return mv88e6060_name(bus, sw_addr);
+}
+
 static int mv88e6060_switch_reset(struct dsa_switch *ds)
 {
 	int i;
@@ -248,15 +258,96 @@ static struct dsa_switch_driver mv88e6060_switch_driver = {
 	.phy_write	= mv88e6060_phy_write,
 };
 
+static int mv88e6060_bind(struct device *dev,
+			  struct device *master, void *data)
+{
+	struct dsa_switch_tree *dst = data;
+	struct mv88e6060_priv *priv;
+	struct device_node *np = dev->of_node;
+	struct dsa_switch *ds;
+	const char *name;
+	int ret = 0;
+
+	ds = devm_kzalloc(dev, sizeof(*ds) + sizeof(*priv), GFP_KERNEL);
+	if (!ds)
+		return -ENOMEM;
+
+	priv = (struct mv88e6060_priv *)(ds + 1);
+	ds->priv = priv;
+
+	ret = of_mdio_parse_bus_and_addr(dev, np, &priv->bus, &priv->sw_addr);
+	if (ret)
+		return ret;
+
+	get_device(&priv->bus->dev);
+
+	ds->drv = &mv88e6060_switch_driver;
+
+	name = mv88e6060_name(priv->bus, priv->sw_addr);
+	if (!name) {
+		dev_err(dev, "Failed to find switch");
+		return -ENODEV;
+	}
+
+	dev_set_drvdata(dev, ds);
+	dsa_switch_register(dst, ds, np, name);
+
+	return 0;
+}
+
+void mv88e6060_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct dsa_switch *ds = dev_get_drvdata(dev);
+	struct mv88e6060_priv *priv = ds_to_priv(ds);
+
+	dsa_switch_unregister(ds);
+	put_device(&priv->bus->dev);
+}
+
+static const struct component_ops mv88e6060_component_ops = {
+	.bind = mv88e6060_bind,
+	.unbind = mv88e6060_unbind,
+};
+
+static int mv88e6060_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mv88e6060_component_ops);
+
+	return 0;
+}
+
+static int mv88e6060_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &mv88e6060_component_ops);
+}
+
+static const struct of_device_id mv88e6060_of_match[] = {
+	{ .compatible = "marvell,mv88e6060" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mv88e6060_of_match);
+
+static struct platform_driver mv88e6060_driver = {
+	.probe  = mv88e6060_probe,
+	.remove = mv88e6060_remove,
+	.driver = {
+		.name = "mv88e6060",
+		.of_match_table = mv88e6060_of_match,
+	},
+};
+
 static int __init mv88e6060_init(void)
 {
 	register_switch_driver(&mv88e6060_switch_driver);
-	return 0;
+
+	return platform_driver_register(&mv88e6060_driver);
 }
 module_init(mv88e6060_init);
 
 static void __exit mv88e6060_cleanup(void)
 {
+	platform_driver_unregister(&mv88e6060_driver);
+
 	unregister_switch_driver(&mv88e6060_switch_driver);
 }
 module_exit(mv88e6060_cleanup);
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 2c23762cbed8..bb39720f3e8b 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -1,6 +1,7 @@
 /*
  * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
  * Copyright (c) 2008-2009 Marvell Semiconductor
+ * Copyright (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -8,12 +9,14 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
@@ -122,5 +125,49 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 };
 
 MODULE_ALIAS("platform:mv88e6123");
-MODULE_ALIAS("platform:mv88e6161");
-MODULE_ALIAS("platform:mv88e6165");
+
+static int mv88e6123_bind(struct device *dev,
+			  struct device *master, void *data)
+{
+	struct dsa_switch_tree *dst = data;
+
+	return mv88e6xxx_bind(dev, dst, &mv88e6123_switch_driver,
+			      mv88e6123_table,
+			      ARRAY_SIZE(mv88e6123_table));
+}
+
+static const struct component_ops mv88e6123_component_ops = {
+	.bind = mv88e6123_bind,
+	.unbind = mv88e6xxx_unbind,
+};
+
+static int mv88e6123_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mv88e6123_component_ops);
+
+	return 0;
+}
+
+static int mv88e6123_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &mv88e6123_component_ops);
+}
+
+static const struct of_device_id mv88e6123_of_match[] = {
+	{ .compatible = "marvell,mv88e6123" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mv88e6123_of_match);
+
+static struct platform_driver mv88e6123_driver = {
+	.probe  = mv88e6123_probe,
+	.remove = mv88e6123_remove,
+	.driver = {
+		.name = "mv88e6123",
+		.of_match_table = mv88e6123_of_match,
+	},
+};
+module_platform_driver(mv88e6123_driver);
+
+MODULE_DESCRIPTION("Driver for Marvell 6123 family ethernet switch chips");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 02d2bca095af..2cd8c2155d3e 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -1,6 +1,7 @@
 /*
  * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support
  * Copyright (c) 2008-2009 Marvell Semiconductor
+ * Copyright (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -8,11 +9,13 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
@@ -173,7 +176,50 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.adjust_link		= mv88e6xxx_adjust_link,
 };
 
-MODULE_ALIAS("platform:mv88e6085");
-MODULE_ALIAS("platform:mv88e6095");
-MODULE_ALIAS("platform:mv88e6095f");
 MODULE_ALIAS("platform:mv88e6131");
+
+static int mv88e6131_bind(struct device *dev,
+			  struct device *master, void *data)
+{
+	struct dsa_switch_tree *dst = data;
+
+	return mv88e6xxx_bind(dev, dst, &mv88e6131_switch_driver,
+			      mv88e6131_table,
+			      ARRAY_SIZE(mv88e6131_table));
+}
+
+static const struct component_ops mv88e6131_component_ops = {
+	.bind = mv88e6131_bind,
+	.unbind = mv88e6xxx_unbind,
+};
+
+static int mv88e6131_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mv88e6131_component_ops);
+
+	return 0;
+}
+
+static int mv88e6131_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &mv88e6131_component_ops);
+}
+
+static const struct of_device_id mv88e6131_of_match[] = {
+	{ .compatible = "marvell,mv88e6131" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mv88e6131_of_match);
+
+static struct platform_driver mv88e6131_driver = {
+	.probe	= mv88e6131_probe,
+	.remove = mv88e6131_remove,
+	.driver = {
+		.name = "mv88e6131",
+		.of_match_table = mv88e6131_of_match,
+	},
+};
+module_platform_driver(mv88e6131_driver);
+
+MODULE_DESCRIPTION("Driver for Marvell 6131 family ethernet switch chips");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index d557be12feb7..780098d0ad19 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -1,6 +1,7 @@
 /* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support
  * Copyright (c) 2008-2009 Marvell Semiconductor
  * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
+ * Copyright (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -8,12 +9,14 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
@@ -120,6 +123,49 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 };
 
 MODULE_ALIAS("platform:mv88e6171");
-MODULE_ALIAS("platform:mv88e6175");
-MODULE_ALIAS("platform:mv88e6350");
-MODULE_ALIAS("platform:mv88e6351");
+
+static int mv88e6171_bind(struct device *dev,
+			  struct device *master, void *data)
+{
+	struct dsa_switch_tree *dst = data;
+
+	return mv88e6xxx_bind(dev, dst, &mv88e6171_switch_driver,
+			      mv88e6171_table,
+			      ARRAY_SIZE(mv88e6171_table));
+}
+
+static const struct component_ops mv88e6171_component_ops = {
+	.bind = mv88e6171_bind,
+	.unbind = mv88e6xxx_unbind,
+};
+
+static int mv88e6171_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mv88e6171_component_ops);
+
+	return 0;
+}
+
+static int mv88e6171_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &mv88e6171_component_ops);
+}
+
+static const struct of_device_id mv88e6171_of_match[] = {
+	{ .compatible = "marvell,mv88e6171" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mv88e6171_of_match);
+
+static struct platform_driver mv88e6171_driver = {
+	.probe  = mv88e6171_probe,
+	.remove = mv88e6171_remove,
+	.driver = {
+		.name = "mv88e6171",
+		.of_match_table = mv88e6171_of_match,
+	},
+};
+module_platform_driver(mv88e6171_driver);
+
+MODULE_DESCRIPTION("Driver for Marvell 6171 family ethernet switch chips");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 959835d69af6..7e28150d44e0 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -2,6 +2,7 @@
  * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support
  *
  * Copyright (c) 2014 Guenter Roeck
+ * Copyright (c) 2015 Andrew Lunn <andrew@lunn.ch>
  *
  * Derived from mv88e6123_61_65.c
  * Copyright (c) 2008-2009 Marvell Semiconductor
@@ -12,6 +13,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
@@ -339,8 +341,50 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.port_fdb_dump		= mv88e6xxx_port_fdb_dump,
 };
 
-MODULE_ALIAS("platform:mv88e6172");
-MODULE_ALIAS("platform:mv88e6176");
-MODULE_ALIAS("platform:mv88e6320");
-MODULE_ALIAS("platform:mv88e6321");
 MODULE_ALIAS("platform:mv88e6352");
+
+static int mv88e6352_bind(struct device *dev,
+			  struct device *master, void *data)
+{
+	struct dsa_switch_tree *dst = data;
+
+	return mv88e6xxx_bind(dev, dst, &mv88e6352_switch_driver,
+			      mv88e6352_table,
+			      ARRAY_SIZE(mv88e6352_table));
+}
+
+static const struct component_ops mv88e6352_component_ops = {
+	.bind = mv88e6352_bind,
+	.unbind = mv88e6xxx_unbind,
+};
+
+static int mv88e6352_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mv88e6352_component_ops);
+
+	return 0;
+}
+
+static int mv88e6352_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &mv88e6352_component_ops);
+}
+
+static const struct of_device_id mv88e6352_of_match[] = {
+	{ .compatible = "marvell,mv88e6352" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mv88e6352_of_match);
+
+static struct platform_driver mv88e6352_driver = {
+	.probe  = mv88e6352_probe,
+	.remove = mv88e6352_remove,
+	.driver = {
+		.name = "mv88e6352",
+		.of_match_table = mv88e6352_of_match,
+	},
+};
+module_platform_driver(mv88e6352_driver);
+
+MODULE_DESCRIPTION("Driver for Marvell 6352 family ethernet switch chips");
+MODULE_LICENSE("GPL");
-- 
2.6.3

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

* [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (17 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:32   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 20/28] vf610: Zii: Convert rev b to switches as individual devices Andrew Lunn
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

From: Florian Fainelli <f.fainelli@gmail.com>

The Broadcom Starfighter 2 switch driver should be a proper platform
driver, now that the DSA code has been updated to allow that, register
a switch device, feed it with the proper configuration data coming
from Device Tree and register our switch device with DSA.

The bulk of the changes consist in moving what bcm_sf2_sw_setup() did
into the component slave bind function.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 .../devicetree/bindings/net/dsa/broadcom.txt       |  48 ++++
 drivers/net/dsa/bcm_sf2.c                          | 248 ++++++++++++---------
 2 files changed, 192 insertions(+), 104 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/broadcom.txt

diff --git a/Documentation/devicetree/bindings/net/dsa/broadcom.txt b/Documentation/devicetree/bindings/net/dsa/broadcom.txt
new file mode 100644
index 000000000000..bd92be0ef2c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/broadcom.txt
@@ -0,0 +1,48 @@
+* Broadcom Starfighter 2 integrated switch device
+
+Required properties:
+
+- compatible: should be "brcm,brcm-sf2"
+- reg: addresses and length of the register sets for the device, must be 6
+  pairs of register addresses and lengths
+- interrupts: interrupts for the devices, must be two interrupts
+
+Optional properties:
+
+- reg-names: litteral names for the device base register addresses,
+  when present must be: "core", "reg", "intrl2_0", "intrl2_1", "fcb",
+  "acb"
+
+- interrupt-names: litternal names for the device interrupt lines,
+  when present must be: "switch_0" and "switch_1"
+
+- brcm,num-gphy: specify the maximum number of integrated gigabit PHYs
+  in the switch
+
+- brcm,num-rgmii-ports: specify the maximum number of RGMII interfaces
+  supported by the switch
+
+- brcm,fcb-pause-override: boolean property, if present indicates that
+  the switch supports Failover Control Block pause override capability
+
+- brcm,acb-packets-inflight: boolean property, if present indicates
+  that the switch Admission Control Block supports reporting the
+  number of packets in-flight in a switch queue
+
+Example:
+
+	switchdev0: switchdev0 {
+		compatible = "brcm,brcm-sf2";
+		reg = <0x0 0x40000
+			0x40000 0x110
+			0x40340 0x30
+			0x40380 0x30
+			0x40400 0x34
+			0x40600 0x208>;
+		interrupts = <0 0x18 0
+				0 0x19 0>;
+		brcm,num-gphy = <1>;
+		brcm,num-rgmii-ports = <2>;
+		brcm,fcb-pause-override;
+		brcm,acb-packets-inflight;
+	};
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index a0222ebd31c6..4f95e03b8c64 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -9,6 +9,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/component.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
@@ -928,81 +929,8 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
 
 static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
 {
-	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
-	struct bcm_sf2_priv *priv;
-	struct device_node *dn;
-	void __iomem **base;
+	struct bcm_sf2_priv *priv = ds_to_priv(ds);
 	unsigned int port;
-	unsigned int i;
-	u32 reg, rev;
-	int ret;
-
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	spin_lock_init(&priv->indir_lock);
-	mutex_init(&priv->stats_mutex);
-
-	/* All the interesting properties are at the parent device_node
-	 * level
-	 */
-	dn = ds->pd->of_node->parent;
-	bcm_sf2_identify_ports(priv, ds->pd->of_node);
-
-	priv->irq0 = irq_of_parse_and_map(dn, 0);
-	priv->irq1 = irq_of_parse_and_map(dn, 1);
-
-	base = &priv->core;
-	for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
-		*base = of_iomap(dn, i);
-		if (*base == NULL) {
-			pr_err("unable to find register: %s\n", reg_names[i]);
-			ret = -ENOMEM;
-			goto out_unmap;
-		}
-		base++;
-	}
-
-	ret = bcm_sf2_sw_rst(priv);
-	if (ret) {
-		pr_err("unable to software reset switch: %d\n", ret);
-		goto out_unmap;
-	}
-
-	/* Disable all interrupts and request them */
-	bcm_sf2_intr_disable(priv);
-
-	ret = request_irq(priv->irq0, bcm_sf2_switch_0_isr, 0,
-			  "switch_0", priv);
-	if (ret < 0) {
-		pr_err("failed to request switch_0 IRQ\n");
-		goto out_unmap;
-	}
-
-	ret = request_irq(priv->irq1, bcm_sf2_switch_1_isr, 0,
-			  "switch_1", priv);
-	if (ret < 0) {
-		pr_err("failed to request switch_1 IRQ\n");
-		goto out_free_irq0;
-	}
-
-	/* Reset the MIB counters */
-	reg = core_readl(priv, CORE_GMNCFGCFG);
-	reg |= RST_MIB_CNT;
-	core_writel(priv, reg, CORE_GMNCFGCFG);
-	reg &= ~RST_MIB_CNT;
-	core_writel(priv, reg, CORE_GMNCFGCFG);
-
-	/* Get the maximum number of ports for this switch */
-	priv->hw_params.num_ports = core_readl(priv, CORE_IMP0_PRT_ID) + 1;
-	if (priv->hw_params.num_ports > DSA_MAX_PORTS)
-		priv->hw_params.num_ports = DSA_MAX_PORTS;
-
-	/* Assume a single GPHY setup if we can't read that property */
-	if (of_property_read_u32(dn, "brcm,num-gphy",
-				 &priv->hw_params.num_gphy))
-		priv->hw_params.num_gphy = 1;
 
 	/* Enable all valid ports and disable those unused */
 	for (port = 0; port < priv->hw_params.num_ports; port++) {
@@ -1031,31 +959,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
 	else
 		ds->phys_mii_mask = 0;
 
-	rev = reg_readl(priv, REG_SWITCH_REVISION);
-	priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) &
-					SWITCH_TOP_REV_MASK;
-	priv->hw_params.core_rev = (rev & SF2_REV_MASK);
-
-	rev = reg_readl(priv, REG_PHY_REVISION);
-	priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
-
-	pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n",
-		priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
-		priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
-		priv->core, priv->irq0, priv->irq1);
-
 	return 0;
-
-out_free_irq0:
-	free_irq(priv->irq0, priv);
-out_unmap:
-	base = &priv->core;
-	for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
-		if (*base)
-			iounmap(*base);
-		base++;
-	}
-	return ret;
 }
 
 static int bcm_sf2_sw_set_addr(struct dsa_switch *ds, u8 *addr)
@@ -1397,19 +1301,155 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = {
 	.port_fdb_dump		= bcm_sf2_sw_fdb_dump,
 };
 
-static int __init bcm_sf2_init(void)
+static int bcm_sf2_sw_bind(struct device *dev,
+			   struct device *master, void *data)
 {
-	register_switch_driver(&bcm_sf2_switch_driver);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dsa_switch_tree *dst = data;
+	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
+	struct resource *res;
+	struct dsa_switch *ds;
+	struct bcm_sf2_priv *priv;
+	struct device_node *dn = pdev->dev.of_node;
+	void __iomem **base;
+	unsigned int i;
+	u32 reg, rev;
+	int ret;
+
+	ds = devm_kzalloc(&pdev->dev, sizeof(*ds) + sizeof(*priv), GFP_KERNEL);
+	if (!ds)
+		return -ENOMEM;
+
+	priv = (struct bcm_sf2_priv *)(ds + 1);
+	ds->priv = priv;
+	ds->drv = &bcm_sf2_switch_driver;
+
+	spin_lock_init(&priv->indir_lock);
+	mutex_init(&priv->stats_mutex);
+
+	/* The port information of the switch is in the immediate child
+	 * sub-node
+	 */
+	bcm_sf2_identify_ports(priv, dn->child);
+
+	priv->irq0 = platform_get_irq(pdev, 0);
+	priv->irq1 = platform_get_irq(pdev, 1);
+
+	base = &priv->core;
+	for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		*base = devm_ioremap_resource(&pdev->dev, res);
+		if (!*base) {
+			dev_err(&pdev->dev,
+				"unable to find register: %s\n", reg_names[i]);
+			return -ENODEV;
+		}
+		base++;
+	}
+
+	ret = bcm_sf2_sw_rst(priv);
+	if (ret) {
+		pr_err("unable to software reset switch: %d\n", ret);
+		return ret;
+	}
+
+	/* Disable all interrupts and request them */
+	bcm_sf2_intr_disable(priv);
+
+	ret = devm_request_irq(&pdev->dev, priv->irq0, bcm_sf2_switch_0_isr, 0,
+			       "switch_0", priv);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request switch_0 IRQ\n");
+		return ret;
+	}
+
+	ret = devm_request_irq(&pdev->dev, priv->irq1, bcm_sf2_switch_1_isr, 0,
+			       "switch_1", priv);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request switch_1 IRQ\n");
+		return ret;
+	}
+
+	/* Reset the MIB counters */
+	reg = core_readl(priv, CORE_GMNCFGCFG);
+	reg |= RST_MIB_CNT;
+	core_writel(priv, reg, CORE_GMNCFGCFG);
+	reg &= ~RST_MIB_CNT;
+	core_writel(priv, reg, CORE_GMNCFGCFG);
+
+	/* Get the maximum number of ports for this switch */
+	priv->hw_params.num_ports = core_readl(priv, CORE_IMP0_PRT_ID) + 1;
+	if (priv->hw_params.num_ports > DSA_MAX_PORTS)
+		priv->hw_params.num_ports = DSA_MAX_PORTS;
+
+	/* Assume a single GPHY setup if we can't read that property */
+	if (of_property_read_u32(dn, "brcm,num-gphy",
+				 &priv->hw_params.num_gphy))
+		priv->hw_params.num_gphy = 1;
+
+	rev = reg_readl(priv, REG_SWITCH_REVISION);
+	priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) &
+					SWITCH_TOP_REV_MASK;
+	priv->hw_params.core_rev = (rev & SF2_REV_MASK);
+
+	rev = reg_readl(priv, REG_PHY_REVISION);
+	priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
+
+	dev_info(&pdev->dev,
+		 "Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n",
+		 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
+		 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
+		 priv->core, priv->irq0, priv->irq1);
+
+	platform_set_drvdata(pdev, ds);
+
+	return dsa_switch_register(dst, ds, dn, "Starfighter 2");
+}
+
+static void bcm_sf2_sw_unbind(struct device *dev,
+			      struct device *master, void *data)
+{
+	struct dsa_switch *ds = dev_get_drvdata(dev);
+	struct bcm_sf2_priv *priv = ds_to_priv(ds);
+
+	/* Disable all ports and interrupts */
+	priv->wol_ports_mask = 0;
+	bcm_sf2_sw_suspend(ds);
+	dsa_switch_unregister(ds);
+}
+
+static const struct component_ops bcm_sf2_component_ops = {
+	.bind = bcm_sf2_sw_bind,
+	.unbind = bcm_sf2_sw_unbind,
+};
+
+static int bcm_sf2_sw_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &bcm_sf2_component_ops);
 
 	return 0;
 }
-module_init(bcm_sf2_init);
 
-static void __exit bcm_sf2_exit(void)
+static int bcm_sf2_sw_probe(struct platform_device *pdev)
 {
-	unregister_switch_driver(&bcm_sf2_switch_driver);
+	return component_add(&pdev->dev, &bcm_sf2_component_ops);
 }
-module_exit(bcm_sf2_exit);
+
+static const struct of_device_id bcm_sf2_of_match[] = {
+	{ .compatible = "brcm,brcm-sf2" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, bcm_sf2_of_match);
+
+static struct platform_driver bcm_sf2_driver = {
+	.probe	= bcm_sf2_sw_probe,
+	.remove	= bcm_sf2_sw_remove,
+	.driver = {
+		.name = "brcm-sf2",
+		.of_match_table = bcm_sf2_of_match,
+	},
+};
+module_platform_driver(bcm_sf2_driver);
 
 MODULE_AUTHOR("Broadcom Corporation");
 MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip");
-- 
2.6.3

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

* [PATCH RFC 20/28] vf610: Zii: Convert rev b to switches as individual devices
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (18 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases Andrew Lunn
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

DSA now expects switches to be true devices with a phandle pointing to
them. Adapt the DT file to this new scheme.
---
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 34 ++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 6e657a9312ce..87dc17adb894 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -77,13 +77,13 @@
 		#size-cells = <0>;
 
 		dsa,ethernet = <&fec1>;
-		dsa,mii-bus = <&mdio_mux_1>;
 
 		/* 6352 - Primary - 7 ports */
 		switch0: switch@2 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x00 0>;
+			reg = <0 0>;
+			switch = <&switchdev0>;
 			eeprom-length = <512>;
 
 			port@0 {
@@ -121,16 +121,15 @@
 					full-duplex;
 				};
 			};
-
 		};
 
 		/* 6352 - Secondary - 7 ports */
 		switch1: switch@0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x00 1>;
+			switch = <&switchdev1>;
+			reg = <0 1>;
 			eeprom-length = <512>;
-			mii-bus = <&mdio_mux_2>;
 
 			port@0 {
 				reg = <0>;
@@ -174,8 +173,8 @@
 		switch2: switch@6 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x00 2>;
-			mii-bus = <&mdio_mux_4>;
+			switch = <&switchdev2>;
+			reg = <0 2>;
 
 			port@0 {
 				reg = <0>;
@@ -226,6 +225,27 @@
 			};
 		};
 	};
+
+	/* Primary switch */
+	switchdev0: switchdev0 {
+		compatible = "marvell,mv88e6352";
+		mii-bus = <&mdio_mux_1>;
+		addr = <0>;
+	};
+
+	/* Secondary switch */
+	switchdev1: switchdev1 {
+		compatible = "marvell,mv88e6352";
+		mii-bus = <&mdio_mux_2>;
+		addr = <0>;
+	};
+
+	/* 6185 10-port switch */
+	switchdev2: switchdev2 {
+		compatible = "marvell,mv88e6131";
+		mii-bus = <&mdio_mux_4>;
+		addr = <0>;
+	};
 };
 
 &iomuxc {
-- 
2.6.3

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

* [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (19 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 20/28] vf610: Zii: Convert rev b to switches as individual devices Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:42   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 22/28] net: dsa: Setup the switches after all have been probed Andrew Lunn
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Due to the complexity it can be hard to know why DSA fails to probe.
Add some debug prints for the common error cases.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 0658077f4e63..2c1f50561343 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -672,6 +672,7 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 
 	ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
 	if (!ethernet) {
+		dev_dbg(dev, "Missing mandatory dsa,ethernet property\n");
 		ret = -EINVAL;
 		goto out_put_mdio;
 	}
@@ -703,8 +704,10 @@ static int dsa_of_probe(struct device *dev, struct dsa_platform_data *pd)
 		if (chip) {
 			cd->of_chip = chip;
 		} else {
-			if (!mdio)
+			if (!mdio) {
+				dev_dbg(dev, "Missing required dsa,mii-bus property\n");
 				return -EINVAL;
+			}
 
 			mdio_bus = of_mdio_find_bus(mdio);
 			if (!mdio_bus)
@@ -1002,13 +1005,17 @@ int dsa_switch_register(struct dsa_switch_tree *dst, struct dsa_switch *ds,
 	struct dsa_platform_data *pd = dst->pd;
 	int index = dsa_find_chip_index(dst, np);
 
-	if (index < 0)
+	if (index < 0) {
+		netdev_dbg(dst->master_netdev, "Registration for unknown switch\n");
 		return index;
+	}
 
 	netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", index, name);
 
-	if (dst->ds[index])
+	if (dst->ds[index]) {
+		netdev_dbg(dst->master_netdev, "Device already registered\n");
 		return -EINVAL;
+	}
 
 	ds->index = index;
 	ds->pd = &pd->chip[index];
-- 
2.6.3

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

* [PATCH RFC 22/28] net: dsa: Setup the switches after all have been probed
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (20 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 23/28] net: dsa: Only setup platform switches, not device switches Andrew Lunn
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Some switches register themselves with DSA, which others are probed by
DSA itself. Move the setup call to after all switches have been
successfully probed.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 2c1f50561343..fbb8fc852a3b 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -382,7 +382,6 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 	struct dsa_chip_data *pd = dst->pd->chip + index;
 	struct dsa_switch_driver *drv;
 	struct dsa_switch *ds;
-	int ret;
 	char *name;
 
 	/*
@@ -412,10 +411,6 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 	ds->tag_protocol = drv->tag_protocol;
 	ds->master_dev = host_dev;
 
-	ret = dsa_switch_setup_one(ds, parent);
-	if (ret)
-		return ERR_PTR(ret);
-
 	return ds;
 }
 
@@ -827,22 +822,28 @@ static inline void dsa_of_remove(struct device *dev,
 static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 			 struct device *parent)
 {
-	int i;
+	int i, ret;
 	unsigned configured = 0;
+	struct dsa_switch *ds;
 	struct dsa_platform_data *pd = dst->pd;
 
 	dst->cpu_switch = -1;
 	dst->cpu_port = -1;
 
 	for (i = 0; i < pd->nr_chips; i++) {
-		struct dsa_switch *ds;
-
 		ds = dsa_switch_setup(dst, i, parent, pd->chip[i].host_dev);
 		if (IS_ERR(ds)) {
 			netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n",
 				   i, PTR_ERR(ds));
 			continue;
 		}
+	}
+
+	for (i = 0; i < pd->nr_chips; i++) {
+		ds = dst->ds[i];
+		ret = dsa_switch_setup_one(ds, parent);
+		if (ret)
+			return ret;
 
 		dst->ds[i] = ds;
 
-- 
2.6.3

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

* [PATCH RFC 23/28] net: dsa: Only setup platform switches, not device switches
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (21 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 22/28] net: dsa: Setup the switches after all have been probed Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 12:56 ` [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing Andrew Lunn
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Switches which are linux devices will register themselves with DSA.
Such switches already have a dsa_switch in the dsa_switch_tree, and
don't need to be probed using the old mechanism.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index fbb8fc852a3b..5e037772bb32 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -823,7 +823,6 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 			 struct device *parent)
 {
 	int i, ret;
-	unsigned configured = 0;
 	struct dsa_switch *ds;
 	struct dsa_platform_data *pd = dst->pd;
 
@@ -831,11 +830,16 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 	dst->cpu_port = -1;
 
 	for (i = 0; i < pd->nr_chips; i++) {
-		ds = dsa_switch_setup(dst, i, parent, pd->chip[i].host_dev);
-		if (IS_ERR(ds)) {
-			netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n",
-				   i, PTR_ERR(ds));
-			continue;
+		if (!dst->ds[i]) {
+			ds = dsa_switch_setup(dst, i, parent,
+					      pd->chip[i].host_dev);
+			if (IS_ERR(ds)) {
+				netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n",
+					   i, PTR_ERR(ds));
+				return PTR_ERR(ds);
+			}
+
+			dst->ds[i] = ds;
 		}
 	}
 
@@ -844,19 +848,9 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 		ret = dsa_switch_setup_one(ds, parent);
 		if (ret)
 			return ret;
-
-		dst->ds[i] = ds;
-
-		++configured;
 	}
 
 	/*
-	 * If no switch was found, exit cleanly
-	 */
-	if (!configured)
-		return -EPROBE_DEFER;
-
-	/*
 	 * If we use a tagging format that doesn't have an ethertype
 	 * field, make sure that all packets from this point on get
 	 * sent to the tag format's receive function.
-- 
2.6.3

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

* [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (22 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 23/28] net: dsa: Only setup platform switches, not device switches Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:46   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work Andrew Lunn
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Switches are either listed in device tree of platform_data. They
should exist. If the probe fails, defer the probe, which is the likely
cause of failure, not broken device tree or platform data.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 5e037772bb32..c5f55b672675 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -391,7 +391,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 	if (drv == NULL) {
 		netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n",
 			   index);
-		return ERR_PTR(-EINVAL);
+		return ERR_PTR(-EPROBE_DEFER);
 	}
 	netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n",
 		    index, name);
-- 
2.6.3

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

* [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work.
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (23 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:48   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules Andrew Lunn
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

With the introduction of switches as linux devices and the use of the
component framework, probing has become more complex. Add some
documentation.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/networking/dsa/dsa.txt | 48 ++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt
index aa9c1f9313cd..376afa135a81 100644
--- a/Documentation/networking/dsa/dsa.txt
+++ b/Documentation/networking/dsa/dsa.txt
@@ -398,6 +398,54 @@ Switch configuration
   on the management interface and "hardcode"/"force" this MAC address for the
   CPU/management interface as an optimization
 
+Call flow
+---------
+
+With the ability for switch devices to be true linux devices, the call
+flow is somewhat complex. The component framework is used to link the
+dsa framework as the master, with switch devices, as slaves.
+
+A switch device should add itself as a component in its probe
+function.
+
+The DSA framework can either be configured using a platform_data
+structure or from the device tree. If device tree is being used, the
+dsa framework probe function will allocate a platform_data structure,
+and populate it using the device tree, via the dsa_of_probe()
+function.  Within the DSA device tree, switch devices are represented
+by a phandle to the switch device. These phandles are saved into the
+platform data so that when switch slaves register themselves, they can
+be correctly positioned in the DSA cluster.
+
+The DSA probe function then creates a dsa_switch_tree structure which
+is the overarching structure representing a switch cluster. The probe
+function then looks in the platform data for the phandles to slave
+devices, and adds a component match based on the phandle. The
+component master is then created. This causes the component framework
+to link slaves to the master.
+
+If all the slave switch can be found, the masters bind function is
+called, dsa_bind(). This in tern causes the switch slaves bind
+function to be called.
+
+The switches bind function allocated memory for its own private use,
+and for a dsa_switch structure, which represents one switch in a DSA
+cluster. The switch then registers with the DSA framework using
+dsa_switch_register().
+
+dsa_switch_register() looks in the platform data and finds the
+position within the cluster for the switch which is registering. The
+switches dsa_switch structure is then attached to the dsa_switch_tree
+structure in the correct place.
+
+Once all slave switches have registered, dsa_setup_dst() is used to
+complete the construction of the dsa_switch_tree structure. This
+starts by setting up switches which are not slave devices. The MDIO
+address of the switch is passed to each switch driver to see if it can
+drive the switch. If it can, a dsa_switch structure is allocated to
+represent the switch and linked into the dsa_switch_tree at the
+correct location.
+
 PHY devices and link management
 -------------------------------
 
-- 
2.6.3

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

* [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (24 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-25 21:47   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect Andrew Lunn
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

Turn mv88e6xxx into a library module, by exporting its symbols.  Have
each driver register their own driver functions with the DSA core in
there init function.

This results in each driver being a loadable module.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/Makefile    | 19 +++--------
 drivers/net/dsa/mv88e6123.c | 16 ++++++++-
 drivers/net/dsa/mv88e6131.c | 17 +++++++++-
 drivers/net/dsa/mv88e6171.c | 17 +++++++++-
 drivers/net/dsa/mv88e6352.c | 17 +++++++++-
 drivers/net/dsa/mv88e6xxx.c | 81 +++++++++++++++++++++++++--------------------
 6 files changed, 114 insertions(+), 53 deletions(-)

diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index a6e09939be65..7fa35fae4531 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,16 +1,7 @@
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
-obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
-mv88e6xxx_drv-y += mv88e6xxx.o
-ifdef CONFIG_NET_DSA_MV88E6123
-mv88e6xxx_drv-y += mv88e6123.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6131
-mv88e6xxx_drv-y += mv88e6131.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6352
-mv88e6xxx_drv-y += mv88e6352.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6171
-mv88e6xxx_drv-y += mv88e6171.o
-endif
+obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
+obj-$(CONFIGNET_DSA_MV88E6131)  += mv88e6123.o
+obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
+obj-$(CONFIG_NET_DSA_MV88E6352) += mv88e6352.o
+obj-$(CONFIG_NET_DSA_MV88E6171) += mv88e6171.o
 obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index bb39720f3e8b..9680e59fd2ae 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -167,7 +167,21 @@ static struct platform_driver mv88e6123_driver = {
 		.of_match_table = mv88e6123_of_match,
 	},
 };
-module_platform_driver(mv88e6123_driver);
 
+static int __init mv88e6123_init(void)
+{
+	register_switch_driver(&mv88e6123_switch_driver);
+
+	return platform_driver_register(&mv88e6123_driver);
+}
+
+static void __exit mv88e6123_exit(void)
+{
+	platform_driver_unregister(&mv88e6123_driver);
+	unregister_switch_driver(&mv88e6123_switch_driver);
+}
+
+module_init(mv88e6123_init);
+module_exit(mv88e6123_exit);
 MODULE_DESCRIPTION("Driver for Marvell 6123 family ethernet switch chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 2cd8c2155d3e..23fa2818b262 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -219,7 +219,22 @@ static struct platform_driver mv88e6131_driver = {
 		.of_match_table = mv88e6131_of_match,
 	},
 };
-module_platform_driver(mv88e6131_driver);
+
+static int __init mv88e6131_init(void)
+{
+	register_switch_driver(&mv88e6131_switch_driver);
+
+	return platform_driver_register(&mv88e6131_driver);
+}
+
+static void __exit mv88e6131_exit(void)
+{
+	platform_driver_unregister(&mv88e6131_driver);
+	unregister_switch_driver(&mv88e6131_switch_driver);
+}
+
+module_init(mv88e6131_init);
+module_exit(mv88e6131_exit);
 
 MODULE_DESCRIPTION("Driver for Marvell 6131 family ethernet switch chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 780098d0ad19..c040664c1241 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -165,7 +165,22 @@ static struct platform_driver mv88e6171_driver = {
 		.of_match_table = mv88e6171_of_match,
 	},
 };
-module_platform_driver(mv88e6171_driver);
+
+static int __init mv88e6171_init(void)
+{
+	register_switch_driver(&mv88e6171_switch_driver);
+
+	return platform_driver_register(&mv88e6171_driver);
+}
+
+static void __exit mv88e6171_exit(void)
+{
+	platform_driver_unregister(&mv88e6171_driver);
+	unregister_switch_driver(&mv88e6171_switch_driver);
+}
+
+module_init(mv88e6171_init);
+module_exit(mv88e6171_exit);
 
 MODULE_DESCRIPTION("Driver for Marvell 6171 family ethernet switch chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 7e28150d44e0..4248055909b0 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -384,7 +384,22 @@ static struct platform_driver mv88e6352_driver = {
 		.of_match_table = mv88e6352_of_match,
 	},
 };
-module_platform_driver(mv88e6352_driver);
+
+static int __init mv88e6352_init(void)
+{
+	register_switch_driver(&mv88e6352_switch_driver);
+
+	return platform_driver_register(&mv88e6352_driver);
+}
+
+static void __exit mv88e6352_exit(void)
+{
+	platform_driver_unregister(&mv88e6352_driver);
+	unregister_switch_driver(&mv88e6352_switch_driver);
+}
+
+module_init(mv88e6352_init);
+module_exit(mv88e6352_exit);
 
 MODULE_DESCRIPTION("Driver for Marvell 6352 family ethernet switch chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 36921c3a1cf0..1dc0c4769036 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -123,6 +123,7 @@ int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_reg_read);
 
 static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 				 int reg, u16 val)
@@ -180,6 +181,7 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_reg_write);
 
 int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
 {
@@ -189,6 +191,7 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_set_addr_direct);
 
 int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
 {
@@ -214,6 +217,7 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_set_addr_indirect);
 
 static int _mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
 {
@@ -339,6 +343,7 @@ void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
 	ps->ppu_timer.data = (unsigned long)ps;
 	ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_ppu_state_init);
 
 int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
 {
@@ -352,6 +357,7 @@ int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_read_ppu);
 
 int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
 			    int regnum, u16 val)
@@ -366,6 +372,7 @@ int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_write_ppu);
 #endif
 
 static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
@@ -546,6 +553,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
 out:
 	mutex_unlock(&ps->smi_mutex);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_adjust_link);
 
 static int _mv88e6xxx_stats_wait(struct dsa_switch *ds)
 {
@@ -749,6 +757,7 @@ mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
 		_mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
 				       mv88e6xxx_hw_stats, port, data);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_strings);
 
 int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
 {
@@ -756,6 +765,7 @@ int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
 		return ARRAY_SIZE(mv88e6xxx_hw_stats);
 	return ARRAY_SIZE(mv88e6xxx_hw_stats) - 3;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_sset_count);
 
 void
 mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
@@ -770,11 +780,13 @@ mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
 			ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
 			mv88e6xxx_hw_stats, port, data);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_ethtool_stats);
 
 int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
 {
 	return 32 * sizeof(u16);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_regs_len);
 
 void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
 			struct ethtool_regs *regs, void *_p)
@@ -794,6 +806,7 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
 			p[i] = ret;
 	}
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_regs);
 
 static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset,
 			   u16 mask)
@@ -837,12 +850,14 @@ int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
 	return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
 			      GLOBAL2_EEPROM_OP_LOAD);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_eeprom_load_wait);
 
 int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
 {
 	return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
 			      GLOBAL2_EEPROM_OP_BUSY);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_eeprom_busy_wait);
 
 static int _mv88e6xxx_atu_wait(struct dsa_switch *ds)
 {
@@ -909,6 +924,7 @@ out:
 	mutex_unlock(&ps->smi_mutex);
 	return reg;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_eee);
 
 int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 		      struct phy_device *phydev, struct ethtool_eee *e)
@@ -935,6 +951,7 @@ out:
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_set_eee);
 
 static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 cmd)
 {
@@ -1122,6 +1139,7 @@ int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_stp_update);
 
 static int _mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *pvid)
 {
@@ -1148,6 +1166,7 @@ int mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *pvid)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_pvid_get);
 
 static int _mv88e6xxx_port_pvid_set(struct dsa_switch *ds, int port, u16 pvid)
 {
@@ -1469,6 +1488,7 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
 	 */
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_vlan_prepare);
 
 static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
 				    bool untagged)
@@ -1523,6 +1543,7 @@ unlock:
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_vlan_add);
 
 static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
 {
@@ -1593,6 +1614,7 @@ unlock:
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_vlan_del);
 
 int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
 			   unsigned long *ports, unsigned long *untagged)
@@ -1639,6 +1661,7 @@ unlock:
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_vlan_getnext);
 
 static int _mv88e6xxx_atu_mac_write(struct dsa_switch *ds,
 				    const unsigned char *addr)
@@ -1726,6 +1749,7 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
 	 */
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_fdb_prepare);
 
 int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
 			   const struct switchdev_obj_port_fdb *fdb,
@@ -1743,6 +1767,7 @@ int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_fdb_add);
 
 int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
 			   const struct switchdev_obj_port_fdb *fdb)
@@ -1757,6 +1782,7 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_fdb_del);
 
 static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
 				  struct mv88e6xxx_atu_entry *entry)
@@ -1871,6 +1897,7 @@ unlock:
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_fdb_dump);
 
 int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members)
 {
@@ -1886,6 +1913,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members)
 	mutex_unlock(&ps->smi_mutex);
 	return err;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_bridge_join);
 
 int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members)
 {
@@ -1901,6 +1929,7 @@ int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members)
 	mutex_unlock(&ps->smi_mutex);
 	return err;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_port_bridge_leave);
 
 static void mv88e6xxx_bridge_work(struct work_struct *work)
 {
@@ -2183,6 +2212,7 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_setup_ports);
 
 int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
 {
@@ -2207,6 +2237,7 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_setup_common);
 
 int mv88e6xxx_setup_global(struct dsa_switch *ds)
 {
@@ -2327,6 +2358,7 @@ unlock:
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_setup_global);
 
 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
 {
@@ -2376,6 +2408,7 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_switch_reset);
 
 int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg)
 {
@@ -2392,6 +2425,7 @@ error:
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_page_write);
 
 int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
 			     int reg, int val)
@@ -2410,6 +2444,7 @@ error:
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_page_read);
 
 static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
 {
@@ -2435,6 +2470,7 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_read);
 
 int
 mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
@@ -2451,6 +2487,7 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_write);
 
 int
 mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
@@ -2467,6 +2504,7 @@ mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_read_indirect);
 
 int
 mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
@@ -2484,6 +2522,7 @@ mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
 	mutex_unlock(&ps->smi_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_phy_write_indirect);
 
 #ifdef CONFIG_NET_DSA_HWMON
 
@@ -2555,6 +2594,7 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
 
 	return mv88e61xx_get_temp(ds, temp);
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_temp);
 
 int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
 {
@@ -2574,6 +2614,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_temp_limit);
 
 int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
 {
@@ -2590,6 +2631,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
 	return mv88e6xxx_phy_page_write(ds, phy, 6, 26,
 					(ret & 0xe0ff) | (temp << 8));
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_set_temp_limit);
 
 int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 {
@@ -2609,6 +2651,7 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_get_temp_alarm);
 #endif /* CONFIG_NET_DSA_HWMON */
 
 char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
@@ -2639,6 +2682,7 @@ char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_lookup_name);
 
 int mv88e6xxx_bind(struct device *dev,
 		   struct dsa_switch_tree *dst,
@@ -2679,6 +2723,7 @@ int mv88e6xxx_bind(struct device *dev,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mv88e6xxx_bind);
 
 void mv88e6xxx_unbind(struct device *dev, struct device *master, void *data)
 {
@@ -2688,41 +2733,7 @@ void mv88e6xxx_unbind(struct device *dev, struct device *master, void *data)
 	dsa_switch_unregister(ds);
 	put_device(&ps->bus->dev);
 }
-
-static int __init mv88e6xxx_init(void)
-{
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
-	register_switch_driver(&mv88e6131_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
-	register_switch_driver(&mv88e6123_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
-	register_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
-	register_switch_driver(&mv88e6171_switch_driver);
-#endif
-	return 0;
-}
-module_init(mv88e6xxx_init);
-
-static void __exit mv88e6xxx_cleanup(void)
-{
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
-	unregister_switch_driver(&mv88e6171_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
-	unregister_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
-	unregister_switch_driver(&mv88e6123_61_65_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
-	unregister_switch_driver(&mv88e6131_switch_driver);
-#endif
-}
-module_exit(mv88e6xxx_cleanup);
+EXPORT_SYMBOL_GPL(mv88e6xxx_unbind);
 
 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
-- 
2.6.3

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

* [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (25 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:45   ` Florian Fainelli
  2015-12-23 12:56 ` [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected Andrew Lunn
  2015-12-23 20:44 ` [PATCH RFC 00/28] DSA: Restructure probing Florian Fainelli
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

When the phy is disconnected, the parent pointer to the netdev it was
attached to is set to NULL. The code then tries to suspend the phy,
but dsa_slave_fixed_link_update needs the parent pointer to determine
which switch the phy is connected to. So it dereferenced a NULL
pointer. Check for this condition.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/slave.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 1e9e9424a33d..b7f8a40e51d4 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -981,11 +981,15 @@ static void dsa_slave_adjust_link(struct net_device *dev)
 static int dsa_slave_fixed_link_update(struct net_device *dev,
 				       struct fixed_phy_status *status)
 {
-	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct dsa_switch *ds = p->parent;
+	struct dsa_slave_priv *p;
+	struct dsa_switch *ds;
 
-	if (ds->drv->fixed_link_update)
-		ds->drv->fixed_link_update(ds, p->port, status);
+	if (dev) {
+		p = netdev_priv(dev);
+		ds = p->parent;
+		if (ds->drv->fixed_link_update)
+			ds->drv->fixed_link_update(ds, p->port, status);
+	}
 
 	return 0;
 }
-- 
2.6.3

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

* [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (26 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect Andrew Lunn
@ 2015-12-23 12:56 ` Andrew Lunn
  2015-12-23 20:45   ` Florian Fainelli
  2015-12-23 20:44 ` [PATCH RFC 00/28] DSA: Restructure probing Florian Fainelli
  28 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 12:56 UTC (permalink / raw)
  To: Florian Fainelli, narmstrong, vivien.didelot; +Cc: netdev, Andrew Lunn

The phy is disconnected from the slave in dsa_slave_destroy(). Don't
destroy fixed link phys until after this, since there can be fixed
linked phys connected to ports.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 net/dsa/dsa.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index c5f55b672675..e344c833e707 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -426,7 +426,18 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
 		hwmon_device_unregister(ds->hwmon_dev);
 #endif
 
-	/* Disable configuration of the CPU and DSA ports */
+	/* Destroy network devices for physical switch ports. */
+	for (port = 0; port < DSA_MAX_PORTS; port++) {
+		if (!(ds->phys_port_mask & (1 << port)))
+			continue;
+
+		if (!ds->ports[port])
+			continue;
+
+		dsa_slave_destroy(ds->ports[port]);
+	}
+
+	/* Remove any fixed link PHYs */
 	for (port = 0; port < DSA_MAX_PORTS; port++) {
 		if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
 			continue;
@@ -444,17 +455,6 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
 		}
 	}
 
-	/* Destroy network devices for physical switch ports. */
-	for (port = 0; port < DSA_MAX_PORTS; port++) {
-		if (!(ds->phys_port_mask & (1 << port)))
-			continue;
-
-		if (!ds->ports[port])
-			continue;
-
-		dsa_slave_destroy(ds->ports[port]);
-	}
-
 	mdiobus_unregister(ds->slave_mii_bus);
 }
 
-- 
2.6.3

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

* Re: [PATCH RFC 01/28] component: remove old add_components method
  2015-12-23 12:56 ` [PATCH RFC 01/28] component: remove old add_components method Andrew Lunn
@ 2015-12-23 13:21   ` Russell King - ARM Linux
  2015-12-23 15:57     ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Russell King - ARM Linux @ 2015-12-23 13:21 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, narmstrong, vivien.didelot, netdev

Why are you sending this?  I'm confused.

On Wed, Dec 23, 2015 at 01:56:15PM +0100, Andrew Lunn wrote:
> From: Russell King <rmk+kernel@arm.linux.org.uk>
> 
> Now that drivers create an array of component matches at probe time, we
> can retire the old methods.  This involves removing the add_components
> master method, and removing component_master_add_child() from public
> view.  We also remove component_add_master() as that interface is no
> longer useful.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/base/component.c  | 31 +++++--------------------------
>  include/linux/component.h |  5 -----
>  2 files changed, 5 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/base/component.c b/drivers/base/component.c
> index f748430bb654..2ca22738ae92 100644
> --- a/drivers/base/component.c
> +++ b/drivers/base/component.c
> @@ -84,7 +84,7 @@ static void component_detach_master(struct master *master, struct component *c)
>   * function and compare data.  This is safe to call for duplicate matches
>   * and will not result in the same component being added multiple times.
>   */
> -int component_master_add_child(struct master *master,
> +static int component_master_add_child(struct master *master,
>  	int (*compare)(struct device *, void *), void *compare_data)
>  {
>  	struct component *c;
> @@ -104,7 +104,6 @@ int component_master_add_child(struct master *master,
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL_GPL(component_master_add_child);
>  
>  static int find_components(struct master *master)
>  {
> @@ -112,14 +111,6 @@ static int find_components(struct master *master)
>  	size_t i;
>  	int ret = 0;
>  
> -	if (!match) {
> -		/*
> -		 * Search the list of components, looking for components that
> -		 * belong to this master, and attach them to the master.
> -		 */
> -		return master->ops->add_components(master->dev, master);
> -	}
> -
>  	/*
>  	 * Scan the array of match functions and attach
>  	 * any components which are found to this master.
> @@ -290,15 +281,10 @@ int component_master_add_with_match(struct device *dev,
>  	struct master *master;
>  	int ret;
>  
> -	if (ops->add_components && match)
> -		return -EINVAL;
> -
> -	if (match) {
> -		/* Reallocate the match array for its true size */
> -		match = component_match_realloc(dev, match, match->num);
> -		if (IS_ERR(match))
> -			return PTR_ERR(match);
> -	}
> +	/* Reallocate the match array for its true size */
> +	match = component_match_realloc(dev, match, match->num);
> +	if (IS_ERR(match))
> +		return PTR_ERR(match);
>  
>  	master = kzalloc(sizeof(*master), GFP_KERNEL);
>  	if (!master)
> @@ -326,13 +312,6 @@ int component_master_add_with_match(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(component_master_add_with_match);
>  
> -int component_master_add(struct device *dev,
> -	const struct component_master_ops *ops)
> -{
> -	return component_master_add_with_match(dev, ops, NULL);
> -}
> -EXPORT_SYMBOL_GPL(component_master_add);
> -
>  void component_master_del(struct device *dev,
>  	const struct component_master_ops *ops)
>  {
> diff --git a/include/linux/component.h b/include/linux/component.h
> index c00dcc302611..71c434a6a5ee 100644
> --- a/include/linux/component.h
> +++ b/include/linux/component.h
> @@ -17,18 +17,13 @@ void component_unbind_all(struct device *, void *);
>  struct master;
>  
>  struct component_master_ops {
> -	int (*add_components)(struct device *, struct master *);
>  	int (*bind)(struct device *);
>  	void (*unbind)(struct device *);
>  };
>  
> -int component_master_add(struct device *, const struct component_master_ops *);
>  void component_master_del(struct device *,
>  	const struct component_master_ops *);
>  
> -int component_master_add_child(struct master *master,
> -	int (*compare)(struct device *, void *), void *compare_data);
> -
>  struct component_match;
>  
>  int component_master_add_with_match(struct device *,
> -- 
> 2.6.3
> 

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH RFC 01/28] component: remove old add_components method
  2015-12-23 13:21   ` Russell King - ARM Linux
@ 2015-12-23 15:57     ` Andrew Lunn
  0 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 15:57 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Florian Fainelli, narmstrong, vivien.didelot, netdev

On Wed, Dec 23, 2015 at 01:21:24PM +0000, Russell King - ARM Linux wrote:
> Why are you sending this?  I'm confused.

Hi Russell

It is part of a bigger series, which i just sent as RFC. I need the
functionality of your patch, but it not yet available upstream. By the
time my patch series leaves RFC and is ready for acceptance, i expect
your patch will be upstream, and i will drop it.

     Andrew

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

* Re: [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver
  2015-12-23 12:56 ` [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver Andrew Lunn
@ 2015-12-23 20:32   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:32 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Hi Andrew,

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> diff --git a/Documentation/devicetree/bindings/net/dsa/broadcom.txt b/Documentation/devicetree/bindings/net/dsa/broadcom.txt
> new file mode 100644
> index 000000000000..bd92be0ef2c8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dsa/broadcom.txt
> @@ -0,0 +1,48 @@
> +* Broadcom Starfighter 2 integrated switch device
> +
> +Required properties:
> +
> +- compatible: should be "brcm,brcm-sf2"
> +- reg: addresses and length of the register sets for the device, must be 6
> +  pairs of register addresses and lengths
> +- interrupts: interrupts for the devices, must be two interrupts
> +
> +Optional properties:
> +
> +- reg-names: litteral names for the device base register addresses,
> +  when present must be: "core", "reg", "intrl2_0", "intrl2_1", "fcb",
> +  "acb"

These are in fact mandatory properties.

> +
> +- interrupt-names: litternal names for the device interrupt lines,
> +  when present must be: "switch_0" and "switch_1"

Likewise

> +
> +- brcm,num-gphy: specify the maximum number of integrated gigabit PHYs
> +  in the switch

Likewise

> +
> +- brcm,num-rgmii-ports: specify the maximum number of RGMII interfaces
> +  supported by the switch
> +
> +- brcm,fcb-pause-override: boolean property, if present indicates that
> +  the switch supports Failover Control Block pause override capability
> +
> +- brcm,acb-packets-inflight: boolean property, if present indicates
> +  that the switch Admission Control Block supports reporting the
> +  number of packets in-flight in a switch queue

All of these above are indeed optional.

Having to introduce a new binding for this driver to be converted is a
major deal breaker, the platforms I use have a frozen, yet wrongly
specified Device Tree binding, but still, we need to keep backward
compatibility with it.

My initial attempt, if you remove the part where I tried to convert
every switch driver into a PHY device handled that:

https://github.com/ffainelli/linux/commit/287fc1b33cdd6155c507a95531fd820a5c6dbaf4

Since we have dsa_of_probe(), that alone should be enough to allow us to
maintain a dsa_platform_data structure along with the old binding. This
is not a whole lot different from your patch 13.

Thanks!
-- 
Florian

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

* Re: [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers
  2015-12-23 12:56 ` [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers Andrew Lunn
@ 2015-12-23 20:36   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:36 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> By passing a device structure to the switch devices, it allows them
> to use devm_* methods for resource management.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory
  2015-12-23 12:56 ` [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory Andrew Lunn
@ 2015-12-23 20:39   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:39 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> Now the switch devices have a dev pointer, make use if it for allocating
> the drivers private data structures using a devm_kzalloc().
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  drivers/net/dsa/bcm_sf2.c   |  7 +++++--
>  drivers/net/dsa/mv88e6123.c |  6 +++---
>  drivers/net/dsa/mv88e6131.c |  6 +++---
>  drivers/net/dsa/mv88e6171.c |  6 +++---
>  drivers/net/dsa/mv88e6352.c |  6 +++---
>  drivers/net/dsa/mv88e6xxx.c | 13 ++++++++++---
>  drivers/net/dsa/mv88e6xxx.h |  5 ++++-
>  include/net/dsa.h           |  8 +++++++-
>  8 files changed, 38 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
> index 6925b3c13895..23326c2a01b8 100644
> --- a/drivers/net/dsa/bcm_sf2.c
> +++ b/drivers/net/dsa/bcm_sf2.c
> @@ -929,7 +929,7 @@ static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
>  static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
>  {
>  	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
> -	struct bcm_sf2_priv *priv = ds_to_priv(ds);
> +	struct bcm_sf2_priv *priv;
>  	struct device_node *dn;
>  	void __iomem **base;
>  	unsigned int port;
> @@ -937,6 +937,10 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds, struct device *dev)
>  	u32 reg, rev;
>  	int ret;
>  
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;

This looks fine overall, except that part, there is an earlier priv =
ds_to_priv() in the function so we might be missing a ds->priv = priv
here once the allocation is successful.

With that fixed: Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 07/28] net: dsa: Remove allocation of driver private memory
  2015-12-23 12:56 ` [PATCH RFC 07/28] net: dsa: Remove allocation of driver " Andrew Lunn
@ 2015-12-23 20:39   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:39 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> The drivers now allocate their own memory for private usage. Remove
> the allocation from the core code.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure
  2015-12-23 12:56 ` [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure Andrew Lunn
@ 2015-12-23 20:40   ` Florian Fainelli
  2016-01-21 20:41   ` Vivien Didelot
  1 sibling, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:40 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> Rather than looking up the mii bus and address every time, do it once
> and setup, and keep it in the private structure.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional
  2015-12-23 12:56 ` [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional Andrew Lunn
@ 2015-12-23 20:42   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:42 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> When all the switches are devices and register to the DSA framework,
> having a dsa,mii-bus property is not required.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases
  2015-12-23 12:56 ` [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases Andrew Lunn
@ 2015-12-23 20:42   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:42 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> Due to the complexity it can be hard to know why DSA fails to probe.
> Add some debug prints for the common error cases.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>

I had something similar here since, thanks!
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
                   ` (27 preceding siblings ...)
  2015-12-23 12:56 ` [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected Andrew Lunn
@ 2015-12-23 20:44 ` Florian Fainelli
  2015-12-23 22:33   ` Andrew Lunn
  28 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:44 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Hi Andrew,

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> As noted in Documentation/networking/dsa/dsa.txt, the current DSA
> architecture has a few architecture problems:
> 
> DSA is implemented as a DSA platform device driver which is convenient because
> it will register the entire DSA switch tree attached to a master network device
> in one-shot, facilitating the device creation and simplifying the device driver
> model a bit, this comes however with a number of limitations:
> 
> - building DSA and its switch drivers as modules is currently not working
> - the device driver parenting does not necessarily reflect the original
>   bus/device the switch can be created from
> - supporting non-MDIO and non-MMIO (platform) switches is not possible
> 
> This RFC patchset attempts to address this. It allows the switch
> device to be true Linux devices, and use of the device component
> framework to bind the switch devices to the DSA framework, similar to
> the way GPU engines are bound to the master GPU driver. The drivers
> are now modules, which can be loaded and unloaded. Reloading however
> currently causes an Opps, hence RFC.
> 
> The code remains backwards compatible with the old binding, and adds a
> new property to facilitate the component framework. Switch drivers get
> there own binding, allowing them to be probed independent of DSA.

Well, sort of, and that is the part that gives me mixed feelings right
now. Your conversion of the bcm_sf2 driver, although it looks good and
gets us where we should go, still poses a major problem for my platforms
where a wrong DTB is frozen (at least for some time).

I would very much like to make it possible for the bcm_sf2 driver to be
a real platform driver, call into dsa_switch_register(), yet remain
compatible with the old binding by using dsa_of_probe(), it could be
based on the compatible string we get probed with, it could be up to the
caller or the callee to attempt both bindings to be parsed etc.

I still think that using a 'dsa' platform device and having to bind
other drivers to it is just an artifact and relic from the original
design that we do not necessarily need anymore but with the components
framework, it seems to get us in a better shape.

That being said, thanks a lot for getting the patches out!
-- 
Florian

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

* Re: [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect
  2015-12-23 12:56 ` [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect Andrew Lunn
@ 2015-12-23 20:45   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:45 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> When the phy is disconnected, the parent pointer to the netdev it was
> attached to is set to NULL. The code then tries to suspend the phy,
> but dsa_slave_fixed_link_update needs the parent pointer to determine
> which switch the phy is connected to. So it dereferenced a NULL
> pointer. Check for this condition.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected
  2015-12-23 12:56 ` [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected Andrew Lunn
@ 2015-12-23 20:45   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:45 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> The phy is disconnected from the slave in dsa_slave_destroy(). Don't
> destroy fixed link phys until after this, since there can be fixed
> linked phys connected to ports.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing
  2015-12-23 12:56 ` [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing Andrew Lunn
@ 2015-12-23 20:46   ` Florian Fainelli
  0 siblings, 0 replies; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:46 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> Switches are either listed in device tree of platform_data. They
> should exist. If the probe fails, defer the probe, which is the likely
> cause of failure, not broken device tree or platform data.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

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

* Re: [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work.
  2015-12-23 12:56 ` [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work Andrew Lunn
@ 2015-12-23 20:48   ` Florian Fainelli
  2015-12-23 22:53     ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 20:48 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> With the introduction of switches as linux devices and the use of the
> component framework, probing has become more complex. Add some
> documentation.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  Documentation/networking/dsa/dsa.txt | 48 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt
> index aa9c1f9313cd..376afa135a81 100644
> --- a/Documentation/networking/dsa/dsa.txt
> +++ b/Documentation/networking/dsa/dsa.txt
> @@ -398,6 +398,54 @@ Switch configuration
>    on the management interface and "hardcode"/"force" this MAC address for the
>    CPU/management interface as an optimization
>  
> +Call flow
> +---------
> +
> +With the ability for switch devices to be true linux devices, the call
> +flow is somewhat complex. The component framework is used to link the
> +dsa framework as the master, with switch devices, as slaves.
> +
> +A switch device should add itself as a component in its probe
> +function.
> +
> +The DSA framework can either be configured using a platform_data
> +structure or from the device tree. If device tree is being used, the
> +dsa framework probe function will allocate a platform_data structure,
> +and populate it using the device tree, via the dsa_of_probe()
> +function.  Within the DSA device tree, switch devices are represented
> +by a phandle to the switch device. These phandles are saved into the
> +platform data so that when switch slaves register themselves, they can
> +be correctly positioned in the DSA cluster.

Humm, I guess I am still not clear on that, in a DT-only system, do I
still need to get the DSA platform device to be probed via DT, along
with references to the switches I want? If that is the case, that seems
a little awkward, could not we probe the individual switches, and see if
they need DSA instead? Or is that how the component framework works,
just being a bit confused here.

Thanks!
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-23 20:44 ` [PATCH RFC 00/28] DSA: Restructure probing Florian Fainelli
@ 2015-12-23 22:33   ` Andrew Lunn
  2015-12-23 23:13     ` Florian Fainelli
  0 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 22:33 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

On Wed, Dec 23, 2015 at 12:44:59PM -0800, Florian Fainelli wrote:
> Hi Andrew,
> 
> Le 23/12/2015 04:56, Andrew Lunn a écrit :
> > As noted in Documentation/networking/dsa/dsa.txt, the current DSA
> > architecture has a few architecture problems:
> > 
> > DSA is implemented as a DSA platform device driver which is convenient because
> > it will register the entire DSA switch tree attached to a master network device
> > in one-shot, facilitating the device creation and simplifying the device driver
> > model a bit, this comes however with a number of limitations:
> > 
> > - building DSA and its switch drivers as modules is currently not working
> > - the device driver parenting does not necessarily reflect the original
> >   bus/device the switch can be created from
> > - supporting non-MDIO and non-MMIO (platform) switches is not possible
> > 
> > This RFC patchset attempts to address this. It allows the switch
> > device to be true Linux devices, and use of the device component
> > framework to bind the switch devices to the DSA framework, similar to
> > the way GPU engines are bound to the master GPU driver. The drivers
> > are now modules, which can be loaded and unloaded. Reloading however
> > currently causes an Opps, hence RFC.
> > 
> > The code remains backwards compatible with the old binding, and adds a
> > new property to facilitate the component framework. Switch drivers get
> > there own binding, allowing them to be probed independent of DSA.

Hi Florian

> Well, sort of, and that is the part that gives me mixed feelings right
> now. Your conversion of the bcm_sf2 driver, although it looks good and
> gets us where we should go, still poses a major problem for my platforms
> where a wrong DTB is frozen (at least for some time).

I hope i've not broken backwards compatibility, so your old DT blobs
should still work. If they don't work, we should debug why.

> I still think that using a 'dsa' platform device and having to bind
> other drivers to it is just an artifact and relic from the original
> design that we do not necessarily need anymore but with the components
> framework, it seems to get us in a better shape.

I don't really see how we can do without a dsa platform driver. We
need something that brings together all the switches in a cluster. We
need somewhere which holds the information about how these switches
are connected together and connected to the host.

    Andrew

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

* Re: [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work.
  2015-12-23 20:48   ` Florian Fainelli
@ 2015-12-23 22:53     ` Andrew Lunn
  2015-12-25  1:29       ` Florian Fainelli
  0 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-23 22:53 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

On Wed, Dec 23, 2015 at 12:48:28PM -0800, Florian Fainelli wrote:
> Le 23/12/2015 04:56, Andrew Lunn a écrit :
> > With the introduction of switches as linux devices and the use of the
> > component framework, probing has become more complex. Add some
> > documentation.
> > 
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > ---
> >  Documentation/networking/dsa/dsa.txt | 48 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 48 insertions(+)
> > 
> > diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt
> > index aa9c1f9313cd..376afa135a81 100644
> > --- a/Documentation/networking/dsa/dsa.txt
> > +++ b/Documentation/networking/dsa/dsa.txt
> > @@ -398,6 +398,54 @@ Switch configuration
> >    on the management interface and "hardcode"/"force" this MAC address for the
> >    CPU/management interface as an optimization
> >  
> > +Call flow
> > +---------
> > +
> > +With the ability for switch devices to be true linux devices, the call
> > +flow is somewhat complex. The component framework is used to link the
> > +dsa framework as the master, with switch devices, as slaves.
> > +
> > +A switch device should add itself as a component in its probe
> > +function.
> > +
> > +The DSA framework can either be configured using a platform_data
> > +structure or from the device tree. If device tree is being used, the
> > +dsa framework probe function will allocate a platform_data structure,
> > +and populate it using the device tree, via the dsa_of_probe()
> > +function.  Within the DSA device tree, switch devices are represented
> > +by a phandle to the switch device. These phandles are saved into the
> > +platform data so that when switch slaves register themselves, they can
> > +be correctly positioned in the DSA cluster.
> 
> Humm, I guess I am still not clear on that, in a DT-only system, do I
> still need to get the DSA platform device to be probed via DT, along
> with references to the switches I want? If that is the case, that seems
> a little awkward, could not we probe the individual switches, and see if
> they need DSA instead? Or is that how the component framework works,
> just being a bit confused here.

The component framework needs one master device and a number of slave
devices. The master device effectively gives the framework a list of
slave devices it needs. When the slave devices probe they register
with the component framework. The master then asks the framework if
its slaves are present, and if not returns -EPRODE_DEFERS and tries
again later.

So the dsa platform device is the master, and the switch devices are
the slaves.

It sounds like you want to 'optimise' for a DSA cluster consisting of
a single switch, throwing away the D in DSA. Now the SF2 is a bit
'odd'. Since it is embedded in the SoC, you cannot have multiple of
them in a cluster. So such an optimization could make sense for the
SF2. But can we do this without adding too more complexity?

     Andrew

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-23 22:33   ` Andrew Lunn
@ 2015-12-23 23:13     ` Florian Fainelli
  2015-12-24 12:58       ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-23 23:13 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: narmstrong, vivien.didelot, netdev

Le 23/12/2015 14:33, Andrew Lunn a écrit :
> On Wed, Dec 23, 2015 at 12:44:59PM -0800, Florian Fainelli wrote:
>> Hi Andrew,
>>
>> Le 23/12/2015 04:56, Andrew Lunn a écrit :
>>> As noted in Documentation/networking/dsa/dsa.txt, the current DSA
>>> architecture has a few architecture problems:
>>>
>>> DSA is implemented as a DSA platform device driver which is convenient because
>>> it will register the entire DSA switch tree attached to a master network device
>>> in one-shot, facilitating the device creation and simplifying the device driver
>>> model a bit, this comes however with a number of limitations:
>>>
>>> - building DSA and its switch drivers as modules is currently not working
>>> - the device driver parenting does not necessarily reflect the original
>>>   bus/device the switch can be created from
>>> - supporting non-MDIO and non-MMIO (platform) switches is not possible
>>>
>>> This RFC patchset attempts to address this. It allows the switch
>>> device to be true Linux devices, and use of the device component
>>> framework to bind the switch devices to the DSA framework, similar to
>>> the way GPU engines are bound to the master GPU driver. The drivers
>>> are now modules, which can be loaded and unloaded. Reloading however
>>> currently causes an Opps, hence RFC.
>>>
>>> The code remains backwards compatible with the old binding, and adds a
>>> new property to facilitate the component framework. Switch drivers get
>>> there own binding, allowing them to be probed independent of DSA.
> 
> Hi Florian
> 
>> Well, sort of, and that is the part that gives me mixed feelings right
>> now. Your conversion of the bcm_sf2 driver, although it looks good and
>> gets us where we should go, still poses a major problem for my platforms
>> where a wrong DTB is frozen (at least for some time).
> 
> I hope i've not broken backwards compatibility, so your old DT blobs
> should still work. If they don't work, we should debug why.
> 
>> I still think that using a 'dsa' platform device and having to bind
>> other drivers to it is just an artifact and relic from the original
>> design that we do not necessarily need anymore but with the components
>> framework, it seems to get us in a better shape.
> 
> I don't really see how we can do without a dsa platform driver. We
> need something that brings together all the switches in a cluster. We
> need somewhere which holds the information about how these switches
> are connected together and connected to the host.

I do not think you need the platform device because ultimately what the
DSA platform device does is bind some data to the master network device
the DSA switch tree is hanging off. Sure you need some piece of code
that is resident in kernel or module space to be able to parse and
allocate that data structure and bind multiple switch drivers together,
but that could be a consequence of probing switch driver using their bus
probe function.

The way I would imagine this in a cluster configuration is that you
probe switches in the order in which they should appear in the final
switch tree (if this order cannot be guaranteed, then defer until it
is), and as you parse Device Tree for these switches you allocate their
resources and update the dsa_switch_tree structure "live".

So for the first switch in tree:
- master network device has no dsa_ptr assigned yet, allocate
dsa_platform_data and this switch's platform data, assign dev->dsa_ptr
so subsequent switches can be attached

For secondary switches in tree:
- locate their index, fetch the master network device dsa_ptr and add
them to the switch tree

If we are using Device Tree this is relatively easy since we can lookup
the entire Device Tree to know the switch tree topology whenever we
probe a switch device driver. If we are using platform data, then, we
should have a way to associate a given MDIO bus address with
supplementary information, very much like what this patch does:

https://dev.openwrt.org/browser/trunk/target/linux/generic/patches-4.3/710-phy-add-mdio_register_board_info.patch

Does that make sense?
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-23 23:13     ` Florian Fainelli
@ 2015-12-24 12:58       ` Andrew Lunn
  2015-12-25  1:47         ` Florian Fainelli
  0 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-24 12:58 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

> I do not think you need the platform device because ultimately what the
> DSA platform device does is bind some data to the master network device
> the DSA switch tree is hanging off. Sure you need some piece of code
> that is resident in kernel or module space to be able to parse and
> allocate that data structure and bind multiple switch drivers together,
> but that could be a consequence of probing switch driver using their bus
> probe function.
> 
> The way I would imagine this in a cluster configuration is that you
> probe switches in the order in which they should appear in the final
> switch tree (if this order cannot be guaranteed, then defer until it
> is), and as you parse Device Tree for these switches you allocate their
> resources and update the dsa_switch_tree structure "live".

How do you get this ordering? You cannot control the probe order in
Linux.

> If we are using Device Tree this is relatively easy since we can lookup
> the entire Device Tree to know the switch tree topology whenever we
> probe a switch device driver. If we are using platform data, then, we
> should have a way to associate a given MDIO bus address with
> supplementary information, very much like what this patch does:

One of my aims is to abstract away the MDIO bus from DSA. How you talk
to the switch is a switch device property. SF2 has a different way to
talk to the switch, memory mapped IO, etc.

Anyway, who do you think the device tree binding will look? Maybe take
the .dts file in patches 2 and 20 to build an example?

	Andrew

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

* Re: [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work.
  2015-12-23 22:53     ` Andrew Lunn
@ 2015-12-25  1:29       ` Florian Fainelli
  2015-12-25 10:00         ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-25  1:29 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: narmstrong, vivien.didelot, netdev

Le 23/12/2015 14:53, Andrew Lunn a écrit :
> On Wed, Dec 23, 2015 at 12:48:28PM -0800, Florian Fainelli wrote:
>> Le 23/12/2015 04:56, Andrew Lunn a écrit :
>>> With the introduction of switches as linux devices and the use of the
>>> component framework, probing has become more complex. Add some
>>> documentation.
>>>
>>> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
>>> ---
>>>  Documentation/networking/dsa/dsa.txt | 48 ++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 48 insertions(+)
>>>
>>> diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt
>>> index aa9c1f9313cd..376afa135a81 100644
>>> --- a/Documentation/networking/dsa/dsa.txt
>>> +++ b/Documentation/networking/dsa/dsa.txt
>>> @@ -398,6 +398,54 @@ Switch configuration
>>>    on the management interface and "hardcode"/"force" this MAC address for the
>>>    CPU/management interface as an optimization
>>>  
>>> +Call flow
>>> +---------
>>> +
>>> +With the ability for switch devices to be true linux devices, the call
>>> +flow is somewhat complex. The component framework is used to link the
>>> +dsa framework as the master, with switch devices, as slaves.
>>> +
>>> +A switch device should add itself as a component in its probe
>>> +function.
>>> +
>>> +The DSA framework can either be configured using a platform_data
>>> +structure or from the device tree. If device tree is being used, the
>>> +dsa framework probe function will allocate a platform_data structure,
>>> +and populate it using the device tree, via the dsa_of_probe()
>>> +function.  Within the DSA device tree, switch devices are represented
>>> +by a phandle to the switch device. These phandles are saved into the
>>> +platform data so that when switch slaves register themselves, they can
>>> +be correctly positioned in the DSA cluster.
>>
>> Humm, I guess I am still not clear on that, in a DT-only system, do I
>> still need to get the DSA platform device to be probed via DT, along
>> with references to the switches I want? If that is the case, that seems
>> a little awkward, could not we probe the individual switches, and see if
>> they need DSA instead? Or is that how the component framework works,
>> just being a bit confused here.
> 
> The component framework needs one master device and a number of slave
> devices. The master device effectively gives the framework a list of
> slave devices it needs. When the slave devices probe they register
> with the component framework. The master then asks the framework if
> its slaves are present, and if not returns -EPRODE_DEFERS and tries
> again later.
> 
> So the dsa platform device is the master, and the switch devices are
> the slaves.

Ok, but then that means I still need to have a "marvell,dsa" node in
Device Tree, that does not make sense to me with your changes, because
the individual compatible and nodes for the switches are enough
information to get their driver to probe, and as a consequence, register
with DSA their switch devices, but let's keep following this point in
the cover letter thread.

> 
> It sounds like you want to 'optimise' for a DSA cluster consisting of
> a single switch, throwing away the D in DSA. Now the SF2 is a bit
> 'odd'. Since it is embedded in the SoC, you cannot have multiple of
> them in a cluster. So such an optimization could make sense for the
> SF2. But can we do this without adding too more complexity?

The distributed case is the complex one, the one with a single switch
hanging off an Ethernet MAC is the most common one and is much simpler
to deal with.
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-24 12:58       ` Andrew Lunn
@ 2015-12-25  1:47         ` Florian Fainelli
  2015-12-25 11:31           ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-25  1:47 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: narmstrong, vivien.didelot, netdev

Le 24/12/2015 04:58, Andrew Lunn a écrit :
>> I do not think you need the platform device because ultimately what the
>> DSA platform device does is bind some data to the master network device
>> the DSA switch tree is hanging off. Sure you need some piece of code
>> that is resident in kernel or module space to be able to parse and
>> allocate that data structure and bind multiple switch drivers together,
>> but that could be a consequence of probing switch driver using their bus
>> probe function.
>>
>> The way I would imagine this in a cluster configuration is that you
>> probe switches in the order in which they should appear in the final
>> switch tree (if this order cannot be guaranteed, then defer until it
>> is), and as you parse Device Tree for these switches you allocate their
>> resources and update the dsa_switch_tree structure "live".
> 
> How do you get this ordering? You cannot control the probe order in
> Linux.

Fair enough, then the ordering is not that important after all, the
cases could be something like these:

- all switch drivers built into the kernel, whichever gets probed first
creates the dsa_switch_tree and attaches its to the master network device
- subsequent switch drivers probed locate that master network device,
use the dsa_switch_tree and insert themselves at the correct index

If you need a working switch tree to boot your system from the network,
then all of this probing will eventually converge thanks to deferred
probing. If you build everything as a module, then the expectation as an
end-user could be that the switch tree becomes only fully functional
when *all* modules, and consequently switch devices are loaded/created.
Whether the switch tree is functional in between is something that
mostly depends on the default switch configuration left by
bootloader/reset defaults, so your mileage may vary.

> 
>> If we are using Device Tree this is relatively easy since we can lookup
>> the entire Device Tree to know the switch tree topology whenever we
>> probe a switch device driver. If we are using platform data, then, we
>> should have a way to associate a given MDIO bus address with
>> supplementary information, very much like what this patch does:
> 
> One of my aims is to abstract away the MDIO bus from DSA. How you talk
> to the switch is a switch device property. SF2 has a different way to
> talk to the switch, memory mapped IO, etc.

I appreciate you trying to see my point of view and mentioning the
driver that I care about, but I am not just after SF2 here, just any
kind of switch in general: PCIe, SPI, I2C, GPIO, MDIO, MMIO is precisely
what I would like to solve instead of narrow MDIO and distributed case
that DSA currently deals with, and MMIO with some help from the of_*
routines which do not need any kind of bus probing and struct device
creation (most often).

> 
> Anyway, who do you think the device tree binding will look? Maybe take
> the .dts file in patches 2 and 20 to build an example?

The binding would look pretty much the same as what the current DSA and
your proposed binding look like, except that instead of encoding the
MDIO address *and* the switch index in tree in the same "reg" properties
(which was wrong along, but I did not really knew it back in 2009 or
so), the two would be different properties.

When you parse the Device Tree you can determine what is the position of
the switch in the switch tree by looking at its ports sub-nodes and see
if they have a "link" property which links them to another device,
eventually, in case where there is not a one to one, but one to many
connection, an additional property can help you figure out how to
flatten things out.

So in practical terms, this could wind up looking like this:

mdio_bus@deadbeef {
	compatible = "acme,mdiobus";
	..
	switch0@0 {
		compatible = "marvell,mv88e6131";
		reg = <0>;
		dsa,addr = <1>;

		switch0port5: port@5 {
				reg = <5>;
				label = "dsa";
				link = <&switch1port9>;
			};
		};
	};
};

soc-bus@cafebabe {
	compatible = "simple-bus";

	switch1@cafedead {
		compatible = "marvell,armada-xp-switch";
		reg = <0xcafedead 0x1000>;
		dsa,addr = <0>;

		
		switch1port9: port9 {
			reg = <9>;
			label = "dsa";
			link = <&switch0port5>;
		};
	};
};

That way you could even intertwine foreign bus switches, and that would
not make a slight difference in how they are managed by DSA.

Your changes in patch 20 make your switches appear out of any busing
hierarchy whereas they are actually child devices of their respective
mdio-mux bus nodes and should appear as such imho.
-- 
Florian

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

* Re: [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work.
  2015-12-25  1:29       ` Florian Fainelli
@ 2015-12-25 10:00         ` Andrew Lunn
  0 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-25 10:00 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

> > It sounds like you want to 'optimise' for a DSA cluster consisting of
> > a single switch, throwing away the D in DSA. Now the SF2 is a bit
> > 'odd'. Since it is embedded in the SoC, you cannot have multiple of
> > them in a cluster. So such an optimization could make sense for the
> > SF2. But can we do this without adding too more complexity?
> 
> The distributed case is the complex one, the one with a single switch
> hanging off an Ethernet MAC is the most common one and is much simpler
> to deal with.

Sure, boards with multiple switches don't happen very often, but they
do exist. If we can solve the general case, a single switch just
works. The reverse is not true. Which is why i've been doing all my
development work on a board with three switches. And in theory, i
could even partition these into two DSA clusters!

	    Andrew

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-25  1:47         ` Florian Fainelli
@ 2015-12-25 11:31           ` Andrew Lunn
  2015-12-25 22:00             ` Florian Fainelli
  0 siblings, 1 reply; 60+ messages in thread
From: Andrew Lunn @ 2015-12-25 11:31 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

> > One of my aims is to abstract away the MDIO bus from DSA. How you talk
> > to the switch is a switch device property. SF2 has a different way to
> > talk to the switch, memory mapped IO, etc.
> 
> I appreciate you trying to see my point of view and mentioning the
> driver that I care about, but I am not just after SF2 here, just any
> kind of switch in general: PCIe, SPI, I2C, GPIO, MDIO, MMIO is precisely
> what I would like to solve instead of narrow MDIO and distributed case
> that DSA currently deals with, and MMIO with some help from the of_*
> routines which do not need any kind of bus probing and struct device
> creation (most often).

And this is achieved with the new structure. How you access the switch
is part of the switch device binding, be it an MDIO bus/addr, an MMIO
reg property, or an i2c client, etc. The switch driver registers a set
of ops which are neutral to the switch access mechanism.

In the DSA node, the mdio bus is now only required when using
backwards compatibility. The reg property is a bit odd, since it is
used for linking DSA ports together. So currently it is kept, but only
one of the two fields is used. We could in a later patchset change
this, since there are currently no in kernel devices with multiple
switches, so we don't have to worry about breaking the binding.

> > Anyway, who do you think the device tree binding will look? Maybe take
> > the .dts file in patches 2 and 20 to build an example?
> 
> The binding would look pretty much the same as what the current DSA and
> your proposed binding look like, except that instead of encoding the
> MDIO address *and* the switch index in tree in the same "reg" properties
> (which was wrong along, but I did not really knew it back in 2009 or
> so), the two would be different properties.

Agreed, as explained above.
 
> When you parse the Device Tree you can determine what is the position of
> the switch in the switch tree by looking at its ports sub-nodes and see
> if they have a "link" property which links them to another device,
> eventually, in case where there is not a one to one, but one to many
> connection, an additional property can help you figure out how to
> flatten things out.
> 
> So in practical terms, this could wind up looking like this:
> 
> mdio_bus@deadbeef {
> 	compatible = "acme,mdiobus";
> 	..
> 	switch0@0 {
> 		compatible = "marvell,mv88e6131";
> 		reg = <0>;
> 		dsa,addr = <1>;

This is not sufficient. It does not tell you which DSA cluster this
switch belongs to.

> 
> 		switch0port5: port@5 {
> 				reg = <5>;
> 				label = "dsa";
> 				link = <&switch1port9>;
> 			};
> 		};
> 	};
> };

Just for clarification, where are the cpu ports and normal user ports?
Here as well?

Making MDIO controlled switches hang of MDIO can be done, but it does
require some bigger changes to the mdio code. I will need to look at
this again, but i think it starts in of_mdiobus_register_phy() which
needs to look a the compatibility field, and do something different to
phy_device_register(). mdio_unregister() will also need some work,
since it only expects phy devices on the mdio bus.

	Andrew

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

* Re: [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules
  2015-12-23 12:56 ` [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules Andrew Lunn
@ 2015-12-25 21:47   ` Florian Fainelli
  2016-01-21 21:29     ` Vivien Didelot
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-25 21:47 UTC (permalink / raw)
  To: Andrew Lunn, narmstrong, vivien.didelot; +Cc: netdev

Le 23/12/2015 04:56, Andrew Lunn a écrit :
> Turn mv88e6xxx into a library module, by exporting its symbols.  Have
> each driver register their own driver functions with the DSA core in
> there init function.
> 
> This results in each driver being a loadable module.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---

[snip]

> +obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
> +obj-$(CONFIGNET_DSA_MV88E6131)  += mv88e6123.o

Missing underscore here between CONFIG and NET.

> +obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
> +obj-$(CONFIG_NET_DSA_MV88E6352) += mv88e6352.o
> +obj-$(CONFIG_NET_DSA_MV88E6171) += mv88e6171.o
>  obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
> diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
> index bb39720f3e8b..9680e59fd2ae 100644
> --- a/drivers/net/dsa/mv88e6123.c
> +++ b/drivers/net/dsa/mv88e6123.c
> @@ -167,7 +167,21 @@ static struct platform_driver mv88e6123_driver = {
>  		.of_match_table = mv88e6123_of_match,
>  	},
>  };
> -module_platform_driver(mv88e6123_driver);
>  
> +static int __init mv88e6123_init(void)
> +{
> +	register_switch_driver(&mv88e6123_switch_driver);
> +
> +	return platform_driver_register(&mv88e6123_driver);
> +}
> +
> +static void __exit mv88e6123_exit(void)
> +{
> +	platform_driver_unregister(&mv88e6123_driver);
> +	unregister_switch_driver(&mv88e6123_switch_driver);
> +}

I think Vivien had started something like this, but it could be nice to
have a helper function/macro which reduces the boilerplate code, not
critical for now though.
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-25 11:31           ` Andrew Lunn
@ 2015-12-25 22:00             ` Florian Fainelli
  2015-12-25 23:41               ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Florian Fainelli @ 2015-12-25 22:00 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: narmstrong, vivien.didelot, netdev

Le 25/12/2015 03:31, Andrew Lunn a écrit :
>>> One of my aims is to abstract away the MDIO bus from DSA. How you talk
>>> to the switch is a switch device property. SF2 has a different way to
>>> talk to the switch, memory mapped IO, etc.
>>
>> I appreciate you trying to see my point of view and mentioning the
>> driver that I care about, but I am not just after SF2 here, just any
>> kind of switch in general: PCIe, SPI, I2C, GPIO, MDIO, MMIO is precisely
>> what I would like to solve instead of narrow MDIO and distributed case
>> that DSA currently deals with, and MMIO with some help from the of_*
>> routines which do not need any kind of bus probing and struct device
>> creation (most often).
> 
> And this is achieved with the new structure. How you access the switch
> is part of the switch device binding, be it an MDIO bus/addr, an MMIO
> reg property, or an i2c client, etc. The switch driver registers a set
> of ops which are neutral to the switch access mechanism.

I am not really questioning whether the abstraction is working, this
clearly does, what I am wondering is if the use of the component
framework requires us to have master and slaves be implemented as strict
platform devices, or if we have a choice in how we mix things together,
like master is a platform device, but slaves could be I2C, SPI client or
even platform devices themselves? That was not quite obvious to me by
looking at the patches, sorry.

If it is the former, then this does not really allow us to make this
framework usable to a wider class of devices. Also, one could imagine
that you could make the master network device's "struct device" be the
master device in the component framework terminology, such that you
could eliminate this synthetic "dsa" platform device.

> 
> In the DSA node, the mdio bus is now only required when using
> backwards compatibility. The reg property is a bit odd, since it is
> used for linking DSA ports together. So currently it is kept, but only
> one of the two fields is used. We could in a later patchset change
> this, since there are currently no in kernel devices with multiple
> switches, so we don't have to worry about breaking the binding.

Sure, that would work.

> 
>>> Anyway, who do you think the device tree binding will look? Maybe take
>>> the .dts file in patches 2 and 20 to build an example?
>>
>> The binding would look pretty much the same as what the current DSA and
>> your proposed binding look like, except that instead of encoding the
>> MDIO address *and* the switch index in tree in the same "reg" properties
>> (which was wrong along, but I did not really knew it back in 2009 or
>> so), the two would be different properties.
> 
> Agreed, as explained above.
>  
>> When you parse the Device Tree you can determine what is the position of
>> the switch in the switch tree by looking at its ports sub-nodes and see
>> if they have a "link" property which links them to another device,
>> eventually, in case where there is not a one to one, but one to many
>> connection, an additional property can help you figure out how to
>> flatten things out.
>>
>> So in practical terms, this could wind up looking like this:
>>
>> mdio_bus@deadbeef {
>> 	compatible = "acme,mdiobus";
>> 	..
>> 	switch0@0 {
>> 		compatible = "marvell,mv88e6131";
>> 		reg = <0>;
>> 		dsa,addr = <1>;
> 
> This is not sufficient. It does not tell you which DSA cluster this
> switch belongs to.

Would it work if we added an additional digit which is the cluster id or
do you need a node grouping switches in a cluster with each other like
you proposed in patch 20?

The question being mostly, if we have the cluster id, address/index in
switch tree, and a double linked list using phandles, is that good
enough to figure out a topology or shall we really have nodes and
sub-nodes with that (we would still need a list one linked list of
phandles to figure out which ports are "dsa").

> 
>>
>> 		switch0port5: port@5 {
>> 				reg = <5>;
>> 				label = "dsa";
>> 				link = <&switch1port9>;
>> 			};
>> 		};
>> 	};
>> };
> 
> Just for clarification, where are the cpu ports and normal user ports?
> Here as well?

I purposely omitted them to make the example simpler to read.

> 
> Making MDIO controlled switches hang of MDIO can be done, but it does
> require some bigger changes to the mdio code. I will need to look at
> this again, but i think it starts in of_mdiobus_register_phy() which
> needs to look a the compatibility field, and do something different to
> phy_device_register(). mdio_unregister() will also need some work,
> since it only expects phy devices on the mdio bus.

Correct, and this is really where I would start before we go on with the
probing restructuring, because that could impact how the new DSA binding
will have to be (re)defined. Right now, converting the Marvell drivers
into individual platform devices is kind of a temporary solution because
we do not have have a proper MDIO device model which is not a PHY.

There are lots of good patches in this series that should probably be
merged right away since they are all improvements.
-- 
Florian

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

* Re: [PATCH RFC 00/28] DSA: Restructure probing
  2015-12-25 22:00             ` Florian Fainelli
@ 2015-12-25 23:41               ` Andrew Lunn
  0 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2015-12-25 23:41 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: narmstrong, vivien.didelot, netdev

> I am not really questioning whether the abstraction is working, this
> clearly does, what I am wondering is if the use of the component
> framework requires us to have master and slaves be implemented as strict
> platform devices, or if we have a choice in how we mix things together,
> like master is a platform device, but slaves could be I2C, SPI client or
> even platform devices themselves? That was not quite obvious to me by
> looking at the patches, sorry.

Slaves can be any sort of device. From what i've seen with GPU usage,
they are sometimes i2c devices, e.g. HDMI and audio framers. The way i
use slaves in the patches, is that all they need is a struct device
and an of node for matching to the master. The master also needs a
struct device. It makes no difference if these struct device are
embedded in a plaform_device, an struct i2c_client, struct phy_device
etc.

> >> mdio_bus@deadbeef {
> >> 	compatible = "acme,mdiobus";
> >> 	..
> >> 	switch0@0 {
> >> 		compatible = "marvell,mv88e6131";
> >> 		reg = <0>;
> >> 		dsa,addr = <1>;
> > 
> > This is not sufficient. It does not tell you which DSA cluster this
> > switch belongs to.
> 
> Would it work if we added an additional digit which is the cluster id or
> do you need a node grouping switches in a cluster with each other like
> you proposed in patch 20?

There is one cluster property at the moment, dsa,ethernet. So we could
actually use that as the cluster identifier, if we assume each cluster
has its own host ethernet.

> 
> The question being mostly, if we have the cluster id, address/index in
> switch tree, and a double linked list using phandles, is that good
> enough to figure out a topology or shall we really have nodes and
> sub-nodes with that (we would still need a list one linked list of
> phandles to figure out which ports are "dsa").

The dsa ports tell us how switches are interconnected. So once we have
all the switches we can determine the topology. What is not so clear
yet is how you know you have all the switches. The binding i proposed
meant the dsa platform device had a complete list of switch devices it
needed to form the cluster. With the distributed binding you are
suggesting, i don't see an easy way we can build the list of slave
devices.

> > Making MDIO controlled switches hang of MDIO can be done, but it does
> > require some bigger changes to the mdio code. I will need to look at
> > this again, but i think it starts in of_mdiobus_register_phy() which
> > needs to look a the compatibility field, and do something different to
> > phy_device_register(). mdio_unregister() will also need some work,
> > since it only expects phy devices on the mdio bus.
> 
> Correct, and this is really where I would start before we go on with the
> probing restructuring, because that could impact how the new DSA binding
> will have to be (re)defined. Right now, converting the Marvell drivers
> into individual platform devices is kind of a temporary solution because
> we do not have have a proper MDIO device model which is not a PHY.

Agreed. So i guess this is the next thing to work on.

> There are lots of good patches in this series that should probably be
> merged right away since they are all improvements.

Care to make a list of which you think should be submitted now?

Thanks
	Andrew

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

* Re: [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure
  2015-12-23 12:56 ` [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure Andrew Lunn
  2015-12-23 20:40   ` Florian Fainelli
@ 2016-01-21 20:41   ` Vivien Didelot
  2016-01-21 20:50     ` Andrew Lunn
  1 sibling, 1 reply; 60+ messages in thread
From: Vivien Didelot @ 2016-01-21 20:41 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, narmstrong; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> Rather than looking up the mii bus and address every time, do it once
> and setup, and keep it in the private structure.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  drivers/net/dsa/mv88e6060.c | 23 +++++++++++++----------
>  drivers/net/dsa/mv88e6060.h | 11 +++++++++++
>  drivers/net/dsa/mv88e6xxx.c | 16 ++++++----------
>  drivers/net/dsa/mv88e6xxx.h |  6 ++++++
>  4 files changed, 36 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
> index 34bc374882c7..d48708dfd963 100644
> --- a/drivers/net/dsa/mv88e6060.c
> +++ b/drivers/net/dsa/mv88e6060.c
> @@ -19,12 +19,9 @@
>  
>  static int reg_read(struct dsa_switch *ds, int addr, int reg)
>  {
> -	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
> +	struct mv88e6060_priv *priv = ds_to_priv(ds);
>  
> -	if (bus == NULL)
> -		return -EINVAL;
> -
> -	return mdiobus_read_nested(bus, ds->pd->sw_addr + addr, reg);
> +	return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
>  }
>  
>  #define REG_READ(addr, reg)					\
> @@ -40,12 +37,9 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)
>  
>  static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
>  {
> -	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
> -
> -	if (bus == NULL)
> -		return -EINVAL;
> +	struct mv88e6060_priv *priv = ds_to_priv(ds);
>  
> -	return mdiobus_write_nested(bus, ds->pd->sw_addr + addr, reg, val);
> +	return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
>  }
>  
>  #define REG_WRITE(addr, reg, val)				\
> @@ -176,6 +170,15 @@ static int mv88e6060_setup(struct dsa_switch *ds, struct device *dev)
>  {
>  	int i;
>  	int ret;
> +	struct mv88e6060_priv *priv;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	ds->priv = priv;
> +	priv->bus = dsa_host_dev_to_mii_bus(ds->master_dev);

This patch drops the checks for !bus, and thus mdiobus_write_nested can
segfault later. Maybe restore the check here?

        if (!priv->bus)
                return -EINVAL;

> +	priv->sw_addr = ds->pd->sw_addr;
>  
>  	ret = mv88e6060_switch_reset(ds);
>  	if (ret < 0)
> diff --git a/drivers/net/dsa/mv88e6060.h b/drivers/net/dsa/mv88e6060.h
> index cc9b2ed4aff4..10249bd16292 100644
> --- a/drivers/net/dsa/mv88e6060.h
> +++ b/drivers/net/dsa/mv88e6060.h
> @@ -108,4 +108,15 @@
>  #define GLOBAL_ATU_MAC_23	0x0e
>  #define GLOBAL_ATU_MAC_45	0x0f
>  
> +struct mv88e6060_priv {
> +	/* MDIO bus and address on bus to use. When in single chip
> +	 * mode, address is 0, and the switch uses multiple addresses
> +	 * on the bus.  When in multi-chip mode, the switch uses a
> +	 * single address which contains two registers used for
> +	 * indirect access to more registers.
> +	 */
> +	struct mii_bus *bus;
> +	int sw_addr;
> +};
> +
>  #endif
> diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
> index 772adc7f9397..170b98f3acbe 100644
> --- a/drivers/net/dsa/mv88e6xxx.c
> +++ b/drivers/net/dsa/mv88e6xxx.c
> @@ -94,15 +94,12 @@ static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,
>  
>  static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
>  {
> -	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
> +	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
>  	int ret;
>  
>  	assert_smi_lock(ds);
>  
> -	if (bus == NULL)
> -		return -EINVAL;
> -
> -	ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg);
> +	ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -159,17 +156,14 @@ static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
>  static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
>  				u16 val)
>  {
> -	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
> +	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
>  
>  	assert_smi_lock(ds);
>  
> -	if (bus == NULL)
> -		return -EINVAL;
> -
>  	dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
>  		addr, reg, val);
>  
> -	return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
> +	return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val);
>  }
>  
>  int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
> @@ -2197,6 +2191,8 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds, struct device *dev)
>  
>  	ds->priv = ps;
>  	ps->ds = ds;
> +	ps->bus = dsa_host_dev_to_mii_bus(ds->master_dev);

Same comment here.

> +	ps->sw_addr = ds->pd->sw_addr;
>  
>  	mutex_init(&ps->smi_mutex);
>  
> diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
> index 72f7dbbce0e2..62069b30f6e5 100644
> --- a/drivers/net/dsa/mv88e6xxx.h
> +++ b/drivers/net/dsa/mv88e6xxx.h
> @@ -388,6 +388,12 @@ struct mv88e6xxx_priv_state {
>  	 */
>  	struct mutex	smi_mutex;
>  
> +	/* The MII bus and the address on the bus that is used to
> +	 * communication with the switch
> +	 */
> +	struct mii_bus *bus;
> +	int sw_addr;
> +
>  #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
>  	/* Handles automatic disabling and re-enabling of the PHY
>  	 * polling unit.
> -- 
> 2.6.3

Thanks,
-v

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

* Re: [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure
  2016-01-21 20:41   ` Vivien Didelot
@ 2016-01-21 20:50     ` Andrew Lunn
  0 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2016-01-21 20:50 UTC (permalink / raw)
  To: Vivien Didelot; +Cc: Florian Fainelli, narmstrong, netdev

> > @@ -176,6 +170,15 @@ static int mv88e6060_setup(struct dsa_switch *ds, struct device *dev)
> >  {
> >  	int i;
> >  	int ret;
> > +	struct mv88e6060_priv *priv;
> > +
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	ds->priv = priv;
> > +	priv->bus = dsa_host_dev_to_mii_bus(ds->master_dev);
> 
> This patch drops the checks for !bus, and thus mdiobus_write_nested can
> segfault later. Maybe restore the check here?

Agreed. I will post a refresh of these patches in a few days. I made a
few changes to integrate with the mdio device patchset which has
recently been merged.

	 Andrew

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

* Re: [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name()
  2015-12-23 12:56 ` [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name() Andrew Lunn
@ 2016-01-21 20:54   ` Vivien Didelot
  0 siblings, 0 replies; 60+ messages in thread
From: Vivien Didelot @ 2016-01-21 20:54 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, narmstrong; +Cc: netdev, Andrew Lunn

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> mv88e6xxx_lookup_name() returns the model name of a switch at a given
> address on an MII bus. Using mii_bus it identify the bus rather than
> the host device is more logical, so change the parameter.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  drivers/net/dsa/mv88e6123.c | 4 +++-
>  drivers/net/dsa/mv88e6131.c | 4 +++-
>  drivers/net/dsa/mv88e6171.c | 4 +++-
>  drivers/net/dsa/mv88e6352.c | 4 +++-
>  drivers/net/dsa/mv88e6xxx.c | 9 +++------
>  drivers/net/dsa/mv88e6xxx.h | 2 +-
>  6 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
> index 6d6fca62e8b1..2c23762cbed8 100644
> --- a/drivers/net/dsa/mv88e6123.c
> +++ b/drivers/net/dsa/mv88e6123.c
> @@ -31,7 +31,9 @@ static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
>  
>  static char *mv88e6123_drv_probe(struct device *host_dev, int sw_addr)
>  {
> -	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6123_table,
> +	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
> +
> +	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6123_table,
>  				     ARRAY_SIZE(mv88e6123_table));
>  }
>  
> diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
> index e0aa3be7f5a9..02d2bca095af 100644
> --- a/drivers/net/dsa/mv88e6131.c
> +++ b/drivers/net/dsa/mv88e6131.c
> @@ -27,7 +27,9 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
>  
>  static char *mv88e6131_drv_probe(struct device *host_dev, int sw_addr)
>  {
> -	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6131_table,
> +	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
> +
> +	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6131_table,
>  				     ARRAY_SIZE(mv88e6131_table));
>  }
>  
> diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
> index 8fc4db23744e..d557be12feb7 100644
> --- a/drivers/net/dsa/mv88e6171.c
> +++ b/drivers/net/dsa/mv88e6171.c
> @@ -26,7 +26,9 @@ static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
>  
>  static char *mv88e6171_drv_probe(struct device *host_dev, int sw_addr)
>  {
> -	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6171_table,
> +	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
> +
> +	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6171_table,
>  				     ARRAY_SIZE(mv88e6171_table));
>  }
>  
> diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
> index 2877ad8acefa..959835d69af6 100644
> --- a/drivers/net/dsa/mv88e6352.c
> +++ b/drivers/net/dsa/mv88e6352.c
> @@ -38,7 +38,9 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
>  
>  static char *mv88e6352_drv_probe(struct device *host_dev, int sw_addr)
>  {
> -	return mv88e6xxx_lookup_name(host_dev, sw_addr, mv88e6352_table,
> +	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
> +
> +	return mv88e6xxx_lookup_name(bus, sw_addr, mv88e6352_table,
>  				     ARRAY_SIZE(mv88e6352_table));
>  }
>  
> diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
> index 170b98f3acbe..23b0ff9f0154 100644
> --- a/drivers/net/dsa/mv88e6xxx.c
> +++ b/drivers/net/dsa/mv88e6xxx.c
> @@ -2606,16 +2606,12 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
>  }
>  #endif /* CONFIG_NET_DSA_HWMON */
>  
> -char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
> +char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
>  			    const struct mv88e6xxx_switch_id *table,
>  			    unsigned int num)
>  {
> -	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
>  	int i, ret;
>  
> -	if (!bus)
> -		return NULL;
> -
>  	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
>  	if (ret < 0)
>  		return NULL;

The check for !bus is removed and thus the underlying calls to
mdiobus_read_nested can segfault.

> @@ -2628,7 +2624,8 @@ char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
>  	/* Look up only the product number */
>  	for (i = 0; i < num; ++i) {
>  		if (table[i].id == (ret & PORT_SWITCH_ID_PROD_NUM_MASK)) {
> -			dev_warn(host_dev, "unknown revision %d, using base switch 0x%x\n",
> +			dev_warn(&bus->dev,
> +				 "unknown revision %d, using base switch 0x%x\n",

Does checkpatch complains about that? I thought it was OK to have
strings exceeding 80 chars.

>  				 ret & PORT_SWITCH_ID_REV_MASK,
>  				 ret & PORT_SWITCH_ID_PROD_NUM_MASK);
>  			return table[i].name;
> diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
> index 62069b30f6e5..441aec066294 100644
> --- a/drivers/net/dsa/mv88e6xxx.h
> +++ b/drivers/net/dsa/mv88e6xxx.h
> @@ -436,7 +436,7 @@ struct mv88e6xxx_hw_stat {
>  };
>  
>  int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
> -char *mv88e6xxx_lookup_name(struct device *host_dev, int sw_addr,
> +char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
>  			    const struct mv88e6xxx_switch_id *table,
>  			    unsigned int num);
>  int mv88e6xxx_setup_ports(struct dsa_switch *ds);
> -- 
> 2.6.3

Thanks,
-v

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

* Re: [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches
  2015-12-23 12:56 ` [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches Andrew Lunn
@ 2016-01-21 21:05   ` Vivien Didelot
  0 siblings, 0 replies; 60+ messages in thread
From: Vivien Didelot @ 2016-01-21 21:05 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, narmstrong; +Cc: netdev, Andrew Lunn

Hi Andrew,

Just a single nitpick below.

Andrew Lunn <andrew@lunn.ch> writes:

<snip>

> diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
> index 02810a50825b..41472dc409ce 100644
> --- a/drivers/net/dsa/mv88e6060.c
> +++ b/drivers/net/dsa/mv88e6060.c
> @@ -1,6 +1,7 @@
>  /*
>   * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
>   * Copyright (c) 2008-2009 Marvell Semiconductor
> + * Copywrite (c) 2015 Andrew Lunn <andrew@lunn.ch>

      Copyright ;-)
      
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by

<snip>

Thanks,
-v

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

* Re: [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules
  2015-12-25 21:47   ` Florian Fainelli
@ 2016-01-21 21:29     ` Vivien Didelot
  2016-01-21 21:54       ` Andrew Lunn
  0 siblings, 1 reply; 60+ messages in thread
From: Vivien Didelot @ 2016-01-21 21:29 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, narmstrong; +Cc: netdev

Hi Andrew, Florian,

Florian Fainelli <f.fainelli@gmail.com> writes:

> Le 23/12/2015 04:56, Andrew Lunn a écrit :
>> Turn mv88e6xxx into a library module, by exporting its symbols.  Have
>> each driver register their own driver functions with the DSA core in
>> there init function.
>> 
>> This results in each driver being a loadable module.
>> 
>> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
>> ---
>
> [snip]
>
>> +obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
>> +obj-$(CONFIGNET_DSA_MV88E6131)  += mv88e6123.o
>
> Missing underscore here between CONFIG and NET.
>
>> +obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
>> +obj-$(CONFIG_NET_DSA_MV88E6352) += mv88e6352.o
>> +obj-$(CONFIG_NET_DSA_MV88E6171) += mv88e6171.o
>>  obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
>> diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
>> index bb39720f3e8b..9680e59fd2ae 100644
>> --- a/drivers/net/dsa/mv88e6123.c
>> +++ b/drivers/net/dsa/mv88e6123.c
>> @@ -167,7 +167,21 @@ static struct platform_driver mv88e6123_driver = {
>>  		.of_match_table = mv88e6123_of_match,
>>  	},
>>  };
>> -module_platform_driver(mv88e6123_driver);
>>  
>> +static int __init mv88e6123_init(void)
>> +{
>> +	register_switch_driver(&mv88e6123_switch_driver);
>> +
>> +	return platform_driver_register(&mv88e6123_driver);
>> +}
>> +
>> +static void __exit mv88e6123_exit(void)
>> +{
>> +	platform_driver_unregister(&mv88e6123_driver);
>> +	unregister_switch_driver(&mv88e6123_switch_driver);
>> +}
>
> I think Vivien had started something like this, but it could be nice to
> have a helper function/macro which reduces the boilerplate code, not
> critical for now though.

Indeed I did suggest this macro and exporting in the past, without
success though:

    https://lkml.org/lkml/2015/5/2/152

Maybe the other approach with a reference driver (e.g. mv88e6352.c)
declaring a table of supported switch names is more natural?

Most Linux drivers factorize the support for similar devices this way
(e.g. lm75, ...).

Thanks,
-v

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

* Re: [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules
  2016-01-21 21:29     ` Vivien Didelot
@ 2016-01-21 21:54       ` Andrew Lunn
  0 siblings, 0 replies; 60+ messages in thread
From: Andrew Lunn @ 2016-01-21 21:54 UTC (permalink / raw)
  To: Vivien Didelot; +Cc: Florian Fainelli, narmstrong, netdev

> >> -module_platform_driver(mv88e6123_driver);
> >>  
> >> +static int __init mv88e6123_init(void)
> >> +{
> >> +	register_switch_driver(&mv88e6123_switch_driver);
> >> +
> >> +	return platform_driver_register(&mv88e6123_driver);
> >> +}
> >> +
> >> +static void __exit mv88e6123_exit(void)
> >> +{
> >> +	platform_driver_unregister(&mv88e6123_driver);
> >> +	unregister_switch_driver(&mv88e6123_switch_driver);
> >> +}
> >
> > I think Vivien had started something like this, but it could be nice to
> > have a helper function/macro which reduces the boilerplate code, not
> > critical for now though.
> 
> Indeed I did suggest this macro and exporting in the past, without
> success though:
> 
>     https://lkml.org/lkml/2015/5/2/152

My reworked patchset uses macros. I also had to change the order of
some of these patches. Otherwise i had modules with two init and exit
functions!

	Andrew

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

end of thread, other threads:[~2016-01-21 21:54 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-23 12:56 [PATCH RFC 00/28] DSA: Restructure probing Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 01/28] component: remove old add_components method Andrew Lunn
2015-12-23 13:21   ` Russell King - ARM Linux
2015-12-23 15:57     ` Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 02/28] ARM: VF610: Add Zodiac Inflight Innovations development boards Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 03/28] net: dsa: Move platform data allocation for OF Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 04/28] dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 05/28] net: dsa: Pass the dsa device to the switch drivers Andrew Lunn
2015-12-23 20:36   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 06/28] net: dsa: Have the switch driver allocate there own private memory Andrew Lunn
2015-12-23 20:39   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 07/28] net: dsa: Remove allocation of driver " Andrew Lunn
2015-12-23 20:39   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 08/28] net: dsa: Keep the mii bus and address in the private structure Andrew Lunn
2015-12-23 20:40   ` Florian Fainelli
2016-01-21 20:41   ` Vivien Didelot
2016-01-21 20:50     ` Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 09/28] net: dsa: Add basic support for component master support Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 10/28] net: dsa: Keep a reference to the switch device for component matching Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 11/28] net: dsa: Add slave component matches based on a phandle to the slave Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 12/28] net: dsa: Make dsa,mii-bus optional Andrew Lunn
2015-12-23 20:42   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 13/28] net: dsa: Add register/unregister functions for switch drivers Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 14/28] net: dsa: Rename DSA probe function Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 15/28] of_mdio: Add "mii-bus" and address property parser Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 16/28] dsa: mv88e6xxx: Use bus in mv88e6xxx_lookup_name() Andrew Lunn
2016-01-21 20:54   ` Vivien Didelot
2015-12-23 12:56 ` [PATCH RFC 17/28] dsa: mv88e6xxx: Add shared code for binding/unbinding a switch driver Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 18/28] dsa: Add platform device support to Marvell switches Andrew Lunn
2016-01-21 21:05   ` Vivien Didelot
2015-12-23 12:56 ` [PATCH RFC 19/28] net: dsa: bcm_sf2: make it a real platform driver Andrew Lunn
2015-12-23 20:32   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 20/28] vf610: Zii: Convert rev b to switches as individual devices Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 21/28] net: dsa: Add some debug prints for error cases Andrew Lunn
2015-12-23 20:42   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 22/28] net: dsa: Setup the switches after all have been probed Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 23/28] net: dsa: Only setup platform switches, not device switches Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 24/28] net: dsa: If a switch fails to probe, defer probing Andrew Lunn
2015-12-23 20:46   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 25/28] Documentation: DSA: Describe how probe of DSA and switches work Andrew Lunn
2015-12-23 20:48   ` Florian Fainelli
2015-12-23 22:53     ` Andrew Lunn
2015-12-25  1:29       ` Florian Fainelli
2015-12-25 10:00         ` Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 26/28] dsa: Convert mv88e6xxx into a library allowing driver modules Andrew Lunn
2015-12-25 21:47   ` Florian Fainelli
2016-01-21 21:29     ` Vivien Didelot
2016-01-21 21:54       ` Andrew Lunn
2015-12-23 12:56 ` [PATCH RFC 27/28] dsa: slave: Don't reference NULL pointer during phy_disconnect Andrew Lunn
2015-12-23 20:45   ` Florian Fainelli
2015-12-23 12:56 ` [PATCH RFC 28/28] dsa: Destroy fixed link phys after the phy has been disconnected Andrew Lunn
2015-12-23 20:45   ` Florian Fainelli
2015-12-23 20:44 ` [PATCH RFC 00/28] DSA: Restructure probing Florian Fainelli
2015-12-23 22:33   ` Andrew Lunn
2015-12-23 23:13     ` Florian Fainelli
2015-12-24 12:58       ` Andrew Lunn
2015-12-25  1:47         ` Florian Fainelli
2015-12-25 11:31           ` Andrew Lunn
2015-12-25 22:00             ` Florian Fainelli
2015-12-25 23:41               ` Andrew Lunn

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