Skip to content

Commit 1d1ae3c

Browse files
IoanaCiorneikuba-moo
authored andcommitted
net: phy: ti: implement generic .handle_interrupt() callback
In an attempt to actually support shared IRQs in phylib, we now move the responsibility of triggering the phylib state machine or just returning IRQ_NONE, based on the IRQ status register, to the PHY driver. Having 3 different IRQ handling callbacks (.handle_interrupt(), .did_interrupt() and .ack_interrupt() ) is confusing so let the PHY driver implement directly an IRQ handler like any other device driver. Make this driver follow the new convention. Cc: Dan Murphy <[email protected]> Signed-off-by: Ioana Ciornei <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a4d7742 commit 1d1ae3c

File tree

6 files changed

+191
-0
lines changed

6 files changed

+191
-0
lines changed

drivers/net/phy/dp83640.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@
5050
#define MII_DP83640_MISR_LINK_INT_EN 0x20
5151
#define MII_DP83640_MISR_ED_INT_EN 0x40
5252
#define MII_DP83640_MISR_LQ_INT_EN 0x80
53+
#define MII_DP83640_MISR_ANC_INT 0x400
54+
#define MII_DP83640_MISR_DUP_INT 0x800
55+
#define MII_DP83640_MISR_SPD_INT 0x1000
56+
#define MII_DP83640_MISR_LINK_INT 0x2000
57+
#define MII_DP83640_MISR_INT_MASK (MII_DP83640_MISR_ANC_INT |\
58+
MII_DP83640_MISR_DUP_INT |\
59+
MII_DP83640_MISR_SPD_INT |\
60+
MII_DP83640_MISR_LINK_INT)
5361

5462
/* phyter seems to miss the mark by 16 ns */
5563
#define ADJTIME_FIX 16
@@ -1193,6 +1201,24 @@ static int dp83640_config_intr(struct phy_device *phydev)
11931201
}
11941202
}
11951203

1204+
static irqreturn_t dp83640_handle_interrupt(struct phy_device *phydev)
1205+
{
1206+
int irq_status;
1207+
1208+
irq_status = phy_read(phydev, MII_DP83640_MISR);
1209+
if (irq_status < 0) {
1210+
phy_error(phydev);
1211+
return IRQ_NONE;
1212+
}
1213+
1214+
if (!(irq_status & MII_DP83640_MISR_INT_MASK))
1215+
return IRQ_NONE;
1216+
1217+
phy_trigger_machine(phydev);
1218+
1219+
return IRQ_HANDLED;
1220+
}
1221+
11961222
static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
11971223
{
11981224
struct dp83640_private *dp83640 =
@@ -1517,6 +1543,7 @@ static struct phy_driver dp83640_driver = {
15171543
.config_init = dp83640_config_init,
15181544
.ack_interrupt = dp83640_ack_interrupt,
15191545
.config_intr = dp83640_config_intr,
1546+
.handle_interrupt = dp83640_handle_interrupt,
15201547
};
15211548

15221549
static int __init dp83640_init(void)

drivers/net/phy/dp83822.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,41 @@ static int dp83822_config_intr(struct phy_device *phydev)
303303
return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
304304
}
305305

306+
static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
307+
{
308+
int irq_status;
309+
310+
/* The MISR1 and MISR2 registers are holding the interrupt status in
311+
* the upper half (15:8), while the lower half (7:0) is used for
312+
* controlling the interrupt enable state of those individual interrupt
313+
* sources. To determine the possible interrupt sources, just read the
314+
* MISR* register and use it directly to know which interrupts have
315+
* been enabled previously or not.
316+
*/
317+
irq_status = phy_read(phydev, MII_DP83822_MISR1);
318+
if (irq_status < 0) {
319+
phy_error(phydev);
320+
return IRQ_NONE;
321+
}
322+
if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
323+
goto trigger_machine;
324+
325+
irq_status = phy_read(phydev, MII_DP83822_MISR2);
326+
if (irq_status < 0) {
327+
phy_error(phydev);
328+
return IRQ_NONE;
329+
}
330+
if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
331+
goto trigger_machine;
332+
333+
return IRQ_NONE;
334+
335+
trigger_machine:
336+
phy_trigger_machine(phydev);
337+
338+
return IRQ_HANDLED;
339+
}
340+
306341
static int dp8382x_disable_wol(struct phy_device *phydev)
307342
{
308343
int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
@@ -576,6 +611,7 @@ static int dp83822_resume(struct phy_device *phydev)
576611
.set_wol = dp83822_set_wol, \
577612
.ack_interrupt = dp83822_ack_interrupt, \
578613
.config_intr = dp83822_config_intr, \
614+
.handle_interrupt = dp83822_handle_interrupt, \
579615
.suspend = dp83822_suspend, \
580616
.resume = dp83822_resume, \
581617
}
@@ -591,6 +627,7 @@ static int dp83822_resume(struct phy_device *phydev)
591627
.set_wol = dp83822_set_wol, \
592628
.ack_interrupt = dp83822_ack_interrupt, \
593629
.config_intr = dp83822_config_intr, \
630+
.handle_interrupt = dp83822_handle_interrupt, \
594631
.suspend = dp83822_suspend, \
595632
.resume = dp83822_resume, \
596633
}

