@@ -91,13 +91,14 @@ struct otto_emdio_cmd_regs {
9191
9292struct otto_emdio_info {
9393 u32 cmd_fail ;
94+ u32 cmd_read ;
9495 u32 cmd_write ;
9596 struct otto_emdio_cmd_regs cmd_regs ;
9697 u8 num_buses ;
9798 u8 num_ports ;
9899 u16 num_pages ;
99100 int (* read_c22 )(struct mii_bus * bus , int phy_id , int regnum );
100- int (* read_c45 )(struct mii_bus * bus , int phy_id , int dev_addr , int regnum );
101+ int (* read_c45 )(struct mii_bus * bus , int port , int dev_addr , int regnum , u32 * value );
101102 int (* write_c22 )(struct mii_bus * bus , int port , int regnum , u16 value );
102103 int (* write_c45 )(struct mii_bus * bus , int port , int dev_addr , int regnum , u16 value );
103104};
@@ -182,6 +183,26 @@ static int otto_emdio_run_cmd(struct mii_bus *bus, u32 cmd,
182183 return cmdstate & info -> cmd_fail ? - ENXIO : 0 ;
183184}
184185
186+ static int otto_emdio_read_cmd (struct mii_bus * bus , u32 cmd ,
187+ struct otto_emdio_cmd_regs * cmd_data , u32 * value )
188+ {
189+ struct otto_emdio_priv * priv = otto_emdio_bus_to_priv (bus );
190+ int ret ;
191+
192+ lockdep_assert_held (& priv -> lock );
193+ ret = otto_emdio_run_cmd (bus , cmd | priv -> info -> cmd_read , cmd_data );
194+ if (ret )
195+ return ret ;
196+
197+ ret = regmap_read (priv -> regmap , priv -> info -> cmd_regs .io_data , value );
198+ if (ret )
199+ return ret ;
200+
201+ * value = FIELD_GET (PHY_CTRL_DATA , * value );
202+
203+ return 0 ;
204+ }
205+
185206static int otto_emdio_write_cmd (struct mii_bus * bus , u32 cmd ,
186207 struct otto_emdio_cmd_regs * cmd_data )
187208{
@@ -268,58 +289,16 @@ static int otto_emdio_9300_write_c22(struct mii_bus *bus, int port, int regnum,
268289 return otto_emdio_write_cmd (bus , PHY_CTRL_TYPE_C22 , & cmd_data );
269290}
270291
271- static int otto_emdio_9300_read_c45 (struct mii_bus * bus , int phy_id , int dev_addr , int regnum )
292+ static int otto_emdio_9300_read_c45 (struct mii_bus * bus , int port ,
293+ int dev_addr , int regnum , u32 * value )
272294{
273- struct otto_emdio_chan * chan = bus -> priv ;
274- struct otto_emdio_priv * priv ;
275- u32 io_reg , cmd_reg , val ;
276- struct regmap * regmap ;
277- int port ;
278- int err ;
279-
280- priv = chan -> priv ;
281- regmap = priv -> regmap ;
282- io_reg = priv -> info -> cmd_regs .io_data ;
283- cmd_reg = priv -> info -> cmd_regs .c22_data ; /* shared command/C22 register */
284-
285- port = otto_emdio_phy_to_port (bus , phy_id );
286- if (port < 0 )
287- return port ;
288-
289- mutex_lock (& priv -> lock );
290- err = otto_emdio_wait_ready (priv );
291- if (err )
292- goto out_err ;
293-
294- val = FIELD_PREP (PHY_CTRL_INDATA , port );
295- err = regmap_write (regmap , io_reg , val );
296- if (err )
297- goto out_err ;
298-
299- val = FIELD_PREP (PHY_CTRL_MMD_DEVAD , dev_addr ) |
300- FIELD_PREP (PHY_CTRL_MMD_REG , regnum );
301- err = regmap_write (regmap , priv -> info -> cmd_regs .c45_data , val );
302- if (err )
303- goto out_err ;
304-
305- err = regmap_write (regmap , cmd_reg , PHY_CTRL_READ | PHY_CTRL_TYPE_C45 | PHY_CTRL_CMD );
306- if (err )
307- goto out_err ;
308-
309- err = otto_emdio_wait_ready (priv );
310- if (err )
311- goto out_err ;
312-
313- err = regmap_read (regmap , io_reg , & val );
314- if (err )
315- goto out_err ;
316-
317- mutex_unlock (& priv -> lock );
318- return FIELD_GET (PHY_CTRL_DATA , val );
295+ struct otto_emdio_cmd_regs cmd_data = {
296+ .c45_data = FIELD_PREP (PHY_CTRL_MMD_DEVAD , dev_addr ) |
297+ FIELD_PREP (PHY_CTRL_MMD_REG , regnum ),
298+ .io_data = FIELD_PREP (PHY_CTRL_INDATA , port ),
299+ };
319300
320- out_err :
321- mutex_unlock (& priv -> lock );
322- return err ;
301+ return otto_emdio_read_cmd (bus , PHY_CTRL_TYPE_C45 , & cmd_data , value );
323302}
324303
325304static int otto_emdio_9300_write_c45 (struct mii_bus * bus , int port ,
@@ -350,6 +329,22 @@ static int otto_emdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16
350329 return ret ;
351330}
352331
332+ static int otto_emdio_read_c45 (struct mii_bus * bus , int phy_id , int dev_addr , int regnum )
333+ {
334+ struct otto_emdio_priv * priv = otto_emdio_bus_to_priv (bus );
335+ int ret , port ;
336+ u32 value ;
337+
338+ port = otto_emdio_phy_to_port (bus , phy_id );
339+ if (port < 0 )
340+ return port ;
341+
342+ scoped_guard (mutex , & priv -> lock )
343+ ret = priv -> info -> read_c45 (bus , port , dev_addr , regnum , & value );
344+
345+ return ret ? ret : value ;
346+ }
347+
353348static int otto_emdio_write_c45 (struct mii_bus * bus , int phy_id ,
354349 int dev_addr , int regnum , u16 value )
355350{
@@ -439,7 +434,7 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
439434
440435 bus -> name = "Realtek Switch MDIO Bus" ;
441436 if (priv -> smi_bus_is_c45 [mdio_bus ]) {
442- bus -> read_c45 = priv -> info -> read_c45 ;
437+ bus -> read_c45 = otto_emdio_read_c45 ;
443438 bus -> write_c45 = otto_emdio_write_c45 ;
444439 } else {
445440 bus -> read = priv -> info -> read_c22 ;
@@ -561,6 +556,7 @@ static int otto_emdio_probe(struct platform_device *pdev)
561556
562557static const struct otto_emdio_info otto_emdio_9300_info = {
563558 .cmd_fail = PHY_CTRL_FAIL ,
559+ .cmd_read = PHY_CTRL_READ ,
564560 .cmd_write = PHY_CTRL_WRITE ,
565561 .cmd_regs = {
566562 .c22_data = RTL9300_SMI_ACCESS_PHY_CTRL_1 ,
0 commit comments