Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1418205 > unrolled thread
| Started by | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| First post | 2016-06-09 11:50 +0200 |
| Last post | 2016-06-09 12:00 +0200 |
| Articles | 15 — 5 participants |
Back to article view | Back to linux.kernel
[RFC v4 00/14] usb/mmc/power: Generic power sequence (and fix USB/LAN when TFTP booting) Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 11:50 +0200
[RFC v4 14/14] ARM: dts: exynos: Fix LAN and HUB after bootloader initialization on Odroid U3 Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 11:50 +0200
[RFC v4 12/14] EXAMPLE CODE: usb: hub: Power sequence the ports on activation Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 11:50 +0200
[RFC v4 07/14] power: pwrseq: Generalize mmc_pwrseq operations by removing mmc prefix Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
[RFC v4 04/14] MAINTAINERS: Retain Ulf Hansson as the same maintainer of pwrseq Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
[RFC v4 09/14] power: pwrseq: Add support for USB hubs with external power Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
[RFC v4 02/14] simplefb: Use new devm_of_regulator_all_get helper and bulk API Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
[RFC v4 01/14] regulator: of: Add helper for getting all supplies Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Mark Brown <broonie@kernel.org> - 2016-06-09 12:40 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 13:50 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Rob Herring <robh@kernel.org> - 2016-06-10 19:40 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Heiko Stübner <heiko@sntech.de> - 2016-06-10 21:00 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies "Rafael J. Wysocki" <rafael@kernel.org> - 2016-06-09 15:00 +0200
Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies Mark Brown <broonie@kernel.org> - 2016-06-09 18:00 +0200
[RFC v4 03/14] power/mmc: Move pwrseq drivers to power/pwrseq Krzysztof Kozlowski <k.kozlowski@samsung.com> - 2016-06-09 12:00 +0200
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 11:50 +0200 |
| Subject | [RFC v4 00/14] usb/mmc/power: Generic power sequence (and fix USB/LAN when TFTP booting) |
| Message-ID | <rI4L7-4zR-3@gated-at.bofh.it> |
Hi,
Another version for solving a problem of power sequence on USB
hubs and devices. Apparently I am not the only one experiencing it.
The patchset tries to provide a framework for generic power sequence
of USB devices but the USB part is left to Peter Chen.
Patchset is also available here:
repo: https://github.com/krzk/linux
branch: for-next/odroid-u3-usb3503-lan-boot-fixes-v4
Changes since v3
================
1. Address Rob's comments. All regulator supplies are parsed and
toggled during power sequence. This comes with two new patches:
a. regulator,
b. simplefb.
2. Minor fixes in pwrseq-simple driver - proper module removal path.
3. Minor fixes in example USB code (pointed out by Stephen Boyd).
Changes since v2
================
1. Add Javier's reviewed-by tags. Address some comments.
2. Re-use existing properties for GPIOs etc by pwrseq-simple
driver. New property is still added: "power-sequence".
I tried to address and do according to Rob's comments.
Please look at patch 6/12 ("power: pwrseq: simple: Add support
for regulator and generic property") for bindings and the
new code around matching "power-sequence" property.
3. I marked the usb code as "EXAMPLE" because that part
is left to Peter Chen.
Problem
=======
When Odroid U3 (usb3503 + smsc95xx + max77686) boots from network (TFTP),
the usb3503 and LAN smsc95xx do not show up in "lsusb". Hard-reset
is required, e.g. by suspend to RAM. The actual TFTP boot does
not have to happen. Just "usb start" from U-Boot is sufficient.
From the schematics, the regulator is a supply only to LAN, however
without toggling it off/on, the usb3503 hub won appear neither.
Solution
========
This is very similar to the MMC pwrseq behavior so the idea is to:
1. Move MMC pwrseq drivers to generic place,
2. Extend the pwrseq-simple with regulator toggling,
3. Add support to USB hub and port core for pwrseq,
4. Toggle the regulator when needed.
Best regards,
Krzysztof
Krzysztof Kozlowski (14):
regulator: of: Add helper for getting all supplies
simplefb: Use new devm_of_regulator_all_get helper and bulk API
power/mmc: Move pwrseq drivers to power/pwrseq
MAINTAINERS: Retain Ulf Hansson as the same maintainer of pwrseq
power: pwrseq: Enable COMPILE_TEST for drivers
power: pwrseq: Remove mmc prefix from mmc_pwrseq
power: pwrseq: Generalize mmc_pwrseq operations by removing mmc prefix
power: pwrseq: simple: Add support for regulators and generic property
power: pwrseq: Add support for USB hubs with external power
usb: hub: Handle deferred probe
EXAMPLE CODE: usb: port: Parse pwrseq phandle from Device Tree
EXAMPLE CODE: usb: hub: Power sequence the ports on activation
ARM: dts: exynos: Switch the buck8 to GPIO mode on Odroid U3
ARM: dts: exynos: Fix LAN and HUB after bootloader initialization on
Odroid U3
.../pwrseq/pwrseq-emmc.txt} | 0
.../pwrseq/pwrseq-simple.txt} | 30 ++-
MAINTAINERS | 9 +
arch/arm/boot/dts/exynos4412-odroidu3.dts | 5 +
drivers/mmc/Kconfig | 2 -
drivers/mmc/core/Makefile | 3 -
drivers/mmc/core/core.c | 8 +-
drivers/mmc/core/host.c | 2 +-
drivers/mmc/core/pwrseq.c | 110 ---------
drivers/mmc/core/pwrseq.h | 52 -----
drivers/mmc/core/pwrseq_simple.c | 141 ------------
drivers/power/Kconfig | 1 +
drivers/power/Makefile | 1 +
drivers/{mmc/core => power/pwrseq}/Kconfig | 22 +-
drivers/power/pwrseq/Makefile | 3 +
drivers/power/pwrseq/pwrseq.c | 153 +++++++++++++
drivers/{mmc/core => power/pwrseq}/pwrseq_emmc.c | 17 +-
drivers/power/pwrseq/pwrseq_simple.c | 245 +++++++++++++++++++++
drivers/regulator/of_regulator.c | 86 ++++++++
drivers/usb/core/hub.c | 16 +-
drivers/usb/core/hub.h | 3 +
drivers/usb/core/port.c | 15 ++
drivers/video/fbdev/simplefb.c | 71 ++----
include/linux/mmc/host.h | 4 +-
include/linux/pwrseq.h | 63 ++++++
include/linux/regulator/of_regulator.h | 13 ++
26 files changed, 680 insertions(+), 395 deletions(-)
rename Documentation/devicetree/bindings/{mmc/mmc-pwrseq-emmc.txt => power/pwrseq/pwrseq-emmc.txt} (100%)
rename Documentation/devicetree/bindings/{mmc/mmc-pwrseq-simple.txt => power/pwrseq/pwrseq-simple.txt} (50%)
delete mode 100644 drivers/mmc/core/pwrseq.c
delete mode 100644 drivers/mmc/core/pwrseq.h
delete mode 100644 drivers/mmc/core/pwrseq_simple.c
rename drivers/{mmc/core => power/pwrseq}/Kconfig (60%)
create mode 100644 drivers/power/pwrseq/Makefile
create mode 100644 drivers/power/pwrseq/pwrseq.c
rename drivers/{mmc/core => power/pwrseq}/pwrseq_emmc.c (88%)
create mode 100644 drivers/power/pwrseq/pwrseq_simple.c
create mode 100644 include/linux/pwrseq.h
--
1.9.1
[toc] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 11:50 +0200 |
| Subject | [RFC v4 14/14] ARM: dts: exynos: Fix LAN and HUB after bootloader initialization on Odroid U3 |
| Message-ID | <rI4L8-4zR-19@gated-at.bofh.it> |
| In reply to | #1418205 |
On Odroid U3 (Exynos4412-based) board if USB was initialized by
bootloader (in U-Boot "usb start" before tftpboot), the HUB (usb3503)
and LAN (smsc95xx) after after successful probing were not visible in the
system ("lsusb").
In such case the devices had to be fully reset before configuring.
Reset by GPIO (called RESET_N pin) and by RESET field in STCD register
in usb3503 HUB are not sufficient. Instead full reset has to be done by
disabling and enabling regulator.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
arch/arm/boot/dts/exynos4412-odroidu3.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 31cdc036fda4..8fd50061d91b 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -99,11 +99,15 @@
clock-names = "refclk";
clocks = <&pmu_system_controller 0>;
refclk-frequency = <24000000>;
+
+ power-sequence;
+ vdd-supply = <&buck8_reg>;
};
&ehci {
port@1 {
status = "okay";
+ usb-pwrseq = <&usb3503>;
};
port@2 {
status = "okay";
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 11:50 +0200 |
| Subject | [RFC v4 12/14] EXAMPLE CODE: usb: hub: Power sequence the ports on activation |
| Message-ID | <rI4L8-4zR-41@gated-at.bofh.it> |
| In reply to | #1418205 |
The autodetection of attached USB device might not work on certain boards where the power is delivered externally. These devices also might require a hard reset. Use pwrseq for that in USB hub. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> --- drivers/usb/core/hub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c421745b84aa..46d9f9aedacc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -26,6 +26,7 @@ #include <linux/mutex.h> #include <linux/random.h> #include <linux/pm_qos.h> +#include <linux/pwrseq.h> #include <asm/uaccess.h> #include <asm/byteorder.h> @@ -1663,6 +1664,15 @@ static int hub_configure(struct usb_hub *hub, usb_hub_adjust_deviceremovable(hdev, hub->descriptor); + /* FIXME: When do the pre-power-on? */ + /* + for (i = 0; i < maxchild; i++) + pwrseq_pre_power_on(hub->ports[i]->pwrseq); + */ + + for (i = 0; i < maxchild; i++) + pwrseq_post_power_on(hub->ports[i]->pwrseq); + hub_activate(hub, HUB_INIT); return 0; -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 07/14] power: pwrseq: Generalize mmc_pwrseq operations by removing mmc prefix |
| Message-ID | <rI4UN-4Do-1@gated-at.bofh.it> |
| In reply to | #1418205 |
The power sequence hooks (mmc_pwrseq_pre_power_on(),
mmc_pwrseq_post_power_on() and mmc_pwrseq_power_off()) can be made more
generic to allow re-use in other subsystems. They do not need to take
pointer to struct mmc_host but instead the struct pwrseq should be
sufficient.
Remove the "mmc" prefix and use the pointer to struct pwrseq as
argument.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
drivers/mmc/core/core.c | 6 +++---
drivers/power/pwrseq/pwrseq.c | 24 +++++++++---------------
drivers/power/pwrseq/pwrseq_emmc.c | 6 ++----
drivers/power/pwrseq/pwrseq_simple.c | 14 ++++++--------
include/linux/pwrseq.h | 18 +++++++++---------
5 files changed, 29 insertions(+), 39 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index edefc3fbebe6..09a4722f9037 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1719,7 +1719,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
if (host->ios.power_mode == MMC_POWER_ON)
return;
- mmc_pwrseq_pre_power_on(host);
+ pwrseq_pre_power_on(host->pwrseq);
host->ios.vdd = fls(ocr) - 1;
host->ios.power_mode = MMC_POWER_UP;
@@ -1740,7 +1740,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
*/
mmc_delay(10);
- mmc_pwrseq_post_power_on(host);
+ pwrseq_post_power_on(host->pwrseq);
host->ios.clock = host->f_init;
@@ -1759,7 +1759,7 @@ void mmc_power_off(struct mmc_host *host)
if (host->ios.power_mode == MMC_POWER_OFF)
return;
- mmc_pwrseq_power_off(host);
+ pwrseq_power_off(host->pwrseq);
host->ios.clock = 0;
host->ios.vdd = 0;
diff --git a/drivers/power/pwrseq/pwrseq.c b/drivers/power/pwrseq/pwrseq.c
index 9c665821f890..495a19d3c30b 100644
--- a/drivers/power/pwrseq/pwrseq.c
+++ b/drivers/power/pwrseq/pwrseq.c
@@ -52,32 +52,26 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
}
EXPORT_SYMBOL_GPL(mmc_pwrseq_alloc);
-void mmc_pwrseq_pre_power_on(struct mmc_host *host)
+void pwrseq_pre_power_on(struct pwrseq *pwrseq)
{
- struct pwrseq *pwrseq = host->pwrseq;
-
if (pwrseq && pwrseq->ops->pre_power_on)
- pwrseq->ops->pre_power_on(host);
+ pwrseq->ops->pre_power_on(pwrseq);
}
-EXPORT_SYMBOL_GPL(mmc_pwrseq_pre_power_on);
+EXPORT_SYMBOL_GPL(pwrseq_pre_power_on);
-void mmc_pwrseq_post_power_on(struct mmc_host *host)
+void pwrseq_post_power_on(struct pwrseq *pwrseq)
{
- struct pwrseq *pwrseq = host->pwrseq;
-
if (pwrseq && pwrseq->ops->post_power_on)
- pwrseq->ops->post_power_on(host);
+ pwrseq->ops->post_power_on(pwrseq);
}
-EXPORT_SYMBOL_GPL(mmc_pwrseq_post_power_on);
+EXPORT_SYMBOL_GPL(pwrseq_post_power_on);
-void mmc_pwrseq_power_off(struct mmc_host *host)
+void pwrseq_power_off(struct pwrseq *pwrseq)
{
- struct pwrseq *pwrseq = host->pwrseq;
-
if (pwrseq && pwrseq->ops->power_off)
- pwrseq->ops->power_off(host);
+ pwrseq->ops->power_off(pwrseq);
}
-EXPORT_SYMBOL_GPL(mmc_pwrseq_power_off);
+EXPORT_SYMBOL_GPL(pwrseq_power_off);
void mmc_pwrseq_free(struct mmc_host *host)
{
diff --git a/drivers/power/pwrseq/pwrseq_emmc.c b/drivers/power/pwrseq/pwrseq_emmc.c
index a68ac9a68e04..dbb7e753beb2 100644
--- a/drivers/power/pwrseq/pwrseq_emmc.c
+++ b/drivers/power/pwrseq/pwrseq_emmc.c
@@ -19,8 +19,6 @@
#include <linux/reboot.h>
#include <linux/pwrseq.h>
-#include <linux/mmc/host.h>
-
struct mmc_pwrseq_emmc {
struct pwrseq pwrseq;
struct notifier_block reset_nb;
@@ -37,9 +35,9 @@ static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq)
udelay(200);
}
-static void mmc_pwrseq_emmc_reset(struct mmc_host *host)
+static void mmc_pwrseq_emmc_reset(struct pwrseq *_pwrseq)
{
- struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
+ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(_pwrseq);
__mmc_pwrseq_emmc_reset(pwrseq);
}
diff --git a/drivers/power/pwrseq/pwrseq_simple.c b/drivers/power/pwrseq/pwrseq_simple.c
index d5fbd653153e..93807a6ef162 100644
--- a/drivers/power/pwrseq/pwrseq_simple.c
+++ b/drivers/power/pwrseq/pwrseq_simple.c
@@ -18,8 +18,6 @@
#include <linux/gpio/consumer.h>
#include <linux/pwrseq.h>
-#include <linux/mmc/host.h>
-
struct mmc_pwrseq_simple {
struct pwrseq pwrseq;
bool clk_enabled;
@@ -46,9 +44,9 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
}
}
-static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
+static void mmc_pwrseq_simple_pre_power_on(struct pwrseq *_pwrseq)
{
- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(_pwrseq);
if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) {
clk_prepare_enable(pwrseq->ext_clk);
@@ -58,16 +56,16 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
}
-static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
+static void mmc_pwrseq_simple_post_power_on(struct pwrseq *_pwrseq)
{
- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(_pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
}
-static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
+static void mmc_pwrseq_simple_power_off(struct pwrseq *_pwrseq)
{
- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(_pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
diff --git a/include/linux/pwrseq.h b/include/linux/pwrseq.h
index 6d2d2a44ad35..fcc8fd855d4c 100644
--- a/include/linux/pwrseq.h
+++ b/include/linux/pwrseq.h
@@ -11,9 +11,9 @@
#include <linux/mmc/host.h>
struct pwrseq_ops {
- void (*pre_power_on)(struct mmc_host *host);
- void (*post_power_on)(struct mmc_host *host);
- void (*power_off)(struct mmc_host *host);
+ void (*pre_power_on)(struct pwrseq *pwrseq);
+ void (*post_power_on)(struct pwrseq *pwrseq);
+ void (*power_off)(struct pwrseq *pwrseq);
};
struct pwrseq {
@@ -28,10 +28,10 @@ struct pwrseq {
int pwrseq_register(struct pwrseq *pwrseq);
void pwrseq_unregister(struct pwrseq *pwrseq);
+void pwrseq_pre_power_on(struct pwrseq *pwrseq);
+void pwrseq_post_power_on(struct pwrseq *pwrseq);
+void pwrseq_power_off(struct pwrseq *pwrseq);
int mmc_pwrseq_alloc(struct mmc_host *host);
-void mmc_pwrseq_pre_power_on(struct mmc_host *host);
-void mmc_pwrseq_post_power_on(struct mmc_host *host);
-void mmc_pwrseq_power_off(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
#else /* CONFIG_POWER_SEQ */
@@ -41,10 +41,10 @@ static inline int pwrseq_register(struct pwrseq *pwrseq)
return -ENOSYS;
}
static inline void pwrseq_unregister(struct pwrseq *pwrseq) {}
+static inline void pwrseq_pre_power_on(struct pwrseq *pwrseq) {}
+static inline void pwrseq_post_power_on(struct pwrseq *pwrseq) {}
+static inline void pwrseq_power_off(struct pwrseq *pwrseq) {}
static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; }
-static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {}
-static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {}
-static inline void mmc_pwrseq_power_off(struct mmc_host *host) {}
static inline void mmc_pwrseq_free(struct mmc_host *host) {}
#endif /* CONFIG_POWER_SEQ */
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 04/14] MAINTAINERS: Retain Ulf Hansson as the same maintainer of pwrseq |
| Message-ID | <rI4UO-4Do-15@gated-at.bofh.it> |
| In reply to | #1418205 |
Before moving pwrseq drivers from drivers/mmc/core/ to drivers/power/, they were maintained by Ulf Hansson. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4f2a75ce5442..71114607502a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9083,6 +9083,15 @@ F: include/linux/power_supply.h F: drivers/power/ X: drivers/power/avs/ +POWER SEQ CORE and DRIVERS +M: Ulf Hansson <ulf.hansson@linaro.org> +L: linux-mmc@vger.kernel.org +T: git git://git.linaro.org/people/ulf.hansson/mmc.git +S: Maintained +F: drivers/power/pwrseq/ +F: include/linux/pwrseq.h +F: Documentation/devicetree/bindings/power/pwrseq/ + POWER STATE COORDINATION INTERFACE (PSCI) M: Mark Rutland <mark.rutland@arm.com> M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 09/14] power: pwrseq: Add support for USB hubs with external power |
| Message-ID | <rI4UO-4Do-21@gated-at.bofh.it> |
| In reply to | #1418205 |
Some USB devices on embedded boards have external power supply which has
to be reset in certain conditions. Add pwrseq interface for this.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
drivers/power/pwrseq/pwrseq.c | 47 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/pwrseq.h | 11 ++++++++++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/power/pwrseq/pwrseq.c b/drivers/power/pwrseq/pwrseq.c
index 495a19d3c30b..722aff4f740f 100644
--- a/drivers/power/pwrseq/pwrseq.c
+++ b/drivers/power/pwrseq/pwrseq.c
@@ -1,7 +1,9 @@
/*
- * Copyright (C) 2014 Linaro Ltd
+ * Copyright (C) 2014 Linaro Ltd
+ * Copyright (C) 2016 Samsung Electronics
*
* Author: Ulf Hansson <ulf.hansson@linaro.org>
+ * Krzysztof Kozlowski <k.kozlowski@samsung.com>
*
* License terms: GNU General Public License (GPL) version 2
*
@@ -52,6 +54,42 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
}
EXPORT_SYMBOL_GPL(mmc_pwrseq_alloc);
+struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name)
+{
+ struct device_node *np;
+ struct pwrseq *p, *ret = NULL;
+
+ np = of_parse_phandle(dev->of_node, phandle_name, 0);
+ if (!np)
+ return NULL;
+
+ mutex_lock(&pwrseq_list_mutex);
+ list_for_each_entry(p, &pwrseq_list, pwrseq_node) {
+ if (p->dev->of_node == np) {
+ if (!try_module_get(p->owner))
+ dev_err(dev,
+ "increasing module refcount failed\n");
+ else
+ ret = p;
+
+ break;
+ }
+ }
+
+ of_node_put(np);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ if (!ret) {
+ dev_dbg(dev, "%s defer probe\n", phandle_name);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ dev_info(dev, "allocated usb-pwrseq\n");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pwrseq_alloc);
+
void pwrseq_pre_power_on(struct pwrseq *pwrseq)
{
if (pwrseq && pwrseq->ops->pre_power_on)
@@ -84,6 +122,13 @@ void mmc_pwrseq_free(struct mmc_host *host)
}
EXPORT_SYMBOL_GPL(mmc_pwrseq_free);
+void pwrseq_free(const struct pwrseq *pwrseq)
+{
+ if (pwrseq)
+ module_put(pwrseq->owner);
+}
+EXPORT_SYMBOL_GPL(pwrseq_free);
+
int pwrseq_register(struct pwrseq *pwrseq)
{
if (!pwrseq || !pwrseq->ops || !pwrseq->dev)
diff --git a/include/linux/pwrseq.h b/include/linux/pwrseq.h
index fcc8fd855d4c..6215b3d6350d 100644
--- a/include/linux/pwrseq.h
+++ b/include/linux/pwrseq.h
@@ -31,9 +31,13 @@ void pwrseq_unregister(struct pwrseq *pwrseq);
void pwrseq_pre_power_on(struct pwrseq *pwrseq);
void pwrseq_post_power_on(struct pwrseq *pwrseq);
void pwrseq_power_off(struct pwrseq *pwrseq);
+
int mmc_pwrseq_alloc(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
+struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name);
+void pwrseq_free(const struct pwrseq *pwrseq);
+
#else /* CONFIG_POWER_SEQ */
static inline int pwrseq_register(struct pwrseq *pwrseq)
@@ -44,9 +48,16 @@ static inline void pwrseq_unregister(struct pwrseq *pwrseq) {}
static inline void pwrseq_pre_power_on(struct pwrseq *pwrseq) {}
static inline void pwrseq_post_power_on(struct pwrseq *pwrseq) {}
static inline void pwrseq_power_off(struct pwrseq *pwrseq) {}
+
static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; }
static inline void mmc_pwrseq_free(struct mmc_host *host) {}
+static inline struct pwrseq *pwrseq_alloc(struct device *dev, const char *phandle_name)
+{
+ return NULL;
+}
+static inline void pwrseq_free(const struct pwrseq *pwrseq) {}
+
#endif /* CONFIG_POWER_SEQ */
#endif /* _LINUX_PWRSEQ_H */
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 02/14] simplefb: Use new devm_of_regulator_all_get helper and bulk API |
| Message-ID | <rI4UO-4Do-11@gated-at.bofh.it> |
| In reply to | #1418205 |
Switch from manual way of getting all regulators to usage of
devm_of_regulator_all_get(). Additionally use the regulator bulk API
which changes the logic in case of failure of regulator enable. Before
if regulator_enable() returned error for one regulator, rest of them
were still enabled. The bulk API does everything atomically.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
Not tested.
---
drivers/video/fbdev/simplefb.c | 71 +++++++++---------------------------------
1 file changed, 14 insertions(+), 57 deletions(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index e9cf19977285..897b95efa40d 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -32,6 +32,7 @@
#include <linux/of_platform.h>
#include <linux/parser.h>
#include <linux/regulator/consumer.h>
+#include <linux/regulator/of_regulator.h>
static struct fb_fix_screeninfo simplefb_fix = {
.id = "simple",
@@ -178,8 +179,8 @@ struct simplefb_par {
struct clk **clks;
#endif
#if defined CONFIG_OF && defined CONFIG_REGULATOR
- u32 regulator_count;
- struct regulator **regulators;
+ unsigned int regulator_count;
+ struct regulator_bulk_data *regulators;
#endif
};
@@ -278,8 +279,6 @@ static void simplefb_clocks_destroy(struct simplefb_par *par) { }
#if defined CONFIG_OF && defined CONFIG_REGULATOR
-#define SUPPLY_SUFFIX "-supply"
-
/*
* Regulator handling code.
*
@@ -303,61 +302,23 @@ static int simplefb_regulators_init(struct simplefb_par *par,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- struct property *prop;
- struct regulator *regulator;
- const char *p;
- int count = 0, i = 0, ret;
+ int ret;
if (dev_get_platdata(&pdev->dev) || !np)
return 0;
- /* Count the number of regulator supplies */
- for_each_property_of_node(np, prop) {
- p = strstr(prop->name, SUPPLY_SUFFIX);
- if (p && p != prop->name)
- count++;
- }
-
- if (!count)
+ ret = devm_of_regulator_all_get(&pdev->dev, &par->regulator_count, &par->regulators);
+ if (ret)
+ return ret;
+ else if (!par->regulator_count)
return 0;
- par->regulators = devm_kcalloc(&pdev->dev, count,
- sizeof(struct regulator *), GFP_KERNEL);
- if (!par->regulators)
- return -ENOMEM;
-
- /* Get all the regulators */
- for_each_property_of_node(np, prop) {
- char name[32]; /* 32 is max size of property name */
-
- p = strstr(prop->name, SUPPLY_SUFFIX);
- if (!p || p == prop->name)
- continue;
-
- strlcpy(name, prop->name,
- strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1);
- regulator = devm_regulator_get_optional(&pdev->dev, name);
- if (IS_ERR(regulator)) {
- if (PTR_ERR(regulator) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- dev_err(&pdev->dev, "regulator %s not found: %ld\n",
- name, PTR_ERR(regulator));
- continue;
- }
- par->regulators[i++] = regulator;
- }
- par->regulator_count = i;
-
/* Enable all the regulators */
- for (i = 0; i < par->regulator_count; i++) {
- ret = regulator_enable(par->regulators[i]);
- if (ret) {
- dev_err(&pdev->dev,
- "failed to enable regulator %d: %d\n",
- i, ret);
- devm_regulator_put(par->regulators[i]);
- par->regulators[i] = NULL;
- }
+ ret = regulator_bulk_enable(par->regulator_count, par->regulators);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to enable regulators: %d\n", ret);
+ return ret;
}
return 0;
@@ -365,14 +326,10 @@ static int simplefb_regulators_init(struct simplefb_par *par,
static void simplefb_regulators_destroy(struct simplefb_par *par)
{
- int i;
-
if (!par->regulators)
return;
- for (i = 0; i < par->regulator_count; i++)
- if (par->regulators[i])
- regulator_disable(par->regulators[i]);
+ regulator_bulk_disable(par->regulator_count, par->regulators);
}
#else
static int simplefb_regulators_init(struct simplefb_par *par,
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rI4UO-4Do-27@gated-at.bofh.it> |
| In reply to | #1418205 |
Few drivers have a need of getting regulator supplies without knowing
their names:
1. The Simple Framebuffer driver works on setup provided by bootloader
(outside of scope of kernel);
2. Generic power sequence driver may be attached to any device node.
Add a Device Tree helper for parsing "-supply" properties and returning
allocated bulk regulator consumers.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
drivers/regulator/of_regulator.c | 86 ++++++++++++++++++++++++++++++++++
include/linux/regulator/of_regulator.h | 13 +++++
2 files changed, 99 insertions(+)
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index cd828dbf9d52..0d2c8dd0ebc0 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -350,3 +350,89 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
return init_data;
}
+
+/**
+ * devm_of_regulator_all_get - get all regulator consumers
+ *
+ * @dev: Device to supply
+ * @num_consumers Number of consumers registered (only on success)
+ * @consumers: Configuration of consumers; names of supplies and clients
+ * are stored here; allocated only on success (NULL otherwise);
+ *
+ * @return 0 on success, an errno on failure.
+ *
+ * This helper function allows drivers to get all regulator consumers
+ * for given device in one operation. The names of regulator supplies
+ * do not have to be provided. If any of the regulators cannot be
+ * acquired then any regulators that were allocated will be freed
+ * before returning to the caller.
+ */
+int devm_of_regulator_all_get(struct device *dev, unsigned int *num_consumers,
+ struct regulator_bulk_data **consumers)
+{
+ struct device_node *np = dev->of_node;
+ struct regulator_bulk_data *bulk;
+ unsigned int count = 0, i = 0;
+ struct property *prop;
+ const char *p;
+ int ret;
+
+ if (!np) {
+ ret = 0;
+ goto err; /* Not really an error */
+ }
+
+ /* Count the number of regulator supplies */
+ for_each_property_of_node(np, prop) {
+ p = strstr(prop->name, "-supply");
+ if (p && p != prop->name)
+ count++;
+ }
+
+ if (!count) {
+ ret = 0;
+ goto err; /* Not really an error */
+ }
+
+ bulk = devm_kcalloc(dev, count, sizeof(**consumers), GFP_KERNEL);
+ if (!bulk) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* Get all the names for supplies */
+ for_each_property_of_node(np, prop) {
+ char *name;
+ int len;
+
+ p = strstr(prop->name, "-supply");
+ if (!p || p == prop->name)
+ continue;
+
+ len = strlen(prop->name) - strlen("-supply") + 1;
+ name = devm_kzalloc(dev, len, GFP_KERNEL);
+ if (!name) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ strlcpy(name, prop->name, len);
+ bulk[i++].supply = name;
+ }
+
+ ret = devm_regulator_bulk_get(dev, i, bulk);
+ if (ret)
+ goto err;
+
+ *consumers = bulk;
+ *num_consumers = i;
+
+ return 0;
+
+err:
+ *num_consumers = 0;
+ *consumers = NULL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_of_regulator_all_get);
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h
index 763953f7e3b8..93a3b7fe92e8 100644
--- a/include/linux/regulator/of_regulator.h
+++ b/include/linux/regulator/of_regulator.h
@@ -7,6 +7,7 @@
#define __LINUX_OF_REG_H
struct regulator_desc;
+struct regulator_bulk_data;
struct of_regulator_match {
const char *name;
@@ -24,6 +25,9 @@ extern struct regulator_init_data
extern int of_regulator_match(struct device *dev, struct device_node *node,
struct of_regulator_match *matches,
unsigned int num_matches);
+extern int devm_of_regulator_all_get(struct device *dev,
+ unsigned int *num_consumers,
+ struct regulator_bulk_data **consumers);
#else
static inline struct regulator_init_data
*of_get_regulator_init_data(struct device *dev,
@@ -40,6 +44,15 @@ static inline int of_regulator_match(struct device *dev,
{
return 0;
}
+static inline int devm_of_regulator_all_get(struct device *dev,
+ unsigned int *num_consumers,
+ struct regulator_bulk_data **consumers)
+{
+ *num_consumers = 0;
+ *consumers = NULL;
+
+ return 0;
+}
#endif /* CONFIG_OF */
#endif /* __LINUX_OF_REG_H */
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2016-06-09 12:40 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rI5xv-579-5@gated-at.bofh.it> |
| In reply to | #1418214 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Jun 09, 2016 at 11:44:18AM +0200, Krzysztof Kozlowski wrote: > Few drivers have a need of getting regulator supplies without knowing > their names: > 1. The Simple Framebuffer driver works on setup provided by bootloader > (outside of scope of kernel); > 2. Generic power sequence driver may be attached to any device node. > > Add a Device Tree helper for parsing "-supply" properties and returning > allocated bulk regulator consumers. I'm still very concerned that this is just an invitation to people to write half baked regulator consumers and half baked DTs to go along with it, making it a standard API that doesn't have big red flags on it that will flag up when "normal" drivers use it is not good. Right now this just looks like a standard API and people are going to just start using it. If we are going to do this perhaps we need a separate header or something to help flag this up. In the case of power sequences I'd expect the sequences to perform operations on named supplies - the core shouldn't know what the supplies are but the thing specifying the sequence should. > drivers/regulator/of_regulator.c | 86 ++++++++++++++++++++++++++++++++++ > include/linux/regulator/of_regulator.h | 13 +++++ > 2 files changed, 99 insertions(+) The external interface shouldn't be DT specific, the Intel people are busy importing all of DT into ACPI so they'll doubtless want an ACPI version.
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 13:50 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rI6Df-5Oe-15@gated-at.bofh.it> |
| In reply to | #1418226 |
On 06/09/2016 12:29 PM, Mark Brown wrote:
> On Thu, Jun 09, 2016 at 11:44:18AM +0200, Krzysztof Kozlowski wrote:
>> Few drivers have a need of getting regulator supplies without knowing
>> their names:
>> 1. The Simple Framebuffer driver works on setup provided by bootloader
>> (outside of scope of kernel);
>> 2. Generic power sequence driver may be attached to any device node.
>>
>> Add a Device Tree helper for parsing "-supply" properties and returning
>> allocated bulk regulator consumers.
>
> I'm still very concerned that this is just an invitation to people to
> write half baked regulator consumers and half baked DTs to go along with
> it, making it a standard API that doesn't have big red flags on it that
> will flag up when "normal" drivers use it is not good. Right now this
> just looks like a standard API and people are going to just start using
> it. If we are going to do this perhaps we need a separate header or
> something to help flag this up.
No problem, I can move it to a special header. Actually, if you dislike
this as an API, it does not have to be in header at all. I can just
duplicate the simplefb code.
> In the case of power sequences I'd expect the sequences to perform
> operations on named supplies - the core shouldn't know what the supplies
> are but the thing specifying the sequence should.
Hm, so maybe passing names like:
usb3503@08 {
reset-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
initial-mode = <1>;
vdd-supply = <&buck8_reg>;
foo-supply = <&buck9_reg>;
power-sequence;
power-sequence-supplies = "vdd", "foo";
};
but this is getting against initial idea of not adding any
power-sequence properties.
>
>> drivers/regulator/of_regulator.c | 86 ++++++++++++++++++++++++++++++++++
>> include/linux/regulator/of_regulator.h | 13 +++++
>> 2 files changed, 99 insertions(+)
>
> The external interface shouldn't be DT specific, the Intel people are
> busy importing all of DT into ACPI so they'll doubtless want an ACPI
> version.
Sure, I'll add it if this approach is acceptable. At this moment this
is not necessary to show my idea so I prefer to avoid doing work which
might be discarded very fast by review.
Thanks for feedback!
Best regards,
Krzysztof
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-06-10 19:40 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rIyzw-7xq-35@gated-at.bofh.it> |
| In reply to | #1418255 |
On Thu, Jun 09, 2016 at 01:42:02PM +0200, Krzysztof Kozlowski wrote:
> On 06/09/2016 12:29 PM, Mark Brown wrote:
> > On Thu, Jun 09, 2016 at 11:44:18AM +0200, Krzysztof Kozlowski wrote:
> >> Few drivers have a need of getting regulator supplies without knowing
> >> their names:
> >> 1. The Simple Framebuffer driver works on setup provided by bootloader
> >> (outside of scope of kernel);
> >> 2. Generic power sequence driver may be attached to any device node.
> >>
> >> Add a Device Tree helper for parsing "-supply" properties and returning
> >> allocated bulk regulator consumers.
> >
> > I'm still very concerned that this is just an invitation to people to
> > write half baked regulator consumers and half baked DTs to go along with
> > it, making it a standard API that doesn't have big red flags on it that
> > will flag up when "normal" drivers use it is not good. Right now this
> > just looks like a standard API and people are going to just start using
> > it. If we are going to do this perhaps we need a separate header or
> > something to help flag this up.
>
> No problem, I can move it to a special header. Actually, if you dislike
> this as an API, it does not have to be in header at all. I can just
> duplicate the simplefb code.
>
> > In the case of power sequences I'd expect the sequences to perform
> > operations on named supplies - the core shouldn't know what the supplies
> > are but the thing specifying the sequence should.
>
> Hm, so maybe passing names like:
>
> usb3503@08 {
> reset-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
> initial-mode = <1>;
> vdd-supply = <&buck8_reg>;
> foo-supply = <&buck9_reg>;
>
> power-sequence;
> power-sequence-supplies = "vdd", "foo";
This alone would be fine as it is just one property, but then what's
next? power-sequence-delay, power-sequence-clocks, etc. What if you
need to express ordering relationship of supplies, clocks, gpios? We end
up with a scripting language in DT and we don't want to have that.
Rob
[toc] | [prev] | [next] | [standalone]
| From | Heiko Stübner <heiko@sntech.de> |
|---|---|
| Date | 2016-06-10 21:00 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rIzOV-8sC-3@gated-at.bofh.it> |
| In reply to | #1419619 |
Am Freitag, 10. Juni 2016, 12:30:56 schrieb Rob Herring:
> On Thu, Jun 09, 2016 at 01:42:02PM +0200, Krzysztof Kozlowski wrote:
> > On 06/09/2016 12:29 PM, Mark Brown wrote:
> > > On Thu, Jun 09, 2016 at 11:44:18AM +0200, Krzysztof Kozlowski wrote:
> > >> Few drivers have a need of getting regulator supplies without knowing
> > >> their names:
> > >> 1. The Simple Framebuffer driver works on setup provided by bootloader
> > >>
> > >> (outside of scope of kernel);
> > >>
> > >> 2. Generic power sequence driver may be attached to any device node.
> > >>
> > >> Add a Device Tree helper for parsing "-supply" properties and returning
> > >> allocated bulk regulator consumers.
> > >
> > > I'm still very concerned that this is just an invitation to people to
> > > write half baked regulator consumers and half baked DTs to go along with
> > > it, making it a standard API that doesn't have big red flags on it that
> > > will flag up when "normal" drivers use it is not good. Right now this
> > > just looks like a standard API and people are going to just start using
> > > it. If we are going to do this perhaps we need a separate header or
> > > something to help flag this up.
> >
> > No problem, I can move it to a special header. Actually, if you dislike
> > this as an API, it does not have to be in header at all. I can just
> > duplicate the simplefb code.
> >
> > > In the case of power sequences I'd expect the sequences to perform
> > > operations on named supplies - the core shouldn't know what the supplies
> > > are but the thing specifying the sequence should.
> >
> > Hm, so maybe passing names like:
> >
> > usb3503@08 {
> >
> > reset-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
> > initial-mode = <1>;
> > vdd-supply = <&buck8_reg>;
> > foo-supply = <&buck9_reg>;
> >
> > power-sequence;
> >
> > power-sequence-supplies = "vdd", "foo";
>
> This alone would be fine as it is just one property, but then what's
> next? power-sequence-delay, power-sequence-clocks, etc. What if you
> need to express ordering relationship of supplies, clocks, gpios? We end
> up with a scripting language in DT and we don't want to have that.
Also, at least from the simple blocks I've seen so far (usb-hub chips, usb-
sata bridges), a power-supply feels more like it should be a regular phy-
supply of the usbphy connected the the host-controller.
It's similar for mmc-controllers where vmmc-supply on the controller handles
the power-supply of the connected card and thus the current mmc power-
sequences do not handle regulators.
Reset-gpios and clock inputs are clearly properties of the actual device, but
the supply control should probably lay with the host controller, especially as
it is the one deciding when to power on/off things.
[toc] | [prev] | [next] | [standalone]
| From | "Rafael J. Wysocki" <rafael@kernel.org> |
|---|---|
| Date | 2016-06-09 15:00 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rI7IZ-6uB-13@gated-at.bofh.it> |
| In reply to | #1418226 |
On Thu, Jun 9, 2016 at 12:29 PM, Mark Brown <broonie@kernel.org> wrote: > On Thu, Jun 09, 2016 at 11:44:18AM +0200, Krzysztof Kozlowski wrote: >> Few drivers have a need of getting regulator supplies without knowing >> their names: >> 1. The Simple Framebuffer driver works on setup provided by bootloader >> (outside of scope of kernel); >> 2. Generic power sequence driver may be attached to any device node. >> >> Add a Device Tree helper for parsing "-supply" properties and returning >> allocated bulk regulator consumers. > > I'm still very concerned that this is just an invitation to people to > write half baked regulator consumers and half baked DTs to go along with > it, making it a standard API that doesn't have big red flags on it that > will flag up when "normal" drivers use it is not good. Right now this > just looks like a standard API and people are going to just start using > it. If we are going to do this perhaps we need a separate header or > something to help flag this up. > > In the case of power sequences I'd expect the sequences to perform > operations on named supplies - the core shouldn't know what the supplies > are but the thing specifying the sequence should. > >> drivers/regulator/of_regulator.c | 86 ++++++++++++++++++++++++++++++++++ >> include/linux/regulator/of_regulator.h | 13 +++++ >> 2 files changed, 99 insertions(+) > > The external interface shouldn't be DT specific, the Intel people are > busy importing all of DT into ACPI Well, not really. If you are referring to the pinctrl proposal discussed recently, that was a proposal from one group at Intel and AFAICS it has been abandoned. > so they'll doubtless want an ACPI version. That is possible, though, so I agree that the external interface should not be DT-specific.
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2016-06-09 18:00 +0200 |
| Subject | Re: [RFC v4 01/14] regulator: of: Add helper for getting all supplies |
| Message-ID | <rIaxb-8nf-15@gated-at.bofh.it> |
| In reply to | #1418297 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Jun 09, 2016 at 02:50:26PM +0200, Rafael J. Wysocki wrote: > On Thu, Jun 9, 2016 at 12:29 PM, Mark Brown <broonie@kernel.org> wrote: > > The external interface shouldn't be DT specific, the Intel people are > > busy importing all of DT into ACPI > Well, not really. > If you are referring to the pinctrl proposal discussed recently, that > was a proposal from one group at Intel and AFAICS it has been > abandoned. Well, it was that, it was the device properties stuff in general and the overlays stuff - plus just the fact that with the Minnowboard style use case people have and the desire to use ACPI it seems like that's going to be something you need.
[toc] | [prev] | [next] | [standalone]
| From | Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|---|---|
| Date | 2016-06-09 12:00 +0200 |
| Subject | [RFC v4 03/14] power/mmc: Move pwrseq drivers to power/pwrseq |
| Message-ID | <rI4UO-4Do-31@gated-at.bofh.it> |
| In reply to | #1418205 |
The MMC power sequence drivers are useful also outside of MMC world: for
USB devices needed a hard-reset before probing. Before extending and
re-using pwrseq drivers, move them to a new place.
The commit does not introduce significant changes in the pwrseq drivers
code so still all the functions are prefixed with "mmc_pwrseq". However
the MMC-specific pwrseq functions has to be now exported and everything
is hidden not by CONFIG_OF but by new CONFIG_POWER_SEQ option.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
.../pwrseq/pwrseq-emmc.txt} | 0
.../pwrseq/pwrseq-simple.txt} | 0
drivers/mmc/Kconfig | 2 --
drivers/mmc/core/Makefile | 3 ---
drivers/mmc/core/core.c | 2 +-
drivers/mmc/core/host.c | 2 +-
drivers/power/Kconfig | 1 +
drivers/power/Makefile | 1 +
drivers/{mmc/core => power/pwrseq}/Kconfig | 18 +++++++++++++-----
drivers/power/pwrseq/Makefile | 3 +++
drivers/{mmc/core => power/pwrseq}/pwrseq.c | 8 ++++++--
drivers/{mmc/core => power/pwrseq}/pwrseq_emmc.c | 3 +--
drivers/{mmc/core => power/pwrseq}/pwrseq_simple.c | 3 +--
{drivers/mmc/core => include/linux}/pwrseq.h | 6 +++---
14 files changed, 31 insertions(+), 21 deletions(-)
rename Documentation/devicetree/bindings/{mmc/mmc-pwrseq-emmc.txt => power/pwrseq/pwrseq-emmc.txt} (100%)
rename Documentation/devicetree/bindings/{mmc/mmc-pwrseq-simple.txt => power/pwrseq/pwrseq-simple.txt} (100%)
rename drivers/{mmc/core => power/pwrseq}/Kconfig (66%)
create mode 100644 drivers/power/pwrseq/Makefile
rename drivers/{mmc/core => power/pwrseq}/pwrseq.c (90%)
rename drivers/{mmc/core => power/pwrseq}/pwrseq_emmc.c (99%)
rename drivers/{mmc/core => power/pwrseq}/pwrseq_simple.c (99%)
rename {drivers/mmc/core => include/linux}/pwrseq.h (94%)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.txt b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-emmc.txt
similarity index 100%
rename from Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.txt
rename to Documentation/devicetree/bindings/power/pwrseq/pwrseq-emmc.txt
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-simple.txt
similarity index 100%
rename from Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
rename to Documentation/devicetree/bindings/power/pwrseq/pwrseq-simple.txt
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index f2eeb38efa65..7ade379e0634 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -21,8 +21,6 @@ config MMC_DEBUG
if MMC
-source "drivers/mmc/core/Kconfig"
-
source "drivers/mmc/card/Kconfig"
source "drivers/mmc/host/Kconfig"
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index f007151dfdc6..a901d3cd09d3 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -8,7 +8,4 @@ mmc_core-y := core.o bus.o host.o \
sdio.o sdio_ops.o sdio_bus.o \
sdio_cis.o sdio_io.o sdio_irq.o \
quirks.o slot-gpio.o
-mmc_core-$(CONFIG_OF) += pwrseq.o
-obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
-obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8b4dfd45433b..edefc3fbebe6 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -25,6 +25,7 @@
#include <linux/pm_runtime.h>
#include <linux/pm_wakeup.h>
#include <linux/suspend.h>
+#include <linux/pwrseq.h>
#include <linux/fault-inject.h>
#include <linux/random.h>
#include <linux/slab.h>
@@ -43,7 +44,6 @@
#include "bus.h"
#include "host.h"
#include "sdio_bus.h"
-#include "pwrseq.h"
#include "mmc_ops.h"
#include "sd_ops.h"
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 1be42fab1a30..1db7d5802adc 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -21,6 +21,7 @@
#include <linux/export.h>
#include <linux/leds.h>
#include <linux/slab.h>
+#include <linux/pwrseq.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -29,7 +30,6 @@
#include "core.h"
#include "host.h"
#include "slot-gpio.h"
-#include "pwrseq.h"
#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 421770ddafa3..2702aca6cd2c 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -511,5 +511,6 @@ config AXP20X_POWER
endif # POWER_SUPPLY
+source "drivers/power/pwrseq/Kconfig"
source "drivers/power/reset/Kconfig"
source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e46b75d448a5..02f9d5da2e76 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_POWER_AVS) += avs/
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
+obj-$(CONFIG_POWER_SEQ) += pwrseq/
obj-$(CONFIG_POWER_RESET) += reset/
obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o
obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o
diff --git a/drivers/mmc/core/Kconfig b/drivers/power/pwrseq/Kconfig
similarity index 66%
rename from drivers/mmc/core/Kconfig
rename to drivers/power/pwrseq/Kconfig
index 250f223aaa80..7ecd66ab61f3 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/power/pwrseq/Kconfig
@@ -1,7 +1,13 @@
-#
-# MMC core configuration
-#
-config PWRSEQ_EMMC
+menuconfig POWER_SEQ
+ default y if OF
+ bool "Hardware reset support for specific devices"
+ help
+ Provides drivers that implements specific power sequences for chips,
+ using the generic power sequence management interface.
+
+if POWER_SEQ
+
+config POWER_SEQ_EMMC
tristate "HW reset support for eMMC"
default y
depends on OF
@@ -12,7 +18,7 @@ config PWRSEQ_EMMC
This driver can also be built as a module. If so, the module
will be called pwrseq_emmc.
-config PWRSEQ_SIMPLE
+config POWER_SEQ_SIMPLE
tristate "Simple HW reset support for MMC"
default y
depends on OF
@@ -22,3 +28,5 @@ config PWRSEQ_SIMPLE
This driver can also be built as a module. If so, the module
will be called pwrseq_simple.
+
+endif
diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile
new file mode 100644
index 000000000000..9e40e4b9068b
--- /dev/null
+++ b/drivers/power/pwrseq/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_POWER_SEQ) += pwrseq.o
+obj-$(CONFIG_POWER_SEQ_SIMPLE) += pwrseq_simple.o
+obj-$(CONFIG_POWER_SEQ_EMMC) += pwrseq_emmc.o
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/power/pwrseq/pwrseq.c
similarity index 90%
rename from drivers/mmc/core/pwrseq.c
rename to drivers/power/pwrseq/pwrseq.c
index 9386c4771814..66310d7643cc 100644
--- a/drivers/mmc/core/pwrseq.c
+++ b/drivers/power/pwrseq/pwrseq.c
@@ -11,11 +11,10 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pwrseq.h>
#include <linux/mmc/host.h>
-#include "pwrseq.h"
-
static DEFINE_MUTEX(pwrseq_list_mutex);
static LIST_HEAD(pwrseq_list);
@@ -51,6 +50,7 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
return 0;
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_alloc);
void mmc_pwrseq_pre_power_on(struct mmc_host *host)
{
@@ -59,6 +59,7 @@ void mmc_pwrseq_pre_power_on(struct mmc_host *host)
if (pwrseq && pwrseq->ops->pre_power_on)
pwrseq->ops->pre_power_on(host);
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_pre_power_on);
void mmc_pwrseq_post_power_on(struct mmc_host *host)
{
@@ -67,6 +68,7 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host)
if (pwrseq && pwrseq->ops->post_power_on)
pwrseq->ops->post_power_on(host);
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_post_power_on);
void mmc_pwrseq_power_off(struct mmc_host *host)
{
@@ -75,6 +77,7 @@ void mmc_pwrseq_power_off(struct mmc_host *host)
if (pwrseq && pwrseq->ops->power_off)
pwrseq->ops->power_off(host);
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_power_off);
void mmc_pwrseq_free(struct mmc_host *host)
{
@@ -85,6 +88,7 @@ void mmc_pwrseq_free(struct mmc_host *host)
host->pwrseq = NULL;
}
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_free);
int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
{
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/power/pwrseq/pwrseq_emmc.c
similarity index 99%
rename from drivers/mmc/core/pwrseq_emmc.c
rename to drivers/power/pwrseq/pwrseq_emmc.c
index adc9c0c614fb..a0583ed46d7f 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/power/pwrseq/pwrseq_emmc.c
@@ -17,11 +17,10 @@
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/reboot.h>
+#include <linux/pwrseq.h>
#include <linux/mmc/host.h>
-#include "pwrseq.h"
-
struct mmc_pwrseq_emmc {
struct mmc_pwrseq pwrseq;
struct notifier_block reset_nb;
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/power/pwrseq/pwrseq_simple.c
similarity index 99%
rename from drivers/mmc/core/pwrseq_simple.c
rename to drivers/power/pwrseq/pwrseq_simple.c
index 450d907c6e6c..786f1db53a3f 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/power/pwrseq/pwrseq_simple.c
@@ -16,11 +16,10 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
+#include <linux/pwrseq.h>
#include <linux/mmc/host.h>
-#include "pwrseq.h"
-
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
diff --git a/drivers/mmc/core/pwrseq.h b/include/linux/pwrseq.h
similarity index 94%
rename from drivers/mmc/core/pwrseq.h
rename to include/linux/pwrseq.h
index d69e751f148b..e230670c1d8d 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/include/linux/pwrseq.h
@@ -23,7 +23,7 @@ struct mmc_pwrseq {
struct module *owner;
};
-#ifdef CONFIG_OF
+#ifdef CONFIG_POWER_SEQ
int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq);
void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq);
@@ -34,7 +34,7 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host);
void mmc_pwrseq_power_off(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
-#else
+#else /* CONFIG_POWER_SEQ */
static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
{
@@ -47,6 +47,6 @@ static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {}
static inline void mmc_pwrseq_power_off(struct mmc_host *host) {}
static inline void mmc_pwrseq_free(struct mmc_host *host) {}
-#endif
+#endif /* CONFIG_POWER_SEQ */
#endif
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web