rpi: add support for rpi power domain driver
Subsystems (10)
v2 cover rpi: add support for rpi power domain driver
Hi,
this patch series contains at first a patch for the power domain subsystem which offers to uninit generic power domains when init was called before.
The RPi Power-Domains need to be enabled/disabled by interacting with the RPi firmware which can fail. To cleanup the probing we need to undo the power domains again which was registered before.
- Alex
Alexander Aring (2):
power: domain: add pm_genpd_uninit
rpi: add support to enable usb power domain
.../bindings/arm/bcm/raspberrypi,bcm2835-power.txt | 25 +++ arch/arm/boot/dts/bcm2835-rpi.dtsi | 11 ++ arch/arm/boot/dts/bcm2835.dtsi | 2 +- arch/arm/mach-bcm/Kconfig | 10 ++ arch/arm/mach-bcm/Makefile | 1 + arch/arm/mach-bcm/raspberrypi-power.c | 180 +++++++++++++++++++++ drivers/base/power/domain.c | 15 ++ include/dt-bindings/arm/raspberrypi-power.h | 14 ++ include/linux/pm_domain.h | 4 + 9 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt create mode 100644 arch/arm/mach-bcm/raspberrypi-power.c create mode 100644 include/dt-bindings/arm/raspberrypi-power.h
Signature · 1 line
2.6.1
RFC v2 1/2 power: domain: add pm_genpd_uninit
This patch adds function pm_genpd_uninit for undo a pm_genpd_init. This is useful for multiple power domains while probing. If the probing fails after one pm_genpd_init was called we need to undo all previous registrations of generic pm domains inside the gpd_list list.
There is a check on IS_ERR_OR_NULL(genpd) which is useful to check again registered power domains and not registered domains, the driver can use this mechanism to have an array with registered and non-registered power domains, where non-registered power domains are NULL.
--- drivers/base/power/domain.c | 15 +++++++++++++++ include/linux/pm_domain.h | 4 ++++ 2 files changed, 19 insertions(+)
drivers/base/power/domain.c +15 -0
@@ -1730,6 +1730,21 @@ void pm_genpd_init(struct generic_pm_domain *genpd, }EXPORT_SYMBOL_GPL (pm_genpd_init); +/** +* pm_genpd_uninit - Uninitialize a generic I/O PM domain object. +* @genpd: PM domain object to initialize. +*/ +void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +if (IS_ERR_OR_NULL (genpd)) +return ; + +mutex_lock (&gpd_list_lock); +list_del (&genpd->gpd_list_node); +mutex_unlock (&gpd_list_lock); +} +EXPORT_SYMBOL_GPL (pm_genpd_uninit); +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF /* * Device Tree based PM domain providers.
include/linux/pm_domain.h +4 -0
@@ -143,6 +143,7 @@ extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd);extern int pm_genpd_name_detach_cpuidle (const char *name);extern void pm_genpd_init (struct generic_pm_domain *genpd,struct dev_power_governor *gov,bool is_off); +extern void pm_genpd_uninit (struct generic_pm_domain *genpd);extern int pm_genpd_poweron (struct generic_pm_domain *genpd);extern int pm_genpd_name_poweron (const char *domain_name);
@@ -212,6 +213,9 @@ static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { } +static inline void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +}static inline int pm_genpd_poweron (struct generic_pm_domain *genpd) {return -ENOSYS ;
Signature · 1 line
2.6.1
RFC v2 1/2 power: domain: add pm_genpd_uninit
Quoted 4 lines · Alexander Aring
This patch adds function
pm_genpd_uninitfor undo apm_genpd_init. This is useful for multiple power domains while probing. If the probing fails after onepm_genpd_initwas called we need to undo all previous registrations of generic pm domains inside thegpd_listlist.
Yes, agree. Although I think it's a bit mote complicated than what you suggest in this simple approach. :-)
Quoted 28 lines
There is a check on
IS_ERR_OR_NULL(genpd)which is useful to check again registered power domains and not registered domains, the driver can use this mechanism to have an array with registered and non-registered power domains, where non-registered power domains are NULL.Cc Rafael J. Wysocki <[email protected]>Cc Kevin Hilman <[email protected]>Cc Ulf Hansson <[email protected]>Cc Pavel Machek <[email protected]>Cc Len Brown <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Signed-off-by Alexander Aring <[email protected]>--- drivers/base/power/domain.c | 15 +++++++++++++++ include/linux/pm_domain.h | 4 ++++ 2 files changed, 19 insertions(+)drivers/base/power/domain.c +2
-0@@ -1730,6 +1730,21 @@ void pm_genpd_init(struct generic_pm_domain *genpd, }EXPORT_SYMBOL_GPL (pm_genpd_init); +/** +* pm_genpd_uninit - Uninitialize a generic I/O PM domain object.
drivers/base/power/domain.c void pm_genpd_init(struct generic_pm_domain *genpd, · line 1744
Quoted 10 lines
drivers/base/power/domain.c +10
-0+* @genpd: PM domain object to initialize. +*/ +void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +if (IS_ERR_OR_NULL (genpd)) +return ; + +mutex_lock (&gpd_list_lock); +list_del (&genpd->gpd_list_node); +mutex_unlock (&gpd_list_lock);
This is too fragile. You don't protect from the cases below.
1. The genpd may have devices attached to it.
2. The genpd may have subdomains.
To deal with these case, that's when it becomes more complex which I guess is the reason to why nobody really cared until now.
Moreover, I think there are some more structures to "uninitialize" besides just unlinking the genpd struct from the gpd list. For example a mutex_destroy() should be done.
Quoted 29 lines
drivers/base/power/domain.c +3
-0+} +EXPORT_SYMBOL_GPL (pm_genpd_uninit); +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF /* * Device Tree based PM domain providers. include/linux/pm_domain.h +4
-1@@ -143,6 +143,7 @@ extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd);extern int pm_genpd_name_detach_cpuidle (const char *name);extern void pm_genpd_init (struct generic_pm_domain *genpd,struct dev_power_governor *gov,bool is_off); +extern void pm_genpd_uninit (struct generic_pm_domain *genpd);extern int pm_genpd_poweron (struct generic_pm_domain *genpd);extern int pm_genpd_name_poweron (const char *domain_name);@@ -212,6 +213,9 @@ static inline void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off) { } +static inline void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +}static inline int pm_genpd_poweron (struct generic_pm_domain *genpd) {return -ENOSYS ; --
Quoted 2 lines
2.6.1
Kind regards
Uffe
RFC v2 1/2 power: domain: add pm_genpd_uninit
Quoted 9 lines · Ulf Hansson
Quoted 4 lines · Alexander Aring
This patch adds function
pm_genpd_uninitfor undo apm_genpd_init. This is useful for multiple power domains while probing. If the probing fails after onepm_genpd_initwas called we need to undo all previous registrations of generic pm domains inside thegpd_listlist.Yes, agree. Although I think it's a bit mote complicated than what you suggest in this simple approach. :-)
ok.
Quoted 41 lines
Quoted 28 lines
There is a check on
IS_ERR_OR_NULL(genpd)which is useful to check again registered power domains and not registered domains, the driver can use this mechanism to have an array with registered and non-registered power domains, where non-registered power domains are NULL.Cc Rafael J. Wysocki <[email protected]>Cc Kevin Hilman <[email protected]>Cc Ulf Hansson <[email protected]>Cc Pavel Machek <[email protected]>Cc Len Brown <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Signed-off-by Alexander Aring <[email protected]>--- drivers/base/power/domain.c | 15 +++++++++++++++ include/linux/pm_domain.h | 4 ++++ 2 files changed, 19 insertions(+)drivers/base/power/domain.c +2
-0@@ -1730,6 +1730,21 @@ void pm_genpd_init(struct generic_pm_domain *genpd, }EXPORT_SYMBOL_GPL (pm_genpd_init); +/** +* pm_genpd_uninit - Uninitialize a generic I/O PM domain object. drivers/base/power/domain.c void pm_genpd_init(struct generic_pm_domain *genpd, · line 1744
Quoted 10 lines
drivers/base/power/domain.c +10
-0+* @genpd: PM domain object to initialize. +*/ +void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +if (IS_ERR_OR_NULL (genpd)) +return ; + +mutex_lock (&gpd_list_lock); +list_del (&genpd->gpd_list_node); +mutex_unlock (&gpd_list_lock);This is too fragile. You don't protect from the cases below.
Quoted 6 lines
1. The genpd may have devices attached to it.
2. The genpd may have subdomains.To deal with these case, that's when it becomes more complex which I guess is the reason to why nobody really cared until now.
Can we not just undo the things which pm_genpd_init does, then let the driver to deal with all other uninitialize of e.g. "subdomains" which might the driver has initialize before? We know there are no slaves or something else which is empty because pm_genpd_init runs INIT_LIST_HEAD, or not?
To make such handling above I would add some:
"pm_genpd_uninit_recursive" function, which cleanup everything from a power domain, e.g. subdomains, etc and other lists.
What do you suggest to me for e.g. the raspberrypi power domain driver, also simple ignore such error handling?
For my current use-case I can remove the failure between pm_genpd_init by simple getting all "power states" (the bool is_off for pm_genpd_init), before calling pm_genpd_init. In this case I don't have any failure between calling pm_genpd_init when another pm_genpd_init was before.
Looks like this:
1. get all states from firmware to get parameter "is_off", which can fail. We should get here the states for the power domains which we want to register only.
2. Then call pm_genpd_init, which cannot be fail between another pm_genpd_init. (There are only void functions in the middle, which cannot fail). If I call pm_genpd_init, I use "is_off" variable from the step of "1.".
But then I have still the call of "of_genpd_add_provider_onecell" at the end of probing which can fail. So this is also not a valid solution, because I need to undo everything before.
Quoted 4 lines
Moreover, I think there are some more structures to "uninitialize" besides just unlinking the genpd struct from the gpd list. For example a
mutex_destroy()should be done.
yes, of course.
- Alex
RFC v2 1/2 power: domain: add pm_genpd_uninit
Hi,
Quoted 4 lines · Alexander Aring
What do you suggest to me for e.g. the raspberrypi power domain driver, also simple ignore such error handling?
ping, I also can add some WARN_ON_ONCE, if the list for sub-domains, etc. are not empty. This would then report about wrong use of pm_genpd_uninit.
- Alex
RFC v2 1/2 power: domain: add pm_genpd_uninit
Quoted 8 lines · Alexander Aring
Hi,
Quoted 4 lines · Alexander Aring
What do you suggest to me for e.g. the raspberrypi power domain driver, also simple ignore such error handling?
Quoted 5 lines
ping, I also can add some
WARN_ON_ONCE, if the list for sub-domains, etc. are not empty. This would then report about wrong use ofpm_genpd_uninit.- Alex
Sorry for the delay.
I think what you suggest would be an okay solution, at least it will improve the current behaviour.
We should verify for sub-domains, attached devices, and if the genpd has an of-provider. That's all I can think of right now, but there may be other things as well.
Kind regards
Uffe
RFC v2 1/2 power: domain: add pm_genpd_uninit
Hi,
Quoted 15 lines · Ulf Hansson
Quoted 8 lines · Alexander Aring
Hi,
Quoted 4 lines · Alexander Aring
What do you suggest to me for e.g. the raspberrypi power domain driver, also simple ignore such error handling?
Quoted 5 lines
ping, I also can add some
WARN_ON_ONCE, if the list for sub-domains, etc. are not empty. This would then report about wrong use ofpm_genpd_uninit.- Alex
Quoted 9 lines
Sorry for the delay.
I think what you suggest would be an okay solution, at least it will improve the current behaviour.
We should verify for sub-domains, attached devices, and if the genpd has an of-provider. That's all I can think of right now, but there may be other things as well.
okay, I added now:
WARN_ON_ONCE(!list_empty(genpd->master_links) ||
!list_empty(genpd->slave_links) ||
!list_empty(genpd->dev_list));So far I understand is master/slave something about domains/subdomains, the dev_list fis for atteched devices.
But how can I check "if the genpd has an of-provider", the "struct generic_pm_domain" doesn't know a "of-provider". There is a static list "of_genpd_providers", do you want to iterate over all and then doing some matching algorithmn? Or do you want to add something inside "struct generic_pm_domain", so a genpd knows about the "of-provider".
I am currently confused about how to check on "of-provider".
- Alex
RFC v2 1/2 power: domain: add pm_genpd_uninit
In reply to Alexander Aring[...]
Quoted 28 lines
Quoted 16 lines
drivers/base/power/domain.c void pm_genpd_init(struct generic_pm_domain *genpd, · line 1744
Quoted 13 lines
drivers/base/power/domain.c +12
-0+/** +* pm_genpd_uninit - Uninitialize a generic I/O PM domain object. +* @genpd: PM domain object to initialize. +*/ +void pm_genpd_uninit (struct generic_pm_domain *genpd) +{ +if (IS_ERR_OR_NULL (genpd)) +return ; + +mutex_lock (&gpd_list_lock); +list_del (&genpd->gpd_list_node); +mutex_unlock (&gpd_list_lock);This is too fragile. You don't protect from the cases below.
Quoted 6 lines
1. The genpd may have devices attached to it.
2. The genpd may have subdomains.To deal with these case, that's when it becomes more complex which I guess is the reason to why nobody really cared until now.
Can we not just undo the things which
pm_genpd_initdoes, then let the driver to deal with all other uninitialize of e.g. "subdomains" which might the driver has initialize before? We know there are no slaves or something else which is empty becausepm_genpd_initrunsINIT_LIST_HEAD, or not?
Quoted 7 lines
To make such handling above I would add some:
"
pm_genpd_uninit_recursive" function, which cleanup everything from a power domain, e.g. subdomains, etc and other lists.What do you suggest to me for e.g. the raspberrypi power domain driver, also simple ignore such error handling?
No, let's give it try so see if can improve the situation.
Quoted 19 lines
For my current use-case I can remove the failure between
pm_genpd_initby simple getting all "power states" (the boolis_offforpm_genpd_init), before callingpm_genpd_init. In this case I don't have any failure between callingpm_genpd_initwhen anotherpm_genpd_initwas before.Looks like this:
1. get all states from firmware to get parameter "
is_off", which can fail. We should get here the states for the power domains which we want to register only.2. Then call
pm_genpd_init, which cannot be fail between anotherpm_genpd_init. (There are only void functions in the middle, which cannot fail). If I callpm_genpd_init, I use "is_off" variable from the step of "1.".
Quoted 3 lines
But then I have still the call of "
of_genpd_add_provider_onecell" at the end of probing which can fail. So this is also not a valid solution, because I need to undo everything before.
Okay, got it.
Quoted 9 lines
Quoted 5 lines
Moreover, I think there are some more structures to "uninitialize" besides just unlinking the genpd struct from the gpd list. For example a
mutex_destroy()should be done.yes, of course.
- Alex
Kind regards
Uffe
RFC v2 2/2 rpi: add support to enable usb power domain
In reply to Alexander AringThis patch adds support for RPi several Power Domains and enable support to enable the USB Power Domain when it's not enabled before.
This patch based on Eric Anholt's patch to support Power Domains. He had an issue about -EPROBE_DEFER inside the power domain subsystem, this issue was solved by commit <311fa6a> ("PM / Domains: Return -EPROBE_DEFER if we fail to init or turn-on domain").
It was tested with barebox and the following scripts before booting linux:
/env/a_off:
# cat /env/a_off #turn off which are enabled by default regulator -n bcm2835_mci0 -s disable regulator -n uart0-pl0110 -s disable
/env/a_on:
# cat /env/a_on #turn off which are enabled by default regulator -n bcm2835_mci0 -s disable regulator -n uart0-pl0110 -s disable
regulator -n bcm2835_mci0 -s enable
regulator -n uart0-pl0110 -s enable
regulator -n uart0-pl0111 -s enable
regulator -n bcm2835_usb -s enable
regulator -n bcm2835_i2c0 -s enable
regulator -n bcm2835_i2c1 -s enable
regulator -n bcm2835_i2c2 -s enable
regulator -n bcm2835_spi -s enable
regulator -n bcm2835_ccp2tx -s enable
regulator -n bcm2835_dsi -s enable
/env/b:
# cat /env/b sh /env/a_on
regulator -n bcm2835_mci0 -s disable
regulator -n uart0-pl0110 -s disable
regulator -n uart0-pl0111 -s disable
regulator -n bcm2835_usb -s disable
regulator -n bcm2835_i2c0 -s disable
regulator -n bcm2835_i2c1 -s disable
regulator -n bcm2835_i2c2 -s disable
regulator -n bcm2835_spi -s disable
regulator -n bcm2835_ccp2tx -s disable
regulator -n bcm2835_dsi -s disable
/env/c:
# cat /env/c sh ./env/b
regulator -n bcm2835_mci0 -s enable
regulator -n uart0-pl0110 -s enable
regulator -n uart0-pl0111 -s enable
regulator -n bcm2835_usb -s enable
regulator -n bcm2835_i2c0 -s enable
regulator -n bcm2835_i2c1 -s enable
regulator -n bcm2835_i2c2 -s enable
regulator -n bcm2835_spi -s enable
regulator -n bcm2835_ccp2tx -s enable
regulator -n bcm2835_dsi -s enable
These scripts enables/disable all regulators inside the bootloader. It was running with a "hard" and "soft" reset without any issues. These testcases should fit to Stephen Warren suggestions:
"(a) before having explicitly turned the power domain on or off at all (b) after having turned it on (c) after having turned it off, and for all power domains."
---
changes since v2:
- add pm_genpd_uninit to handle probing failure.
- move power domain drive to his own driver in arch/arm/mach-bcm/ Also add own devicetree node for this driver, "raspberrypi,bcm2835-power".
- Removing all power domains which might exists for the firmware API but we currently have no use-case for it. I tried to keep the same domain numbering in generic power domains subsystem like they are offered from the firmware API. This works, all power_domains which are NULL inside the array of genpd_onecell_data.domains[#] will be ignored.
- Adding Eric Anholt and me to the authors.
- Creating devicetree documentation for the power domain driver.
- fix error handling in raspberrypi_firmware_set_power.
- Remove comment about mapping between power domains array, this is not necessary anymore. I add a "enabled" attribute to raspberrypi_power_domain which indicates if a domain should be registered or not (zeroed values does not indicate such handling, but enabled is false then).
- remove "goto mbox" not necessary anymore because an own driver implementation.
- Update devicetrees for changes in v2.
.../bindings/arm/bcm/raspberrypi,bcm2835-power.txt | 25 +++ arch/arm/boot/dts/bcm2835-rpi.dtsi | 11 ++ arch/arm/boot/dts/bcm2835.dtsi | 2 +- arch/arm/mach-bcm/Kconfig | 10 ++ arch/arm/mach-bcm/Makefile | 1 + arch/arm/mach-bcm/raspberrypi-power.c | 180 +++++++++++++++++++++ include/dt-bindings/arm/raspberrypi-power.h | 14 ++ 7 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt create mode 100644 arch/arm/mach-bcm/raspberrypi-power.c create mode 100644 include/dt-bindings/arm/raspberrypi-power.h
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +25 -0
@@ -0,0 +1,25 @@ +Raspberry Pi power domain driver + +Required properties: + +- compatible: Should be "raspberrypi,bcm2835-power". +- firmware: Reference to the RPi firmware device node. +- #power-domain-cells: Should be <1>, we providing multiple power domains. + +The valid defines for power domain are: + + RPI_POWER_DOMAIN_USB + +Example: + +power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; +}; + +Example for using power domain: + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +};
arch/arm/boot/dts/bcm2835-rpi.dtsi +11 -0
@@ -1,3 +1,4 @@ +#include <dt-bindings/arm/raspberrypi-power.h> #include "bcm2835.dtsi" / {
@@ -20,6 +21,12 @@ compatible = "raspberrypi,bcm2835-firmware"; mboxes = <&mailbox>; }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; }; };
@@ -56,3 +63,7 @@ status = "okay"; bus-width = <4>; }; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +};
arch/arm/boot/dts/bcm2835.dtsi +1 -1
@@ -149,7 +149,7 @@ status = "disabled"; }; - usb at 7e980000 { + usb: usb at 7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>;
arch/arm/mach-bcm/Kconfig +10 -0
@@ -120,6 +120,16 @@ config ARCH_BCM2835 This enables support for the Broadcom BCM2835 SoC. This SoC is used in the Raspberry Pi and Roku 2 devices. +config RASPBERRY_POWER + bool "Raspberry Pi power domain driver" + depends on ARCH_BCM2835 + depends on RASPBERRYPI_FIRMWARE + select PM_GENERIC_DOMAINS if PM + select PM_GENERIC_DOMAINS_OF if PM + help + This enables support for the RPi power domains which can be enabled + or disabled via the RPi firmware. + config ARCH_BCM_63XX bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 depends on MMU
arch/arm/mach-bcm/Makefile +1 -0
@@ -33,6 +33,7 @@ endif # BCM2835 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o +obj-$(CONFIG_RASPBERRY_POWER) += raspberrypi-power.o # BCM5301X obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
arch/arm/mach-bcm/raspberrypi-power.c new file +180 -0
180 lines not on this page · raw message
include/dt-bindings/arm/raspberrypi-power.h new file +14 -0
@@ -0,0 +1,14 @@ +/* +* Copyright ? 2015 Broadcom +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H +#define _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H + +#define RPI_POWER_DOMAIN_USB 3 + +#endif /* _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H */
Signature · 1 line
2.6.1
RFC v2 2/2 rpi: add support to enable usb power domain
Hi Alexander,
i think this subject should better start with "ARM:".
Am 03.11.2015 um 23:45 schrieb Alexander Aring:
Quoted 30 lines
This patch adds support for RPi several Power Domains and enable support to enable the USB Power Domain when it's not enabled before.
This patch based on Eric Anholt's patch to support Power Domains. He had an issue about -EPROBE_DEFER inside the power domain subsystem, this issue was solved by commit <311fa6a> ("PM / Domains: Return -EPROBE_DEFER if we fail to init or turn-on domain").
[...]
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +15
-0@@ -0,0 +1,25 @@ +Raspberry Pi power domain driver + +Required properties: + +- compatible: Should be "raspberrypi,bcm2835-power". +- firmware: Reference to the RPi firmware device node. +- #power-domain-cells: Should be <1>, we providing multiple power domains. + +The valid defines for power domain are: + + RPI_POWER_DOMAIN_USB + +Example: + +power: power {
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt line 25
Quoted 10 lines
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +10
-0+ compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; +}; + +Example for using power domain: + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +};
Refering to Documentation/devicetree/bindings/submitting-patches.txt binding doc should be a separate patch.
Quoted 48 lines
arch/arm/boot/dts/bcm2835-rpi.dtsi +11
-0@@ -1,3 +1,4 @@ +#include <dt-bindings/arm/raspberrypi-power.h> #include "bcm2835.dtsi" / {@@ -20,6 +21,12 @@ compatible = "raspberrypi,bcm2835-firmware"; mboxes = <&mailbox>; }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; }; };@@ -56,3 +63,7 @@ status = "okay"; bus-width = <4>; }; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +};arch/arm/boot/dts/bcm2835.dtsi +1
-1@@ -149,7 +149,7 @@ status = "disabled"; }; - usb at 7e980000 { + usb: usb at 7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>;arch/arm/mach-bcm/Kconfig +0
-0
arch/arm/mach-bcm/Kconfig config ARCH_BCM2835 · line 123
Quoted 4 lines
arch/arm/mach-bcm/Kconfig +1
-0@@ -120,6 +120,16 @@ config ARCH_BCM2835 This enables support for the Broadcom BCM2835 SoC. This SoC is used in the Raspberry Pi and Roku 2 devices. +config RASPBERRY_POWER
RASPBERRYPI_POWER?
arch/arm/mach-bcm/Kconfig config ARCH_BCM2835 · line 127
Quoted 4 lines
arch/arm/mach-bcm/Kconfig +4
-0+ bool "Raspberry Pi power domain driver" + depends on ARCH_BCM2835 + depends on RASPBERRYPI_FIRMWARE + select PM_GENERIC_DOMAINS if PM
Since PM_GENERIC_DOMAINS_OF depends on PM_GENERIC_DOMAINS this line should be redundant.
Quoted 30 lines
arch/arm/mach-bcm/Kconfig +5
-0+ select PM_GENERIC_DOMAINS_OF if PM + help + This enables support for the RPi power domains which can be enabled + or disabled via the RPi firmware. + config ARCH_BCM_63XX bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 depends on MMUarch/arm/mach-bcm/Makefile +1
-0@@ -33,6 +33,7 @@ endif # BCM2835 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o +obj-$(CONFIG_RASPBERRY_POWER) += raspberrypi-power.o # BCM5301X obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.oarch/arm/mach-bcm/raspberrypi-power.c new file +4
-0@@ -0,0 +1,180 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation.
arch/arm/mach-bcm/raspberrypi-power.c line 14
Quoted 10 lines
arch/arm/mach-bcm/raspberrypi-power.c new file +10
-0+* +* Authors: +* (C) 2015 Pengutronix, Alexander Aring <[email protected]> +* Eric Anholt <[email protected]> +*/ + +#include <linux/module.h> +#include <linux/pm_domain.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h>
Please sort alphabetical.
Quoted 14 lines
arch/arm/mach-bcm/raspberrypi-power.c new file +14
-0+#include <dt-bindings/arm/raspberrypi-power.h> +#include <soc/bcm2835/raspberrypi-firmware.h> + +#define RPI_POWER_DOMAIN (_domain, _name) \ + [_domain] = { \ + .domain = _domain, \ + .enabled = true, \ + .base = { \ + .name = _name, \ + .power_off = raspberrypi_domain_off, \ + .power_on = raspberrypi_domain_on, \ + }, \ + } +
arch/arm/mach-bcm/raspberrypi-power.c line 38
Quoted 10 lines
arch/arm/mach-bcm/raspberrypi-power.c new file +10
-0+struct raspberrypi_power_domain { +u32 domain; +bool enabled; +struct generic_pm_domain base; +}; + +struct rpi_power_domain_packet { +u32 domain; +u32 on; +} __packet;
It would be nice to use consequently rpi_ as prefix instead of raspberrypi_ .
Quoted 7 lines
arch/arm/mach-bcm/raspberrypi-power.c new file +0
-0include/dt-bindings/arm/raspberrypi-power.h new file +0
-0
include/dt-bindings/arm/raspberrypi-power.h line 10
Quoted 10 lines
include/dt-bindings/arm/raspberrypi-power.h new file +10
-0@@ -0,0 +1,14 @@ +/* +* Copyright ? 2015 Broadcom +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H +#define _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H
This needs renaming.
Thanks
Stefan
Quoted 5 lines
include/dt-bindings/arm/raspberrypi-power.h new file +4
-0+ +#define RPI_POWER_DOMAIN_USB 3 + +#endif /* _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H */
RFC v2 2/2 rpi: add support to enable usb power domain
Quoted 4 lines · Stefan Wahren
Hi Alexander,
i think this subject should better start with "ARM:".
ok. I will change every thing which you recognised.
Thanks.
- Alex
RFC v2 2/2 rpi: add support to enable usb power domain
In reply to Stefan WahrenOn Thu, Nov 05, 2015 at 08:15:35AM +0100, Stefan Wahren wrote:
...
Quoted 8 lines
arch/arm/mach-bcm/Kconfig config ARCH_BCM2835 · line 127
Quoted 4 lines
arch/arm/mach-bcm/Kconfig +4
-0+ bool "Raspberry Pi power domain driver" + depends on ARCH_BCM2835 + depends on RASPBERRYPI_FIRMWARE + select PM_GENERIC_DOMAINS if PMSince
PM_GENERIC_DOMAINS_OFdepends onPM_GENERIC_DOMAINSthis line should be redundant.
I can't remove the line:
select PM_GENERIC_DOMAINS if PM
here. It's true that "PM_GENERIC_DOMAINS_OF depends on PM_GENERIC_DOMAINS", but Kconfig can't handle the dependency here with select. That's why sometimes people teaches me "select is evil".
I will get:
warning: (RASPBERRYPI_POWER) selects PM_GENERIC_DOMAINS_OF which has unmet direct dependencies (PM_GENERIC_DOMAINS && OF)
otherwise.
Nevertheless we can't also use "depends on PM_GENERIC_DOMAINS if PM" because, PM_GENERIC_DOMAINS is a hidden entry (has no Kconfig prompt).
- Alex
Rob Herring
maintainerRFC v2 2/2 rpi: add support to enable usb power domain
In reply to Alexander AringQuoted 119 lines · Alexander Aring
This patch adds support for RPi several Power Domains and enable support to enable the USB Power Domain when it's not enabled before.
This patch based on Eric Anholt's patch to support Power Domains. He had an issue about -EPROBE_DEFER inside the power domain subsystem, this issue was solved by commit <311fa6a> ("PM / Domains: Return -EPROBE_DEFER if we fail to init or turn-on domain").
It was tested with barebox and the following scripts before booting linux:
/env/a_off:
# cat /env/a_off #turn off which are enabled by default regulator -n bcm2835_mci0 -s disable regulator -n uart0-pl0110 -s disable/env/a_on:
# cat /env/a_on #turn off which are enabled by default regulator -n bcm2835_mci0 -s disable regulator -n uart0-pl0110 -s disableregulator -n
bcm2835_mci0-s enable
regulator -n uart0-pl0110 -s enable
regulator -n uart0-pl0111 -s enable
regulator -nbcm2835_usb-s enable
regulator -nbcm2835_i2c0-s enable
regulator -nbcm2835_i2c1-s enable
regulator -nbcm2835_i2c2-s enable
regulator -nbcm2835_spi-s enable
regulator -nbcm2835_ccp2tx-s enable
regulator -nbcm2835_dsi-s enable/env/b:
# cat /env/b sh /env/a_onregulator -n
bcm2835_mci0-s disable
regulator -n uart0-pl0110 -s disable
regulator -n uart0-pl0111 -s disable
regulator -nbcm2835_usb-s disable
regulator -nbcm2835_i2c0-s disable
regulator -nbcm2835_i2c1-s disable
regulator -nbcm2835_i2c2-s disable
regulator -nbcm2835_spi-s disable
regulator -nbcm2835_ccp2tx-s disable
regulator -nbcm2835_dsi-s disable/env/c:
# cat /env/c sh ./env/bregulator -n
bcm2835_mci0-s enable
regulator -n uart0-pl0110 -s enable
regulator -n uart0-pl0111 -s enable
regulator -nbcm2835_usb-s enable
regulator -nbcm2835_i2c0-s enable
regulator -nbcm2835_i2c1-s enable
regulator -nbcm2835_i2c2-s enable
regulator -nbcm2835_spi-s enable
regulator -nbcm2835_ccp2tx-s enable
regulator -nbcm2835_dsi-s enableThese scripts enables/disable all regulators inside the bootloader. It was running with a "hard" and "soft" reset without any issues. These testcases should fit to Stephen Warren suggestions:
"(a) before having explicitly turned the power domain on or off at all (b) after having turned it on (c) after having turned it off, and for all power domains."
Cc Stephen Warren <[email protected]>Cc Lee Jones <[email protected]>Cc Eric Anholt <[email protected]>Signed-off-by Alexander Aring <[email protected]>---
changes since v2:
- addpm_genpd_uninitto handle probing failure.
- move power domain drive to his own driver inarch/arm/mach-bcm/Also add own devicetree node for this driver, "raspberrypi,bcm2835-power".
- Removing all power domains which might exists for the firmware API but we currently have no use-case for it. I tried to keep the same domain numbering in generic power domains subsystem like they are offered from the firmware API. This works, allpower_domainswhich are NULL inside the array of genpd_onecell_data.domains[#] will be ignored.
- Adding Eric Anholt and me to the authors.
- Creating devicetree documentation for the power domain driver.
- fix error handling inraspberrypi_firmware_set_power.
- Remove comment about mapping between power domains array, this is not necessary anymore. I add a "enabled" attribute toraspberrypi_power_domainwhich indicates if a domain should be registered or not (zeroed values does not indicate such handling, but enabled is false then).
- remove "goto mbox" not necessary anymore because an own driver implementation.
- Update devicetrees for changes in v2..../bindings/arm/bcm/raspberrypi,bcm2835-power.txt | 25 +++ arch/arm/boot/dts/bcm2835-rpi.dtsi | 11 ++ arch/arm/boot/dts/bcm2835.dtsi | 2 +- arch/arm/mach-bcm/Kconfig | 10 ++ arch/arm/mach-bcm/Makefile | 1 + arch/arm/mach-bcm/raspberrypi-power.c | 180 +++++++++++++++++++++ include/dt-bindings/arm/raspberrypi-power.h | 14 ++ 7 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt create mode 100644 arch/arm/mach-bcm/raspberrypi-power.c create mode 100644 include/dt-bindings/arm/raspberrypi-power.hDocumentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +0
-0
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt line 5
Quoted 5 lines
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +5
-0@@ -0,0 +1,25 @@ +Raspberry Pi power domain driver + +Required properties: + +- compatible: Should be "raspberrypi,bcm2835-power".
These are board or chip level power domains? If the latter, the vendor should not be raspberrypi, but Broadcom. If the former, then it should describe the board rather than the chip.
Rob
RFC v2 2/2 rpi: add support to enable usb power domain
Hi,
Quoted 1 line · Rob Herring
On Tue, Nov 03, 2015 at 11:45:11PM +0100, Alexander Aring wrote:
...
Quoted 17 lines
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt line 5
Quoted 12 lines
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt new file +5
-0@@ -0,0 +1,25 @@ +Raspberry Pi power domain driver + +Required properties: + +- compatible: Should be "raspberrypi,bcm2835-power".These are board or chip level power domains? If the latter, the vendor should not be raspberrypi, but Broadcom. If the former, then it should describe the board rather than the chip.
the access to the power domains is provided by the firmware. The firmware is RPi specific. On an other bcm2835 with another firmware it would be working complete different.
Everything which is accessable over the firmware is RPi specific.
- Alex