drivers/net/phy/dp83848.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@
3737
DP83848_MISR_SPD_INT_EN | \
3838
DP83848_MISR_LINK_INT_EN)
3939

40+
#define DP83848_MISR_RHF_INT BIT(8)
41+
#define DP83848_MISR_FHF_INT BIT(9)
42+
#define DP83848_MISR_ANC_INT BIT(10)
43+
#define DP83848_MISR_DUP_INT BIT(11)
44+
#define DP83848_MISR_SPD_INT BIT(12)
45+
#define DP83848_MISR_LINK_INT BIT(13)
46+
#define DP83848_MISR_ED_INT BIT(14)
47+
48+
#define DP83848_INT_MASK \
49+
(DP83848_MISR_ANC_INT | \
50+
DP83848_MISR_DUP_INT | \
51+
DP83848_MISR_SPD_INT | \
52+
DP83848_MISR_LINK_INT)
53+
4054
static int dp83848_ack_interrupt(struct phy_device *phydev)
4155
{
4256
int err = phy_read(phydev, DP83848_MISR);
@@ -66,6 +80,24 @@ static int dp83848_config_intr(struct phy_device *phydev)
6680
return phy_write(phydev, DP83848_MICR, control);
6781
}
6882

83+
static irqreturn_t dp83848_handle_interrupt(struct phy_device *phydev)
84+
{
85+
int irq_status;
86+
87+
irq_status = phy_read(phydev, DP83848_MISR);
88+
if (irq_status < 0) {
89+
phy_error(phydev);
90+
return IRQ_NONE;
91+
}
92+
93+
if (!(irq_status & DP83848_INT_MASK))
94+
return IRQ_NONE;
95+
96+
phy_trigger_machine(phydev);
97+
98+
return IRQ_HANDLED;
99+
}
100+
69101
static int dp83848_config_init(struct phy_device *phydev)
70102
{
71103
int val;
@@ -104,6 +136,7 @@ MODULE_DEVICE_TABLE(mdio, dp83848_tbl);
104136
/* IRQ related */ \
105137
.ack_interrupt = dp83848_ack_interrupt, \
106138
.config_intr = dp83848_config_intr, \
139+
.handle_interrupt = dp83848_handle_interrupt, \
107140
}
108141

109142
static struct phy_driver dp83848_driver[] = {

drivers/net/phy/dp83867.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,30 @@ static int dp83867_config_intr(struct phy_device *phydev)
310310
return phy_write(phydev, MII_DP83867_MICR, micr_status);
311311
}
312312

