diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index b1aaabb55b89..fdd8d3baaa58 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -3640,11 +3640,13 @@ int ksz_switch_register(struct ksz_device *dev) ret = ksz_switch_detect(dev); if (ret) - return ret; + goto err_out; info = ksz_lookup_info(dev->chip_id); - if (!info) - return -ENODEV; + if (!info) { + ret = -ENODEV; + goto err_out; + } /* Update the compatible info with the probed one */ dev->info = info; @@ -3654,7 +3656,7 @@ int ksz_switch_register(struct ksz_device *dev) ret = ksz_check_device_id(dev); if (ret) - return ret; + goto err_out; dev->dev_ops = dev->info->ops; @@ -3665,8 +3667,10 @@ int ksz_switch_register(struct ksz_device *dev) dev->ports = devm_kzalloc(dev->dev, dev->info->port_cnt * sizeof(struct ksz_port), GFP_KERNEL); - if (!dev->ports) - return -ENOMEM; + if (!dev->ports) { + ret = -ENOMEM; + goto err_out; + } for (i = 0; i < dev->info->port_cnt; i++) { spin_lock_init(&dev->ports[i].mib.stats64_lock); @@ -3675,8 +3679,10 @@ int ksz_switch_register(struct ksz_device *dev) devm_kzalloc(dev->dev, sizeof(u64) * (dev->info->mib_cnt + 1), GFP_KERNEL); - if (!dev->ports[i].mib.counters) - return -ENOMEM; + if (!dev->ports[i].mib.counters) { + ret = -ENOMEM; + goto err_out; + } dev->ports[i].ksz_dev = dev; dev->ports[i].num = i; @@ -3705,7 +3711,8 @@ int ksz_switch_register(struct ksz_device *dev) if (!(dev->port_mask & BIT(port_num))) { of_node_put(port); of_node_put(ports); - return -EINVAL; + ret = -EINVAL; + goto err_out; } of_get_phy_mode(port, &dev->ports[port_num].interface); @@ -3720,7 +3727,8 @@ int ksz_switch_register(struct ksz_device *dev) "microchip,synclko-disable"); if (dev->synclko_125 && dev->synclko_disable) { dev_err(dev->dev, "inconsistent synclko settings\n"); - return -EINVAL; + ret = -EINVAL; + goto err_out; } dev->disable_internal_ldo = of_property_read_bool(dev->dev->of_node, @@ -3733,7 +3741,7 @@ int ksz_switch_register(struct ksz_device *dev) ret = dsa_register_switch(dev->ds); if (ret) { dev->dev_ops->exit(dev); - return ret; + goto err_out; } /* Read MIB counters every 30 seconds to avoid overflow. */ @@ -3744,6 +3752,12 @@ int ksz_switch_register(struct ksz_device *dev) ret = ksz_devlink_param_setup(dev->ds); +err_out: + if (ret && dev->reset_gpio) { + gpiod_set_value_cansleep(dev->reset_gpio, 1); + dev_warn(dev->dev, "ksz_switch_register: err_out: %pe", ERR_PTR(ret)); + } + return ret; } EXPORT_SYMBOL(ksz_switch_register);