aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/Kconfig1
-rw-r--r--drivers/net/phy/meson-gxl.c77
-rw-r--r--drivers/net/phy/smsc.c20
-rw-r--r--include/linux/smscphy.h6
4 files changed, 28 insertions, 76 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 54874555c921..6b9525def973 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -70,6 +70,7 @@ config AMD_PHY
config MESON_GXL_PHY
tristate "Amlogic Meson GXL Internal PHY"
depends on ARCH_MESON || COMPILE_TEST
+ select SMSC_PHY
help
Currently has a driver for the Amlogic Meson GXL Internal PHY
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index a6015cd03bff..3dea7c752057 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -13,6 +13,7 @@
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/bitfield.h>
+#include <linux/smscphy.h>
#define TSTCNTL 20
#define TSTCNTL_READ BIT(15)
@@ -23,18 +24,6 @@
#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
#define TSTREAD1 21
#define TSTWRITE 23
-#define INTSRC_FLAG 29
-#define INTSRC_ANEG_PR BIT(1)
-#define INTSRC_PARALLEL_FAULT BIT(2)
-#define INTSRC_ANEG_LP_ACK BIT(3)
-#define INTSRC_LINK_DOWN BIT(4)
-#define INTSRC_REMOTE_FAULT BIT(5)
-#define INTSRC_ANEG_COMPLETE BIT(6)
-#define INTSRC_ENERGY_DETECT BIT(7)
-#define INTSRC_MASK 30
-
-#define INT_SOURCES (INTSRC_LINK_DOWN | INTSRC_ANEG_COMPLETE | \
- INTSRC_ENERGY_DETECT)
#define BANK_ANALOG_DSP 0
#define BANK_WOL 1
@@ -195,59 +184,6 @@ read_status_continue:
return genphy_read_status(phydev);
}
-static int meson_gxl_ack_interrupt(struct phy_device *phydev)
-{
- int ret = phy_read(phydev, INTSRC_FLAG);
-
- return ret < 0 ? ret : 0;
-}
-
-static int meson_gxl_config_intr(struct phy_device *phydev)
-{
- int ret;
-
- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
- /* Ack any pending IRQ */
- ret = meson_gxl_ack_interrupt(phydev);
- if (ret)
- return ret;
-
- ret = phy_write(phydev, INTSRC_MASK, INT_SOURCES);
- } else {
- ret = phy_write(phydev, INTSRC_MASK, 0);
-
- /* Ack any pending IRQ */
- ret = meson_gxl_ack_interrupt(phydev);
- }
-
- return ret;
-}
-
-static irqreturn_t meson_gxl_handle_interrupt(struct phy_device *phydev)
-{
- int irq_status;
-
- irq_status = phy_read(phydev, INTSRC_FLAG);
- if (irq_status < 0) {
- phy_error(phydev);
- return IRQ_NONE;
- }
-
- irq_status &= INT_SOURCES;
-
- if (irq_status == 0)
- return IRQ_NONE;
-
- /* Aneg-complete interrupt is used for link-up detection */
- if (phydev->autoneg == AUTONEG_ENABLE &&
- irq_status == INTSRC_ENERGY_DETECT)
- return IRQ_HANDLED;
-
- phy_trigger_machine(phydev);
-
- return IRQ_HANDLED;
-}
-
static struct phy_driver meson_gxl_phy[] = {
{
PHY_ID_MATCH_EXACT(0x01814400),
@@ -257,8 +193,8 @@ static struct phy_driver meson_gxl_phy[] = {
.soft_reset = genphy_soft_reset,
.config_init = meson_gxl_config_init,
.read_status = meson_gxl_read_status,
- .config_intr = meson_gxl_config_intr,
- .handle_interrupt = meson_gxl_handle_interrupt,
+ .config_intr = smsc_phy_config_intr,
+ .handle_interrupt = smsc_phy_handle_interrupt,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_mmd = genphy_read_mmd_unsupported,
@@ -268,9 +204,12 @@ static struct phy_driver meson_gxl_phy[] = {
.name = "Meson G12A Internal PHY",
/* PHY_BASIC_FEATURES */
.flags = PHY_IS_INTERNAL,
+ .probe = smsc_phy_probe,
+ .config_init = smsc_phy_config_init,
.soft_reset = genphy_soft_reset,
- .config_intr = meson_gxl_config_intr,
- .handle_interrupt = meson_gxl_handle_interrupt,
+ .read_status = lan87xx_read_status,
+ .config_intr = smsc_phy_config_intr,
+ .handle_interrupt = smsc_phy_handle_interrupt,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_mmd = genphy_read_mmd_unsupported,
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 721871184205..730964b856ab 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -54,7 +54,7 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
return rc < 0 ? rc : 0;
}
-static int smsc_phy_config_intr(struct phy_device *phydev)
+int smsc_phy_config_intr(struct phy_device *phydev)
{
int rc;
@@ -75,8 +75,9 @@ static int smsc_phy_config_intr(struct phy_device *phydev)
return rc < 0 ? rc : 0;
}
+EXPORT_SYMBOL_GPL(smsc_phy_config_intr);
-static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
+irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
{
int irq_status;
@@ -95,18 +96,20 @@ static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
return IRQ_HANDLED;
}
+EXPORT_SYMBOL_GPL(smsc_phy_handle_interrupt);
-static int smsc_phy_config_init(struct phy_device *phydev)
+int smsc_phy_config_init(struct phy_device *phydev)
{
struct smsc_phy_priv *priv = phydev->priv;
- if (!priv->energy_enable || phydev->irq != PHY_POLL)
+ if (!priv || !priv->energy_enable || phydev->irq != PHY_POLL)
return 0;
/* Enable energy detect power down mode */
return phy_set_bits(phydev, MII_LAN83C185_CTRL_STATUS,
MII_LAN83C185_EDPWRDOWN);
}
+EXPORT_SYMBOL_GPL(smsc_phy_config_init);
static int smsc_phy_reset(struct phy_device *phydev)
{
@@ -186,7 +189,7 @@ static int lan95xx_config_aneg_ext(struct phy_device *phydev)
* The workaround is only applicable to poll mode. Energy Detect Power-Down may
* not be used in interrupt mode lest link change detection becomes unreliable.
*/
-static int lan87xx_read_status(struct phy_device *phydev)
+int lan87xx_read_status(struct phy_device *phydev)
{
struct smsc_phy_priv *priv = phydev->priv;
int err;
@@ -195,7 +198,8 @@ static int lan87xx_read_status(struct phy_device *phydev)
if (err)
return err;
- if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) {
+ if (!phydev->link && priv && priv->energy_enable &&
+ phydev->irq == PHY_POLL) {
/* Disable EDPD to wake up PHY */
int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
if (rc < 0)
@@ -229,6 +233,7 @@ static int lan87xx_read_status(struct phy_device *phydev)
return err;
}
+EXPORT_SYMBOL_GPL(lan87xx_read_status);
static int smsc_get_sset_count(struct phy_device *phydev)
{
@@ -269,7 +274,7 @@ static void smsc_get_stats(struct phy_device *phydev,
data[i] = smsc_get_stat(phydev, i);
}
-static int smsc_phy_probe(struct phy_device *phydev)
+int smsc_phy_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
struct smsc_phy_priv *priv;
@@ -294,6 +299,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
return clk_set_rate(refclk, 50 * 1000 * 1000);
}
+EXPORT_SYMBOL_GPL(smsc_phy_probe);
static struct phy_driver smsc_phy_driver[] = {
{
diff --git a/include/linux/smscphy.h b/include/linux/smscphy.h
index 1a136271ba6a..80f37c1dba58 100644
--- a/include/linux/smscphy.h
+++ b/include/linux/smscphy.h
@@ -28,4 +28,10 @@
#define MII_LAN83C185_MODE_POWERDOWN 0xC0 /* Power Down mode */
#define MII_LAN83C185_MODE_ALL 0xE0 /* All capable mode */
+int smsc_phy_config_intr(struct phy_device *phydev);
+irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev);
+int smsc_phy_config_init(struct phy_device *phydev);
+int lan87xx_read_status(struct phy_device *phydev);
+int smsc_phy_probe(struct phy_device *phydev);
+
#endif /* __LINUX_SMSCPHY_H__ */