This patchset has a bit of a history and some parts of it has been posted
earlier.
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/262725.html
I intentially didn't increase version number of the patches, since I think it
will cause more confusion than clarity.
A summary of changes since the last patchset (link above):
- Instead of letting driver core handling the device to power domain
binding/unbinding, follow the behavior of how the ACPI power domain
is handled.
This is a summary of what these patches are intended to do:
1)
Add generic power domain OF-based support which also includes APIs to handle
attach/detach of generic power domains to devices.
2)
Adding a common API to attach/detach power domains and include support for the
ACPI and the generic power domain in there.
3)
From subsystem level code, at probe/remove, convert from invoking the ACPI
specific power domain attach/detach functions to the new common attach/detach
APIs.
4)
Add support for the AMBA bus to attach/detach power domains, using the new
common APIs.
5)
Convert Exynos to use the new generic power domain OF support.
Obviously, there are dependencies througout this patchset, which means if they
get accepted the all need to go together.
Tomasz Figa (2):
PM / Domains: Add generic OF-based power domain look-up
ARM: exynos: Move to generic power domain bindings
Ulf Hansson (7):
ACPI / PM: Let acpi_dev_pm_detach() return an error code
PM / Domains: Add APIs to attach/detach a power domain for a device
drivercore / platform: Convert to dev_pm_domain_attach|detach()
i2c: core: Convert to dev_pm_domain_attach|detach()
mmc: sdio: Convert to dev_pm_domain_attach|detach()
spi: core: Convert to dev_pm_domain_attach|detach()
amba: Add support for attach/detach of power domains
.../bindings/arm/exynos/power_domain.txt | 13 +-
.../devicetree/bindings/power/power_domain.txt | 51 ++++
arch/arm/mach-exynos/pm_domains.c | 78 +-----
drivers/acpi/device_pm.c | 4 +
drivers/amba/bus.c | 10 +-
drivers/base/platform.c | 15 +-
drivers/base/power/common.c | 58 ++++
drivers/base/power/domain.c | 291 +++++++++++++++++++++
drivers/i2c/i2c-core.c | 13 +-
drivers/mmc/core/sdio_bus.c | 4 +-
drivers/spi/spi.c | 12 +-
include/linux/acpi.h | 7 +-
include/linux/pm.h | 14 +
include/linux/pm_domain.h | 46 ++++
kernel/power/Kconfig | 4 +
15 files changed, 514 insertions(+), 106 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt
--
1.9.1
To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/acpi/device_pm.c | 4 ++++
include/linux/acpi.h | 7 +++++--
2 files changed, 9 insertions(+), 2 deletions(-)
From: Tomasz Figa <redacted>
This patch introduces generic code to perform power domain look-up using
device tree and automatically bind devices to their power domains.
Generic device tree binding is introduced to specify power domains of
devices in their device tree nodes.
Backwards compatibility with legacy Samsung-specific power domain
bindings is provided, but for now the new code is not compiled when
CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
will change as soon as Exynos power domain code gets converted to use
the generic framework in further patch.
Signed-off-by: Tomasz Figa <redacted>
Signed-off-by: Ulf Hansson <redacted>
[Ulf:Add attach|detach functions]
---
.../devicetree/bindings/power/power_domain.txt | 51 ++++
drivers/base/power/domain.c | 291 +++++++++++++++++++++
include/linux/pm_domain.h | 46 ++++
kernel/power/Kconfig | 4 +
4 files changed, 392 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt
@@ -0,0 +1,51 @@+* Generic power domains++System on chip designs are often divided into multiple power domains that+can be used for power gating of selected IP blocks for power saving by+reduced leakage current.++This device tree binding can be used to bind power domain consumer devices+with their power domains provided by power domain providers. A power domain+provider can be represented by any node in the device tree and can provide+one or more power domains. A consumer node can refer to the provider by+a phandle and a set of phandle arguments (so called power domain specifier)+of length specified by #power-domain-cells property in the power domain+provider node.++==Power domain providers==++Required properties:+ - #power-domain-cells : Number of cells in a power domain specifier;+ Typically 0 for nodes representing a single power domain and 1 for nodes+ providing multiple power domains (e.g. power controllers), but can be+ any value as specified by device tree binding documentation of particular+ provider.++Example:++ power: power-controller at 12340000 {+ compatible = "foo,power-controller";+ reg = <0x12340000 0x1000>;+ #power-domain-cells = <1>;+ };++The node above defines a power controller that is a power domain provider+and expects one cell as its phandle argument.++==Power domain consumers==++Required properties:+ - power-domains : A phandle and power domain specifier as defined by bindings+ of power controller specified by phandle.++Example:++ leaky-device at 12350000 {+ compatible = "foo,i-leak-current";+ reg = <0x12350000 0x1000>;+ power-domains = <&power 0>;+ };++The node above defines a typical power domain consumer device, which is located+inside power domain with index 0 of power controller represented by node with+label "power".
@@ -2189,3 +2190,293 @@ void pm_genpd_init(struct generic_pm_domain *genpd,list_add(&genpd->gpd_list_node,&gpd_list);mutex_unlock(&gpd_list_lock);}++#ifdef CONFIG_PM_GENERIC_DOMAINS_OF+/*+*DeviceTreebasedpowerdomainproviders.+*+*Thecodebelowimplementsgenericdevicetreebasedpowerdomainproviders+*thatbinddevicetreenodeswithgenericpowerdomainsregisteredinthe+*system.+*+*Anydriverthatregistersgenericpowerdomainsandneedtosupportbinding+*ofdevicestothesedomainsissupposedtoregisterapowerdomainprovider,+*whichmapsapowerdomainspecifierretrievedfromdevicetreetoapower+*domain.+*+*Twosimplemappingfunctionshavebeenprovidedforconvenience:+*-of_genpd_xlate_simple()for1:1devicetreenodetodomainmapping,+*-of_genpd_xlate_onecell()formappingofmultipledomainspernode+*byindex.+*/++/**+*structof_genpd_provider-Powerdomainproviderregistrationstructure+*@link:Entryingloballistofdomainproviders+*@node:Pointertodevicetreenodeofdomainprovider+*@xlate:Provider-specificxlatecallbackmappingasetofspecifiercells+*intoapowerdomain.+*@data:contextpointertobepassedinto@xlatecallback+*/+structof_genpd_provider{+structlist_headlink;+structdevice_node*node;+genpd_xlate_txlate;+void*data;+};++/* List of registered power domain providers. */+staticLIST_HEAD(of_genpd_providers);+/* Mutex to protect the list above. */+staticDEFINE_MUTEX(of_genpd_mutex);++/**+*of_genpd_xlate_simple()-Xlatefunctionfordirectnode-domainmapping+*@genpdspec:OFphandleargstomapintoapowerdomain+*@data:xlatefunctionprivatedata-pointertostructgeneric_pm_domain+*+*Thisisagenericxlatefunctionthatcanbeusedtomodelpowerdomains+*thathavetheirowndevicetreenodes.Theprivatedataofxlatefunction+*needstobeavalidpointertostructgeneric_pm_domain.+*/+structgeneric_pm_domain*of_genpd_xlate_simple(+structof_phandle_args*genpdspec,+void*data)+{+if(genpdspec->args_count!=0)+returnERR_PTR(-EINVAL);+returndata;+}+EXPORT_SYMBOL_GPL(of_genpd_xlate_simple);++/**+*of_genpd_xlate_onecell()-Xlatefunctionforprovidersusingsingleindex.+*@genpdspec:OFphandleargstomapintoapowerdomain+*@data:xlatefunctionprivatedata-pointertostructgenpd_onecell_data+*+*Thisisagenericxlatefunctionthatcanbeusedtomodelsimplepower+*domaincontrollersthathaveonedevicetreenodeandprovidemultiple+*powerdomains.Asinglecellisusedasanindextoanarrayofpower+*domainsspecifiedingenpd_onecell_datastructwhenregisteringthe+*provider.+*/+structgeneric_pm_domain*of_genpd_xlate_onecell(+structof_phandle_args*genpdspec,+void*data)+{+structgenpd_onecell_data*genpd_data=data;+unsignedintidx=genpdspec->args[0];++if(genpdspec->args_count!=1)+returnERR_PTR(-EINVAL);++if(idx>=genpd_data->domain_num){+pr_err("%s: invalid domain index %d\n",__func__,idx);+returnERR_PTR(-EINVAL);+}++returngenpd_data->domains[idx];+}+EXPORT_SYMBOL_GPL(of_genpd_xlate_onecell);++/**+*of_genpd_add_provider()-Registeradomainproviderforanode+*@np:Devicenodepointerassociatedwithdomainprovider.+*@xlate:Callbackfordecodingdomainfromphandlearguments.+*@data:Contextpointerfor@genpd_src_getcallback.+*/+intof_genpd_add_provider(structdevice_node*np,genpd_xlate_txlate,+void*data)+{+structof_genpd_provider*cp;++cp=kzalloc(sizeof(*cp),GFP_KERNEL);+if(!cp)+return-ENOMEM;++cp->node=of_node_get(np);+cp->data=data;+cp->xlate=xlate;++mutex_lock(&of_genpd_mutex);+list_add(&cp->link,&of_genpd_providers);+mutex_unlock(&of_genpd_mutex);+pr_debug("Added domain provider from %s\n",np->full_name);++return0;+}+EXPORT_SYMBOL_GPL(of_genpd_add_provider);++/**+*of_genpd_del_provider()-Removeapreviouslyregistereddomainprovider+*@np:Devicenodepointerassociatedwithdomainprovider+*/+voidof_genpd_del_provider(structdevice_node*np)+{+structof_genpd_provider*cp;++mutex_lock(&of_genpd_mutex);+list_for_each_entry(cp,&of_genpd_providers,link){+if(cp->node==np){+list_del(&cp->link);+of_node_put(cp->node);+kfree(cp);+break;+}+}+mutex_unlock(&of_genpd_mutex);+}+EXPORT_SYMBOL_GPL(of_genpd_del_provider);++/**+*of_genpd_get_from_provider()-Look-uppowerdomain+*@genpdspec:OFphandleargstouseforlook-up+*+*Looksfordomainproviderundernodespecifiedby@genpdspecandiffound+*usesxlatefunctionoftheprovidertomapphandleargstoapowerdomain.+*+*Returnsavalidpointertostructgeneric_pm_domainonsuccessorERR_PTR()+*onfailure.+*/+staticstructgeneric_pm_domain*of_genpd_get_from_provider(+structof_phandle_args*genpdspec)+{+structgeneric_pm_domain*genpd=ERR_PTR(-ENOENT);+structof_genpd_provider*provider;++mutex_lock(&of_genpd_mutex);++/* Check if we have such a provider in our array */+list_for_each_entry(provider,&of_genpd_providers,link){+if(provider->node==genpdspec->np)+genpd=provider->xlate(genpdspec,provider->data);+if(!IS_ERR(genpd))+break;+}++mutex_unlock(&of_genpd_mutex);++returngenpd;+}++/**+*genpd_dev_pm_attach-Attachadevicetoit'spowerdomainusingDT.+*@dev:Devicetoattach.+*+*Parsedevice'sOFnodetofindapowerdomainspecifier.Ifsuchisfound,+*attachesthedevicetoretrievedpm_domainops.+*+*BothgenericandlegacySamsung-specificDTbindingsaresupportedto+*keepbackwardscompatibilitywithexistingDTBs.+*+*Returns0onsuccessfullyattachedpowerdomainornegativeerrorcode.+*/+intgenpd_dev_pm_attach(structdevice*dev)+{+structof_phandle_argspd_args;+structgeneric_pm_domain*pd;+intret;++if(!dev->of_node)+return-ENODEV;++if(dev->pm_domain)+return-EEXIST;++ret=of_parse_phandle_with_args(dev->of_node,"power-domains",+"#power-domain-cells",0,&pd_args);+if(ret<0){+if(ret!=-ENOENT)+returnret;++/*+*TrylegacySamsung-specificbindings+*(forbackwardscompatibilityofDTABI)+*/+pd_args.args_count=0;+pd_args.np=of_parse_phandle(dev->of_node,+"samsung,power-domain",0);+if(!pd_args.np)+return-ENOENT;+}++pd=of_genpd_get_from_provider(&pd_args);+if(IS_ERR(pd)){+dev_dbg(dev,"%s() failed to find power domain: %ld\n",+__func__,PTR_ERR(pd));+of_node_put(dev->of_node);+returnPTR_ERR(pd);+}++dev_dbg(dev,"adding to power domain %s\n",pd->name);++while(1){+ret=pm_genpd_add_device(pd,dev);+if(ret!=-EAGAIN)+break;+cond_resched();+}++if(ret<0){+dev_err(dev,"failed to add to power domain %s: %d",+pd->name,ret);+of_node_put(dev->of_node);+returnret;+}++return0;+}+EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);++/**+*genpd_dev_pm_detach-Detachadevicefromit'spowerdomain.+*@dev:Devicetoattach.+*+*Trytolocateacorrespondinggenericpowerdomain,whichthedevice+*thenpreviouslywereattachedto.Iffoundthedeviceisdetachedfrom+*thepowerdomain.+*+*Returns0onsuccessfullydetachedpowerdomainornegativeerrorcode.+*/+intgenpd_dev_pm_detach(structdevice*dev)+{+structgeneric_pm_domain*pd=NULL,*gpd;+intret=0;++if(!dev->pm_domain)+return-ENODEV;++mutex_lock(&gpd_list_lock);+list_for_each_entry(gpd,&gpd_list,gpd_list_node){+if(&gpd->domain==dev->pm_domain){+pd=gpd;+break;+}+}+mutex_unlock(&gpd_list_lock);++if(!pd)+return-ENOENT;++dev_dbg(dev,"removing from power domain %s\n",pd->name);++while(1){+ret=pm_genpd_remove_device(pd,dev);+if(ret!=-EAGAIN)+break;+cond_resched();+}++if(ret<0){+dev_err(dev,"failed to remove from power domain %s: %d",+pd->name,ret);+returnret;+}++/* Check if domain can be powered off after removing this device. */+genpd_queue_power_off_work(pd);++return0;+}+EXPORT_SYMBOL_GPL(genpd_dev_pm_detach);+#endif
To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().
Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().
The supported power domains at this point are the ACPI and the generic
power domains.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 14 +++++++++++
2 files changed, 72 insertions(+)
Previously only the ACPI power domain was supported by the platform
bus.
Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/base/platform.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
Previously only the ACPI power domain was supported by the i2c bus.
Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.
Cc: linux-mmc at vger.kernel.org
Signed-off-by: Ulf Hansson <redacted>
---
drivers/mmc/core/sdio_bus.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Previously only the ACPI power domain was supported by the i2c bus.
Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.
Cc: linux-spi at vger.kernel.org
Signed-off-by: Ulf Hansson <redacted>
---
drivers/spi/spi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
AMBA devices may on some SoCs resides in power domains. To be able to
manage these devices from there, let's try to attach devices to their
corresponding power domain during the probe phase.
To reverse these actions at the remove phase, we try to detach the
device from it's power domain.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/amba/bus.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
From: Tomasz Figa <redacted>
This patch moves Exynos power domain code to use the new generic power
domain look-up framework introduced in previous patches, thus also
allowing the new code to be compiled with CONFIG_ARCH_EXYNOS as well.
Signed-off-by: Tomasz Figa <redacted>
Cc: linux-samsung-soc at vger.kernel.org
Signed-off-by: Ulf Hansson <redacted>
[Ulf:Rebased and resolved conflicts]
---
.../bindings/arm/exynos/power_domain.txt | 13 ++--
arch/arm/mach-exynos/pm_domains.c | 78 +---------------------
kernel/power/Kconfig | 2 +-
3 files changed, 8 insertions(+), 85 deletions(-)
@@ -8,6 +8,8 @@ Required Properties: * samsung,exynos4210-pd - for exynos4210 type power domain. - reg: physical base address of the controller and length of memory mapped region.+- #power-domain-cells: number of cells in power domain specifier;+ must be 0. Optional Properties: - clocks: List of clock handles. The parent clocks of the input clocks to the
@@ -106,78 +106,6 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)returnexynos_pd_power(domain,false);}-staticvoidexynos_add_device_to_domain(structexynos_pm_domain*pd,-structdevice*dev)-{-intret;--dev_dbg(dev,"adding to power domain %s\n",pd->pd.name);--while(1){-ret=pm_genpd_add_device(&pd->pd,dev);-if(ret!=-EAGAIN)-break;-cond_resched();-}--pm_genpd_dev_need_restore(dev,true);-}--staticvoidexynos_remove_device_from_domain(structdevice*dev)-{-structgeneric_pm_domain*genpd=dev_to_genpd(dev);-intret;--dev_dbg(dev,"removing from power domain %s\n",genpd->name);--while(1){-ret=pm_genpd_remove_device(genpd,dev);-if(ret!=-EAGAIN)-break;-cond_resched();-}-}--staticvoidexynos_read_domain_from_dt(structdevice*dev)-{-structplatform_device*pd_pdev;-structexynos_pm_domain*pd;-structdevice_node*node;--node=of_parse_phandle(dev->of_node,"samsung,power-domain",0);-if(!node)-return;-pd_pdev=of_find_device_by_node(node);-if(!pd_pdev)-return;-pd=platform_get_drvdata(pd_pdev);-exynos_add_device_to_domain(pd,dev);-}--staticintexynos_pm_notifier_call(structnotifier_block*nb,-unsignedlongevent,void*data)-{-structdevice*dev=data;--switch(event){-caseBUS_NOTIFY_BIND_DRIVER:-if(dev->of_node)-exynos_read_domain_from_dt(dev);--break;--caseBUS_NOTIFY_UNBOUND_DRIVER:-exynos_remove_device_from_domain(dev);--break;-}-returnNOTIFY_DONE;-}--staticstructnotifier_blockplatform_nb={-.notifier_call=exynos_pm_notifier_call,-};-static__initintexynos4_pm_init_power_domain(void){structplatform_device*pdev;
@@ -203,7 +131,6 @@ static __init int exynos4_pm_init_power_domain(void)pd->base=of_iomap(np,0);pd->pd.power_off=exynos_pd_power_off;pd->pd.power_on=exynos_pd_power_on;-pd->pd.of_node=np;pd->oscclk=clk_get(dev,"oscclk");if(IS_ERR(pd->oscclk))
@@ -229,15 +156,12 @@ static __init int exynos4_pm_init_power_domain(void)clk_put(pd->oscclk);no_clk:-platform_set_drvdata(pdev,pd);-on=__raw_readl(pd->base+0x4)&S5P_INT_LOCAL_PWR_EN;pm_genpd_init(&pd->pd,NULL,!on);+of_genpd_add_provider(np,of_genpd_xlate_simple,&pd->pd);}-bus_register_notifier(&platform_bus_type,&platform_nb);-return0;}arch_initcall(exynos4_pm_init_power_domain);
From: Philipp Zabel <p.zabel@pengutronix.de> Date: 2014-08-26 13:15:18
Hi Ulf,
Am Dienstag, den 26.08.2014, 14:07 +0200 schrieb Ulf Hansson:
From: Tomasz Figa <redacted>
This patch introduces generic code to perform power domain look-up using
device tree and automatically bind devices to their power domains.
Generic device tree binding is introduced to specify power domains of
devices in their device tree nodes.
Backwards compatibility with legacy Samsung-specific power domain
bindings is provided, but for now the new code is not compiled when
CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
will change as soon as Exynos power domain code gets converted to use
the generic framework in further patch.
Signed-off-by: Tomasz Figa <redacted>
Signed-off-by: Ulf Hansson <redacted>
Thank you for updating this series. I've tested patches 1-4
using the PU power domain on i.MX6.
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
From: Rafael J. Wysocki <hidden> Date: 2014-08-27 00:16:02
On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
quoted hunk
To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/acpi/device_pm.c | 4 ++++
include/linux/acpi.h | 7 +++++--
2 files changed, 9 insertions(+), 2 deletions(-)
From: Rafael J. Wysocki <hidden> Date: 2014-08-27 00:20:49
On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
quoted hunk
To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().
Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().
The supported power domains at this point are the ACPI and the generic
power domains.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 14 +++++++++++
2 files changed, 72 insertions(+)
On a more general note, are you sure that the place where we call
acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
quoted hunk
+
+/**
+ * dev_pm_domain_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ * @power_off: Used to indicate whether we should power off the device.
+ *
+ * The @dev may be attached to a power domain. By iterating through the
+ * available alternatives we detach it from it's power domain.
+ *
+ * This functions will reverse the actions from dev_pm_domain_attach() and
+ * thus detach the @dev from it's power domain. Typically it should be invoked
+ * from subsystem level code during the remove phase.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+ if (acpi_dev_pm_detach(dev, power_off))
+ return genpd_dev_pm_detach(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-owner at vger.kernel.org] On Behalf Of Ulf Hansson
Sent: Tuesday, August 26, 2014 8:07 PM
To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm at vger.kernel.org
To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/acpi/device_pm.c | 4 ++++
include/linux/acpi.h | 7 +++++--
2 files changed, 9 insertions(+), 2 deletions(-)
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On 27 August 2014 02:16, Rafael J. Wysocki [off-list ref] wrote:
On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
quoted
To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/acpi/device_pm.c | 4 ++++
include/linux/acpi.h | 7 +++++--
2 files changed, 9 insertions(+), 2 deletions(-)
Sure.
If you prefer that term, I can also change on the other patches in
this patchset. There are commit-msg etc , where I think I have used
"power domain".
It looks like you've never compiled this, have you?
You are absolutely right. There were quite some combinations of
CONFIG_PM_* that I tried out, but I totally forgot ACPI, sorry! I will
make sure to do it in v2.
On 27 August 2014 07:43, Zheng, Lv [off-list ref] wrote:
Hi,
quoted
From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-owner at vger.kernel.org] On Behalf Of Ulf Hansson
Sent: Tuesday, August 26, 2014 8:07 PM
To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm at vger.kernel.org
To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/acpi/device_pm.c | 4 ++++
include/linux/acpi.h | 7 +++++--
2 files changed, 9 insertions(+), 2 deletions(-)
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On 27 August 2014 02:20, Rafael J. Wysocki [off-list ref] wrote:
On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
quoted
To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().
Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().
The supported power domains at this point are the ACPI and the generic
power domains.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 14 +++++++++++
2 files changed, 72 insertions(+)
@@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)returnret;}EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);++/**+*dev_pm_domain_attach-Attachadevicetoit'spowerdomain.+*@dev:Devicetoattach.+*@power_on:Usedtoindicatewhetherweshouldpoweronthedevice.+*+*The@devmayonlybeattachedtoasinglepowerdomain.Byiteratingthrough+*theavailablealternativeswetrytofindavaliddomainforthedevice.+*+*Thisfunctionshouldtypicallybeinvokedfromsubsystemlevelcodeduring+*theprobephase.Especiallyforthosethat'sholddeviceswhichrequires+*powermanagementthroughpowerdomains.+*+*Callersmustensurepropersynchronizationofthisfunctionwithpower+*managementcallbacks.+*+*Returns0onsuccessfullyattachedpowerdomainornegativeerrorcode.+*/+intdev_pm_domain_attach(structdevice*dev,boolpower_on)+{+intret;++ret=acpi_dev_pm_attach(dev,power_on);+if(ret==-EPROBE_DEFER)
This doesn't seem to be possible today. At least I'm not sure how it can
happen.
You are right, but I did this intentionally. The reason for having
this check, was that I didn't want the new API to put the limit on
handling deferred probe.
I happy the above check, if you think it's better!?
Kind regards
Uffe
On a more general note, are you sure that the place where we call
acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
Currently, I haven't seen any place where it doesn't make sense.
Additionally if such place is found, we may either just ignore it and
let the caller of the API worry about the returned error or invoke the
genpd/acpi API immediately instead.
quoted
+
+/**
+ * dev_pm_domain_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ * @power_off: Used to indicate whether we should power off the device.
+ *
+ * The @dev may be attached to a power domain. By iterating through the
+ * available alternatives we detach it from it's power domain.
+ *
+ * This functions will reverse the actions from dev_pm_domain_attach() and
+ * thus detach the @dev from it's power domain. Typically it should be invoked
+ * from subsystem level code during the remove phase.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+ if (acpi_dev_pm_detach(dev, power_off))
+ return genpd_dev_pm_detach(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
On 27 August 2014 09:37, Ulf Hansson [off-list ref] wrote:
On 27 August 2014 02:20, Rafael J. Wysocki [off-list ref] wrote:
quoted
On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
quoted
To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().
Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().
The supported power domains at this point are the ACPI and the generic
power domains.
Signed-off-by: Ulf Hansson <redacted>
---
drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 14 +++++++++++
2 files changed, 72 insertions(+)
@@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)returnret;}EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);++/**+*dev_pm_domain_attach-Attachadevicetoit'spowerdomain.+*@dev:Devicetoattach.+*@power_on:Usedtoindicatewhetherweshouldpoweronthedevice.+*+*The@devmayonlybeattachedtoasinglepowerdomain.Byiteratingthrough+*theavailablealternativeswetrytofindavaliddomainforthedevice.+*+*Thisfunctionshouldtypicallybeinvokedfromsubsystemlevelcodeduring+*theprobephase.Especiallyforthosethat'sholddeviceswhichrequires+*powermanagementthroughpowerdomains.+*+*Callersmustensurepropersynchronizationofthisfunctionwithpower+*managementcallbacks.+*+*Returns0onsuccessfullyattachedpowerdomainornegativeerrorcode.+*/+intdev_pm_domain_attach(structdevice*dev,boolpower_on)+{+intret;++ret=acpi_dev_pm_attach(dev,power_on);+if(ret==-EPROBE_DEFER)
This doesn't seem to be possible today. At least I'm not sure how it can
happen.
You are right, but I did this intentionally. The reason for having
this check, was that I didn't want the new API to put the limit on
handling deferred probe.
I happy the above check, if you think it's better!?
On a more general note, are you sure that the place where we call
acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
Currently, I haven't seen any place where it doesn't make sense.
Additionally if such place is found, we may either just ignore it and
let the caller of the API worry about the returned error or invoke the
genpd/acpi API immediately instead.
quoted
quoted
+
+/**
+ * dev_pm_domain_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ * @power_off: Used to indicate whether we should power off the device.
+ *
+ * The @dev may be attached to a power domain. By iterating through the
+ * available alternatives we detach it from it's power domain.
+ *
+ * This functions will reverse the actions from dev_pm_domain_attach() and
+ * thus detach the @dev from it's power domain. Typically it should be invoked
+ * from subsystem level code during the remove phase.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+ if (acpi_dev_pm_detach(dev, power_off))
+ return genpd_dev_pm_detach(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach);