Commit 6eaf9d18 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-platform-glue'

Joachim Eastwood says:

====================
convert stmmac glue layers into platform drivers

This patch set aims to convert the current dwmac glue layers into
proper platform drivers as request by Arnd[1]. These changes start
from patch 3 and onwards.

Overview:
Platform driver functions like probe and remove are exported from
the stmmac platform and then used in subsequent glue later
conversions. The conversion involes adding the platform driver
boiler plate code and adding it to the build system. The last patch
removes the driver from the stmmac platform code thus making it into
a library for common platform driver functions.

The two first patches adds glue layer for my platform. I chose to
first add old style glue layer and then convert it. The churn this
creates is just 3 lines.

I would be very nice if people could test this patch set on their
respective platform. My testing has been limited to compiling and
testing on my (LPC18xx) platform. Thanks!

Next I will look into cleaning up the stmmac platform code.

[1] http://marc.info/?l=linux-arm-kernel&m=143059524606459&w=2
====================
Tested-by: default avatarChen-Yu Tsai <wens@csie.org>
Tested-by: default avatarDinh Nguyen <dinguyen@opensource.altera.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7eafd9b4 50649ab1
* NXP LPC1850 GMAC ethernet controller
This device is a platform glue layer for stmmac.
Please see stmmac.txt for the other unchanged properties.
Required properties:
- compatible: Should contain "nxp,lpc1850-dwmac"
Examples:
mac: ethernet@40010000 {
compatible = "nxp,lpc1850-dwmac", "snps,dwmac-3.611", "snps,dwmac";
reg = <0x40010000 0x2000>;
interrupts = <5>;
interrupt-names = "macirq";
clocks = <&ccu1 CLK_CPU_ETHERNET>;
clock-names = "stmmaceth";
resets = <&rgu 22>;
reset-names = "stmmaceth";
}
......@@ -26,6 +26,82 @@ config STMMAC_PLATFORM
If unsure, say N.
if STMMAC_PLATFORM
config DWMAC_GENERIC
tristate "Generic driver for DWMAC"
default STMMAC_PLATFORM
---help---
Generic DWMAC driver for platforms that don't require any
platform specific code to function or is using platform
data for setup.
config DWMAC_LPC18XX
tristate "NXP LPC18xx/43xx DWMAC support"
default ARCH_LPC18XX
depends on OF
select MFD_SYSCON
---help---
Support for NXP LPC18xx/43xx DWMAC Ethernet.
config DWMAC_MESON
tristate "Amlogic Meson dwmac support"
default ARCH_MESON
depends on OF
help
Support for Ethernet controller on Amlogic Meson SoCs.
This selects the Amlogic Meson SoC glue layer support for
the stmmac device driver. This driver is used for Meson6 and
Meson8 SoCs.
config DWMAC_ROCKCHIP
tristate "Rockchip dwmac support"
default ARCH_ROCKCHIP
depends on OF
select MFD_SYSCON
help
Support for Ethernet controller on Rockchip RK3288 SoC.
This selects the Rockchip RK3288 SoC glue layer support for
the stmmac device driver.
config DWMAC_SOCFPGA
tristate "SOCFPGA dwmac support"
default ARCH_SOCFPGA
depends on OF
select MFD_SYSCON
help
Support for ethernet controller on Altera SOCFPGA
This selects the Altera SOCFPGA SoC glue layer support
for the stmmac device driver. This driver is used for
arria5 and cyclone5 FPGA SoCs.
config DWMAC_STI
tristate "STi GMAC support"
default ARCH_STI
depends on OF
select MFD_SYSCON
---help---
Support for ethernet controller on STi SOCs.
This selects STi SoC glue layer support for the stmmac
device driver. This driver is used on for the STi series
SOCs GMAC ethernet controller.
config DWMAC_SUNXI
tristate "Allwinner GMAC support"
default ARCH_SUNXI
depends on OF
---help---
Support for Allwinner A20/A31 GMAC ethernet controllers.
This selects Allwinner SoC glue layer support for the
stmmac device driver. This driver is used for A20/A31
GMAC ethernet controller.
endif
config STMMAC_PCI
tristate "STMMAC PCI bus support"
depends on STMMAC_ETH && PCI
......
......@@ -4,9 +4,16 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y)
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
# Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o
stmmac-platform-objs:= stmmac_platform.o
obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
stmmac-pci-objs:= stmmac_pci.o
/*
* Generic DWMAC platform driver
*
* Copyright (C) 2007-2011 STMicroelectronics Ltd
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include "stmmac.h"
#include "stmmac_platform.h"
static const struct of_device_id dwmac_generic_match[] = {
{ .compatible = "st,spear600-gmac"},
{ .compatible = "snps,dwmac-3.610"},
{ .compatible = "snps,dwmac-3.70a"},
{ .compatible = "snps,dwmac-3.710"},
{ .compatible = "snps,dwmac"},
{ }
};
MODULE_DEVICE_TABLE(of, dwmac_generic_match);
static struct platform_driver dwmac_generic_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = STMMAC_RESOURCE_NAME,
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = of_match_ptr(dwmac_generic_match),
},
};
module_platform_driver(dwmac_generic_driver);
MODULE_DESCRIPTION("Generic dwmac driver");
MODULE_LICENSE("GPL v2");
/*
* DWMAC glue for NXP LPC18xx/LPC43xx Ethernet
*
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/stmmac.h>
#include "stmmac_platform.h"
/* Register defines for CREG syscon */
#define LPC18XX_CREG_CREG6 0x12c
# define LPC18XX_CREG_CREG6_ETHMODE_MASK 0x7
# define LPC18XX_CREG_CREG6_ETHMODE_MII 0x0
# define LPC18XX_CREG_CREG6_ETHMODE_RMII 0x4
struct lpc18xx_dwmac_priv_data {
struct regmap *reg;
int interface;
};
static void *lpc18xx_dwmac_setup(struct platform_device *pdev)
{
struct lpc18xx_dwmac_priv_data *dwmac;
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
if (!dwmac)
return ERR_PTR(-ENOMEM);
dwmac->interface = of_get_phy_mode(pdev->dev.of_node);
if (dwmac->interface < 0)
return ERR_PTR(dwmac->interface);
dwmac->reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
if (IS_ERR(dwmac->reg)) {
dev_err(&pdev->dev, "Syscon lookup failed\n");
return dwmac->reg;
}
return dwmac;
}
static int lpc18xx_dwmac_init(struct platform_device *pdev, void *priv)
{
struct lpc18xx_dwmac_priv_data *dwmac = priv;
u8 ethmode;
if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII;
} else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
} else {
dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
return -EINVAL;
}
regmap_update_bits(dwmac->reg, LPC18XX_CREG_CREG6,
LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
return 0;
}
static const struct stmmac_of_data lpc18xx_dwmac_data = {
.has_gmac = 1,
.setup = lpc18xx_dwmac_setup,
.init = lpc18xx_dwmac_init,
};
static const struct of_device_id lpc18xx_dwmac_match[] = {
{ .compatible = "nxp,lpc1850-dwmac", .data = &lpc18xx_dwmac_data },
{ }
};
MODULE_DEVICE_TABLE(of, lpc18xx_dwmac_match);
static struct platform_driver lpc18xx_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "lpc18xx-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = lpc18xx_dwmac_match,
},
};
module_platform_driver(lpc18xx_dwmac_driver);
MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
MODULE_DESCRIPTION("DWMAC glue for LPC18xx/43xx Ethernet");
MODULE_LICENSE("GPL v2");
......@@ -15,6 +15,7 @@
#include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/stmmac.h>
......@@ -63,7 +64,28 @@ static void *meson6_dwmac_setup(struct platform_device *pdev)
return dwmac;
}
const struct stmmac_of_data meson6_dwmac_data = {
static const struct stmmac_of_data meson6_dwmac_data = {
.setup = meson6_dwmac_setup,
.fix_mac_speed = meson6_dwmac_fix_mac_speed,
};
static const struct of_device_id meson6_dwmac_match[] = {
{ .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
static struct platform_driver meson6_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "meson6-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = meson6_dwmac_match,
},
};
module_platform_driver(meson6_dwmac_driver);
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer");
MODULE_LICENSE("GPL v2");
......@@ -22,13 +22,17 @@
#include <linux/phy.h>
#include <linux/of_net.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include "stmmac_platform.h"
struct rk_priv_data {
struct platform_device *pdev;
int phy_iface;
......@@ -428,10 +432,31 @@ static void rk_fix_speed(void *priv, unsigned int speed)
dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
}
const struct stmmac_of_data rk3288_gmac_data = {
static const struct stmmac_of_data rk3288_gmac_data = {
.has_gmac = 1,
.fix_mac_speed = rk_fix_speed,
.setup = rk_gmac_setup,
.init = rk_gmac_init,
.exit = rk_gmac_exit,
};
static const struct of_device_id rk_gmac_dwmac_match[] = {
{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_gmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
static struct platform_driver rk_gmac_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "rk_gmac-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = rk_gmac_dwmac_match,
},
};
module_platform_driver(rk_gmac_dwmac_driver);
MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
MODULE_LICENSE("GPL");
......@@ -257,9 +257,28 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
return ret;
}
const struct stmmac_of_data socfpga_gmac_data = {
static const struct stmmac_of_data socfpga_gmac_data = {
.setup = socfpga_dwmac_probe,
.init = socfpga_dwmac_init,
.exit = socfpga_dwmac_exit,
.fix_mac_speed = socfpga_dwmac_fix_mac_speed,
};
static const struct of_device_id socfpga_dwmac_match[] = {
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
{ }
};
MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
static struct platform_driver socfpga_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "socfpga-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = socfpga_dwmac_match,
},
};
module_platform_driver(socfpga_dwmac_driver);
MODULE_LICENSE("GPL v2");
......@@ -17,6 +17,7 @@
#include <linux/stmmac.h>
#include <linux/phy.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/clk.h>
#include <linux/of.h>
......@@ -351,16 +352,40 @@ static void *sti_dwmac_setup(struct platform_device *pdev)
return dwmac;
}
const struct stmmac_of_data stih4xx_dwmac_data = {
static const struct stmmac_of_data stih4xx_dwmac_data = {
.fix_mac_speed = stih4xx_fix_retime_src,
.setup = sti_dwmac_setup,
.init = stix4xx_init,
.exit = sti_dwmac_exit,
};
const struct stmmac_of_data stid127_dwmac_data = {
static const struct stmmac_of_data stid127_dwmac_data = {
.fix_mac_speed = stid127_fix_retime_src,
.setup = sti_dwmac_setup,
.init = stid127_init,
.exit = sti_dwmac_exit,
};
static const struct of_device_id sti_dwmac_match[] = {
{ .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, sti_dwmac_match);
static struct platform_driver sti_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "sti-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = sti_dwmac_match,
},
};
module_platform_driver(sti_dwmac_driver);
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@st.com>");
MODULE_DESCRIPTION("STMicroelectronics DWMAC Specific Glue layer");
MODULE_LICENSE("GPL");
......@@ -18,7 +18,9 @@
#include <linux/stmmac.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/of_net.h>
#include <linux/regulator/consumer.h>
......@@ -132,7 +134,7 @@ static void sun7i_fix_speed(void *priv, unsigned int speed)
/* of_data specifying hardware features and callbacks.
* hardware features were copied from Allwinner drivers. */
const struct stmmac_of_data sun7i_gmac_data = {
static const struct stmmac_of_data sun7i_gmac_data = {
.has_gmac = 1,
.tx_coe = 1,
.fix_mac_speed = sun7i_fix_speed,
......@@ -140,3 +142,24 @@ const struct stmmac_of_data sun7i_gmac_data = {
.init = sun7i_gmac_init,
.exit = sun7i_gmac_exit,
};
static const struct of_device_id sun7i_dwmac_match[] = {
{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, sun7i_dwmac_match);
static struct platform_driver sun7i_dwmac_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "sun7i-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = sun7i_dwmac_match,
},
};
module_platform_driver(sun7i_dwmac_driver);
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
MODULE_DESCRIPTION("Allwinner sunxi DWMAC specific glue layer");
MODULE_LICENSE("GPL");
......@@ -32,25 +32,6 @@
#include "stmmac.h"
#include "stmmac_platform.h"
static const struct of_device_id stmmac_dt_ids[] = {
/* SoC specific glue layers should come before generic bindings */
{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_gmac_data},
{ .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
{ .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
{ .compatible = "st,spear600-gmac"},
{ .compatible = "snps,dwmac-3.610"},
{ .compatible = "snps,dwmac-3.70a"},
{ .compatible = "snps,dwmac-3.710"},
{ .compatible = "snps,dwmac"},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
#ifdef CONFIG_OF
/**
......@@ -129,11 +110,12 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
struct stmmac_dma_cfg *dma_cfg;
const struct of_device_id *device;
struct device *dev = &pdev->dev;
if (!np)
return -ENODEV;
device = of_match_device(stmmac_dt_ids, &pdev->dev);
device = of_match_device(dev->driver->of_match_table, dev);
if (!device)
return -ENODEV;
......@@ -268,7 +250,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
* the necessary platform resources, invoke custom helper (if required) and
* invoke the main probe function.
*/
static int stmmac_pltfr_probe(struct platform_device *pdev)
int stmmac_pltfr_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *res;
......@@ -374,6 +356,7 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
return 0;
}
EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
/**
* stmmac_pltfr_remove
......@@ -381,7 +364,7 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
* Description: this function calls the main to free the net resources
* and calls the platforms hook and release the resources (e.g. mem).
*/
static int stmmac_pltfr_remove(struct platform_device *pdev)
int stmmac_pltfr_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(ndev);
......@@ -395,6 +378,7 @@ static int stmmac_pltfr_remove(struct platform_device *pdev)
return ret;
}
EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
#ifdef CONFIG_PM_SLEEP
/**
......@@ -438,21 +422,6 @@ static int stmmac_pltfr_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
stmmac_pltfr_suspend, stmmac_pltfr_resume);
static struct platform_driver stmmac_pltfr_driver = {
.probe = stmmac_pltfr_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = STMMAC_RESOURCE_NAME,
.pm = &stmmac_pltfr_pm_ops,
.of_match_table = of_match_ptr(stmmac_dt_ids),
},
};
module_platform_driver(stmmac_pltfr_driver);
MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
MODULE_LICENSE("GPL");
SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
stmmac_pltfr_resume);
EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
......@@ -19,11 +19,8 @@
#ifndef __STMMAC_PLATFORM_H__
#define __STMMAC_PLATFORM_H__
extern const struct stmmac_of_data meson6_dwmac_data;
extern const struct stmmac_of_data sun7i_gmac_data;
extern const struct stmmac_of_data stih4xx_dwmac_data;
extern const struct stmmac_of_data stid127_dwmac_data;
extern const struct stmmac_of_data socfpga_gmac_data;
extern const struct stmmac_of_data rk3288_gmac_data;
int stmmac_pltfr_probe(struct platform_device *pdev);
int stmmac_pltfr_remove(struct platform_device *pdev);
extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
#endif /* __STMMAC_PLATFORM_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment