Skip to content

Commit b4b830a

Browse files
vadimp-nvidiajwrdegoede
authored andcommitted
platform/mellanox: mlxreg-lc: Fix error flow and extend verbosity
Fix error flow: - Clean-up client object in case of probing failure. - Prevent running remove routine in case of probing failure. Probing and removing are invoked by hotplug events raised upon line card insertion and removing. If probing procedure failed all data is cleared and there is nothing to do in remove routine. Fixes: 62f9529 ("platform/mellanox: mlxreg-lc: Add initial support for Nvidia line card devices") Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> Link: https://lore.kernel.org/r/20220719153540.61304-1-vadimp@nvidia.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent c9d959f commit b4b830a

1 file changed

Lines changed: 63 additions & 19 deletions

File tree

drivers/platform/mellanox/mlxreg-lc.c

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,12 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
716716
switch (regval) {
717717
case MLXREG_LC_SN4800_C16:
718718
err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data);
719-
if (err)
719+
if (err) {
720+
dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n",
721+
data->hpdev.brdinfo->type, data->hpdev.nr,
722+
data->hpdev.brdinfo->addr);
720723
return err;
724+
}
721725
break;
722726
default:
723727
return -ENODEV;
@@ -730,8 +734,11 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
730734
mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr,
731735
NULL, 0, mlxreg_lc->mux_data,
732736
sizeof(*mlxreg_lc->mux_data));
733-
if (IS_ERR(mlxreg_lc->mux))
737+
if (IS_ERR(mlxreg_lc->mux)) {
738+
dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n",
739+
data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
734740
return PTR_ERR(mlxreg_lc->mux);
741+
}
735742

736743
/* Register IO access driver. */
737744
if (mlxreg_lc->io_data) {
@@ -740,6 +747,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
740747
platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0,
741748
mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data));
742749
if (IS_ERR(mlxreg_lc->io_regs)) {
750+
dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
751+
data->hpdev.brdinfo->type, data->hpdev.nr,
752+
data->hpdev.brdinfo->addr);
743753
err = PTR_ERR(mlxreg_lc->io_regs);
744754
goto fail_register_io;
745755
}
@@ -753,6 +763,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
753763
mlxreg_lc->led_data,
754764
sizeof(*mlxreg_lc->led_data));
755765
if (IS_ERR(mlxreg_lc->led)) {
766+
dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n",
767+
data->hpdev.brdinfo->type, data->hpdev.nr,
768+
data->hpdev.brdinfo->addr);
756769
err = PTR_ERR(mlxreg_lc->led);
757770
goto fail_register_led;
758771
}
@@ -809,7 +822,8 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
809822
if (!data->hpdev.adapter) {
810823
dev_err(&pdev->dev, "Failed to get adapter for bus %d\n",
811824
data->hpdev.nr);
812-
return -EFAULT;
825+
err = -EFAULT;
826+
goto i2c_get_adapter_fail;
813827
}
814828

815829
/* Create device at the top of line card I2C tree.*/
@@ -818,32 +832,40 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
818832
if (IS_ERR(data->hpdev.client)) {
819833
dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
820834
data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
821-
822-
i2c_put_adapter(data->hpdev.adapter);
823-
data->hpdev.adapter = NULL;
824-
return PTR_ERR(data->hpdev.client);
835+
err = PTR_ERR(data->hpdev.client);
836+
goto i2c_new_device_fail;
825837
}
826838

827839
regmap = devm_regmap_init_i2c(data->hpdev.client,
828840
&mlxreg_lc_regmap_conf);
829841
if (IS_ERR(regmap)) {
842+
dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
843+
data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
830844
err = PTR_ERR(regmap);
831-
goto mlxreg_lc_probe_fail;
845+
goto devm_regmap_init_i2c_fail;
832846
}
833847

834848
/* Set default registers. */
835849
for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) {
836850
err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg,
837851
mlxreg_lc_regmap_default[i].def);
838-
if (err)
839-
goto mlxreg_lc_probe_fail;
852+
if (err) {
853+
dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n",
854+
i, data->hpdev.brdinfo->type, data->hpdev.nr,
855+
data->hpdev.brdinfo->addr);
856+
goto regmap_write_fail;
857+
}
840858
}
841859

842860
/* Sync registers with hardware. */
843861
regcache_mark_dirty(regmap);
844862
err = regcache_sync(regmap);
845-
if (err)
846-
goto mlxreg_lc_probe_fail;
863+
if (err) {
864+
dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
865+
data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
866+
err = PTR_ERR(regmap);
867+
goto regcache_sync_fail;
868+
}
847869

848870
par_pdata = data->hpdev.brdinfo->platform_data;
849871
mlxreg_lc->par_regmap = par_pdata->regmap;
@@ -854,12 +876,27 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
854876
/* Configure line card. */
855877
err = mlxreg_lc_config_init(mlxreg_lc, regmap, data);
856878
if (err)
857-
goto mlxreg_lc_probe_fail;
879+
goto mlxreg_lc_config_init_fail;
858880

859881
return err;
860882

861-
mlxreg_lc_probe_fail:
883+
mlxreg_lc_config_init_fail:
884+
regcache_sync_fail:
885+
regmap_write_fail:
886+
devm_regmap_init_i2c_fail:
887+
if (data->hpdev.client) {
888+
i2c_unregister_device(data->hpdev.client);
889+
data->hpdev.client = NULL;
890+
}
891+
i2c_new_device_fail:
862892
i2c_put_adapter(data->hpdev.adapter);
893+
data->hpdev.adapter = NULL;
894+
i2c_get_adapter_fail:
895+
/* Clear event notification callback and handle. */
896+
if (data->notifier) {
897+
data->notifier->user_handler = NULL;
898+
data->notifier->handle = NULL;
899+
}
863900
return err;
864901
}
865902

@@ -868,11 +905,18 @@ static int mlxreg_lc_remove(struct platform_device *pdev)
868905
struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
869906
struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
870907

871-
/* Clear event notification callback. */
872-
if (data->notifier) {
873-
data->notifier->user_handler = NULL;
874-
data->notifier->handle = NULL;
875-
}
908+
/*
909+
* Probing and removing are invoked by hotplug events raised upon line card insertion and
910+
* removing. If probing procedure fails all data is cleared. However, hotplug event still
911+
* will be raised on line card removing and activate removing procedure. In this case there
912+
* is nothing to remove.
913+
*/
914+
if (!data->notifier || !data->notifier->handle)
915+
return 0;
916+
917+
/* Clear event notification callback and handle. */
918+
data->notifier->user_handler = NULL;
919+
data->notifier->handle = NULL;
876920

877921
/* Destroy static I2C device feeding by main power. */
878922
mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,

0 commit comments

Comments
 (0)