Message ID | 20240916134928.3654054-8-alexander.usyskin@intel.com |
---|---|
State | New |
Headers | show |
Series | spi: add driver for Intel discrete graphics | expand |
On Mon, Sep 16, 2024 at 04:49:23PM +0300, Alexander Usyskin wrote: > Enable runtime PM in spi driver to notify graphics driver that > whole card should be kept awake while spi operations are > performed through this driver. > > CC: Lucas De Marchi <lucas.demarchi@intel.com> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> > --- > drivers/spi/spi-intel-dg.c | 44 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/drivers/spi/spi-intel-dg.c b/drivers/spi/spi-intel-dg.c > index c76b0a70f8d8..a14fc3190520 100644 > --- a/drivers/spi/spi-intel-dg.c > +++ b/drivers/spi/spi-intel-dg.c > @@ -12,11 +12,14 @@ > #include <linux/module.h> > #include <linux/mtd/mtd.h> > #include <linux/mtd/partitions.h> > +#include <linux/pm_runtime.h> > #include <linux/string.h> > #include <linux/slab.h> > #include <linux/sizes.h> > #include <linux/types.h> > > +#define INTEL_DG_SPI_RPM_TIMEOUT 500 > + > struct intel_dg_spi { > struct kref refcnt; > struct mtd_info mtd; > @@ -471,6 +474,12 @@ static int intel_dg_spi_erase(struct mtd_info *mtd, struct erase_info *info) > total_len = info->len; > addr = info->addr; > > + ret = pm_runtime_resume_and_get(mtd->dev.parent); > + if (ret < 0) { > + dev_err(&mtd->dev, "rpm: get failed %d\n", ret); If I understood correctly, this is the device = &aux_dev->dev; which is the drm->pdev.dev ? This is to ensure that the graphics driver is not going to runtime suspend, right? > + return ret; > + } > + > mutex_lock(&spi->lock); > > while (total_len > 0) { > @@ -512,6 +521,8 @@ static int intel_dg_spi_erase(struct mtd_info *mtd, struct erase_info *info) > > out: > mutex_unlock(&spi->lock); > + pm_runtime_mark_last_busy(mtd->dev.parent); > + pm_runtime_put_autosuspend(mtd->dev.parent); > return ret; > } > > @@ -545,6 +556,12 @@ static int intel_dg_spi_read(struct mtd_info *mtd, loff_t from, size_t len, > if (len > spi->regions[idx].size - from) > len = spi->regions[idx].size - from; > > + ret = pm_runtime_resume_and_get(mtd->dev.parent); > + if (ret < 0) { > + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); > + return ret; > + } > + > mutex_lock(&spi->lock); > > ret = spi_read(spi, region, from, len, buf); > @@ -557,6 +574,8 @@ static int intel_dg_spi_read(struct mtd_info *mtd, loff_t from, size_t len, > *retlen = ret; > > mutex_unlock(&spi->lock); > + pm_runtime_mark_last_busy(mtd->dev.parent); > + pm_runtime_put_autosuspend(mtd->dev.parent); > return 0; > } > > @@ -590,6 +609,12 @@ static int intel_dg_spi_write(struct mtd_info *mtd, loff_t to, size_t len, > if (len > spi->regions[idx].size - to) > len = spi->regions[idx].size - to; > > + ret = pm_runtime_resume_and_get(mtd->dev.parent); > + if (ret < 0) { > + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); > + return ret; > + } > + > mutex_lock(&spi->lock); > > ret = spi_write(spi, region, to, len, buf); > @@ -602,6 +627,8 @@ static int intel_dg_spi_write(struct mtd_info *mtd, loff_t to, size_t len, > *retlen = ret; > > mutex_unlock(&spi->lock); > + pm_runtime_mark_last_busy(mtd->dev.parent); > + pm_runtime_put_autosuspend(mtd->dev.parent); > return 0; > } > > @@ -747,6 +774,17 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, > } > } > > + pm_runtime_enable(device); > + > + pm_runtime_set_autosuspend_delay(device, INTEL_DG_SPI_RPM_TIMEOUT); > + pm_runtime_use_autosuspend(device); If the above assumption is right, then I don't believe you should change the device settings in here. But if you tell me that this 'device' is the spi one, and not the graphics dgfx, then I believe this code would be missing the runtime pm suspend/resume functions. > + > + ret = pm_runtime_resume_and_get(device); > + if (ret < 0) { > + dev_err(device, "rpm: get failed %d\n", ret); > + goto err_norpm; > + } > + > spi->base = devm_ioremap_resource(device, &ispi->bar); > if (IS_ERR(spi->base)) { > dev_err(device, "mmio not mapped\n"); > @@ -769,9 +807,13 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, > > dev_set_drvdata(&aux_dev->dev, spi); > > + pm_runtime_put(device); > return 0; > > err: > + pm_runtime_put(device); > +err_norpm: > + pm_runtime_disable(device); > kref_put(&spi->refcnt, intel_dg_spi_release); > return ret; > } > @@ -783,6 +825,8 @@ static void intel_dg_spi_remove(struct auxiliary_device *aux_dev) > if (!spi) > return; > > + pm_runtime_disable(&aux_dev->dev); > + > mtd_device_unregister(&spi->mtd); > > dev_set_drvdata(&aux_dev->dev, NULL); > -- > 2.34.1 >
diff --git a/drivers/spi/spi-intel-dg.c b/drivers/spi/spi-intel-dg.c index c76b0a70f8d8..a14fc3190520 100644 --- a/drivers/spi/spi-intel-dg.c +++ b/drivers/spi/spi-intel-dg.c @@ -12,11 +12,14 @@ #include <linux/module.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <linux/pm_runtime.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/sizes.h> #include <linux/types.h> +#define INTEL_DG_SPI_RPM_TIMEOUT 500 + struct intel_dg_spi { struct kref refcnt; struct mtd_info mtd; @@ -471,6 +474,12 @@ static int intel_dg_spi_erase(struct mtd_info *mtd, struct erase_info *info) total_len = info->len; addr = info->addr; + ret = pm_runtime_resume_and_get(mtd->dev.parent); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %d\n", ret); + return ret; + } + mutex_lock(&spi->lock); while (total_len > 0) { @@ -512,6 +521,8 @@ static int intel_dg_spi_erase(struct mtd_info *mtd, struct erase_info *info) out: mutex_unlock(&spi->lock); + pm_runtime_mark_last_busy(mtd->dev.parent); + pm_runtime_put_autosuspend(mtd->dev.parent); return ret; } @@ -545,6 +556,12 @@ static int intel_dg_spi_read(struct mtd_info *mtd, loff_t from, size_t len, if (len > spi->regions[idx].size - from) len = spi->regions[idx].size - from; + ret = pm_runtime_resume_and_get(mtd->dev.parent); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); + return ret; + } + mutex_lock(&spi->lock); ret = spi_read(spi, region, from, len, buf); @@ -557,6 +574,8 @@ static int intel_dg_spi_read(struct mtd_info *mtd, loff_t from, size_t len, *retlen = ret; mutex_unlock(&spi->lock); + pm_runtime_mark_last_busy(mtd->dev.parent); + pm_runtime_put_autosuspend(mtd->dev.parent); return 0; } @@ -590,6 +609,12 @@ static int intel_dg_spi_write(struct mtd_info *mtd, loff_t to, size_t len, if (len > spi->regions[idx].size - to) len = spi->regions[idx].size - to; + ret = pm_runtime_resume_and_get(mtd->dev.parent); + if (ret < 0) { + dev_err(&mtd->dev, "rpm: get failed %zd\n", ret); + return ret; + } + mutex_lock(&spi->lock); ret = spi_write(spi, region, to, len, buf); @@ -602,6 +627,8 @@ static int intel_dg_spi_write(struct mtd_info *mtd, loff_t to, size_t len, *retlen = ret; mutex_unlock(&spi->lock); + pm_runtime_mark_last_busy(mtd->dev.parent); + pm_runtime_put_autosuspend(mtd->dev.parent); return 0; } @@ -747,6 +774,17 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, } } + pm_runtime_enable(device); + + pm_runtime_set_autosuspend_delay(device, INTEL_DG_SPI_RPM_TIMEOUT); + pm_runtime_use_autosuspend(device); + + ret = pm_runtime_resume_and_get(device); + if (ret < 0) { + dev_err(device, "rpm: get failed %d\n", ret); + goto err_norpm; + } + spi->base = devm_ioremap_resource(device, &ispi->bar); if (IS_ERR(spi->base)) { dev_err(device, "mmio not mapped\n"); @@ -769,9 +807,13 @@ static int intel_dg_spi_probe(struct auxiliary_device *aux_dev, dev_set_drvdata(&aux_dev->dev, spi); + pm_runtime_put(device); return 0; err: + pm_runtime_put(device); +err_norpm: + pm_runtime_disable(device); kref_put(&spi->refcnt, intel_dg_spi_release); return ret; } @@ -783,6 +825,8 @@ static void intel_dg_spi_remove(struct auxiliary_device *aux_dev) if (!spi) return; + pm_runtime_disable(&aux_dev->dev); + mtd_device_unregister(&spi->mtd); dev_set_drvdata(&aux_dev->dev, NULL);
Enable runtime PM in spi driver to notify graphics driver that whole card should be kept awake while spi operations are performed through this driver. CC: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> --- drivers/spi/spi-intel-dg.c | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)