diff options
| author | Andrew Lunn <andrew@lunn.ch> | 2015-02-14 13:17:50 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-02-19 15:52:25 -0500 |
| commit | f30446839b5a283cde54f7e233bbebc69bbd3d16 (patch) | |
| tree | d3ed4858d8c276f529fa956072f2b9723e0e5fcb /drivers/net | |
| parent | ea8860eb504a953cf8fe0e96c3166201b05c9b73 (diff) | |
net: dsa: mv88e6352: Refactor shareable code
The mv88e6352 allows access to the port phys via an internal mdio bus
which is accessed using registers in the GLOBAL 2 range. The mv88e6171
and probably other devices use the same mechanism. Move this code into
the shared mv88e6xxx.c library.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/dsa/mv88e6352.c | 77 | ||||
| -rw-r--r-- | drivers/net/dsa/mv88e6xxx.c | 53 | ||||
| -rw-r--r-- | drivers/net/dsa/mv88e6xxx.h | 6 |
3 files changed, 71 insertions, 65 deletions
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index e13adc7b3dda..1ebd8f96072a 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c | |||
| @@ -22,59 +22,6 @@ | |||
| 22 | #include <net/dsa.h> | 22 | #include <net/dsa.h> |
| 23 | #include "mv88e6xxx.h" | 23 | #include "mv88e6xxx.h" |
| 24 | 24 | ||
| 25 | static int mv88e6352_wait(struct dsa_switch *ds, int reg, int offset, u16 mask) | ||
| 26 | { | ||
| 27 | unsigned long timeout = jiffies + HZ / 10; | ||
| 28 | |||
| 29 | while (time_before(jiffies, timeout)) { | ||
| 30 | int ret; | ||
| 31 | |||
| 32 | ret = REG_READ(reg, offset); | ||
| 33 | if (!(ret & mask)) | ||
| 34 | return 0; | ||
| 35 | |||
| 36 | usleep_range(1000, 2000); | ||
| 37 | } | ||
| 38 | return -ETIMEDOUT; | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline int mv88e6352_phy_wait(struct dsa_switch *ds) | ||
| 42 | { | ||
| 43 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x18, 0x8000); | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds) | ||
| 47 | { | ||
| 48 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x0800); | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds) | ||
| 52 | { | ||
| 53 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x8000); | ||
| 54 | } | ||
| 55 | |||
| 56 | static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum) | ||
| 57 | { | ||
| 58 | int ret; | ||
| 59 | |||
| 60 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum); | ||
| 61 | |||
| 62 | ret = mv88e6352_phy_wait(ds); | ||
| 63 | if (ret < 0) | ||
| 64 | return ret; | ||
| 65 | |||
| 66 | return REG_READ(REG_GLOBAL2, 0x19); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int __mv88e6352_phy_write(struct dsa_switch *ds, int addr, int regnum, | ||
| 70 | u16 val) | ||
| 71 | { | ||
| 72 | REG_WRITE(REG_GLOBAL2, 0x19, val); | ||
| 73 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum); | ||
| 74 | |||
| 75 | return mv88e6352_phy_wait(ds); | ||
| 76 | } | ||
| 77 | |||
| 78 | static char *mv88e6352_probe(struct device *host_dev, int sw_addr) | 25 | static char *mv88e6352_probe(struct device *host_dev, int sw_addr) |
| 79 | { | 26 | { |
| 80 | struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); | 27 | struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); |
| @@ -346,12 +293,12 @@ static int mv88e6352_phy_page_read(struct dsa_switch *ds, | |||
| 346 | int ret; | 293 | int ret; |
| 347 | 294 | ||
| 348 | mutex_lock(&ps->phy_mutex); | 295 | mutex_lock(&ps->phy_mutex); |
| 349 | ret = __mv88e6352_phy_write(ds, port, 0x16, page); | 296 | ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); |
| 350 | if (ret < 0) | 297 | if (ret < 0) |
| 351 | goto error; | 298 | goto error; |
| 352 | ret = __mv88e6352_phy_read(ds, port, reg); | 299 | ret = mv88e6xxx_phy_read_indirect(ds, port, reg); |
| 353 | error: | 300 | error: |
| 354 | __mv88e6352_phy_write(ds, port, 0x16, 0x0); | 301 | mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); |
| 355 | mutex_unlock(&ps->phy_mutex); | 302 | mutex_unlock(&ps->phy_mutex); |
| 356 | return ret; | 303 | return ret; |
| 357 | } | 304 | } |
| @@ -363,13 +310,13 @@ static int mv88e6352_phy_page_write(struct dsa_switch *ds, | |||
| 363 | int ret; | 310 | int ret; |
| 364 | 311 | ||
| 365 | mutex_lock(&ps->phy_mutex); | 312 | mutex_lock(&ps->phy_mutex); |
| 366 | ret = __mv88e6352_phy_write(ds, port, 0x16, page); | 313 | ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); |
| 367 | if (ret < 0) | 314 | if (ret < 0) |
| 368 | goto error; | 315 | goto error; |
| 369 | 316 | ||
| 370 | ret = __mv88e6352_phy_write(ds, port, reg, val); | 317 | ret = mv88e6xxx_phy_write_indirect(ds, port, reg, val); |
| 371 | error: | 318 | error: |
| 372 | __mv88e6352_phy_write(ds, port, 0x16, 0x0); | 319 | mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); |
| 373 | mutex_unlock(&ps->phy_mutex); | 320 | mutex_unlock(&ps->phy_mutex); |
| 374 | return ret; | 321 | return ret; |
| 375 | } | 322 | } |
| @@ -482,7 +429,7 @@ mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum) | |||
| 482 | return addr; | 429 | return addr; |
| 483 | 430 | ||
| 484 | mutex_lock(&ps->phy_mutex); | 431 | mutex_lock(&ps->phy_mutex); |
| 485 | ret = __mv88e6352_phy_read(ds, addr, regnum); | 432 | ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum); |
| 486 | mutex_unlock(&ps->phy_mutex); | 433 | mutex_unlock(&ps->phy_mutex); |
| 487 | 434 | ||
| 488 | return ret; | 435 | return ret; |
| @@ -499,7 +446,7 @@ mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) | |||
| 499 | return addr; | 446 | return addr; |
| 500 | 447 | ||
| 501 | mutex_lock(&ps->phy_mutex); | 448 | mutex_lock(&ps->phy_mutex); |
| 502 | ret = __mv88e6352_phy_write(ds, addr, regnum, val); | 449 | ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val); |
| 503 | mutex_unlock(&ps->phy_mutex); | 450 | mutex_unlock(&ps->phy_mutex); |
| 504 | 451 | ||
| 505 | return ret; | 452 | return ret; |
| @@ -553,7 +500,7 @@ static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) | |||
| 553 | if (ret < 0) | 500 | if (ret < 0) |
| 554 | goto error; | 501 | goto error; |
| 555 | 502 | ||
| 556 | ret = mv88e6352_eeprom_busy_wait(ds); | 503 | ret = mv88e6xxx_eeprom_busy_wait(ds); |
| 557 | if (ret < 0) | 504 | if (ret < 0) |
| 558 | goto error; | 505 | goto error; |
| 559 | 506 | ||
| @@ -576,7 +523,7 @@ static int mv88e6352_get_eeprom(struct dsa_switch *ds, | |||
| 576 | 523 | ||
| 577 | eeprom->magic = 0xc3ec4951; | 524 | eeprom->magic = 0xc3ec4951; |
| 578 | 525 | ||
| 579 | ret = mv88e6352_eeprom_load_wait(ds); | 526 | ret = mv88e6xxx_eeprom_load_wait(ds); |
| 580 | if (ret < 0) | 527 | if (ret < 0) |
| 581 | return ret; | 528 | return ret; |
| 582 | 529 | ||
| @@ -657,7 +604,7 @@ static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, | |||
| 657 | if (ret < 0) | 604 | if (ret < 0) |
| 658 | goto error; | 605 | goto error; |
| 659 | 606 | ||
| 660 | ret = mv88e6352_eeprom_busy_wait(ds); | 607 | ret = mv88e6xxx_eeprom_busy_wait(ds); |
| 661 | error: | 608 | error: |
| 662 | mutex_unlock(&ps->eeprom_mutex); | 609 | mutex_unlock(&ps->eeprom_mutex); |
| 663 | return ret; | 610 | return ret; |
| @@ -681,7 +628,7 @@ static int mv88e6352_set_eeprom(struct dsa_switch *ds, | |||
| 681 | len = eeprom->len; | 628 | len = eeprom->len; |
| 682 | eeprom->len = 0; | 629 | eeprom->len = 0; |
| 683 | 630 | ||
| 684 | ret = mv88e6352_eeprom_load_wait(ds); | 631 | ret = mv88e6xxx_eeprom_load_wait(ds); |
| 685 | if (ret < 0) | 632 | if (ret < 0) |
| 686 | return ret; | 633 | return ret; |
| 687 | 634 | ||
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 3e7e31a6abb7..a83ace0803e7 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
| @@ -596,6 +596,59 @@ error: | |||
| 596 | } | 596 | } |
| 597 | #endif /* CONFIG_NET_DSA_HWMON */ | 597 | #endif /* CONFIG_NET_DSA_HWMON */ |
| 598 | 598 | ||
| 599 | static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask) | ||
| 600 | { | ||
| 601 | unsigned long timeout = jiffies + HZ / 10; | ||
| 602 | |||
| 603 | while (time_before(jiffies, timeout)) { | ||
| 604 | int ret; | ||
| 605 | |||
| 606 | ret = REG_READ(reg, offset); | ||
| 607 | if (!(ret & mask)) | ||
| 608 | return 0; | ||
| 609 | |||
| 610 | usleep_range(1000, 2000); | ||
| 611 | } | ||
