Message ID | 20240131141653.2689260-2-jarkko.nikula@linux.intel.com |
---|---|
State | Superseded |
Headers | show |
Series | i2c: designware: Generic polling mode code | expand |
On Wed, Jan 31, 2024 at 04:16:47PM +0200, Jarkko Nikula wrote: > Currently initialization flow in i2c_dw_probe_master() skips a few steps > and has code duplication for polling mode implementation. > > Simplify this by adding a new ACCESS_POLLING flag that is set for those > two platforms that currently use polling mode and use it to skip > interrupt handler setup. ... > #define ACCESS_INTR_MASK BIT(0) > #define ACCESS_NO_IRQ_SUSPEND BIT(1) > #define ARBITRATION_SEMAPHORE BIT(2) > +#define ACCESS_POLLING BIT(3) For the sake of consistency, you may incorporate internal patch from somebody else to move to the same prefix (namespace) for ARBITRATION_SEMAPHORE. ... > + if (!(dev->flags & ACCESS_POLLING)) { Actually seems to me that is better to have in a separate helper and you then can do here something like ret = i2c_dw_request_irq(...); if (ret) return ret; > + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, > + irq_flags, dev_name(dev->dev), dev); > + if (ret) { > + dev_err(dev->dev, "failure requesting irq %i: %d\n", > + dev->irq, ret); > + return ret; > + }
Hi Andy, > > + if (!(dev->flags & ACCESS_POLLING)) { > > Actually seems to me that is better to have in a separate helper and you > then can do here something like > > ret = i2c_dw_request_irq(...); > if (ret) > return ret; I find it a bit misleading because the first question that comes to mind upon reading such a line is, 'What if access is polling?' without looking inside the function. In this case, a more appropriate name would then be i2c_sw_request_irq_if_needed(). :) Andi
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index a7f6f3eafad7..78c8062a8eb5 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -303,6 +303,7 @@ struct dw_i2c_dev { #define ACCESS_INTR_MASK BIT(0) #define ACCESS_NO_IRQ_SUSPEND BIT(1) #define ARBITRATION_SEMAPHORE BIT(2) +#define ACCESS_POLLING BIT(3) #define MODEL_MSCC_OCELOT BIT(8) #define MODEL_BAIKAL_BT1 BIT(9) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 85dbd0eb5392..e879a0f5cc97 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -953,31 +953,6 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) return 0; } -static int i2c_dw_poll_adap_quirk(struct dw_i2c_dev *dev) -{ - struct i2c_adapter *adap = &dev->adapter; - int ret; - - pm_runtime_get_noresume(dev->dev); - ret = i2c_add_numbered_adapter(adap); - if (ret) - dev_err(dev->dev, "Failed to add adapter: %d\n", ret); - pm_runtime_put_noidle(dev->dev); - - return ret; -} - -static bool i2c_dw_is_model_poll(struct dw_i2c_dev *dev) -{ - switch (dev->flags & MODEL_MASK) { - case MODEL_AMD_NAVI_GPU: - case MODEL_WANGXUN_SP: - return true; - default: - return false; - } -} - int i2c_dw_probe_master(struct dw_i2c_dev *dev) { struct i2c_adapter *adap = &dev->adapter; @@ -1033,9 +1008,6 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) adap->dev.parent = dev->dev; i2c_set_adapdata(adap, dev); - if (i2c_dw_is_model_poll(dev)) - return i2c_dw_poll_adap_quirk(dev); - if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { irq_flags = IRQF_NO_SUSPEND; } else { @@ -1049,12 +1021,14 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) regmap_write(dev->map, DW_IC_INTR_MASK, 0); i2c_dw_release_lock(dev); - ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, - dev_name(dev->dev), dev); - if (ret) { - dev_err(dev->dev, "failure requesting irq %i: %d\n", - dev->irq, ret); - return ret; + if (!(dev->flags & ACCESS_POLLING)) { + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, + irq_flags, dev_name(dev->dev), dev); + if (ret) { + dev_err(dev->dev, "failure requesting irq %i: %d\n", + dev->irq, ret); + return ret; + } } ret = i2c_dw_init_recovery_info(dev); diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 61d7a27aa070..9be9a2658e1f 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -154,7 +154,7 @@ static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) { struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev); - dev->flags |= MODEL_AMD_NAVI_GPU; + dev->flags |= MODEL_AMD_NAVI_GPU | ACCESS_POLLING; dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; return 0; } diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 855b698e99c0..4ab41ba39d55 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -290,7 +290,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) dev->flags = (uintptr_t)device_get_match_data(&pdev->dev); if (device_property_present(&pdev->dev, "wx,i2c-snps-model")) - dev->flags = MODEL_WANGXUN_SP; + dev->flags = MODEL_WANGXUN_SP | ACCESS_POLLING; dev->dev = &pdev->dev; dev->irq = irq;
Currently initialization flow in i2c_dw_probe_master() skips a few steps and has code duplication for polling mode implementation. Simplify this by adding a new ACCESS_POLLING flag that is set for those two platforms that currently use polling mode and use it to skip interrupt handler setup. Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> --- drivers/i2c/busses/i2c-designware-core.h | 1 + drivers/i2c/busses/i2c-designware-master.c | 42 ++++----------------- drivers/i2c/busses/i2c-designware-pcidrv.c | 2 +- drivers/i2c/busses/i2c-designware-platdrv.c | 2 +- 4 files changed, 11 insertions(+), 36 deletions(-)