]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: adc: ad7124: Add error reporting during probe
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>
Fri, 6 Dec 2024 17:28:41 +0000 (18:28 +0100)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 11 Dec 2024 19:20:48 +0000 (19:20 +0000)
A driver that silently fails to probe is annoying and hard to debug. So
add messages in the error paths of the probe function.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/55e24392f1e4d5b9896f00a52a93c1c4b1feac43.1733504533.git.u.kleine-koenig@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7124.c

index af74bea18a69ffad8bbf0652a7c8ee8bb9566472..ab5c215fbcceb092ec50b864d3f839be87b17998 100644 (file)
@@ -360,20 +360,21 @@ static int ad7124_find_free_config_slot(struct ad7124_state *st)
        return free_cfg_slot;
 }
 
+/* Only called during probe, so dev_err_probe() can be used */
 static int ad7124_init_config_vref(struct ad7124_state *st, struct ad7124_channel_config *cfg)
 {
+       struct device *dev = &st->sd.spi->dev;
        unsigned int refsel = cfg->refsel;
 
        switch (refsel) {
        case AD7124_REFIN1:
        case AD7124_REFIN2:
        case AD7124_AVDD_REF:
-               if (IS_ERR(st->vref[refsel])) {
-                       dev_err(&st->sd.spi->dev,
-                               "Error, trying to use external voltage reference without a %s regulator.\n",
-                               ad7124_ref_names[refsel]);
-                       return PTR_ERR(st->vref[refsel]);
-               }
+               if (IS_ERR(st->vref[refsel]))
+                       return dev_err_probe(dev, PTR_ERR(st->vref[refsel]),
+                                            "Error, trying to use external voltage reference without a %s regulator.\n",
+                                            ad7124_ref_names[refsel]);
+
                cfg->vref_mv = regulator_get_voltage(st->vref[refsel]);
                /* Conversion from uV to mV */
                cfg->vref_mv /= 1000;
@@ -384,8 +385,7 @@ static int ad7124_init_config_vref(struct ad7124_state *st, struct ad7124_channe
                st->adc_control |= AD7124_ADC_CTRL_REF_EN(1);
                return 0;
        default:
-               dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel);
-               return -EINVAL;
+               return dev_err_probe(dev, -EINVAL, "Invalid reference %d\n", refsel);
        }
 }
 
@@ -752,8 +752,10 @@ static const struct iio_info ad7124_info = {
        .attrs = &ad7124_attrs_group,
 };
 
+/* Only called during probe, so dev_err_probe() can be used */
 static int ad7124_soft_reset(struct ad7124_state *st)
 {
+       struct device *dev = &st->sd.spi->dev;
        unsigned int readval, timeout;
        int ret;
 
@@ -766,7 +768,7 @@ static int ad7124_soft_reset(struct ad7124_state *st)
        do {
                ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval);
                if (ret < 0)
-                       return ret;
+                       return dev_err_probe(dev, ret, "Error reading status register\n");
 
                if (!(readval & AD7124_STATUS_POR_FLAG_MSK))
                        return 0;
@@ -775,35 +777,30 @@ static int ad7124_soft_reset(struct ad7124_state *st)
                usleep_range(100, 2000);
        } while (--timeout);
 
-       dev_err(&st->sd.spi->dev, "Soft reset failed\n");
-
-       return -EIO;
+       return dev_err_probe(dev, -EIO, "Soft reset failed\n");
 }
 
 static int ad7124_check_chip_id(struct ad7124_state *st)
 {
+       struct device *dev = &st->sd.spi->dev;
        unsigned int readval, chip_id, silicon_rev;
        int ret;
 
        ret = ad_sd_read_reg(&st->sd, AD7124_ID, 1, &readval);
        if (ret < 0)
-               return ret;
+               return dev_err_probe(dev, ret, "Failure to read ID register\n");
 
        chip_id = AD7124_DEVICE_ID_GET(readval);
        silicon_rev = AD7124_SILICON_REV_GET(readval);
 
-       if (chip_id != st->chip_info->chip_id) {
-               dev_err(&st->sd.spi->dev,
-                       "Chip ID mismatch: expected %u, got %u\n",
-                       st->chip_info->chip_id, chip_id);
-               return -ENODEV;
-       }
+       if (chip_id != st->chip_info->chip_id)
+               return dev_err_probe(dev, -ENODEV,
+                                    "Chip ID mismatch: expected %u, got %u\n",
+                                    st->chip_info->chip_id, chip_id);
 
-       if (silicon_rev == 0) {
-               dev_err(&st->sd.spi->dev,
-                       "Silicon revision empty. Chip may not be present\n");
-               return -ENODEV;
-       }
+       if (silicon_rev == 0)
+               return dev_err_probe(dev, -ENODEV,
+                                    "Silicon revision empty. Chip may not be present\n");
 
        return 0;
 }