313+
static irqreturn_t dp83867_handle_interrupt(struct phy_device *phydev)
314+
{
315+
int irq_status, irq_enabled;
316+
317+
irq_status = phy_read(phydev, MII_DP83867_ISR);
318+
if (irq_status < 0) {
319+
phy_error(phydev);
320+
return IRQ_NONE;
321+
}
322+
323+
irq_enabled = phy_read(phydev, MII_DP83867_MICR);
324+
if (irq_enabled < 0) {
325+
phy_error(phydev);
326+
return IRQ_NONE;
327+
}
328+
329+
if (!(irq_status & irq_enabled))
330+
return IRQ_NONE;
331+
332+
phy_trigger_machine(phydev);
333+
334+
return IRQ_HANDLED;
335+
}
336+
313337
static int dp83867_read_status(struct phy_device *phydev)
314338
{
315339
int status = phy_read(phydev, MII_DP83867_PHYSTS);
@@ -827,6 +851,7 @@ static struct phy_driver dp83867_driver[] = {
827851
/* IRQ related */
828852
.ack_interrupt = dp83867_ack_interrupt,
829853
.config_intr = dp83867_config_intr,
854+
.handle_interrupt = dp83867_handle_interrupt,
830855

831856
.suspend = genphy_suspend,
832857
.resume = genphy_resume,

drivers/net/phy/dp83869.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,30 @@ static int dp83869_config_intr(struct phy_device *phydev)
207207
return phy_write(phydev, MII_DP83869_MICR, micr_status);
208208
}
209209

210+
static irqreturn_t dp83869_handle_interrupt(struct phy_device *phydev)
211+
{
212+
int irq_status, irq_enabled;
213+
214+
irq_status = phy_read(phydev, MII_DP83869_ISR);
215+
if (irq_status < 0) {
216+
phy_error(phydev);
217+
return IRQ_NONE;
218+
}
219+
220+
irq_enabled = phy_read(phydev, MII_DP83869_MICR);
221+
if (irq_enabled < 0) {
222+
phy_error(phydev);
223+
return IRQ_NONE;
224+
}
225+
226+
if (!(irq_status & irq_enabled))
227+
return IRQ_NONE;
228+
229+
phy_trigger_machine(phydev);
230+
231+
return IRQ_HANDLED;
232+
}
233+
210234
static int dp83869_set_wol(struct phy_device *phydev,
211235
struct ethtool_wolinfo *wol)
212236
{
@@ -852,6 +876,7 @@ static struct phy_driver dp83869_driver[] = {
852876
/* IRQ related */
853877
.ack_interrupt = dp83869_ack_interrupt,
854878
.config_intr = dp83869_config_intr,
879+
.handle_interrupt = dp83869_handle_interrupt,
855880
.read_status = dp83869_read_status,
856881

857882
.get_tunable = dp83869_get_tunable,

drivers/net/phy/dp83tc811.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,49 @@ static int dp83811_config_intr(struct phy_device *phydev)
254254
return err;
255255
}
256256

257+
static irqreturn_t dp83811_handle_interrupt(struct phy_device *phydev)
258+
{
259+
int irq_status;
260+
261+
/* The INT_STAT registers 1, 2 and 3 are holding the interrupt status
262+
* in the upper half (15:8), while the lower half (7:0) is used for
263+
* controlling the interrupt enable state of those individual interrupt
264+
* sources. To determine the possible interrupt sources, just read the
265+
* INT_STAT* register and use it directly to know which interrupts have
266+
* been enabled previously or not.
267+
*/
268+
irq_status = phy_read(phydev, MII_DP83811_INT_STAT1);
269+
if (irq_status < 0) {
270+
phy_error(phydev);
271+
return IRQ_NONE;
272+
}
273+
if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
274+
goto trigger_machine;
275+
276+
irq_status = phy_read(phydev, MII_DP83811_INT_STAT2);
277+
if (irq_status < 0) {
278+
phy_error(phydev);
279+
return IRQ_NONE;
280+
}
281+
if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
282+
goto trigger_machine;
283+
284+
irq_status = phy_read(phydev, MII_DP83811_INT_STAT3);
285+
if (irq_status < 0) {
286+
phy_error(phydev);
287+
return IRQ_NONE;
288+
}
289+
if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
290+
goto trigger_machine;
291+
292+
return IRQ_NONE;
293+
294+
trigger_machine:
295+
phy_trigger_machine(phydev);
296+
297+
return IRQ_HANDLED;
298+
}
299+
257300
static int dp83811_config_aneg(struct phy_device *phydev)
258301
{
259302
int value, err;
@@ -345,6 +388,7 @@ static struct phy_driver dp83811_driver[] = {
345388
.set_wol = dp83811_set_wol,
346389
.ack_interrupt = dp83811_ack_interrupt,
347390
.config_intr = dp83811_config_intr,
391+
.handle_interrupt = dp83811_handle_interrupt,
348392
.suspend = dp83811_suspend,
349393
.resume = dp83811_resume,
350394
},

0 commit comments

Comments
 (0)