2022-01-10 19:54:54

by Sergey Shtylyov

[permalink] [raw]
Subject: [PATCH 0/2] Make platform_get_irq[_byname]_optional() optional

Here are 2 patches making platform_get_irq[_byname]_optional() return 0 on
IRQ not being found, thus aligning those with the other *_optional() APIs;
they are against the 'driver-core-linus' branch of GregKH's 'driver-core.git'
repo plus the patch disallowing IRQ0 in platform_get_irq() and its ilk:

https://lore.kernel.org/lkml/[email protected]/

That patch was against the 'driver-core-linus' branch, so had to do these 2
against that branch as well; tell me if I should rebase to 'driver-core-next'.

Sergey Shtylyov (2):
platform: make platform_get_irq_optional() optional
platform: make platform_get_irq_byname_optional() optional

drivers/base/platform.c | 69 ++++++++++++-------
drivers/char/ipmi/bt-bmc.c | 8 ++-
drivers/counter/interrupt-cnt.c | 4 +-
drivers/edac/xgene_edac.c | 2 +-
drivers/gpio/gpio-altera.c | 3 +-
drivers/gpio/gpio-mvebu.c | 2 +-
drivers/gpio/gpio-tqmx86.c | 2 +-
drivers/gpu/drm/lima/lima_device.c | 2 +-
drivers/i2c/busses/i2c-brcmstb.c | 8 +--
drivers/i2c/busses/i2c-ocores.c | 4 +-
drivers/mailbox/tegra-hsp.c | 4 +-
drivers/mmc/host/sh_mmcif.c | 4 +-
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 +-
drivers/net/can/rcar/rcar_canfd.c | 4 +-
drivers/net/dsa/b53/b53_srab.c | 2 +-
drivers/net/ethernet/davicom/dm9000.c | 2 +-
drivers/net/ethernet/freescale/fec_main.c | 2 +-
drivers/net/ethernet/freescale/fec_ptp.c | 4 +-
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 4 +-
.../ethernet/stmicro/stmmac/stmmac_platform.c | 4 +-
.../pci/controller/dwc/pcie-designware-host.c | 2 +-
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 4 +-
drivers/platform/chrome/cros_ec_lpc.c | 2 +-
drivers/platform/x86/intel/punit_ipc.c | 2 +-
drivers/power/supply/mp2629_charger.c | 4 +-
drivers/spi/spi-bcm-qspi.c | 2 +-
drivers/spi/spi-hisi-sfc-v3xx.c | 2 +-
drivers/spi/spi-mtk-nor.c | 3 +-
drivers/spi/spi-rspi.c | 8 +--
drivers/thermal/rcar_gen3_thermal.c | 2 +-
drivers/tty/serial/8250/8250_mtk.c | 4 +-
drivers/tty/serial/sh-sci.c | 6 +-
drivers/uio/uio_pdrv_genirq.c | 2 +-
drivers/usb/cdns3/cdns3-plat.c | 5 +-
drivers/usb/host/xhci-mtk.c | 2 +-
drivers/usb/mtu3/mtu3_core.c | 2 +-
drivers/vfio/platform/vfio_platform.c | 6 +-
sound/soc/dwc/dwc-i2s.c | 4 +-
38 files changed, 110 insertions(+), 90 deletions(-)

--
2.26.3



2022-01-10 19:55:04

by Sergey Shtylyov

[permalink] [raw]
Subject: [PATCH 1/2] platform: make platform_get_irq_optional() optional

This patch is based on the former Andy Shevchenko's patch:

https://lore.kernel.org/lkml/[email protected]/

Currently platform_get_irq_optional() returns an error code even if IRQ
resource simply has not been found. It prevents the callers from being
error code agnostic in their error handling:

ret = platform_get_irq_optional(...);
if (ret < 0 && ret != -ENXIO)
return ret; // respect deferred probe
if (ret > 0)
...we get an IRQ...

All other *_optional() APIs seem to return 0 or NULL in case an optional
resource is not available. Let's follow this good example, so that the
callers would look like:

ret = platform_get_irq_optional(...);
if (ret < 0)
return ret;
if (ret > 0)
...we get an IRQ...

Reported-by: Matthias Schiffer <[email protected]>
Signed-off-by: Sergey Shtylyov <[email protected]>
---
drivers/base/platform.c | 56 +++++++++++++++---------
drivers/char/ipmi/bt-bmc.c | 8 ++--
drivers/counter/interrupt-cnt.c | 4 +-
drivers/edac/xgene_edac.c | 2 +-
drivers/gpio/gpio-altera.c | 3 +-
drivers/gpio/gpio-mvebu.c | 2 +-
drivers/gpio/gpio-tqmx86.c | 2 +-
drivers/i2c/busses/i2c-brcmstb.c | 8 ++--
drivers/i2c/busses/i2c-ocores.c | 4 +-
drivers/mmc/host/sh_mmcif.c | 4 +-
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 +-
drivers/net/ethernet/davicom/dm9000.c | 2 +-
drivers/net/ethernet/freescale/fec_ptp.c | 2 +-
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 4 +-
drivers/platform/chrome/cros_ec_lpc.c | 2 +-
drivers/platform/x86/intel/punit_ipc.c | 2 +-
drivers/power/supply/mp2629_charger.c | 4 +-
drivers/spi/spi-hisi-sfc-v3xx.c | 2 +-
drivers/spi/spi-mtk-nor.c | 3 +-
drivers/thermal/rcar_gen3_thermal.c | 2 +-
drivers/tty/serial/8250/8250_mtk.c | 4 +-
drivers/tty/serial/sh-sci.c | 6 +--
drivers/uio/uio_pdrv_genirq.c | 2 +-
drivers/vfio/platform/vfio_platform.c | 6 ++-
sound/soc/dwc/dwc-i2s.c | 4 +-
25 files changed, 79 insertions(+), 63 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index fc5a933f3698..7c7b3638f02d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -148,25 +148,7 @@ devm_platform_ioremap_resource_byname(struct platform_device *pdev,
EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
#endif /* CONFIG_HAS_IOMEM */

-/**
- * platform_get_irq_optional - get an optional IRQ for a device
- * @dev: platform device
- * @num: IRQ number index
- *
- * Gets an IRQ for a platform device. Device drivers should check the return
- * value for errors so as to not pass a negative integer value to the
- * request_irq() APIs. This is the same as platform_get_irq(), except that it
- * does not print an error message if an IRQ can not be obtained.
- *
- * For example::
- *
- * int irq = platform_get_irq_optional(pdev, 0);
- * if (irq < 0)
- * return irq;
- *
- * Return: non-zero IRQ number on success, negative error number on failure.
- */
-int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
+static int __platform_get_irq(struct platform_device *dev, unsigned int num)
{
int ret;
#ifdef CONFIG_SPARC
@@ -235,6 +217,38 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
return -EINVAL;
return ret;
}
+
+/**
+ * platform_get_irq_optional - get an optional IRQ for a device
+ * @dev: platform device
+ * @num: IRQ number index
+ *
+ * Gets an IRQ for a platform device. Device drivers should check the return
+ * value for errors so as to not pass a negative integer value to the
+ * request_irq() APIs. This is the same as platform_get_irq(), except that it
+ * does not print an error message if an IRQ can not be obtained and returns
+ * 0 when IRQ resource has not been found.
+ *
+ * For example::
+ *
+ * int irq = platform_get_irq_optional(pdev, 0);
+ * if (irq < 0)
+ * return irq;
+ * if (irq > 0)
+ * ...we have IRQ line defined...
+ *
+ * Return: non-zero IRQ number on success, 0 if IRQ wasn't found, negative error
+ * number on failure.
+ */
+int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
+{
+ int ret;
+
+ ret = __platform_get_irq(dev, num);
+ if (ret == -ENXIO)
+ return 0;
+ return ret;
+}
EXPORT_SYMBOL_GPL(platform_get_irq_optional);

/**
@@ -258,7 +272,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
{
int ret;

- ret = platform_get_irq_optional(dev, num);
+ ret = __platform_get_irq(dev, num);
if (ret < 0 && ret != -EPROBE_DEFER)
dev_err(&dev->dev, "IRQ index %u not found\n", num);

@@ -276,7 +290,7 @@ int platform_irq_count(struct platform_device *dev)
{
int ret, nr = 0;

- while ((ret = platform_get_irq_optional(dev, nr)) >= 0)
+ while ((ret = __platform_get_irq(dev, nr)) >= 0)
nr++;

if (ret == -EPROBE_DEFER)
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 7450904e330a..fdc63bfa5be4 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -382,12 +382,14 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
bt_bmc->irq = platform_get_irq_optional(pdev, 0);
if (bt_bmc->irq < 0)
return bt_bmc->irq;
+ if (!bt_bmc->irq)
+ return 0;

rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
DEVICE_NAME, bt_bmc);
if (rc < 0) {
dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
- bt_bmc->irq = rc;
+ bt_bmc->irq = 0;
return rc;
}

@@ -438,7 +440,7 @@ static int bt_bmc_probe(struct platform_device *pdev)

bt_bmc_config_irq(bt_bmc, pdev);

- if (bt_bmc->irq >= 0) {
+ if (bt_bmc->irq > 0) {
dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
} else {
dev_info(dev, "No IRQ; using timer\n");
@@ -464,7 +466,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev);

misc_deregister(&bt_bmc->miscdev);
- if (bt_bmc->irq < 0)
+ if (bt_bmc->irq <= 0)
del_timer_sync(&bt_bmc->poll_timer);
return 0;
}
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index 8514a87fcbee..a0564c035961 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -156,9 +156,7 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
return -ENOMEM;

priv->irq = platform_get_irq_optional(pdev, 0);
- if (priv->irq == -ENXIO)
- priv->irq = 0;
- else if (priv->irq < 0)
+ if (priv->irq < 0)
return dev_err_probe(dev, priv->irq, "failed to get IRQ\n");

priv->gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_IN);
diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index 2ccd1db5e98f..0d1bdd27cd78 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -1917,7 +1917,7 @@ static int xgene_edac_probe(struct platform_device *pdev)

for (i = 0; i < 3; i++) {
irq = platform_get_irq_optional(pdev, i);
- if (irq < 0) {
+ if (irq <= 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
rc = -EINVAL;
goto out_err;
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
index b59fae993626..02a2995aa368 100644
--- a/drivers/gpio/gpio-altera.c
+++ b/drivers/gpio/gpio-altera.c
@@ -267,8 +267,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
altera_gc->mmchip.gc.parent = &pdev->dev;

altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0);
-
- if (altera_gc->mapped_irq < 0)
+ if (altera_gc->mapped_irq <= 0)
goto skip_irq;

if (of_property_read_u32(node, "altr,interrupt-type", &reg)) {
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 8f429d9f3661..a72a7bfc5a92 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -1294,7 +1294,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
for (i = 0; i < 4; i++) {
int irq = platform_get_irq_optional(pdev, i);

- if (irq < 0)
+ if (irq <= 0)
continue;
irq_set_chained_handler_and_data(irq, mvebu_gpio_irq_handler,
mvchip);
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
index 5b103221b58d..dc0f83236ce8 100644
--- a/drivers/gpio/gpio-tqmx86.c
+++ b/drivers/gpio/gpio-tqmx86.c
@@ -237,7 +237,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
int ret, irq;

irq = platform_get_irq_optional(pdev, 0);
- if (irq < 0 && irq != -ENXIO)
+ if (irq < 0)
return irq;

res = platform_get_resource(pdev, IORESOURCE_IO, 0);
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 490ee3962645..69395ae27a1a 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -250,7 +250,7 @@ static int brcmstb_i2c_wait_for_completion(struct brcmstb_i2c_dev *dev)
int ret = 0;
unsigned long timeout = msecs_to_jiffies(I2C_TIMEOUT);

- if (dev->irq >= 0) {
+ if (dev->irq > 0) {
if (!wait_for_completion_timeout(&dev->done, timeout))
ret = -ETIMEDOUT;
} else {
@@ -297,7 +297,7 @@ static int brcmstb_send_i2c_cmd(struct brcmstb_i2c_dev *dev,
return rc;

/* only if we are in interrupt mode */
- if (dev->irq >= 0)
+ if (dev->irq > 0)
reinit_completion(&dev->done);

/* enable BSC CTL interrupt line */
@@ -652,7 +652,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);

/* register the ISR handler */
- if (dev->irq >= 0) {
+ if (dev->irq > 0) {
rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr,
IRQF_SHARED,
int_name ? int_name : pdev->name,
@@ -696,7 +696,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)

dev_info(dev->device, "%s@%dhz registered in %s mode\n",
int_name ? int_name : " ", dev->clk_freq_hz,
- (dev->irq >= 0) ? "interrupt" : "polling");
+ (dev->irq > 0) ? "interrupt" : "polling");

return 0;

diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index a0af027db04c..1f4d5e52ff42 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -691,10 +691,10 @@ static int ocores_i2c_probe(struct platform_device *pdev)
if (of_device_is_compatible(pdev->dev.of_node,
"sifive,fu540-c000-i2c")) {
i2c->flags |= OCORES_FLAG_BROKEN_IRQ;
- irq = -ENXIO;
+ irq = 0;
}

- if (irq == -ENXIO) {
+ if (!irq) {
ocores_algorithm.master_xfer = ocores_xfer_polling;
} else {
if (irq < 0)
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index bcc595c70a9f..f558b9862032 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1465,14 +1465,14 @@ static int sh_mmcif_probe(struct platform_device *pdev)
sh_mmcif_sync_reset(host);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

- name = irq[1] < 0 ? dev_name(dev) : "sh_mmc:error";
+ name = irq[1] <= 0 ? dev_name(dev) : "sh_mmc:error";
ret = devm_request_threaded_irq(dev, irq[0], sh_mmcif_intr,
sh_mmcif_irqt, 0, name, host);
if (ret) {
dev_err(dev, "request_irq error (%s)\n", name);
goto err_clk;
}
- if (irq[1] >= 0) {
+ if (irq[1] > 0) {
ret = devm_request_threaded_irq(dev, irq[1],
sh_mmcif_intr, sh_mmcif_irqt,
0, "sh_mmc:int", host);
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index f75929783b94..ac222985efde 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1521,7 +1521,7 @@ static irqreturn_t brcmnand_ctlrdy_irq(int irq, void *data)

/* check if you need to piggy back on the ctrlrdy irq */
if (ctrl->edu_pending) {
- if (irq == ctrl->irq && ((int)ctrl->edu_irq >= 0))
+ if (irq == ctrl->irq && ((int)ctrl->edu_irq > 0))
/* Discard interrupts while using dedicated edu irq */
return IRQ_HANDLED;

@@ -2956,7 +2956,7 @@ static int brcmnand_edu_setup(struct platform_device *pdev)
brcmnand_edu_init(ctrl);

ctrl->edu_irq = platform_get_irq_optional(pdev, 1);
- if (ctrl->edu_irq < 0) {
+ if (ctrl->edu_irq <= 0) {
dev_warn(dev,
"FLASH EDU enabled, using ctlrdy irq\n");
} else {
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 0985ab216566..740c660a9411 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -1509,7 +1509,7 @@ dm9000_probe(struct platform_device *pdev)
}

db->irq_wake = platform_get_irq_optional(pdev, 1);
- if (db->irq_wake >= 0) {
+ if (db->irq_wake > 0) {
dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);

ret = request_irq(db->irq_wake, dm9000_wol_interrupt,
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index d71eac7e1924..158676eda48d 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -620,7 +620,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
/* Failure to get an irq is not fatal,
* only the PTP_CLOCK_PPS clock events should stop
*/
- if (irq >= 0) {
+ if (irq > 0) {
ret = devm_request_irq(&pdev->dev, irq, fec_pps_interrupt,
0, pdev->name, ndev);
if (ret < 0)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 9de617ca9daa..4914d6aca208 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -439,7 +439,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
u32 val;
int ret;

- if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) {
+ if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq > 0) {
INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq,
IRQF_SHARED, dev_name(channel->dev), channel);
@@ -486,7 +486,7 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
val &= ~USB2_INT_ENABLE_UCOM_INTEN;
writel(val, usb2_base + USB2_INT_ENABLE);

- if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel))
+ if (channel->irq > 0 && !rcar_gen3_is_any_rphy_initialized(channel))
free_irq(channel->irq, channel);

return 0;
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index d6306d2a096f..91686d306534 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -400,7 +400,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
irq = platform_get_irq_optional(pdev, 0);
if (irq > 0)
ec_dev->irq = irq;
- else if (irq != -ENXIO) {
+ else if (irq < 0) {
dev_err(dev, "couldn't retrieve IRQ number (%d)\n", irq);
return irq;
}
diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
index 66bb39fd0ef9..f3cf5ee1466f 100644
--- a/drivers/platform/x86/intel/punit_ipc.c
+++ b/drivers/platform/x86/intel/punit_ipc.c
@@ -278,7 +278,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, punit_ipcdev);

irq = platform_get_irq_optional(pdev, 0);
- if (irq < 0) {
+ if (irq <= 0) {
dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n");
} else {
ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
index bdf924b73e47..51289700a7ac 100644
--- a/drivers/power/supply/mp2629_charger.c
+++ b/drivers/power/supply/mp2629_charger.c
@@ -581,9 +581,9 @@ static int mp2629_charger_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, charger);

irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);
- if (irq < 0) {
+ if (irq <= 0) {
dev_err(dev, "get irq fail: %d\n", irq);
- return irq;
+ return irq < 0 ? irq : -ENXIO;
}

for (i = 0; i < MP2629_MAX_FIELD; i++) {
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index d3a23b1c2a4c..476ddc081c60 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -467,7 +467,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
dev_err(dev, "failed to request irq%d, ret = %d\n", host->irq, ret);
host->irq = 0;
}
- } else {
+ } else if (host->irq < 0) {
host->irq = 0;
}

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 5c93730615f8..2422b0545936 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -829,8 +829,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
mtk_nor_init(sp);

irq = platform_get_irq_optional(pdev, 0);
-
- if (irq < 0) {
+ if (irq <= 0) {
dev_warn(sp->dev, "IRQ not available.");
} else {
ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0,
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 43eb25b167bc..776cfed4339c 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -430,7 +430,7 @@ static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,

for (i = 0; i < 2; i++) {
irq = platform_get_irq_optional(pdev, i);
- if (irq < 0)
+ if (irq <= 0)
return irq;

irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d",
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index fb65dc601b23..328ab074fd89 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -621,7 +621,7 @@ static int __maybe_unused mtk8250_suspend(struct device *dev)
serial8250_suspend_port(data->line);

pinctrl_pm_select_sleep_state(dev);
- if (irq >= 0) {
+ if (irq > 0) {
err = enable_irq_wake(irq);
if (err) {
dev_err(dev,
@@ -641,7 +641,7 @@ static int __maybe_unused mtk8250_resume(struct device *dev)
struct mtk8250_data *data = dev_get_drvdata(dev);
int irq = data->rx_wakeup_irq;

- if (irq >= 0)
+ if (irq > 0)
disable_irq_wake(irq);
pinctrl_pm_select_default_state(dev);

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 89ee43061d3a..a67f8e532a73 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1926,7 +1926,7 @@ static int sci_request_irq(struct sci_port *port)
* Certain port types won't support all of the
* available interrupt sources.
*/
- if (unlikely(irq < 0))
+ if (unlikely(irq <= 0))
continue;
}

@@ -1974,7 +1974,7 @@ static void sci_free_irq(struct sci_port *port)
* Certain port types won't support all of the available
* interrupt sources.
*/
- if (unlikely(irq < 0))
+ if (unlikely(irq <= 0))
continue;

/* Check if already freed (irq was muxed) */
@@ -2901,7 +2901,7 @@ static int sci_init_single(struct platform_device *dev,
if (sci_port->irqs[0] < 0)
return -ENXIO;

- if (sci_port->irqs[1] < 0)
+ if (sci_port->irqs[1] <= 0)
for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++)
sci_port->irqs[i] = sci_port->irqs[0];

diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 63258b6accc4..7fd275fc6ceb 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -162,7 +162,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
if (!uioinfo->irq) {
ret = platform_get_irq_optional(pdev, 0);
uioinfo->irq = ret;
- if (ret == -ENXIO)
+ if (!ret)
uioinfo->irq = UIO_IRQ_NONE;
else if (ret == -EPROBE_DEFER)
return ret;
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index 68a1c87066d7..cd7494933563 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -32,8 +32,12 @@ static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
static int get_platform_irq(struct vfio_platform_device *vdev, int i)
{
struct platform_device *pdev = (struct platform_device *) vdev->opaque;
+ int ret;

- return platform_get_irq_optional(pdev, i);
+ ret = platform_get_irq_optional(pdev, i);
+ if (ret < 0)
+ return ret;
+ return ret > 0 ? ret : -ENXIO;
}

static int vfio_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index 5cb58929090d..ff19c5130459 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -643,7 +643,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
dev->dev = &pdev->dev;

irq = platform_get_irq_optional(pdev, 0);
- if (irq >= 0) {
+ if (irq > 0) {
ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
pdev->name, dev);
if (ret < 0) {
@@ -697,7 +697,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
}

if (!pdata) {
- if (irq >= 0) {
+ if (irq > 0) {
ret = dw_pcm_register(pdev);
dev->use_pio = true;
} else {
--
2.26.3


2022-01-10 19:55:10

by Sergey Shtylyov

[permalink] [raw]
Subject: [PATCH 2/2] platform: make platform_get_irq_byname_optional() optional

Currently platform_get_irq_byname_optional() returns an error code even
if IRQ resource simply has not been found. It prevents the callers from
being error code agnostic in their error handling:

ret = platform_get_irq_byname_optional(...);
if (ret < 0 && ret != -ENXIO)
return ret; // respect deferred probe
if (ret > 0)
...we get an IRQ...

All other *_optional() APIs seem to return 0 or NULL in case an optional
resource is not available. Let's follow this good example, so that the
callers would look like:

ret = platform_get_irq_byname_optional(...);
if (ret < 0)
return ret;
if (ret > 0)
...we get an IRQ...

Signed-off-by: Sergey Shtylyov <[email protected]>
---
drivers/base/platform.c | 13 ++++++++++---
drivers/gpu/drm/lima/lima_device.c | 2 +-
drivers/mailbox/tegra-hsp.c | 4 ++--
drivers/net/can/rcar/rcar_canfd.c | 4 ++--
drivers/net/dsa/b53/b53_srab.c | 2 +-
drivers/net/ethernet/freescale/fec_main.c | 2 +-
drivers/net/ethernet/freescale/fec_ptp.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 4 ++--
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 4 ++--
drivers/pci/controller/dwc/pcie-designware-host.c | 2 +-
drivers/spi/spi-bcm-qspi.c | 2 +-
drivers/spi/spi-rspi.c | 8 ++++----
drivers/usb/cdns3/cdns3-plat.c | 5 +----
drivers/usb/host/xhci-mtk.c | 2 +-
drivers/usb/mtu3/mtu3_core.c | 2 +-
15 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 7c7b3638f02d..1d0ea635922b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -495,14 +495,21 @@ EXPORT_SYMBOL_GPL(platform_get_irq_byname);
* @name: IRQ name
*
* Get an optional IRQ by name like platform_get_irq_byname(). Except that it
- * does not print an error message if an IRQ can not be obtained.
+ * does not print an error message if an IRQ can not be obtained and returns
+ * 0 when IRQ resource has not been found.
*
- * Return: non-zero IRQ number on success, negative error number on failure.
+ * Return: non-zero IRQ number on success, 0 if IRQ wasn't found, negative error
+ * number on failure.
*/
int platform_get_irq_byname_optional(struct platform_device *dev,
const char *name)
{
- return __platform_get_irq_byname(dev, name);
+ int ret;
+
+ ret = __platform_get_irq_byname(dev, name);
+ if (ret == -ENXIO)
+ return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname_optional);

diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
index 65fdca366e41..e3659aa687c2 100644
--- a/drivers/gpu/drm/lima/lima_device.c
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -223,7 +223,7 @@ static int lima_init_ip(struct lima_device *dev, int index)
if (irq_name) {
err = must ? platform_get_irq_byname(pdev, irq_name) :
platform_get_irq_byname_optional(pdev, irq_name);
- if (err < 0)
+ if (err <= 0)
goto out;
ip->irq = err;
}
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
index acd0675da681..17aa88e31445 100644
--- a/drivers/mailbox/tegra-hsp.c
+++ b/drivers/mailbox/tegra-hsp.c
@@ -667,7 +667,7 @@ static int tegra_hsp_probe(struct platform_device *pdev)
hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK;

err = platform_get_irq_byname_optional(pdev, "doorbell");
- if (err >= 0)
+ if (err > 0)
hsp->doorbell_irq = err;

if (hsp->num_si > 0) {
@@ -687,7 +687,7 @@ static int tegra_hsp_probe(struct platform_device *pdev)
return -ENOMEM;

err = platform_get_irq_byname_optional(pdev, name);
- if (err >= 0) {
+ if (err > 0) {
hsp->shared_irqs[i] = err;
count++;
}
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index ff9d0f5ae0dd..1d4794493c6a 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1778,7 +1778,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)

if (chip_id == RENESAS_RCAR_GEN3) {
ch_irq = platform_get_irq_byname_optional(pdev, "ch_int");
- if (ch_irq < 0) {
+ if (ch_irq <= 0) {
/* For backward compatibility get irq by index */
ch_irq = platform_get_irq(pdev, 0);
if (ch_irq < 0)
@@ -1786,7 +1786,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
}

g_irq = platform_get_irq_byname_optional(pdev, "g_int");
- if (g_irq < 0) {
+ if (g_irq <= 0) {
/* For backward compatibility get irq by index */
g_irq = platform_get_irq(pdev, 1);
if (g_irq < 0)
diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c
index 4591bb1c05d2..80b7c8f053ad 100644
--- a/drivers/net/dsa/b53/b53_srab.c
+++ b/drivers/net/dsa/b53/b53_srab.c
@@ -420,7 +420,7 @@ static int b53_srab_irq_enable(struct b53_device *dev, int port)
/* Interrupt is optional and was not specified, do not make
* this fatal
*/
- if (p->irq == -ENXIO)
+ if (!p->irq)
return ret;

ret = request_threaded_irq(p->irq, b53_srab_port_isr,
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index bc418b910999..fba36d09a6e0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3933,7 +3933,7 @@ fec_probe(struct platform_device *pdev)
for (i = 0; i < irq_cnt; i++) {
snprintf(irq_name, sizeof(irq_name), "int%d", i);
irq = platform_get_irq_byname_optional(pdev, irq_name);
- if (irq < 0)
+ if (irq <= 0)
irq = platform_get_irq(pdev, i);
if (irq < 0) {
ret = irq;
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index 158676eda48d..251863c2d5a4 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -615,7 +615,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep);

irq = platform_get_irq_byname_optional(pdev, "pps");
- if (irq < 0)
+ if (irq <= 0)
irq = platform_get_irq_optional(pdev, irq_idx);
/* Failure to get an irq is not fatal,
* only the PTP_CLOCK_PPS clock events should stop
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index 2b38a499a404..5519b5b35365 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -342,7 +342,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER)
return -EPROBE_DEFER;

- if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
+ if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup > 0) {
err = device_init_wakeup(&pdev->dev, true);
if (err) {
dev_err(&pdev->dev, "Failed to init wake up irq\n");
@@ -426,7 +426,7 @@ static int stm32_dwmac_remove(struct platform_device *pdev)

stm32_dwmac_clk_disable(priv->plat->bsp_priv);

- if (dwmac->irq_pwr_wakeup >= 0) {
+ if (dwmac->irq_pwr_wakeup > 0) {
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 232ac98943cd..dcfc04f7bfd4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -679,7 +679,7 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
*/
stmmac_res->wol_irq =
platform_get_irq_byname_optional(pdev, "eth_wake_irq");
- if (stmmac_res->wol_irq < 0) {
+ if (stmmac_res->wol_irq <= 0) {
if (stmmac_res->wol_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n");
@@ -688,7 +688,7 @@ int stmmac_get_platform_resources(struct platform_device *pdev,

stmmac_res->lpi_irq =
platform_get_irq_byname_optional(pdev, "eth_lpi");
- if (stmmac_res->lpi_irq < 0) {
+ if (stmmac_res->lpi_irq <= 0) {
if (stmmac_res->lpi_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index f4755f3a03be..00e1a33fd06d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -364,7 +364,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
} else if (pp->has_msi_ctrl) {
if (!pp->msi_irq) {
pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
- if (pp->msi_irq < 0) {
+ if (pp->msi_irq <= 0) {
pp->msi_irq = platform_get_irq(pdev, 0);
if (pp->msi_irq < 0)
return pp->msi_irq;
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index f3de3305d0f5..40ca101e9875 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -1595,7 +1595,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
irq = platform_get_irq(pdev, 0);
}

- if (irq >= 0) {
+ if (irq > 0) {
ret = devm_request_irq(&pdev->dev, irq,
qspi_irq_tab[val].irq_handler, 0,
name,
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 41761f0d892a..b736b57f5ff2 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1330,16 +1330,16 @@ static int rspi_probe(struct platform_device *pdev)
ctlr->max_native_cs = rspi->ops->num_hw_ss;

ret = platform_get_irq_byname_optional(pdev, "rx");
- if (ret < 0) {
+ if (ret <= 0) {
ret = platform_get_irq_byname_optional(pdev, "mux");
- if (ret < 0)
+ if (ret <= 0)
ret = platform_get_irq(pdev, 0);
- if (ret >= 0)
+ if (ret > 0)
rspi->rx_irq = rspi->tx_irq = ret;
} else {
rspi->rx_irq = ret;
ret = platform_get_irq_byname(pdev, "tx");
- if (ret >= 0)
+ if (ret > 0)
rspi->tx_irq = ret;
}

diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c
index 4d0f027e5bd3..7379b6026f9f 100644
--- a/drivers/usb/cdns3/cdns3-plat.c
+++ b/drivers/usb/cdns3/cdns3-plat.c
@@ -108,10 +108,7 @@ static int cdns3_plat_probe(struct platform_device *pdev)
cdns->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup");
if (cdns->wakeup_irq == -EPROBE_DEFER)
return cdns->wakeup_irq;
- else if (cdns->wakeup_irq == 0)
- return -EINVAL;
-
- if (cdns->wakeup_irq < 0) {
+ if (cdns->wakeup_irq <= 0) {
dev_dbg(dev, "couldn't get wakeup irq\n");
cdns->wakeup_irq = 0x0;
}
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 58a0eae4f41b..e3071e7cb165 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -495,7 +495,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
return ret;

irq = platform_get_irq_byname_optional(pdev, "host");
- if (irq < 0) {
+ if (irq <= 0) {
if (irq == -EPROBE_DEFER)
return irq;

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index c4a2c37abf62..08173c05a1d6 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -925,7 +925,7 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
return -ENOMEM;

mtu->irq = platform_get_irq_byname_optional(pdev, "device");
- if (mtu->irq < 0) {
+ if (mtu->irq <= 0) {
if (mtu->irq == -EPROBE_DEFER)
return mtu->irq;

--
2.26.3


2022-01-10 20:11:47

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello,

On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> This patch is based on the former Andy Shevchenko's patch:
>
> https://lore.kernel.org/lkml/[email protected]/
>
> Currently platform_get_irq_optional() returns an error code even if IRQ
> resource simply has not been found. It prevents the callers from being
> error code agnostic in their error handling:
>
> ret = platform_get_irq_optional(...);
> if (ret < 0 && ret != -ENXIO)
> return ret; // respect deferred probe
> if (ret > 0)
> ...we get an IRQ...
>
> All other *_optional() APIs seem to return 0 or NULL in case an optional
> resource is not available. Let's follow this good example, so that the
> callers would look like:
>
> ret = platform_get_irq_optional(...);
> if (ret < 0)
> return ret;
> if (ret > 0)
> ...we get an IRQ...

The difference to gpiod_get_optional (and most other *_optional) is that
you can use the NULL value as if it were a valid GPIO.

As this isn't given with for irqs, I don't think changing the return
value has much sense. In my eyes the problem with platform_get_irq() and
platform_get_irq_optional() is that someone considered it was a good
idea that a global function emits an error message. The problem is,
that's only true most of the time. (Sometimes the caller can handle an
error (here: the absence of an irq) just fine, sometimes the generic
error message just isn't as good as a message by the caller could be.
(here: The caller could emit "TX irq not found" which is a much nicer
message than "IRQ index 5 not found".)

My suggestion would be to keep the return value of
platform_get_irq_optional() as is, but rename it to
platform_get_irq_silent() to get rid of the expectation invoked by the
naming similarity that motivated you to change
platform_get_irq_optional().

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (1.98 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-10 21:08:43

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > This patch is based on the former Andy Shevchenko's patch:
> >
> > https://lore.kernel.org/lkml/[email protected]/
> >
> > Currently platform_get_irq_optional() returns an error code even if IRQ
> > resource simply has not been found. It prevents the callers from being
> > error code agnostic in their error handling:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0 && ret != -ENXIO)
> > return ret; // respect deferred probe
> > if (ret > 0)
> > ...we get an IRQ...
> >
> > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > resource is not available. Let's follow this good example, so that the
> > callers would look like:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0)
> > return ret;
> > if (ret > 0)
> > ...we get an IRQ...
>
> The difference to gpiod_get_optional (and most other *_optional) is that
> you can use the NULL value as if it were a valid GPIO.

The problem is not only there, but also in the platform_get_irq() and that
problem is called vIRQ0. Or as Linus put it "_cookie_" for IRQ, which never
ever should be 0.

> As this isn't given with for irqs, I don't think changing the return
> value has much sense. In my eyes the problem with platform_get_irq() and
> platform_get_irq_optional() is that someone considered it was a good
> idea that a global function emits an error message. The problem is,
> that's only true most of the time. (Sometimes the caller can handle an
> error (here: the absence of an irq) just fine, sometimes the generic
> error message just isn't as good as a message by the caller could be.
> (here: The caller could emit "TX irq not found" which is a much nicer
> message than "IRQ index 5 not found".)
>
> My suggestion would be to keep the return value of
> platform_get_irq_optional() as is, but rename it to
> platform_get_irq_silent() to get rid of the expectation invoked by the
> naming similarity that motivated you to change
> platform_get_irq_optional().

This won't fix the issue with vIRQ0.

--
With Best Regards,
Andy Shevchenko



2022-01-10 21:19:50

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> Hello,
>
> On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > This patch is based on the former Andy Shevchenko's patch:
> >
> > https://lore.kernel.org/lkml/[email protected]/
> >
> > Currently platform_get_irq_optional() returns an error code even if IRQ
> > resource simply has not been found. It prevents the callers from being
> > error code agnostic in their error handling:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0 && ret != -ENXIO)
> > return ret; // respect deferred probe
> > if (ret > 0)
> > ...we get an IRQ...
> >
> > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > resource is not available. Let's follow this good example, so that the
> > callers would look like:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0)
> > return ret;
> > if (ret > 0)
> > ...we get an IRQ...
>
> The difference to gpiod_get_optional (and most other *_optional) is that
> you can use the NULL value as if it were a valid GPIO.
>
> As this isn't given with for irqs, I don't think changing the return
> value has much sense.

We actually want platform_get_irq_optional() to look different to all
the other _optional() methods because it is not equivalent. If it
looks the same, developers will assume it is the same, and get
themselves into trouble.

> My suggestion would be to keep the return value of
> platform_get_irq_optional() as is, but rename it to
> platform_get_irq_silent() to get rid of the expectation invoked by
> the naming similarity that motivated you to change
> platform_get_irq_optional().

This is a good idea.

Andrew

2022-01-10 21:46:38

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 10, 2022 at 11:07:03PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > This patch is based on the former Andy Shevchenko's patch:
> > >
> > > https://lore.kernel.org/lkml/[email protected]/
> > >
> > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > resource simply has not been found. It prevents the callers from being
> > > error code agnostic in their error handling:
> > >
> > > ret = platform_get_irq_optional(...);
> > > if (ret < 0 && ret != -ENXIO)
> > > return ret; // respect deferred probe
> > > if (ret > 0)
> > > ...we get an IRQ...
> > >
> > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > resource is not available. Let's follow this good example, so that the
> > > callers would look like:
> > >
> > > ret = platform_get_irq_optional(...);
> > > if (ret < 0)
> > > return ret;
> > > if (ret > 0)
> > > ...we get an IRQ...
> >
> > The difference to gpiod_get_optional (and most other *_optional) is that
> > you can use the NULL value as if it were a valid GPIO.
>
> The problem is not only there, but also in the platform_get_irq() and that
> problem is called vIRQ0. Or as Linus put it "_cookie_" for IRQ, which never
> ever should be 0.

IMHO it's best to avoid yielding zero for a value that should be
interpreted as an (virtual) irq. Then callers don't even have to
consider if it's a valid value or not.

> > As this isn't given with for irqs, I don't think changing the return
> > value has much sense. In my eyes the problem with platform_get_irq() and
> > platform_get_irq_optional() is that someone considered it was a good
> > idea that a global function emits an error message. The problem is,
> > that's only true most of the time. (Sometimes the caller can handle an
> > error (here: the absence of an irq) just fine, sometimes the generic
> > error message just isn't as good as a message by the caller could be.
> > (here: The caller could emit "TX irq not found" which is a much nicer
> > message than "IRQ index 5 not found".)
> >
> > My suggestion would be to keep the return value of
> > platform_get_irq_optional() as is, but rename it to
> > platform_get_irq_silent() to get rid of the expectation invoked by the
> > naming similarity that motivated you to change
> > platform_get_irq_optional().
>
> This won't fix the issue with vIRQ0.

Is the patch about vIRQ0, or did you only start to consider it when I
said that for gpio NULL is a dummy value? If the former, the commit log
should better mention that.

Anyhow, I still think renaming platform_get_irq_optional() to
platform_get_irq_silent() is a good idea and the patches in this thread
are not.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.96 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-12 08:34:08

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Andrew,

On Mon, Jan 10, 2022 at 10:20 PM Andrew Lunn <[email protected]> wrote:
> On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-König wrote:
> > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > This patch is based on the former Andy Shevchenko's patch:
> > >
> > > https://lore.kernel.org/lkml/[email protected]/
> > >
> > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > resource simply has not been found. It prevents the callers from being
> > > error code agnostic in their error handling:
> > >
> > > ret = platform_get_irq_optional(...);
> > > if (ret < 0 && ret != -ENXIO)
> > > return ret; // respect deferred probe
> > > if (ret > 0)
> > > ...we get an IRQ...
> > >
> > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > resource is not available. Let's follow this good example, so that the
> > > callers would look like:
> > >
> > > ret = platform_get_irq_optional(...);
> > > if (ret < 0)
> > > return ret;
> > > if (ret > 0)
> > > ...we get an IRQ...
> >
> > The difference to gpiod_get_optional (and most other *_optional) is that
> > you can use the NULL value as if it were a valid GPIO.
> >
> > As this isn't given with for irqs, I don't think changing the return
> > value has much sense.
>
> We actually want platform_get_irq_optional() to look different to all
> the other _optional() methods because it is not equivalent. If it
> looks the same, developers will assume it is the same, and get
> themselves into trouble.

Developers already assume it is the same, and thus forget they have
to check against -ENXIO instead of zero.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-12 08:54:06

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 09:33:48AM +0100, Geert Uytterhoeven wrote:
> Hi Andrew,
>
> On Mon, Jan 10, 2022 at 10:20 PM Andrew Lunn <[email protected]> wrote:
> > On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> > > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > > This patch is based on the former Andy Shevchenko's patch:
> > > >
> > > > https://lore.kernel.org/lkml/[email protected]/
> > > >
> > > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > > resource simply has not been found. It prevents the callers from being
> > > > error code agnostic in their error handling:
> > > >
> > > > ret = platform_get_irq_optional(...);
> > > > if (ret < 0 && ret != -ENXIO)
> > > > return ret; // respect deferred probe
> > > > if (ret > 0)
> > > > ...we get an IRQ...
> > > >
> > > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > > resource is not available. Let's follow this good example, so that the
> > > > callers would look like:
> > > >
> > > > ret = platform_get_irq_optional(...);
> > > > if (ret < 0)
> > > > return ret;
> > > > if (ret > 0)
> > > > ...we get an IRQ...
> > >
> > > The difference to gpiod_get_optional (and most other *_optional) is that
> > > you can use the NULL value as if it were a valid GPIO.
> > >
> > > As this isn't given with for irqs, I don't think changing the return
> > > value has much sense.
> >
> > We actually want platform_get_irq_optional() to look different to all
> > the other _optional() methods because it is not equivalent. If it
> > looks the same, developers will assume it is the same, and get
> > themselves into trouble.
>
> Developers already assume it is the same, and thus forget they have
> to check against -ENXIO instead of zero.

Is this an ack for renaming platform_get_irq_optional() to
platform_get_irq_silent()?

And then a coccinelle or sparse or ... hook that catches people testing
the return value against 0 would be great.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.23 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-12 10:27:23

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Wed, Jan 12, 2022 at 9:51 AM Uwe Kleine-König
<[email protected]> wrote:
> On Wed, Jan 12, 2022 at 09:33:48AM +0100, Geert Uytterhoeven wrote:
> > On Mon, Jan 10, 2022 at 10:20 PM Andrew Lunn <[email protected]> wrote:
> > > On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-König wrote:
> > > > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > > > This patch is based on the former Andy Shevchenko's patch:
> > > > >
> > > > > https://lore.kernel.org/lkml/[email protected]/
> > > > >
> > > > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > > > resource simply has not been found. It prevents the callers from being
> > > > > error code agnostic in their error handling:
> > > > >
> > > > > ret = platform_get_irq_optional(...);
> > > > > if (ret < 0 && ret != -ENXIO)
> > > > > return ret; // respect deferred probe
> > > > > if (ret > 0)
> > > > > ...we get an IRQ...
> > > > >
> > > > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > > > resource is not available. Let's follow this good example, so that the
> > > > > callers would look like:
> > > > >
> > > > > ret = platform_get_irq_optional(...);
> > > > > if (ret < 0)
> > > > > return ret;
> > > > > if (ret > 0)
> > > > > ...we get an IRQ...
> > > >
> > > > The difference to gpiod_get_optional (and most other *_optional) is that
> > > > you can use the NULL value as if it were a valid GPIO.
> > > >
> > > > As this isn't given with for irqs, I don't think changing the return
> > > > value has much sense.
> > >
> > > We actually want platform_get_irq_optional() to look different to all
> > > the other _optional() methods because it is not equivalent. If it
> > > looks the same, developers will assume it is the same, and get
> > > themselves into trouble.
> >
> > Developers already assume it is the same, and thus forget they have
> > to check against -ENXIO instead of zero.
>
> Is this an ack for renaming platform_get_irq_optional() to
> platform_get_irq_silent()?

No it isn't ;-)

If an optional IRQ is not present, drivers either just ignore it (e.g.
for devices that can have multiple interrupts or a single muxed IRQ),
or they have to resort to polling. For the latter, fall-back handling
is needed elsewhere in the driver.
To me it sounds much more logical for the driver to check if an
optional irq is non-zero (available) or zero (not available), than to
sprinkle around checks for -ENXIO. In addition, you have to remember
that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
(or some other error code) to indicate absence. I thought not having
to care about the actual error code was the main reason behind the
introduction of the *_optional() APIs.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-12 12:29:47

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 11:27:02AM +0100, Geert Uytterhoeven wrote:
> On Wed, Jan 12, 2022 at 9:51 AM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Wed, Jan 12, 2022 at 09:33:48AM +0100, Geert Uytterhoeven wrote:
> > > On Mon, Jan 10, 2022 at 10:20 PM Andrew Lunn <[email protected]> wrote:
> > > > On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> > > > > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > > > > This patch is based on the former Andy Shevchenko's patch:
> > > > > >
> > > > > > https://lore.kernel.org/lkml/[email protected]/
> > > > > >
> > > > > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > > > > resource simply has not been found. It prevents the callers from being
> > > > > > error code agnostic in their error handling:
> > > > > >
> > > > > > ret = platform_get_irq_optional(...);
> > > > > > if (ret < 0 && ret != -ENXIO)
> > > > > > return ret; // respect deferred probe
> > > > > > if (ret > 0)
> > > > > > ...we get an IRQ...
> > > > > >
> > > > > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > > > > resource is not available. Let's follow this good example, so that the
> > > > > > callers would look like:
> > > > > >
> > > > > > ret = platform_get_irq_optional(...);
> > > > > > if (ret < 0)
> > > > > > return ret;
> > > > > > if (ret > 0)
> > > > > > ...we get an IRQ...
> > > > >
> > > > > The difference to gpiod_get_optional (and most other *_optional) is that
> > > > > you can use the NULL value as if it were a valid GPIO.
> > > > >
> > > > > As this isn't given with for irqs, I don't think changing the return
> > > > > value has much sense.
> > > >
> > > > We actually want platform_get_irq_optional() to look different to all
> > > > the other _optional() methods because it is not equivalent. If it
> > > > looks the same, developers will assume it is the same, and get
> > > > themselves into trouble.
> > >
> > > Developers already assume it is the same, and thus forget they have
> > > to check against -ENXIO instead of zero.
> >
> > Is this an ack for renaming platform_get_irq_optional() to
> > platform_get_irq_silent()?
>
> No it isn't ;-)
>
> If an optional IRQ is not present, drivers either just ignore it (e.g.
> for devices that can have multiple interrupts or a single muxed IRQ),
> or they have to resort to polling. For the latter, fall-back handling
> is needed elsewhere in the driver.
> To me it sounds much more logical for the driver to check if an
> optional irq is non-zero (available) or zero (not available), than to
> sprinkle around checks for -ENXIO. In addition, you have to remember
> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> (or some other error code) to indicate absence. I thought not having
> to care about the actual error code was the main reason behind the
> introduction of the *_optional() APIs.

For the record, I'm on the same page with Geert.

--
With Best Regards,
Andy Shevchenko



2022-01-12 13:40:20

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

> If an optional IRQ is not present, drivers either just ignore it (e.g.
> for devices that can have multiple interrupts or a single muxed IRQ),
> or they have to resort to polling. For the latter, fall-back handling
> is needed elsewhere in the driver.
> To me it sounds much more logical for the driver to check if an
> optional irq is non-zero (available) or zero (not available), than to
> sprinkle around checks for -ENXIO. In addition, you have to remember
> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> (or some other error code) to indicate absence. I thought not having
> to care about the actual error code was the main reason behind the
> introduction of the *_optional() APIs.

The *_optional() functions return an error code if there has been a
real error which should be reported up the call stack. This excludes
whatever error code indicates the requested resource does not exist,
which can be -ENODEV etc. If the device does not exist, a magic cookie
is returned which appears to be a valid resources but in fact is
not. So the users of these functions just need to check for an error
code, and fail the probe if present.

You seems to be suggesting in binary return value: non-zero
(available) or zero (not available)

This discards the error code when something goes wrong. That is useful
information to have, so we should not be discarding it.

IRQ don't currently have a magic cookie value. One option would be to
add such a magic cookie to the subsystem. Otherwise, since 0 is
invalid, return 0 to indicate the IRQ does not exist.

The request for a script checking this then makes sense. However, i
don't know how well coccinelle/sparse can track values across function
calls. They probably can check for:

ret = irq_get_optional()
if (ret < 0)
return ret;

A missing if < 0 statement somewhere later is very likely to be an
error. A comparison of <= 0 is also likely to be an error. A check for
> 0 before calling any other IRQ functions would be good. I'm
surprised such a check does not already existing in the IRQ API, but
there are probably historical reasons for that.

Andrew

2022-01-12 13:53:04

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 02:38:37PM +0100, Andrew Lunn wrote:
> > If an optional IRQ is not present, drivers either just ignore it (e.g.
> > for devices that can have multiple interrupts or a single muxed IRQ),
> > or they have to resort to polling. For the latter, fall-back handling
> > is needed elsewhere in the driver.
> > To me it sounds much more logical for the driver to check if an
> > optional irq is non-zero (available) or zero (not available), than to
> > sprinkle around checks for -ENXIO. In addition, you have to remember
> > that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > (or some other error code) to indicate absence. I thought not having
> > to care about the actual error code was the main reason behind the
> > introduction of the *_optional() APIs.
>
> The *_optional() functions return an error code if there has been a
> real error which should be reported up the call stack. This excludes
> whatever error code indicates the requested resource does not exist,
> which can be -ENODEV etc. If the device does not exist, a magic cookie
> is returned which appears to be a valid resources but in fact is
> not. So the users of these functions just need to check for an error
> code, and fail the probe if present.
>
> You seems to be suggesting in binary return value: non-zero
> (available) or zero (not available)


No, what is suggested is to (besides the API changes):
- do not treat ENXIO as something special in platform_get_irq*()
- allow platform_get_irq*() to return other error codes

> This discards the error code when something goes wrong. That is useful
> information to have, so we should not be discarding it.
>
> IRQ don't currently have a magic cookie value. One option would be to
> add such a magic cookie to the subsystem. Otherwise, since 0 is
> invalid, return 0 to indicate the IRQ does not exist.
>
> The request for a script checking this then makes sense. However, i
> don't know how well coccinelle/sparse can track values across function
> calls. They probably can check for:
>
> ret = irq_get_optional()
> if (ret < 0)
> return ret;
>
> A missing if < 0 statement somewhere later is very likely to be an
> error. A comparison of <= 0 is also likely to be an error. A check for
> > 0 before calling any other IRQ functions would be good. I'm
> surprised such a check does not already existing in the IRQ API, but
> there are probably historical reasons for that.
>
> Andrew

--
With Best Regards,
Andy Shevchenko



2022-01-12 13:55:07

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Andrew,

On Wed, Jan 12, 2022 at 2:38 PM Andrew Lunn <[email protected]> wrote:
> > If an optional IRQ is not present, drivers either just ignore it (e.g.
> > for devices that can have multiple interrupts or a single muxed IRQ),
> > or they have to resort to polling. For the latter, fall-back handling
> > is needed elsewhere in the driver.
> > To me it sounds much more logical for the driver to check if an
> > optional irq is non-zero (available) or zero (not available), than to
> > sprinkle around checks for -ENXIO. In addition, you have to remember
> > that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > (or some other error code) to indicate absence. I thought not having
> > to care about the actual error code was the main reason behind the
> > introduction of the *_optional() APIs.
>
> The *_optional() functions return an error code if there has been a
> real error which should be reported up the call stack. This excludes
> whatever error code indicates the requested resource does not exist,
> which can be -ENODEV etc. If the device does not exist, a magic cookie
> is returned which appears to be a valid resources but in fact is
> not. So the users of these functions just need to check for an error
> code, and fail the probe if present.

Agreed.

Note that in most (all?) other cases, the return type is a pointer
(e.g. to struct clk), and NULL is the magic cookie.

> You seems to be suggesting in binary return value: non-zero
> (available) or zero (not available)

Only in case of success. In case of a real failure, an error code
must be returned.

> This discards the error code when something goes wrong. That is useful
> information to have, so we should not be discarding it.

No, the error code must be retained in case of failure.

> IRQ don't currently have a magic cookie value. One option would be to
> add such a magic cookie to the subsystem. Otherwise, since 0 is
> invalid, return 0 to indicate the IRQ does not exist.

Exactly. And using 0 means the similar code can be used as for other
subsystems, where NULL would be returned.

The only remaining difference is the "dummy cookie can be passed
to other functions" behavior. Which is IMHO a valid difference,
as unlike with e.g. clk_prepare_enable(), you do pass extra data to
request_irq(), and sometimes you do need to handle the absence of
the interrupt using e.g. polling.

> The request for a script checking this then makes sense. However, i
> don't know how well coccinelle/sparse can track values across function
> calls. They probably can check for:
>
> ret = irq_get_optional()
> if (ret < 0)
> return ret;
>
> A missing if < 0 statement somewhere later is very likely to be an
> error. A comparison of <= 0 is also likely to be an error. A check for
> > 0 before calling any other IRQ functions would be good. I'm
> surprised such a check does not already existing in the IRQ API, but
> there are probably historical reasons for that.

There are still a few platforms where IRQ 0 does exist.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-12 14:41:55

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 2:55 PM Geert Uytterhoeven <[email protected]> wrote:
>
> Hi Andrew,
>
> On Wed, Jan 12, 2022 at 2:38 PM Andrew Lunn <[email protected]> wrote:
> > > If an optional IRQ is not present, drivers either just ignore it (e.g.
> > > for devices that can have multiple interrupts or a single muxed IRQ),
> > > or they have to resort to polling. For the latter, fall-back handling
> > > is needed elsewhere in the driver.
> > > To me it sounds much more logical for the driver to check if an
> > > optional irq is non-zero (available) or zero (not available), than to
> > > sprinkle around checks for -ENXIO. In addition, you have to remember
> > > that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > > (or some other error code) to indicate absence. I thought not having
> > > to care about the actual error code was the main reason behind the
> > > introduction of the *_optional() APIs.
> >
> > The *_optional() functions return an error code if there has been a
> > real error which should be reported up the call stack. This excludes
> > whatever error code indicates the requested resource does not exist,
> > which can be -ENODEV etc. If the device does not exist, a magic cookie
> > is returned which appears to be a valid resources but in fact is
> > not. So the users of these functions just need to check for an error
> > code, and fail the probe if present.
>
> Agreed.
>
> Note that in most (all?) other cases, the return type is a pointer
> (e.g. to struct clk), and NULL is the magic cookie.
>
> > You seems to be suggesting in binary return value: non-zero
> > (available) or zero (not available)
>
> Only in case of success. In case of a real failure, an error code
> must be returned.
>
> > This discards the error code when something goes wrong. That is useful
> > information to have, so we should not be discarding it.
>
> No, the error code must be retained in case of failure.
>
> > IRQ don't currently have a magic cookie value. One option would be to
> > add such a magic cookie to the subsystem. Otherwise, since 0 is
> > invalid, return 0 to indicate the IRQ does not exist.
>
> Exactly. And using 0 means the similar code can be used as for other
> subsystems, where NULL would be returned.
>
> The only remaining difference is the "dummy cookie can be passed
> to other functions" behavior. Which is IMHO a valid difference,
> as unlike with e.g. clk_prepare_enable(), you do pass extra data to
> request_irq(), and sometimes you do need to handle the absence of
> the interrupt using e.g. polling.
>
> > The request for a script checking this then makes sense. However, i
> > don't know how well coccinelle/sparse can track values across function
> > calls. They probably can check for:
> >
> > ret = irq_get_optional()
> > if (ret < 0)
> > return ret;
> >
> > A missing if < 0 statement somewhere later is very likely to be an
> > error. A comparison of <= 0 is also likely to be an error. A check for
> > > 0 before calling any other IRQ functions would be good. I'm
> > surprised such a check does not already existing in the IRQ API, but
> > there are probably historical reasons for that.
>
> There are still a few platforms where IRQ 0 does exist.

Not just a few even. This happens on a reasonably recent x86 PC:

rafael@gratch:~/work/linux-pm> head -2 /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
0: 10 0 0 0 0 0
IR-IO-APIC 2-edge
timer

2022-01-12 15:05:42

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/12/22 5:41 PM, Rafael J. Wysocki wrote:

[...]
>>>> If an optional IRQ is not present, drivers either just ignore it (e.g.
>>>> for devices that can have multiple interrupts or a single muxed IRQ),
>>>> or they have to resort to polling. For the latter, fall-back handling
>>>> is needed elsewhere in the driver.
>>>> To me it sounds much more logical for the driver to check if an
>>>> optional irq is non-zero (available) or zero (not available), than to
>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>> (or some other error code) to indicate absence. I thought not having
>>>> to care about the actual error code was the main reason behind the
>>>> introduction of the *_optional() APIs.
>>>
>>> The *_optional() functions return an error code if there has been a
>>> real error which should be reported up the call stack. This excludes
>>> whatever error code indicates the requested resource does not exist,
>>> which can be -ENODEV etc. If the device does not exist, a magic cookie
>>> is returned which appears to be a valid resources but in fact is
>>> not. So the users of these functions just need to check for an error
>>> code, and fail the probe if present.
>>
>> Agreed.
>>
>> Note that in most (all?) other cases, the return type is a pointer
>> (e.g. to struct clk), and NULL is the magic cookie.
>>
>>> You seems to be suggesting in binary return value: non-zero
>>> (available) or zero (not available)
>>
>> Only in case of success. In case of a real failure, an error code
>> must be returned.
>>
>>> This discards the error code when something goes wrong. That is useful
>>> information to have, so we should not be discarding it.
>>
>> No, the error code must be retained in case of failure.
>>
>>> IRQ don't currently have a magic cookie value. One option would be to
>>> add such a magic cookie to the subsystem. Otherwise, since 0 is
>>> invalid, return 0 to indicate the IRQ does not exist.
>>
>> Exactly. And using 0 means the similar code can be used as for other
>> subsystems, where NULL would be returned.
>>
>> The only remaining difference is the "dummy cookie can be passed
>> to other functions" behavior. Which is IMHO a valid difference,
>> as unlike with e.g. clk_prepare_enable(), you do pass extra data to
>> request_irq(), and sometimes you do need to handle the absence of
>> the interrupt using e.g. polling.
>>
>>> The request for a script checking this then makes sense. However, i
>>> don't know how well coccinelle/sparse can track values across function
>>> calls. They probably can check for:
>>>
>>> ret = irq_get_optional()
>>> if (ret < 0)
>>> return ret;
>>>
>>> A missing if < 0 statement somewhere later is very likely to be an
>>> error. A comparison of <= 0 is also likely to be an error. A check for
>>>> 0 before calling any other IRQ functions would be good. I'm
>>> surprised such a check does not already existing in the IRQ API, but
>>> there are probably historical reasons for that.
>>
>> There are still a few platforms where IRQ 0 does exist.
>
> Not just a few even. This happens on a reasonably recent x86 PC:
>
> rafael@gratch:~/work/linux-pm> head -2 /proc/interrupts
> CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
> 0: 10 0 0 0 0 0
> IR-IO-APIC 2-edge
> timer

IIRC Linus has proclaimed that IRQ0 was valid for the i8253 driver (living in
arch/x86/); IRQ0 only was frowned upon when returned by platform_get_irq() and its
ilk.

MBR, Sergey

2022-01-12 15:14:08

by Hans de Goede

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi,

On 1/12/22 16:05, Sergey Shtylyov wrote:
> On 1/12/22 5:41 PM, Rafael J. Wysocki wrote:
>
> [...]
>>>>> If an optional IRQ is not present, drivers either just ignore it (e.g.
>>>>> for devices that can have multiple interrupts or a single muxed IRQ),
>>>>> or they have to resort to polling. For the latter, fall-back handling
>>>>> is needed elsewhere in the driver.
>>>>> To me it sounds much more logical for the driver to check if an
>>>>> optional irq is non-zero (available) or zero (not available), than to
>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>>> (or some other error code) to indicate absence. I thought not having
>>>>> to care about the actual error code was the main reason behind the
>>>>> introduction of the *_optional() APIs.
>>>>Hi,
>>>> The *_optional() functions return an error code if there has been a
>>>> real error which should be reported up the call stack. This excludes
>>>> whatever error code indicates the requested resource does not exist,
>>>> which can be -ENODEV etc. If the device does not exist, a magic cookie
>>>> is returned which appears to be a valid resources but in fact is
>>>> not. So the users of these functions just need to check for an error
>>>> code, and fail the probe if present.
>>>
>>> Agreed.
>>>
>>> Note that in most (all?) other cases, the return type is a pointer
>>> (e.g. to struct clk), and NULL is the magic cookie.
>>>
>>>> You seems to be suggesting in binary return value: non-zero
>>>> (available) or zero (not available)
>>>
>>> Only in case of success. In case of a real failure, an error code
>>> must be returned.
>>>
>>>> This discards the error code when something goes wrong. That is useful
>>>> information to have, so we should not be discarding it.
>>>
>>> No, the error code must be retained in case of failure.
>>>
>>>> IRQ don't currently have a magic cookie value. One option would be to
>>>> add such a magic cookie to the subsystem. Otherwise, since 0 is
>>>> invalid, return 0 to indicate the IRQ does not exist.
>>>
>>> Exactly. And using 0 means the similar code can be used as for other
>>> subsystems, where NULL would be returned.
>>>
>>> The only remaining difference is the "dummy cookie can be passed
>>> to other functions" behavior. Which is IMHO a valid difference,
>>> as unlike with e.g. clk_prepare_enable(), you do pass extra data to
>>> request_irq(), and sometimes you do need to handle the absence of
>>> the interrupt using e.g. polling.
>>>
>>>> The request for a script checking this then makes sense. However, i
>>>> don't know how well coccinelle/sparse can track values across function
>>>> calls. They probably can check for:
>>>>
>>>> ret = irq_get_optional()
>>>> if (ret < 0)
>>>> return ret;
>>>>
>>>> A missing if < 0 statement somewhere later is very likely to be an
>>>> error. A comparison of <= 0 is also likely to be an error. A check for
>>>>> 0 before calling any other IRQ functions would be good. I'm
>>>> surprised such a check does not already existing in the IRQ API, but
>>>> there are probably historical reasons for that.
>>>
>>> There are still a few platforms where IRQ 0 does exist.
>>
>> Not just a few even. This happens on a reasonably recent x86 PC:
>>
>> rafael@gratch:~/work/linux-pm> head -2 /proc/interrupts
>> CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
>> 0: 10 0 0 0 0 0
>> IR-IO-APIC 2-edge
>> timer
>
> IIRC Linus has proclaimed that IRQ0 was valid for the i8253 driver (living in
> arch/x86/); IRQ0 only was frowned upon when returned by platform_get_irq() and its
> ilk.
>
> MBR, Sergey

Right, platform_get_irq() has this:

WARN(ret == 0, "0 is an invalid IRQ number\n");

So given that platform_get_irq() returning 0 is not expected, it seems
reasonable for platform_get_irq_optional() to use 0 as a special
"no irq available" return value, matching the NULL returned by
gpiod_get_optional().

Regards,

Hans


2022-01-12 15:48:35

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 4:14 PM Hans de Goede <[email protected]> wrote:
>
> Hi,
>
> On 1/12/22 16:05, Sergey Shtylyov wrote:
> > On 1/12/22 5:41 PM, Rafael J. Wysocki wrote:
> >
> > [...]
> >>>>> If an optional IRQ is not present, drivers either just ignore it (e.g.
> >>>>> for devices that can have multiple interrupts or a single muxed IRQ),
> >>>>> or they have to resort to polling. For the latter, fall-back handling
> >>>>> is needed elsewhere in the driver.
> >>>>> To me it sounds much more logical for the driver to check if an
> >>>>> optional irq is non-zero (available) or zero (not available), than to
> >>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
> >>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> >>>>> (or some other error code) to indicate absence. I thought not having
> >>>>> to care about the actual error code was the main reason behind the
> >>>>> introduction of the *_optional() APIs.
> >>>>Hi,
> >>>> The *_optional() functions return an error code if there has been a
> >>>> real error which should be reported up the call stack. This excludes
> >>>> whatever error code indicates the requested resource does not exist,
> >>>> which can be -ENODEV etc. If the device does not exist, a magic cookie
> >>>> is returned which appears to be a valid resources but in fact is
> >>>> not. So the users of these functions just need to check for an error
> >>>> code, and fail the probe if present.
> >>>
> >>> Agreed.
> >>>
> >>> Note that in most (all?) other cases, the return type is a pointer
> >>> (e.g. to struct clk), and NULL is the magic cookie.
> >>>
> >>>> You seems to be suggesting in binary return value: non-zero
> >>>> (available) or zero (not available)
> >>>
> >>> Only in case of success. In case of a real failure, an error code
> >>> must be returned.
> >>>
> >>>> This discards the error code when something goes wrong. That is useful
> >>>> information to have, so we should not be discarding it.
> >>>
> >>> No, the error code must be retained in case of failure.
> >>>
> >>>> IRQ don't currently have a magic cookie value. One option would be to
> >>>> add such a magic cookie to the subsystem. Otherwise, since 0 is
> >>>> invalid, return 0 to indicate the IRQ does not exist.
> >>>
> >>> Exactly. And using 0 means the similar code can be used as for other
> >>> subsystems, where NULL would be returned.
> >>>
> >>> The only remaining difference is the "dummy cookie can be passed
> >>> to other functions" behavior. Which is IMHO a valid difference,
> >>> as unlike with e.g. clk_prepare_enable(), you do pass extra data to
> >>> request_irq(), and sometimes you do need to handle the absence of
> >>> the interrupt using e.g. polling.
> >>>
> >>>> The request for a script checking this then makes sense. However, i
> >>>> don't know how well coccinelle/sparse can track values across function
> >>>> calls. They probably can check for:
> >>>>
> >>>> ret = irq_get_optional()
> >>>> if (ret < 0)
> >>>> return ret;
> >>>>
> >>>> A missing if < 0 statement somewhere later is very likely to be an
> >>>> error. A comparison of <= 0 is also likely to be an error. A check for
> >>>>> 0 before calling any other IRQ functions would be good. I'm
> >>>> surprised such a check does not already existing in the IRQ API, but
> >>>> there are probably historical reasons for that.
> >>>
> >>> There are still a few platforms where IRQ 0 does exist.
> >>
> >> Not just a few even. This happens on a reasonably recent x86 PC:
> >>
> >> rafael@gratch:~/work/linux-pm> head -2 /proc/interrupts
> >> CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
> >> 0: 10 0 0 0 0 0
> >> IR-IO-APIC 2-edge
> >> timer
> >
> > IIRC Linus has proclaimed that IRQ0 was valid for the i8253 driver (living in
> > arch/x86/); IRQ0 only was frowned upon when returned by platform_get_irq() and its
> > ilk.
> >
> > MBR, Sergey
>
> Right, platform_get_irq() has this:
>
> WARN(ret == 0, "0 is an invalid IRQ number\n");
>
> So given that platform_get_irq() returning 0 is not expected, it seems
> reasonable for platform_get_irq_optional() to use 0 as a special
> "no irq available" return value, matching the NULL returned by
> gpiod_get_optional().

Sounds reasonable to me.

2022-01-12 16:27:25

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 03:41:38PM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 12, 2022 at 2:55 PM Geert Uytterhoeven <[email protected]> wrote:
> >
> > Hi Andrew,
> >
> > On Wed, Jan 12, 2022 at 2:38 PM Andrew Lunn <[email protected]> wrote:
> > > > If an optional IRQ is not present, drivers either just ignore it (e.g.
> > > > for devices that can have multiple interrupts or a single muxed IRQ),
> > > > or they have to resort to polling. For the latter, fall-back handling
> > > > is needed elsewhere in the driver.
> > > > To me it sounds much more logical for the driver to check if an
> > > > optional irq is non-zero (available) or zero (not available), than to
> > > > sprinkle around checks for -ENXIO. In addition, you have to remember
> > > > that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > > > (or some other error code) to indicate absence. I thought not having
> > > > to care about the actual error code was the main reason behind the
> > > > introduction of the *_optional() APIs.
> > >
> > > The *_optional() functions return an error code if there has been a
> > > real error which should be reported up the call stack. This excludes
> > > whatever error code indicates the requested resource does not exist,
> > > which can be -ENODEV etc. If the device does not exist, a magic cookie
> > > is returned which appears to be a valid resources but in fact is
> > > not. So the users of these functions just need to check for an error
> > > code, and fail the probe if present.
> >
> > Agreed.
> >
> > Note that in most (all?) other cases, the return type is a pointer
> > (e.g. to struct clk), and NULL is the magic cookie.
> >
> > > You seems to be suggesting in binary return value: non-zero
> > > (available) or zero (not available)
> >
> > Only in case of success. In case of a real failure, an error code
> > must be returned.
> >
> > > This discards the error code when something goes wrong. That is useful
> > > information to have, so we should not be discarding it.
> >
> > No, the error code must be retained in case of failure.
> >
> > > IRQ don't currently have a magic cookie value. One option would be to
> > > add such a magic cookie to the subsystem. Otherwise, since 0 is
> > > invalid, return 0 to indicate the IRQ does not exist.
> >
> > Exactly. And using 0 means the similar code can be used as for other
> > subsystems, where NULL would be returned.
> >
> > The only remaining difference is the "dummy cookie can be passed
> > to other functions" behavior. Which is IMHO a valid difference,
> > as unlike with e.g. clk_prepare_enable(), you do pass extra data to
> > request_irq(), and sometimes you do need to handle the absence of
> > the interrupt using e.g. polling.
> >
> > > The request for a script checking this then makes sense. However, i
> > > don't know how well coccinelle/sparse can track values across function
> > > calls. They probably can check for:
> > >
> > > ret = irq_get_optional()
> > > if (ret < 0)
> > > return ret;
> > >
> > > A missing if < 0 statement somewhere later is very likely to be an
> > > error. A comparison of <= 0 is also likely to be an error. A check for
> > > > 0 before calling any other IRQ functions would be good. I'm
> > > surprised such a check does not already existing in the IRQ API, but
> > > there are probably historical reasons for that.
> >
> > There are still a few platforms where IRQ 0 does exist.
>
> Not just a few even. This happens on a reasonably recent x86 PC:

Yes, but the timer doesn't use platform_get_irq*() and friends.

> rafael@gratch:~/work/linux-pm> head -2 /proc/interrupts
> CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
> 0: 10 0 0 0 0 0
> IR-IO-APIC 2-edge
> timer

--
With Best Regards,
Andy Shevchenko



2022-01-12 21:33:09

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 11:27:02AM +0100, Geert Uytterhoeven wrote:
> Hi Uwe,
>
> On Wed, Jan 12, 2022 at 9:51 AM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Wed, Jan 12, 2022 at 09:33:48AM +0100, Geert Uytterhoeven wrote:
> > > On Mon, Jan 10, 2022 at 10:20 PM Andrew Lunn <[email protected]> wrote:
> > > > On Mon, Jan 10, 2022 at 09:10:14PM +0100, Uwe Kleine-K?nig wrote:
> > > > > On Mon, Jan 10, 2022 at 10:54:48PM +0300, Sergey Shtylyov wrote:
> > > > > > This patch is based on the former Andy Shevchenko's patch:
> > > > > >
> > > > > > https://lore.kernel.org/lkml/[email protected]/
> > > > > >
> > > > > > Currently platform_get_irq_optional() returns an error code even if IRQ
> > > > > > resource simply has not been found. It prevents the callers from being
> > > > > > error code agnostic in their error handling:
> > > > > >
> > > > > > ret = platform_get_irq_optional(...);
> > > > > > if (ret < 0 && ret != -ENXIO)
> > > > > > return ret; // respect deferred probe
> > > > > > if (ret > 0)
> > > > > > ...we get an IRQ...
> > > > > >
> > > > > > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > > > > > resource is not available. Let's follow this good example, so that the
> > > > > > callers would look like:
> > > > > >
> > > > > > ret = platform_get_irq_optional(...);
> > > > > > if (ret < 0)
> > > > > > return ret;
> > > > > > if (ret > 0)
> > > > > > ...we get an IRQ...
> > > > >
> > > > > The difference to gpiod_get_optional (and most other *_optional) is that
> > > > > you can use the NULL value as if it were a valid GPIO.
> > > > >
> > > > > As this isn't given with for irqs, I don't think changing the return
> > > > > value has much sense.
> > > >
> > > > We actually want platform_get_irq_optional() to look different to all
> > > > the other _optional() methods because it is not equivalent. If it
> > > > looks the same, developers will assume it is the same, and get
> > > > themselves into trouble.
> > >
> > > Developers already assume it is the same, and thus forget they have
> > > to check against -ENXIO instead of zero.

I agree that -ENXIO is unfortunate and -ENOENT would be more in line
with other functions. I assume it's insane to want to change that.

> > Is this an ack for renaming platform_get_irq_optional() to
> > platform_get_irq_silent()?
>
> No it isn't ;-)
>
> If an optional IRQ is not present, drivers either just ignore it (e.g.
> for devices that can have multiple interrupts or a single muxed IRQ),
> or they have to resort to polling. For the latter, fall-back handling
> is needed elsewhere in the driver.

I think irq are not suitable for such a dummy handling. For clocks or
GPIOs there are cases where just doing nothing in the absence of a
certain optional clock or GPIO is fine.

I checked a few users of platform_get_irq_optional() and I didn't find a
single one that doesn't need to differentiate the irq and the no-irq
case later. Do you know one? If you do, isn't that so exceptional that
it doesn't justify the idea of a dummy irq value? So until proven
otherwise I think platform_get_irq_optional() just isn't in the spirit
of clk_get_optional() and gpiod_get_optional() because there are no use
cases where a dummy value would be good enough. (Even if request_irq
would be a noop for a dummy irq value.)

The motivation why platform_get_irq_optional() was introduced was just
that platform_get_irq() started to emit an error message (in commit
7723f4c5ecdb8d832f049f8483beb0d1081cedf6) and the (proportional) few
drivers where the error message was bad needed a variant that doesn't
emit the error message. Look at
31a8d8fa84c51d3ab00bf059158d5de6178cf890, the motivation to use
platform_get_irq_optional() wasn't that it simplifies handling in the
driver, but that it doesn't emit an error message. Or
8f5783ad9eb83747471f61f94dbe209fb9fb8a7d, or
2fd276c3ee4bd42eb034f8954964a5ae74187c6b, or
55cc33fab5ac9f7e2a97aa7c564e8b35355886d5. Just look at the output of git
log -Splatform_get_irq_optional to find some more.

That convinces me, that platform_get_irq_optional() is a bad name. The
only difference to platform_get_irq is that it's silent. And returning
a dummy irq value (which would make it aligned with the other _optional
functions) isn't possible.

> To me it sounds much more logical for the driver to check if an
> optional irq is non-zero (available) or zero (not available), than to
> sprinkle around checks for -ENXIO. In addition, you have to remember
> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> (or some other error code) to indicate absence. I thought not having
> to care about the actual error code was the main reason behind the
> introduction of the *_optional() APIs.

No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
that you can handle an absent GPIO (or clk) as if it were available.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (5.06 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-12 21:45:52

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 10:31:21PM +0100, Uwe Kleine-K?nig wrote:
> On Wed, Jan 12, 2022 at 11:27:02AM +0100, Geert Uytterhoeven wrote:

(Do we really need *all* the CCs here?)

> That convinces me, that platform_get_irq_optional() is a bad name. The
> only difference to platform_get_irq is that it's silent. And returning
> a dummy irq value (which would make it aligned with the other _optional
> functions) isn't possible.

There is regulator_get_optional() which is I believe the earliest of
these APIs, it doesn't return a dummy either (and is silent too) - this
is because regulator_get() does return a dummy since it's the vastly
common case that regulators must be physically present and them not
being found is due to there being an error in the system description.
It's unfortunate that we've ended up with these two different senses for
_optional(), people frequently get tripped up by it.

> > To me it sounds much more logical for the driver to check if an
> > optional irq is non-zero (available) or zero (not available), than to
> > sprinkle around checks for -ENXIO. In addition, you have to remember
> > that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > (or some other error code) to indicate absence. I thought not having
> > to care about the actual error code was the main reason behind the
> > introduction of the *_optional() APIs.

> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> that you can handle an absent GPIO (or clk) as if it were available.

Similarly for the regulator API, kind of.


Attachments:
(No filename) (1.53 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-13 11:09:56

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Wed, Jan 12, 2022 at 09:45:25PM +0000, Mark Brown wrote:
> On Wed, Jan 12, 2022 at 10:31:21PM +0100, Uwe Kleine-K?nig wrote:
> > On Wed, Jan 12, 2022 at 11:27:02AM +0100, Geert Uytterhoeven wrote:
>
> (Do we really need *all* the CCs here?)

It's probably counteractive to finding an agreement because there are
too many opinions on that matter. But I didn't dare to strip it down,
too :-)

> > That convinces me, that platform_get_irq_optional() is a bad name. The
> > only difference to platform_get_irq is that it's silent. And returning
> > a dummy irq value (which would make it aligned with the other _optional
> > functions) isn't possible.
>
> There is regulator_get_optional() which is I believe the earliest of
> these APIs, it doesn't return a dummy either (and is silent too) - this
> is because regulator_get() does return a dummy since it's the vastly
> common case that regulators must be physically present and them not
> being found is due to there being an error in the system description.
> It's unfortunate that we've ended up with these two different senses for
> _optional(), people frequently get tripped up by it.

Yeah, I tripped over that one already, too. And according to my counting
this results in three different senses now :-\ :

a) regulator
regulator_get returns a dummy, regulator_get_optional returns ERR_PTR(-ENODEV)
b) clk + gpiod
..._get returns ERR_PTR(-ENODEV), ..._get_optional returns a dummy
c) platform_get_irq()
platform_get_irq_optional() is just a silent variant of
platform_get_irq(); the return values are identical.

This is all very unfortunate. In my eyes b) is the most sensible
sense, but the past showed that we don't agree here. (The most annoying
part of regulator_get is the warning that is emitted that regularily
makes customers ask what happens here and if this is fixable.)

I think at least c) is easy to resolve because
platform_get_irq_optional() isn't that old yet and mechanically
replacing it by platform_get_irq_silent() should be easy and safe.
And this is orthogonal to the discussion if -ENOXIO is a sensible return
value and if it's as easy as it could be to work with errors on irq
lookups.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.31 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-13 14:45:53

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:

> This is all very unfortunate. In my eyes b) is the most sensible
> sense, but the past showed that we don't agree here. (The most annoying
> part of regulator_get is the warning that is emitted that regularily
> makes customers ask what happens here and if this is fixable.)

Fortunately it can be fixed, and it's safer to clearly specify things.
The prints are there because when the description is wrong enough to
cause things to blow up we can fail to boot or run messily and
forgetting to describe some supplies (or typoing so they haven't done
that) and people were having a hard time figuring out what might've
happened.

> I think at least c) is easy to resolve because
> platform_get_irq_optional() isn't that old yet and mechanically
> replacing it by platform_get_irq_silent() should be easy and safe.
> And this is orthogonal to the discussion if -ENOXIO is a sensible return
> value and if it's as easy as it could be to work with errors on irq
> lookups.

It'd certainly be good to name anything that doesn't correspond to one
of the existing semantics for the API (!) something different rather
than adding yet another potentially overloaded meaning.


Attachments:
(No filename) (1.21 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-13 19:46:12

by Uwe Kleine-König

[permalink] [raw]
Subject: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

The subsystems regulator, clk and gpio have the concept of a dummy
resource. For regulator, clk and gpio there is a semantic difference
between the regular _get() function and the _get_optional() variant.
(One might return the dummy resource, the other won't. Unfortunately
which one implements which isn't the same for these three.) The
difference between platform_get_irq() and platform_get_irq_optional() is
only that the former might emit an error message and the later won't.

To prevent people's expectations that there is a semantic difference
between these too, rename platform_get_irq_optional() to
platform_get_irq_silent() to make the actual difference more obvious.

The #define for the old name can and should be removed once all patches
currently in flux still relying on platform_get_irq_optional() are
fixed.

Signed-off-by: Uwe Kleine-K?nig <[email protected]>
---
Hello,

On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
> On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
>
> > This is all very unfortunate. In my eyes b) is the most sensible
> > sense, but the past showed that we don't agree here. (The most annoying
> > part of regulator_get is the warning that is emitted that regularily
> > makes customers ask what happens here and if this is fixable.)
>
> Fortunately it can be fixed, and it's safer to clearly specify things.
> The prints are there because when the description is wrong enough to
> cause things to blow up we can fail to boot or run messily and
> forgetting to describe some supplies (or typoing so they haven't done
> that) and people were having a hard time figuring out what might've
> happened.

Yes, that's right. I sent a patch for such a warning in 2019 and pinged
occationally. Still waiting for it to be merged :-\
(https://lore.kernel.org/r/[email protected])

> > I think at least c) is easy to resolve because
> > platform_get_irq_optional() isn't that old yet and mechanically
> > replacing it by platform_get_irq_silent() should be easy and safe.
> > And this is orthogonal to the discussion if -ENOXIO is a sensible return
> > value and if it's as easy as it could be to work with errors on irq
> > lookups.
>
> It'd certainly be good to name anything that doesn't correspond to one
> of the existing semantics for the API (!) something different rather
> than adding yet another potentially overloaded meaning.

It seems we're (at least) three who agree about this. Here is a patch
fixing the name.

Best regards
Uwe

drivers/base/platform.c | 12 ++++++------
drivers/char/ipmi/bt-bmc.c | 2 +-
drivers/char/ipmi/ipmi_si_platform.c | 4 ++--
drivers/char/tpm/tpm_tis.c | 2 +-
drivers/counter/interrupt-cnt.c | 2 +-
drivers/cpufreq/qcom-cpufreq-hw.c | 2 +-
drivers/dma/mmp_pdma.c | 2 +-
drivers/edac/xgene_edac.c | 2 +-
drivers/gpio/gpio-altera.c | 2 +-
drivers/gpio/gpio-dwapb.c | 2 +-
drivers/gpio/gpio-mvebu.c | 2 +-
drivers/gpio/gpio-realtek-otto.c | 2 +-
drivers/gpio/gpio-tqmx86.c | 2 +-
drivers/gpio/gpio-xilinx.c | 2 +-
drivers/gpu/drm/v3d/v3d_irq.c | 2 +-
drivers/i2c/busses/i2c-brcmstb.c | 2 +-
drivers/i2c/busses/i2c-ocores.c | 2 +-
drivers/i2c/busses/i2c-pca-platform.c | 2 +-
drivers/irqchip/irq-renesas-intc-irqpin.c | 2 +-
drivers/irqchip/irq-renesas-irqc.c | 2 +-
drivers/mfd/intel_pmc_bxt.c | 2 +-
drivers/mmc/host/sh_mmcif.c | 2 +-
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +-
drivers/mtd/nand/raw/renesas-nand-controller.c | 2 +-
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +-
drivers/net/ethernet/davicom/dm9000.c | 2 +-
drivers/net/ethernet/freescale/fec_ptp.c | 2 +-
drivers/net/ethernet/marvell/mvmdio.c | 2 +-
drivers/net/ethernet/ti/davinci_emac.c | 2 +-
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
drivers/perf/arm_smmuv3_pmu.c | 2 +-
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +-
drivers/pinctrl/intel/pinctrl-baytrail.c | 2 +-
drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +-
drivers/pinctrl/pinctrl-keembay.c | 2 +-
drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +-
drivers/platform/chrome/cros_ec_lpc.c | 2 +-
drivers/platform/x86/hp_accel.c | 2 +-
drivers/platform/x86/intel/punit_ipc.c | 2 +-
drivers/platform/x86/intel_scu_pltdrv.c | 2 +-
drivers/power/supply/mp2629_charger.c | 2 +-
drivers/rtc/rtc-m48t59.c | 2 +-
drivers/spi/spi-hisi-sfc-v3xx.c | 2 +-
drivers/spi/spi-mtk-nor.c | 2 +-
drivers/thermal/rcar_gen3_thermal.c | 2 +-
drivers/tty/serial/8250/8250_mtk.c | 2 +-
drivers/tty/serial/altera_jtaguart.c | 2 +-
drivers/tty/serial/altera_uart.c | 2 +-
drivers/tty/serial/imx.c | 4 ++--
drivers/tty/serial/qcom_geni_serial.c | 2 +-
drivers/tty/serial/sh-sci.c | 2 +-
drivers/uio/uio_pdrv_genirq.c | 2 +-
drivers/usb/phy/phy-tegra-usb.c | 2 +-
drivers/vfio/platform/vfio_platform.c | 2 +-
drivers/watchdog/dw_wdt.c | 2 +-
drivers/watchdog/orion_wdt.c | 4 ++--
drivers/watchdog/qcom-wdt.c | 2 +-
include/linux/platform_device.h | 9 ++++++++-
sound/soc/dwc/dwc-i2s.c | 2 +-
sound/soc/intel/keembay/kmb_platform.c | 2 +-
61 files changed, 77 insertions(+), 70 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6cb04ac48bf0..acb9962b9889 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
#endif /* CONFIG_HAS_IOMEM */

/**
- * platform_get_irq_optional - get an optional IRQ for a device
+ * platform_get_irq_silent - get an optional IRQ for a device
* @dev: platform device
* @num: IRQ number index
*
@@ -160,13 +160,13 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
*
* For example::
*
- * int irq = platform_get_irq_optional(pdev, 0);
+ * int irq = platform_get_irq_silent(pdev, 0);
* if (irq < 0)
* return irq;
*
* Return: non-zero IRQ number on success, negative error number on failure.
*/
-int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
+int platform_get_irq_silent(struct platform_device *dev, unsigned int num)
{
int ret;
#ifdef CONFIG_SPARC
@@ -234,7 +234,7 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
WARN(ret == 0, "0 is an invalid IRQ number\n");
return ret;
}
-EXPORT_SYMBOL_GPL(platform_get_irq_optional);
+EXPORT_SYMBOL_GPL(platform_get_irq_silent);

/**
* platform_get_irq - get an IRQ for a device
@@ -257,7 +257,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
{
int ret;

- ret = platform_get_irq_optional(dev, num);
+ ret = platform_get_irq_silent(dev, num);
if (ret < 0)
return dev_err_probe(&dev->dev, ret,
"IRQ index %u not found\n", num);
@@ -276,7 +276,7 @@ int platform_irq_count(struct platform_device *dev)
{
int ret, nr = 0;

- while ((ret = platform_get_irq_optional(dev, nr)) >= 0)
+ while ((ret = platform_get_irq_silent(dev, nr)) >= 0)
nr++;

if (ret == -EPROBE_DEFER)
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 7450904e330a..73bdbc59c9d0 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -379,7 +379,7 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
int rc;
u32 reg;

- bt_bmc->irq = platform_get_irq_optional(pdev, 0);
+ bt_bmc->irq = platform_get_irq_silent(pdev, 0);
if (bt_bmc->irq < 0)
return bt_bmc->irq;

diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c
index 505cc978c97a..4c666eed24d9 100644
--- a/drivers/char/ipmi/ipmi_si_platform.c
+++ b/drivers/char/ipmi/ipmi_si_platform.c
@@ -192,7 +192,7 @@ static int platform_ipmi_probe(struct platform_device *pdev)
else
io.slave_addr = slave_addr;

- io.irq = platform_get_irq_optional(pdev, 0);
+ io.irq = platform_get_irq_silent(pdev, 0);
if (io.irq > 0)
io.irq_setup = ipmi_std_irq_setup;
else
@@ -368,7 +368,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
io.irq = tmp;
io.irq_setup = acpi_gpe_irq_setup;
} else {
- int irq = platform_get_irq_optional(pdev, 0);
+ int irq = platform_get_irq_silent(pdev, 0);

if (irq > 0) {
io.irq = irq;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index d3f2e5364c27..3e6785ad62f2 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -318,7 +318,7 @@ static int tpm_tis_plat_probe(struct platform_device *pdev)
}
tpm_info.res = *res;

- tpm_info.irq = platform_get_irq_optional(pdev, 0);
+ tpm_info.irq = platform_get_irq_silent(pdev, 0);
if (tpm_info.irq <= 0) {
if (pdev != force_pdev)
tpm_info.irq = -1;
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index 8514a87fcbee..65b9254e63a9 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -155,7 +155,7 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;

- priv->irq = platform_get_irq_optional(pdev, 0);
+ priv->irq = platform_get_irq_silent(pdev, 0);
if (priv->irq == -ENXIO)
priv->irq = 0;
else if (priv->irq < 0)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 05f3d7876e44..3d1fe9ba98a7 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -374,7 +374,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
* Look for LMh interrupt. If no interrupt line is specified /
* if there is an error, allow cpufreq to be enabled as usual.
*/
- data->throttle_irq = platform_get_irq_optional(pdev, index);
+ data->throttle_irq = platform_get_irq_silent(pdev, index);
if (data->throttle_irq == -ENXIO)
return 0;
if (data->throttle_irq < 0)
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index a23563cd118b..707ac21652a6 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -1059,7 +1059,7 @@ static int mmp_pdma_probe(struct platform_device *op)
pdev->dma_channels = dma_channels;

for (i = 0; i < dma_channels; i++) {
- if (platform_get_irq_optional(op, i) > 0)
+ if (platform_get_irq_silent(op, i) > 0)
irq_num++;
}

diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index 2ccd1db5e98f..87aa537f3b72 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -1916,7 +1916,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
int i;

for (i = 0; i < 3; i++) {
- irq = platform_get_irq_optional(pdev, i);
+ irq = platform_get_irq_silent(pdev, i);
if (irq < 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
rc = -EINVAL;
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
index b59fae993626..a1a7d8c0ef13 100644
--- a/drivers/gpio/gpio-altera.c
+++ b/drivers/gpio/gpio-altera.c
@@ -266,7 +266,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
altera_gc->mmchip.gc.owner = THIS_MODULE;
altera_gc->mmchip.gc.parent = &pdev->dev;

- altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0);
+ altera_gc->mapped_irq = platform_get_irq_silent(pdev, 0);

if (altera_gc->mapped_irq < 0)
goto skip_irq;
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index b0f3aca61974..133153a40808 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -543,7 +543,7 @@ static void dwapb_get_irq(struct device *dev, struct fwnode_handle *fwnode,

for (j = 0; j < pp->ngpio; j++) {
if (has_acpi_companion(dev))
- irq = platform_get_irq_optional(to_platform_device(dev), j);
+ irq = platform_get_irq_silent(to_platform_device(dev), j);
else
irq = fwnode_irq_get(fwnode, j);
if (irq > 0)
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 4c1f9e1091b7..eaaf6fd54d79 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -1291,7 +1291,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
* pins.
*/
for (i = 0; i < 4; i++) {
- int irq = platform_get_irq_optional(pdev, i);
+ int irq = platform_get_irq_silent(pdev, i);

if (irq < 0)
continue;
diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c
index bd75401b549d..b945049c1a39 100644
--- a/drivers/gpio/gpio-realtek-otto.c
+++ b/drivers/gpio/gpio-realtek-otto.c
@@ -289,7 +289,7 @@ static int realtek_gpio_probe(struct platform_device *pdev)
ctrl->gc.ngpio = ngpios;
ctrl->gc.owner = THIS_MODULE;

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) {
girq = &ctrl->gc.irq;
girq->chip = &realtek_gpio_irq_chip;
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
index 5b103221b58d..16afb563f813 100644
--- a/drivers/gpio/gpio-tqmx86.c
+++ b/drivers/gpio/gpio-tqmx86.c
@@ -236,7 +236,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
struct resource *res;
int ret, irq;

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq < 0 && irq != -ENXIO)
return irq;

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index b6d3a57e27ed..a451bd19d501 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -658,7 +658,7 @@ static int xgpio_probe(struct platform_device *pdev)

xgpio_save_regs(chip);

- chip->irq = platform_get_irq_optional(pdev, 0);
+ chip->irq = platform_get_irq_silent(pdev, 0);
if (chip->irq <= 0)
goto skip_irq;

diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
index e714d5318f30..8c88a1958fd4 100644
--- a/drivers/gpu/drm/v3d/v3d_irq.c
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
@@ -214,7 +214,7 @@ v3d_irq_init(struct v3d_dev *v3d)
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);

- irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
+ irq1 = platform_get_irq_silent(v3d_to_pdev(v3d), 1);
if (irq1 == -EPROBE_DEFER)
return irq1;
if (irq1 > 0) {
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 490ee3962645..0e53d149a207 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -646,7 +646,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
int_name = NULL;

/* Get the interrupt number */
- dev->irq = platform_get_irq_optional(pdev, 0);
+ dev->irq = platform_get_irq_silent(pdev, 0);

/* disable the bsc interrupt line */
brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index a0af027db04c..c6d21b833964 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -682,7 +682,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)

init_waitqueue_head(&i2c->wait);

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
/*
* Since the SoC does have an interrupt, its DT has an interrupt
* property - But this should be bypassed as the IRQ logic in this
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 86d4f75ef8d3..783b474097f7 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -138,7 +138,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
int ret = 0;
int irq;

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
/* If irq is 0, we do polling. */
if (irq < 0)
irq = 0;
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 37f9a4499fdb..934669b20d0d 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -417,7 +417,7 @@ static int intc_irqpin_probe(struct platform_device *pdev)

/* allow any number of IRQs between 1 and INTC_IRQPIN_MAX */
for (k = 0; k < INTC_IRQPIN_MAX; k++) {
- ret = platform_get_irq_optional(pdev, k);
+ ret = platform_get_irq_silent(pdev, k);
if (ret == -ENXIO)
break;
if (ret < 0)
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index 909325f88239..95ff42746e95 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -141,7 +141,7 @@ static int irqc_probe(struct platform_device *pdev)

/* allow any number of IRQs between 1 and IRQC_IRQ_MAX */
for (k = 0; k < IRQC_IRQ_MAX; k++) {
- ret = platform_get_irq_optional(pdev, k);
+ ret = platform_get_irq_silent(pdev, k);
if (ret == -ENXIO)
break;
if (ret < 0)
diff --git a/drivers/mfd/intel_pmc_bxt.c b/drivers/mfd/intel_pmc_bxt.c
index 9f01d38acc7f..dc58dfd87043 100644
--- a/drivers/mfd/intel_pmc_bxt.c
+++ b/drivers/mfd/intel_pmc_bxt.c
@@ -309,7 +309,7 @@ static int intel_pmc_get_resources(struct platform_device *pdev,
struct resource *res;
int ret;

- scu_data->irq = platform_get_irq_optional(pdev, 0);
+ scu_data->irq = platform_get_irq_silent(pdev, 0);

res = platform_get_resource(pdev, IORESOURCE_MEM,
PLAT_RESOURCE_IPC_INDEX);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index bcc595c70a9f..aa5579520b06 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1396,7 +1396,7 @@ static int sh_mmcif_probe(struct platform_device *pdev)
const char *name;

irq[0] = platform_get_irq(pdev, 0);
- irq[1] = platform_get_irq_optional(pdev, 1);
+ irq[1] = platform_get_irq_silent(pdev, 1);
if (irq[0] < 0)
return -ENXIO;

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index f75929783b94..2aa10a1755ba 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2955,7 +2955,7 @@ static int brcmnand_edu_setup(struct platform_device *pdev)
/* initialize edu */
brcmnand_edu_init(ctrl);

- ctrl->edu_irq = platform_get_irq_optional(pdev, 1);
+ ctrl->edu_irq = platform_get_irq_silent(pdev, 1);
if (ctrl->edu_irq < 0) {
dev_warn(dev,
"FLASH EDU enabled, using ctlrdy irq\n");
diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c
index 428e08362956..c33958bda059 100644
--- a/drivers/mtd/nand/raw/renesas-nand-controller.c
+++ b/drivers/mtd/nand/raw/renesas-nand-controller.c
@@ -1354,7 +1354,7 @@ static int rnandc_probe(struct platform_device *pdev)
goto disable_hclk;

rnandc_dis_interrupts(rnandc);
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq == -EPROBE_DEFER) {
ret = irq;
goto disable_eclk;
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 226f4403cfed..4cfc62a5380a 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -3989,7 +3989,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
err = priv->irq1;
goto err;
}
- priv->wol_irq = platform_get_irq_optional(pdev, 2);
+ priv->wol_irq = platform_get_irq_silent(pdev, 2);

priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base)) {
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 0985ab216566..43f181e13bab 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -1508,7 +1508,7 @@ dm9000_probe(struct platform_device *pdev)
goto out;
}

- db->irq_wake = platform_get_irq_optional(pdev, 1);
+ db->irq_wake = platform_get_irq_silent(pdev, 1);
if (db->irq_wake >= 0) {
dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index af99017a5453..dc65bb1caad4 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -612,7 +612,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)

irq = platform_get_irq_byname_optional(pdev, "pps");
if (irq < 0)
- irq = platform_get_irq_optional(pdev, irq_idx);
+ irq = platform_get_irq_silent(pdev, irq_idx);
/* Failure to get an irq is not fatal,
* only the PTP_CLOCK_PPS clock events should stop
*/
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index ef878973b859..cdf4ff41bd66 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -349,7 +349,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
}


- dev->err_interrupt = platform_get_irq_optional(pdev, 0);
+ dev->err_interrupt = platform_get_irq_silent(pdev, 0);
if (dev->err_interrupt > 0 &&
resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
dev_err(&pdev->dev,
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 31df3267a01a..30d5a785d485 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1455,7 +1455,7 @@ static int emac_dev_open(struct net_device *ndev)

/* Request IRQ */
if (dev_of_node(&priv->pdev->dev)) {
- while ((ret = platform_get_irq_optional(priv->pdev, res_num)) != -ENXIO) {
+ while ((ret = platform_get_irq_silent(priv->pdev, res_num)) != -ENXIO) {
if (ret < 0)
goto rollback;

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 23ac353b35fe..5be7e93d4087 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1961,13 +1961,13 @@ static int axienet_probe(struct platform_device *pdev)
lp->rx_irq = irq_of_parse_and_map(np, 1);
lp->tx_irq = irq_of_parse_and_map(np, 0);
of_node_put(np);
- lp->eth_irq = platform_get_irq_optional(pdev, 0);
+ lp->eth_irq = platform_get_irq_silent(pdev, 0);
} else {
/* Check for these resources directly on the Ethernet node. */
lp->dma_regs = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
lp->rx_irq = platform_get_irq(pdev, 1);
lp->tx_irq = platform_get_irq(pdev, 0);
- lp->eth_irq = platform_get_irq_optional(pdev, 2);
+ lp->eth_irq = platform_get_irq_silent(pdev, 2);
}
if (IS_ERR(lp->dma_regs)) {
dev_err(&pdev->dev, "could not map DMA regs\n");
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index c49108a72865..c4a709470398 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -852,7 +852,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
smmu_pmu->reloc_base = smmu_pmu->reg_base;
}

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0)
smmu_pmu->irq = irq;

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 9de617ca9daa..9cbd4e396f0f 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -672,7 +672,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)

channel->obint_enable_bits = USB2_OBINT_BITS;
/* get irq number here and request_irq for OTG in phy_init */
- channel->irq = platform_get_irq_optional(pdev, 0);
+ channel->irq = platform_get_irq_silent(pdev, 0);
channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
int ret;
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index 52fa2f4cd618..1acf9355ab44 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -848,7 +848,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
"gpio-ranges");

/* optional GPIO interrupt support */
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0) {
struct irq_chip *irqc;
struct gpio_irq_chip *girq;
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 4c01333e1406..cc5a74aea6e5 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -1568,7 +1568,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
#endif

/* set up interrupts */
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0) {
struct gpio_irq_chip *girq;

diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 561fa322b0b4..984c5c0b4304 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -879,7 +879,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
gc->parent = dev;

/* set up interrupts */
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0) {
struct gpio_irq_chip *girq;

diff --git a/drivers/pinctrl/pinctrl-keembay.c b/drivers/pinctrl/pinctrl-keembay.c
index 152c35bce8ec..628f642ec220 100644
--- a/drivers/pinctrl/pinctrl-keembay.c
+++ b/drivers/pinctrl/pinctrl-keembay.c
@@ -1490,7 +1490,7 @@ static int keembay_gpiochip_probe(struct keembay_pinctrl *kpc,
struct keembay_gpio_irq *kmb_irq = &kpc->irq[i];
int irq;

- irq = platform_get_irq_optional(pdev, i);
+ irq = platform_get_irq_silent(pdev, i);
if (irq <= 0)
continue;

diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 0f6e9305fec5..47160ec0407c 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1108,7 +1108,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
}
drvdata->dev = dev;

- ret = platform_get_irq_optional(pdev, 0);
+ ret = platform_get_irq_silent(pdev, 0);
if (ret < 0 && ret != -ENXIO)
return ret;
if (ret > 0)
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index d6306d2a096f..30f06d4b6ad8 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -397,7 +397,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
* Some boards do not have an IRQ allotted for cros_ec_lpc,
* which makes ENXIO an expected (and safe) scenario.
*/
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0)
ec_dev->irq = irq;
else if (irq != -ENXIO) {
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index e9f852f7c27f..bffc9093a629 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -305,7 +305,7 @@ static int lis3lv02d_probe(struct platform_device *device)
lis3_dev.write = lis3lv02d_acpi_write;

/* obtain IRQ number of our device from ACPI */
- ret = platform_get_irq_optional(device, 0);
+ ret = platform_get_irq_silent(device, 0);
if (ret > 0)
lis3_dev.irq = ret;

diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
index 66bb39fd0ef9..2f22d5de767a 100644
--- a/drivers/platform/x86/intel/punit_ipc.c
+++ b/drivers/platform/x86/intel/punit_ipc.c
@@ -277,7 +277,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, punit_ipcdev);

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq < 0) {
dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n");
} else {
diff --git a/drivers/platform/x86/intel_scu_pltdrv.c b/drivers/platform/x86/intel_scu_pltdrv.c
index 56ec6ae4c824..2d3e5174da8e 100644
--- a/drivers/platform/x86/intel_scu_pltdrv.c
+++ b/drivers/platform/x86/intel_scu_pltdrv.c
@@ -23,7 +23,7 @@ static int intel_scu_platform_probe(struct platform_device *pdev)
struct intel_scu_ipc_dev *scu;
const struct resource *res;

- scu_data.irq = platform_get_irq_optional(pdev, 0);
+ scu_data.irq = platform_get_irq_silent(pdev, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOMEM;
diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
index bdf924b73e47..e279a4bdf6a4 100644
--- a/drivers/power/supply/mp2629_charger.c
+++ b/drivers/power/supply/mp2629_charger.c
@@ -580,7 +580,7 @@ static int mp2629_charger_probe(struct platform_device *pdev)
charger->dev = dev;
platform_set_drvdata(pdev, charger);

- irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);
+ irq = platform_get_irq_silent(to_platform_device(dev->parent), 0);
if (irq < 0) {
dev_err(dev, "get irq fail: %d\n", irq);
return irq;
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index f0f6b9b6daec..aebc8a73acfe 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
/* Try to get irq number. We also can work in
* the mode without IRQ.
*/
- m48t59->irq = platform_get_irq_optional(pdev, 0);
+ m48t59->irq = platform_get_irq_silent(pdev, 0);
if (m48t59->irq <= 0)
m48t59->irq = NO_IRQ;

diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index d3a23b1c2a4c..76f4934a23e7 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -451,7 +451,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
goto err_put_master;
}

- host->irq = platform_get_irq_optional(pdev, 0);
+ host->irq = platform_get_irq_silent(pdev, 0);
if (host->irq == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto err_put_master;
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 5c93730615f8..64aec31355bb 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -828,7 +828,7 @@ static int mtk_nor_probe(struct platform_device *pdev)

mtk_nor_init(sp);

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);

if (irq < 0) {
dev_warn(sp->dev, "IRQ not available.");
diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 43eb25b167bc..ef6c6880a943 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -429,7 +429,7 @@ static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,
int ret, irq;

for (i = 0; i < 2; i++) {
- irq = platform_get_irq_optional(pdev, i);
+ irq = platform_get_irq_silent(pdev, i);
if (irq < 0)
return irq;

diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index fb65dc601b23..1f4cbe37627e 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -585,7 +585,7 @@ static int mtk8250_probe(struct platform_device *pdev)
goto err_pm_disable;
}

- data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
+ data->rx_wakeup_irq = platform_get_irq_silent(pdev, 1);

return 0;

diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c
index 37bffe406b18..1cd2bdee3d40 100644
--- a/drivers/tty/serial/altera_jtaguart.c
+++ b/drivers/tty/serial/altera_jtaguart.c
@@ -439,7 +439,7 @@ static int altera_jtaguart_probe(struct platform_device *pdev)
else
return -ENODEV;

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq < 0 && irq != -ENXIO)
return irq;
if (irq > 0)
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index 64a352b40197..415883ccfbbd 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -576,7 +576,7 @@ static int altera_uart_probe(struct platform_device *pdev)
else
return -EINVAL;

- ret = platform_get_irq_optional(pdev, 0);
+ ret = platform_get_irq_silent(pdev, 0);
if (ret < 0 && ret != -ENXIO)
return ret;
if (ret > 0)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index df8a0c8b8b29..8791f51e52cb 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2258,8 +2258,8 @@ static int imx_uart_probe(struct platform_device *pdev)
rxirq = platform_get_irq(pdev, 0);
if (rxirq < 0)
return rxirq;
- txirq = platform_get_irq_optional(pdev, 1);
- rtsirq = platform_get_irq_optional(pdev, 2);
+ txirq = platform_get_irq_silent(pdev, 1);
+ rtsirq = platform_get_irq_silent(pdev, 2);

sport->port.dev = &pdev->dev;
sport->port.mapbase = res->start;
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index aedc38893e6c..893922e520a9 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1406,7 +1406,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);

if (!console)
- port->wakeup_irq = platform_get_irq_optional(pdev, 1);
+ port->wakeup_irq = platform_get_irq_silent(pdev, 1);

if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap"))
port->rx_tx_swap = true;
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 968967d722d4..f2fb298b3aed 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2860,7 +2860,7 @@ static int sci_init_single(struct platform_device *dev,

for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) {
if (i)
- sci_port->irqs[i] = platform_get_irq_optional(dev, i);
+ sci_port->irqs[i] = platform_get_irq_silent(dev, i);
else
sci_port->irqs[i] = platform_get_irq(dev, i);
}
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 63258b6accc4..a2673a8ebd3f 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -160,7 +160,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
priv->pdev = pdev;

if (!uioinfo->irq) {
- ret = platform_get_irq_optional(pdev, 0);
+ ret = platform_get_irq_silent(pdev, 0);
uioinfo->irq = ret;
if (ret == -ENXIO)
uioinfo->irq = UIO_IRQ_NONE;
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index 68cd4b68e3a2..5237c62f60f0 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -1353,7 +1353,7 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
return -ENOMEM;

tegra_phy->soc_config = of_device_get_match_data(&pdev->dev);
- tegra_phy->irq = platform_get_irq_optional(pdev, 0);
+ tegra_phy->irq = platform_get_irq_silent(pdev, 0);

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index 68a1c87066d7..60b4f5ce5aa1 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -33,7 +33,7 @@ static int get_platform_irq(struct vfio_platform_device *vdev, int i)
{
struct platform_device *pdev = (struct platform_device *) vdev->opaque;

- return platform_get_irq_optional(pdev, i);
+ return platform_get_irq_silent(pdev, i);
}

static int vfio_platform_probe(struct platform_device *pdev)
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index cd578843277e..9c792ab66a83 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -617,7 +617,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
* pending either until the next watchdog kick event or up to the
* system reset.
*/
- ret = platform_get_irq_optional(pdev, 0);
+ ret = platform_get_irq_silent(pdev, 0);
if (ret > 0) {
ret = devm_request_irq(dev, ret, dw_wdt_irq,
IRQF_SHARED | IRQF_TRIGGER_RISING,
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 127eefc9161d..c533fbb37895 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -602,7 +602,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &dev->wdt.status);

/* Request the IRQ only after the watchdog is disabled */
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0) {
/*
* Not all supported platforms specify an interrupt for the
@@ -617,7 +617,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
}

/* Optional 2nd interrupt for pretimeout */
- irq = platform_get_irq_optional(pdev, 1);
+ irq = platform_get_irq_silent(pdev, 1);
if (irq > 0) {
orion_wdt_info.options |= WDIOF_PRETIMEOUT;
ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq,
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 0d2209c5eaca..f1bbfed047a1 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -257,7 +257,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
}

/* check if there is pretimeout support */
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (data->pretimeout && irq > 0) {
ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
"wdt_bark", &wdt->wdd);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 7c96f169d274..6d495f15f717 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -69,7 +69,14 @@ extern void __iomem *
devm_platform_ioremap_resource_byname(struct platform_device *pdev,
const char *name);
extern int platform_get_irq(struct platform_device *, unsigned int);
-extern int platform_get_irq_optional(struct platform_device *, unsigned int);
+extern int platform_get_irq_silent(struct platform_device *, unsigned int);
+
+/*
+ * platform_get_irq_optional was recently renamed to platform_get_irq_silent.
+ * Fixup users to not break patches that were created before the rename.
+ */
+#define platform_get_irq_optional(pdev, index) platform_get_irq_silent(pdev, index)
+
extern int platform_irq_count(struct platform_device *);
extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
struct irq_affinity *affd,
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index 5cb58929090d..f7cfe8f7cce0 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -642,7 +642,7 @@ static int dw_i2s_probe(struct platform_device *pdev)

dev->dev = &pdev->dev;

- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq >= 0) {
ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
pdev->name, dev);
diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c
index a6fb74ba1c42..ee0159b7e9f6 100644
--- a/sound/soc/intel/keembay/kmb_platform.c
+++ b/sound/soc/intel/keembay/kmb_platform.c
@@ -882,7 +882,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev)
kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));

if (kmb_i2s->use_pio) {
- irq = platform_get_irq_optional(pdev, 0);
+ irq = platform_get_irq_silent(pdev, 0);
if (irq > 0) {
ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
pdev->name, kmb_i2s);
--
2.34.1



--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (39.46 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-13 20:18:04

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.

Reviewed-by: Mark Brown <[email protected]>


Attachments:
(No filename) (607.00 B)
signature.asc (488.00 B)
Download all attachments

2022-01-13 20:31:47

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 13, 2022 at 11:44 AM Uwe Kleine-König
<[email protected]> wrote:
>
> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.
>
> To prevent people's expectations that there is a semantic difference
> between these too, rename platform_get_irq_optional() to
> platform_get_irq_silent() to make the actual difference more obvious.
>
> The #define for the old name can and should be removed once all patches
> currently in flux still relying on platform_get_irq_optional() are
> fixed.
>
> Signed-off-by: Uwe Kleine-König <[email protected]>


For watchdog:

Acked-by: Guenter Roeck <[email protected]>

>
> ---
> Hello,
>
> On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
> > On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-König wrote:
> >
> > > This is all very unfortunate. In my eyes b) is the most sensible
> > > sense, but the past showed that we don't agree here. (The most annoying
> > > part of regulator_get is the warning that is emitted that regularily
> > > makes customers ask what happens here and if this is fixable.)
> >
> > Fortunately it can be fixed, and it's safer to clearly specify things.
> > The prints are there because when the description is wrong enough to
> > cause things to blow up we can fail to boot or run messily and
> > forgetting to describe some supplies (or typoing so they haven't done
> > that) and people were having a hard time figuring out what might've
> > happened.
>
> Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> occationally. Still waiting for it to be merged :-\
> (https://lore.kernel.org/r/[email protected])
>
> > > I think at least c) is easy to resolve because
> > > platform_get_irq_optional() isn't that old yet and mechanically
> > > replacing it by platform_get_irq_silent() should be easy and safe.
> > > And this is orthogonal to the discussion if -ENOXIO is a sensible return
> > > value and if it's as easy as it could be to work with errors on irq
> > > lookups.
> >
> > It'd certainly be good to name anything that doesn't correspond to one
> > of the existing semantics for the API (!) something different rather
> > than adding yet another potentially overloaded meaning.
>
> It seems we're (at least) three who agree about this. Here is a patch
> fixing the name.
>
> Best regards
> Uwe
>
> drivers/base/platform.c | 12 ++++++------
> drivers/char/ipmi/bt-bmc.c | 2 +-
> drivers/char/ipmi/ipmi_si_platform.c | 4 ++--
> drivers/char/tpm/tpm_tis.c | 2 +-
> drivers/counter/interrupt-cnt.c | 2 +-
> drivers/cpufreq/qcom-cpufreq-hw.c | 2 +-
> drivers/dma/mmp_pdma.c | 2 +-
> drivers/edac/xgene_edac.c | 2 +-
> drivers/gpio/gpio-altera.c | 2 +-
> drivers/gpio/gpio-dwapb.c | 2 +-
> drivers/gpio/gpio-mvebu.c | 2 +-
> drivers/gpio/gpio-realtek-otto.c | 2 +-
> drivers/gpio/gpio-tqmx86.c | 2 +-
> drivers/gpio/gpio-xilinx.c | 2 +-
> drivers/gpu/drm/v3d/v3d_irq.c | 2 +-
> drivers/i2c/busses/i2c-brcmstb.c | 2 +-
> drivers/i2c/busses/i2c-ocores.c | 2 +-
> drivers/i2c/busses/i2c-pca-platform.c | 2 +-
> drivers/irqchip/irq-renesas-intc-irqpin.c | 2 +-
> drivers/irqchip/irq-renesas-irqc.c | 2 +-
> drivers/mfd/intel_pmc_bxt.c | 2 +-
> drivers/mmc/host/sh_mmcif.c | 2 +-
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +-
> drivers/mtd/nand/raw/renesas-nand-controller.c | 2 +-
> drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +-
> drivers/net/ethernet/davicom/dm9000.c | 2 +-
> drivers/net/ethernet/freescale/fec_ptp.c | 2 +-
> drivers/net/ethernet/marvell/mvmdio.c | 2 +-
> drivers/net/ethernet/ti/davinci_emac.c | 2 +-
> drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
> drivers/perf/arm_smmuv3_pmu.c | 2 +-
> drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
> drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +-
> drivers/pinctrl/intel/pinctrl-baytrail.c | 2 +-
> drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +-
> drivers/pinctrl/pinctrl-keembay.c | 2 +-
> drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +-
> drivers/platform/chrome/cros_ec_lpc.c | 2 +-
> drivers/platform/x86/hp_accel.c | 2 +-
> drivers/platform/x86/intel/punit_ipc.c | 2 +-
> drivers/platform/x86/intel_scu_pltdrv.c | 2 +-
> drivers/power/supply/mp2629_charger.c | 2 +-
> drivers/rtc/rtc-m48t59.c | 2 +-
> drivers/spi/spi-hisi-sfc-v3xx.c | 2 +-
> drivers/spi/spi-mtk-nor.c | 2 +-
> drivers/thermal/rcar_gen3_thermal.c | 2 +-
> drivers/tty/serial/8250/8250_mtk.c | 2 +-
> drivers/tty/serial/altera_jtaguart.c | 2 +-
> drivers/tty/serial/altera_uart.c | 2 +-
> drivers/tty/serial/imx.c | 4 ++--
> drivers/tty/serial/qcom_geni_serial.c | 2 +-
> drivers/tty/serial/sh-sci.c | 2 +-
> drivers/uio/uio_pdrv_genirq.c | 2 +-
> drivers/usb/phy/phy-tegra-usb.c | 2 +-
> drivers/vfio/platform/vfio_platform.c | 2 +-
> drivers/watchdog/dw_wdt.c | 2 +-
> drivers/watchdog/orion_wdt.c | 4 ++--
> drivers/watchdog/qcom-wdt.c | 2 +-
> include/linux/platform_device.h | 9 ++++++++-
> sound/soc/dwc/dwc-i2s.c | 2 +-
> sound/soc/intel/keembay/kmb_platform.c | 2 +-
> 61 files changed, 77 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 6cb04ac48bf0..acb9962b9889 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
> #endif /* CONFIG_HAS_IOMEM */
>
> /**
> - * platform_get_irq_optional - get an optional IRQ for a device
> + * platform_get_irq_silent - get an optional IRQ for a device
> * @dev: platform device
> * @num: IRQ number index
> *
> @@ -160,13 +160,13 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
> *
> * For example::
> *
> - * int irq = platform_get_irq_optional(pdev, 0);
> + * int irq = platform_get_irq_silent(pdev, 0);
> * if (irq < 0)
> * return irq;
> *
> * Return: non-zero IRQ number on success, negative error number on failure.
> */
> -int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
> +int platform_get_irq_silent(struct platform_device *dev, unsigned int num)
> {
> int ret;
> #ifdef CONFIG_SPARC
> @@ -234,7 +234,7 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
> WARN(ret == 0, "0 is an invalid IRQ number\n");
> return ret;
> }
> -EXPORT_SYMBOL_GPL(platform_get_irq_optional);
> +EXPORT_SYMBOL_GPL(platform_get_irq_silent);
>
> /**
> * platform_get_irq - get an IRQ for a device
> @@ -257,7 +257,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
> {
> int ret;
>
> - ret = platform_get_irq_optional(dev, num);
> + ret = platform_get_irq_silent(dev, num);
> if (ret < 0)
> return dev_err_probe(&dev->dev, ret,
> "IRQ index %u not found\n", num);
> @@ -276,7 +276,7 @@ int platform_irq_count(struct platform_device *dev)
> {
> int ret, nr = 0;
>
> - while ((ret = platform_get_irq_optional(dev, nr)) >= 0)
> + while ((ret = platform_get_irq_silent(dev, nr)) >= 0)
> nr++;
>
> if (ret == -EPROBE_DEFER)
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index 7450904e330a..73bdbc59c9d0 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -379,7 +379,7 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> int rc;
> u32 reg;
>
> - bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> + bt_bmc->irq = platform_get_irq_silent(pdev, 0);
> if (bt_bmc->irq < 0)
> return bt_bmc->irq;
>
> diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c
> index 505cc978c97a..4c666eed24d9 100644
> --- a/drivers/char/ipmi/ipmi_si_platform.c
> +++ b/drivers/char/ipmi/ipmi_si_platform.c
> @@ -192,7 +192,7 @@ static int platform_ipmi_probe(struct platform_device *pdev)
> else
> io.slave_addr = slave_addr;
>
> - io.irq = platform_get_irq_optional(pdev, 0);
> + io.irq = platform_get_irq_silent(pdev, 0);
> if (io.irq > 0)
> io.irq_setup = ipmi_std_irq_setup;
> else
> @@ -368,7 +368,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
> io.irq = tmp;
> io.irq_setup = acpi_gpe_irq_setup;
> } else {
> - int irq = platform_get_irq_optional(pdev, 0);
> + int irq = platform_get_irq_silent(pdev, 0);
>
> if (irq > 0) {
> io.irq = irq;
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index d3f2e5364c27..3e6785ad62f2 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -318,7 +318,7 @@ static int tpm_tis_plat_probe(struct platform_device *pdev)
> }
> tpm_info.res = *res;
>
> - tpm_info.irq = platform_get_irq_optional(pdev, 0);
> + tpm_info.irq = platform_get_irq_silent(pdev, 0);
> if (tpm_info.irq <= 0) {
> if (pdev != force_pdev)
> tpm_info.irq = -1;
> diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
> index 8514a87fcbee..65b9254e63a9 100644
> --- a/drivers/counter/interrupt-cnt.c
> +++ b/drivers/counter/interrupt-cnt.c
> @@ -155,7 +155,7 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
> if (!priv)
> return -ENOMEM;
>
> - priv->irq = platform_get_irq_optional(pdev, 0);
> + priv->irq = platform_get_irq_silent(pdev, 0);
> if (priv->irq == -ENXIO)
> priv->irq = 0;
> else if (priv->irq < 0)
> diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
> index 05f3d7876e44..3d1fe9ba98a7 100644
> --- a/drivers/cpufreq/qcom-cpufreq-hw.c
> +++ b/drivers/cpufreq/qcom-cpufreq-hw.c
> @@ -374,7 +374,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
> * Look for LMh interrupt. If no interrupt line is specified /
> * if there is an error, allow cpufreq to be enabled as usual.
> */
> - data->throttle_irq = platform_get_irq_optional(pdev, index);
> + data->throttle_irq = platform_get_irq_silent(pdev, index);
> if (data->throttle_irq == -ENXIO)
> return 0;
> if (data->throttle_irq < 0)
> diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
> index a23563cd118b..707ac21652a6 100644
> --- a/drivers/dma/mmp_pdma.c
> +++ b/drivers/dma/mmp_pdma.c
> @@ -1059,7 +1059,7 @@ static int mmp_pdma_probe(struct platform_device *op)
> pdev->dma_channels = dma_channels;
>
> for (i = 0; i < dma_channels; i++) {
> - if (platform_get_irq_optional(op, i) > 0)
> + if (platform_get_irq_silent(op, i) > 0)
> irq_num++;
> }
>
> diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
> index 2ccd1db5e98f..87aa537f3b72 100644
> --- a/drivers/edac/xgene_edac.c
> +++ b/drivers/edac/xgene_edac.c
> @@ -1916,7 +1916,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
> int i;
>
> for (i = 0; i < 3; i++) {
> - irq = platform_get_irq_optional(pdev, i);
> + irq = platform_get_irq_silent(pdev, i);
> if (irq < 0) {
> dev_err(&pdev->dev, "No IRQ resource\n");
> rc = -EINVAL;
> diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
> index b59fae993626..a1a7d8c0ef13 100644
> --- a/drivers/gpio/gpio-altera.c
> +++ b/drivers/gpio/gpio-altera.c
> @@ -266,7 +266,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
> altera_gc->mmchip.gc.owner = THIS_MODULE;
> altera_gc->mmchip.gc.parent = &pdev->dev;
>
> - altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0);
> + altera_gc->mapped_irq = platform_get_irq_silent(pdev, 0);
>
> if (altera_gc->mapped_irq < 0)
> goto skip_irq;
> diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
> index b0f3aca61974..133153a40808 100644
> --- a/drivers/gpio/gpio-dwapb.c
> +++ b/drivers/gpio/gpio-dwapb.c
> @@ -543,7 +543,7 @@ static void dwapb_get_irq(struct device *dev, struct fwnode_handle *fwnode,
>
> for (j = 0; j < pp->ngpio; j++) {
> if (has_acpi_companion(dev))
> - irq = platform_get_irq_optional(to_platform_device(dev), j);
> + irq = platform_get_irq_silent(to_platform_device(dev), j);
> else
> irq = fwnode_irq_get(fwnode, j);
> if (irq > 0)
> diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
> index 4c1f9e1091b7..eaaf6fd54d79 100644
> --- a/drivers/gpio/gpio-mvebu.c
> +++ b/drivers/gpio/gpio-mvebu.c
> @@ -1291,7 +1291,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
> * pins.
> */
> for (i = 0; i < 4; i++) {
> - int irq = platform_get_irq_optional(pdev, i);
> + int irq = platform_get_irq_silent(pdev, i);
>
> if (irq < 0)
> continue;
> diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c
> index bd75401b549d..b945049c1a39 100644
> --- a/drivers/gpio/gpio-realtek-otto.c
> +++ b/drivers/gpio/gpio-realtek-otto.c
> @@ -289,7 +289,7 @@ static int realtek_gpio_probe(struct platform_device *pdev)
> ctrl->gc.ngpio = ngpios;
> ctrl->gc.owner = THIS_MODULE;
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) {
> girq = &ctrl->gc.irq;
> girq->chip = &realtek_gpio_irq_chip;
> diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
> index 5b103221b58d..16afb563f813 100644
> --- a/drivers/gpio/gpio-tqmx86.c
> +++ b/drivers/gpio/gpio-tqmx86.c
> @@ -236,7 +236,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
> struct resource *res;
> int ret, irq;
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq < 0 && irq != -ENXIO)
> return irq;
>
> diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
> index b6d3a57e27ed..a451bd19d501 100644
> --- a/drivers/gpio/gpio-xilinx.c
> +++ b/drivers/gpio/gpio-xilinx.c
> @@ -658,7 +658,7 @@ static int xgpio_probe(struct platform_device *pdev)
>
> xgpio_save_regs(chip);
>
> - chip->irq = platform_get_irq_optional(pdev, 0);
> + chip->irq = platform_get_irq_silent(pdev, 0);
> if (chip->irq <= 0)
> goto skip_irq;
>
> diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
> index e714d5318f30..8c88a1958fd4 100644
> --- a/drivers/gpu/drm/v3d/v3d_irq.c
> +++ b/drivers/gpu/drm/v3d/v3d_irq.c
> @@ -214,7 +214,7 @@ v3d_irq_init(struct v3d_dev *v3d)
> V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
> V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
>
> - irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
> + irq1 = platform_get_irq_silent(v3d_to_pdev(v3d), 1);
> if (irq1 == -EPROBE_DEFER)
> return irq1;
> if (irq1 > 0) {
> diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
> index 490ee3962645..0e53d149a207 100644
> --- a/drivers/i2c/busses/i2c-brcmstb.c
> +++ b/drivers/i2c/busses/i2c-brcmstb.c
> @@ -646,7 +646,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
> int_name = NULL;
>
> /* Get the interrupt number */
> - dev->irq = platform_get_irq_optional(pdev, 0);
> + dev->irq = platform_get_irq_silent(pdev, 0);
>
> /* disable the bsc interrupt line */
> brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
> diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
> index a0af027db04c..c6d21b833964 100644
> --- a/drivers/i2c/busses/i2c-ocores.c
> +++ b/drivers/i2c/busses/i2c-ocores.c
> @@ -682,7 +682,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
>
> init_waitqueue_head(&i2c->wait);
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> /*
> * Since the SoC does have an interrupt, its DT has an interrupt
> * property - But this should be bypassed as the IRQ logic in this
> diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
> index 86d4f75ef8d3..783b474097f7 100644
> --- a/drivers/i2c/busses/i2c-pca-platform.c
> +++ b/drivers/i2c/busses/i2c-pca-platform.c
> @@ -138,7 +138,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
> int ret = 0;
> int irq;
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> /* If irq is 0, we do polling. */
> if (irq < 0)
> irq = 0;
> diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
> index 37f9a4499fdb..934669b20d0d 100644
> --- a/drivers/irqchip/irq-renesas-intc-irqpin.c
> +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
> @@ -417,7 +417,7 @@ static int intc_irqpin_probe(struct platform_device *pdev)
>
> /* allow any number of IRQs between 1 and INTC_IRQPIN_MAX */
> for (k = 0; k < INTC_IRQPIN_MAX; k++) {
> - ret = platform_get_irq_optional(pdev, k);
> + ret = platform_get_irq_silent(pdev, k);
> if (ret == -ENXIO)
> break;
> if (ret < 0)
> diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
> index 909325f88239..95ff42746e95 100644
> --- a/drivers/irqchip/irq-renesas-irqc.c
> +++ b/drivers/irqchip/irq-renesas-irqc.c
> @@ -141,7 +141,7 @@ static int irqc_probe(struct platform_device *pdev)
>
> /* allow any number of IRQs between 1 and IRQC_IRQ_MAX */
> for (k = 0; k < IRQC_IRQ_MAX; k++) {
> - ret = platform_get_irq_optional(pdev, k);
> + ret = platform_get_irq_silent(pdev, k);
> if (ret == -ENXIO)
> break;
> if (ret < 0)
> diff --git a/drivers/mfd/intel_pmc_bxt.c b/drivers/mfd/intel_pmc_bxt.c
> index 9f01d38acc7f..dc58dfd87043 100644
> --- a/drivers/mfd/intel_pmc_bxt.c
> +++ b/drivers/mfd/intel_pmc_bxt.c
> @@ -309,7 +309,7 @@ static int intel_pmc_get_resources(struct platform_device *pdev,
> struct resource *res;
> int ret;
>
> - scu_data->irq = platform_get_irq_optional(pdev, 0);
> + scu_data->irq = platform_get_irq_silent(pdev, 0);
>
> res = platform_get_resource(pdev, IORESOURCE_MEM,
> PLAT_RESOURCE_IPC_INDEX);
> diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
> index bcc595c70a9f..aa5579520b06 100644
> --- a/drivers/mmc/host/sh_mmcif.c
> +++ b/drivers/mmc/host/sh_mmcif.c
> @@ -1396,7 +1396,7 @@ static int sh_mmcif_probe(struct platform_device *pdev)
> const char *name;
>
> irq[0] = platform_get_irq(pdev, 0);
> - irq[1] = platform_get_irq_optional(pdev, 1);
> + irq[1] = platform_get_irq_silent(pdev, 1);
> if (irq[0] < 0)
> return -ENXIO;
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index f75929783b94..2aa10a1755ba 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -2955,7 +2955,7 @@ static int brcmnand_edu_setup(struct platform_device *pdev)
> /* initialize edu */
> brcmnand_edu_init(ctrl);
>
> - ctrl->edu_irq = platform_get_irq_optional(pdev, 1);
> + ctrl->edu_irq = platform_get_irq_silent(pdev, 1);
> if (ctrl->edu_irq < 0) {
> dev_warn(dev,
> "FLASH EDU enabled, using ctlrdy irq\n");
> diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c
> index 428e08362956..c33958bda059 100644
> --- a/drivers/mtd/nand/raw/renesas-nand-controller.c
> +++ b/drivers/mtd/nand/raw/renesas-nand-controller.c
> @@ -1354,7 +1354,7 @@ static int rnandc_probe(struct platform_device *pdev)
> goto disable_hclk;
>
> rnandc_dis_interrupts(rnandc);
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq == -EPROBE_DEFER) {
> ret = irq;
> goto disable_eclk;
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> index 226f4403cfed..4cfc62a5380a 100644
> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> @@ -3989,7 +3989,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
> err = priv->irq1;
> goto err;
> }
> - priv->wol_irq = platform_get_irq_optional(pdev, 2);
> + priv->wol_irq = platform_get_irq_silent(pdev, 2);
>
> priv->base = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(priv->base)) {
> diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
> index 0985ab216566..43f181e13bab 100644
> --- a/drivers/net/ethernet/davicom/dm9000.c
> +++ b/drivers/net/ethernet/davicom/dm9000.c
> @@ -1508,7 +1508,7 @@ dm9000_probe(struct platform_device *pdev)
> goto out;
> }
>
> - db->irq_wake = platform_get_irq_optional(pdev, 1);
> + db->irq_wake = platform_get_irq_silent(pdev, 1);
> if (db->irq_wake >= 0) {
> dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);
>
> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
> index af99017a5453..dc65bb1caad4 100644
> --- a/drivers/net/ethernet/freescale/fec_ptp.c
> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> @@ -612,7 +612,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
>
> irq = platform_get_irq_byname_optional(pdev, "pps");
> if (irq < 0)
> - irq = platform_get_irq_optional(pdev, irq_idx);
> + irq = platform_get_irq_silent(pdev, irq_idx);
> /* Failure to get an irq is not fatal,
> * only the PTP_CLOCK_PPS clock events should stop
> */
> diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
> index ef878973b859..cdf4ff41bd66 100644
> --- a/drivers/net/ethernet/marvell/mvmdio.c
> +++ b/drivers/net/ethernet/marvell/mvmdio.c
> @@ -349,7 +349,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
> }
>
>
> - dev->err_interrupt = platform_get_irq_optional(pdev, 0);
> + dev->err_interrupt = platform_get_irq_silent(pdev, 0);
> if (dev->err_interrupt > 0 &&
> resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
> dev_err(&pdev->dev,
> diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
> index 31df3267a01a..30d5a785d485 100644
> --- a/drivers/net/ethernet/ti/davinci_emac.c
> +++ b/drivers/net/ethernet/ti/davinci_emac.c
> @@ -1455,7 +1455,7 @@ static int emac_dev_open(struct net_device *ndev)
>
> /* Request IRQ */
> if (dev_of_node(&priv->pdev->dev)) {
> - while ((ret = platform_get_irq_optional(priv->pdev, res_num)) != -ENXIO) {
> + while ((ret = platform_get_irq_silent(priv->pdev, res_num)) != -ENXIO) {
> if (ret < 0)
> goto rollback;
>
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index 23ac353b35fe..5be7e93d4087 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -1961,13 +1961,13 @@ static int axienet_probe(struct platform_device *pdev)
> lp->rx_irq = irq_of_parse_and_map(np, 1);
> lp->tx_irq = irq_of_parse_and_map(np, 0);
> of_node_put(np);
> - lp->eth_irq = platform_get_irq_optional(pdev, 0);
> + lp->eth_irq = platform_get_irq_silent(pdev, 0);
> } else {
> /* Check for these resources directly on the Ethernet node. */
> lp->dma_regs = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
> lp->rx_irq = platform_get_irq(pdev, 1);
> lp->tx_irq = platform_get_irq(pdev, 0);
> - lp->eth_irq = platform_get_irq_optional(pdev, 2);
> + lp->eth_irq = platform_get_irq_silent(pdev, 2);
> }
> if (IS_ERR(lp->dma_regs)) {
> dev_err(&pdev->dev, "could not map DMA regs\n");
> diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> index c49108a72865..c4a709470398 100644
> --- a/drivers/perf/arm_smmuv3_pmu.c
> +++ b/drivers/perf/arm_smmuv3_pmu.c
> @@ -852,7 +852,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
> smmu_pmu->reloc_base = smmu_pmu->reg_base;
> }
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0)
> smmu_pmu->irq = irq;
>
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 9de617ca9daa..9cbd4e396f0f 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -672,7 +672,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>
> channel->obint_enable_bits = USB2_OBINT_BITS;
> /* get irq number here and request_irq for OTG in phy_init */
> - channel->irq = platform_get_irq_optional(pdev, 0);
> + channel->irq = platform_get_irq_silent(pdev, 0);
> channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
> if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
> int ret;
> diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
> index 52fa2f4cd618..1acf9355ab44 100644
> --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
> +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
> @@ -848,7 +848,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
> "gpio-ranges");
>
> /* optional GPIO interrupt support */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0) {
> struct irq_chip *irqc;
> struct gpio_irq_chip *girq;
> diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
> index 4c01333e1406..cc5a74aea6e5 100644
> --- a/drivers/pinctrl/intel/pinctrl-baytrail.c
> +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
> @@ -1568,7 +1568,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
> #endif
>
> /* set up interrupts */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0) {
> struct gpio_irq_chip *girq;
>
> diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
> index 561fa322b0b4..984c5c0b4304 100644
> --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
> +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
> @@ -879,7 +879,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
> gc->parent = dev;
>
> /* set up interrupts */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0) {
> struct gpio_irq_chip *girq;
>
> diff --git a/drivers/pinctrl/pinctrl-keembay.c b/drivers/pinctrl/pinctrl-keembay.c
> index 152c35bce8ec..628f642ec220 100644
> --- a/drivers/pinctrl/pinctrl-keembay.c
> +++ b/drivers/pinctrl/pinctrl-keembay.c
> @@ -1490,7 +1490,7 @@ static int keembay_gpiochip_probe(struct keembay_pinctrl *kpc,
> struct keembay_gpio_irq *kmb_irq = &kpc->irq[i];
> int irq;
>
> - irq = platform_get_irq_optional(pdev, i);
> + irq = platform_get_irq_silent(pdev, i);
> if (irq <= 0)
> continue;
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index 0f6e9305fec5..47160ec0407c 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1108,7 +1108,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
> }
> drvdata->dev = dev;
>
> - ret = platform_get_irq_optional(pdev, 0);
> + ret = platform_get_irq_silent(pdev, 0);
> if (ret < 0 && ret != -ENXIO)
> return ret;
> if (ret > 0)
> diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
> index d6306d2a096f..30f06d4b6ad8 100644
> --- a/drivers/platform/chrome/cros_ec_lpc.c
> +++ b/drivers/platform/chrome/cros_ec_lpc.c
> @@ -397,7 +397,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
> * Some boards do not have an IRQ allotted for cros_ec_lpc,
> * which makes ENXIO an expected (and safe) scenario.
> */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0)
> ec_dev->irq = irq;
> else if (irq != -ENXIO) {
> diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
> index e9f852f7c27f..bffc9093a629 100644
> --- a/drivers/platform/x86/hp_accel.c
> +++ b/drivers/platform/x86/hp_accel.c
> @@ -305,7 +305,7 @@ static int lis3lv02d_probe(struct platform_device *device)
> lis3_dev.write = lis3lv02d_acpi_write;
>
> /* obtain IRQ number of our device from ACPI */
> - ret = platform_get_irq_optional(device, 0);
> + ret = platform_get_irq_silent(device, 0);
> if (ret > 0)
> lis3_dev.irq = ret;
>
> diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c
> index 66bb39fd0ef9..2f22d5de767a 100644
> --- a/drivers/platform/x86/intel/punit_ipc.c
> +++ b/drivers/platform/x86/intel/punit_ipc.c
> @@ -277,7 +277,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, punit_ipcdev);
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq < 0) {
> dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n");
> } else {
> diff --git a/drivers/platform/x86/intel_scu_pltdrv.c b/drivers/platform/x86/intel_scu_pltdrv.c
> index 56ec6ae4c824..2d3e5174da8e 100644
> --- a/drivers/platform/x86/intel_scu_pltdrv.c
> +++ b/drivers/platform/x86/intel_scu_pltdrv.c
> @@ -23,7 +23,7 @@ static int intel_scu_platform_probe(struct platform_device *pdev)
> struct intel_scu_ipc_dev *scu;
> const struct resource *res;
>
> - scu_data.irq = platform_get_irq_optional(pdev, 0);
> + scu_data.irq = platform_get_irq_silent(pdev, 0);
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!res)
> return -ENOMEM;
> diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
> index bdf924b73e47..e279a4bdf6a4 100644
> --- a/drivers/power/supply/mp2629_charger.c
> +++ b/drivers/power/supply/mp2629_charger.c
> @@ -580,7 +580,7 @@ static int mp2629_charger_probe(struct platform_device *pdev)
> charger->dev = dev;
> platform_set_drvdata(pdev, charger);
>
> - irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);
> + irq = platform_get_irq_silent(to_platform_device(dev->parent), 0);
> if (irq < 0) {
> dev_err(dev, "get irq fail: %d\n", irq);
> return irq;
> diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
> index f0f6b9b6daec..aebc8a73acfe 100644
> --- a/drivers/rtc/rtc-m48t59.c
> +++ b/drivers/rtc/rtc-m48t59.c
> @@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
> /* Try to get irq number. We also can work in
> * the mode without IRQ.
> */
> - m48t59->irq = platform_get_irq_optional(pdev, 0);
> + m48t59->irq = platform_get_irq_silent(pdev, 0);
> if (m48t59->irq <= 0)
> m48t59->irq = NO_IRQ;
>
> diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
> index d3a23b1c2a4c..76f4934a23e7 100644
> --- a/drivers/spi/spi-hisi-sfc-v3xx.c
> +++ b/drivers/spi/spi-hisi-sfc-v3xx.c
> @@ -451,7 +451,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
> goto err_put_master;
> }
>
> - host->irq = platform_get_irq_optional(pdev, 0);
> + host->irq = platform_get_irq_silent(pdev, 0);
> if (host->irq == -EPROBE_DEFER) {
> ret = -EPROBE_DEFER;
> goto err_put_master;
> diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
> index 5c93730615f8..64aec31355bb 100644
> --- a/drivers/spi/spi-mtk-nor.c
> +++ b/drivers/spi/spi-mtk-nor.c
> @@ -828,7 +828,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
>
> mtk_nor_init(sp);
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
>
> if (irq < 0) {
> dev_warn(sp->dev, "IRQ not available.");
> diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
> index 43eb25b167bc..ef6c6880a943 100644
> --- a/drivers/thermal/rcar_gen3_thermal.c
> +++ b/drivers/thermal/rcar_gen3_thermal.c
> @@ -429,7 +429,7 @@ static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,
> int ret, irq;
>
> for (i = 0; i < 2; i++) {
> - irq = platform_get_irq_optional(pdev, i);
> + irq = platform_get_irq_silent(pdev, i);
> if (irq < 0)
> return irq;
>
> diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
> index fb65dc601b23..1f4cbe37627e 100644
> --- a/drivers/tty/serial/8250/8250_mtk.c
> +++ b/drivers/tty/serial/8250/8250_mtk.c
> @@ -585,7 +585,7 @@ static int mtk8250_probe(struct platform_device *pdev)
> goto err_pm_disable;
> }
>
> - data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
> + data->rx_wakeup_irq = platform_get_irq_silent(pdev, 1);
>
> return 0;
>
> diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c
> index 37bffe406b18..1cd2bdee3d40 100644
> --- a/drivers/tty/serial/altera_jtaguart.c
> +++ b/drivers/tty/serial/altera_jtaguart.c
> @@ -439,7 +439,7 @@ static int altera_jtaguart_probe(struct platform_device *pdev)
> else
> return -ENODEV;
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq < 0 && irq != -ENXIO)
> return irq;
> if (irq > 0)
> diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
> index 64a352b40197..415883ccfbbd 100644
> --- a/drivers/tty/serial/altera_uart.c
> +++ b/drivers/tty/serial/altera_uart.c
> @@ -576,7 +576,7 @@ static int altera_uart_probe(struct platform_device *pdev)
> else
> return -EINVAL;
>
> - ret = platform_get_irq_optional(pdev, 0);
> + ret = platform_get_irq_silent(pdev, 0);
> if (ret < 0 && ret != -ENXIO)
> return ret;
> if (ret > 0)
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index df8a0c8b8b29..8791f51e52cb 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -2258,8 +2258,8 @@ static int imx_uart_probe(struct platform_device *pdev)
> rxirq = platform_get_irq(pdev, 0);
> if (rxirq < 0)
> return rxirq;
> - txirq = platform_get_irq_optional(pdev, 1);
> - rtsirq = platform_get_irq_optional(pdev, 2);
> + txirq = platform_get_irq_silent(pdev, 1);
> + rtsirq = platform_get_irq_silent(pdev, 2);
>
> sport->port.dev = &pdev->dev;
> sport->port.mapbase = res->start;
> diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
> index aedc38893e6c..893922e520a9 100644
> --- a/drivers/tty/serial/qcom_geni_serial.c
> +++ b/drivers/tty/serial/qcom_geni_serial.c
> @@ -1406,7 +1406,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
> uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
>
> if (!console)
> - port->wakeup_irq = platform_get_irq_optional(pdev, 1);
> + port->wakeup_irq = platform_get_irq_silent(pdev, 1);
>
> if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap"))
> port->rx_tx_swap = true;
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 968967d722d4..f2fb298b3aed 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -2860,7 +2860,7 @@ static int sci_init_single(struct platform_device *dev,
>
> for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) {
> if (i)
> - sci_port->irqs[i] = platform_get_irq_optional(dev, i);
> + sci_port->irqs[i] = platform_get_irq_silent(dev, i);
> else
> sci_port->irqs[i] = platform_get_irq(dev, i);
> }
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 63258b6accc4..a2673a8ebd3f 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -160,7 +160,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
> priv->pdev = pdev;
>
> if (!uioinfo->irq) {
> - ret = platform_get_irq_optional(pdev, 0);
> + ret = platform_get_irq_silent(pdev, 0);
> uioinfo->irq = ret;
> if (ret == -ENXIO)
> uioinfo->irq = UIO_IRQ_NONE;
> diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
> index 68cd4b68e3a2..5237c62f60f0 100644
> --- a/drivers/usb/phy/phy-tegra-usb.c
> +++ b/drivers/usb/phy/phy-tegra-usb.c
> @@ -1353,7 +1353,7 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> tegra_phy->soc_config = of_device_get_match_data(&pdev->dev);
> - tegra_phy->irq = platform_get_irq_optional(pdev, 0);
> + tegra_phy->irq = platform_get_irq_silent(pdev, 0);
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!res) {
> diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
> index 68a1c87066d7..60b4f5ce5aa1 100644
> --- a/drivers/vfio/platform/vfio_platform.c
> +++ b/drivers/vfio/platform/vfio_platform.c
> @@ -33,7 +33,7 @@ static int get_platform_irq(struct vfio_platform_device *vdev, int i)
> {
> struct platform_device *pdev = (struct platform_device *) vdev->opaque;
>
> - return platform_get_irq_optional(pdev, i);
> + return platform_get_irq_silent(pdev, i);
> }
>
> static int vfio_platform_probe(struct platform_device *pdev)
> diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
> index cd578843277e..9c792ab66a83 100644
> --- a/drivers/watchdog/dw_wdt.c
> +++ b/drivers/watchdog/dw_wdt.c
> @@ -617,7 +617,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
> * pending either until the next watchdog kick event or up to the
> * system reset.
> */
> - ret = platform_get_irq_optional(pdev, 0);
> + ret = platform_get_irq_silent(pdev, 0);
> if (ret > 0) {
> ret = devm_request_irq(dev, ret, dw_wdt_irq,
> IRQF_SHARED | IRQF_TRIGGER_RISING,
> diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
> index 127eefc9161d..c533fbb37895 100644
> --- a/drivers/watchdog/orion_wdt.c
> +++ b/drivers/watchdog/orion_wdt.c
> @@ -602,7 +602,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
> set_bit(WDOG_HW_RUNNING, &dev->wdt.status);
>
> /* Request the IRQ only after the watchdog is disabled */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0) {
> /*
> * Not all supported platforms specify an interrupt for the
> @@ -617,7 +617,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
> }
>
> /* Optional 2nd interrupt for pretimeout */
> - irq = platform_get_irq_optional(pdev, 1);
> + irq = platform_get_irq_silent(pdev, 1);
> if (irq > 0) {
> orion_wdt_info.options |= WDIOF_PRETIMEOUT;
> ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq,
> diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
> index 0d2209c5eaca..f1bbfed047a1 100644
> --- a/drivers/watchdog/qcom-wdt.c
> +++ b/drivers/watchdog/qcom-wdt.c
> @@ -257,7 +257,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
> }
>
> /* check if there is pretimeout support */
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (data->pretimeout && irq > 0) {
> ret = devm_request_irq(dev, irq, qcom_wdt_isr, 0,
> "wdt_bark", &wdt->wdd);
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 7c96f169d274..6d495f15f717 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -69,7 +69,14 @@ extern void __iomem *
> devm_platform_ioremap_resource_byname(struct platform_device *pdev,
> const char *name);
> extern int platform_get_irq(struct platform_device *, unsigned int);
> -extern int platform_get_irq_optional(struct platform_device *, unsigned int);
> +extern int platform_get_irq_silent(struct platform_device *, unsigned int);
> +
> +/*
> + * platform_get_irq_optional was recently renamed to platform_get_irq_silent.
> + * Fixup users to not break patches that were created before the rename.
> + */
> +#define platform_get_irq_optional(pdev, index) platform_get_irq_silent(pdev, index)
> +
> extern int platform_irq_count(struct platform_device *);
> extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
> struct irq_affinity *affd,
> diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
> index 5cb58929090d..f7cfe8f7cce0 100644
> --- a/sound/soc/dwc/dwc-i2s.c
> +++ b/sound/soc/dwc/dwc-i2s.c
> @@ -642,7 +642,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
>
> dev->dev = &pdev->dev;
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq >= 0) {
> ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
> pdev->name, dev);
> diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c
> index a6fb74ba1c42..ee0159b7e9f6 100644
> --- a/sound/soc/intel/keembay/kmb_platform.c
> +++ b/sound/soc/intel/keembay/kmb_platform.c
> @@ -882,7 +882,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev)
> kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));
>
> if (kmb_i2s->use_pio) {
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = platform_get_irq_silent(pdev, 0);
> if (irq > 0) {
> ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
> pdev->name, kmb_i2s);
> --
> 2.34.1
>
>
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |

2022-01-13 20:35:49

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/13/22 12:45 AM, Mark Brown wrote:

[...]
> (Do we really need *all* the CCs here?)

Yeah, 25 files were changed and that resulted in 75 persons/lists addressed.
I didn't expect such a wide audience myself... :-)

>> That convinces me, that platform_get_irq_optional() is a bad name. The
>> only difference to platform_get_irq is that it's silent. And returning
>> a dummy irq value (which would make it aligned with the other _optional
>> functions) isn't possible.

> There is regulator_get_optional() which is I believe the earliest of
> these APIs, it doesn't return a dummy either (and is silent too) - this

Hm, I'm seeing it's rather noisy... :-)

> is because regulator_get() does return a dummy since it's the vastly
> common case that regulators must be physically present and them not
> being found is due to there being an error in the system description.
> It's unfortunate that we've ended up with these two different senses for
> _optional(), people frequently get tripped up by it.
>
>>> To me it sounds much more logical for the driver to check if an
>>> optional irq is non-zero (available) or zero (not available), than to
>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>> (or some other error code) to indicate absence. I thought not having
>>> to care about the actual error code was the main reason behind the
>>> introduction of the *_optional() APIs.
>
>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
>> that you can handle an absent GPIO (or clk) as if it were available.

Hm, I've just looked at these and must note that they match 1:1 with
platform_get_irq_optional(). Unfortunately, we can't however behave the
same way in request_irq() -- because it has to support IRQ0 for the sake
of i8253 drivers in arch/...

> Similarly for the regulator API, kind of.

MBR, Sergey

2022-01-13 20:58:02

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/13/22 11:17 PM, Mark Brown wrote:

>> The subsystems regulator, clk and gpio have the concept of a dummy
>> resource. For regulator, clk and gpio there is a semantic difference
>> between the regular _get() function and the _get_optional() variant.
>> (One might return the dummy resource, the other won't. Unfortunately
>> which one implements which isn't the same for these three.) The
>> difference between platform_get_irq() and platform_get_irq_optional() is
>> only that the former might emit an error message and the later won't.

This is only a current difference but I'm still going to return 0 ISO
-ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there
alone... :-)

> Reviewed-by: Mark Brown <[email protected]>

Hm... I'm seeing a tag bit not seeing the patch itself...

MBR, Sergey

2022-01-13 21:43:11

by Florian Fainelli

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()



On 1/13/2022 11:43 AM, Uwe Kleine-König wrote:
> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.
>
> To prevent people's expectations that there is a semantic difference
> between these too, rename platform_get_irq_optional() to
> platform_get_irq_silent() to make the actual difference more obvious.
>
> The #define for the old name can and should be removed once all patches
> currently in flux still relying on platform_get_irq_optional() are
> fixed.
>
> Signed-off-by: Uwe Kleine-König <[email protected]>
> ---
> Hello,
>
> On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
>> On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-König wrote:
>>
>>> This is all very unfortunate. In my eyes b) is the most sensible
>>> sense, but the past showed that we don't agree here. (The most annoying
>>> part of regulator_get is the warning that is emitted that regularily
>>> makes customers ask what happens here and if this is fixable.)
>>
>> Fortunately it can be fixed, and it's safer to clearly specify things.
>> The prints are there because when the description is wrong enough to
>> cause things to blow up we can fail to boot or run messily and
>> forgetting to describe some supplies (or typoing so they haven't done
>> that) and people were having a hard time figuring out what might've
>> happened.
>
> Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> occationally. Still waiting for it to be merged :-\
> (https://lore.kernel.org/r/[email protected])
>
>>> I think at least c) is easy to resolve because
>>> platform_get_irq_optional() isn't that old yet and mechanically
>>> replacing it by platform_get_irq_silent() should be easy and safe.
>>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
>>> value and if it's as easy as it could be to work with errors on irq
>>> lookups.
>>
>> It'd certainly be good to name anything that doesn't correspond to one
>> of the existing semantics for the API (!) something different rather
>> than adding yet another potentially overloaded meaning.
>
> It seems we're (at least) three who agree about this. Here is a patch
> fixing the name.

From an API naming perspective this does not make much sense anymore
with the name chosen, it is understood that whent he function is called
platform_get_irq_optional(), optional applies to the IRQ. An optional
IRQ is something people can reason about because it makes sense.

What is a a "silent" IRQ however? It does not apply to the object it is
trying to fetch to anymore, but to the message that may not be printed
in case the resource failed to be obtained, because said resource is
optional. Woah, that's quite a stretch.

Following the discussion and original 2 patches set from Sergey, it is
not entirely clear to me anymore what is it that we are trying to fix.

I nearly forgot, I would paint it blue, sky blue, not navy blue, not
light blue ;)
--
Florian

2022-01-13 22:44:32

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 13, 2022 at 11:57:43PM +0300, Sergey Shtylyov wrote:
> On 1/13/22 11:17 PM, Mark Brown wrote:
>
> >> The subsystems regulator, clk and gpio have the concept of a dummy
> >> resource. For regulator, clk and gpio there is a semantic difference
> >> between the regular _get() function and the _get_optional() variant.
> >> (One might return the dummy resource, the other won't. Unfortunately
> >> which one implements which isn't the same for these three.) The
> >> difference between platform_get_irq() and platform_get_irq_optional() is
> >> only that the former might emit an error message and the later won't.
>
> This is only a current difference but I'm still going to return 0 ISO
> -ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there
> alone... :-)

This would address a bit of the critic in my commit log. But as 0 isn't
a dummy value like the dummy values that exist for clk, gpiod and
regulator I still think that the naming is a bad idea because it's not
in the spirit of the other *_get_optional functions.

Seeing you say that -ENXIO is a bad return value for
platform_get_irq_optional() and 0 should be used instead, I wonder why
not changing platform_get_irq() to return 0 instead of -ENXIO, too.
This question is for now only about a sensible semantic. That actually
changing platform_get_irq() is probably harder than changing
platform_get_irq_optional() is a different story.

If only platform_get_irq_optional() is changed and given that the
callers have to do something like:

if (this_irq_exists()):
... (e.g. request_irq)
else:
... (e.g. setup polling)

I really think it's a bad idea that this_irq_exists() has to be
different for platform_get_irq() vs. platform_get_irq_optional().

> > Reviewed-by: Mark Brown <[email protected]>
>
> Hm... I'm seeing a tag bit not seeing the patch itself...

See https://lore.kernel.org/all/[email protected]/

This is just a tree-wide
s/platform_get_irq_optional/platform_get_irq_silent/ + a macro to not
break callers of platform_get_irq_optional().

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.21 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-13 23:07:32

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 13, 2022 at 01:42:57PM -0800, Florian Fainelli wrote:
>
>
> On 1/13/2022 11:43 AM, Uwe Kleine-K?nig wrote:
> > The subsystems regulator, clk and gpio have the concept of a dummy
> > resource. For regulator, clk and gpio there is a semantic difference
> > between the regular _get() function and the _get_optional() variant.
> > (One might return the dummy resource, the other won't. Unfortunately
> > which one implements which isn't the same for these three.) The
> > difference between platform_get_irq() and platform_get_irq_optional() is
> > only that the former might emit an error message and the later won't.
> >
> > To prevent people's expectations that there is a semantic difference
> > between these too, rename platform_get_irq_optional() to
> > platform_get_irq_silent() to make the actual difference more obvious.
> >
> > The #define for the old name can and should be removed once all patches
> > currently in flux still relying on platform_get_irq_optional() are
> > fixed.
> >
> > Signed-off-by: Uwe Kleine-K?nig <[email protected]>
> > ---
> > Hello,
> >
> > On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
> > > On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
> > >
> > > > This is all very unfortunate. In my eyes b) is the most sensible
> > > > sense, but the past showed that we don't agree here. (The most annoying
> > > > part of regulator_get is the warning that is emitted that regularily
> > > > makes customers ask what happens here and if this is fixable.)
> > >
> > > Fortunately it can be fixed, and it's safer to clearly specify things.
> > > The prints are there because when the description is wrong enough to
> > > cause things to blow up we can fail to boot or run messily and
> > > forgetting to describe some supplies (or typoing so they haven't done
> > > that) and people were having a hard time figuring out what might've
> > > happened.
> >
> > Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> > occationally. Still waiting for it to be merged :-\
> > (https://lore.kernel.org/r/[email protected])
> >
> > > > I think at least c) is easy to resolve because
> > > > platform_get_irq_optional() isn't that old yet and mechanically
> > > > replacing it by platform_get_irq_silent() should be easy and safe.
> > > > And this is orthogonal to the discussion if -ENOXIO is a sensible return
> > > > value and if it's as easy as it could be to work with errors on irq
> > > > lookups.
> > >
> > > It'd certainly be good to name anything that doesn't correspond to one
> > > of the existing semantics for the API (!) something different rather
> > > than adding yet another potentially overloaded meaning.
> >
> > It seems we're (at least) three who agree about this. Here is a patch
> > fixing the name.
>
> From an API naming perspective this does not make much sense anymore with
> the name chosen, it is understood that whent he function is called
> platform_get_irq_optional(), optional applies to the IRQ. An optional IRQ is
> something people can reason about because it makes sense.

The problem I see is that the semantic is different to the other
available *_get_optional() functions. And this isn't fixable for irqs.
So better don't use that naming scheme.

> What is a a "silent" IRQ however? It does not apply to the object it is
> trying to fetch to anymore, but to the message that may not be printed in
> case the resource failed to be obtained, because said resource is optional.
> Woah, that's quite a stretch.

I'm surprised that the semantic isn't obvious, but ok, I can accept
that.Can you maek a constructive suggestion here? What name pair would
you choose for the two functions functions under discussion?

(BTW, my favourite would be that platform_get_irq() doesn't emit an
error message and the caller is reliable for emitting that. But I think
it's too late for this approach.)

> Following the discussion and original 2 patches set from Sergey, it is not
> entirely clear to me anymore what is it that we are trying to fix.

(I think) Sergey's focus is:

platform_get_irq_optional() returning -ENXIO is ugly, other
functions return -ENOENT and other *_get_optional() functions
return NULL for "This resource doesn't exist". So let's return 0
in this case.

My focus is:

There cannot be an "optional irq" where the driver doesn't have
to care if the irq actually exist or not. So the pattern with
*_get_optional() isn't sensible for irqs and if changing the
returned value meaning "This resource doesn't exist" is sensible
for platform_get_irq_optional(), I claim it's sensible for
platform_get_irq(), too.

So the semantic difference between platform_get_irq() and
platform_get_irq_optional() is only that one emits an error
message and the other doesn't. So this function pair should use
a different naming than get + get_optional as this naming evokes
expectations that must be wrong as there cannot be a dummy irq
value.

> I nearly forgot, I would paint it blue, sky blue, not navy blue, not light
> blue ;)

no way. green is the ultimate blue for platform_get_irq() :-)

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (5.23 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-14 06:57:42

by Peter Korsgaard

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

>>>>> "Uwe" == Uwe Kleine-König <[email protected]> writes:

> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.

> To prevent people's expectations that there is a semantic difference
> between these too, rename platform_get_irq_optional() to
> platform_get_irq_silent() to make the actual difference more obvious.

> The #define for the old name can and should be removed once all patches
> currently in flux still relying on platform_get_irq_optional() are
> fixed.

> Signed-off-by: Uwe Kleine-König <[email protected]>

For i2c-ocores.c:

Acked-by: Peter Korsgaard <[email protected]>

--
Bye, Peter Korsgaard

2022-01-14 09:26:59

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello Sergey,

On Thu, Jan 13, 2022 at 11:35:34PM +0300, Sergey Shtylyov wrote:
> On 1/13/22 12:45 AM, Mark Brown wrote:
> >>> To me it sounds much more logical for the driver to check if an
> >>> optional irq is non-zero (available) or zero (not available), than to
> >>> sprinkle around checks for -ENXIO. In addition, you have to remember
> >>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> >>> (or some other error code) to indicate absence. I thought not having
> >>> to care about the actual error code was the main reason behind the
> >>> introduction of the *_optional() APIs.
> >
> >> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> >> that you can handle an absent GPIO (or clk) as if it were available.
>
> Hm, I've just looked at these and must note that they match 1:1 with
> platform_get_irq_optional(). Unfortunately, we can't however behave the
> same way in request_irq() -- because it has to support IRQ0 for the sake
> of i8253 drivers in arch/...

Let me reformulate your statement to the IMHO equivalent:

If you set aside the differences between
platform_get_irq_optional() and gpiod_get_optional(),
platform_get_irq_optional() is like gpiod_get_optional().

The introduction of gpiod_get_optional() made it possible to simplify
the following code:

reset_gpio = gpiod_get(...)
if IS_ERR(reset_gpio):
error = PTR_ERR(reset_gpio)
if error != -ENDEV:
return error
else:
gpiod_set_direction(reset_gpiod, INACTIVE)

to

reset_gpio = gpiod_get_optional(....)
if IS_ERR(reset_gpio):
return reset_gpio
gpiod_set_direction(reset_gpiod, INACTIVE)

and I never need to actually know if the reset_gpio actually exists.
Either the line is put into its inactive state, or it doesn't exist and
then gpiod_set_direction is a noop. For a regulator or a clk this works
in a similar way.

However for an interupt this cannot work. You will always have to check
if the irq is actually there or not because if it's not you cannot just
ignore that. So there is no benefit of an optional irq.

Leaving error message reporting aside, the introduction of
platform_get_irq_optional() allows to change

irq = platform_get_irq(...);
if (irq < 0 && irq != -ENXIO) {
return irq;
} else if (irq >= 0) {
... setup irq operation ...
} else { /* irq == -ENXIO */
... setup polling ...
}

to

irq = platform_get_irq_optional(...);
if (irq < 0 && irq != -ENXIO) {
return irq;
} else if (irq >= 0) {
... setup irq operation ...
} else { /* irq == -ENXIO */
... setup polling ...
}

which isn't a win. When changing the return value as you suggest, it can
be changed instead to:

irq = platform_get_irq_optional(...);
if (irq < 0) {
return irq;
} else if (irq > 0) {
... setup irq operation ...
} else { /* irq == 0 */
... setup polling ...
}

which is a tad nicer. If that is your goal however I ask you to also
change the semantic of platform_get_irq() to return 0 on "not found".
Note the win is considerably less compared to gpiod_get_optional vs
gpiod_get however. And then it still lacks the semantic of a dummy irq
which IMHO forfeits the right to call it ..._optional().

Now I'm unwilling to continue the discussion unless there pops up a
suggestion that results in a considerable part (say > 10%) of the
drivers using platform_get_irq_optional not having to check if the
return value corresponds to "not found".

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (3.51 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-14 09:39:27

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Fri, Jan 14, 2022 at 10:26 AM Uwe Kleine-König
<[email protected]> wrote:
> On Thu, Jan 13, 2022 at 11:35:34PM +0300, Sergey Shtylyov wrote:
> > On 1/13/22 12:45 AM, Mark Brown wrote:
> > >>> To me it sounds much more logical for the driver to check if an
> > >>> optional irq is non-zero (available) or zero (not available), than to
> > >>> sprinkle around checks for -ENXIO. In addition, you have to remember
> > >>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> > >>> (or some other error code) to indicate absence. I thought not having
> > >>> to care about the actual error code was the main reason behind the
> > >>> introduction of the *_optional() APIs.
> > >
> > >> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> > >> that you can handle an absent GPIO (or clk) as if it were available.
> >
> > Hm, I've just looked at these and must note that they match 1:1 with
> > platform_get_irq_optional(). Unfortunately, we can't however behave the
> > same way in request_irq() -- because it has to support IRQ0 for the sake
> > of i8253 drivers in arch/...
>
> Let me reformulate your statement to the IMHO equivalent:
>
> If you set aside the differences between
> platform_get_irq_optional() and gpiod_get_optional(),
> platform_get_irq_optional() is like gpiod_get_optional().
>
> The introduction of gpiod_get_optional() made it possible to simplify
> the following code:
>
> reset_gpio = gpiod_get(...)
> if IS_ERR(reset_gpio):
> error = PTR_ERR(reset_gpio)
> if error != -ENDEV:
> return error
> else:
> gpiod_set_direction(reset_gpiod, INACTIVE)
>
> to
>
> reset_gpio = gpiod_get_optional(....)
> if IS_ERR(reset_gpio):
> return reset_gpio
> gpiod_set_direction(reset_gpiod, INACTIVE)
>
> and I never need to actually know if the reset_gpio actually exists.
> Either the line is put into its inactive state, or it doesn't exist and
> then gpiod_set_direction is a noop. For a regulator or a clk this works
> in a similar way.
>
> However for an interupt this cannot work. You will always have to check
> if the irq is actually there or not because if it's not you cannot just
> ignore that. So there is no benefit of an optional irq.
>
> Leaving error message reporting aside, the introduction of
> platform_get_irq_optional() allows to change
>
> irq = platform_get_irq(...);
> if (irq < 0 && irq != -ENXIO) {
> return irq;
> } else if (irq >= 0) {
> ... setup irq operation ...
> } else { /* irq == -ENXIO */
> ... setup polling ...
> }
>
> to
>
> irq = platform_get_irq_optional(...);
> if (irq < 0 && irq != -ENXIO) {
> return irq;
> } else if (irq >= 0) {
> ... setup irq operation ...
> } else { /* irq == -ENXIO */
> ... setup polling ...
> }
>
> which isn't a win. When changing the return value as you suggest, it can
> be changed instead to:
>
> irq = platform_get_irq_optional(...);
> if (irq < 0) {
> return irq;
> } else if (irq > 0) {
> ... setup irq operation ...
> } else { /* irq == 0 */
> ... setup polling ...
> }
>
> which is a tad nicer. If that is your goal however I ask you to also
> change the semantic of platform_get_irq() to return 0 on "not found".

Please don't make that change. If platform_get_irq() would return 0 on
"not found", all existing users have to be changed to:

irq = platform_get_irq(...);
if (irq < 0) {
return irq;
} else if (!irq) {
return -ENOENT;
} else {
... setup irq operation ...
}

If the IRQ is not optional, there should be an error code when it is
not present. This keeps error handling simple.

The _optional() difference lies in the zero/NULL vs. error code in
case of not present.

> Note the win is considerably less compared to gpiod_get_optional vs
> gpiod_get however. And then it still lacks the semantic of a dummy irq
> which IMHO forfeits the right to call it ..._optional().
>
> Now I'm unwilling to continue the discussion unless there pops up a
> suggestion that results in a considerable part (say > 10%) of the
> drivers using platform_get_irq_optional not having to check if the
> return value corresponds to "not found".

Usually drivers do have to check if the interrupt was present or
not, because they may have to change the operation of the driver,
depending on interrupt-based or timer/polling-based processing.

Clocks, regulators, and resets are different, as their absence is
really a no-op. The absence of an interrupt is not a no-op (except
for the separate interrupts vs. a single muxed interrupt case).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-14 09:59:11

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

Hi Uwe,

On Thu, Jan 13, 2022 at 11:43 PM Uwe Kleine-König
<[email protected]> wrote:
> On Thu, Jan 13, 2022 at 11:57:43PM +0300, Sergey Shtylyov wrote:
> > On 1/13/22 11:17 PM, Mark Brown wrote:
> > >> The subsystems regulator, clk and gpio have the concept of a dummy
> > >> resource. For regulator, clk and gpio there is a semantic difference
> > >> between the regular _get() function and the _get_optional() variant.
> > >> (One might return the dummy resource, the other won't. Unfortunately
> > >> which one implements which isn't the same for these three.) The
> > >> difference between platform_get_irq() and platform_get_irq_optional() is
> > >> only that the former might emit an error message and the later won't.
> >
> > This is only a current difference but I'm still going to return 0 ISO
> > -ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there
> > alone... :-)
>
> This would address a bit of the critic in my commit log. But as 0 isn't
> a dummy value like the dummy values that exist for clk, gpiod and
> regulator I still think that the naming is a bad idea because it's not
> in the spirit of the other *_get_optional functions.
>
> Seeing you say that -ENXIO is a bad return value for
> platform_get_irq_optional() and 0 should be used instead, I wonder why
> not changing platform_get_irq() to return 0 instead of -ENXIO, too.
> This question is for now only about a sensible semantic. That actually
> changing platform_get_irq() is probably harder than changing
> platform_get_irq_optional() is a different story.
>
> If only platform_get_irq_optional() is changed and given that the
> callers have to do something like:
>
> if (this_irq_exists()):
> ... (e.g. request_irq)
> else:
> ... (e.g. setup polling)
>
> I really think it's a bad idea that this_irq_exists() has to be
> different for platform_get_irq() vs. platform_get_irq_optional().

For platform_get_irq(), the IRQ being absent is an error condition,
hence it should return an error code.
For platform_get_irq_optional(), the IRQ being absent is not an error
condition, hence it should not return an error code, and 0 is OK.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-14 11:34:30

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/13/22 11:57 PM, Sergey Shtylyov wrote:

>>> The subsystems regulator, clk and gpio have the concept of a dummy
>>> resource. For regulator, clk and gpio there is a semantic difference
>>> between the regular _get() function and the _get_optional() variant.
>>> (One might return the dummy resource, the other won't. Unfortunately
>>> which one implements which isn't the same for these three.) The
>>> difference between platform_get_irq() and platform_get_irq_optional() is
>>> only that the former might emit an error message and the later won't.
>
> This is only a current difference but I'm still going to return 0 ISO
> -ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there

platform.

> alone... :-)
>
>> Reviewed-by: Mark Brown <[email protected]>
>
> Hm... I'm seeing a tag bit not seeing the patch itself...

Grr, my mail server tossed it into the spam folder... :-(

MBR, Sergey

2022-01-14 13:06:20

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.
>
> To prevent people's expectations that there is a semantic difference
> between these too, rename platform_get_irq_optional() to
> platform_get_irq_silent() to make the actual difference more obvious.
>
> The #define for the old name can and should be removed once all patches
> currently in flux still relying on platform_get_irq_optional() are
> fixed.
>
> Signed-off-by: Uwe Kleine-K?nig <[email protected]>
> ---
> Hello,
>
> On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
> > On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
> >
> > > This is all very unfortunate. In my eyes b) is the most sensible
> > > sense, but the past showed that we don't agree here. (The most annoying
> > > part of regulator_get is the warning that is emitted that regularily
> > > makes customers ask what happens here and if this is fixable.)
> >
> > Fortunately it can be fixed, and it's safer to clearly specify things.
> > The prints are there because when the description is wrong enough to
> > cause things to blow up we can fail to boot or run messily and
> > forgetting to describe some supplies (or typoing so they haven't done
> > that) and people were having a hard time figuring out what might've
> > happened.
>
> Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> occationally. Still waiting for it to be merged :-\
> (https://lore.kernel.org/r/[email protected])
>
> > > I think at least c) is easy to resolve because
> > > platform_get_irq_optional() isn't that old yet and mechanically
> > > replacing it by platform_get_irq_silent() should be easy and safe.
> > > And this is orthogonal to the discussion if -ENOXIO is a sensible return
> > > value and if it's as easy as it could be to work with errors on irq
> > > lookups.
> >
> > It'd certainly be good to name anything that doesn't correspond to one
> > of the existing semantics for the API (!) something different rather
> > than adding yet another potentially overloaded meaning.
>
> It seems we're (at least) three who agree about this. Here is a patch
> fixing the name.


And similar number of people are on the other side.

--
With Best Regards,
Andy Shevchenko



2022-01-14 23:02:32

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/14/22 12:42 AM, Florian Fainelli wrote:

>> The subsystems regulator, clk and gpio have the concept of a dummy
>> resource. For regulator, clk and gpio there is a semantic difference
>> between the regular _get() function and the _get_optional() variant.
>> (One might return the dummy resource, the other won't. Unfortunately
>> which one implements which isn't the same for these three.) The
>> difference between platform_get_irq() and platform_get_irq_optional() is
>> only that the former might emit an error message and the later won't.
>>
>> To prevent people's expectations that there is a semantic difference
>> between these too, rename platform_get_irq_optional() to
>> platform_get_irq_silent() to make the actual difference more obvious.
>>
>> The #define for the old name can and should be removed once all patches
>> currently in flux still relying on platform_get_irq_optional() are
>> fixed.
>>
>> Signed-off-by: Uwe Kleine-König <[email protected]>
[...]
>>>> I think at least c) is easy to resolve because
>>>> platform_get_irq_optional() isn't that old yet and mechanically
>>>> replacing it by platform_get_irq_silent() should be easy and safe.
>>>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
>>>> value and if it's as easy as it could be to work with errors on irq
>>>> lookups.
>>>
>>> It'd certainly be good to name anything that doesn't correspond to one
>>> of the existing semantics for the API (!) something different rather
>>> than adding yet another potentially overloaded meaning.
>>
>> It seems we're (at least) three who agree about this. Here is a patch
>> fixing the name.
>
> From an API naming perspective this does not make much sense anymore with the name chosen,
> it is understood that whent he function is called platform_get_irq_optional(), optional applies
> to the IRQ. An optional IRQ is something people can reason about because it makes sense.

Right! :-)

> What is a a "silent" IRQ however? It does not apply to the object it is trying to fetch to
> anymore, but to the message that may not be printed in case the resource failed to be obtained,
> because said resource is optional. Woah, that's quite a stretch.

Right again! :-)

> Following the discussion and original 2 patches set from Sergey, it is not entirely clear to me
> anymore what is it that we are trying to fix.

Andy and me tried to fix the platform_get_irq[_byname]_optional() value, corresponding to
a missing (optional) IRQ resource from -ENXIO to 0, in order to keep the callers error code
agnostic. This change completely aligns e.g. platform_get_irq_optional() with clk_get_optional()
and gpiod_get_optional()...
Unforunately, we can't "fix" request_irq() and company to treat 0 as missing IRQ -- they have
to keep the ability to get called from the arch/ code (that doesn't use platform_get_irq(), etc.

> I nearly forgot, I would paint it blue, sky blue, not navy blue, not light blue ;)

:-)

PS: Florian, something was wrong with your mail client -- I had to manually wrap your quotes,
else there were super long unbroken paragraphs...

2022-01-14 23:02:38

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/13/22 11:35 PM, Sergey Shtylyov wrote:

[...]
>> (Do we really need *all* the CCs here?)
>
> Yeah, 25 files were changed and that resulted in 75 persons/lists addressed.
> I didn't expect such a wide audience myself... :-)

And, of course, I specified --nogit-fallback to scripts/get_maintainers.pl, so
there's no random people...

[...]

MBR, Sergey

2022-01-14 23:03:20

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/14/22 12:25 PM, Uwe Kleine-K?nig wrote:

>>>>> To me it sounds much more logical for the driver to check if an
>>>>> optional irq is non-zero (available) or zero (not available), than to
>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>>> (or some other error code) to indicate absence. I thought not having
>>>>> to care about the actual error code was the main reason behind the
>>>>> introduction of the *_optional() APIs.
>>>
>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
>>>> that you can handle an absent GPIO (or clk) as if it were available.
>>
>> Hm, I've just looked at these and must note that they match 1:1 with
>> platform_get_irq_optional(). Unfortunately, we can't however behave the
>> same way in request_irq() -- because it has to support IRQ0 for the sake
>> of i8253 drivers in arch/...
>
> Let me reformulate your statement to the IMHO equivalent:
>
> If you set aside the differences between
> platform_get_irq_optional() and gpiod_get_optional(),

Sorry, I should make it clear this is actually the diff between a would-be
platform_get_irq_optional() after my patch, not the current code...

> platform_get_irq_optional() is like gpiod_get_optional().
>
> The introduction of gpiod_get_optional() made it possible to simplify
> the following code:
>
> reset_gpio = gpiod_get(...)
> if IS_ERR(reset_gpio):
> error = PTR_ERR(reset_gpio)
> if error != -ENDEV:

ENODEV?

> return error
> else:
> gpiod_set_direction(reset_gpiod, INACTIVE)
>
> to
>
> reset_gpio = gpiod_get_optional(....)
> if IS_ERR(reset_gpio):
> return reset_gpio
> gpiod_set_direction(reset_gpiod, INACTIVE)
>
> and I never need to actually know if the reset_gpio actually exists.
> Either the line is put into its inactive state, or it doesn't exist and
> then gpiod_set_direction is a noop. For a regulator or a clk this works
> in a similar way.
>
> However for an interupt this cannot work. You will always have to check
> if the irq is actually there or not because if it's not you cannot just
> ignore that. So there is no benefit of an optional irq.
>
> Leaving error message reporting aside, the introduction of
> platform_get_irq_optional() allows to change
>
> irq = platform_get_irq(...);
> if (irq < 0 && irq != -ENXIO) {
> return irq;
> } else if (irq >= 0) {

Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).

> ... setup irq operation ...
> } else { /* irq == -ENXIO */
> ... setup polling ...
> }
>
> to
>
> irq = platform_get_irq_optional(...);
> if (irq < 0 && irq != -ENXIO) {
> return irq;
> } else if (irq >= 0) {
> ... setup irq operation ...
> } else { /* irq == -ENXIO */
> ... setup polling ...
> }
>
> which isn't a win. When changing the return value as you suggest, it can
> be changed instead to:
>
> irq = platform_get_irq_optional(...);
> if (irq < 0) {
> return irq;
> } else if (irq > 0) {
> ... setup irq operation ...
> } else { /* irq == 0 */
> ... setup polling ...
> }
>
> which is a tad nicer. If that is your goal however I ask you to also
> change the semantic of platform_get_irq() to return 0 on "not found".

Well, I'm not totally opposed to that... but would there be a considerable win?
Anyway, we should 1st stop returning 0 for "valid" IRQs -- this is done by my patch
the discussed patch series are atop of.

> Note the win is considerably less compared to gpiod_get_optional vs

If there's any at all... We'd basically have to touch /all/ platform_get_irq()
calls (and get an even larger CC list ;-)).

> gpiod_get however. And then it still lacks the semantic of a dummy irq
> which IMHO forfeits the right to call it ..._optional().

Not quite grasping it... Why e.g. clk_get() doesn't return 0 for a not found clock?

> Now I'm unwilling to continue the discussion unless there pops up a
> suggestion that results in a considerable part (say > 10%) of the
> drivers using platform_get_irq_optional not having to check if the
> return value corresponds to "not found".

Note that many actual drivers don't follow the pattern prescribed in the comment to
platform_get_irq_optional() and their check for an optional IRQ look like irq < 0
(and, after my patches, irq <= 0). Maybe we shouldn't even bother returning the error
codes and just return 0 for all kinds of misfortunes instead? :-)

> Best regards
> Uwe

MBR, Sergey

2022-01-14 23:04:07

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/13/22 10:43 PM, Uwe Kleine-K?nig wrote:

> The subsystems regulator, clk and gpio have the concept of a dummy
> resource. For regulator, clk and gpio there is a semantic difference
> between the regular _get() function and the _get_optional() variant.
> (One might return the dummy resource, the other won't. Unfortunately
> which one implements which isn't the same for these three.) The
> difference between platform_get_irq() and platform_get_irq_optional() is
> only that the former might emit an error message and the later won't.
>
> To prevent people's expectations that there is a semantic difference
> between these too, rename platform_get_irq_optional() to
> platform_get_irq_silent() to make the actual difference more obvious.
>
> The #define for the old name can and should be removed once all patches
> currently in flux still relying on platform_get_irq_optional() are
> fixed.

Hm... I'm afraid that with this #define they would never get fixed... :-)

> Signed-off-by: Uwe Kleine-K?nig <[email protected]>
> ---
> Hello,
>
> On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
>> On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
>>
>>> This is all very unfortunate. In my eyes b) is the most sensible
>>> sense, but the past showed that we don't agree here. (The most annoying
>>> part of regulator_get is the warning that is emitted that regularily
>>> makes customers ask what happens here and if this is fixable.)
>>
>> Fortunately it can be fixed, and it's safer to clearly specify things.
>> The prints are there because when the description is wrong enough to
>> cause things to blow up we can fail to boot or run messily and
>> forgetting to describe some supplies (or typoing so they haven't done
>> that) and people were having a hard time figuring out what might've
>> happened.
>
> Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> occationally. Still waiting for it to be merged :-\
> (https://lore.kernel.org/r/[email protected])
>
>>> I think at least c) is easy to resolve because
>>> platform_get_irq_optional() isn't that old yet and mechanically
>>> replacing it by platform_get_irq_silent() should be easy and safe.
>>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
>>> value and if it's as easy as it could be to work with errors on irq
>>> lookups.
>>
>> It'd certainly be good to name anything that doesn't correspond to one
>> of the existing semantics for the API (!) something different rather
>> than adding yet another potentially overloaded meaning.
>
> It seems we're (at least) three who agree about this. Here is a patch
> fixing the name.

I can't say I genrally agree with this patch...

[...]
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 7c96f169d274..6d495f15f717 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -69,7 +69,14 @@ extern void __iomem *
> devm_platform_ioremap_resource_byname(struct platform_device *pdev,
> const char *name);
> extern int platform_get_irq(struct platform_device *, unsigned int);
> -extern int platform_get_irq_optional(struct platform_device *, unsigned int);
> +extern int platform_get_irq_silent(struct platform_device *, unsigned int);
> +
> +/*
> + * platform_get_irq_optional was recently renamed to platform_get_irq_silent.
> + * Fixup users to not break patches that were created before the rename.
> + */
> +#define platform_get_irq_optional(pdev, index) platform_get_irq_silent(pdev, index)
> +

Yeah, why bother fixing if it compiles anyway?
I think an inline wrapper with an indication to gcc that the function is deprecated
(I just forgot how it should look) would be better instead...

> extern int platform_irq_count(struct platform_device *);
> extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
> struct irq_affinity *affd,
[...]
MBR, Sergey

2022-01-14 23:05:07

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Fri, Jan 14, 2022 at 10:45:38PM +0300, Sergey Shtylyov wrote:
> On 1/13/22 10:43 PM, Uwe Kleine-K?nig wrote:
>
> > The subsystems regulator, clk and gpio have the concept of a dummy
> > resource. For regulator, clk and gpio there is a semantic difference
> > between the regular _get() function and the _get_optional() variant.
> > (One might return the dummy resource, the other won't. Unfortunately
> > which one implements which isn't the same for these three.) The
> > difference between platform_get_irq() and platform_get_irq_optional() is
> > only that the former might emit an error message and the later won't.
> >
> > To prevent people's expectations that there is a semantic difference
> > between these too, rename platform_get_irq_optional() to
> > platform_get_irq_silent() to make the actual difference more obvious.
> >
> > The #define for the old name can and should be removed once all patches
> > currently in flux still relying on platform_get_irq_optional() are
> > fixed.
>
> Hm... I'm afraid that with this #define they would never get fixed... :-)

I will care for it.

> > Signed-off-by: Uwe Kleine-K?nig <[email protected]>
> > ---
> > Hello,
> >
> > On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
> >> On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
> >>
> >>> This is all very unfortunate. In my eyes b) is the most sensible
> >>> sense, but the past showed that we don't agree here. (The most annoying
> >>> part of regulator_get is the warning that is emitted that regularily
> >>> makes customers ask what happens here and if this is fixable.)
> >>
> >> Fortunately it can be fixed, and it's safer to clearly specify things.
> >> The prints are there because when the description is wrong enough to
> >> cause things to blow up we can fail to boot or run messily and
> >> forgetting to describe some supplies (or typoing so they haven't done
> >> that) and people were having a hard time figuring out what might've
> >> happened.
> >
> > Yes, that's right. I sent a patch for such a warning in 2019 and pinged
> > occationally. Still waiting for it to be merged :-\
> > (https://lore.kernel.org/r/[email protected])
> >
> >>> I think at least c) is easy to resolve because
> >>> platform_get_irq_optional() isn't that old yet and mechanically
> >>> replacing it by platform_get_irq_silent() should be easy and safe.
> >>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
> >>> value and if it's as easy as it could be to work with errors on irq
> >>> lookups.
> >>
> >> It'd certainly be good to name anything that doesn't correspond to one
> >> of the existing semantics for the API (!) something different rather
> >> than adding yet another potentially overloaded meaning.
> >
> > It seems we're (at least) three who agree about this. Here is a patch
> > fixing the name.
>
> I can't say I genrally agree with this patch...

Yes, I didn't count you to the three people signaling agreement.

> [...]
> > diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> > index 7c96f169d274..6d495f15f717 100644
> > --- a/include/linux/platform_device.h
> > +++ b/include/linux/platform_device.h
> > @@ -69,7 +69,14 @@ extern void __iomem *
> > devm_platform_ioremap_resource_byname(struct platform_device *pdev,
> > const char *name);
> > extern int platform_get_irq(struct platform_device *, unsigned int);
> > -extern int platform_get_irq_optional(struct platform_device *, unsigned int);
> > +extern int platform_get_irq_silent(struct platform_device *, unsigned int);
> > +
> > +/*
> > + * platform_get_irq_optional was recently renamed to platform_get_irq_silent.
> > + * Fixup users to not break patches that were created before the rename.
> > + */
> > +#define platform_get_irq_optional(pdev, index) platform_get_irq_silent(pdev, index)
> > +
>
> Yeah, why bother fixing if it compiles anyway?

The plan is to remove the define in one or two kernel releases. The idea
is only to not break patches that are currently in next.

> I think an inline wrapper with an indication to gcc that the function is deprecated
> (I just forgot how it should look) would be better instead...

The deprecated function annotation is generally frowned upon. See
771c035372a0.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (4.52 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-14 23:05:59

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Fri, Jan 14, 2022 at 10:14:10PM +0300, Sergey Shtylyov wrote:
> On 1/14/22 12:25 PM, Uwe Kleine-K?nig wrote:
>
> >>>>> To me it sounds much more logical for the driver to check if an
> >>>>> optional irq is non-zero (available) or zero (not available), than to
> >>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
> >>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> >>>>> (or some other error code) to indicate absence. I thought not having
> >>>>> to care about the actual error code was the main reason behind the
> >>>>> introduction of the *_optional() APIs.
> >>>
> >>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> >>>> that you can handle an absent GPIO (or clk) as if it were available.
> >>
> >> Hm, I've just looked at these and must note that they match 1:1 with
> >> platform_get_irq_optional(). Unfortunately, we can't however behave the
> >> same way in request_irq() -- because it has to support IRQ0 for the sake
> >> of i8253 drivers in arch/...
> >
> > Let me reformulate your statement to the IMHO equivalent:
> >
> > If you set aside the differences between
> > platform_get_irq_optional() and gpiod_get_optional(),
>
> Sorry, I should make it clear this is actually the diff between a would-be
> platform_get_irq_optional() after my patch, not the current code...

The similarity is that with your patch both gpiod_get_optional() and
platform_get_irq_optional() return NULL and 0 on not-found. The relevant
difference however is that for a gpiod NULL is a dummy value, while for
irqs it's not. So the similarity is only syntactically, but not
semantically.

> > platform_get_irq_optional() is like gpiod_get_optional().
> >
> > The introduction of gpiod_get_optional() made it possible to simplify
> > the following code:
> >
> > reset_gpio = gpiod_get(...)
> > if IS_ERR(reset_gpio):
> > error = PTR_ERR(reset_gpio)
> > if error != -ENDEV:
>
> ENODEV?

Yes, typo.

> > return error
> > else:
> > gpiod_set_direction(reset_gpiod, INACTIVE)
> >
> > to
> >
> > reset_gpio = gpiod_get_optional(....)
> > if IS_ERR(reset_gpio):
> > return reset_gpio
> > gpiod_set_direction(reset_gpiod, INACTIVE)
> >
> > and I never need to actually know if the reset_gpio actually exists.
> > Either the line is put into its inactive state, or it doesn't exist and
> > then gpiod_set_direction is a noop. For a regulator or a clk this works
> > in a similar way.
> >
> > However for an interupt this cannot work. You will always have to check
> > if the irq is actually there or not because if it's not you cannot just
> > ignore that. So there is no benefit of an optional irq.
> >
> > Leaving error message reporting aside, the introduction of
> > platform_get_irq_optional() allows to change
> >
> > irq = platform_get_irq(...);
> > if (irq < 0 && irq != -ENXIO) {
> > return irq;
> > } else if (irq >= 0) {
>
> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).

This is a topic I don't feel strong for, so I'm sloppy here. If changing
this is all that is needed to convince you of my point ...

> > ... setup irq operation ...
> > } else { /* irq == -ENXIO */
> > ... setup polling ...
> > }
> >
> > to
> >
> > irq = platform_get_irq_optional(...);
> > if (irq < 0 && irq != -ENXIO) {
> > return irq;
> > } else if (irq >= 0) {
> > ... setup irq operation ...
> > } else { /* irq == -ENXIO */
> > ... setup polling ...
> > }
> >
> > which isn't a win. When changing the return value as you suggest, it can
> > be changed instead to:
> >
> > irq = platform_get_irq_optional(...);
> > if (irq < 0) {
> > return irq;
> > } else if (irq > 0) {
> > ... setup irq operation ...
> > } else { /* irq == 0 */
> > ... setup polling ...
> > }
> >
> > which is a tad nicer. If that is your goal however I ask you to also
> > change the semantic of platform_get_irq() to return 0 on "not found".
>
> Well, I'm not totally opposed to that... but would there be a considerable win?

Well, compared to your suggestion of making platform_get_irq_optional()
return 0 on "not-found" the considerable win would be that
platform_get_irq_optional() and platform_get_irq() are not different
just because platform_get_irq() is to hard to change.

> Anyway, we should 1st stop returning 0 for "valid" IRQs -- this is done by my patch
> the discussed patch series are atop of.
>
> > Note the win is considerably less compared to gpiod_get_optional vs
>
> If there's any at all... We'd basically have to touch /all/ platform_get_irq()
> calls (and get an even larger CC list ;-)).

You got me wrong here. I meant that even if you change both
platform_get_irq() and platform_get_irq_optional() to return 0 on
"not-found", the win is small compared to the benefit of having both
clk_get() and clk_get_optional().

> > gpiod_get however. And then it still lacks the semantic of a dummy irq
> > which IMHO forfeits the right to call it ..._optional().
>
> Not quite grasping it... Why e.g. clk_get() doesn't return 0 for a not found clock?

Because NULL is not an error value for clk and when calling clk_get()
you want a failure when the clk you asked for isn't available.

Sure you could do the following in a case where you want to insist the
clk to be actually available:

clk = clk_get_optional(...)
if (IS_ERR_OR_NULL(clk)) {
err = PTR_ERR(clk) || -ENODEV;
return dev_err_probe(dev, err, ....);
}

but this is more ugly than

clk = clk_get(...)
if (IS_ERR(clk)) {
err = PTR_ERR(clk);
return dev_err_probe(dev, err, ....);
}

Additionally the first usage would hard-code in the drivers that NULL is
the dummy value which you might want to consider a layer violation.

You have to understand that for clk (and regulator and gpiod) NULL is a
valid descriptor that can actually be used, it just has no effect. So
this is a convenience value for the case "If the clk/regulator/gpiod in
question isn't available, there is nothing to do". This is what makes
clk_get_optional() and the others really useful and justifies their
existence. This doesn't apply to platform_get_irq_optional().

So clk_get() is sane and sensible for cases where you need the clk to be
there. It doesn't emit an error message, because the caller knows better
if it's worth an error message and in some cases the caller can also
emit a better error message than clk_get() itself.

clk_get_optional() is sane and sensible for cases where the clk might be
absent and it helps you because you don't have to differentiate between
"not found" and "there is an actual resource".

The reason for platform_get_irq_optional()'s existence is just that
platform_get_irq() emits an error message which is wrong or suboptimal
in some cases (and IMHO is platform_get_irq() root fault). It doesn't
simplify handling the "not found" case. So let's not pretend by the
choice of function names that there is a similarity between clk_get() +
clk_get_optional() and platform_get_irq() + platform_get_irq_optional().

And as you cannot change platform_get_irq_optional() to return a working
dummy value, IMHO the only sane way out is renaming it.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (7.39 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-16 06:45:55

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/14/22 11:29 PM, Uwe Kleine-K?nig wrote:

>>> The subsystems regulator, clk and gpio have the concept of a dummy
>>> resource. For regulator, clk and gpio there is a semantic difference
>>> between the regular _get() function and the _get_optional() variant.
>>> (One might return the dummy resource, the other won't. Unfortunately
>>> which one implements which isn't the same for these three.) The
>>> difference between platform_get_irq() and platform_get_irq_optional() is
>>> only that the former might emit an error message and the later won't.
>>>
>>> To prevent people's expectations that there is a semantic difference
>>> between these too, rename platform_get_irq_optional() to
>>> platform_get_irq_silent() to make the actual difference more obvious.
>>>
>>> The #define for the old name can and should be removed once all patches
>>> currently in flux still relying on platform_get_irq_optional() are
>>> fixed.
>>
>> Hm... I'm afraid that with this #define they would never get fixed... :-)
>
> I will care for it.

Ah! OK then. :-)

>>> Signed-off-by: Uwe Kleine-K?nig <[email protected]>
>>> ---
>>> Hello,
>>>
>>> On Thu, Jan 13, 2022 at 02:45:30PM +0000, Mark Brown wrote:
>>>> On Thu, Jan 13, 2022 at 12:08:31PM +0100, Uwe Kleine-K?nig wrote:
>>>>
>>>>> This is all very unfortunate. In my eyes b) is the most sensible
>>>>> sense, but the past showed that we don't agree here. (The most annoying
>>>>> part of regulator_get is the warning that is emitted that regularily
>>>>> makes customers ask what happens here and if this is fixable.)
>>>>
>>>> Fortunately it can be fixed, and it's safer to clearly specify things.
>>>> The prints are there because when the description is wrong enough to
>>>> cause things to blow up we can fail to boot or run messily and
>>>> forgetting to describe some supplies (or typoing so they haven't done
>>>> that) and people were having a hard time figuring out what might've
>>>> happened.
>>>
>>> Yes, that's right. I sent a patch for such a warning in 2019 and pinged
>>> occationally. Still waiting for it to be merged :-\
>>> (https://lore.kernel.org/r/[email protected])
>>>
>>>>> I think at least c) is easy to resolve because
>>>>> platform_get_irq_optional() isn't that old yet and mechanically
>>>>> replacing it by platform_get_irq_silent() should be easy and safe.
>>>>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
>>>>> value and if it's as easy as it could be to work with errors on irq
>>>>> lookups.
>>>>
>>>> It'd certainly be good to name anything that doesn't correspond to one
>>>> of the existing semantics for the API (!) something different rather
>>>> than adding yet another potentially overloaded meaning.
>>>
>>> It seems we're (at least) three who agree about this. Here is a patch
>>> fixing the name.
>>
>> I can't say I genrally agree with this patch...
>
> Yes, I didn't count you to the three people signaling agreement.

:-D

>> [...]
>>> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
>>> index 7c96f169d274..6d495f15f717 100644
>>> --- a/include/linux/platform_device.h
>>> +++ b/include/linux/platform_device.h
>>> @@ -69,7 +69,14 @@ extern void __iomem *
>>> devm_platform_ioremap_resource_byname(struct platform_device *pdev,
>>> const char *name);
>>> extern int platform_get_irq(struct platform_device *, unsigned int);
>>> -extern int platform_get_irq_optional(struct platform_device *, unsigned int);
>>> +extern int platform_get_irq_silent(struct platform_device *, unsigned int);
>>> +
>>> +/*
>>> + * platform_get_irq_optional was recently renamed to platform_get_irq_silent.
>>> + * Fixup users to not break patches that were created before the rename.
>>> + */
>>> +#define platform_get_irq_optional(pdev, index) platform_get_irq_silent(pdev, index)
>>> +
>>
>> Yeah, why bother fixing if it compiles anyway?
>
> The plan is to remove the define in one or two kernel releases. The idea
> is only to not break patches that are currently in next.
>
>> I think an inline wrapper with an indication to gcc that the function is deprecated
>> (I just forgot how it should look) would be better instead...
>
> The deprecated function annotation is generally frowned upon. See
> 771c035372a0.

Not sure I share the sentiment but good to know about that.

> Best regards
> Uwe

MBR, Sergey

2022-01-16 06:46:12

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Fri, Jan 14, 2022 at 08:55:07PM +0300, Sergey Shtylyov wrote:
> On 1/14/22 12:42 AM, Florian Fainelli wrote:
>
> >> The subsystems regulator, clk and gpio have the concept of a dummy
> >> resource. For regulator, clk and gpio there is a semantic difference
> >> between the regular _get() function and the _get_optional() variant.
> >> (One might return the dummy resource, the other won't. Unfortunately
> >> which one implements which isn't the same for these three.) The
> >> difference between platform_get_irq() and platform_get_irq_optional() is
> >> only that the former might emit an error message and the later won't.
> >>
> >> To prevent people's expectations that there is a semantic difference
> >> between these too, rename platform_get_irq_optional() to
> >> platform_get_irq_silent() to make the actual difference more obvious.
> >>
> >> The #define for the old name can and should be removed once all patches
> >> currently in flux still relying on platform_get_irq_optional() are
> >> fixed.
> >>
> >> Signed-off-by: Uwe Kleine-K?nig <[email protected]>
> [...]
> >>>> I think at least c) is easy to resolve because
> >>>> platform_get_irq_optional() isn't that old yet and mechanically
> >>>> replacing it by platform_get_irq_silent() should be easy and safe.
> >>>> And this is orthogonal to the discussion if -ENOXIO is a sensible return
> >>>> value and if it's as easy as it could be to work with errors on irq
> >>>> lookups.
> >>>
> >>> It'd certainly be good to name anything that doesn't correspond to one
> >>> of the existing semantics for the API (!) something different rather
> >>> than adding yet another potentially overloaded meaning.
> >>
> >> It seems we're (at least) three who agree about this. Here is a patch
> >> fixing the name.
> >
> > From an API naming perspective this does not make much sense anymore with the name chosen,
> > it is understood that whent he function is called platform_get_irq_optional(), optional applies
> > to the IRQ. An optional IRQ is something people can reason about because it makes sense.
>
> Right! :-)
>
> > What is a a "silent" IRQ however? It does not apply to the object it is trying to fetch to
> > anymore, but to the message that may not be printed in case the resource failed to be obtained,
> > because said resource is optional. Woah, that's quite a stretch.
>
> Right again! :-)

So you oppose to the name chosen, but not the renaming as such. I
already asked Florian if he has a better name, do you have a
constructive suggestion? What about platform_silently_get_irq? Or
platform_get_irq_silently?

Do you agree that it's unfortunate that platform_get_irq_optional() has a
different usage convention than clk_get_optional() and
gpiod_get_optional()?

Do you agree that the difference between platform_get_irq_optional() and
platform_get_irq() is only that one of them issues an error message and
the other doesn't?

Currently the return values of platform_get_irq_optional() and
platform_get_irq() are identical. Do you agree that any change to clean
up the return value convention of platform_get_irq_optional() also
would be sensible for platform_get_irq()?

Do you agree that changing the way how return values of
platform_get_irq_optional() have to be evaluated without adapting
platform_get_irq() in the same way, artifially breaks the releation
between these two functions?

> > Following the discussion and original 2 patches set from Sergey, it is not entirely clear to me
> > anymore what is it that we are trying to fix.
>
> Andy and me tried to fix the platform_get_irq[_byname]_optional() value, corresponding to
> a missing (optional) IRQ resource from -ENXIO to 0, in order to keep the callers error code
> agnostic. This change completely aligns e.g. platform_get_irq_optional() with clk_get_optional()
> and gpiod_get_optional()...

Did you read and understand my objection? Yes, in the not found case the
return value is a 32-bit or 64-bit long zero value (0 or NULL) for these
functions. But for irqs you cannot treat that as an irq number. For clks
this works, and this is the fact that justifies the "optional" in the
name and that simplifies further handling without having to check if the
value returned by clk_get_optional corresponds to the dummy clk or a
real one. Just returning 0 for not-found doesn't justify "optional" in
the name. Or do you think kmalloc should better be called
kmalloc_optional because it returns NULL if there is no more memory
available?

The only thing you accomplish with returning 0 instead of -ENXIO is that
the check for this value in the callers has to be adapted. But as you
cannot handle 0 and a "normal" irq in the same way (i.e. pass it to
request_irq)

In my eyes error code agnostic isn't a sensible goal. If you ask for a
resource and it's not there and your driver can cope and this cannot be
done by just treating the returned value as a valid resource, making it
explicit that the error code for "not found" is handled is a good thing.
In my opinion it's not a good enough reason to change a function's
return conventions just that I can handle one of the various results
using

if (ret == 0)

instead of

if (ret == -ENXIO)

Also there is no justification to change the value for "not found" to
zero. The next developer might be annoyed by having to check for
-EPROBE_DEFER and wants to introduce a special function that behaves
like platform_get_irq, just returns 0 when platform_get_irq returns
-ENOENT.

> Unforunately, we can't "fix" request_irq() and company to treat 0 as missing IRQ -- they have
> to keep the ability to get called from the arch/ code (that doesn't use platform_get_irq(), etc.

Note that even if request_irq would be a noop for 0, the biggest part of
the drivers wouldn't be done with request_irq(0, ...) because in the
absense of an irq something has to be done about it.

Oh my, I failed to not continue this discussion really badly. But I
really cannot stand people arguing for wrong things and ignoring my
reasoning completely. In case you feel the same way: I agree that -ENXIO
is the wrong value for not-found. But to change this wrong behaviour to
another wrong behaviour isn't an improvement.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (6.37 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-16 06:46:28

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Fri, Jan 14, 2022 at 10:58:51AM +0100, Geert Uytterhoeven wrote:
> Hi Uwe,
>
> On Thu, Jan 13, 2022 at 11:43 PM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Thu, Jan 13, 2022 at 11:57:43PM +0300, Sergey Shtylyov wrote:
> > > On 1/13/22 11:17 PM, Mark Brown wrote:
> > > >> The subsystems regulator, clk and gpio have the concept of a dummy
> > > >> resource. For regulator, clk and gpio there is a semantic difference
> > > >> between the regular _get() function and the _get_optional() variant.
> > > >> (One might return the dummy resource, the other won't. Unfortunately
> > > >> which one implements which isn't the same for these three.) The
> > > >> difference between platform_get_irq() and platform_get_irq_optional() is
> > > >> only that the former might emit an error message and the later won't.
> > >
> > > This is only a current difference but I'm still going to return 0 ISO
> > > -ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there
> > > alone... :-)
> >
> > This would address a bit of the critic in my commit log. But as 0 isn't
> > a dummy value like the dummy values that exist for clk, gpiod and
> > regulator I still think that the naming is a bad idea because it's not
> > in the spirit of the other *_get_optional functions.
> >
> > Seeing you say that -ENXIO is a bad return value for
> > platform_get_irq_optional() and 0 should be used instead, I wonder why
> > not changing platform_get_irq() to return 0 instead of -ENXIO, too.
> > This question is for now only about a sensible semantic. That actually
> > changing platform_get_irq() is probably harder than changing
> > platform_get_irq_optional() is a different story.
> >
> > If only platform_get_irq_optional() is changed and given that the
> > callers have to do something like:
> >
> > if (this_irq_exists()):
> > ... (e.g. request_irq)
> > else:
> > ... (e.g. setup polling)
> >
> > I really think it's a bad idea that this_irq_exists() has to be
> > different for platform_get_irq() vs. platform_get_irq_optional().
>
> For platform_get_irq(), the IRQ being absent is an error condition,
> hence it should return an error code.
> For platform_get_irq_optional(), the IRQ being absent is not an error
> condition, hence it should not return an error code, and 0 is OK.

Please show a few examples how this simplifies the code. If it's only
that a driver has to check for == 0 instead of == -ENXIO, than that's
not a good enough motivation to make platform_get_irq_optional()
different to platform_get_irq().

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.76 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-16 06:46:37

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Fri, Jan 14, 2022 at 03:04:38PM +0200, Andy Shevchenko wrote:
> On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> > > It'd certainly be good to name anything that doesn't correspond to one
> > > of the existing semantics for the API (!) something different rather
> > > than adding yet another potentially overloaded meaning.
> >
> > It seems we're (at least) three who agree about this. Here is a patch
> > fixing the name.
>
> And similar number of people are on the other side.

If someone already opposed to the renaming (and not only the name) I
must have missed that.

So you think it's a good idea to keep the name
platform_get_irq_optional() despite the "not found" value returned by it
isn't usable as if it were a normal irq number?

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (963.00 B)
signature.asc (499.00 B)
Download all attachments

2022-01-16 16:22:22

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

Hello,

I'm trying to objectively summarize the discussions in this thread in
the hope this helps finding a way that most people can live with.

First a description of the status quo:

There are several function pairs *get() and *get_optional() that however
are different in various aspects. Their relevant properties are listes
in the following table. Ideally each line had only identical entries.

| clk_get | gpiod_get | platform_get_irq | regulator_get |
return value | | | | |
on not-found | ERR_PTR(-ENOENT) | ERR_PTR(-ENOENT) | -ENXIO | dummy[1] |
(plain get) | | | | |
| | | | |
return value | | | | |
on not-found | dummy[1] | dummy[1] | -ENXIO | ERR_PTR(-ENOENT) |
(get_optional) | | | | |
| | | | |
emits an error message | | | | |
on error (including | no | no | yes[2] | no |
not-found) | | | | |
| | | | |
get_optional emits an error | | | | |
message on error (including | no | no | no | no |
not-found) | | | | |
| | | | |
summary: | returning a dummy | returning a dummy | doesn't emit an | returning error code |
*_get_optional() differs from | on not-found | on not-found | error message | on not-found |
*_get by: | | | | |


[1] the dummy value is a valid resource descriptor, the API functions
are a noop for this dummy value. This dummy value is NULL for
all three subsystems.
[2] no error is printed for -EPROBE_DEFER.

The inversion between clk+gpio vs. regulator is unforunate, swaping one
or the other would be good for consistency, but this isn't the topic of
this thread. Only so much: It's not agreed upon which variant is the
better one and the difference is of historical origin.

There are now different suggestions to improve the situation regarding
platform_get_irq() compared to the other functions:

a) by Sergey
platform_get_irq_optional() is changed to return 0 on not-found.

b) by Uwe
rename platform_get_irq_optional() to platform_get_irq_silent()

The argument pro a) is:

platform_get_irq_optional() is aligned to clk_get() and
gpiod_get() by returning 0 on not-found.

The argument contra a)

The return value 0 for platform_get_irq() is only syntactically
nearer to the dummy value of clk_get() and gpiod_get(). A dummy
value isn't available and probably not sensible to introduce for
irq because most drivers have to check for the not-found
situation anyhow to setup polling.

The argument pro b) is:

The relevant difference between platform_get_irq() and its
optional variant is that the latter is silent. This is a
different concept for the meaning of optional compared to the
other *_get_optional().

The argument contra b) is:

The chosen name is bad, because driver authors might wonder what
a silent irq is.

---- end of summary

A possible compromise: We can have both. We rename
platform_get_irq_optional() to platform_get_irq_silent() (or
platform_get_irq_silently() if this is preferred) and once all users are
are changed (which can be done mechanically), we reintroduce a
platform_get_irq_optional() with Sergey's suggested semantic (i.e.
return 0 on not-found, no error message printking).

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (3.46 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-16 16:22:58

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:
> On Fri, Jan 14, 2022 at 10:14:10PM +0300, Sergey Shtylyov wrote:
>> On 1/14/22 12:25 PM, Uwe Kleine-K?nig wrote:
>>
>>>>>>> To me it sounds much more logical for the driver to check if an
>>>>>>> optional irq is non-zero (available) or zero (not available), than to
>>>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>>>>> (or some other error code) to indicate absence. I thought not having
>>>>>>> to care about the actual error code was the main reason behind the
>>>>>>> introduction of the *_optional() APIs.
>>>>>
>>>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
>>>>>> that you can handle an absent GPIO (or clk) as if it were available.
>>>>
>>>> Hm, I've just looked at these and must note that they match 1:1 with
>>>> platform_get_irq_optional(). Unfortunately, we can't however behave the
>>>> same way in request_irq() -- because it has to support IRQ0 for the sake
>>>> of i8253 drivers in arch/...
>>>
>>> Let me reformulate your statement to the IMHO equivalent:
>>>
>>> If you set aside the differences between
>>> platform_get_irq_optional() and gpiod_get_optional(),
>>
>> Sorry, I should make it clear this is actually the diff between a would-be
>> platform_get_irq_optional() after my patch, not the current code...
>
> The similarity is that with your patch both gpiod_get_optional() and
> platform_get_irq_optional() return NULL and 0 on not-found. The relevant
> difference however is that for a gpiod NULL is a dummy value, while for
> irqs it's not. So the similarity is only syntactically, but not
> semantically.
>
>>> platform_get_irq_optional() is like gpiod_get_optional().
>>>
>>> The introduction of gpiod_get_optional() made it possible to simplify
>>> the following code:
>>>
>>> reset_gpio = gpiod_get(...)
>>> if IS_ERR(reset_gpio):
>>> error = PTR_ERR(reset_gpio)
>>> if error != -ENDEV:
>>
>> ENODEV?
>
> Yes, typo.
>
>>> return error
>>> else:
>>> gpiod_set_direction(reset_gpiod, INACTIVE)
>>>
>>> to
>>>
>>> reset_gpio = gpiod_get_optional(....)
>>> if IS_ERR(reset_gpio):
>>> return reset_gpio
>>> gpiod_set_direction(reset_gpiod, INACTIVE)
>>>
>>> and I never need to actually know if the reset_gpio actually exists.
>>> Either the line is put into its inactive state, or it doesn't exist and
>>> then gpiod_set_direction is a noop. For a regulator or a clk this works
>>> in a similar way.
>>>
>>> However for an interupt this cannot work. You will always have to check
>>> if the irq is actually there or not because if it's not you cannot just
>>> ignore that. So there is no benefit of an optional irq.
>>>
>>> Leaving error message reporting aside, the introduction of
>>> platform_get_irq_optional() allows to change
>>>
>>> irq = platform_get_irq(...);
>>> if (irq < 0 && irq != -ENXIO) {
>>> return irq;
>>> } else if (irq >= 0) {
>>
>> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
>
> This is a topic I don't feel strong for, so I'm sloppy here. If changing
> this is all that is needed to convince you of my point ...

See below. :-)

>>> ... setup irq operation ...
>>> } else { /* irq == -ENXIO */
>>> ... setup polling ...
>>> }
>>>
>>> to
>>>
>>> irq = platform_get_irq_optional(...);
>>> if (irq < 0 && irq != -ENXIO) {
>>> return irq;
>>> } else if (irq >= 0) {
>>> ... setup irq operation ...
>>> } else { /* irq == -ENXIO */
>>> ... setup polling ...
>>> }
>>>
>>> which isn't a win. When changing the return value as you suggest, it can
>>> be changed instead to:
>>>
>>> irq = platform_get_irq_optional(...);
>>> if (irq < 0) {
>>> return irq;
>>> } else if (irq > 0) {
>>> ... setup irq operation ...
>>> } else { /* irq == 0 */
>>> ... setup polling ...
>>> }
>>>
>>> which is a tad nicer. If that is your goal however I ask you to also
>>> change the semantic of platform_get_irq() to return 0 on "not found".
>>
>> Well, I'm not totally opposed to that... but would there be a considerable win?

> Well, compared to your suggestion of making platform_get_irq_optional()
> return 0 on "not-found" the considerable win would be that
> platform_get_irq_optional() and platform_get_irq() are not different

They would really be the same function if we do that. But...

> just because platform_get_irq() is to hard to change.

It's not just that, of course. If you make platform_get_irq() return 0
ISO -ENXIO, you'd have to add the handling of that 0 to all the callers,
and that won't be as simple as:

if (irq < 0)
return irq;

since we can't just propagate 0 upstream, we'd have to return something like
-ENXIO (or whatever error we see fit). Does that really scale well?

>> Anyway, we should 1st stop returning 0 for "valid" IRQs -- this is done by my patch
>> the discussed patch series are atop of.
>>
>>> Note the win is considerably less compared to gpiod_get_optional vs
>>
>> If there's any at all... We'd basically have to touch /all/ platform_get_irq()
>> calls (and get an even larger CC list ;-)).
>
> You got me wrong here. I meant that even if you change both
> platform_get_irq() and platform_get_irq_optional() to return 0 on
> "not-found", the win is small compared to the benefit of having both

There's no win at all, it seems.

> clk_get() and clk_get_optional().
>
>>> gpiod_get however. And then it still lacks the semantic of a dummy irq
>>> which IMHO forfeits the right to call it ..._optional().
>>
>> Not quite grasping it... Why e.g. clk_get() doesn't return 0 for a not found clock?
>
> Because NULL is not an error value for clk and when calling clk_get()
> you want a failure when the clk you asked for isn't available.
>
> Sure you could do the following in a case where you want to insist the
> clk to be actually available:
>
> clk = clk_get_optional(...)
> if (IS_ERR_OR_NULL(clk)) {
> err = PTR_ERR(clk) || -ENODEV;
> return dev_err_probe(dev, err, ....);
> }
>
> but this is more ugly than
>
> clk = clk_get(...)
> if (IS_ERR(clk)) {
> err = PTR_ERR(clk);
> return dev_err_probe(dev, err, ....);
> }
>
> Additionally the first usage would hard-code in the drivers that NULL is
> the dummy value which you might want to consider a layer violation.

Unfortunately, we don't have a single layer in case of IRQs... There's
no platform_request_irq() (yet? :-)).

> You have to understand that for clk (and regulator and gpiod) NULL is a
> valid descriptor that can actually be used, it just has no effect. So
> this is a convenience value for the case "If the clk/regulator/gpiod in
> question isn't available, there is nothing to do". This is what makes
> clk_get_optional() and the others really useful and justifies their
> existence. This doesn't apply to platform_get_irq_optional().

I do understand that. However, IRQs are a different beast with their
own justifications...

> So clk_get() is sane and sensible for cases where you need the clk to be
> there. It doesn't emit an error message, because the caller knows better
> if it's worth an error message and in some cases the caller can also
> emit a better error message than clk_get() itself.

I haven't been thinking about the IRQ error messages at all (yet?)...
And when I start thinking about it, it doesn't seem that bad, perhaps
even saves a lot of the .rodata section... :-)

> clk_get_optional() is sane and sensible for cases where the clk might be
> absent and it helps you because you don't have to differentiate between
> "not found" and "there is an actual resource".
>
> The reason for platform_get_irq_optional()'s existence is just that
> platform_get_irq() emits an error message which is wrong or suboptimal

I think you are very wrong here. The real reason is to simplify the
callers.

> in some cases (and IMHO is platform_get_irq() root fault). It doesn't
> simplify handling the "not found" case.

Oh, it does... you don't have to special-case 0 when handling its result.
In my book, it's a major simplification.

> So let's not pretend by the
> choice of function names that there is a similarity between clk_get() +
> clk_get_optional() and platform_get_irq() + platform_get_irq_optional().

OK, no similarity. But that's well justified.

> And as you cannot change platform_get_irq_optional() to return a working
> dummy value, IMHO the only sane way out is renaming it.

Your rename really focused on the wrong aspect of the function, I think...

> Best regards
> Uwe

MBR, Sergey

2022-01-16 16:23:08

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/15/22 6:21 PM, Uwe Kleine-K?nig wrote:

[...]
>>>>>> The subsystems regulator, clk and gpio have the concept of a dummy
>>>>>> resource. For regulator, clk and gpio there is a semantic difference
>>>>>> between the regular _get() function and the _get_optional() variant.
>>>>>> (One might return the dummy resource, the other won't. Unfortunately
>>>>>> which one implements which isn't the same for these three.) The
>>>>>> difference between platform_get_irq() and platform_get_irq_optional() is
>>>>>> only that the former might emit an error message and the later won't.
>>>>
>>>> This is only a current difference but I'm still going to return 0 ISO
>>>> -ENXIO from latform_get_irq_optional(), no way I'd leave that -ENXIO there
>>>> alone... :-)
>>>
>>> This would address a bit of the critic in my commit log. But as 0 isn't
>>> a dummy value like the dummy values that exist for clk, gpiod and
>>> regulator I still think that the naming is a bad idea because it's not
>>> in the spirit of the other *_get_optional functions.
>>>
>>> Seeing you say that -ENXIO is a bad return value for
>>> platform_get_irq_optional() and 0 should be used instead, I wonder why
>>> not changing platform_get_irq() to return 0 instead of -ENXIO, too.
>>> This question is for now only about a sensible semantic. That actually
>>> changing platform_get_irq() is probably harder than changing
>>> platform_get_irq_optional() is a different story.
>>>
>>> If only platform_get_irq_optional() is changed and given that the
>>> callers have to do something like:
>>>
>>> if (this_irq_exists()):
>>> ... (e.g. request_irq)
>>> else:
>>> ... (e.g. setup polling)
>>>
>>> I really think it's a bad idea that this_irq_exists() has to be
>>> different for platform_get_irq() vs. platform_get_irq_optional().
>>
>> For platform_get_irq(), the IRQ being absent is an error condition,
>> hence it should return an error code.
>> For platform_get_irq_optional(), the IRQ being absent is not an error
>> condition, hence it should not return an error code, and 0 is OK.
>
> Please show a few examples how this simplifies the code. If it's only

As for platform_get_irq(), returning -ENXIO simplifies things a lot: you don't
have to check for 0 at every freaking call site and have s/th like (every
time!):

irq = platform_get_irq();
if (irq <= 0)
return irq ?: -ENXIO; // any error code you choose

instead of just:

irq = platform_get_irq();
if (irq < 0)
return irq;

This scales better in my book.

> that a driver has to check for == 0 instead of == -ENXIO, than that's
> not a good enough motivation to make platform_get_irq_optional()
> different to platform_get_irq().

Again, it scales better... good motivation in my eyes.

> Best regards
> Uwe

MBR, Sergey

2022-01-17 08:01:59

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
> A possible compromise: We can have both. We rename
> platform_get_irq_optional() to platform_get_irq_silent() (or
> platform_get_irq_silently() if this is preferred) and once all users are
> are changed (which can be done mechanically), we reintroduce a
> platform_get_irq_optional() with Sergey's suggested semantic (i.e.
> return 0 on not-found, no error message printking).

Please do not do that as anyone trying to forward-port an old driver
will miss the abi change of functionality and get confused. Make
build-breaking changes, if the way a function currently works is
changed in order to give people a chance.

thanks,

greg k-h

2022-01-17 09:40:55

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello!

On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:

>>>>>>> To me it sounds much more logical for the driver to check if an
>>>>>>> optional irq is non-zero (available) or zero (not available), than to
>>>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>>>>> (or some other error code) to indicate absence. I thought not having
>>>>>>> to care about the actual error code was the main reason behind the
>>>>>>> introduction of the *_optional() APIs.
>>>>>
>>>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
>>>>>> that you can handle an absent GPIO (or clk) as if it were available.
>>>>
>>>> Hm, I've just looked at these and must note that they match 1:1 with
>>>> platform_get_irq_optional(). Unfortunately, we can't however behave the
>>>> same way in request_irq() -- because it has to support IRQ0 for the sake
>>>> of i8253 drivers in arch/...
>>>
>>> Let me reformulate your statement to the IMHO equivalent:
>>>
>>> If you set aside the differences between
>>> platform_get_irq_optional() and gpiod_get_optional(),
>>
>> Sorry, I should make it clear this is actually the diff between a would-be
>> platform_get_irq_optional() after my patch, not the current code...
>
> The similarity is that with your patch both gpiod_get_optional() and
> platform_get_irq_optional() return NULL and 0 on not-found. The relevant
> difference however is that for a gpiod NULL is a dummy value, while for
> irqs it's not. So the similarity is only syntactically, but not
> semantically.

I have noting to say here, rather than optional IRQ could well have a different
meaning than for clk/gpio/etc.

[...]
>>> However for an interupt this cannot work. You will always have to check
>>> if the irq is actually there or not because if it's not you cannot just
>>> ignore that. So there is no benefit of an optional irq.
>>>
>>> Leaving error message reporting aside, the introduction of
>>> platform_get_irq_optional() allows to change
>>>
>>> irq = platform_get_irq(...);
>>> if (irq < 0 && irq != -ENXIO) {
>>> return irq;
>>> } else if (irq >= 0) {
>>
>> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
>
> This is a topic I don't feel strong for, so I'm sloppy here. If changing
> this is all that is needed to convince you of my point ...

Note that we should absolutely (and first of all) stop returning 0 from platform_get_irq()
on a "real" IRQ0. Handling that "still good" zero absolutely doesn't scale e.g. for the subsystems
(like libata) which take 0 as an indication that the polling mode should be used... We can't afford
to be sloppy here. ;-)

[...]

> Best regards
> Uwe

MBR, Sergey

2022-01-17 17:01:55

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> On 1/14/22 11:22 PM, Uwe Kleine-König wrote:
> > You have to understand that for clk (and regulator and gpiod) NULL is a
> > valid descriptor that can actually be used, it just has no effect. So
> > this is a convenience value for the case "If the clk/regulator/gpiod in
> > question isn't available, there is nothing to do". This is what makes
> > clk_get_optional() and the others really useful and justifies their
> > existence. This doesn't apply to platform_get_irq_optional().
>
> I do understand that. However, IRQs are a different beast with their
> own justifications...

> > clk_get_optional() is sane and sensible for cases where the clk might be
> > absent and it helps you because you don't have to differentiate between
> > "not found" and "there is an actual resource".
> >
> > The reason for platform_get_irq_optional()'s existence is just that
> > platform_get_irq() emits an error message which is wrong or suboptimal
>
> I think you are very wrong here. The real reason is to simplify the
> callers.

Indeed.

Even for clocks, you cannot assume that you can always blindly use
the returned dummy (actually a NULL pointer) to call into the clk
API. While this works fine for simple use cases, where you just
want to enable/disable an optional clock (clk_prepare_enable() and
clk_disable_unprepare()), it does not work for more complex use cases.

Consider a device with multiple clock inputs, some of them optional,
where the device driver has to find, select and configure a suitable
clock to operate at a certain clock frequency. The driver can call
clk_get_rate(NULL) fine, but will always receive a zero rate, so it
has to check for this (regardless of this being a dummy clock or not,
because this could be an unpopulated clock crystal, which would be
described in DT as a (present) fixed-rate clock with clock-frequency
= <0>).
For configuring the clock rate, the driver does need to check
explicitly for the presence of a dummy clock, as clk_set_rate(NULL,
rate) returns 0 ("success"), while obviously it didn't do anything,
and thus configuring the device to use that clock would cause breakage.

You can check if the clock is a real clock or a dummy using
"if (clk) ...".
And you'd use the same pattern with platform_irq_get_optional() if it
would return 0 if the IRQ was not found: "if (irq) ...".

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-17 17:02:41

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello,

On Sun, Jan 16, 2022 at 09:15:20PM +0300, Sergey Shtylyov wrote:
> On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:
>
> >>>>>>> To me it sounds much more logical for the driver to check if an
> >>>>>>> optional irq is non-zero (available) or zero (not available), than to
> >>>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
> >>>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> >>>>>>> (or some other error code) to indicate absence. I thought not having
> >>>>>>> to care about the actual error code was the main reason behind the
> >>>>>>> introduction of the *_optional() APIs.
> >>>>>
> >>>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> >>>>>> that you can handle an absent GPIO (or clk) as if it were available.
> >>>>
> >>>> Hm, I've just looked at these and must note that they match 1:1 with
> >>>> platform_get_irq_optional(). Unfortunately, we can't however behave the
> >>>> same way in request_irq() -- because it has to support IRQ0 for the sake
> >>>> of i8253 drivers in arch/...
> >>>
> >>> Let me reformulate your statement to the IMHO equivalent:
> >>>
> >>> If you set aside the differences between
> >>> platform_get_irq_optional() and gpiod_get_optional(),
> >>
> >> Sorry, I should make it clear this is actually the diff between a would-be
> >> platform_get_irq_optional() after my patch, not the current code...
> >
> > The similarity is that with your patch both gpiod_get_optional() and
> > platform_get_irq_optional() return NULL and 0 on not-found. The relevant
> > difference however is that for a gpiod NULL is a dummy value, while for
> > irqs it's not. So the similarity is only syntactically, but not
> > semantically.
>
> I have noting to say here, rather than optional IRQ could well have a different
> meaning than for clk/gpio/etc.
>
> [...]
> >>> However for an interupt this cannot work. You will always have to check
> >>> if the irq is actually there or not because if it's not you cannot just
> >>> ignore that. So there is no benefit of an optional irq.
> >>>
> >>> Leaving error message reporting aside, the introduction of
> >>> platform_get_irq_optional() allows to change
> >>>
> >>> irq = platform_get_irq(...);
> >>> if (irq < 0 && irq != -ENXIO) {
> >>> return irq;
> >>> } else if (irq >= 0) {
> >>
> >> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
> >
> > This is a topic I don't feel strong for, so I'm sloppy here. If changing
> > this is all that is needed to convince you of my point ...
>
> Note that we should absolutely (and first of all) stop returning 0 from platform_get_irq()
> on a "real" IRQ0. Handling that "still good" zero absolutely doesn't scale e.g. for the subsystems
> (like libata) which take 0 as an indication that the polling mode should be used... We can't afford
> to be sloppy here. ;-)

Then maybe do that really first? I didn't recheck, but is this what the
driver changes in your patch is about?

After some more thoughts I wonder if your focus isn't to align
platform_get_irq_optional to (clk|gpiod|regulator)_get_optional, but to
simplify return code checking. Because with your change we have:

- < 0 -> error
- == 0 -> no irq
- > 0 -> irq

For my part I'd say this doesn't justify the change, but at least I
could better life with the reasoning. If you start at:

irq = platform_get_irq_optional(...)
if (irq < 0 && irq != -ENXIO)
return irq
else if (irq > 0)
setup_irq(irq);
else
setup_polling()

I'd change that to

irq = platform_get_irq_optional(...)
if (irq > 0) /* or >= 0 ? */
setup_irq(irq)
else if (irq == -ENXIO)
setup_polling()
else
return irq

This still has to mention -ENXIO, but this is ok and checking for 0 just
hardcodes a different return value.

Anyhow, I think if you still want to change platform_get_irq_optional
you should add a few patches converting some drivers which demonstrates
the improvement for the callers.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (4.18 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-17 17:04:08

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello Geert,

On Mon, Jan 17, 2022 at 09:41:42AM +0100, Geert Uytterhoeven wrote:
> On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> > On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:
> > > You have to understand that for clk (and regulator and gpiod) NULL is a
> > > valid descriptor that can actually be used, it just has no effect. So
> > > this is a convenience value for the case "If the clk/regulator/gpiod in
> > > question isn't available, there is nothing to do". This is what makes
> > > clk_get_optional() and the others really useful and justifies their
> > > existence. This doesn't apply to platform_get_irq_optional().
> >
> > I do understand that. However, IRQs are a different beast with their
> > own justifications...
>
> > > clk_get_optional() is sane and sensible for cases where the clk might be
> > > absent and it helps you because you don't have to differentiate between
> > > "not found" and "there is an actual resource".
> > >
> > > The reason for platform_get_irq_optional()'s existence is just that
> > > platform_get_irq() emits an error message which is wrong or suboptimal
> >
> > I think you are very wrong here. The real reason is to simplify the
> > callers.
>
> Indeed.

The commit that introduced platform_get_irq_optional() said:

Introduce a new platform_get_irq_optional() that works much like
platform_get_irq() but does not output an error on failure to
find the interrupt.

So the author of 8973ea47901c81a1912bd05f1577bed9b5b52506 failed to
mention the real reason? Or look at
31a8d8fa84c51d3ab00bf059158d5de6178cf890:

[...] use platform_get_irq_optional() to get second/third IRQ
which are optional to avoid below error message during probe:
[...]

Look through the output of

git log -Splatform_get_irq_optional

to find several more of these.

Also I fail to see how a caller of (today's) platform_get_irq_optional()
is simpler than a caller of platform_get_irq() given that there is no
semantic difference between the two. Please show me a single
conversion from platform_get_irq to platform_get_irq_optional that
yielded a simplification.

So you need some more effort to convince me of your POV.

> Even for clocks, you cannot assume that you can always blindly use
> the returned dummy (actually a NULL pointer) to call into the clk
> API. While this works fine for simple use cases, where you just
> want to enable/disable an optional clock (clk_prepare_enable() and
> clk_disable_unprepare()), it does not work for more complex use cases.

Agreed. But for clks and gpiods and regulators the simple case is quite
usual. For irqs it isn't.

And if you cannot blindly use the dummy, then you're not the targetted
caller of *_get_optional() and should better use *_get() and handle
-ENODEV explicitly.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.97 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-17 17:09:11

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Mon, Jan 17, 2022 at 10:24 AM Uwe Kleine-König
<[email protected]> wrote:
> On Mon, Jan 17, 2022 at 09:41:42AM +0100, Geert Uytterhoeven wrote:
> > On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> > > On 1/14/22 11:22 PM, Uwe Kleine-König wrote:
> > > > You have to understand that for clk (and regulator and gpiod) NULL is a
> > > > valid descriptor that can actually be used, it just has no effect. So
> > > > this is a convenience value for the case "If the clk/regulator/gpiod in
> > > > question isn't available, there is nothing to do". This is what makes
> > > > clk_get_optional() and the others really useful and justifies their
> > > > existence. This doesn't apply to platform_get_irq_optional().
> > >
> > > I do understand that. However, IRQs are a different beast with their
> > > own justifications...
> >
> > > > clk_get_optional() is sane and sensible for cases where the clk might be
> > > > absent and it helps you because you don't have to differentiate between
> > > > "not found" and "there is an actual resource".
> > > >
> > > > The reason for platform_get_irq_optional()'s existence is just that
> > > > platform_get_irq() emits an error message which is wrong or suboptimal
> > >
> > > I think you are very wrong here. The real reason is to simplify the
> > > callers.
> >
> > Indeed.
>
> The commit that introduced platform_get_irq_optional() said:
>
> Introduce a new platform_get_irq_optional() that works much like
> platform_get_irq() but does not output an error on failure to
> find the interrupt.
>
> So the author of 8973ea47901c81a1912bd05f1577bed9b5b52506 failed to
> mention the real reason? Or look at
> 31a8d8fa84c51d3ab00bf059158d5de6178cf890:
>
> [...] use platform_get_irq_optional() to get second/third IRQ
> which are optional to avoid below error message during probe:
> [...]
>
> Look through the output of
>
> git log -Splatform_get_irq_optional
>
> to find several more of these.

Commit 8973ea47901c81a1 ("driver core: platform: Introduce
platform_get_irq_optional()") and the various fixups fixed the ugly
printing of error messages that were not applicable.
In hindsight, probably commit 7723f4c5ecdb8d83 ("driver core:
platform: Add an error message to platform_get_irq*()") should have
been reverted instead, until a platform_get_irq_optional() with proper
semantics was introduced. But as we were all in a hurry to kill
the non-applicable error message, we went for the quick and dirty fix.

> Also I fail to see how a caller of (today's) platform_get_irq_optional()
> is simpler than a caller of platform_get_irq() given that there is no
> semantic difference between the two. Please show me a single
> conversion from platform_get_irq to platform_get_irq_optional that
> yielded a simplification.

That's exactly why we want to change the latter to return 0 ;-)

> So you need some more effort to convince me of your POV.
>
> > Even for clocks, you cannot assume that you can always blindly use
> > the returned dummy (actually a NULL pointer) to call into the clk
> > API. While this works fine for simple use cases, where you just
> > want to enable/disable an optional clock (clk_prepare_enable() and
> > clk_disable_unprepare()), it does not work for more complex use cases.
>
> Agreed. But for clks and gpiods and regulators the simple case is quite
> usual. For irqs it isn't.

It is for devices that can have either separate interrupts, or a single
multiplexed interrupt.

The logic in e.g. drivers/tty/serial/sh-sci.c and
drivers/spi/spi-rspi.c could be simplified and improved (currently
it doesn't handle deferred probe) if platform_get_irq_optional()
would return 0 instead of -ENXIO.

> And if you cannot blindly use the dummy, then you're not the targetted
> caller of *_get_optional() and should better use *_get() and handle
> -ENODEV explicitly.

No, because the janitors tend to consolidate error message handling,
by moving the printing up, inside the *_get() methods. That's exactly
what happened here.
So there are three reasons: because the absence of an optional IRQ
is not an error, and thus that should not cause (a) an error code
to be returned, and (b) an error message to be printed, and (c)
because it can simplify the logic in device drivers.

Commit 8973ea47901c81a1 ("driver core: platform: Introduce
platform_get_irq_optional()") fixed (b), but didn't address (a) and
(c).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-17 17:14:18

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 17, 2022 at 11:35:52AM +0100, Geert Uytterhoeven wrote:
> Hi Uwe,
>
> On Mon, Jan 17, 2022 at 10:24 AM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Mon, Jan 17, 2022 at 09:41:42AM +0100, Geert Uytterhoeven wrote:
> > > On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> > > > On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:
> > > > > You have to understand that for clk (and regulator and gpiod) NULL is a
> > > > > valid descriptor that can actually be used, it just has no effect. So
> > > > > this is a convenience value for the case "If the clk/regulator/gpiod in
> > > > > question isn't available, there is nothing to do". This is what makes
> > > > > clk_get_optional() and the others really useful and justifies their
> > > > > existence. This doesn't apply to platform_get_irq_optional().
> > > >
> > > > I do understand that. However, IRQs are a different beast with their
> > > > own justifications...
> > >
> > > > > clk_get_optional() is sane and sensible for cases where the clk might be
> > > > > absent and it helps you because you don't have to differentiate between
> > > > > "not found" and "there is an actual resource".
> > > > >
> > > > > The reason for platform_get_irq_optional()'s existence is just that
> > > > > platform_get_irq() emits an error message which is wrong or suboptimal
> > > >
> > > > I think you are very wrong here. The real reason is to simplify the
> > > > callers.
> > >
> > > Indeed.
> >
> > The commit that introduced platform_get_irq_optional() said:
> >
> > Introduce a new platform_get_irq_optional() that works much like
> > platform_get_irq() but does not output an error on failure to
> > find the interrupt.
> >
> > So the author of 8973ea47901c81a1912bd05f1577bed9b5b52506 failed to
> > mention the real reason? Or look at
> > 31a8d8fa84c51d3ab00bf059158d5de6178cf890:
> >
> > [...] use platform_get_irq_optional() to get second/third IRQ
> > which are optional to avoid below error message during probe:
> > [...]
> >
> > Look through the output of
> >
> > git log -Splatform_get_irq_optional
> >
> > to find several more of these.
>
> Commit 8973ea47901c81a1 ("driver core: platform: Introduce
> platform_get_irq_optional()") and the various fixups fixed the ugly
> printing of error messages that were not applicable.
> In hindsight, probably commit 7723f4c5ecdb8d83 ("driver core:
> platform: Add an error message to platform_get_irq*()") should have
> been reverted instead, until a platform_get_irq_optional() with proper
> semantics was introduced.

ack.

> But as we were all in a hurry to kill the non-applicable error
> message, we went for the quick and dirty fix.
>
> > Also I fail to see how a caller of (today's) platform_get_irq_optional()
> > is simpler than a caller of platform_get_irq() given that there is no
> > semantic difference between the two. Please show me a single
> > conversion from platform_get_irq to platform_get_irq_optional that
> > yielded a simplification.
>
> That's exactly why we want to change the latter to return 0 ;-)

OK. So you agree to my statement "The reason for
platform_get_irq_optional()'s existence is just that platform_get_irq()
emits an error message [...]". Actually you don't want to oppose but
say: It's unfortunate that the silent variant of platform_get_irq() took
the obvious name of a function that could have an improved return code
semantic.

So my suggestion to rename todays platform_get_irq_optional() to
platform_get_irq_silently() and then introducing
platform_get_irq_optional() with your suggested semantic seems
intriguing and straigt forward to me.

Another thought: platform_get_irq emits an error message for all
problems. Wouldn't it be consistent to let platform_get_irq_optional()
emit an error message for all problems but "not found"?
Alternatively remove the error printk from platform_get_irq().

> > So you need some more effort to convince me of your POV.
> >
> > > Even for clocks, you cannot assume that you can always blindly use
> > > the returned dummy (actually a NULL pointer) to call into the clk
> > > API. While this works fine for simple use cases, where you just
> > > want to enable/disable an optional clock (clk_prepare_enable() and
> > > clk_disable_unprepare()), it does not work for more complex use cases.
> >
> > Agreed. But for clks and gpiods and regulators the simple case is quite
> > usual. For irqs it isn't.
>
> It is for devices that can have either separate interrupts, or a single
> multiplexed interrupt.
>
> The logic in e.g. drivers/tty/serial/sh-sci.c and
> drivers/spi/spi-rspi.c could be simplified and improved (currently
> it doesn't handle deferred probe) if platform_get_irq_optional()
> would return 0 instead of -ENXIO.

Looking at sh-sci.c the irq handling logic could be improved even
without a changed platform_get_irq_optional():

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 968967d722d4..c7dc9fb84844 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2873,11 +2873,13 @@ static int sci_init_single(struct platform_device *dev,
* interrupt ID numbers, or muxed together with another interrupt.
*/
if (sci_port->irqs[0] < 0)
- return -ENXIO;
+ return sci_port->irqs[0];

- if (sci_port->irqs[1] < 0)
+ if (sci_port->irqs[1] == -ENXIO)
for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++)
sci_port->irqs[i] = sci_port->irqs[0];
+ else if (sci_port->irqs[1] < 0)
+ return sci_port->irqs[1];

sci_port->params = sci_probe_regmap(p);
if (unlikely(sci_port->params == NULL))

And then the code flow is actively irritating. sci_init_single() copies
irqs[0] to all other irqs[i] and then sci_request_irq() loops over the
already requested irqs and checks for duplicates. A single place that
identifies the exact set of required irqs would already help a lot.

Also for spi-rspi.c I don't see how platform_get_irq_byname_optional()
returning 0 instead of -ENXIO would help. Please talk in patches.

Preferably first simplify in-driver logic to make the conversion to the
new platform_get_irq_optional() actually reviewable.

> > And if you cannot blindly use the dummy, then you're not the targetted
> > caller of *_get_optional() and should better use *_get() and handle
> > -ENODEV explicitly.
>
> No, because the janitors tend to consolidate error message handling,
> by moving the printing up, inside the *_get() methods. That's exactly
> what happened here.

This is in my eyes the root cause of the issues at hand. Moving the
error message handling into a get function is only right for most of the
callers. So the more conservative approach would be to introduce a noisy
variant of the get function and convert all users that benefit
separately while the unreviewed callers and those that don't want an
error message can happily continue to use the silent variant.

> So there are three reasons: because the absence of an optional IRQ
> is not an error, and thus that should not cause (a) an error code
> to be returned, and (b) an error message to be printed, and (c)
> because it can simplify the logic in device drivers.

I don't agree to (a). If the value signaling not-found is -ENXIO or 0
(or -ENODEV) doesn't matter much. I wouldn't deviate from the return
code semantics of platform_get_irq() just for having to check against 0
instead of -ENXIO. Zero is then just another magic value.
(c) still has to be proven, see above.

> Commit 8973ea47901c81a1 ("driver core: platform: Introduce
> platform_get_irq_optional()") fixed (b), but didn't address (a) and
> (c).

Yes, it fixed (b) and picked a bad name for that.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (7.88 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-17 17:16:24

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/10/22 10:54 PM, Sergey Shtylyov wrote:

> This patch is based on the former Andy Shevchenko's patch:
>
> https://lore.kernel.org/lkml/[email protected]/
>
> Currently platform_get_irq_optional() returns an error code even if IRQ
> resource simply has not been found. It prevents the callers from being
> error code agnostic in their error handling:
>
> ret = platform_get_irq_optional(...);
> if (ret < 0 && ret != -ENXIO)
> return ret; // respect deferred probe
> if (ret > 0)
> ...we get an IRQ...
>
> All other *_optional() APIs seem to return 0 or NULL in case an optional
> resource is not available. Let's follow this good example, so that the
> callers would look like:
>
> ret = platform_get_irq_optional(...);
> if (ret < 0)
> return ret;
> if (ret > 0)
> ...we get an IRQ...
>
> Reported-by: Matthias Schiffer <[email protected]>
> Signed-off-by: Sergey Shtylyov <[email protected]>
[...]

Please don't merge this as yet, I'm going thru this patch once again
and have already found some sloppy code. :-/

> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index 7450904e330a..fdc63bfa5be4 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -382,12 +382,14 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> if (bt_bmc->irq < 0)
> return bt_bmc->irq;
> + if (!bt_bmc->irq)
> + return 0;

Hm, this is sloppy. Will recast and rebase to the -next branch.

>
> rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
> DEVICE_NAME, bt_bmc);
> if (rc < 0) {
> dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
> - bt_bmc->irq = rc;
> + bt_bmc->irq = 0;

This change isn't needed...

> return rc;
> }
>
[...]
> diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
> index 2ccd1db5e98f..0d1bdd27cd78 100644
> --- a/drivers/edac/xgene_edac.c
> +++ b/drivers/edac/xgene_edac.c
> @@ -1917,7 +1917,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
>
> for (i = 0; i < 3; i++) {
> irq = platform_get_irq_optional(pdev, i);

Is *_optinal() even correct here?

> - if (irq < 0) {
> + if (irq <= 0) {
> dev_err(&pdev->dev, "No IRQ resource\n");
> rc = -EINVAL;
> goto out_err;
[...]
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index f75929783b94..ac222985efde 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1521,7 +1521,7 @@ static irqreturn_t brcmnand_ctlrdy_irq(int irq, void *data)
>
> /* check if you need to piggy back on the ctrlrdy irq */
> if (ctrl->edu_pending) {
> - if (irq == ctrl->irq && ((int)ctrl->edu_irq >= 0))
> + if (irq == ctrl->irq && ((int)ctrl->edu_irq > 0))

Note to self: the cast to *int* isn't needed, the edu_irq field is *int* already...

[...]
> diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
> index bdf924b73e47..51289700a7ac 100644
> --- a/drivers/power/supply/mp2629_charger.c
> +++ b/drivers/power/supply/mp2629_charger.c
> @@ -581,9 +581,9 @@ static int mp2629_charger_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, charger);
>
> irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);

Again, is *_optional() even correct here?

> - if (irq < 0) {
> + if (irq <= 0) {
> dev_err(dev, "get irq fail: %d\n", irq);
> - return irq;
> + return irq < 0 ? irq : -ENXIO;
> }
>
> for (i = 0; i < MP2629_MAX_FIELD; i++) {
[...]
> diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
> index 43eb25b167bc..776cfed4339c 100644
> --- a/drivers/thermal/rcar_gen3_thermal.c
> +++ b/drivers/thermal/rcar_gen3_thermal.c
> @@ -430,7 +430,7 @@ static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,
>
> for (i = 0; i < 2; i++) {
> irq = platform_get_irq_optional(pdev, i);
> - if (irq < 0)
> + if (irq <= 0)
> return irq;

Sloppy code again? We shouldn't return 0...

[...]
> diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
> index 68a1c87066d7..cd7494933563 100644
> --- a/drivers/vfio/platform/vfio_platform.c
> +++ b/drivers/vfio/platform/vfio_platform.c
> @@ -32,8 +32,12 @@ static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
> static int get_platform_irq(struct vfio_platform_device *vdev, int i)
> {
> struct platform_device *pdev = (struct platform_device *) vdev->opaque;
> + int ret;
>
> - return platform_get_irq_optional(pdev, i);
> + ret = platform_get_irq_optional(pdev, i);
> + if (ret < 0)
> + return ret;
> + return ret > 0 ? ret : -ENXIO;

Could be expressed more concisely:

return ret ? : -ENXIO;

just like vfio_amba.c does it...

[...]

MBR, Sergey

2022-01-18 02:26:24

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Mon, Jan 17, 2022 at 12:49 PM Uwe Kleine-König
<[email protected]> wrote:
> On Mon, Jan 17, 2022 at 11:35:52AM +0100, Geert Uytterhoeven wrote:
> > On Mon, Jan 17, 2022 at 10:24 AM Uwe Kleine-König
> > <[email protected]> wrote:
> > > On Mon, Jan 17, 2022 at 09:41:42AM +0100, Geert Uytterhoeven wrote:
> > > > On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> > > > > On 1/14/22 11:22 PM, Uwe Kleine-König wrote:
> > > > > > You have to understand that for clk (and regulator and gpiod) NULL is a
> > > > > > valid descriptor that can actually be used, it just has no effect. So
> > > > > > this is a convenience value for the case "If the clk/regulator/gpiod in
> > > > > > question isn't available, there is nothing to do". This is what makes
> > > > > > clk_get_optional() and the others really useful and justifies their
> > > > > > existence. This doesn't apply to platform_get_irq_optional().
> > > > >
> > > > > I do understand that. However, IRQs are a different beast with their
> > > > > own justifications...
> > > >
> > > > > > clk_get_optional() is sane and sensible for cases where the clk might be
> > > > > > absent and it helps you because you don't have to differentiate between
> > > > > > "not found" and "there is an actual resource".
> > > > > >
> > > > > > The reason for platform_get_irq_optional()'s existence is just that
> > > > > > platform_get_irq() emits an error message which is wrong or suboptimal
> > > > >
> > > > > I think you are very wrong here. The real reason is to simplify the
> > > > > callers.
> > > >
> > > > Indeed.
> > >
> > > The commit that introduced platform_get_irq_optional() said:
> > >
> > > Introduce a new platform_get_irq_optional() that works much like
> > > platform_get_irq() but does not output an error on failure to
> > > find the interrupt.
> > >
> > > So the author of 8973ea47901c81a1912bd05f1577bed9b5b52506 failed to
> > > mention the real reason? Or look at
> > > 31a8d8fa84c51d3ab00bf059158d5de6178cf890:
> > >
> > > [...] use platform_get_irq_optional() to get second/third IRQ
> > > which are optional to avoid below error message during probe:
> > > [...]
> > >
> > > Look through the output of
> > >
> > > git log -Splatform_get_irq_optional
> > >
> > > to find several more of these.
> >
> > Commit 8973ea47901c81a1 ("driver core: platform: Introduce
> > platform_get_irq_optional()") and the various fixups fixed the ugly
> > printing of error messages that were not applicable.
> > In hindsight, probably commit 7723f4c5ecdb8d83 ("driver core:
> > platform: Add an error message to platform_get_irq*()") should have
> > been reverted instead, until a platform_get_irq_optional() with proper
> > semantics was introduced.
>
> ack.
>
> > But as we were all in a hurry to kill the non-applicable error
> > message, we went for the quick and dirty fix.
> >
> > > Also I fail to see how a caller of (today's) platform_get_irq_optional()
> > > is simpler than a caller of platform_get_irq() given that there is no
> > > semantic difference between the two. Please show me a single
> > > conversion from platform_get_irq to platform_get_irq_optional that
> > > yielded a simplification.
> >
> > That's exactly why we want to change the latter to return 0 ;-)
>
> OK. So you agree to my statement "The reason for
> platform_get_irq_optional()'s existence is just that platform_get_irq()
> emits an error message [...]". Actually you don't want to oppose but
> say: It's unfortunate that the silent variant of platform_get_irq() took
> the obvious name of a function that could have an improved return code
> semantic.
>
> So my suggestion to rename todays platform_get_irq_optional() to
> platform_get_irq_silently() and then introducing
> platform_get_irq_optional() with your suggested semantic seems
> intriguing and straigt forward to me.

I don't really see the point of needing platform_get_irq_silently(),
unless as an intermediary step, where it's going to be removed again
once the conversion has completed.
Still, the rename would touch all users at once anyway.

> Another thought: platform_get_irq emits an error message for all
> problems. Wouldn't it be consistent to let platform_get_irq_optional()
> emit an error message for all problems but "not found"?
> Alternatively remove the error printk from platform_get_irq().

Yes, all problems but not found are real errors.

> > > So you need some more effort to convince me of your POV.
> > >
> > > > Even for clocks, you cannot assume that you can always blindly use
> > > > the returned dummy (actually a NULL pointer) to call into the clk
> > > > API. While this works fine for simple use cases, where you just
> > > > want to enable/disable an optional clock (clk_prepare_enable() and
> > > > clk_disable_unprepare()), it does not work for more complex use cases.
> > >
> > > Agreed. But for clks and gpiods and regulators the simple case is quite
> > > usual. For irqs it isn't.
> >
> > It is for devices that can have either separate interrupts, or a single
> > multiplexed interrupt.
> >
> > The logic in e.g. drivers/tty/serial/sh-sci.c and
> > drivers/spi/spi-rspi.c could be simplified and improved (currently
> > it doesn't handle deferred probe) if platform_get_irq_optional()
> > would return 0 instead of -ENXIO.
>
> Looking at sh-sci.c the irq handling logic could be improved even
> without a changed platform_get_irq_optional():
>
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 968967d722d4..c7dc9fb84844 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -2873,11 +2873,13 @@ static int sci_init_single(struct platform_device *dev,
> * interrupt ID numbers, or muxed together with another interrupt.
> */
> if (sci_port->irqs[0] < 0)
> - return -ENXIO;
> + return sci_port->irqs[0];
>
> - if (sci_port->irqs[1] < 0)
> + if (sci_port->irqs[1] == -ENXIO)
> for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++)
> sci_port->irqs[i] = sci_port->irqs[0];
> + else if (sci_port->irqs[1] < 0)
> + return sci_port->irqs[1];
>
> sci_port->params = sci_probe_regmap(p);
> if (unlikely(sci_port->params == NULL))
>
> And then the code flow is actively irritating. sci_init_single() copies
> irqs[0] to all other irqs[i] and then sci_request_irq() loops over the
> already requested irqs and checks for duplicates. A single place that
> identifies the exact set of required irqs would already help a lot.

Yeah, it's ugly and convoluted, like the wide set of hardware the
driver supports.

> Also for spi-rspi.c I don't see how platform_get_irq_byname_optional()
> returning 0 instead of -ENXIO would help. Please talk in patches.

--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1420,17 +1420,25 @@ static int rspi_probe(struct platform_device *pdev)
ctlr->max_native_cs = rspi->ops->num_hw_ss;

ret = platform_get_irq_byname_optional(pdev, "rx");
- if (ret < 0) {
+ if (ret < 0)
+ goto error2;
+
+ if (!ret) {
ret = platform_get_irq_byname_optional(pdev, "mux");
- if (ret < 0)
+ if (!ret)
ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto error2;
+
if (ret >= 0)
rspi->rx_irq = rspi->tx_irq = ret;
} else {
rspi->rx_irq = ret;
ret = platform_get_irq_byname(pdev, "tx");
- if (ret >= 0)
- rspi->tx_irq = ret;
+ if (ret < 0)
+ goto error2;
+
+ rspi->tx_irq = ret;
}

if (rspi->rx_irq == rspi->tx_irq) {

I like it when the "if (ret < ) ..." error handling is the first check to do.
With -ENXIO, it becomes more convoluted. and looks less nice (IMHO).

> Preferably first simplify in-driver logic to make the conversion to the
> new platform_get_irq_optional() actually reviewable.

So I have to choose between

if (ret < 0 && ret != -ENXIO)
return ret;

if (ret) {
...
}

and

if (ret == -ENXIO) {
...
} else if (ret < 0)
return ret;
}

with the final target being

if (ret < 0)
return ret;

if (ret) {
...
}

So the first option means the final change is smaller, but it looks less
nice than the second option (IMHO).
But the second option means more churn.

> > So there are three reasons: because the absence of an optional IRQ
> > is not an error, and thus that should not cause (a) an error code
> > to be returned, and (b) an error message to be printed, and (c)
> > because it can simplify the logic in device drivers.
>
> I don't agree to (a). If the value signaling not-found is -ENXIO or 0
> (or -ENODEV) doesn't matter much. I wouldn't deviate from the return
> code semantics of platform_get_irq() just for having to check against 0
> instead of -ENXIO. Zero is then just another magic value.

Zero is a natural magic value (also for pointers).
Errors are always negative.
Positive values are cookies (or pointers) associated with success.

> (c) still has to be proven, see above.
>
> > Commit 8973ea47901c81a1 ("driver core: platform: Introduce
> > platform_get_irq_optional()") fixed (b), but didn't address (a) and
> > (c).
>
> Yes, it fixed (b) and picked a bad name for that.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-18 02:53:42

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 17, 2022 at 02:08:19PM +0100, Geert Uytterhoeven wrote:
> Hi Uwe,
>
> On Mon, Jan 17, 2022 at 12:49 PM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Mon, Jan 17, 2022 at 11:35:52AM +0100, Geert Uytterhoeven wrote:
> > > On Mon, Jan 17, 2022 at 10:24 AM Uwe Kleine-K?nig
> > > <[email protected]> wrote:
> > > > On Mon, Jan 17, 2022 at 09:41:42AM +0100, Geert Uytterhoeven wrote:
> > > > > On Sat, Jan 15, 2022 at 9:22 PM Sergey Shtylyov <[email protected]> wrote:
> > > > > > On 1/14/22 11:22 PM, Uwe Kleine-K?nig wrote:
> > > > > > > You have to understand that for clk (and regulator and gpiod) NULL is a
> > > > > > > valid descriptor that can actually be used, it just has no effect. So
> > > > > > > this is a convenience value for the case "If the clk/regulator/gpiod in
> > > > > > > question isn't available, there is nothing to do". This is what makes
> > > > > > > clk_get_optional() and the others really useful and justifies their
> > > > > > > existence. This doesn't apply to platform_get_irq_optional().
> > > > > >
> > > > > > I do understand that. However, IRQs are a different beast with their
> > > > > > own justifications...
> > > > >
> > > > > > > clk_get_optional() is sane and sensible for cases where the clk might be
> > > > > > > absent and it helps you because you don't have to differentiate between
> > > > > > > "not found" and "there is an actual resource".
> > > > > > >
> > > > > > > The reason for platform_get_irq_optional()'s existence is just that
> > > > > > > platform_get_irq() emits an error message which is wrong or suboptimal
> > > > > >
> > > > > > I think you are very wrong here. The real reason is to simplify the
> > > > > > callers.
> > > > >
> > > > > Indeed.
> > > >
> > > > The commit that introduced platform_get_irq_optional() said:
> > > >
> > > > Introduce a new platform_get_irq_optional() that works much like
> > > > platform_get_irq() but does not output an error on failure to
> > > > find the interrupt.
> > > >
> > > > So the author of 8973ea47901c81a1912bd05f1577bed9b5b52506 failed to
> > > > mention the real reason? Or look at
> > > > 31a8d8fa84c51d3ab00bf059158d5de6178cf890:
> > > >
> > > > [...] use platform_get_irq_optional() to get second/third IRQ
> > > > which are optional to avoid below error message during probe:
> > > > [...]
> > > >
> > > > Look through the output of
> > > >
> > > > git log -Splatform_get_irq_optional
> > > >
> > > > to find several more of these.
> > >
> > > Commit 8973ea47901c81a1 ("driver core: platform: Introduce
> > > platform_get_irq_optional()") and the various fixups fixed the ugly
> > > printing of error messages that were not applicable.
> > > In hindsight, probably commit 7723f4c5ecdb8d83 ("driver core:
> > > platform: Add an error message to platform_get_irq*()") should have
> > > been reverted instead, until a platform_get_irq_optional() with proper
> > > semantics was introduced.
> >
> > ack.
> >
> > > But as we were all in a hurry to kill the non-applicable error
> > > message, we went for the quick and dirty fix.
> > >
> > > > Also I fail to see how a caller of (today's) platform_get_irq_optional()
> > > > is simpler than a caller of platform_get_irq() given that there is no
> > > > semantic difference between the two. Please show me a single
> > > > conversion from platform_get_irq to platform_get_irq_optional that
> > > > yielded a simplification.
> > >
> > > That's exactly why we want to change the latter to return 0 ;-)
> >
> > OK. So you agree to my statement "The reason for
> > platform_get_irq_optional()'s existence is just that platform_get_irq()
> > emits an error message [...]". Actually you don't want to oppose but
> > say: It's unfortunate that the silent variant of platform_get_irq() took
> > the obvious name of a function that could have an improved return code
> > semantic.
> >
> > So my suggestion to rename todays platform_get_irq_optional() to
> > platform_get_irq_silently() and then introducing
> > platform_get_irq_optional() with your suggested semantic seems
> > intriguing and straigt forward to me.
>
> I don't really see the point of needing platform_get_irq_silently(),
> unless as an intermediary step, where it's going to be removed again
> once the conversion has completed.

We agree that one of the two functions is enough, just differ in which
of the two we want to have. :-)

If you think platform_get_irq_silently() is a good intermediate step for
your goal, then we agree to rename platform_get_irq_optional(). So I
suggest you ack my patch.

> Still, the rename would touch all users at once anyway.

It would be more easy to keep the conversion regression-free however. A
plain rename is simple to verify. And then converting to the new
platform_get_irq_optional() can be done individually and without the
need to do everything in a single step.

> > Another thought: platform_get_irq emits an error message for all
> > problems. Wouldn't it be consistent to let platform_get_irq_optional()
> > emit an error message for all problems but "not found"?
> > Alternatively remove the error printk from platform_get_irq().
>
> Yes, all problems but not found are real errors.

If you want to make platform_get_irq and its optional variant more
similar to the others, dropping the error message is the way to go.

> > > > So you need some more effort to convince me of your POV.
> > > >
> > > > > Even for clocks, you cannot assume that you can always blindly use
> > > > > the returned dummy (actually a NULL pointer) to call into the clk
> > > > > API. While this works fine for simple use cases, where you just
> > > > > want to enable/disable an optional clock (clk_prepare_enable() and
> > > > > clk_disable_unprepare()), it does not work for more complex use cases.
> > > >
> > > > Agreed. But for clks and gpiods and regulators the simple case is quite
> > > > usual. For irqs it isn't.
> > >
> > > It is for devices that can have either separate interrupts, or a single
> > > multiplexed interrupt.
> > >
> > > The logic in e.g. drivers/tty/serial/sh-sci.c and
> > > drivers/spi/spi-rspi.c could be simplified and improved (currently
> > > it doesn't handle deferred probe) if platform_get_irq_optional()
> > > would return 0 instead of -ENXIO.
> >
> > Looking at sh-sci.c the irq handling logic could be improved even
> > without a changed platform_get_irq_optional():
> >
> > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> > index 968967d722d4..c7dc9fb84844 100644
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -2873,11 +2873,13 @@ static int sci_init_single(struct platform_device *dev,
> > * interrupt ID numbers, or muxed together with another interrupt.
> > */
> > if (sci_port->irqs[0] < 0)
> > - return -ENXIO;
> > + return sci_port->irqs[0];
> >
> > - if (sci_port->irqs[1] < 0)
> > + if (sci_port->irqs[1] == -ENXIO)
> > for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++)
> > sci_port->irqs[i] = sci_port->irqs[0];
> > + else if (sci_port->irqs[1] < 0)
> > + return sci_port->irqs[1];
> >
> > sci_port->params = sci_probe_regmap(p);
> > if (unlikely(sci_port->params == NULL))
> >
> > And then the code flow is actively irritating. sci_init_single() copies
> > irqs[0] to all other irqs[i] and then sci_request_irq() loops over the
> > already requested irqs and checks for duplicates. A single place that
> > identifies the exact set of required irqs would already help a lot.
>
> Yeah, it's ugly and convoluted, like the wide set of hardware the
> driver supports.
>
> > Also for spi-rspi.c I don't see how platform_get_irq_byname_optional()
> > returning 0 instead of -ENXIO would help. Please talk in patches.
>
> --- a/drivers/spi/spi-rspi.c
> +++ b/drivers/spi/spi-rspi.c
> @@ -1420,17 +1420,25 @@ static int rspi_probe(struct platform_device *pdev)
> ctlr->max_native_cs = rspi->ops->num_hw_ss;
>
> ret = platform_get_irq_byname_optional(pdev, "rx");
> - if (ret < 0) {
> + if (ret < 0)
> + goto error2;
> +
> + if (!ret) {
> ret = platform_get_irq_byname_optional(pdev, "mux");
> - if (ret < 0)
> + if (!ret)
> ret = platform_get_irq(pdev, 0);
> + if (ret < 0)
> + goto error2;
> +
> if (ret >= 0)
> rspi->rx_irq = rspi->tx_irq = ret;
> } else {
> rspi->rx_irq = ret;
> ret = platform_get_irq_byname(pdev, "tx");
> - if (ret >= 0)
> - rspi->tx_irq = ret;
> + if (ret < 0)
> + goto error2;
> +
> + rspi->tx_irq = ret;
> }
>
> if (rspi->rx_irq == rspi->tx_irq) {

This is not a simplification, just looking at the line count and the
added gotos. That's because it also improves error handling and so the
effect isn't easily spotted.

> I like it when the "if (ret < ) ..." error handling is the first check to do.

That's a relevant difference between us.

> With -ENXIO, it becomes more convoluted. and looks less nice (IMHO).
>
> > Preferably first simplify in-driver logic to make the conversion to the
> > new platform_get_irq_optional() actually reviewable.
>
> So I have to choose between
>
> if (ret < 0 && ret != -ENXIO)
> return ret;
>
> if (ret) {
> ...
> }
>
> and
>
> if (ret == -ENXIO) {
> ...
> } else if (ret < 0)
> return ret;
> }

I would do the latter, then it's in the normal order for error handling

handle some specific errors;
forward unhandled errors up the stack;
handle success;

but it seems you prefer to not call "not found" an error. Actually I
think it's an advantage that the driver has to mention -ENXIO, feels
like proper error handling to me. I guess we won't agree about that
though.

What about the following idea (in pythonic pseudo code for simplicity):

# the rspi device either has two irqs, one for rx and one for
# tx, or a single one for both together.

def muxed_hander(irq):
status = readl(STATUS)
if status & IF_RX:
rx_handler()
if status & IF_TX:
tx_handler()

def probe_muxed_irq():
irq = platform_get_irq_by_name("mux")
if irq < 0:
return irq;

request_irq(irq, muxed_handler)

def probe_separate_irqs():
txirq = platform_get_irq_by_name("tx")
if txirq < 0:
return txirq

rxirq = platform_get_irq_by_name("rx")
if rxirq < 0:
return rxirq

request_irq(txirq, tx_handler)
request_irq(rxirq, rx_handler)

def probe():
ret = probe_separate_irqs()
if ret == -ENXIO:
ret = probe_muxed_irq()

if ret < 0:
return ret

looks clean (to me that is) and allows to skip the demuxing in
tx_handler and rx_handler (which might or might not yield improved
runtime behaviour). Maybe a bit more verbose, but simpler to grasp for a
human, isn't it?

> with the final target being
>
> if (ret < 0)
> return ret;
>
> if (ret) {
> ...
> }
>
> So the first option means the final change is smaller, but it looks less
> nice than the second option (IMHO).
> But the second option means more churn.
>
> > > So there are three reasons: because the absence of an optional IRQ
> > > is not an error, and thus that should not cause (a) an error code
> > > to be returned, and (b) an error message to be printed, and (c)
> > > because it can simplify the logic in device drivers.
> >
> > I don't agree to (a). If the value signaling not-found is -ENXIO or 0
> > (or -ENODEV) doesn't matter much. I wouldn't deviate from the return
> > code semantics of platform_get_irq() just for having to check against 0
> > instead of -ENXIO. Zero is then just another magic value.
>
> Zero is a natural magic value (also for pointers).
> Errors are always negative.
> Positive values are cookies (or pointers) associated with success.

Yeah, the issue where we don't agree is if "not-found" is special enough
to deserve the natural magic value. For me -ENXIO is magic enough to
handle the absence of an irq line. I consider it even the better magic
value.

> > (c) still has to be proven, see above.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (12.64 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-19 23:00:36

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Mon, Jan 17, 2022 at 6:06 PM Uwe Kleine-König
<[email protected]> wrote:
> On Mon, Jan 17, 2022 at 02:08:19PM +0100, Geert Uytterhoeven wrote:
> > On Mon, Jan 17, 2022 at 12:49 PM Uwe Kleine-König
> > <[email protected]> wrote:
> > > > The logic in e.g. drivers/tty/serial/sh-sci.c and
> > > > drivers/spi/spi-rspi.c could be simplified and improved (currently
> > > > it doesn't handle deferred probe) if platform_get_irq_optional()
> > > > would return 0 instead of -ENXIO.

> > > Also for spi-rspi.c I don't see how platform_get_irq_byname_optional()
> > > returning 0 instead of -ENXIO would help. Please talk in patches.

[...]

> This is not a simplification, just looking at the line count and the
> added gotos. That's because it also improves error handling and so the
> effect isn't easily spotted.

Yes, it's larger because it adds currently missing error handling.

> What about the following idea (in pythonic pseudo code for simplicity):

No idea what you gain by throwing in a language that is irrelevant
to kernel programming (why no Rust? ;-)

> > > > So there are three reasons: because the absence of an optional IRQ
> > > > is not an error, and thus that should not cause (a) an error code
> > > > to be returned, and (b) an error message to be printed, and (c)
> > > > because it can simplify the logic in device drivers.
> > >
> > > I don't agree to (a). If the value signaling not-found is -ENXIO or 0
> > > (or -ENODEV) doesn't matter much. I wouldn't deviate from the return
> > > code semantics of platform_get_irq() just for having to check against 0
> > > instead of -ENXIO. Zero is then just another magic value.
> >
> > Zero is a natural magic value (also for pointers).
> > Errors are always negative.
> > Positive values are cookies (or pointers) associated with success.
>
> Yeah, the issue where we don't agree is if "not-found" is special enough
> to deserve the natural magic value. For me -ENXIO is magic enough to
> handle the absence of an irq line. I consider it even the better magic
> value.

It differs from other subsystems (clk, gpio, reset), which do return
zero on not found.
What's the point in having *_optional() APIs if they just return the
same values as the non-optional ones?


Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-20 00:23:54

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello Geert,

On Tue, Jan 18, 2022 at 09:25:01AM +0100, Geert Uytterhoeven wrote:
> On Mon, Jan 17, 2022 at 6:06 PM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > On Mon, Jan 17, 2022 at 02:08:19PM +0100, Geert Uytterhoeven wrote:
> > > On Mon, Jan 17, 2022 at 12:49 PM Uwe Kleine-K?nig
> > > <[email protected]> wrote:
> > > > > So there are three reasons: because the absence of an optional IRQ
> > > > > is not an error, and thus that should not cause (a) an error code
> > > > > to be returned, and (b) an error message to be printed, and (c)
> > > > > because it can simplify the logic in device drivers.
> > > >
> > > > I don't agree to (a). If the value signaling not-found is -ENXIO or 0
> > > > (or -ENODEV) doesn't matter much. I wouldn't deviate from the return
> > > > code semantics of platform_get_irq() just for having to check against 0
> > > > instead of -ENXIO. Zero is then just another magic value.
> > >
> > > Zero is a natural magic value (also for pointers).
> > > Errors are always negative.
> > > Positive values are cookies (or pointers) associated with success.
> >
> > Yeah, the issue where we don't agree is if "not-found" is special enough
> > to deserve the natural magic value. For me -ENXIO is magic enough to
> > handle the absence of an irq line. I consider it even the better magic
> > value.
>
> It differs from other subsystems (clk, gpio, reset), which do return
> zero on not found.

IMHO it doesn't matter at all that the return value is zero, relevant is
the semantic of the returned value. For clk, gpio, reset and regulator
NULL is a usable dummy, for irqs it's not. So what you do with the value
returned by platform_get_irq_whatever() is: you compare it with the
(magic?) not-found value, and if it matches, you enter a suitable
if-block.

For the (clk|gpiod|regulator)_get_optional() you don't have to check
against the magic not-found value (so no implementation detail magic
leaks into the caller code) and just pass it to the next API function.
(And my expectation would be that if you chose to represent not-found by
(void *)66 instead of NULL, you won't have to adapt any user, just the
framework internal checks. This is a good thing!)

> What's the point in having *_optional() APIs if they just return the
> same values as the non-optional ones?

The upside is that functions with a similar name have similar semantics.
But I agree, having platform_get_irq_optional() with the same return
value for not-found is bad. Changing the return semantic is only one way
to cope with that, renaming such the actual semantic difference is
obvious from the function name is another (IMHO better one).

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (2.84 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-20 00:27:56

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On Sun, Jan 16, 2022 at 03:19:06PM +0100, Greg Kroah-Hartman wrote:
> On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
> > A possible compromise: We can have both. We rename
> > platform_get_irq_optional() to platform_get_irq_silent() (or
> > platform_get_irq_silently() if this is preferred) and once all users are
> > are changed (which can be done mechanically), we reintroduce a
> > platform_get_irq_optional() with Sergey's suggested semantic (i.e.
> > return 0 on not-found, no error message printking).
>
> Please do not do that as anyone trying to forward-port an old driver
> will miss the abi change of functionality and get confused. Make
> build-breaking changes, if the way a function currently works is
> changed in order to give people a chance.

Fine for me. I assume this is a Nack for Sergey's patch?

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (1.01 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-20 01:08:41

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Tue, Jan 18, 2022 at 10:09 AM Uwe Kleine-König
<[email protected]> wrote:
> On Tue, Jan 18, 2022 at 09:25:01AM +0100, Geert Uytterhoeven wrote:
> > On Mon, Jan 17, 2022 at 6:06 PM Uwe Kleine-König
> > <[email protected]> wrote:
> > > On Mon, Jan 17, 2022 at 02:08:19PM +0100, Geert Uytterhoeven wrote:
> > > > On Mon, Jan 17, 2022 at 12:49 PM Uwe Kleine-König
> > > > <[email protected]> wrote:
> > > > > > So there are three reasons: because the absence of an optional IRQ
> > > > > > is not an error, and thus that should not cause (a) an error code
> > > > > > to be returned, and (b) an error message to be printed, and (c)
> > > > > > because it can simplify the logic in device drivers.
> > > > >
> > > > > I don't agree to (a). If the value signaling not-found is -ENXIO or 0
> > > > > (or -ENODEV) doesn't matter much. I wouldn't deviate from the return
> > > > > code semantics of platform_get_irq() just for having to check against 0
> > > > > instead of -ENXIO. Zero is then just another magic value.
> > > >
> > > > Zero is a natural magic value (also for pointers).
> > > > Errors are always negative.
> > > > Positive values are cookies (or pointers) associated with success.
> > >
> > > Yeah, the issue where we don't agree is if "not-found" is special enough
> > > to deserve the natural magic value. For me -ENXIO is magic enough to
> > > handle the absence of an irq line. I consider it even the better magic
> > > value.
> >
> > It differs from other subsystems (clk, gpio, reset), which do return
> > zero on not found.
>
> IMHO it doesn't matter at all that the return value is zero, relevant is
> the semantic of the returned value. For clk, gpio, reset and regulator
> NULL is a usable dummy, for irqs it's not. So what you do with the value
> returned by platform_get_irq_whatever() is: you compare it with the
> (magic?) not-found value, and if it matches, you enter a suitable
> if-block.
>
> For the (clk|gpiod|regulator)_get_optional() you don't have to check
> against the magic not-found value (so no implementation detail magic
> leaks into the caller code) and just pass it to the next API function.
> (And my expectation would be that if you chose to represent not-found by
> (void *)66 instead of NULL, you won't have to adapt any user, just the
> framework internal checks. This is a good thing!)

Ah, there is the wrong assumption: drivers sometimes do need to know
if the resource was found, and thus do need to know about (void *)66,
-ENODEV, or -ENXIO. I already gave examples for IRQ and clk before.
I can imagine these exist for gpiod and regulator, too, as soon as
you go beyond the trivial "enable" and "disable" use-cases.

And 0/NULL vs. > 0 is the natural check here: missing, but not
an error. Even for IRQ this was envisioned before, when it was
decided that vIRQ zero does not exist.
(Inconsistent) Error codes are not, as missing optional resources
are not error conditions.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-20 01:08:56

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On Tue, Jan 18, 2022 at 10:18:19AM +0100, Uwe Kleine-K?nig wrote:
> On Sun, Jan 16, 2022 at 03:19:06PM +0100, Greg Kroah-Hartman wrote:
> > On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
> > > A possible compromise: We can have both. We rename
> > > platform_get_irq_optional() to platform_get_irq_silent() (or
> > > platform_get_irq_silently() if this is preferred) and once all users are
> > > are changed (which can be done mechanically), we reintroduce a
> > > platform_get_irq_optional() with Sergey's suggested semantic (i.e.
> > > return 0 on not-found, no error message printking).
> >
> > Please do not do that as anyone trying to forward-port an old driver
> > will miss the abi change of functionality and get confused. Make
> > build-breaking changes, if the way a function currently works is
> > changed in order to give people a chance.
>
> Fine for me. I assume this is a Nack for Sergey's patch?

This set of patches is going nowhere as-is, sorry. The thread is too
confusing and people are not agreeing at all.

greg k-h

2022-01-20 08:51:59

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello Geert,

On Tue, Jan 18, 2022 at 10:37:25AM +0100, Geert Uytterhoeven wrote:
> On Tue, Jan 18, 2022 at 10:09 AM Uwe Kleine-K?nig
> <[email protected]> wrote:
> > For the (clk|gpiod|regulator)_get_optional() you don't have to check
> > against the magic not-found value (so no implementation detail magic
> > leaks into the caller code) and just pass it to the next API function.
> > (And my expectation would be that if you chose to represent not-found by
> > (void *)66 instead of NULL, you won't have to adapt any user, just the
> > framework internal checks. This is a good thing!)
>
> Ah, there is the wrong assumption: drivers sometimes do need to know
> if the resource was found, and thus do need to know about (void *)66,
> -ENODEV, or -ENXIO. I already gave examples for IRQ and clk before.
> I can imagine these exist for gpiod and regulator, too, as soon as
> you go beyond the trivial "enable" and "disable" use-cases.

My premise is that every user who has to check for "not found"
explicitly should not use (clk|gpiod)_get_optional() but
(clk|gpiod)_get() and do proper (and explicit) error handling for
-ENODEV. (clk|gpiod)_get_optional() is only for these trivial use-cases.

> And 0/NULL vs. > 0 is the natural check here: missing, but not
> an error.

For me it it 100% irrelevant if "not found" is an error for the query
function or not. I just have to be able to check for "not found" and
react accordingly.

And adding a function

def platform_get_irq_opional():
ret = platform_get_irq()
if ret == -ENXIO:
return 0
return ret

it's not a useful addition to the API if I cannot use 0 as a dummy
because it doesn't simplify the caller enough to justify the additional
function.

The only thing I need to be able is to distinguish the cases "there is
an irq", "there is no irq" and anything else is "there is a problem I
cannot handle and so forward it to my caller". The semantic of
platform_get_irq() is able to satisfy this requirement[1], so why introduce
platform_get_irq_opional() for the small advantage that I can check for
not-found using

if (!irq)

instead of

if (irq != -ENXIO)

? The semantic of platform_get_irq() is easier ("Either a usable
non-negative irq number or a negative error number") compared to
platform_get_irq_optional() ("Either a usable positive irq number or a
negative error number or 0 meaning not found"). Usage of
platform_get_irq() isn't harder or more expensive (neither for a human
reader nor for a maching running the resulting compiled code).
For a human reader

if (irq != -ENXIO)

is even easier to understand because for

if (!irq)

they have to check where the value comes from, see it's
platform_get_irq_optional() and understand that 0 means not-found.

This function just adds overhead because as a irq framework user I have
to understand another function. For me the added benefit is too small to
justify the additional function. And you break out-of-tree drivers.
These are all no major counter arguments, but as the advantage isn't
major either, they still matter.

Best regards
Uwe

[1] the only annoying thing is the error message.

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (3.30 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-20 09:10:40

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hi Uwe,

On Tue, Jan 18, 2022 at 1:08 PM Uwe Kleine-König
<[email protected]> wrote:
> On Tue, Jan 18, 2022 at 10:37:25AM +0100, Geert Uytterhoeven wrote:
> > On Tue, Jan 18, 2022 at 10:09 AM Uwe Kleine-König
> > <[email protected]> wrote:
> > > For the (clk|gpiod|regulator)_get_optional() you don't have to check
> > > against the magic not-found value (so no implementation detail magic
> > > leaks into the caller code) and just pass it to the next API function.
> > > (And my expectation would be that if you chose to represent not-found by
> > > (void *)66 instead of NULL, you won't have to adapt any user, just the
> > > framework internal checks. This is a good thing!)
> >
> > Ah, there is the wrong assumption: drivers sometimes do need to know
> > if the resource was found, and thus do need to know about (void *)66,
> > -ENODEV, or -ENXIO. I already gave examples for IRQ and clk before.
> > I can imagine these exist for gpiod and regulator, too, as soon as
> > you go beyond the trivial "enable" and "disable" use-cases.
>
> My premise is that every user who has to check for "not found"
> explicitly should not use (clk|gpiod)_get_optional() but
> (clk|gpiod)_get() and do proper (and explicit) error handling for
> -ENODEV. (clk|gpiod)_get_optional() is only for these trivial use-cases.
>
> > And 0/NULL vs. > 0 is the natural check here: missing, but not
> > an error.
>
> For me it it 100% irrelevant if "not found" is an error for the query
> function or not. I just have to be able to check for "not found" and
> react accordingly.
>
> And adding a function
>
> def platform_get_irq_opional():
> ret = platform_get_irq()
> if ret == -ENXIO:
> return 0
> return ret
>
> it's not a useful addition to the API if I cannot use 0 as a dummy
> because it doesn't simplify the caller enough to justify the additional
> function.
>
> The only thing I need to be able is to distinguish the cases "there is
> an irq", "there is no irq" and anything else is "there is a problem I
> cannot handle and so forward it to my caller". The semantic of
> platform_get_irq() is able to satisfy this requirement[1], so why introduce
> platform_get_irq_opional() for the small advantage that I can check for
> not-found using
>
> if (!irq)
>
> instead of
>
> if (irq != -ENXIO)
>
> ? The semantic of platform_get_irq() is easier ("Either a usable
> non-negative irq number or a negative error number") compared to
> platform_get_irq_optional() ("Either a usable positive irq number or a
> negative error number or 0 meaning not found"). Usage of
> platform_get_irq() isn't harder or more expensive (neither for a human
> reader nor for a maching running the resulting compiled code).
> For a human reader
>
> if (irq != -ENXIO)
>
> is even easier to understand because for
>
> if (!irq)
>
> they have to check where the value comes from, see it's
> platform_get_irq_optional() and understand that 0 means not-found.

"vIRQ zero does not exist."

> This function just adds overhead because as a irq framework user I have
> to understand another function. For me the added benefit is too small to
> justify the additional function. And you break out-of-tree drivers.
> These are all no major counter arguments, but as the advantage isn't
> major either, they still matter.
>
> Best regards
> Uwe
>
> [1] the only annoying thing is the error message.

So there's still a need for two functions.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-20 12:47:27

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Tue, Jan 18, 2022 at 01:49:15PM +0100, Geert Uytterhoeven wrote:
> nst the magic not-found value (so no implementation detail magic
> > > > leaks into the caller code) and just pass it to the next API function=
> .
> > > > (And my expectation would be that if you chose to represent not-found=
> by
> > > > (void *)66 instead of NULL, you won't have to adapt any user, just th=
> e
> > > > framework internal checks. This is a good thing!)
> > >
> > > Ah, there is the wrong assumption: drivers sometimes do need to know
> > > if the resource was found, and thus do need to know about (void *)66,
> > > -ENODEV, or -ENXIO. I already gave examples for IRQ and clk before.
> > > I can imagine these exist for gpiod and regulator, too, as soon as
> > > you go beyond the trivial "enable" and "disable" use-cases.
> >
> > My premise is that every user who has to check for "not found"
> > explicitly should not use (clk|gpiod)_get_optional() but
> > (clk|gpiod)_get() and do proper (and explicit) error handling for
> > -ENODEV. (clk|gpiod)_get_optional() is only for these trivial use-cases.
> >
> > > And 0/NULL vs. > 0 is the natural check here: missing, but not
> > > an error.
> >
> > For me it it 100% irrelevant if "not found" is an error for the query
> > function or not. I just have to be able to check for "not found" and
> > react accordingly.
> >
> > And adding a function
> >
> > def platform_get_irq_opional():
> > ret =3D platform_get_irq()
> > if ret =3D=3D -ENXIO:
> > return 0
> > return ret
> >
> > it's not a useful addition to the API if I cannot use 0 as a dummy
> > because it doesn't simplify the caller enough to justify the additional
> > function.
> >
> > The only thing I need to be able is to distinguish the cases "there is
> > an irq", "there is no irq" and anything else is "there is a problem I
> > cannot handle and so forward it to my caller". The semantic of
> > platform_get_irq() is able to satisfy this requirement[1], so why introdu=
> ce
> > platform_get_irq_opional() for the small advantage that I can check for
> > not-found using
> >
> > if (!irq)
> >
> > instead of
> >
> > if (irq !=3D -ENXIO)
> >
> > ? The semantic of platform_get_irq() is easier ("Either a usable
> > non-negative irq number or a negative error number") compared to
> > platform_get_irq_optional() ("Either a usable positive irq number or a
> > negative error number or 0 meaning not found"). Usage of
> > platform_get_irq() isn't harder or more expensive (neither for a human
> > reader nor for a maching running the resulting compiled code).
> > For a human reader
> >
> > if (irq !=3D -ENXIO)
> >
> > is even easier to understand because for
> >
> > if (!irq)
> >
> > they have to check where the value comes from, see it's
> > platform_get_irq_optional() and understand that 0 means not-found.
>
> "vIRQ zero does not exist."

With that statement in mind I would expect that a function that gives me
an (v)irq number never returns 0.

> > This function just adds overhead because as a irq framework user I have
> > to understand another function. For me the added benefit is too small to
> > justify the additional function. And you break out-of-tree drivers.
> > These are all no major counter arguments, but as the advantage isn't
> > major either, they still matter.
> >
> > Best regards
> > Uwe
> >
> > [1] the only annoying thing is the error message.
>
> So there's still a need for two functions.

Or a single function not emitting an error message together with the
callers being responsible for calling dev_err().

So the options in my preference order (first is best) are:

- Remove the printk from platform_get_irq() and remove
platform_get_irq_optional();

- Rename platform_get_irq_optional() to platform_get_irq_silently()

- Keep platform_get_irq_optional() as is

- Collect underpants

- ?

- Change semantic of platform_get_irq_optional()

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (4.19 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-21 07:36:21

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello!

On 1/17/22 11:47 AM, Uwe Kleine-K?nig wrote:

[...]
>>>>>>>>> To me it sounds much more logical for the driver to check if an
>>>>>>>>> optional irq is non-zero (available) or zero (not available), than to
>>>>>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
>>>>>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
>>>>>>>>> (or some other error code) to indicate absence. I thought not having
>>>>>>>>> to care about the actual error code was the main reason behind the
>>>>>>>>> introduction of the *_optional() APIs.
>>>>>>>
>>>>>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
>>>>>>>> that you can handle an absent GPIO (or clk) as if it were available.
>>>>>>
>>>>>> Hm, I've just looked at these and must note that they match 1:1 with
>>>>>> platform_get_irq_optional(). Unfortunately, we can't however behave the
>>>>>> same way in request_irq() -- because it has to support IRQ0 for the sake
>>>>>> of i8253 drivers in arch/...
>>>>>
>>>>> Let me reformulate your statement to the IMHO equivalent:
>>>>>
>>>>> If you set aside the differences between
>>>>> platform_get_irq_optional() and gpiod_get_optional(),
>>>>
>>>> Sorry, I should make it clear this is actually the diff between a would-be
>>>> platform_get_irq_optional() after my patch, not the current code...
>>>
>>> The similarity is that with your patch both gpiod_get_optional() and
>>> platform_get_irq_optional() return NULL and 0 on not-found. The relevant
>>> difference however is that for a gpiod NULL is a dummy value, while for
>>> irqs it's not. So the similarity is only syntactically, but not
>>> semantically.
>>
>> I have noting to say here, rather than optional IRQ could well have a different
>> meaning than for clk/gpio/etc.
>>
>> [...]
>>>>> However for an interupt this cannot work. You will always have to check
>>>>> if the irq is actually there or not because if it's not you cannot just
>>>>> ignore that. So there is no benefit of an optional irq.
>>>>>
>>>>> Leaving error message reporting aside, the introduction of
>>>>> platform_get_irq_optional() allows to change
>>>>>
>>>>> irq = platform_get_irq(...);
>>>>> if (irq < 0 && irq != -ENXIO) {
>>>>> return irq;
>>>>> } else if (irq >= 0) {
>>>>
>>>> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
>>>
>>> This is a topic I don't feel strong for, so I'm sloppy here. If changing
>>> this is all that is needed to convince you of my point ...
>>
>> Note that we should absolutely (and first of all) stop returning 0 from platform_get_irq()
>> on a "real" IRQ0. Handling that "still good" zero absolutely doesn't scale e.g. for the subsystems
>> (like libata) which take 0 as an indication that the polling mode should be used... We can't afford
>> to be sloppy here. ;-)
>
> Then maybe do that really first?

I'm doing it first already:

https://lore.kernel.org/all/[email protected]/

This series is atop of the above patch...

> I didn't recheck, but is this what the
> driver changes in your patch is about?

Partly, yes. We can afford to play with the meaning of 0 after the above patch.

> After some more thoughts I wonder if your focus isn't to align
> platform_get_irq_optional to (clk|gpiod|regulator)_get_optional, but to
> simplify return code checking. Because with your change we have:
>
> - < 0 -> error
> - == 0 -> no irq
> - > 0 -> irq

Mainly, yes. That's why the code examples were given in the description.

> For my part I'd say this doesn't justify the change, but at least I
> could better life with the reasoning. If you start at:
>
> irq = platform_get_irq_optional(...)
> if (irq < 0 && irq != -ENXIO)
> return irq
> else if (irq > 0)
> setup_irq(irq);
> else
> setup_polling()
>
> I'd change that to
>
> irq = platform_get_irq_optional(...)
> if (irq > 0) /* or >= 0 ? */

Not >= 0, no...

> setup_irq(irq)
> else if (irq == -ENXIO)
> setup_polling()
> else
> return irq
>
> This still has to mention -ENXIO, but this is ok and checking for 0 just
> hardcodes a different return value.

I think comparing with 0 is simpler (and shorter) than with -ENXIO, if you
consider the RISC CPUs, like e.g. MIPS...

> Anyhow, I think if you still want to change platform_get_irq_optional
> you should add a few patches converting some drivers which demonstrates
> the improvement for the callers.

Mhm, I did include all the drivers where the IRQ checks have to be modified,
not sure what else you want me to touch...

> Best regards
> Uwe

MBR, Sergey

2022-01-21 10:12:48

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Tue, Jan 18, 2022 at 11:21:45PM +0300, Sergey Shtylyov wrote:
> Hello!
>
> On 1/17/22 11:47 AM, Uwe Kleine-K?nig wrote:
>
> [...]
> >>>>>>>>> To me it sounds much more logical for the driver to check if an
> >>>>>>>>> optional irq is non-zero (available) or zero (not available), than to
> >>>>>>>>> sprinkle around checks for -ENXIO. In addition, you have to remember
> >>>>>>>>> that this one returns -ENXIO, while other APIs use -ENOENT or -ENOSYS
> >>>>>>>>> (or some other error code) to indicate absence. I thought not having
> >>>>>>>>> to care about the actual error code was the main reason behind the
> >>>>>>>>> introduction of the *_optional() APIs.
> >>>>>>>
> >>>>>>>> No, the main benefit of gpiod_get_optional() (and clk_get_optional()) is
> >>>>>>>> that you can handle an absent GPIO (or clk) as if it were available.
> >>>>>>
> >>>>>> Hm, I've just looked at these and must note that they match 1:1 with
> >>>>>> platform_get_irq_optional(). Unfortunately, we can't however behave the
> >>>>>> same way in request_irq() -- because it has to support IRQ0 for the sake
> >>>>>> of i8253 drivers in arch/...
> >>>>>
> >>>>> Let me reformulate your statement to the IMHO equivalent:
> >>>>>
> >>>>> If you set aside the differences between
> >>>>> platform_get_irq_optional() and gpiod_get_optional(),
> >>>>
> >>>> Sorry, I should make it clear this is actually the diff between a would-be
> >>>> platform_get_irq_optional() after my patch, not the current code...
> >>>
> >>> The similarity is that with your patch both gpiod_get_optional() and
> >>> platform_get_irq_optional() return NULL and 0 on not-found. The relevant
> >>> difference however is that for a gpiod NULL is a dummy value, while for
> >>> irqs it's not. So the similarity is only syntactically, but not
> >>> semantically.
> >>
> >> I have noting to say here, rather than optional IRQ could well have a different
> >> meaning than for clk/gpio/etc.
> >>
> >> [...]
> >>>>> However for an interupt this cannot work. You will always have to check
> >>>>> if the irq is actually there or not because if it's not you cannot just
> >>>>> ignore that. So there is no benefit of an optional irq.
> >>>>>
> >>>>> Leaving error message reporting aside, the introduction of
> >>>>> platform_get_irq_optional() allows to change
> >>>>>
> >>>>> irq = platform_get_irq(...);
> >>>>> if (irq < 0 && irq != -ENXIO) {
> >>>>> return irq;
> >>>>> } else if (irq >= 0) {
> >>>>
> >>>> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
> >>>
> >>> This is a topic I don't feel strong for, so I'm sloppy here. If changing
> >>> this is all that is needed to convince you of my point ...
> >>
> >> Note that we should absolutely (and first of all) stop returning 0 from platform_get_irq()
> >> on a "real" IRQ0. Handling that "still good" zero absolutely doesn't scale e.g. for the subsystems
> >> (like libata) which take 0 as an indication that the polling mode should be used... We can't afford
> >> to be sloppy here. ;-)
> >
> > Then maybe do that really first?
>
> I'm doing it first already:
>
> https://lore.kernel.org/all/[email protected]/
>
> This series is atop of the above patch...

Ah, I missed that (probably because I didn't get the cover letter).

> > I didn't recheck, but is this what the
> > driver changes in your patch is about?
>
> Partly, yes. We can afford to play with the meaning of 0 after the above patch.

But the changes that are in patch 1 are all needed?

> > After some more thoughts I wonder if your focus isn't to align
> > platform_get_irq_optional to (clk|gpiod|regulator)_get_optional, but to
> > simplify return code checking. Because with your change we have:
> >
> > - < 0 -> error
> > - == 0 -> no irq
> > - > 0 -> irq
>
> Mainly, yes. That's why the code examples were given in the description.
>
> > For my part I'd say this doesn't justify the change, but at least I
> > could better life with the reasoning. If you start at:
> >
> > irq = platform_get_irq_optional(...)
> > if (irq < 0 && irq != -ENXIO)
> > return irq
> > else if (irq > 0)
> > setup_irq(irq);
> > else
> > setup_polling()
> >
> > I'd change that to
> >
> > irq = platform_get_irq_optional(...)
> > if (irq > 0) /* or >= 0 ? */
>
> Not >= 0, no...
>
> > setup_irq(irq)
> > else if (irq == -ENXIO)
> > setup_polling()
> > else
> > return irq
> >
> > This still has to mention -ENXIO, but this is ok and checking for 0 just
> > hardcodes a different return value.
>
> I think comparing with 0 is simpler (and shorter) than with -ENXIO, if you
> consider the RISC CPUs, like e.g. MIPS...

Hmm, I don't know MIPS good enough to judge. So I created a small C
file:

$ cat test.c
#include <errno.h>

int platform_get_irq_optional(void);
void a(void);

int func_0()
{
int irq = platform_get_irq_optional();

if (irq == 0)
a();
}

int func_enxio()
{
int irq = platform_get_irq_optional();

if (irq == -ENXIO)
a();
}

With some cross compilers as provided by Debian doing

$CC -c -O3 test.c
nm --size-sort test.o

I get:

compiler | size of func_0 | size of func_enxio
================================+==================|====================
aarch64-linux-gnu-gcc | 0000000000000024 | 0000000000000028
arm-linux-gnueabi-gcc | 00000018 | 00000018
arm-linux-gnueabihf-gcc | 00000010 | 00000012
i686-linux-gnu-gcc | 0000002a | 0000002a
mips64el-linux-gnuabi64-gcc | 0000000000000054 | 000000000000005c
powerpc-linux-gnu-gcc | 00000058 | 00000058
s390x-linux-gnu-gcc | 000000000000002e | 0000000000000030
x86_64-linux-gnu-gcc | 0000000000000022 | 0000000000000022

So you save some bytes indeed.

> > Anyhow, I think if you still want to change platform_get_irq_optional
> > you should add a few patches converting some drivers which demonstrates
> > the improvement for the callers.
>
> Mhm, I did include all the drivers where the IRQ checks have to be modified,
> not sure what else you want me to touch...

I somehow expected that the changes that are now necessary (or possible)
to callers makes them prettier somehow. Looking at your patch again:

- drivers/counter/interrupt-cnt.c
This one is strange in my eyes because it tests the return value of
gpiod_get_optional against NULL :-(

- drivers/edac/xgene_edac.c
This one just wants a silent irq lookup and then throws away the
error code returned by platform_get_irq_optional() to return -EINVAL.
Not so nice, is it?

- drivers/gpio/gpio-altera.c
This one just wants a silent irq lookup. And maybe it should only
goto skip_irq if the irq was not found, but on an other error code
abort the probe?!

- drivers/gpio/gpio-mvebu.c
Similar to gpio-altera.c: Wants a silent irq and improved error
handling.

- drivers/i2c/busses/i2c-brcmstb.c
A bit ugly that we now have dev->irq == 0 if the irq isn't available,
but if requesting the irq failed irq = -1 is used?

- drivers/mmc/host/sh_mmcif.c
Broken error handling. This one wants to abort on irq[1] < 0 (with
your changed semantic).

I stopped here.

It seems quite common that drivers assume a value < 0 returned by
platform_get_irq means not-found and don't care for -EPROBE_DEFER (what
else can happen?) Changing a relevant function in that mess seems
unfortunate here :-\

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (7.64 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-21 19:09:48

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On 1/18/22 12:18 PM, Uwe Kleine-K?nig wrote:
> On Sun, Jan 16, 2022 at 03:19:06PM +0100, Greg Kroah-Hartman wrote:
>> On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
>>> A possible compromise: We can have both. We rename
>>> platform_get_irq_optional() to platform_get_irq_silent() (or
>>> platform_get_irq_silently() if this is preferred) and once all users are
>>> are changed (which can be done mechanically), we reintroduce a
>>> platform_get_irq_optional() with Sergey's suggested semantic (i.e.
>>> return 0 on not-found, no error message printking).
>>
>> Please do not do that as anyone trying to forward-port an old driver
>> will miss the abi change of functionality and get confused. Make
>> build-breaking changes, if the way a function currently works is
>> changed in order to give people a chance.
>
> Fine for me. I assume this is a Nack for Sergey's patch?

Which patch do you mean? I'm starting to get really muddled... :-(

> Best regards
> Uwe

MBR, Sergey

2022-01-21 19:11:38

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

Hello Sergey,

On Wed, Jan 19, 2022 at 01:56:12PM +0300, Sergey Shtylyov wrote:
> On 1/18/22 12:18 PM, Uwe Kleine-K?nig wrote:
> > On Sun, Jan 16, 2022 at 03:19:06PM +0100, Greg Kroah-Hartman wrote:
> >> On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
> >>> A possible compromise: We can have both. We rename
> >>> platform_get_irq_optional() to platform_get_irq_silent() (or
> >>> platform_get_irq_silently() if this is preferred) and once all users are
> >>> are changed (which can be done mechanically), we reintroduce a
> >>> platform_get_irq_optional() with Sergey's suggested semantic (i.e.
> >>> return 0 on not-found, no error message printking).
> >>
> >> Please do not do that as anyone trying to forward-port an old driver
> >> will miss the abi change of functionality and get confused. Make
> >> build-breaking changes, if the way a function currently works is
> >> changed in order to give people a chance.
> >
> > Fine for me. I assume this is a Nack for Sergey's patch?
>
> Which patch do you mean? I'm starting to get really muddled... :-(

I'm talking about "[PATCH 1/2] platform: make
platform_get_irq_optional() optional" because "trying to forward-port an
old driver will miss the abi" applies to it.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (1.42 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-21 19:12:03

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On 1/19/22 2:33 PM, Uwe Kleine-K?nig wrote:

[...]
>>>>> A possible compromise: We can have both. We rename
>>>>> platform_get_irq_optional() to platform_get_irq_silent() (or
>>>>> platform_get_irq_silently() if this is preferred) and once all users are
>>>>> are changed (which can be done mechanically), we reintroduce a
>>>>> platform_get_irq_optional() with Sergey's suggested semantic (i.e.
>>>>> return 0 on not-found, no error message printking).
>>>>
>>>> Please do not do that as anyone trying to forward-port an old driver
>>>> will miss the abi change of functionality and get confused. Make
>>>> build-breaking changes, if the way a function currently works is
>>>> changed in order to give people a chance.
>>>
>>> Fine for me. I assume this is a Nack for Sergey's patch?
>>
>> Which patch do you mean? I'm starting to get really muddled... :-(
>
> I'm talking about "[PATCH 1/2] platform: make
> platform_get_irq_optional() optional"

I thought GregKH was talking about your renaming patch... :-/

> because "trying to forward-port an
> old driver will miss the abi" applies to it.

Mhm... why not tell me right from the start? Jr even tell that to Andy
instead of merging his patch, so I wouldn't get sucked into this work?
I wouldn't bother with v2 and it would have saved a lot of time spent on
email... :-(
Do we also remember that "the stable API is a nonsense" thing? :-)

> Best regards
> Uwe

MBR, Sergey

2022-01-21 19:22:53

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 17, 2022 at 02:57:32PM +0300, Sergey Shtylyov wrote:
> On 1/10/22 10:54 PM, Sergey Shtylyov wrote:
>
> > This patch is based on the former Andy Shevchenko's patch:
> >
> > https://lore.kernel.org/lkml/[email protected]/
> >
> > Currently platform_get_irq_optional() returns an error code even if IRQ
> > resource simply has not been found. It prevents the callers from being
> > error code agnostic in their error handling:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0 && ret != -ENXIO)
> > return ret; // respect deferred probe
> > if (ret > 0)
> > ...we get an IRQ...
> >
> > All other *_optional() APIs seem to return 0 or NULL in case an optional
> > resource is not available. Let's follow this good example, so that the
> > callers would look like:
> >
> > ret = platform_get_irq_optional(...);
> > if (ret < 0)
> > return ret;
> > if (ret > 0)
> > ...we get an IRQ...
> >
> > Reported-by: Matthias Schiffer <[email protected]>
> > Signed-off-by: Sergey Shtylyov <[email protected]>
> [...]
>
> Please don't merge this as yet, I'm going thru this patch once again
> and have already found some sloppy code. :-/

Who would you expect to merge this? I would have expected Greg, but he
seems to have given up this thread.

> > diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> > index 7450904e330a..fdc63bfa5be4 100644
> > --- a/drivers/char/ipmi/bt-bmc.c
> > +++ b/drivers/char/ipmi/bt-bmc.c
> > @@ -382,12 +382,14 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> > bt_bmc->irq = platform_get_irq_optional(pdev, 0);
> > if (bt_bmc->irq < 0)
> > return bt_bmc->irq;
> > + if (!bt_bmc->irq)
> > + return 0;
>
> Hm, this is sloppy. Will recast and rebase to the -next branch.

I didn't think about what you mean with sloppy, but the code is
equivalent to

if (bt_bmc->irq <= 0)
return bt_bmc->irq;

> >
> > rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
> > DEVICE_NAME, bt_bmc);
> > if (rc < 0) {
> > dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
> > - bt_bmc->irq = rc;
> > + bt_bmc->irq = 0;
>
> This change isn't needed...
>
> > return rc;
> > }
> >
> [...]
> > diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
> > index 2ccd1db5e98f..0d1bdd27cd78 100644
> > --- a/drivers/edac/xgene_edac.c
> > +++ b/drivers/edac/xgene_edac.c
> > @@ -1917,7 +1917,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
> >
> > for (i = 0; i < 3; i++) {
> > irq = platform_get_irq_optional(pdev, i);
>
> Is *_optinal() even correct here?

_optinal isn't correct, _optional maybe is. :-)
Anyhow, look at e26124cd5f7099949109608845bba9e9bf96599c, the driver was
fixed not to print two error messages and the wrong option was picked.

> > - if (irq < 0) {
> > + if (irq <= 0) {
> > dev_err(&pdev->dev, "No IRQ resource\n");
> > rc = -EINVAL;
> > goto out_err;

What's wrong here is that the return code is hardcoded ...

> [...]
> > diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > index f75929783b94..ac222985efde 100644
> > --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > @@ -1521,7 +1521,7 @@ static irqreturn_t brcmnand_ctlrdy_irq(int irq, void *data)
> >
> > /* check if you need to piggy back on the ctrlrdy irq */
> > if (ctrl->edu_pending) {
> > - if (irq == ctrl->irq && ((int)ctrl->edu_irq >= 0))
> > + if (irq == ctrl->irq && ((int)ctrl->edu_irq > 0))
>
> Note to self: the cast to *int* isn't needed, the edu_irq field is *int* already...
>
> [...]
> > diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
> > index bdf924b73e47..51289700a7ac 100644
> > --- a/drivers/power/supply/mp2629_charger.c
> > +++ b/drivers/power/supply/mp2629_charger.c
> > @@ -581,9 +581,9 @@ static int mp2629_charger_probe(struct platform_device *pdev)
> > platform_set_drvdata(pdev, charger);
> >
> > irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);
>
> Again, is *_optional() even correct here?
>
> > - if (irq < 0) {
> > + if (irq <= 0) {
> > dev_err(dev, "get irq fail: %d\n", irq);
> > - return irq;
> > + return irq < 0 ? irq : -ENXIO;

Ack, could be simplified by switching to platform_get_irq().

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (4.64 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-21 19:32:51

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

Hello!

On 1/19/22 1:26 AM, Uwe Kleine-K?nig wrote:

[...]
>>>>>>> However for an interupt this cannot work. You will always have to check
>>>>>>> if the irq is actually there or not because if it's not you cannot just
>>>>>>> ignore that. So there is no benefit of an optional irq.
>>>>>>>
>>>>>>> Leaving error message reporting aside, the introduction of
>>>>>>> platform_get_irq_optional() allows to change
>>>>>>>
>>>>>>> irq = platform_get_irq(...);
>>>>>>> if (irq < 0 && irq != -ENXIO) {
>>>>>>> return irq;
>>>>>>> } else if (irq >= 0) {
>>>>>>
>>>>>> Rather (irq > 0) actually, IRQ0 is considered invalid (but still returned).
>>>>>
>>>>> This is a topic I don't feel strong for, so I'm sloppy here. If changing
>>>>> this is all that is needed to convince you of my point ...
>>>>
>>>> Note that we should absolutely (and first of all) stop returning 0 from platform_get_irq()
>>>> on a "real" IRQ0. Handling that "still good" zero absolutely doesn't scale e.g. for the subsystems
>>>> (like libata) which take 0 as an indication that the polling mode should be used... We can't afford
>>>> to be sloppy here. ;-)
>>>
>>> Then maybe do that really first?
>>
>> I'm doing it first already:
>>
>> https://lore.kernel.org/all/[email protected]/
>>
>> This series is atop of the above patch...
>
> Ah, I missed that (probably because I didn't get the cover letter).
>
>>> I didn't recheck, but is this what the
>>> driver changes in your patch is about?
>>
>> Partly, yes. We can afford to play with the meaning of 0 after the above patch.
>
> But the changes that are in patch 1 are all needed?

Yes, they follow from the platform_get_irq_optional() changing the sense of its result...

[...]
>>> For my part I'd say this doesn't justify the change, but at least I
>>> could better life with the reasoning. If you start at:
>>>
>>> irq = platform_get_irq_optional(...)
>>> if (irq < 0 && irq != -ENXIO)
>>> return irq
>>> else if (irq > 0)
>>> setup_irq(irq);
>>> else
>>> setup_polling()
>>>
>>> I'd change that to
>>>
>>> irq = platform_get_irq_optional(...)
>>> if (irq > 0) /* or >= 0 ? */
>>
>> Not >= 0, no...
>>
>>> setup_irq(irq)
>>> else if (irq == -ENXIO)
>>> setup_polling()
>>> else
>>> return irq
>>>
>>> This still has to mention -ENXIO, but this is ok and checking for 0 just
>>> hardcodes a different return value.
>>
>> I think comparing with 0 is simpler (and shorter) than with -ENXIO, if you
>> consider the RISC CPUs, like e.g. MIPS...
>
> Hmm, I don't know MIPS good enough to judge. So I created a small C

MIPS has read-only register 0 (containing 0 :-)) which should simplify things. But
I'd have to check the actual object code... yeah, MIPS has a branching instruction that
compares 2 registers and branches on the result'; with -ENXIO you'd have to load an
immediate value into a register first...

> file:
>
> $ cat test.c
> #include <errno.h>
>
> int platform_get_irq_optional(void);
> void a(void);
>
> int func_0()
> {
> int irq = platform_get_irq_optional();
>
> if (irq == 0)
> a();
> }
>
> int func_enxio()
> {
> int irq = platform_get_irq_optional();
>
> if (irq == -ENXIO)
> a();
> }
>
> With some cross compilers as provided by Debian doing
>
> $CC -c -O3 test.c

Mhm, do we really use -O3 to build the kernel?

> nm --size-sort test.o
>
> I get:
>
> compiler | size of func_0 | size of func_enxio
> ================================+==================|====================
> aarch64-linux-gnu-gcc | 0000000000000024 | 0000000000000028
> arm-linux-gnueabi-gcc | 00000018 | 00000018
> arm-linux-gnueabihf-gcc | 00000010 | 00000012

Hm, 2 bytes only -- perhaps Thumb mode?

> i686-linux-gnu-gcc | 0000002a | 0000002a

Expected.

> mips64el-linux-gnuabi64-gcc | 0000000000000054 | 000000000000005c

That's even more than expected -- 64-bit mode used?

> powerpc-linux-gnu-gcc | 00000058 | 00000058

Well, they say

> s390x-linux-gnu-gcc | 000000000000002e | 0000000000000030
> x86_64-linux-gnu-gcc | 0000000000000022 | 0000000000000022

Again, as expected...

> So you save some bytes indeed.

I see you have a lot of spare time (unlike me!). :-)

>>> Anyhow, I think if you still want to change platform_get_irq_optional
>>> you should add a few patches converting some drivers which demonstrates
>>> the improvement for the callers.
>>
>> Mhm, I did include all the drivers where the IRQ checks have to be modified,
>> not sure what else you want me to touch...
>
> I somehow expected that the changes that are now necessary (or possible)
> to callers makes them prettier somehow. Looking at your patch again:

I think they do...

>
> - drivers/counter/interrupt-cnt.c
> This one is strange in my eyes because it tests the return value of
> gpiod_get_optional against NULL :-(

Mhm, how is this connected with my patch? :-/

> - drivers/edac/xgene_edac.c
> This one just wants a silent irq lookup and then throws away the
> error code returned by platform_get_irq_optional() to return -EINVAL.
> Not so nice, is it?

I have dropped this file from my (to be posted yet) v2... sorry that it
took so long...

> - drivers/gpio/gpio-altera.c
> This one just wants a silent irq lookup. And maybe it should only
> goto skip_irq if the irq was not found, but on an other error code
> abort the probe?!

That's debatable... but anyway it's a matter of a separate (follow up)
patch...

>
> - drivers/gpio/gpio-mvebu.c
> Similar to gpio-altera.c: Wants a silent irq and improved error
> handling.

Same as above...

> - drivers/i2c/busses/i2c-brcmstb.c
> A bit ugly that we now have dev->irq == 0 if the irq isn't available,
> but if requesting the irq failed irq = -1 is used?

This doesn't matter much really but can change to 0, if you want... :-)

>
> - drivers/mmc/host/sh_mmcif.c
> Broken error handling. This one wants to abort on irq[1] < 0 (with
> your changed semantic).

Again, matter of a separate patch (I don't have the guily hardware anymore
but I guess Geert could help with that).

> I stopped here.

Note that most of your complaints are about the existing driver logic --
which my patch just couldn't deal with... I currently don't have the bandwidth
for addressing all your complaints; some (more obvious) I'm goiing to address
as the time permits, the draft patches have been done already...

> It seems quite common that drivers assume a value < 0 returned by
> platform_get_irq means not-found

Of course, before this patch -ENXIO meant IRQ-not-found, many drivers
don't bother to filter it out separately (for simplicity?).

> and don't care for -EPROBE_DEFER (what else can happen?).

Hm, I haven't really seen a lot the probe dererral mishandling in the code
touched by at least my patch #1...

> Changing a relevant function in that mess seems unfortunate here :-\

You seem to have some spare time and I'm getting distracted contrariwise...
want to help? :-)

> Best regards
> Uwe

MBR, Sergey

2022-01-21 19:40:34

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/19/22 6:02 PM, Uwe Kleine-K?nig wrote:

[...]
>>> This patch is based on the former Andy Shevchenko's patch:
>>>
>>> https://lore.kernel.org/lkml/[email protected]/
>>>
>>> Currently platform_get_irq_optional() returns an error code even if IRQ
>>> resource simply has not been found. It prevents the callers from being
>>> error code agnostic in their error handling:
>>>
>>> ret = platform_get_irq_optional(...);
>>> if (ret < 0 && ret != -ENXIO)
>>> return ret; // respect deferred probe
>>> if (ret > 0)
>>> ...we get an IRQ...
>>>
>>> All other *_optional() APIs seem to return 0 or NULL in case an optional
>>> resource is not available. Let's follow this good example, so that the
>>> callers would look like:
>>>
>>> ret = platform_get_irq_optional(...);
>>> if (ret < 0)
>>> return ret;
>>> if (ret > 0)
>>> ...we get an IRQ...
>>>
>>> Reported-by: Matthias Schiffer <[email protected]>
>>> Signed-off-by: Sergey Shtylyov <[email protected]>
>> [...]
>>
>> Please don't merge this as yet, I'm going thru this patch once again
>> and have already found some sloppy code. :-/
>
> Who would you expect to merge this? I would have expected Greg, but he

Me too, it's his area, the message was addressed to Greg KH...

> seems to have given up this thread.

You instill too much uncertainty in him. :-)

>>> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
>>> index 7450904e330a..fdc63bfa5be4 100644
>>> --- a/drivers/char/ipmi/bt-bmc.c
>>> +++ b/drivers/char/ipmi/bt-bmc.c
>>> @@ -382,12 +382,14 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>>> bt_bmc->irq = platform_get_irq_optional(pdev, 0);
>>> if (bt_bmc->irq < 0)
>>> return bt_bmc->irq;
>>> + if (!bt_bmc->irq)
>>> + return 0;
>>
>> Hm, this is sloppy. Will recast and rebase to the -next branch.
>
> I didn't think about what you mean with sloppy, but the code is
> equivalent to
>
> if (bt_bmc->irq <= 0)
> return bt_bmc->irq;

Exactly.

[...]
>>> diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
>>> index 2ccd1db5e98f..0d1bdd27cd78 100644
>>> --- a/drivers/edac/xgene_edac.c
>>> +++ b/drivers/edac/xgene_edac.c
>>> @@ -1917,7 +1917,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
>>>
>>> for (i = 0; i < 3; i++) {
>>> irq = platform_get_irq_optional(pdev, i);
>>
>> Is *_optinal() even correct here?
>
> _optinal isn't correct, _optional maybe is. :-)

No. :-)

> Anyhow, look at e26124cd5f7099949109608845bba9e9bf96599c, the driver was
> fixed not to print two error messages and the wrong option was picked.

I think this patch is wrong...

>>> - if (irq < 0) {
>>> + if (irq <= 0) {
>>> dev_err(&pdev->dev, "No IRQ resource\n");

This is what needed to be thrown overboard... :-)

>>> rc = -EINVAL;
>>> goto out_err;
>
> What's wrong here is that the return code is hardcoded ...

This is wrong as well -- kills the deferred probing. I have 2 separate patches
for this driver now... just need some time to get 'em ready...

[...]
>>> index bdf924b73e47..51289700a7ac 100644
>>> --- a/drivers/power/supply/mp2629_charger.c
>>> +++ b/drivers/power/supply/mp2629_charger.c
>>> @@ -581,9 +581,9 @@ static int mp2629_charger_probe(struct platform_device *pdev)
>>> platform_set_drvdata(pdev, charger);
>>>
>>> irq = platform_get_irq_optional(to_platform_device(dev->parent), 0);
>>
>> Again, is *_optional() even correct here?
>>
>>> - if (irq < 0) {
>>> + if (irq <= 0) {
>>> dev_err(dev, "get irq fail: %d\n", irq);
>>> - return irq;
>>> + return irq < 0 ? irq : -ENXIO;
>
> Ack, could be simplified by switching to platform_get_irq().

Have a draft patch...

> Best regards
> Uwe

MBR, Sergey

2022-01-21 19:47:43

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/18/22 5:29 PM, Uwe Kleine-K?nig wrote:

>> nst the magic not-found value (so no implementation detail magic
>>>>> leaks into the caller code) and just pass it to the next API function=
>> .
>>>>> (And my expectation would be that if you chose to represent not-found=
>> by
>>>>> (void *)66 instead of NULL, you won't have to adapt any user, just th=
>> e
>>>>> framework internal checks. This is a good thing!)
>>>>
>>>> Ah, there is the wrong assumption: drivers sometimes do need to know
>>>> if the resource was found, and thus do need to know about (void *)66,
>>>> -ENODEV, or -ENXIO. I already gave examples for IRQ and clk before.
>>>> I can imagine these exist for gpiod and regulator, too, as soon as
>>>> you go beyond the trivial "enable" and "disable" use-cases.
>>>
>>> My premise is that every user who has to check for "not found"
>>> explicitly should not use (clk|gpiod)_get_optional() but
>>> (clk|gpiod)_get() and do proper (and explicit) error handling for
>>> -ENODEV. (clk|gpiod)_get_optional() is only for these trivial use-cases.
>>>
>>>> And 0/NULL vs. > 0 is the natural check here: missing, but not
>>>> an error.
>>>
>>> For me it it 100% irrelevant if "not found" is an error for the query
>>> function or not. I just have to be able to check for "not found" and
>>> react accordingly.
>>>
>>> And adding a function
>>>
>>> def platform_get_irq_opional():
>>> ret =3D platform_get_irq()
>>> if ret =3D=3D -ENXIO:
>>> return 0
>>> return ret
>>>
>>> it's not a useful addition to the API if I cannot use 0 as a dummy
>>> because it doesn't simplify the caller enough to justify the additional
>>> function.
>>>
>>> The only thing I need to be able is to distinguish the cases "there is
>>> an irq", "there is no irq" and anything else is "there is a problem I
>>> cannot handle and so forward it to my caller". The semantic of
>>> platform_get_irq() is able to satisfy this requirement[1], so why introdu=
>> ce
>>> platform_get_irq_opional() for the small advantage that I can check for
>>> not-found using
>>>
>>> if (!irq)
>>>
>>> instead of
>>>
>>> if (irq !=3D -ENXIO)
>>>
>>> ? The semantic of platform_get_irq() is easier ("Either a usable
>>> non-negative irq number or a negative error number") compared to
>>> platform_get_irq_optional() ("Either a usable positive irq number or a
>>> negative error number or 0 meaning not found"). Usage of
>>> platform_get_irq() isn't harder or more expensive (neither for a human
>>> reader nor for a maching running the resulting compiled code).
>>> For a human reader
>>>
>>> if (irq !=3D -ENXIO)
>>>
>>> is even easier to understand because for
>>>
>>> if (!irq)
>>>
>>> they have to check where the value comes from, see it's
>>> platform_get_irq_optional() and understand that 0 means not-found.
>>
>> "vIRQ zero does not exist."
>
> With that statement in mind I would expect that a function that gives me
> an (v)irq number never returns 0.
>
>>> This function just adds overhead because as a irq framework user I have
>>> to understand another function. For me the added benefit is too small to
>>> justify the additional function. And you break out-of-tree drivers.
>>> These are all no major counter arguments, but as the advantage isn't
>>> major either, they still matter.
>>>
>>> Best regards
>>> Uwe
>>>
>>> [1] the only annoying thing is the error message.
>>
>> So there's still a need for two functions.
>
> Or a single function not emitting an error message together with the
> callers being responsible for calling dev_err().
>
> So the options in my preference order (first is best) are:
>
> - Remove the printk from platform_get_irq() and remove
> platform_get_irq_optional();

Strong NAK here:
- dev_err() in our function saves a lot of (repeatable!) comments;
- we've already discussed that it's more optimal to check againt 0 than
against -ENXIO in the callers.

> - Rename platform_get_irq_optional() to platform_get_irq_silently()

NAK as well. We'd better off complaining about irq < 0 in this function.

> - Keep platform_get_irq_optional() as is

NAK, it's suboptimal in the call sites.

> - Collect underpants
>
> - ?

You're on your own here. :-)

> - Change semantic of platform_get_irq_optional()

Yes, we should change the semantics if it serves our goals better.

> Best regards
> Uwe

MBR, Sergey

2022-01-21 19:56:01

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/19/22 7:12 PM, Sergey Shtylyov wrote:

[...]
>>> So there's still a need for two functions.
>>
>> Or a single function not emitting an error message together with the
>> callers being responsible for calling dev_err().
>>
>> So the options in my preference order (first is best) are:
>>
>> - Remove the printk from platform_get_irq() and remove
>> platform_get_irq_optional();
>
> Strong NAK here:
> - dev_err() in our function saves a lot of (repeatable!) comments;

s/comments/code/.
Actually, I think I can accept the removal of dev_err_probe() in platform_get_irq()
as this is not a common practice anyway (yet? :-))...

> - we've already discussed that it's more optimal to check againt 0 than

Against. :-)

> against -ENXIO in the callers.

And we also aim to be the error code agnostic in the callers...

>> - Rename platform_get_irq_optional() to platform_get_irq_silently()
>
> NAK as well. We'd better off complaining about irq < 0 in this function.

>> - Keep platform_get_irq_optional() as is
>
> NAK, it's suboptimal in the call sites.

s/in/on/.

[...]

>> Best regards
>> Uwe

MBR, Sergey

2022-01-21 19:58:24

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Sat, Jan 15, 2022 at 02:55:50PM +0100, Uwe Kleine-K?nig wrote:
> On Fri, Jan 14, 2022 at 08:55:07PM +0300, Sergey Shtylyov wrote:

> Or do you think kmalloc should better be called
> kmalloc_optional because it returns NULL if there is no more memory
> available?

Oh, do you know that kmalloc() may return NULL and small cookie value and
actually one has to check for that (yes, either before or after against
different variables)?

kmalloc() is exactly an example that justifies the Sergey's patch.

--
With Best Regards,
Andy Shevchenko


2022-01-21 19:58:45

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Sat, Jan 15, 2022 at 02:55:50PM +0100, Uwe Kleine-K?nig wrote:
> On Fri, Jan 14, 2022 at 08:55:07PM +0300, Sergey Shtylyov wrote:
> > On 1/14/22 12:42 AM, Florian Fainelli wrote:

> So you oppose to the name chosen, but not the renaming as such.

I oppose the name change. The unneeded churn right now since it won't fix
the issues with the underneath API (platform_get_irq() in this case) and
will require one more iteration over callers again.

The main issue that platform_get_irq*() returns magic error code while
treating 0 in a very special way (issuing WARN() and considering it as
a successful cookie) and this all is quite confusing.

If you are going to fix the underlying issue, welcome! Now I see only
the step to somewhere. I.o.w. this change _standalone_ makes no sense
to me.

--
With Best Regards,
Andy Shevchenko


2022-01-21 19:58:59

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Sat, Jan 15, 2022 at 04:45:39PM +0100, Uwe Kleine-K?nig wrote:
> On Fri, Jan 14, 2022 at 03:04:38PM +0200, Andy Shevchenko wrote:
> > On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> > > > It'd certainly be good to name anything that doesn't correspond to one
> > > > of the existing semantics for the API (!) something different rather
> > > > than adding yet another potentially overloaded meaning.
> > >
> > > It seems we're (at least) three who agree about this. Here is a patch
> > > fixing the name.
> >
> > And similar number of people are on the other side.
>
> If someone already opposed to the renaming (and not only the name) I
> must have missed that.
>
> So you think it's a good idea to keep the name
> platform_get_irq_optional() despite the "not found" value returned by it
> isn't usable as if it were a normal irq number?

I meant that on the other side people who are in favour of Sergey's patch.
Since that I commented already that I opposed the renaming being a standalone
change.

Do you agree that we have several issues with platform_get_irq*() APIs?

1. The unfortunate naming
2. The vIRQ0 handling: a) WARN() followed by b) returned value 0
3. The specific cookie for "IRQ not found, while no error happened" case


--
With Best Regards,
Andy Shevchenko


2022-01-21 19:59:05

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Fri, Jan 14, 2022 at 10:45:38PM +0300, Sergey Shtylyov wrote:
> On 1/13/22 10:43 PM, Uwe Kleine-K?nig wrote:
>
> > The subsystems regulator, clk and gpio have the concept of a dummy
> > resource. For regulator, clk and gpio there is a semantic difference
> > between the regular _get() function and the _get_optional() variant.
> > (One might return the dummy resource, the other won't. Unfortunately
> > which one implements which isn't the same for these three.) The
> > difference between platform_get_irq() and platform_get_irq_optional() is
> > only that the former might emit an error message and the later won't.
> >
> > To prevent people's expectations that there is a semantic difference
> > between these too, rename platform_get_irq_optional() to
> > platform_get_irq_silent() to make the actual difference more obvious.
> >
> > The #define for the old name can and should be removed once all patches
> > currently in flux still relying on platform_get_irq_optional() are
> > fixed.
>
> Hm... I'm afraid that with this #define they would never get fixed... :-)

Agree. The problems I have listed in another reply should be fixed at once by
the same series.

--
With Best Regards,
Andy Shevchenko


2022-01-21 19:59:10

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On Mon, Jan 17, 2022 at 09:47:32AM +0100, Uwe Kleine-K?nig wrote:
> On Sun, Jan 16, 2022 at 09:15:20PM +0300, Sergey Shtylyov wrote:

...

> Because with your change we have:
>
> - < 0 -> error
> - == 0 -> no irq
> - > 0 -> irq
>
> For my part I'd say this doesn't justify the change, but at least I
> could better life with the reasoning. If you start at:
>
> irq = platform_get_irq_optional(...)
> if (irq < 0 && irq != -ENXIO)
> return irq
> else if (irq > 0)
> setup_irq(irq);
> else
> setup_polling()
>
> I'd change that to
>
> irq = platform_get_irq_optional(...)
> if (irq > 0) /* or >= 0 ? */
> setup_irq(irq)
> else if (irq == -ENXIO)
> setup_polling()
> else
> return irq
>
> This still has to mention -ENXIO, but this is ok and checking for 0 just
> hardcodes a different return value.

It's what we are against of. The idea is to have

irq = platform_get_irq_optional(...)
if (irq < 0) // we do not care about special cookies here
return irq;

if (irq)
setup_irq(irq)
else
setup_polling()

See the difference? Your code is convoluted.

> Anyhow, I think if you still want to change platform_get_irq_optional
> you should add a few patches converting some drivers which demonstrates
> the improvement for the callers.



--
With Best Regards,
Andy Shevchenko


2022-01-21 19:59:21

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional (summary)

On Sat, Jan 15, 2022 at 07:36:43PM +0100, Uwe Kleine-K?nig wrote:
> Hello,
>
> I'm trying to objectively summarize the discussions in this thread in
> the hope this helps finding a way that most people can live with.
>
> First a description of the status quo:

I do not really understand why we put an equal sign in all implications between
meaning of the 0 cookie and NULL as an (non-existed) instance of an object?

It's like comparing None object in Python to False.

--
With Best Regards,
Andy Shevchenko


2022-01-21 20:00:25

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On 1/19/22 9:51 PM, Andy Shevchenko wrote:

[...]
>>>>> It'd certainly be good to name anything that doesn't correspond to one
>>>>> of the existing semantics for the API (!) something different rather
>>>>> than adding yet another potentially overloaded meaning.
>>>>
>>>> It seems we're (at least) three who agree about this. Here is a patch
>>>> fixing the name.
>>>
>>> And similar number of people are on the other side.
>>
>> If someone already opposed to the renaming (and not only the name) I
>> must have missed that.
>>
>> So you think it's a good idea to keep the name
>> platform_get_irq_optional() despite the "not found" value returned by it
>> isn't usable as if it were a normal irq number?
>
> I meant that on the other side people who are in favour of Sergey's patch.
> Since that I commented already that I opposed the renaming being a standalone
> change.
>
> Do you agree that we have several issues with platform_get_irq*() APIs?
>
> 1. The unfortunate naming

Mmm, "what's in a name?"... is this the topmost prio issue?

> 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0

This is the most severe issue, I think...

> 3. The specific cookie for "IRQ not found, while no error happened" case

MBR, Sergey

2022-01-21 20:00:28

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

Hello!

On 1/19/22 9:36 PM, Andy Shevchenko wrote:

[...]
>> So you oppose to the name chosen, but not the renaming as such.
>
> I oppose the name change. The unneeded churn right now since it won't fix
> the issues with the underneath API (platform_get_irq() in this case) and
> will require one more iteration over callers again.
>
> The main issue that platform_get_irq*() returns magic error code while
> treating 0 in a very special way (issuing WARN() and considering it as
> a successful cookie) and this all is quite confusing.

I have a patch for that -- to which you were hostile for some reason I still
can't understand. :-)

> If you are going to fix the underlying issue, welcome! Now I see only
> the step to somewhere. I.o.w. this change _standalone_ makes no sense
> to me.

We already have a fix, no? It just hasn't been applied still... :-)
Without it the 2 patches dealing with *_optional() don't have much sense.

MBR, Sergey

2022-01-21 20:00:59

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/19/22 9:58 PM, Andy Shevchenko wrote:

[...]
>> Because with your change we have:
>>
>> - < 0 -> error
>> - == 0 -> no irq
>> - > 0 -> irq
>>
>> For my part I'd say this doesn't justify the change, but at least I
>> could better life with the reasoning. If you start at:
>>
>> irq = platform_get_irq_optional(...)
>> if (irq < 0 && irq != -ENXIO)
>> return irq
>> else if (irq > 0)
>> setup_irq(irq);
>> else
>> setup_polling()
>>
>> I'd change that to
>>
>> irq = platform_get_irq_optional(...)
>> if (irq > 0) /* or >= 0 ? */
>> setup_irq(irq)
>> else if (irq == -ENXIO)
>> setup_polling()
>> else
>> return irq
>>
>> This still has to mention -ENXIO, but this is ok and checking for 0 just
>> hardcodes a different return value.
>
> It's what we are against of. The idea is to have
>
> irq = platform_get_irq_optional(...)
> if (irq < 0) // we do not care about special cookies here
> return irq;
>
> if (irq)
> setup_irq(irq)
> else
> setup_polling()
>
> See the difference? Your code is convoluted.

... and it's longer when you look at the translated code! :-)

[...]

MBR, Sergey

2022-01-21 20:04:09

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Wed, Jan 19, 2022 at 10:47:06PM +0300, Sergey Shtylyov wrote:
> On 1/19/22 9:51 PM, Andy Shevchenko wrote:

> >>>>> It'd certainly be good to name anything that doesn't correspond to one
> >>>>> of the existing semantics for the API (!) something different rather
> >>>>> than adding yet another potentially overloaded meaning.
> >>>>
> >>>> It seems we're (at least) three who agree about this. Here is a patch
> >>>> fixing the name.
> >>>
> >>> And similar number of people are on the other side.
> >>
> >> If someone already opposed to the renaming (and not only the name) I
> >> must have missed that.
> >>
> >> So you think it's a good idea to keep the name
> >> platform_get_irq_optional() despite the "not found" value returned by it
> >> isn't usable as if it were a normal irq number?
> >
> > I meant that on the other side people who are in favour of Sergey's patch.
> > Since that I commented already that I opposed the renaming being a standalone
> > change.
> >
> > Do you agree that we have several issues with platform_get_irq*() APIs?
> >
> > 1. The unfortunate naming
>
> Mmm, "what's in a name?"... is this the topmost prio issue?

The order is arbitrary.

> > 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0
>
> This is the most severe issue, I think...
>
> > 3. The specific cookie for "IRQ not found, while no error happened" case

--
With Best Regards,
Andy Shevchenko


2022-01-21 21:09:15

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Wed, Jan 19, 2022 at 08:51:29PM +0200, Andy Shevchenko wrote:
> On Sat, Jan 15, 2022 at 04:45:39PM +0100, Uwe Kleine-K?nig wrote:
> > On Fri, Jan 14, 2022 at 03:04:38PM +0200, Andy Shevchenko wrote:
> > > On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> > > > > It'd certainly be good to name anything that doesn't correspond to one
> > > > > of the existing semantics for the API (!) something different rather
> > > > > than adding yet another potentially overloaded meaning.
> > > >
> > > > It seems we're (at least) three who agree about this. Here is a patch
> > > > fixing the name.
> > >
> > > And similar number of people are on the other side.
> >
> > If someone already opposed to the renaming (and not only the name) I
> > must have missed that.
> >
> > So you think it's a good idea to keep the name
> > platform_get_irq_optional() despite the "not found" value returned by it
> > isn't usable as if it were a normal irq number?
>
> I meant that on the other side people who are in favour of Sergey's patch.
> Since that I commented already that I opposed the renaming being a standalone
> change.
>
> Do you agree that we have several issues with platform_get_irq*() APIs?
>
> 1. The unfortunate naming

unfortunate naming for the currently implemented semantic, yes.

> 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0

I'm happy with the vIRQ0 handling. Today platform_get_irq() and it's
silent variant returns either a valid and usuable irq number or a
negative error value. That's totally fine.

> 3. The specific cookie for "IRQ not found, while no error happened" case

Not sure what you mean here. I have no problem that a situation I can
cope with is called an error for the query function. I just do error
handling and continue happily. So the part "while no error happened" is
irrelevant to me.

Additionally I see the problems:

4. The semantic as implemented in Sergey's patch isn't better than the
current one. platform_get_irq*() is still considerably different from
(clk|gpiod)_get* because the not-found value for the _optional variant
isn't usuable for the irq case. For clk and gpio I get rid of a whole if
branch, for irq I only change the if-condition. (And if that change is
considered good or bad seems to be subjective.)

For the idea to add a warning to platform_get_irq_optional for all but
-ENXIO (and -EPROBE_DEFER), I see the problem:

5. platform_get_irq*() issuing an error message is only correct most of
the time and given proper error handling in the caller (which might be
able to handle not only -ENXIO but maybe also -EINVAL[1]) the error message
is irritating. Today platform_get_irq() emits an error message for all
but -EPROBE_DEFER. As soon as we find a driver that handles -EINVAL we
need a function platform_get_irq_variant1 to be silent for -EINVAL,
-EPROBE_DEFER and -ENXIO (or platform_get_irq_variant2 that is only
silent for -EINVAL and -EPROBE_DEFER?)

IMHO a query function should always be silent and let the caller do the
error handling. And if it's only because

mydev: IRQ index 0 not found

is worse than

mydev: neither TX irq not a muxed RX/TX irq found

. Also "index 0" is irritating for devices that are expected to have
only a single irq (i.e. the majority of all devices).

Yes, I admit, we can safe some code by pushing the error message in a
query function. But that doesn't only have advantages.

Best regards
Uwe

[1] Looking through the source I wonder: What are the errors that can happen
in platform_get_irq*()? (calling everything but a valid irq number
an error) Looking at many callers, they only seem to expect "not
found" and some "probe defer" (even platform_get_irq() interprets
everything but -EPROBE_DEFER as "IRQ index %u not found\n".)
IMHO before we should consider to introduce a platform_get_irq*()
variant with improved semantics, some cleanup in the internals of
the irq lookup are necessary.

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | https://www.pengutronix.de/ |


Attachments:
(No filename) (4.12 kB)
signature.asc (499.00 B)
Download all attachments

2022-01-21 21:40:19

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 1/2] platform: make platform_get_irq_optional() optional

On 1/17/22 4:08 PM, Geert Uytterhoeven wrote:

[...]
>>> But as we were all in a hurry to kill the non-applicable error
>>> message, we went for the quick and dirty fix.
>>>
>>>> Also I fail to see how a caller of (today's) platform_get_irq_optional()
>>>> is simpler than a caller of platform_get_irq() given that there is no
>>>> semantic difference between the two. Please show me a single
>>>> conversion from platform_get_irq to platform_get_irq_optional that
>>>> yielded a simplification.
>>>
>>> That's exactly why we want to change the latter to return 0 ;-)
>>
>> OK. So you agree to my statement "The reason for
>> platform_get_irq_optional()'s existence is just that platform_get_irq()
>> emits an error message [...]". Actually you don't want to oppose but
>> say: It's unfortunate that the silent variant of platform_get_irq() took
>> the obvious name of a function that could have an improved return code
>> semantic.
>>
>> So my suggestion to rename todays platform_get_irq_optional() to
>> platform_get_irq_silently() and then introducing
>> platform_get_irq_optional() with your suggested semantic seems
>> intriguing and straigt forward to me.
>
> I don't really see the point of needing platform_get_irq_silently(),
> unless as an intermediary step, where it's going to be removed again
> once the conversion has completed.
> Still, the rename would touch all users at once anyway.
>
>> Another thought: platform_get_irq emits an error message for all
>> problems. Wouldn't it be consistent to let platform_get_irq_optional()
>> emit an error message for all problems but "not found"?
>> Alternatively remove the error printk from platform_get_irq().
>
> Yes, all problems but not found are real errors.

ACK for using dev_err_probe() in platfrom_get_irq_optional()
for the real errors...
I've also noted that only platfrom_get_irq_optional() got converted
from dev_err() to dev_err_probe() but not platfrom_get_irq_byname_optional()...

[...]

> Gr{oetje,eeting}s,
>
> Geert

MBR, Sergey

2022-01-24 19:26:42

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Thu, Jan 20, 2022 at 08:57:18AM +0100, Uwe Kleine-K?nig wrote:
> On Wed, Jan 19, 2022 at 08:51:29PM +0200, Andy Shevchenko wrote:
> > On Sat, Jan 15, 2022 at 04:45:39PM +0100, Uwe Kleine-K?nig wrote:
> > > On Fri, Jan 14, 2022 at 03:04:38PM +0200, Andy Shevchenko wrote:
> > > > On Thu, Jan 13, 2022 at 08:43:58PM +0100, Uwe Kleine-K?nig wrote:
> > > > > > It'd certainly be good to name anything that doesn't correspond to one
> > > > > > of the existing semantics for the API (!) something different rather
> > > > > > than adding yet another potentially overloaded meaning.
> > > > >
> > > > > It seems we're (at least) three who agree about this. Here is a patch
> > > > > fixing the name.
> > > >
> > > > And similar number of people are on the other side.
> > >
> > > If someone already opposed to the renaming (and not only the name) I
> > > must have missed that.
> > >
> > > So you think it's a good idea to keep the name
> > > platform_get_irq_optional() despite the "not found" value returned by it
> > > isn't usable as if it were a normal irq number?
> >
> > I meant that on the other side people who are in favour of Sergey's patch.
> > Since that I commented already that I opposed the renaming being a standalone
> > change.
> >
> > Do you agree that we have several issues with platform_get_irq*() APIs?
> >
> > 1. The unfortunate naming
>
> unfortunate naming for the currently implemented semantic, yes.

Yes.

> > 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0
>
> I'm happy with the vIRQ0 handling. Today platform_get_irq() and it's
> silent variant returns either a valid and usuable irq number or a
> negative error value. That's totally fine.

It might return 0.
Actually it seems that the WARN() can only be issued in two cases:
- SPARC with vIRQ0 in one of the array member
- fallback to ACPI for GPIO IRQ resource with index 0

But the latter is bogus, because it would mean a bug in the ACPI code.

The bottom line here is the SPARC case. Anybody familiar with the platform
can shed a light on this. If there is no such case, we may remove warning
along with ret = 0 case from platfrom_get_irq().

> > 3. The specific cookie for "IRQ not found, while no error happened" case
>
> Not sure what you mean here. I have no problem that a situation I can
> cope with is called an error for the query function. I just do error
> handling and continue happily. So the part "while no error happened" is
> irrelevant to me.

I meant that instead of using special error code, 0 is very much good for
the cases when IRQ is not found. It allows to distinguish -ENXIO from the
low layer from -ENXIO with this magic meaning.

> Additionally I see the problems:
>
> 4. The semantic as implemented in Sergey's patch isn't better than the
> current one.

I disagree on this. See above on why.

> platform_get_irq*() is still considerably different from
> (clk|gpiod)_get* because the not-found value for the _optional variant
> isn't usuable for the irq case. For clk and gpio I get rid of a whole if
> branch, for irq I only change the if-condition. (And if that change is
> considered good or bad seems to be subjective.)

You are mixing up two things:
- semantics of the pointer
- semantics of the cookie

Like I said previously the mistake is in putting an equal sign between apples
and oranges (or in terms of Python, which is a good example here, None and
False objects, where in both case 0 is magic and Python `if X`, `while `X` will
work in the same way, the `typeof(X)` is different semantically).

> For the idea to add a warning to platform_get_irq_optional for all but
> -ENXIO (and -EPROBE_DEFER), I see the problem:
>
> 5. platform_get_irq*() issuing an error message is only correct most of
> the time and given proper error handling in the caller (which might be
> able to handle not only -ENXIO but maybe also -EINVAL[1]) the error message
> is irritating. Today platform_get_irq() emits an error message for all
> but -EPROBE_DEFER. As soon as we find a driver that handles -EINVAL we
> need a function platform_get_irq_variant1 to be silent for -EINVAL,
> -EPROBE_DEFER and -ENXIO (or platform_get_irq_variant2 that is only
> silent for -EINVAL and -EPROBE_DEFER?)
>
> IMHO a query function should always be silent and let the caller do the
> error handling. And if it's only because
>
> mydev: IRQ index 0 not found
>
> is worse than
>
> mydev: neither TX irq not a muxed RX/TX irq found
>
> . Also "index 0" is irritating for devices that are expected to have
> only a single irq (i.e. the majority of all devices).

Yeah, ack the #5.

> Yes, I admit, we can safe some code by pushing the error message in a
> query function. But that doesn't only have advantages.

> [1] Looking through the source I wonder: What are the errors that can happen
> in platform_get_irq*()? (calling everything but a valid irq number
> an error) Looking at many callers, they only seem to expect "not
> found" and some "probe defer" (even platform_get_irq() interprets
> everything but -EPROBE_DEFER as "IRQ index %u not found\n".)
> IMHO before we should consider to introduce a platform_get_irq*()
> variant with improved semantics, some cleanup in the internals of
> the irq lookup are necessary.

--
With Best Regards,
Andy Shevchenko


2022-01-24 21:54:17

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

Hello!

On 1/24/22 6:01 PM, Andy Shevchenko wrote:

>>>>>>> It'd certainly be good to name anything that doesn't correspond to one
>>>>>>> of the existing semantics for the API (!) something different rather
>>>>>>> than adding yet another potentially overloaded meaning.
>>>>>>
>>>>>> It seems we're (at least) three who agree about this. Here is a patch
>>>>>> fixing the name.
>>>>>
>>>>> And similar number of people are on the other side.
>>>>
>>>> If someone already opposed to the renaming (and not only the name) I
>>>> must have missed that.
>>>>
>>>> So you think it's a good idea to keep the name
>>>> platform_get_irq_optional() despite the "not found" value returned by it
>>>> isn't usable as if it were a normal irq number?
>>>
>>> I meant that on the other side people who are in favour of Sergey's patch.
>>> Since that I commented already that I opposed the renaming being a standalone
>>> change.
>>>
>>> Do you agree that we have several issues with platform_get_irq*() APIs?
[...]
>>> 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0
>>
>> I'm happy with the vIRQ0 handling. Today platform_get_irq() and it's
>> silent variant returns either a valid and usuable irq number or a
>> negative error value. That's totally fine.
>
> It might return 0.
> Actually it seems that the WARN() can only be issued in two cases:
> - SPARC with vIRQ0 in one of the array member
> - fallback to ACPI for GPIO IRQ resource with index 0

You have probably missed the recent discovery that arch/sh/boards/board-aps4*.c
causes IRQ0 to be passed as a direct IRQ resource?

> But the latter is bogus, because it would mean a bug in the ACPI code.

Worth changing >= 0 to > 0 there, maybe?

> The bottom line here is the SPARC case. Anybody familiar with the platform
> can shed a light on this. If there is no such case, we may remove warning
> along with ret = 0 case from platfrom_get_irq().

I'm afraid you're too fast here... :-)
We'll have a really hard time if we continue to allow IRQ0 to be returned by
platform_get_irq() -- we'll have oto fileter it out in the callers then...

>>> 3. The specific cookie for "IRQ not found, while no error happened" case
>>
>> Not sure what you mean here. I have no problem that a situation I can
>> cope with is called an error for the query function. I just do error
>> handling and continue happily. So the part "while no error happened" is
>> irrelevant to me.
>
> I meant that instead of using special error code, 0 is very much good for
> the cases when IRQ is not found. It allows to distinguish -ENXIO from the
> low layer from -ENXIO with this magic meaning.

I don't see how -ENXIO can trickle from the lower layers, frankly...

[...]

MBR, Sergey

2022-01-25 09:30:40

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

Hi Sergey,

On Mon, Jan 24, 2022 at 10:02 PM Sergey Shtylyov <[email protected]> wrote:
> On 1/24/22 6:01 PM, Andy Shevchenko wrote:
> >>>>>>> It'd certainly be good to name anything that doesn't correspond to one
> >>>>>>> of the existing semantics for the API (!) something different rather
> >>>>>>> than adding yet another potentially overloaded meaning.
> >>>>>>
> >>>>>> It seems we're (at least) three who agree about this. Here is a patch
> >>>>>> fixing the name.
> >>>>>
> >>>>> And similar number of people are on the other side.
> >>>>
> >>>> If someone already opposed to the renaming (and not only the name) I
> >>>> must have missed that.
> >>>>
> >>>> So you think it's a good idea to keep the name
> >>>> platform_get_irq_optional() despite the "not found" value returned by it
> >>>> isn't usable as if it were a normal irq number?
> >>>
> >>> I meant that on the other side people who are in favour of Sergey's patch.
> >>> Since that I commented already that I opposed the renaming being a standalone
> >>> change.
> >>>
> >>> Do you agree that we have several issues with platform_get_irq*() APIs?
> [...]
> >>> 2. The vIRQ0 handling: a) WARN() followed by b) returned value 0
> >>
> >> I'm happy with the vIRQ0 handling. Today platform_get_irq() and it's
> >> silent variant returns either a valid and usuable irq number or a
> >> negative error value. That's totally fine.
> >
> > It might return 0.
> > Actually it seems that the WARN() can only be issued in two cases:
> > - SPARC with vIRQ0 in one of the array member
> > - fallback to ACPI for GPIO IRQ resource with index 0
>
> You have probably missed the recent discovery that arch/sh/boards/board-aps4*.c
> causes IRQ0 to be passed as a direct IRQ resource?

So far no one reported seeing the big fat warning ;-)

> > The bottom line here is the SPARC case. Anybody familiar with the platform
> > can shed a light on this. If there is no such case, we may remove warning
> > along with ret = 0 case from platfrom_get_irq().
>
> I'm afraid you're too fast here... :-)
> We'll have a really hard time if we continue to allow IRQ0 to be returned by
> platform_get_irq() -- we'll have oto fileter it out in the callers then...

So far no one reported seeing the big fat warning?

> >>> 3. The specific cookie for "IRQ not found, while no error happened" case
> >>
> >> Not sure what you mean here. I have no problem that a situation I can
> >> cope with is called an error for the query function. I just do error
> >> handling and continue happily. So the part "while no error happened" is
> >> irrelevant to me.
> >
> > I meant that instead of using special error code, 0 is very much good for
> > the cases when IRQ is not found. It allows to distinguish -ENXIO from the
> > low layer from -ENXIO with this magic meaning.
>
> I don't see how -ENXIO can trickle from the lower layers, frankly...

It might one day, leading to very hard to track bugs.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-01-25 17:34:29

by Matthias Schiffer

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Tue, 2022-01-25 at 09:25 +0100, Geert Uytterhoeven wrote:
> Hi Sergey,
>
> On Mon, Jan 24, 2022 at 10:02 PM Sergey Shtylyov <[email protected]>
> wrote:
> > On 1/24/22 6:01 PM, Andy Shevchenko wrote:
> > > > > > > > > It'd certainly be good to name anything that doesn't
> > > > > > > > > correspond to one
> > > > > > > > > of the existing semantics for the API (!) something
> > > > > > > > > different rather
> > > > > > > > > than adding yet another potentially overloaded
> > > > > > > > > meaning.
> > > > > > > >
> > > > > > > > It seems we're (at least) three who agree about this.
> > > > > > > > Here is a patch
> > > > > > > > fixing the name.
> > > > > > >
> > > > > > > And similar number of people are on the other side.
> > > > > >
> > > > > > If someone already opposed to the renaming (and not only
> > > > > > the name) I
> > > > > > must have missed that.
> > > > > >
> > > > > > So you think it's a good idea to keep the name
> > > > > > platform_get_irq_optional() despite the "not found" value
> > > > > > returned by it
> > > > > > isn't usable as if it were a normal irq number?
> > > > >
> > > > > I meant that on the other side people who are in favour of
> > > > > Sergey's patch.
> > > > > Since that I commented already that I opposed the renaming
> > > > > being a standalone
> > > > > change.
> > > > >
> > > > > Do you agree that we have several issues with
> > > > > platform_get_irq*() APIs?
> > [...]
> > > > > 2. The vIRQ0 handling: a) WARN() followed by b) returned
> > > > > value 0
> > > >
> > > > I'm happy with the vIRQ0 handling. Today platform_get_irq() and
> > > > it's
> > > > silent variant returns either a valid and usuable irq number or
> > > > a
> > > > negative error value. That's totally fine.
> > >
> > > It might return 0.
> > > Actually it seems that the WARN() can only be issued in two
> > > cases:
> > > - SPARC with vIRQ0 in one of the array member
> > > - fallback to ACPI for GPIO IRQ resource with index 0
> >
> > You have probably missed the recent discovery that
> > arch/sh/boards/board-aps4*.c
> > causes IRQ0 to be passed as a direct IRQ resource?
>
> So far no one reported seeing the big fat warning ;-)

FWIW, we had a similar issue with an IRQ resource passed from the
tqmx86 MFD driver do the GPIO driver, which we noticed due to this
warning, and which was fixed
in a946506c48f3bd09363c9d2b0a178e55733bcbb6
and 9b87f43537acfa24b95c236beba0f45901356eb2.
I believe these changes are what promted this whole discussion and led
to my "Reported-by" on the patch?

It is not entirely clear to me when IRQ 0 is valid and when it isn't,
but the warning seems useful to me. Maybe it would make more sense to
warn when such an IRQ resource is registered for a platform device, and
not when it is looked up?

My opinion is that it would be very confusing if there are any places
in the kernel (on some platforms) where IRQ 0 is valid, but for
platform_get_irq() it would suddenly mean "not found". Keeping a
negative return value seems preferable to me for this reason.

(An alternative, more involved idea would be to add 1 to all IRQ
"cookies", so IRQ 0 would return 1, leaving 0 as a special value. I
have absolutely no idea how big the API surface is that would need
changes, and it is likely not worth the effort at all.)


>
> > > The bottom line here is the SPARC case. Anybody familiar with the
> > > platform
> > > can shed a light on this. If there is no such case, we may remove
> > > warning
> > > along with ret = 0 case from platfrom_get_irq().
> >
> > I'm afraid you're too fast here... :-)
> > We'll have a really hard time if we continue to allow IRQ0 to be
> > returned by
> > platform_get_irq() -- we'll have oto fileter it out in the callers
> > then...
>
> So far no one reported seeing the big fat warning?
>
> > > > > 3. The specific cookie for "IRQ not found, while no error
> > > > > happened" case
> > > >
> > > > Not sure what you mean here. I have no problem that a situation
> > > > I can
> > > > cope with is called an error for the query function. I just do
> > > > error
> > > > handling and continue happily. So the part "while no error
> > > > happened" is
> > > > irrelevant to me.
> > >
> > > I meant that instead of using special error code, 0 is very much
> > > good for
> > > the cases when IRQ is not found. It allows to distinguish -ENXIO
> > > from the
> > > low layer from -ENXIO with this magic meaning.
> >
> > I don't see how -ENXIO can trickle from the lower layers,
> > frankly...
>
> It might one day, leading to very hard to track bugs.

As gregkh noted, changing the return value without also making the
compile fail will be a huge PITA whenever driver patches are back- or
forward-ported, as it would require subtle changes in error paths,
which can easily slip through unnoticed, in particular with half-
automated stable backports.

Even if another return value like -ENODEV might be better aligned with
...regulator_get_optional() and similar functions, or we even find a
way to make 0 usable for this, none of the proposed changes strike me
as big enough a win to outweigh the churn caused by making such a
change at all.

Kind regards,
Matthias



>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 --
> [email protected]
>
> In personal conversations with technical people, I call myself a
> hacker. But
> when I'm talking to journalists I just say "programmer" or something
> like that.
> -- Linus Torvalds

2022-01-25 20:01:13

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH] driver core: platform: Rename platform_get_irq_optional() to platform_get_irq_silent()

On Tue, Jan 25, 2022 at 01:56:05PM +0100, Matthias Schiffer wrote:
> On Tue, 2022-01-25 at 09:25 +0100, Geert Uytterhoeven wrote:
> > On Mon, Jan 24, 2022 at 10:02 PM Sergey Shtylyov <[email protected]>
> > wrote:
> > > On 1/24/22 6:01 PM, Andy Shevchenko wrote:

...

> > > > > > 2. The vIRQ0 handling: a) WARN() followed by b) returned
> > > > > > value 0
> > > > >
> > > > > I'm happy with the vIRQ0 handling. Today platform_get_irq() and
> > > > > it's
> > > > > silent variant returns either a valid and usuable irq number or
> > > > > a
> > > > > negative error value. That's totally fine.
> > > >
> > > > It might return 0.
> > > > Actually it seems that the WARN() can only be issued in two
> > > > cases:
> > > > - SPARC with vIRQ0 in one of the array member
> > > > - fallback to ACPI for GPIO IRQ resource with index 0
> > >
> > > You have probably missed the recent discovery that
> > > arch/sh/boards/board-aps4*.c
> > > causes IRQ0 to be passed as a direct IRQ resource?
> >
> > So far no one reported seeing the big fat warning ;-)
>
> FWIW, we had a similar issue with an IRQ resource passed from the
> tqmx86 MFD driver do the GPIO driver, which we noticed due to this
> warning, and which was fixed
> in a946506c48f3bd09363c9d2b0a178e55733bcbb6
> and 9b87f43537acfa24b95c236beba0f45901356eb2.

No, it's not, unfortunately :-( You just band aided the warning issue, but the
root cause is the WARN() and possibility to see valid (v)IRQ0 in the resources.
See below.

> I believe these changes are what promted this whole discussion and led
> to my "Reported-by" on the patch?
>
> It is not entirely clear to me when IRQ 0 is valid and when it isn't,
> but the warning seems useful to me. Maybe it would make more sense to
> warn when such an IRQ resource is registered for a platform device, and
> not when it is looked up?
>
> My opinion is that it would be very confusing if there are any places
> in the kernel (on some platforms) where IRQ 0 is valid,

And those places are board files like yours :( They have to be fixed
eventually. Ideally by using IRQ domains. At least that's how it's
done elsewhere.

> but for
> platform_get_irq() it would suddenly mean "not found". Keeping a
> negative return value seems preferable to me for this reason.

IRQ 0 is valid, vIRQ0 (or read it as cookie) is not.

Now, the problem in your case is that you are talking about board files, while
ACPI and DT never gives resource with vIRQ0. For board files some (legacy) code
decides that it's fine to supply HW IRQ, while the de facto case is that
platform_get_resource() returns whatever is in the resource, while
platform_get_irq() should return a cookie.

> (An alternative, more involved idea would be to add 1 to all IRQ
> "cookies", so IRQ 0 would return 1, leaving 0 as a special value. I
> have absolutely no idea how big the API surface is that would need
> changes, and it is likely not worth the effort at all.)

This is what IRQ domains do, they start vIRQs from 1.

> > > > The bottom line here is the SPARC case. Anybody familiar with the
> > > > platform
> > > > can shed a light on this. If there is no such case, we may remove
> > > > warning
> > > > along with ret = 0 case from platfrom_get_irq().
> > >
> > > I'm afraid you're too fast here... :-)
> > > We'll have a really hard time if we continue to allow IRQ0 to be
> > > returned by
> > > platform_get_irq() -- we'll have oto fileter it out in the callers
> > > then...
> >
> > So far no one reported seeing the big fat warning?
> >
> > > > > > 3. The specific cookie for "IRQ not found, while no error
> > > > > > happened" case
> > > > >
> > > > > Not sure what you mean here. I have no problem that a situation
> > > > > I can
> > > > > cope with is called an error for the query function. I just do
> > > > > error
> > > > > handling and continue happily. So the part "while no error
> > > > > happened" is
> > > > > irrelevant to me.
> > > >
> > > > I meant that instead of using special error code, 0 is very much
> > > > good for
> > > > the cases when IRQ is not found. It allows to distinguish -ENXIO
> > > > from the
> > > > low layer from -ENXIO with this magic meaning.
> > >
> > > I don't see how -ENXIO can trickle from the lower layers,
> > > frankly...
> >
> > It might one day, leading to very hard to track bugs.
>
> As gregkh noted, changing the return value without also making the
> compile fail will be a huge PITA whenever driver patches are back- or
> forward-ported, as it would require subtle changes in error paths,
> which can easily slip through unnoticed, in particular with half-
> automated stable backports.

Let's not modify kernel at all then, because in many cases it is a PITA
for back- or forward-porting :-)

> Even if another return value like -ENODEV might be better aligned with
> ...regulator_get_optional() and similar functions, or we even find a
> way to make 0 usable for this, none of the proposed changes strike me
> as big enough a win to outweigh the churn caused by making such a
> change at all.

Yeah, let's continue to suffer from ugly interface and see more band aids
landing around...

--
With Best Regards,
Andy Shevchenko