Skip to content

Commit c3892e8

Browse files
committed
Merge branch 'reuse-smsc-phy-functionality'
Heiner Kallweit says: ==================== net: phy: reuse SMSC PHY driver functionality in the meson-gxl PHY driver The Amlogic Meson internal PHY's have the same register layout as certain SMSC PHY's (also for non-c22-standard registers). This seems to be more than just coincidence. Apparently they also need the same workaround for EDPD mode (energy detect power down). Therefore let's reuse SMSC PHY driver functionality in the meson-gxl PHY driver. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2627139 + be66fcc commit c3892e8

File tree

4 files changed

+28
-76
lines changed

4 files changed

+28
-76
lines changed

drivers/net/phy/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ config AMD_PHY
7070
config MESON_GXL_PHY
7171
tristate "Amlogic Meson GXL Internal PHY"
7272
depends on ARCH_MESON || COMPILE_TEST
73+
select SMSC_PHY
7374
help
7475
Currently has a driver for the Amlogic Meson GXL Internal PHY
7576

drivers/net/phy/meson-gxl.c

Lines changed: 8 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/phy.h>
1414
#include <linux/netdevice.h>
1515
#include <linux/bitfield.h>
16+
#include <linux/smscphy.h>
1617

1718
#define TSTCNTL 20
1819
#define TSTCNTL_READ BIT(15)
@@ -23,18 +24,6 @@
2324
#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
2425
#define TSTREAD1 21
2526
#define TSTWRITE 23
26-
#define INTSRC_FLAG 29
27-
#define INTSRC_ANEG_PR BIT(1)
28-
#define INTSRC_PARALLEL_FAULT BIT(2)
29-
#define INTSRC_ANEG_LP_ACK BIT(3)
30-
#define INTSRC_LINK_DOWN BIT(4)
31-
#define INTSRC_REMOTE_FAULT BIT(5)
32-
#define INTSRC_ANEG_COMPLETE BIT(6)
33-
#define INTSRC_ENERGY_DETECT BIT(7)
34-
#define INTSRC_MASK 30
35-
36-
#define INT_SOURCES (INTSRC_LINK_DOWN | INTSRC_ANEG_COMPLETE | \
37-
INTSRC_ENERGY_DETECT)
3827

3928
#define BANK_ANALOG_DSP 0
4029
#define BANK_WOL 1
@@ -195,59 +184,6 @@ static int meson_gxl_read_status(struct phy_device *phydev)
195184
return genphy_read_status(phydev);
196185
}
197186

