summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-01-05 12:08:19 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-01-05 12:08:19 +0100
commitcdd3ad8795af8d2b9384b5c2919cef9365749520 (patch)
tree08c26c8881a24b297aee41a0fc2911c4a0c3b849
parent10b25c12c2b2afa6fea0959596f7341d30b196cf (diff)
parent9e34d2ee095eef72abda98af486b2c26020a9622 (diff)
downloadbarebox-cdd3ad8795af8d2b9384b5c2919cef9365749520.tar.gz
barebox-cdd3ad8795af8d2b9384b5c2919cef9365749520.tar.xz
Merge branch 'for-next/mii'
-rw-r--r--arch/arm/configs/zii_vf610_dev_defconfig1
-rw-r--r--arch/arm/dts/vf610-zii-cfu1-rev-a.dts3
-rw-r--r--arch/arm/dts/vf610-zii-dev-rev-b.dts386
-rw-r--r--arch/arm/dts/vf610-zii-dev-rev-c.dts391
-rw-r--r--arch/arm/dts/vf610-zii-dev.dtsi354
-rw-r--r--arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts2
-rw-r--r--arch/arm/dts/vf610-zii-spu3-rev-a.dts4
-rw-r--r--arch/arm/mach-imx/imx-bbu-internal.c3
-rw-r--r--commands/miitool.c9
-rw-r--r--drivers/net/phy/Kconfig18
-rw-r--r--drivers/net/phy/Makefile3
-rw-r--r--drivers/net/phy/mdio-mux-gpio.c147
-rw-r--r--drivers/net/phy/mdio-mux.c143
-rw-r--r--drivers/net/phy/mdio_bus.c30
-rw-r--r--include/fs.h9
-rw-r--r--include/linux/mdio-mux.h30
-rw-r--r--include/linux/phy.h4
17 files changed, 401 insertions, 1136 deletions
diff --git a/arch/arm/configs/zii_vf610_dev_defconfig b/arch/arm/configs/zii_vf610_dev_defconfig
index e2cb658d9c..ee77f40002 100644
--- a/arch/arm/configs/zii_vf610_dev_defconfig
+++ b/arch/arm/configs/zii_vf610_dev_defconfig
@@ -92,6 +92,7 @@ CONFIG_LM75=y
CONFIG_DRIVER_NET_FEC_IMX=y
CONFIG_MARVELL_PHY=y
CONFIG_MICREL_PHY=y
+CONFIG_MDIO_BUS_MUX_GPIO=y
CONFIG_NET_USB=y
CONFIG_NET_USB_ASIX=y
CONFIG_NET_USB_SMSC95XX=y
diff --git a/arch/arm/dts/vf610-zii-cfu1-rev-a.dts b/arch/arm/dts/vf610-zii-cfu1-rev-a.dts
index 4147d138bc..7e87a15c11 100644
--- a/arch/arm/dts/vf610-zii-cfu1-rev-a.dts
+++ b/arch/arm/dts/vf610-zii-cfu1-rev-a.dts
@@ -42,9 +42,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+/dts-v1/;
+#include <arm/vf610-zii-dev.dtsi>
-/dts-v1/;
#include "vf610-zii-dev.dtsi"
/ {
diff --git a/arch/arm/dts/vf610-zii-dev-rev-b.dts b/arch/arm/dts/vf610-zii-dev-rev-b.dts
index bf0a01021e..1eb01f44a7 100644
--- a/arch/arm/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/dts/vf610-zii-dev-rev-b.dts
@@ -42,390 +42,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/dts-v1/;
+#include <arm/vf610-zii-dev-rev-b.dts>
#include "vf610-zii-dev.dtsi"
-
-/*
- * =============================================================
- * The following code is shared with Linux kernel and should be
- * removed once it trickles down from there eventually
- * =============================================================
- */
-
-/ {
- model = "ZII VF610 Development Board, Rev B";
- compatible = "zii,vf610dev-b", "zii,vf610dev", "fsl,vf610";
-
- 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>;
-
- switch0: switch0@0 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- dsa,member = <0 0>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
- 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>;
- };
-
- port@6 {
- reg = <6>;
- label = "cpu";
- ethernet = <&fec1>;
- fixed-link {
- speed = <100>;
- full-duplex;
- };
- };
- };
- };
- };
-
- mdio_mux_2: mdio@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch1: switch1@0 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- dsa,member = <0 1>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
- port@0 {
- reg = <0>;
- label = "lan3";
- phy-handle = <&switch1phy0>;
- };
-
- port@1 {
- reg = <1>;
- label = "lan4";
- phy-handle = <&switch1phy1>;
- };
-
- port@2 {
- reg = <2>;
- label = "lan5";
- phy-handle = <&switch1phy2>;
- };
-
- 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>;
- };
- };
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- switch1phy0: switch1phy0@0 {
- reg = <0>;
- };
- switch1phy1: switch1phy0@1 {
- reg = <1>;
- };
- switch1phy2: switch1phy0@2 {
- reg = <2>;
- };
- };
- };
- };
-
- mdio_mux_4: mdio@4 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4>;
-
- switch2: switch2@0 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- dsa,member = <0 2>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
- 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;
- };
- };
- };
- };
- };
-
- mdio_mux_8: mdio@8 {
- reg = <8>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-
- spi0 {
- compatible = "spi-gpio";
- pinctrl-0 = <&pinctrl_gpio_spi0>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>;
- gpio-mosi = <&gpio1 11 GPIO_ACTIVE_HIGH>;
- gpio-miso = <&gpio1 10 GPIO_ACTIVE_HIGH>;
- cs-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH
- &gpio1 8 GPIO_ACTIVE_HIGH>;
- num-chipselects = <2>;
-
- m25p128@0 {
- compatible = "m25p128", "jedec,spi-nor";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0>;
- spi-max-frequency = <1000000>;
- };
-
- at93c46d@1 {
- compatible = "atmel,at93c46d";
- pinctrl-0 = <&pinctrl_gpio_e6185_eeprom_sel>;
- pinctrl-names = "default";
- #address-cells = <0>;
- #size-cells = <0>;
- reg = <1>;
- spi-max-frequency = <500000>;
- spi-cs-high;
- data-size = <16>;
- select-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
- };
- };
-};
-
-&i2c0 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- status = "okay";
-
- gpio5: pca9554@20 {
- compatible = "nxp,pca9554";
- reg = <0x20>;
- gpio-controller;
- #gpio-cells = <2>;
-
- };
-
- gpio6: pca9554@22 {
- compatible = "nxp,pca9554";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pca9554_22>;
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-parent = <&gpio2>;
- interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
- };
-};
-
-&i2c2 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- status = "okay";
-
- tca9548@70 {
- compatible = "nxp,pca9548";
- pinctrl-0 = <&pinctrl_i2c_mux_reset>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x70>;
- reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- sfp1: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- sfp2: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
-
- sfp3: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
-
- sfp4: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@4 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4>;
- };
- };
-};
-
-
-&iomuxc {
- pinctrl_gpio_e6185_eeprom_sel: pinctrl-gpio-e6185-eeprom-spi0 {
- fsl,pins = <
- VF610_PAD_PTE27__GPIO_132 0x33e2
- >;
- };
-
- pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
- fsl,pins = <
- VF610_PAD_PTB22__GPIO_44 0x33e2
- VF610_PAD_PTB21__GPIO_43 0x33e2
- VF610_PAD_PTB20__GPIO_42 0x33e1
- VF610_PAD_PTB19__GPIO_41 0x33e2
- VF610_PAD_PTB18__GPIO_40 0x33e2
- >;
- };
-
- 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_pca9554_22: pinctrl-pca95540-22 {
- fsl,pins = <
- VF610_PAD_PTB28__GPIO_98 0x219d
- >;
- };
-};
-
-/*
- * =============================================================
- * End of shared part
- * =============================================================
-*/
diff --git a/arch/arm/dts/vf610-zii-dev-rev-c.dts b/arch/arm/dts/vf610-zii-dev-rev-c.dts
index 5228942632..797b31bef9 100644
--- a/arch/arm/dts/vf610-zii-dev-rev-c.dts
+++ b/arch/arm/dts/vf610-zii-dev-rev-c.dts
@@ -42,399 +42,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/dts-v1/;
+#include <arm/vf610-zii-dev-rev-c.dts>
#include "vf610-zii-dev.dtsi"
-/*
- * =============================================================
- * The following code is shared with Linux kernel and should be
- * removed once it trickles down from there eventually
- * =============================================================
- */
-
-/ {
- model = "ZII VF610 Development Board, Rev C";
- compatible = "zii,vf610dev-c", "zii,vf610dev", "fsl,vf610";
-
- 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 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>;
-
- switch0: switch0@0 {
- compatible = "marvell,mv88e6190";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- dsa,member = <0 0>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "cpu";
- ethernet = <&fec1>;
- fixed-link {
- speed = <100>;
- full-duplex;
- };
- };
-
- port@1 {
- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
- reg = <3>;
- label = "lan3";
- };
-
- port@4 {
- reg = <4>;
- label = "lan4";
- };
-
- switch0port10: port@10 {
- reg = <10>;
- label = "dsa";
- phy-mode = "xgmii";
- link = <&switch1port10>;
- };
- };
- };
- };
-
- mdio_mux_2: mdio@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch1: switch1@0 {
- compatible = "marvell,mv88e6190";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- dsa,member = <0 1>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
- label = "lan5";
- };
-
- port@2 {
- reg = <2>;
- label = "lan6";
- };
-
- port@3 {
- reg = <3>;
- label = "lan7";
- };
-
- port@4 {
- reg = <4>;
- label = "lan8";
- };
-
-
- switch1port10: port@10 {
- reg = <10>;
- label = "dsa";
- phy-mode = "xgmii";
- link = <&switch0port10>;
- };
- };
- };
- };
-
- mdio_mux_4: mdio@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-&dspi0 {
- bus-num = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_dspi0>;
- status = "okay";
- spi-num-chipselects = <2>;
-
- m25p128@0 {
- compatible = "m25p128", "jedec,spi-nor";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0>;
- spi-max-frequency = <50000000>;
- };
-
- atzb-rf-233@1 {
- compatible = "atmel,at86rf233";
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctr_atzb_rf_233>;
-
- spi-max-frequency = <7500000>;
- reg = <1>;
- interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-parent = <&gpio3>;
- xtal-trim = /bits/ 8 <0x06>;
-
- sleep-gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
- reset-gpio = <&gpio6 10 GPIO_ACTIVE_HIGH>;
-
- fsl,spi-cs-sck-delay = <180>;
- fsl,spi-sck-cs-delay = <250>;
- };
-};
-
-&dspi2 {
- bus-num = <2>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_dspi2>;
- status = "okay";
- spi-num-chipselects = <2>;
-};
-
-&i2c0 {
- /*
- * U712
- *
- * Exposed signals:
- * P1 - WE2_CMD
- * P2 - WE2_CLK
- */
- gpio5: pca9557@18 {
- compatible = "nxp,pca9557";
- reg = <0x18>;
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- /*
- * U121
- *
- * Exposed signals:
- * I/O0 - ENET_SWR_EN
- * I/O1 - ESW1_RESETn
- * I/O2 - ARINC_RESET
- * I/O3 - DD1_IO_RESET
- * I/O4 - ESW2_RESETn
- * I/O5 - ESW3_RESETn
- * I/O6 - ESW4_RESETn
- * I/O8 - TP909
- * I/O9 - FEM_SEL
- * I/O10 - WIFI_RESETn
- * I/O11 - PHY_RSTn
- * I/O12 - OPT1_SD
- * I/O13 - OPT2_SD
- * I/O14 - OPT1_TX_DIS
- * I/O15 - OPT2_TX_DIS
- */
- gpio6: sx1503@20 {
- compatible = "semtech,sx1503q";
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sx1503_20>;
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- reg = <0x20>;
- interrupt-parent = <&gpio0>;
- interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
- gpio-controller;
- interrupt-controller;
-
- enet_swr_en {
- gpio-hog;
- gpios = <0 GPIO_ACTIVE_HIGH>;
- output-high;
- line-name = "enet-swr-en";
- };
- };
-
- /*
- * U715
- *
- * Exposed signals:
- * IO0 - WE1_CLK
- * IO1 - WE1_CMD
- */
- gpio7: pca9554@22 {
- compatible = "nxp,pca9554";
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
-
- };
-};
-
-&i2c1 {
- at24mac602@00 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- read-only;
- };
-};
-
-&i2c2 {
- tca9548@70 {
- compatible = "nxp,pca9548";
- pinctrl-0 = <&pinctrl_i2c_mux_reset>;
- pinctrl-names = "default";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x70>;
- reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- };
-
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- sfp2: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
-
- sfp3: at24c04@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
- };
-
- i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
- };
-};
-
-&uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- status = "okay";
-};
-
-&gpio0 {
- eth0_intrp {
- gpio-hog;
- gpios = <23 GPIO_ACTIVE_HIGH>;
- input;
- line-name = "sx1503-irq";
- };
-};
-
-&gpio3 {
- eth0_intrp {
- gpio-hog;
- gpios = <2 GPIO_ACTIVE_HIGH>;
- input;
- line-name = "eth0-intrp";
- };
-};
-
-&fec0 {
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- ethernet-phy@0 {
- compatible = "ethernet-phy-ieee802.3-c22";
-
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_fec0_phy_int>;
-
- interrupt-parent = <&gpio3>;
- interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
- reg = <0>;
- };
- };
-};
-
-&iomuxc {
- pinctr_atzb_rf_233: pinctrl-atzb-rf-233 {
- fsl,pins = <
- VF610_PAD_PTB2__GPIO_24 0x31c2
- VF610_PAD_PTE27__GPIO_132 0x33e2
- >;
- };
-
-
- pinctrl_sx1503_20: pinctrl-sx1503-20 {
- fsl,pins = <
- VF610_PAD_PTB1__GPIO_23 0x219d
- >;
- };
-
- pinctrl_uart3: uart3grp {
- fsl,pins = <
- VF610_PAD_PTA20__UART3_TX 0x21a2
- VF610_PAD_PTA21__UART3_RX 0x21a1
- >;
- };
-
- pinctrl_mdio_mux: pinctrl-mdio-mux {
- fsl,pins = <
- VF610_PAD_PTA18__GPIO_8 0x31c2
- VF610_PAD_PTA19__GPIO_9 0x31c2
- VF610_PAD_PTB3__GPIO_25 0x31c2
- >;
- };
-
- pinctrl_fec0_phy_int: pinctrl-fec0-phy-int {
- fsl,pins = <
- VF610_PAD_PTB28__GPIO_98 0x219d
- >;
- };
-};
-
-/*
- * =============================================================
- * End of shared part
- * =============================================================
- */
-
-
&dspi0 {
m25p128@0 {
partition@0 {
diff --git a/arch/arm/dts/vf610-zii-dev.dtsi b/arch/arm/dts/vf610-zii-dev.dtsi
index dae077cedb..4bf81451a6 100644
--- a/arch/arm/dts/vf610-zii-dev.dtsi
+++ b/arch/arm/dts/vf610-zii-dev.dtsi
@@ -42,360 +42,6 @@ n * copy, modify, merge, publish, distribute, sublicense, and/or
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
-/*
- * =============================================================
- * The following code is shared with Linux kernel and should be
- * removed once it trickles down from there eventually
- * =============================================================
- */
-
-#include <arm/vf610.dtsi>
-
-/ {
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory {
- reg = <0x80000000 0x20000000>;
- };
-
- gpio-leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&pinctrl_leds_debug>;
- pinctrl-names = "default";
-
- debug {
- label = "zii:green:debug1";
- gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "heartbeat";
- };
- };
-
- reg_vcc_3v3_mcu: regulator-vcc-3v3-mcu {
- compatible = "regulator-fixed";
- regulator-name = "vcc_3v3_mcu";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- usb0_vbus: regulator-usb0-vbus {
- compatible = "regulator-fixed";
- pinctrl-0 = <&pinctrl_usb_vbus>;
- 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";
-};
-
-&fec0 {
- phy-mode = "rmii";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_fec0>;
- 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", "gpio";
- pinctrl-0 = <&pinctrl_i2c0>;
- pinctrl-1 = <&pinctrl_i2c0_gpio>;
- scl-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
- sda-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
- status = "okay";
-
- 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";
-};
-
-&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;
- vbus-supply = <&usb0_vbus>;
- dr_mode = "host";
- status = "okay";
-};
-
-&usbh1 {
- disable-over-current;
- status = "okay";
-};
-
-&usbmisc0 {
- status = "okay";
-};
-
-&usbmisc1 {
- status = "okay";
-};
-
-&usbphy0 {
- status = "okay";
-};
-
-&usbphy1 {
- status = "okay";
-};
-
-&iomuxc {
- pinctrl_adc0_ad5: adc0ad5grp {
- fsl,pins = <
- VF610_PAD_PTC30__ADC0_SE5 0x00a1
- >;
- };
-
- pinctrl_dspi0: dspi0grp {
- fsl,pins = <
- VF610_PAD_PTB18__DSPI0_CS1 0x1182
- VF610_PAD_PTB19__DSPI0_CS0 0x1182
- VF610_PAD_PTB20__DSPI0_SIN 0x1181
- VF610_PAD_PTB21__DSPI0_SOUT 0x1182
- VF610_PAD_PTB22__DSPI0_SCK 0x1182
- >;
- };
-
- pinctrl_dspi2: dspi2grp {
- fsl,pins = <
- VF610_PAD_PTD31__DSPI2_CS1 0x1182
- VF610_PAD_PTD30__DSPI2_CS0 0x1182
- VF610_PAD_PTD29__DSPI2_SIN 0x1181
- VF610_PAD_PTD28__DSPI2_SOUT 0x1182
- VF610_PAD_PTD27__DSPI2_SCK 0x1182
- >;
- };
-
- 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_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_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
- >;
- };
-
- pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
- fsl,pins = <
- VF610_PAD_PTB22__GPIO_44 0x33e2
- VF610_PAD_PTB21__GPIO_43 0x33e2
- VF610_PAD_PTB20__GPIO_42 0x33e1
- VF610_PAD_PTB19__GPIO_41 0x33e2
- VF610_PAD_PTB18__GPIO_40 0x33e2
- >;
- };
-
- pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
- fsl,pins = <
- VF610_PAD_PTE14__GPIO_119 0x31c2
- >;
- };
-
- pinctrl_i2c0: i2c0grp {
- fsl,pins = <
- VF610_PAD_PTB14__I2C0_SCL 0x37ff
- VF610_PAD_PTB15__I2C0_SDA 0x37ff
- >;
- };
-
- pinctrl_i2c0_gpio: i2c0grp-gpio {
- fsl,pins = <
- VF610_PAD_PTB14__GPIO_36 0x31c2
- VF610_PAD_PTB15__GPIO_37 0x31c2
- >;
- };
-
-
- 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_leds_debug: pinctrl-leds-debug {
- fsl,pins = <
- VF610_PAD_PTD20__GPIO_74 0x31c2
- >;
- };
-
- 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_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_usb_vbus: pinctrl-usb-vbus {
- fsl,pins = <
- VF610_PAD_PTA16__GPIO_6 0x31c2
- >;
- };
-
- pinctrl_usb0_host: usb0-host-grp {
- fsl,pins = <
- VF610_PAD_PTD6__GPIO_85 0x0062
- >;
- };
-};
-
-/*
- * =============================================================
- * End of shared part
- * =============================================================
- */
-
/ {
audio_ext: mclk_osc {
compatible = "fixed-clock";
diff --git a/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts b/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts
index d10f460e32..12c2568bcc 100644
--- a/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts
+++ b/arch/arm/dts/vf610-zii-scu4-aib-rev-c.dts
@@ -44,6 +44,8 @@
/dts-v1/;
+#include <arm/vf610-zii-dev.dtsi>
+
#include "vf610-zii-dev.dtsi"
/ {
diff --git a/arch/arm/dts/vf610-zii-spu3-rev-a.dts b/arch/arm/dts/vf610-zii-spu3-rev-a.dts
index 25ab26ddfd..f362e7f0b9 100644
--- a/arch/arm/dts/vf610-zii-spu3-rev-a.dts
+++ b/arch/arm/dts/vf610-zii-spu3-rev-a.dts
@@ -43,8 +43,10 @@
*/
/dts-v1/;
-#include "vf610-zii-dev.dtsi"
+#include <arm/vf610-zii-dev.dtsi>
+
+#include "vf610-zii-dev.dtsi"
/ {
model = "ZII VF610 SPU3 Switch Management Board";
diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c
index c6f5e14511..5783da6102 100644
--- a/arch/arm/mach-imx/imx-bbu-internal.c
+++ b/arch/arm/mach-imx/imx-bbu-internal.c
@@ -133,8 +133,7 @@ static int imx_bbu_check_prereq(const char *devicefile, struct bbu_data *data)
if (ret)
return ret;
- if (!strncmp(devicefile, "/dev/", 5))
- device_detect_by_name(devicefile + 5);
+ device_detect_by_name(devpath_to_name(devicefile));
return 0;
}
diff --git a/commands/miitool.c b/commands/miitool.c
index 07bce18651..dea4f853ce 100644
--- a/commands/miitool.c
+++ b/commands/miitool.c
@@ -225,7 +225,8 @@ static int show_basic_mii(struct mii_bus *mii, struct phy_device *phydev,
return 0;
}
-static void mdiobus_show(struct device_d *dev, char *phydevname, int verbose)
+static void mdiobus_show(struct device_d *dev, const char *phydevname,
+ int verbose)
{
struct mii_bus *mii = to_mii_bus(dev);
int i;
@@ -337,7 +338,9 @@ static int do_miitool(int argc, char *argv[])
case MIITOOL_SHOW:
for_each_mii_bus(mii) {
mdiobus_detect(&mii->dev);
- mdiobus_show(&mii->dev, phydevname, verbose);
+ mdiobus_show(&mii->dev,
+ devpath_to_name(phydevname),
+ verbose);
}
break;
}
@@ -357,7 +360,7 @@ BAREBOX_CMD_HELP_TEXT("adapters use an MII to autonegotiate link speed and duple
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT("-v", "increase verbosity")
-BAREBOX_CMD_HELP_OPT("-s <devname>", "show PHY status (not providing PHY prints status of all)")
+BAREBOX_CMD_HELP_OPT("-s <devpath/devname>", "show PHY status (not providing PHY prints status of all)")
BAREBOX_CMD_HELP_OPT("-r <busno>:<adr>", "register a PHY")
BAREBOX_CMD_HELP_END
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ea2e062656..cda752b659 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -66,6 +66,24 @@ config MDIO_GPIO
---help---
Supports GPIO lib-based MDIO busses.
+config MDIO_BUS_MUX
+ bool
+ help
+ This module provides a driver framework for MDIO bus
+ multiplexers which connect one of several child MDIO busses
+ to a parent bus. Switching between child busses is done by
+ device specific drivers.
+
+config MDIO_BUS_MUX_GPIO
+ bool "GPIO controlled MDIO bus multiplexers"
+ depends on OF_GPIO
+ select MDIO_BUS_MUX
+ help
+ This module provides a driver for MDIO bus multiplexers that
+ are controlled via GPIO lines. The multiplexer connects one of
+ several child MDIO busses to a parent bus. Child bus
+ selection is under the control of GPIO lines.
+
endif
endmenu
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 13b8f6545d..30b20f8ee6 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -10,3 +10,6 @@ obj-$(CONFIG_SMSC_PHY) += smsc.o
obj-$(CONFIG_MDIO_MVEBU) += mdio-mvebu.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
+obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o
+obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o
+
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
new file mode 100644
index 0000000000..221353cbcb
--- /dev/null
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2017 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * Based on analogous code from Linux kernel
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <linux/mdio-mux.h>
+#include <gpio.h>
+#include <of_gpio.h>
+
+
+struct mdio_mux_gpio_state {
+ struct gpio *gpios;
+ int gpios_num;
+};
+
+static void mdio_mux_gpio_set_active(struct mdio_mux_gpio_state *s,
+ unsigned int mask, int value)
+{
+ while (mask) {
+ const int n = __ffs(mask);
+ mask >>= n + 1;
+
+ if (WARN_ON(n >= s->gpios_num))
+ break;
+
+ gpio_set_active(s->gpios[n].gpio, value);
+ }
+}
+
+static int mdio_mux_gpio_switch_fn(int current_child, int desired_child,
+ void *data)
+{
+ if (current_child < 0)
+ current_child = 0;
+
+ if (current_child != desired_child) {
+ struct mdio_mux_gpio_state *s = data;
+ /*
+ * GPIOs that are set in both current and desired
+ * states can be left untouched. So we calculate them
+ * and clear corresponding bits in both states.
+ */
+ const int unchanged = current_child & desired_child;
+
+ current_child &= ~unchanged;
+ desired_child &= ~unchanged;
+
+ /*
+ * First step: disable all of the currently selected
+ * bits that are no loger needed
+ */
+ mdio_mux_gpio_set_active(s, current_child, 0);
+ /*
+ * Second step: enable all of the GPIOs that are
+ * desired to be selected
+ */
+ mdio_mux_gpio_set_active(s, desired_child, 1);
+ }
+
+ return 0;
+}
+
+static int mdio_mux_gpio_probe(struct device_d *dev)
+{
+ struct mdio_mux_gpio_state *s;
+ int i, r;
+
+ s = xzalloc(sizeof(*s));
+
+ s->gpios_num = of_gpio_count(dev->device_node);
+ if (s->gpios_num <= 0) {
+ dev_err(dev, "No GPIOs specified\n");
+ r = -EINVAL;
+ goto free_mem;
+ }
+
+ s->gpios = xzalloc(s->gpios_num * sizeof(s->gpios[0]));
+
+ for (i = 0; i < s->gpios_num; i++) {
+ enum of_gpio_flags flags;
+
+ r = of_get_gpio_flags(dev->device_node, i, &flags);
+ if (!gpio_is_valid(r)) {
+ r = (r < 0) ? r : -EINVAL;
+ goto free_mem;
+ }
+
+ s->gpios[i].gpio = r;
+ s->gpios[i].label = dev_name(dev);
+ s->gpios[i].flags = GPIOF_OUT_INIT_INACTIVE;
+
+ if (flags & OF_GPIO_ACTIVE_LOW)
+ s->gpios[i].flags |= GPIOF_ACTIVE_LOW;
+ }
+
+ r = gpio_request_array(s->gpios, s->gpios_num);
+ if (r < 0)
+ goto free_gpios;
+
+
+ r = mdio_mux_init(dev, dev->device_node,
+ mdio_mux_gpio_switch_fn, s, NULL);
+ if (r < 0)
+ goto free_gpios;
+
+ return 0;
+
+free_gpios:
+ gpio_free_array(s->gpios, s->gpios_num);
+free_mem:
+ free(s->gpios);
+ free(s);
+ return r;
+}
+
+static const struct of_device_id mdio_mux_gpio_match[] = {
+ {
+ .compatible = "mdio-mux-gpio",
+ },
+ {},
+};
+
+static struct driver_d mdio_mux_gpio_driver = {
+ .name = "mdio-mux-gpio",
+ .probe = mdio_mux_gpio_probe,
+ .of_compatible = mdio_mux_gpio_match,
+};
+device_platform_driver(mdio_mux_gpio_driver);
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
new file mode 100644
index 0000000000..1f57d86c6f
--- /dev/null
+++ b/drivers/net/phy/mdio-mux.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2017 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * Based on analogous code from Linux kernel
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <linux/mdio-mux.h>
+#include <linux/phy.h>
+
+struct mdio_mux_parent_bus {
+ struct mii_bus *mii_bus;
+ int current_child;
+ int parent_id;
+ void *switch_data;
+ int (*switch_fn)(int current_child, int desired_child, void *data);
+};
+
+struct mdio_mux_child_bus {
+ struct mii_bus mii_bus;
+ struct mdio_mux_parent_bus *parent;
+ struct mdio_mux_child_bus *next;
+ int bus_number;
+};
+
+static int mdio_mux_read_or_write(struct mii_bus *bus, int phy_id,
+ int regnum, u16 *val)
+{
+ struct mdio_mux_child_bus *cb = bus->priv;
+ struct mdio_mux_parent_bus *pb = cb->parent;
+ int r;
+
+ r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
+ if (!r) {
+ pb->current_child = cb->bus_number;
+ if (val)
+ r = pb->mii_bus->write(pb->mii_bus, phy_id,
+ regnum, *val);
+ else
+ r = pb->mii_bus->read(pb->mii_bus, phy_id,
+ regnum);
+ }
+ return r;
+}
+
+static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+ return mdio_mux_read_or_write(bus, phy_id, regnum, NULL);
+}
+
+static int mdio_mux_write(struct mii_bus *bus, int phy_id,
+ int regnum, u16 val)
+{
+ return mdio_mux_read_or_write(bus, phy_id, regnum, &val);
+}
+
+int mdio_mux_init(struct device_d *dev,
+ struct device_node *mux_node,
+ int (*switch_fn)(int cur, int desired, void *data),
+ void *data,
+ struct mii_bus *mux_bus)
+{
+ static int parent_count = 0;
+
+ struct device_node *parent_bus_node;
+ struct device_node *child_bus_node;
+ struct mdio_mux_parent_bus *pb;
+ struct mdio_mux_child_bus *cb;
+ struct mii_bus *parent_bus;
+ int r;
+
+ if (!mux_node)
+ return -ENODEV;
+
+ if (!mux_bus) {
+ parent_bus_node = of_parse_phandle(mux_node,
+ "mdio-parent-bus", 0);
+
+ if (!parent_bus_node)
+ return -ENODEV;
+
+ parent_bus = of_mdio_find_bus(parent_bus_node);
+
+ if (!parent_bus)
+ return -EPROBE_DEFER;
+ } else {
+ parent_bus_node = NULL;
+ parent_bus = mux_bus;
+ }
+
+ pb = xzalloc(sizeof(*pb));
+
+ pb->switch_data = data;
+ pb->switch_fn = switch_fn;
+ pb->current_child = -1;
+ pb->parent_id = parent_count++;
+ pb->mii_bus = parent_bus;
+
+ for_each_available_child_of_node(mux_node, child_bus_node) {
+ int v;
+
+ r = of_property_read_u32(child_bus_node, "reg", &v);
+ if (r) {
+ dev_err(dev,
+ "Error: Failed to find reg for child %pOF\n",
+ child_bus_node);
+ continue;
+ }
+
+ cb = xzalloc(sizeof(*cb));
+ cb->bus_number = v;
+ cb->parent = pb;
+
+ cb->mii_bus.priv = cb;
+ cb->mii_bus.parent = dev;
+ cb->mii_bus.read = mdio_mux_read;
+ cb->mii_bus.write = mdio_mux_write;
+ cb->mii_bus.dev.device_node = child_bus_node;
+
+ r = mdiobus_register(&cb->mii_bus);
+ if (r) {
+ dev_err(dev,
+ "Error: Failed to register MDIO bus for child %pOF\n",
+ child_bus_node);
+ }
+ }
+
+ parent_bus->is_multiplexed = true;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mdio_mux_init);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 012b90e834..d209716a14 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -32,6 +32,9 @@ int mdiobus_detect(struct device_d *dev)
struct mii_bus *mii = to_mii_bus(dev);
int i, ret;
+ if (mii->is_multiplexed)
+ return 0;
+
for (i = 0; i < PHY_MAX_ADDR; i++) {
struct phy_device *phydev;
@@ -207,6 +210,33 @@ struct mii_bus *mdiobus_get_bus(int busnum)
}
/**
+ * of_mdio_find_bus - Given an mii_bus node, find the mii_bus.
+ * @mdio_bus_np: Pointer to the mii_bus.
+ *
+ * Returns a reference to the mii_bus, or NULL if none found.
+ *
+ * Because the association of a device_node and mii_bus is made via
+ * mdiobus_register(), the mii_bus cannot be found before it is
+ * registered with mdiobus_register().
+ *
+ */
+struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np)
+{
+ struct mii_bus *mii;
+
+ if (!mdio_bus_np)
+ return NULL;
+
+ for_each_mii_bus(mii)
+ if (mii->dev.device_node == mdio_bus_np)
+ return mii;
+
+ return NULL;
+}
+EXPORT_SYMBOL(of_mdio_find_bus);
+
+
+/**
* mdio_bus_match - determine if given PHY driver supports the given PHY device
* @dev: target PHY device
* @drv: given PHY driver
diff --git a/include/fs.h b/include/fs.h
index 5c5fff8701..3d88bfad4a 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -10,6 +10,7 @@
#include <driver.h>
#include <filetype.h>
#include <linux/fs.h>
+#include <linux/string.h>
#define PATH_MAX 1024 /* include/linux/limits.h */
@@ -171,4 +172,12 @@ void mount_all(void);
void fsdev_set_linux_rootarg(struct fs_device_d *fsdev, const char *str);
char *path_get_linux_rootarg(const char *path);
+static inline const char *devpath_to_name(const char *devpath)
+{
+ if (devpath && !strncmp(devpath, "/dev/", 5))
+ return devpath + 5;
+
+ return devpath;
+}
+
#endif /* __FS_H */
diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h
new file mode 100644
index 0000000000..1730939bfc
--- /dev/null
+++ b/include/linux/mdio-mux.h
@@ -0,0 +1,30 @@
+/*
+ * MDIO bus multiplexer framwork.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+#ifndef __LINUX_MDIO_MUX_H
+#define __LINUX_MDIO_MUX_H
+#include <driver.h>
+#include <linux/phy.h>
+
+/* mdio_mux_init() - Initialize a MDIO mux
+ * @dev The device owning the MDIO mux
+ * @mux_node The device node of the MDIO mux
+ * @switch_fn The function called for switching target MDIO child
+ * @data Private data used by switch_fn()
+ * @mux_bus An optional parent bus (Other case are to use parent_bus property)
+ */
+int mdio_mux_init(struct device_d *dev,
+ struct device_node *mux_node,
+ int (*switch_fn) (int cur, int desired, void *data),
+ void *data,
+ struct mii_bus *mux_bus);
+
+void mdio_mux_uninit(void *mux_handle);
+
+#endif /* __LINUX_MDIO_MUX_H */
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d7b10afbc9..ac750f5c3a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -100,6 +100,8 @@ struct mii_bus {
u32 phy_mask;
struct list_head list;
+
+ bool is_multiplexed;
};
#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
@@ -116,6 +118,8 @@ int mdiobus_detect(struct device_d *dev);
struct mii_bus *mdiobus_get_bus(int busnum);
+struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np);
+
/**
* mdiobus_read - Convenience function for reading a given MII mgmt register
* @bus: the mii_bus struct