From: Chen-Yu Tsai <wens@csie.org> To: Maxime Ripard <maxime.ripard@free-electrons.com>, Florian Fainelli <f.fainelli@gmail.com>, Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>, Mark Rutland <mark.rutland@arm.com>, Ian Campbell <ijc+devicetree@hellion.org.uk>, Kumar Gala <galak@codeaurora.org> Cc: Chen-Yu Tsai <wens@csie.org>, netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, LABBE Corentin <clabbe.montjoie@gmail.com> Subject: [PATCH RFC 2/5] net: phy: sun8i-h3-ephy: Add driver for Allwinner H3 Ethernet PHY Date: Tue, 5 Apr 2016 00:22:31 +0800 [thread overview] Message-ID: <1459786954-12649-3-git-send-email-wens@csie.org> (raw) In-Reply-To: <1459786954-12649-1-git-send-email-wens@csie.org> The Allwinner H3 SoC incorporates an Ethernet PHY. This is enabled and configured through a memory mapped hardware register. This same register also configures the MAC interface mode and TX clock source. Also covered by the register, but not supported in this driver, are TX/RX clock delay chains and inverters, and an RMII module. Signed-off-by: Chen-Yu Tsai <wens@csie.org> --- drivers/net/phy/Kconfig | 8 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/sun8i-h3-ephy.c | 266 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 drivers/net/phy/sun8i-h3-ephy.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 6dad9a9c356c..f4b9eb6e9114 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -276,3 +276,11 @@ endif # PHYLIB config MICREL_KS8995MA tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch" depends on SPI + +config SUN8I_H3_EPHY + tristate "Allwinner sun8i H3 Ethernet PHY" + depends on OF && HAS_IOMEM && COMMON_CLK && RESET_CONTROLLER + depends on MACH_SUN8I || COMPILE_TEST + help + This modules provides a driver for the internal Ethernet PHY + and Ethernet MAC controls found in the Allwinner H3 SoC. diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index fcdbb9299fab..7cec3aceb518 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -44,3 +44,4 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_MICROCHIP_PHY) += microchip.o obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o +obj-$(CONFIG_SUN8I_H3_EPHY) += sun8i-h3-ephy.o diff --git a/drivers/net/phy/sun8i-h3-ephy.c b/drivers/net/phy/sun8i-h3-ephy.c new file mode 100644 index 000000000000..bf2703bee024 --- /dev/null +++ b/drivers/net/phy/sun8i-h3-ephy.c @@ -0,0 +1,266 @@ +/* + * Allwinner sun8i H3 E(thernet) PHY driver + * + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> + * + * 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. + * + * 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 <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/spinlock.h> + +#define REG_PHY_ADDR_SHIFT 20 +#define REG_PHY_ADDR_MASK GENMASK(4, 0) +#define REG_LED_POL BIT(17) /* 1: active low, 0: active high */ +#define REG_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */ +#define REG_PHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */ + +#define REG_DEFAULT_VALUE 0x58000 +#define REG_DEFAULT_MASK GENMASK(31, 15) + +#define REG_GPIT 2 +#define REG_ETCS_MASK 0x3 +#define SUN8I_H3_EMAC_PARENTS 2 +#define MII_PHY_CLK_RATE 25000000 +#define INT_TX_CLK_RATE 125000000 +#define MII_PHY_CLK_NAME "mii_phy_tx" +#define INT_TX_CLK_NAME "int_tx" + +struct sun8i_h3_ephy { + struct device *dev; + void __iomem *reg; + struct clk *clk; + struct reset_control *reset; + struct clk *mac_clks[SUN8I_H3_EMAC_PARENTS + 1]; +}; + +static DEFINE_SPINLOCK(sun8i_h3_ephy_lock); + +/* The EMAC clock/interface controls are much like those found on the A20, + * which is supported by sun7i-a20-gmac-clk. The H3 adds an RMII module, + * enabled by bit 13. Unfortunately vendor code and documentation don't + * explain how it should work with the other bits, and no hardware + * actually uses it. + */ +static u32 sun8i_h3_emac_mux_table[SUN8I_H3_EMAC_PARENTS] = { + 0x0, /* Select TX clock from MII PHY */ + 0x2, /* Select internal TX clock (for RGMII) */ +}; + +static const char *sun8i_h3_emac_mux_parents[SUN8I_H3_EMAC_PARENTS] = { + MII_PHY_CLK_NAME, + INT_TX_CLK_NAME, +}; + +int sun8i_h3_ephy_register_clocks(struct sun8i_h3_ephy *phy) +{ + struct device *dev = phy->dev; + struct device_node *np = dev->of_node; + const char *clk_name; + struct clk_mux *mux; + struct clk_gate *gate; + int ret; + + if (of_property_read_string(np, "clock-output-names", &clk_name)) { + dev_err(phy->dev, "No clock output name given\n"); + return -EINVAL; + } + + /* allocate mux and gate clock structs */ + mux = devm_kzalloc(dev, sizeof(struct clk_mux), GFP_KERNEL); + if (!mux) + return -ENOMEM; + + gate = devm_kzalloc(dev, sizeof(struct clk_gate), GFP_KERNEL); + if (!gate) + return -ENOMEM; + + /* Register fixed clocks to use as parents */ + phy->mac_clks[0] = clk_register_fixed_rate(dev, MII_PHY_CLK_NAME, + NULL, 0, MII_PHY_CLK_RATE); + if (IS_ERR(phy->mac_clks[0])) + return PTR_ERR(phy->mac_clks[0]); + + phy->mac_clks[1] = clk_register_fixed_rate(dev, INT_TX_CLK_NAME, + NULL, 0, INT_TX_CLK_RATE); + if (IS_ERR(phy->mac_clks[1])) { + ret = PTR_ERR(phy->mac_clks[1]); + goto err_int_tx_clk; + } + + /* set up gate and mux properties */ + gate->reg = phy->reg; + gate->bit_idx = REG_GPIT; + gate->lock = &sun8i_h3_ephy_lock; + mux->reg = phy->reg; + mux->mask = REG_ETCS_MASK; + mux->table = sun8i_h3_emac_mux_table; + mux->lock = &sun8i_h3_ephy_lock; + + phy->mac_clks[2] = clk_register_composite(dev, clk_name, + sun8i_h3_emac_mux_parents, + SUN8I_H3_EMAC_PARENTS, + &mux->hw, &clk_mux_ops, + NULL, NULL, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(phy->mac_clks[2])) { + ret = PTR_ERR(phy->mac_clks[2]); + goto err_tx_clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + phy->mac_clks[2]); + if (ret) + goto err_of_clk; + + return 0; + +err_of_clk: + /* TODO: switch to clk_unregister_composite when it's available */ + clk_unregister(phy->mac_clks[2]); +err_tx_clk: + clk_unregister_fixed_rate(phy->mac_clks[1]); +err_int_tx_clk: + clk_unregister_fixed_rate(phy->mac_clks[0]); + + return ret; +} + +static void sun8i_h3_ephy_init_phy(struct sun8i_h3_ephy *phy, u32 addr) +{ + u32 val = readl(phy->reg); + + /* set default values, but don't touch clock settings */ + val = (val & ~REG_DEFAULT_MASK) | REG_DEFAULT_VALUE; + + if (addr < REG_PHY_ADDR_MASK) { + dev_info(phy->dev, "Using interal PHY at 0x%x\n", addr); + + val |= addr << REG_PHY_ADDR_SHIFT; + val &= ~REG_SHUTDOWN; + val |= REG_PHY_SELECT; + + if (of_property_read_bool(phy->dev->of_node, + "allwinner,leds-active-low")) + val |= REG_LED_POL; + } else { + dev_info(phy->dev, "Using external PHY\n"); + } + + writel(val, phy->reg); +} + +static void sun8i_h3_ephy_reset_phy(struct sun8i_h3_ephy *phy) +{ + u32 val; + + val = readl(phy->reg); + val = (val & ~REG_DEFAULT_MASK) | REG_DEFAULT_VALUE; + writel(val, phy->reg); +} + +int sun8i_h3_ephy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct sun8i_h3_ephy *phy; + struct resource *res; + u32 addr = REG_PHY_ADDR_MASK; + int ret; + + ret = of_property_read_u32(np, "allwinner,ephy-addr", &addr); + if (!ret && addr > REG_PHY_ADDR_MASK) { + dev_err(dev, "invalid PHY address: 0x%x\n", addr); + return -EINVAL; + } else if (ret && ret != -EINVAL) { + dev_err(dev, "could not get PHY address: %d\n", ret); + return ret; + } + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + phy->clk = devm_clk_get(dev, NULL); + if (IS_ERR(phy->clk)) { + dev_err(dev, "failed to get clock\n"); + return PTR_ERR(phy->clk); + } + + phy->reset = devm_reset_control_get(dev, NULL); + if (IS_ERR(phy->reset)) { + dev_err(dev, "failed to get reset control\n"); + return PTR_ERR(phy->reset); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + phy->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(phy->reg)) { + dev_err(dev, "failed to map registers\n"); + return PTR_ERR(phy->reg); + } + + ret = clk_prepare_enable(phy->clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + + ret = reset_control_deassert(phy->reset); + if (ret) { + dev_err(dev, "failed to deassert reset control\n"); + goto err_reset; + } + + sun8i_h3_ephy_init_phy(phy, addr); + + ret = sun8i_h3_ephy_register_clocks(phy); + if (ret) + goto err_tx_clk; + + return 0; + +err_tx_clk: + sun8i_h3_ephy_reset_phy(phy); + reset_control_assert(phy->reset); +err_reset: + clk_disable_unprepare(phy->clk); + return ret; +} + +static const struct of_device_id sun8i_h3_ephy_of_match[] = { + { .compatible = "allwinner,sun8i-h3-ephy", }, + { }, +}; +MODULE_DEVICE_TABLE(of, sun8i_h3_ephy_of_match); + +static struct platform_driver sun8i_h3_ephy_driver = { + .probe = sun8i_h3_ephy_probe, + .driver = { + .of_match_table = sun8i_h3_ephy_of_match, + .name = "sun8i-h3-ephy", + } +}; +module_platform_driver(sun8i_h3_ephy_driver); + +MODULE_DESCRIPTION("Allwinner sun8i H3 Ethernet PHY driver"); +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); +MODULE_LICENSE("GPL v2"); -- 2.7.0
WARNING: multiple messages have this Message-ID (diff)
From: wens@csie.org (Chen-Yu Tsai) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH RFC 2/5] net: phy: sun8i-h3-ephy: Add driver for Allwinner H3 Ethernet PHY Date: Tue, 5 Apr 2016 00:22:31 +0800 [thread overview] Message-ID: <1459786954-12649-3-git-send-email-wens@csie.org> (raw) In-Reply-To: <1459786954-12649-1-git-send-email-wens@csie.org> The Allwinner H3 SoC incorporates an Ethernet PHY. This is enabled and configured through a memory mapped hardware register. This same register also configures the MAC interface mode and TX clock source. Also covered by the register, but not supported in this driver, are TX/RX clock delay chains and inverters, and an RMII module. Signed-off-by: Chen-Yu Tsai <wens@csie.org> --- drivers/net/phy/Kconfig | 8 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/sun8i-h3-ephy.c | 266 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 drivers/net/phy/sun8i-h3-ephy.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 6dad9a9c356c..f4b9eb6e9114 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -276,3 +276,11 @@ endif # PHYLIB config MICREL_KS8995MA tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch" depends on SPI + +config SUN8I_H3_EPHY + tristate "Allwinner sun8i H3 Ethernet PHY" + depends on OF && HAS_IOMEM && COMMON_CLK && RESET_CONTROLLER + depends on MACH_SUN8I || COMPILE_TEST + help + This modules provides a driver for the internal Ethernet PHY + and Ethernet MAC controls found in the Allwinner H3 SoC. diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index fcdbb9299fab..7cec3aceb518 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -44,3 +44,4 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o obj-$(CONFIG_MICROCHIP_PHY) += microchip.o obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o +obj-$(CONFIG_SUN8I_H3_EPHY) += sun8i-h3-ephy.o diff --git a/drivers/net/phy/sun8i-h3-ephy.c b/drivers/net/phy/sun8i-h3-ephy.c new file mode 100644 index 000000000000..bf2703bee024 --- /dev/null +++ b/drivers/net/phy/sun8i-h3-ephy.c @@ -0,0 +1,266 @@ +/* + * Allwinner sun8i H3 E(thernet) PHY driver + * + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> + * + * 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. + * + * 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 <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/spinlock.h> + +#define REG_PHY_ADDR_SHIFT 20 +#define REG_PHY_ADDR_MASK GENMASK(4, 0) +#define REG_LED_POL BIT(17) /* 1: active low, 0: active high */ +#define REG_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */ +#define REG_PHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */ + +#define REG_DEFAULT_VALUE 0x58000 +#define REG_DEFAULT_MASK GENMASK(31, 15) + +#define REG_GPIT 2 +#define REG_ETCS_MASK 0x3 +#define SUN8I_H3_EMAC_PARENTS 2 +#define MII_PHY_CLK_RATE 25000000 +#define INT_TX_CLK_RATE 125000000 +#define MII_PHY_CLK_NAME "mii_phy_tx" +#define INT_TX_CLK_NAME "int_tx" + +struct sun8i_h3_ephy { + struct device *dev; + void __iomem *reg; + struct clk *clk; + struct reset_control *reset; + struct clk *mac_clks[SUN8I_H3_EMAC_PARENTS + 1]; +}; + +static DEFINE_SPINLOCK(sun8i_h3_ephy_lock); + +/* The EMAC clock/interface controls are much like those found on the A20, + * which is supported by sun7i-a20-gmac-clk. The H3 adds an RMII module, + * enabled by bit 13. Unfortunately vendor code and documentation don't + * explain how it should work with the other bits, and no hardware + * actually uses it. + */ +static u32 sun8i_h3_emac_mux_table[SUN8I_H3_EMAC_PARENTS] = { + 0x0, /* Select TX clock from MII PHY */ + 0x2, /* Select internal TX clock (for RGMII) */ +}; + +static const char *sun8i_h3_emac_mux_parents[SUN8I_H3_EMAC_PARENTS] = { + MII_PHY_CLK_NAME, + INT_TX_CLK_NAME, +}; + +int sun8i_h3_ephy_register_clocks(struct sun8i_h3_ephy *phy) +{ + struct device *dev = phy->dev; + struct device_node *np = dev->of_node; + const char *clk_name; + struct clk_mux *mux; + struct clk_gate *gate; + int ret; + + if (of_property_read_string(np, "clock-output-names", &clk_name)) { + dev_err(phy->dev, "No clock output name given\n"); + return -EINVAL; + } + + /* allocate mux and gate clock structs */ + mux = devm_kzalloc(dev, sizeof(struct clk_mux), GFP_KERNEL); + if (!mux) + return -ENOMEM; + + gate = devm_kzalloc(dev, sizeof(struct clk_gate), GFP_KERNEL); + if (!gate) + return -ENOMEM; + + /* Register fixed clocks to use as parents */ + phy->mac_clks[0] = clk_register_fixed_rate(dev, MII_PHY_CLK_NAME, + NULL, 0, MII_PHY_CLK_RATE); + if (IS_ERR(phy->mac_clks[0])) + return PTR_ERR(phy->mac_clks[0]); + + phy->mac_clks[1] = clk_register_fixed_rate(dev, INT_TX_CLK_NAME, + NULL, 0, INT_TX_CLK_RATE); + if (IS_ERR(phy->mac_clks[1])) { + ret = PTR_ERR(phy->mac_clks[1]); + goto err_int_tx_clk; + } + + /* set up gate and mux properties */ + gate->reg = phy->reg; + gate->bit_idx = REG_GPIT; + gate->lock = &sun8i_h3_ephy_lock; + mux->reg = phy->reg; + mux->mask = REG_ETCS_MASK; + mux->table = sun8i_h3_emac_mux_table; + mux->lock = &sun8i_h3_ephy_lock; + + phy->mac_clks[2] = clk_register_composite(dev, clk_name, + sun8i_h3_emac_mux_parents, + SUN8I_H3_EMAC_PARENTS, + &mux->hw, &clk_mux_ops, + NULL, NULL, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(phy->mac_clks[2])) { + ret = PTR_ERR(phy->mac_clks[2]); + goto err_tx_clk; + } + + ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + phy->mac_clks[2]); + if (ret) + goto err_of_clk; + + return 0; + +err_of_clk: + /* TODO: switch to clk_unregister_composite when it's available */ + clk_unregister(phy->mac_clks[2]); +err_tx_clk: + clk_unregister_fixed_rate(phy->mac_clks[1]); +err_int_tx_clk: + clk_unregister_fixed_rate(phy->mac_clks[0]); + + return ret; +} + +static void sun8i_h3_ephy_init_phy(struct sun8i_h3_ephy *phy, u32 addr) +{ + u32 val = readl(phy->reg); + + /* set default values, but don't touch clock settings */ + val = (val & ~REG_DEFAULT_MASK) | REG_DEFAULT_VALUE; + + if (addr < REG_PHY_ADDR_MASK) { + dev_info(phy->dev, "Using interal PHY at 0x%x\n", addr); + + val |= addr << REG_PHY_ADDR_SHIFT; + val &= ~REG_SHUTDOWN; + val |= REG_PHY_SELECT; + + if (of_property_read_bool(phy->dev->of_node, + "allwinner,leds-active-low")) + val |= REG_LED_POL; + } else { + dev_info(phy->dev, "Using external PHY\n"); + } + + writel(val, phy->reg); +} + +static void sun8i_h3_ephy_reset_phy(struct sun8i_h3_ephy *phy) +{ + u32 val; + + val = readl(phy->reg); + val = (val & ~REG_DEFAULT_MASK) | REG_DEFAULT_VALUE; + writel(val, phy->reg); +} + +int sun8i_h3_ephy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct sun8i_h3_ephy *phy; + struct resource *res; + u32 addr = REG_PHY_ADDR_MASK; + int ret; + + ret = of_property_read_u32(np, "allwinner,ephy-addr", &addr); + if (!ret && addr > REG_PHY_ADDR_MASK) { + dev_err(dev, "invalid PHY address: 0x%x\n", addr); + return -EINVAL; + } else if (ret && ret != -EINVAL) { + dev_err(dev, "could not get PHY address: %d\n", ret); + return ret; + } + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + phy->clk = devm_clk_get(dev, NULL); + if (IS_ERR(phy->clk)) { + dev_err(dev, "failed to get clock\n"); + return PTR_ERR(phy->clk); + } + + phy->reset = devm_reset_control_get(dev, NULL); + if (IS_ERR(phy->reset)) { + dev_err(dev, "failed to get reset control\n"); + return PTR_ERR(phy->reset); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + phy->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(phy->reg)) { + dev_err(dev, "failed to map registers\n"); + return PTR_ERR(phy->reg); + } + + ret = clk_prepare_enable(phy->clk); + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + + ret = reset_control_deassert(phy->reset); + if (ret) { + dev_err(dev, "failed to deassert reset control\n"); + goto err_reset; + } + + sun8i_h3_ephy_init_phy(phy, addr); + + ret = sun8i_h3_ephy_register_clocks(phy); + if (ret) + goto err_tx_clk; + + return 0; + +err_tx_clk: + sun8i_h3_ephy_reset_phy(phy); + reset_control_assert(phy->reset); +err_reset: + clk_disable_unprepare(phy->clk); + return ret; +} + +static const struct of_device_id sun8i_h3_ephy_of_match[] = { + { .compatible = "allwinner,sun8i-h3-ephy", }, + { }, +}; +MODULE_DEVICE_TABLE(of, sun8i_h3_ephy_of_match); + +static struct platform_driver sun8i_h3_ephy_driver = { + .probe = sun8i_h3_ephy_probe, + .driver = { + .of_match_table = sun8i_h3_ephy_of_match, + .name = "sun8i-h3-ephy", + } +}; +module_platform_driver(sun8i_h3_ephy_driver); + +MODULE_DESCRIPTION("Allwinner sun8i H3 Ethernet PHY driver"); +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); +MODULE_LICENSE("GPL v2"); -- 2.7.0
next prev parent reply other threads:[~2016-04-04 16:22 UTC|newest] Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-04-04 16:22 [PATCH RFC 0/5] net: phy: sun8i-h3-ephy: Add Allwinner H3 Ethernet PHY driver Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` [PATCH RFC 1/5] net: phy: sun8i-h3-ephy: Add bindings for Allwinner H3 Ethernet PHY Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-07 17:57 ` Rob Herring 2016-04-07 17:57 ` Rob Herring 2016-04-07 17:57 ` Rob Herring 2016-04-11 19:23 ` Florian Fainelli 2016-04-11 19:23 ` Florian Fainelli 2016-04-12 1:38 ` Chen-Yu Tsai 2016-04-12 1:38 ` Chen-Yu Tsai 2016-05-07 5:30 ` Chen-Yu Tsai 2016-05-07 5:30 ` Chen-Yu Tsai 2016-05-07 5:30 ` Chen-Yu Tsai 2016-05-07 8:14 ` Hans de Goede 2016-05-07 8:14 ` Hans de Goede 2016-04-04 16:22 ` Chen-Yu Tsai [this message] 2016-04-04 16:22 ` [PATCH RFC 2/5] net: phy: sun8i-h3-ephy: Add driver " Chen-Yu Tsai 2016-04-11 19:23 ` Florian Fainelli 2016-04-11 19:23 ` Florian Fainelli 2016-04-11 19:23 ` Florian Fainelli 2016-04-14 2:04 ` Chen-Yu Tsai 2016-04-14 2:04 ` Chen-Yu Tsai 2016-04-04 16:22 ` [PATCH RFC 3/5] ARM: dts: sun8i-h3: Add H3 Ethernet PHY device node to sun8i-h3.dtsi Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` [PATCH RFC 4/5] ARM: dts: sun8i-h3: Add Ethernet controller " Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-04 16:22 ` [PATCH RFC 5/5] ARM: dts: sun8i: Enable Ethernet controller on the Orange PI PC Chen-Yu Tsai 2016-04-04 16:22 ` Chen-Yu Tsai 2016-04-11 19:25 ` Florian Fainelli 2016-04-11 19:25 ` Florian Fainelli 2016-04-11 19:25 ` Florian Fainelli
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1459786954-12649-3-git-send-email-wens@csie.org \ --to=wens@csie.org \ --cc=clabbe.montjoie@gmail.com \ --cc=devicetree@vger.kernel.org \ --cc=f.fainelli@gmail.com \ --cc=galak@codeaurora.org \ --cc=ijc+devicetree@hellion.org.uk \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=maxime.ripard@free-electrons.com \ --cc=netdev@vger.kernel.org \ --cc=pawel.moll@arm.com \ --cc=robh+dt@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.