198-
static int meson_gxl_ack_interrupt(struct phy_device *phydev)
199-
{
200-
int ret = phy_read(phydev, INTSRC_FLAG);
201-
202-
return ret < 0 ? ret : 0;
203-
}
204-
205-
static int meson_gxl_config_intr(struct phy_device *phydev)
206-
{
207-
int ret;
208-
209-
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
210-
/* Ack any pending IRQ */
211-
ret = meson_gxl_ack_interrupt(phydev);
212-
if (ret)
213-
return ret;
214-
215-
ret = phy_write(phydev, INTSRC_MASK, INT_SOURCES);
216-
} else {
217-
ret = phy_write(phydev, INTSRC_MASK, 0);
218-
219-
/* Ack any pending IRQ */
220-
ret = meson_gxl_ack_interrupt(phydev);
221-
}
222-
223-
return ret;
224-
}
225-
226-
static irqreturn_t meson_gxl_handle_interrupt(struct phy_device *phydev)
227-
{
228-
int irq_status;
229-
230-
irq_status = phy_read(phydev, INTSRC_FLAG);
231-
if (irq_status < 0) {
232-
phy_error(phydev);
233-
return IRQ_NONE;
234-
}
235-
236-
irq_status &= INT_SOURCES;
237-
238-
if (irq_status == 0)
239-
return IRQ_NONE;
240-
241-
/* Aneg-complete interrupt is used for link-up detection */
242-
if (phydev->autoneg == AUTONEG_ENABLE &&
243-
irq_status == INTSRC_ENERGY_DETECT)
244-
return IRQ_HANDLED;
245-
246-
phy_trigger_machine(phydev);
247-
248-
return IRQ_HANDLED;
249-
}
250-
251187
static struct phy_driver meson_gxl_phy[] = {
252188
{
253189
PHY_ID_MATCH_EXACT(0x01814400),
@@ -257,8 +193,8 @@ static struct phy_driver meson_gxl_phy[] = {
257193
.soft_reset = genphy_soft_reset,
258194
.config_init = meson_gxl_config_init,
259195
.read_status = meson_gxl_read_status,
260-
.config_intr = meson_gxl_config_intr,
261-
.handle_interrupt = meson_gxl_handle_interrupt,
196+
.config_intr = smsc_phy_config_intr,
197+
.handle_interrupt = smsc_phy_handle_interrupt,
262198
.suspend = genphy_suspend,
263199
.resume = genphy_resume,
264200
.read_mmd = genphy_read_mmd_unsupported,
@@ -268,9 +204,12 @@ static struct phy_driver meson_gxl_phy[] = {
268204
.name = "Meson G12A Internal PHY",
269205
/* PHY_BASIC_FEATURES */
270206
.flags = PHY_IS_INTERNAL,
207+
.probe = smsc_phy_probe,
208+
.config_init = smsc_phy_config_init,
271209
.soft_reset = genphy_soft_reset,
272-
.config_intr = meson_gxl_config_intr,
273-
.handle_interrupt = meson_gxl_handle_interrupt,
210+
.read_status = lan87xx_read_status,
211+
.config_intr = smsc_phy_config_intr,
212+
.handle_interrupt = smsc_phy_handle_interrupt,
274213
.suspend = genphy_suspend,
275214
.resume = genphy_resume,
276215
.read_mmd = genphy_read_mmd_unsupported,

drivers/net/phy/smsc.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
5454
return rc < 0 ? rc : 0;
5555
}
5656

57-
static int smsc_phy_config_intr(struct phy_device *phydev)
57+
int smsc_phy_config_intr(struct phy_device *phydev)
5858
{
5959
int rc;
6060

@@ -75,8 +75,9 @@ static int smsc_phy_config_intr(struct phy_device *phydev)
7575

7676
return rc < 0 ? rc : 0;
7777
}
78+
EXPORT_SYMBOL_GPL(smsc_phy_config_intr);
7879

79-
static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
80+
irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
8081
{
8182
int irq_status;
8283

@@ -95,18 +96,20 @@ static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
9596

9697
return IRQ_HANDLED;
9798
}
99+
EXPORT_SYMBOL_GPL(smsc_phy_handle_interrupt);
98100

99-
static int smsc_phy_config_init(struct phy_device *phydev)
101+
int smsc_phy_config_init(struct phy_device *phydev)
100102
{
101103
struct smsc_phy_priv *priv = phydev->priv;
102104

103-
if (!priv->energy_enable || phydev->irq != PHY_POLL)
105+
if (!priv || !priv->energy_enable || phydev->irq != PHY_POLL)
104106
return 0;
105107

106108
/* Enable energy detect power down mode */
107109
return phy_set_bits(phydev, MII_LAN83C185_CTRL_STATUS,
108110
MII_LAN83C185_EDPWRDOWN);
109111
}
112+
EXPORT_SYMBOL_GPL(smsc_phy_config_init);
110113

111114
static int smsc_phy_reset(struct phy_device *phydev)
112115
{
@@ -186,7 +189,7 @@ static int lan95xx_config_aneg_ext(struct phy_device *phydev)
186189
* The workaround is only applicable to poll mode. Energy Detect Power-Down may
187190
* not be used in interrupt mode lest link change detection becomes unreliable.
188191
*/
189-
static int lan87xx_read_status(struct phy_device *phydev)
192+
int lan87xx_read_status(struct phy_device *phydev)
190193
{
191194
struct smsc_phy_priv *priv = phydev->priv;
192195
int err;
@@ -195,7 +198,8 @@ static int lan87xx_read_status(struct phy_device *phydev)
195198
if (err)
196199
return err;
197200

198-
if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) {
201+
if (!phydev->link && priv && priv->energy_enable &&
202+
phydev->irq == PHY_POLL) {
199203
/* Disable EDPD to wake up PHY */
200204
int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
201205
if (rc < 0)
@@ -229,6 +233,7 @@ static int lan87xx_read_status(struct phy_device *phydev)
229233

230234
return err;
231235
}
236+
EXPORT_SYMBOL_GPL(lan87xx_read_status);
232237

233238
static int smsc_get_sset_count(struct phy_device *phydev)
234239
{
@@ -269,7 +274,7 @@ static void smsc_get_stats(struct phy_device *phydev,
269274
data[i] = smsc_get_stat(phydev, i);
270275
}
271276

272-
static int smsc_phy_probe(struct phy_device *phydev)
277+
int smsc_phy_probe(struct phy_device *phydev)
273278
{
274279
struct device *dev = &phydev->mdio.dev;
275280
struct smsc_phy_priv *priv;
@@ -294,6 +299,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
294299

295300
return clk_set_rate(refclk, 50 * 1000 * 1000);
296301
}
302+
EXPORT_SYMBOL_GPL(smsc_phy_probe);
297303

298304
static struct phy_driver smsc_phy_driver[] = {
299305
{

include/linux/smscphy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@
2828
#define MII_LAN83C185_MODE_POWERDOWN 0xC0 /* Power Down mode */
2929
#define MII_LAN83C185_MODE_ALL 0xE0 /* All capable mode */
3030

31+
int smsc_phy_config_intr(struct phy_device *phydev);
32+
irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev);
33+
int smsc_phy_config_init(struct phy_device *phydev);
34+
int lan87xx_read_status(struct phy_device *phydev);
35+
int smsc_phy_probe(struct phy_device *phydev);
36+
3137
#endif /* __LINUX_SMSCPHY_H__ */

0 commit comments

Comments
 (0)