@@ -862,16 +859,18 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
        device_for_each_child_node_scoped(dev, child) {
                ret = fwnode_property_read_u32(child, "reg", &channel);
                if (ret)
-                       return ret;
+                       return dev_err_probe(dev, ret,
+                                            "Failed to parse reg property of %pfwP\n", child);
 
                if (channel >= indio_dev->num_channels)
                        return dev_err_probe(dev, -EINVAL,
-                               "Channel index >= number of channels\n");
+                                            "Channel index >= number of channels in %pfwP\n", child);
 
                ret = fwnode_property_read_u32_array(child, "diff-channels",
                                                     ain, 2);
                if (ret)
-                       return ret;
+                       return dev_err_probe(dev, ret,
+                                            "Failed to parse diff-channels property of %pfwP\n", child);
 
                if (!ad7124_valid_input_select(ain[0], st->chip_info) ||
                    !ad7124_valid_input_select(ain[1], st->chip_info))
@@ -908,12 +907,13 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
 
 static int ad7124_setup(struct ad7124_state *st)
 {
+       struct device *dev = &st->sd.spi->dev;
        unsigned int fclk, power_mode;
        int i, ret;
 
        fclk = clk_get_rate(st->mclk);
        if (!fclk)
-               return -EINVAL;
+               return dev_err_probe(dev, -EINVAL, "Failed to get mclk rate\n");
 
        /* The power mode changes the master clock frequency */
        power_mode = ad7124_find_closest_match(ad7124_master_clk_freq_hz,
@@ -922,7 +922,7 @@ static int ad7124_setup(struct ad7124_state *st)
        if (fclk != ad7124_master_clk_freq_hz[power_mode]) {
                ret = clk_set_rate(st->mclk, fclk);
                if (ret)
-                       return ret;
+                       return dev_err_probe(dev, ret, "Failed to set mclk rate\n");
        }
 
        /* Set the power mode */
@@ -950,7 +950,7 @@ static int ad7124_setup(struct ad7124_state *st)
 
        ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control);
        if (ret < 0)
-               return ret;
+               return dev_err_probe(dev, ret, "Failed to setup CONTROL register\n");
 
        return ret;
 }
@@ -963,13 +963,14 @@ static void ad7124_reg_disable(void *r)
 static int ad7124_probe(struct spi_device *spi)
 {
        const struct ad7124_chip_info *info;
+       struct device *dev = &spi->dev;
        struct ad7124_state *st;
        struct iio_dev *indio_dev;
        int i, ret;
 
        info = spi_get_device_match_data(spi);
        if (!info)
-               return -ENODEV;
+               return dev_err_probe(dev, -ENODEV, "Failed to get match data\n");
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (!indio_dev)
@@ -1004,17 +1005,17 @@ static int ad7124_probe(struct spi_device *spi)
 
                ret = regulator_enable(st->vref[i]);
                if (ret)
-                       return ret;
+                       return dev_err_probe(dev, ret, "Failed to enable regulator #%d\n", i);
 
                ret = devm_add_action_or_reset(&spi->dev, ad7124_reg_disable,
                                               st->vref[i]);
                if (ret)
-                       return ret;
+                       return dev_err_probe(dev, ret, "Failed to register disable handler for regulator #%d\n", i);
        }
 
        st->mclk = devm_clk_get_enabled(&spi->dev, "mclk");
        if (IS_ERR(st->mclk))
-               return PTR_ERR(st->mclk);
+               return dev_err_probe(dev, PTR_ERR(st->mclk), "Failed to get mclk\n");
 
        ret = ad7124_soft_reset(st);
        if (ret < 0)
@@ -1030,10 +1031,13 @@ static int ad7124_probe(struct spi_device *spi)
 
        ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
        if (ret < 0)
-               return ret;
+               return dev_err_probe(dev, ret, "Failed to setup triggers\n");
 
-       return devm_iio_device_register(&spi->dev, indio_dev);
+       ret = devm_iio_device_register(&spi->dev, indio_dev);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to register iio device\n");
 
+       return 0;
 }
 
 static const struct of_device_id ad7124_of_match[] = {