[PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power gate

Shenwei Wang Shenwei.Wang at freescale.com
Thu Aug 20 07:48:43 PDT 2015


3rd Ping.

Shenwei

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015年8月12日 10:47
> To: gregkh at linuxfoundation.org; arnd at arndb.de
> Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> 
> 2nd Ping.
> 
> Regards,
> Shenwei
> 
> > -----Original Message-----
> > From: linux-arm-kernel
> > [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of
> > Shenwei Wang
> > Sent: 2015年7月30日 11:11
> > To: gregkh at linuxfoundation.org; arnd at arndb.de
> > Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> > Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> > power gate
> >
> > When system goes into low power states like SUSPEND_MEM and
> > HIBERNATION, the hardware IP block may be powered off to reduce the power
> consumption.
> > This power down will lost all the data inside the ram. This patch
> > added the dev_pm_ops and implemented two callbacks: suspend_noirq and
> > resume_noirq, which will save the data in the on-chip-ram right before
> > power down and restore it after system resumes.
> >
> > A new property string named "can-power-gate" is added to the
> > devicetree bindings too.
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> > Signed-off-by: Anson Huang <b20788 at freescale.com>
> > ---
> > Change log:
> >
> > PATCH v3
> > 	Removed the unnecessary clk_enable/clk_disable.
> >
> > PATCH v2
> > 	Use vmalloc to allocate the SRAM backup memory.
> > 	Code clean up.
> >
> >  Documentation/devicetree/bindings/misc/sram.txt |  2 ++
> >  drivers/misc/sram.c                             | 42
> > +++++++++++++++++++++++++
> >  2 files changed, 44 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> > b/Documentation/devicetree/bindings/misc/sram.txt
> > index 36cbe5a..1170086 100644
> > --- a/Documentation/devicetree/bindings/misc/sram.txt
> > +++ b/Documentation/devicetree/bindings/misc/sram.txt
> > @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> >
> >  - compatible : standard definition, should contain a vendor specific string
> >                 in the form <vendor>,[<device>-]<usage>
> > +- can-power-gate: a property to tell the driver that the sram can support
> > +		power gate
> >
> >  Example:
> >
> > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index
> > 15c33cc..db9f1fa
> > 100644
> > --- a/drivers/misc/sram.c
> > +++ b/drivers/misc/sram.c
> > @@ -30,7 +30,9 @@
> >
> >  struct sram_dev {
> >  	struct device *dev;
> > +	void *power_off_save;
> >  	void __iomem *virt_base;
> > +	u32 size;
> >
> >  	struct gen_pool *pool;
> >  	struct clk *clk;
> > @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev
> > *sram, struct resource *res)
> >  	return ret;
> >  }
> >
> > +static int sram_suspend_noirq(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct sram_dev *sram = platform_get_drvdata(pdev);
> > +
> > +	if (!sram->power_off_save)
> > +		return 0;
> > +
> > +	/* Save necessary regs */
> > +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> > +
> > +	return 0;
> > +}
> > +
> > +static int sram_resume_noirq(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct sram_dev *sram = platform_get_drvdata(pdev);
> > +
> > +	if (!sram->power_off_save)
> > +		return 0;
> > +
> > +	memcpy(sram->virt_base, sram->power_off_save, sram->size);
> > +
> > +	return 0;
> > +}
> > +
> >  static int sram_probe(struct platform_device *pdev)  {
> >  	struct sram_dev *sram;
> > @@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
> >  	}
> >
> >  	size = resource_size(res);
> > +	sram->size = size;
> >
> >  	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
> >  		dev_err(sram->dev, "could not request region for resource\n"); @@
> > -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)
> >
> >  	platform_set_drvdata(pdev, sram);
> >
> > +	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
> > +		sram->power_off_save = vmalloc(size);
> > +
> >  	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
> >  		gen_pool_size(sram->pool) / 1024, sram->virt_base);
> >
> > @@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
> >  	if (sram->clk)
> >  		clk_disable_unprepare(sram->clk);
> >
> > +	if (sram->power_off_save)
> > +		vfree(sram->power_off_save);
> > +
> >  	return 0;
> >  }
> >
> > @@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] =
> > {  }; #endif
> >
> > +static const struct dev_pm_ops sram_pm_ops = {
> > +	.suspend_noirq = sram_suspend_noirq,
> > +	.resume_noirq = sram_resume_noirq,
> > +};
> > +
> >  static struct platform_driver sram_driver = {
> >  	.driver = {
> >  		.name = "sram",
> >  		.of_match_table = of_match_ptr(sram_dt_ids),
> > +		.pm	= &sram_pm_ops,
> >  	},
> >  	.probe = sram_probe,
> >  	.remove = sram_remove,
> > --
> > 2.5.0.rc2
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


More information about the linux-arm-kernel mailing list