Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add dev_warn_probe() and improve error handling in

Merge series from Dragan Simic <dsimic@manjaro.org>:

This is a small series that introduces dev_warn_probe() function, which
produces warnings on failed resource acquisitions, and improves error
handling in the probe paths of Rockchip SPI drivers, by using functions
dev_err_probe() and dev_warn_probe() properly in multiple places.

This series also performs a bunch of small, rather trivial code cleanups,
to make the code neater and a bit easier to read.

+116 -44
+102 -29
drivers/base/core.c
··· 4980 4980 4981 4981 #endif 4982 4982 4983 + static void __dev_probe_failed(const struct device *dev, int err, bool fatal, 4984 + const char *fmt, va_list vargsp) 4985 + { 4986 + struct va_format vaf; 4987 + va_list vargs; 4988 + 4989 + /* 4990 + * On x86_64 and possibly on other architectures, va_list is actually a 4991 + * size-1 array containing a structure. As a result, function parameter 4992 + * vargsp decays from T[1] to T*, and &vargsp has type T** rather than 4993 + * T(*)[1], which is expected by its assignment to vaf.va below. 4994 + * 4995 + * One standard way to solve this mess is by creating a copy in a local 4996 + * variable of type va_list and then using a pointer to that local copy 4997 + * instead, which is the approach employed here. 4998 + */ 4999 + va_copy(vargs, vargsp); 5000 + 5001 + vaf.fmt = fmt; 5002 + vaf.va = &vargs; 5003 + 5004 + switch (err) { 5005 + case -EPROBE_DEFER: 5006 + device_set_deferred_probe_reason(dev, &vaf); 5007 + dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 5008 + break; 5009 + 5010 + case -ENOMEM: 5011 + /* Don't print anything on -ENOMEM, there's already enough output */ 5012 + break; 5013 + 5014 + default: 5015 + /* Log fatal final failures as errors, otherwise produce warnings */ 5016 + if (fatal) 5017 + dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 5018 + else 5019 + dev_warn(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 5020 + break; 5021 + } 5022 + 5023 + va_end(vargs); 5024 + } 5025 + 4983 5026 /** 4984 5027 * dev_err_probe - probe error check and log helper 4985 5028 * @dev: the pointer to the struct device ··· 5035 4992 * -EPROBE_DEFER and propagate error upwards. 5036 4993 * In case of -EPROBE_DEFER it sets also defer probe reason, which can be 5037 4994 * checked later by reading devices_deferred debugfs attribute. 5038 - * It replaces code sequence:: 4995 + * It replaces the following code sequence:: 5039 4996 * 5040 4997 * if (err != -EPROBE_DEFER) 5041 4998 * dev_err(dev, ...); ··· 5047 5004 * 5048 5005 * return dev_err_probe(dev, err, ...); 5049 5006 * 5050 - * Using this helper in your probe function is totally fine even if @err is 5051 - * known to never be -EPROBE_DEFER. 5007 + * Using this helper in your probe function is totally fine even if @err 5008 + * is known to never be -EPROBE_DEFER. 5052 5009 * The benefit compared to a normal dev_err() is the standardized format 5053 - * of the error code, it being emitted symbolically (i.e. you get "EAGAIN" 5054 - * instead of "-35") and the fact that the error code is returned which allows 5055 - * more compact error paths. 5010 + * of the error code, which is emitted symbolically (i.e. you get "EAGAIN" 5011 + * instead of "-35"), and having the error code returned allows more 5012 + * compact error paths. 5056 5013 * 5057 5014 * Returns @err. 5058 5015 */ 5059 5016 int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) 5060 5017 { 5061 - struct va_format vaf; 5062 - va_list args; 5018 + va_list vargs; 5063 5019 5064 - va_start(args, fmt); 5065 - vaf.fmt = fmt; 5066 - vaf.va = &args; 5020 + va_start(vargs, fmt); 5067 5021 5068 - switch (err) { 5069 - case -EPROBE_DEFER: 5070 - device_set_deferred_probe_reason(dev, &vaf); 5071 - dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 5072 - break; 5022 + /* Use dev_err() for logging when err doesn't equal -EPROBE_DEFER */ 5023 + __dev_probe_failed(dev, err, true, fmt, vargs); 5073 5024 5074 - case -ENOMEM: 5075 - /* 5076 - * We don't print anything on -ENOMEM, there is already enough 5077 - * output. 5078 - */ 5079 - break; 5080 - 5081 - default: 5082 - dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); 5083 - break; 5084 - } 5085 - 5086 - va_end(args); 5025 + va_end(vargs); 5087 5026 5088 5027 return err; 5089 5028 } 5090 5029 EXPORT_SYMBOL_GPL(dev_err_probe); 5030 + 5031 + /** 5032 + * dev_warn_probe - probe error check and log helper 5033 + * @dev: the pointer to the struct device 5034 + * @err: error value to test 5035 + * @fmt: printf-style format string 5036 + * @...: arguments as specified in the format string 5037 + * 5038 + * This helper implements common pattern present in probe functions for error 5039 + * checking: print debug or warning message depending if the error value is 5040 + * -EPROBE_DEFER and propagate error upwards. 5041 + * In case of -EPROBE_DEFER it sets also defer probe reason, which can be 5042 + * checked later by reading devices_deferred debugfs attribute. 5043 + * It replaces the following code sequence:: 5044 + * 5045 + * if (err != -EPROBE_DEFER) 5046 + * dev_warn(dev, ...); 5047 + * else 5048 + * dev_dbg(dev, ...); 5049 + * return err; 5050 + * 5051 + * with:: 5052 + * 5053 + * return dev_warn_probe(dev, err, ...); 5054 + * 5055 + * Using this helper in your probe function is totally fine even if @err 5056 + * is known to never be -EPROBE_DEFER. 5057 + * The benefit compared to a normal dev_warn() is the standardized format 5058 + * of the error code, which is emitted symbolically (i.e. you get "EAGAIN" 5059 + * instead of "-35"), and having the error code returned allows more 5060 + * compact error paths. 5061 + * 5062 + * Returns @err. 5063 + */ 5064 + int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...) 5065 + { 5066 + va_list vargs; 5067 + 5068 + va_start(vargs, fmt); 5069 + 5070 + /* Use dev_warn() for logging when err doesn't equal -EPROBE_DEFER */ 5071 + __dev_probe_failed(dev, err, false, fmt, vargs); 5072 + 5073 + va_end(vargs); 5074 + 5075 + return err; 5076 + } 5077 + EXPORT_SYMBOL_GPL(dev_warn_probe); 5091 5078 5092 5079 static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) 5093 5080 {
+13 -15
drivers/spi/spi-rockchip.c
··· 773 773 774 774 rs->apb_pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); 775 775 if (IS_ERR(rs->apb_pclk)) { 776 - dev_err(&pdev->dev, "Failed to get apb_pclk\n"); 777 - ret = PTR_ERR(rs->apb_pclk); 776 + ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk), 777 + "Failed to get apb_pclk\n"); 778 778 goto err_put_ctlr; 779 779 } 780 780 781 781 rs->spiclk = devm_clk_get_enabled(&pdev->dev, "spiclk"); 782 782 if (IS_ERR(rs->spiclk)) { 783 - dev_err(&pdev->dev, "Failed to get spi_pclk\n"); 784 - ret = PTR_ERR(rs->spiclk); 783 + ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk), 784 + "Failed to get spi_pclk\n"); 785 785 goto err_put_ctlr; 786 786 } 787 787 ··· 817 817 818 818 rs->fifo_len = get_fifo_len(rs); 819 819 if (!rs->fifo_len) { 820 - dev_err(&pdev->dev, "Failed to get fifo length\n"); 821 - ret = -EINVAL; 820 + ret = dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n"); 822 821 goto err_put_ctlr; 823 822 } 824 823 ··· 857 858 858 859 ctlr->dma_tx = dma_request_chan(rs->dev, "tx"); 859 860 if (IS_ERR(ctlr->dma_tx)) { 860 - /* Check tx to see if we need defer probing driver */ 861 - if (PTR_ERR(ctlr->dma_tx) == -EPROBE_DEFER) { 862 - ret = -EPROBE_DEFER; 861 + /* Check tx to see if we need to defer driver probing */ 862 + ret = dev_warn_probe(rs->dev, PTR_ERR(ctlr->dma_tx), 863 + "Failed to request optional TX DMA channel\n"); 864 + if (ret == -EPROBE_DEFER) 863 865 goto err_disable_pm_runtime; 864 - } 865 - dev_warn(rs->dev, "Failed to request TX DMA channel\n"); 866 866 ctlr->dma_tx = NULL; 867 867 } 868 868 869 869 ctlr->dma_rx = dma_request_chan(rs->dev, "rx"); 870 870 if (IS_ERR(ctlr->dma_rx)) { 871 - if (PTR_ERR(ctlr->dma_rx) == -EPROBE_DEFER) { 872 - ret = -EPROBE_DEFER; 871 + /* Check rx to see if we need to defer driver probing */ 872 + ret = dev_warn_probe(rs->dev, PTR_ERR(ctlr->dma_rx), 873 + "Failed to request optional RX DMA channel\n"); 874 + if (ret == -EPROBE_DEFER) 873 875 goto err_free_dma_tx; 874 - } 875 - dev_warn(rs->dev, "Failed to request RX DMA channel\n"); 876 876 ctlr->dma_rx = NULL; 877 877 } 878 878
+1
include/linux/dev_printk.h
··· 276 276 dev_driver_string(dev), dev_name(dev), ## arg) 277 277 278 278 __printf(3, 4) int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); 279 + __printf(3, 4) int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...); 279 280 280 281 /* Simple helper for dev_err_probe() when ERR_PTR() is to be returned. */ 281 282 #define dev_err_ptr_probe(dev, ___err, fmt, ...) \