mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset handlers
Instead of calling mv88e6xxx_g2_eeprom_wait() directly from
mv88e6xxx_hardware_reset(), add configurable pre- and post-reset hard
reset handlers. Initially, the handlers are set to
mv88e6xxx_g2_eeprom_wait() for all families that have get/set_eeprom()
to match the existing behavior. No functional change intended (except
for additional error messages on failure).
Fixes: 6ccf50d4d4
("net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent")
Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
369dac68d2
commit
0fdd27b9d6
2 changed files with 52 additions and 4 deletions
|
@ -3086,6 +3086,7 @@ static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
|
|||
static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
struct gpio_desc *gpiod = chip->reset;
|
||||
int err;
|
||||
|
||||
/* If there is a GPIO connected to the reset pin, toggle it */
|
||||
if (gpiod) {
|
||||
|
@ -3094,17 +3095,26 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
|
|||
* mid-byte, causing the first EEPROM read after the reset
|
||||
* from the wrong location resulting in the switch booting
|
||||
* to wrong mode and inoperable.
|
||||
* For this reason, switch families with EEPROM support
|
||||
* generally wait for EEPROM loads to complete as their pre-
|
||||
* and post-reset handlers.
|
||||
*/
|
||||
if (chip->info->ops->get_eeprom)
|
||||
mv88e6xxx_g2_eeprom_wait(chip);
|
||||
if (chip->info->ops->hardware_reset_pre) {
|
||||
err = chip->info->ops->hardware_reset_pre(chip);
|
||||
if (err)
|
||||
dev_err(chip->dev, "pre-reset error: %d\n", err);
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(gpiod, 1);
|
||||
usleep_range(10000, 20000);
|
||||
gpiod_set_value_cansleep(gpiod, 0);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
if (chip->info->ops->get_eeprom)
|
||||
mv88e6xxx_g2_eeprom_wait(chip);
|
||||
if (chip->info->ops->hardware_reset_post) {
|
||||
err = chip->info->ops->hardware_reset_post(chip);
|
||||
if (err)
|
||||
dev_err(chip->dev, "post-reset error: %d\n", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4334,6 +4344,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4524,6 +4536,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6352_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4624,6 +4638,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6352_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4718,6 +4734,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4776,6 +4794,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4832,6 +4852,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4891,6 +4913,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6352_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -4944,6 +4968,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
|||
.watchdog_ops = &mv88e6250_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6250_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
|
@ -4991,6 +5017,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -5050,6 +5078,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
|
@ -5096,6 +5126,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
|
@ -5146,6 +5178,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -5301,6 +5335,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6352_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -5363,6 +5399,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -5425,6 +5463,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.watchdog_ops = &mv88e6390_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
@ -5490,6 +5530,8 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
|
|||
.watchdog_ops = &mv88e6393x_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6390_g1_rmu_disable,
|
||||
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
||||
|
|
|
@ -487,6 +487,12 @@ struct mv88e6xxx_ops {
|
|||
int (*ppu_enable)(struct mv88e6xxx_chip *chip);
|
||||
int (*ppu_disable)(struct mv88e6xxx_chip *chip);
|
||||
|
||||
/* Additional handlers to run before and after hard reset, to make sure
|
||||
* that the switch and EEPROM are in a good state.
|
||||
*/
|
||||
int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip);
|
||||
int (*hardware_reset_post)(struct mv88e6xxx_chip *chip);
|
||||
|
||||
/* Switch Software Reset */
|
||||
int (*reset)(struct mv88e6xxx_chip *chip);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue