* [U-Boot] [PATCH v8 01/10] reset: add reset_request()
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all() patrice.chotard at st.com
` (9 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
This is needed in error path to assert previously deasserted
reset by using a saved reset_ctl reference.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v8: _ none
v7: _ none
v6: _ none
v5: _ none
v4: _ none
v3: _ none
v2: _ none
drivers/reset/reset-uclass.c | 9 +++++++++
include/reset.h | 9 +++++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index de3695f..4fd82b9 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -97,6 +97,15 @@ int reset_get_by_name(struct udevice *dev, const char *name,
return reset_get_by_index(dev, index, reset_ctl);
}
+int reset_request(struct reset_ctl *reset_ctl)
+{
+ struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
+
+ debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
+
+ return ops->request(reset_ctl);
+}
+
int reset_free(struct reset_ctl *reset_ctl)
{
struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
diff --git a/include/reset.h b/include/reset.h
index f45fcf8..4f2e35f 100644
--- a/include/reset.h
+++ b/include/reset.h
@@ -100,6 +100,15 @@ int reset_get_by_name(struct udevice *dev, const char *name,
struct reset_ctl *reset_ctl);
/**
+ * reset_request - Request a reset signal.
+ *
+ * @reset_ctl: A reset control struct.
+ *
+ * @return 0 if OK, or a negative error code.
+ */
+int reset_request(struct reset_ctl *reset_ctl);
+
+/**
* reset_free - Free a previously requested reset signal.
*
* @reset_ctl: A reset control struct that was previously successfully
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all()
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 01/10] reset: add reset_request() patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 9:02 ` Lothar Waßmann
2017-06-21 7:50 ` [U-Boot] [PATCH v8 03/10] clk: add clk_disable_all() patrice.chotard at st.com
` (8 subsequent siblings)
10 siblings, 1 reply; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
Add reset_assert_all() method which Request/Assert/Free an
array of resets signal that has been previously successfully
requested by reset_get_by_*()
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v8: _ none
v7: _ none
v6: _ none
v5: _ none
v4: _ add reset_assert_all() method as suggested by Marek Vasut
and Simon Glass
drivers/reset/reset-uclass.c | 22 ++++++++++++++++++++++
include/reset.h | 17 +++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index 4fd82b9..c39ce14 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -133,6 +133,28 @@ int reset_deassert(struct reset_ctl *reset_ctl)
return ops->rst_deassert(reset_ctl);
}
+int reset_assert_all(struct reset_ctl *reset_ctl, int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ debug("%s(reset_ctl[%d]=%p)\n", __func__, i, &reset_ctl[i]);
+
+ ret = reset_request(&reset_ctl[i]);
+ if (ret)
+ return ret;
+
+ ret = reset_assert(&reset_ctl[i]);
+ if (ret)
+ return ret;
+
+ ret = reset_free(&reset_ctl[i]);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
UCLASS_DRIVER(reset) = {
.id = UCLASS_RESET,
.name = "reset",
diff --git a/include/reset.h b/include/reset.h
index 4f2e35f..2678257 100644
--- a/include/reset.h
+++ b/include/reset.h
@@ -144,6 +144,17 @@ int reset_assert(struct reset_ctl *reset_ctl);
*/
int reset_deassert(struct reset_ctl *reset_ctl);
+/**
+ * reset_assert_all - Request/Assert/Free resets.
+ *
+ * This function will request, assert and free array of clocks,
+ *
+ * @reset_ctl: A reset struct array that was previously successfully
+ * requested by reset_get_by_*().
+ * @count Number of reset contained in the array
+ * @return 0 if OK, or a negative error code.
+ */
+int reset_assert_all(struct reset_ctl *reset_ctl, int count);
#else
static inline int reset_get_by_index(struct udevice *dev, int index,
struct reset_ctl *reset_ctl)
@@ -171,6 +182,12 @@ static inline int reset_deassert(struct reset_ctl *reset_ctl)
{
return 0;
}
+
+static inline int reset_assert_all(struct reset_ctl *reset_ctl, int count)
+{
+ return 0;
+}
+
#endif
#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all()
2017-06-21 7:50 ` [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all() patrice.chotard at st.com
@ 2017-06-21 9:02 ` Lothar Waßmann
2017-06-21 11:18 ` Patrice CHOTARD
0 siblings, 1 reply; 16+ messages in thread
From: Lothar Waßmann @ 2017-06-21 9:02 UTC (permalink / raw)
To: u-boot
Hi,
On Wed, 21 Jun 2017 09:50:16 +0200 patrice.chotard at st.com wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
>
> Add reset_assert_all() method which Request/Assert/Free an
> array of resets signal that has been previously successfully
> requested by reset_get_by_*()
>
IMO this is a terrible API. The purpose of a request() function is to
mark a resource as in-use, so that it cannot be deallocated or
otherwise destroyed until it is explicitly freed by the user.
It doesn't make any sense to request a resource, perform an action on
it (enable/disable a clock, assert/deasser a reset line, ...) and
free it right away.
The caller of reset_assert_all() should make sure that all reset
resources are requested before calling this function and keep them
requested until after relinquish using them.
The same holds for the clk_disable_all() in your other patch.
Lothar Waßmann
^ permalink raw reply [flat|nested] 16+ messages in thread
* [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all()
2017-06-21 9:02 ` Lothar Waßmann
@ 2017-06-21 11:18 ` Patrice CHOTARD
0 siblings, 0 replies; 16+ messages in thread
From: Patrice CHOTARD @ 2017-06-21 11:18 UTC (permalink / raw)
To: u-boot
Hi
On 06/21/2017 11:02 AM, Lothar Waßmann wrote:
> Hi,
>
> On Wed, 21 Jun 2017 09:50:16 +0200 patrice.chotard at st.com wrote:
>> From: Patrice Chotard <patrice.chotard@st.com>
>>
>> Add reset_assert_all() method which Request/Assert/Free an
>> array of resets signal that has been previously successfully
>> requested by reset_get_by_*()
>>
> IMO this is a terrible API. The purpose of a request() function is to
> mark a resource as in-use, so that it cannot be deallocated or
> otherwise destroyed until it is explicitly freed by the user.
>
> It doesn't make any sense to request a resource, perform an action on
> it (enable/disable a clock, assert/deasser a reset line, ...) and
> free it right away.
>
> The caller of reset_assert_all() should make sure that all reset
> resources are requested before calling this function and keep them
> requested until after relinquish using them.
> The same holds for the clk_disable_all() in your other patch.
Following your remark in patch 7, i have started to rework this API as
you described here by removing the request in reset_assert_all() and in
clock_disable_all(). I agree it makes no sense.
It will be fixed in the v9
Thanks
Patrice
>
>
>
> Lothar Waßmann
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [U-Boot] [PATCH v8 03/10] clk: add clk_disable_all()
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 01/10] reset: add reset_request() patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 02/10] reset: add reset_assert_all() patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 04/10] dm: core: add ofnode_count_phandle_with_args() patrice.chotard at st.com
` (7 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
Add clk_disable_all() method which Request/Disable/Free an
array of clocks that has been previously requested by
clk_request/get_by_*()
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ replace clk->dev by clk[i].dev in clk_request() param
v7: _ none
v6: _ none
v5: _ none
v4: _ none
v3: _ add commit message
v2: _ create this independant path for printf() replacement
drivers/clk/clk-uclass.c | 22 ++++++++++++++++++++++
include/clk.h | 10 ++++++++++
2 files changed, 32 insertions(+)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 83b6328..f6ad106 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -187,6 +187,28 @@ int clk_disable(struct clk *clk)
return ops->disable(clk);
}
+int clk_disable_all(struct clk *clk, int count)
+{
+ int i, ret;
+
+ debug("%s(clk=%p count=%d)\n", __func__, clk, count);
+
+ for (i = 0; i < count; i++) {
+ ret = clk_request(clk[i].dev, &clk[i]);
+ if (ret && ret != -ENOSYS)
+ return ret;
+
+ ret = clk_disable(&clk[i]);
+ if (ret && ret != -ENOSYS)
+ return ret;
+
+ ret = clk_free(&clk[i]);
+ if (ret && ret != -ENOSYS)
+ return ret;
+ }
+ return 0;
+}
+
UCLASS_DRIVER(clk) = {
.id = UCLASS_CLK,
.name = "clk",
diff --git a/include/clk.h b/include/clk.h
index 5a5c2ff..e04c274 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -174,6 +174,16 @@ int clk_enable(struct clk *clk);
*/
int clk_disable(struct clk *clk);
+/**
+ * clk_disable_all() - Request/Disable (turn off)/Free clocks.
+ *
+ * @clk: A clock struct array that was previously successfully
+ * requested by clk_request/get_by_*().
+ * @count Number of clock contained in the array
+ * @return zero on success, or -ve error code.
+ */
+int clk_disable_all(struct clk *clk, int count);
+
int soc_clk_dump(void);
#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 04/10] dm: core: add ofnode_count_phandle_with_args()
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (2 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 03/10] clk: add clk_disable_all() patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 05/10] usb: host: ehci-generic: replace printf() by error() patrice.chotard at st.com
` (6 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
This function is usefull to get phandle number contained
in a property list.
For example, this allows to allocate the right amount
of memory to keep clock's reference contained into the
"clocks" property.
To implement it, either of_count_phandle_with_args() or
fdtdec_parse_phandle_with_args() are used respectively
for live tree and flat tree.
By passing index = -1, these 2 functions returns the
number of phandle contained into the property list.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v8: _ none
v7: _ add ofnode_count_phandle_with_args() which returns
the phandle number contained into a property list.
drivers/core/of_access.c | 7 +++++++
drivers/core/ofnode.c | 12 ++++++++++++
include/dm/of_access.h | 18 ++++++++++++++++++
include/dm/ofnode.h | 17 +++++++++++++++++
4 files changed, 54 insertions(+)
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 93a6560..76d5996 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -641,6 +641,13 @@ int of_parse_phandle_with_args(const struct device_node *np,
index, out_args);
}
+int of_count_phandle_with_args(const struct device_node *np,
+ const char *list_name, const char *cells_name)
+{
+ return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
+ -1, NULL);
+}
+
static void of_alias_add(struct alias_prop *ap, struct device_node *np,
int id, const char *stem, int stem_len)
{
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index ac312d6..02bc5d2 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -307,6 +307,18 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
return 0;
}
+int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
+ const char *cells_name)
+{
+ if (ofnode_is_np(node))
+ return of_count_phandle_with_args(ofnode_to_np(node),
+ list_name, cells_name);
+ else
+ return fdtdec_parse_phandle_with_args(gd->fdt_blob,
+ ofnode_to_offset(node), list_name, cells_name,
+ 0, -1, NULL);
+}
+
ofnode ofnode_path(const char *path)
{
if (of_live_active())
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index 142f0f4..5be29b1 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -315,6 +315,24 @@ int of_parse_phandle_with_args(const struct device_node *np,
int index, struct of_phandle_args *out_args);
/**
+ * of_count_phandle_with_args() - Count the number of phandle in a list
+ *
+ * @np: pointer to a device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name: property name that specifies phandles' arguments count
+ * @return number of phandle found, -ENOENT if
+ * @list_name does not exist, -EINVAL if a phandle was not found,
+ * @cells_name could not be found, the arguments were truncated or there
+ * were too many arguments.
+ *
+ * Returns number of phandle found on success, on error returns appropriate
+ * errno value.
+ *
+ */
+int of_count_phandle_with_args(const struct device_node *np,
+ const char *list_name, const char *cells_name);
+
+/**
* of_alias_scan() - Scan all properties of the 'aliases' node
*
* The function scans all the properties of the 'aliases' node and populates
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 149622a..3f2cfbb 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -423,6 +423,23 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
struct ofnode_phandle_args *out_args);
/**
+ * ofnode_count_phandle_with_args() - Count number of phandle in a list
+ *
+ * This function is useful to count phandles into a list.
+ * Returns number of phandle on success, on error returns appropriate
+ * errno value.
+ *
+ * @node: device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name: property name that specifies phandles' arguments count
+ * @return number of phandle on success, -ENOENT if @list_name does not
+ * exist, -EINVAL if a phandle was not found, @cells_name could not
+ * be found.
+ */
+int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
+ const char *cells_name);
+
+/**
* ofnode_path() - find a node by full path
*
* @path: Full path to node, e.g. "/bus/spi at 1"
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 05/10] usb: host: ehci-generic: replace printf() by error()
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (3 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 04/10] dm: core: add ofnode_count_phandle_with_args() patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
` (5 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
this allows to get file, line and function location
of the current error message.
Signed-off-by: patrice chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v8: _ none
v7: _ none
v6: _ none
v5: _ none
v4: _ none
v3: _ add commit message
v2: _ create this independant path for printf() replacement
drivers/usb/host/ehci-generic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index fb78462..2116ae1 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -34,7 +34,7 @@ static int ehci_usb_probe(struct udevice *dev)
if (ret < 0)
break;
if (clk_enable(&clk))
- printf("failed to enable clock %d\n", i);
+ error("failed to enable clock %d\n", i);
clk_free(&clk);
}
@@ -46,7 +46,7 @@ static int ehci_usb_probe(struct udevice *dev)
if (ret < 0)
break;
if (reset_deassert(&reset))
- printf("failed to deassert reset %d\n", i);
+ error("failed to deassert reset %d\n", i);
reset_free(&reset);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (4 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 05/10] usb: host: ehci-generic: replace printf() by error() patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 07/10] usb: host: ehci-generic: add generic PHY support patrice.chotard at st.com
` (4 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
Use an array to save enabled clocks reference and deasserted resets
in order to respectively disabled and asserted them in case of error
during probe() or during driver removal.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ replace devm_kmalloc() by devm_kcalloc()
_ fix error path by propagating initial error code until the end of probe()
v7: _ replace clk_count() and reset_count() by ofnode_count_phandle_with_args()
v6: _ none
v5: _ none
v4: _ update the memory allocation for deasserted resets and enabled
clocks reference list. Replace lists by arrays.
_ usage of new RESET and CLOCK methods clk_count(), reset_count(),
reset_assert_all() and clk_disable_all().
v3: _ keep enabled clocks and deasserted resets reference in list in order to
disable clock or assert resets in error path or in .remove callback
_ use struct generic_ehci * instead of struct udevice * as parameter for
ehci_release_resets() and ehci_release_clocks()
drivers/usb/host/ehci-generic.c | 120 ++++++++++++++++++++++++++++++++--------
1 file changed, 97 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 2116ae1..5cc7f2a 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <clk.h>
+#include <dm/ofnode.h>
#include <reset.h>
#include <asm/io.h>
#include <dm.h>
@@ -18,43 +19,116 @@
*/
struct generic_ehci {
struct ehci_ctrl ctrl;
+ struct clk *clocks;
+ struct reset_ctl *resets;
+ int clock_count;
+ int reset_count;
};
static int ehci_usb_probe(struct udevice *dev)
{
+ struct generic_ehci *priv = dev_get_priv(dev);
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
- int i;
-
- for (i = 0; ; i++) {
- struct clk clk;
- int ret;
-
- ret = clk_get_by_index(dev, i, &clk);
- if (ret < 0)
- break;
- if (clk_enable(&clk))
- error("failed to enable clock %d\n", i);
- clk_free(&clk);
+ int i, err, ret, clock_nb, reset_nb;
+
+ err = 0;
+ priv->clock_count = 0;
+ clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
+ "#clock-cells");
+ if (clock_nb > 0) {
+ priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
+ GFP_KERNEL);
+ if (!priv->clocks)
+ return -ENOMEM;
+
+ for (i = 0; i < clock_nb; i++) {
+ err = clk_get_by_index(dev, i, &priv->clocks[i]);
+
+ if (err < 0)
+ break;
+ err = clk_enable(&priv->clocks[i]);
+ if (err) {
+ error("failed to enable clock %d\n", i);
+ clk_free(&priv->clocks[i]);
+ goto clk_err;
+ }
+ priv->clock_count++;
+ clk_free(&priv->clocks[i]);
+ }
+ } else {
+ if (clock_nb != -ENOENT) {
+ error("failed to get clock phandle(%d)\n", clock_nb);
+ return clock_nb;
+ }
}
- for (i = 0; ; i++) {
- struct reset_ctl reset;
- int ret;
+ priv->reset_count = 0;
+ reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
+ "#reset-cells");
+ if (reset_nb > 0) {
+ priv->resets = devm_kcalloc(dev, reset_nb,
+ sizeof(struct reset_ctl),
+ GFP_KERNEL);
+ if (!priv->resets)
+ return -ENOMEM;
+
+ for (i = 0; i < reset_nb; i++) {
+ err = reset_get_by_index(dev, i, &priv->resets[i]);
+ if (err < 0)
+ break;
- ret = reset_get_by_index(dev, i, &reset);
- if (ret < 0)
- break;
- if (reset_deassert(&reset))
- error("failed to deassert reset %d\n", i);
- reset_free(&reset);
+ if (reset_deassert(&priv->resets[i])) {
+ error("failed to deassert reset %d\n", i);
+ reset_free(&priv->resets[i]);
+ goto reset_err;
+ }
+ priv->reset_count++;
+ reset_free(&priv->resets[i]);
+ }
+ } else {
+ if (reset_nb != -ENOENT) {
+ error("failed to get reset phandle(%d)\n", reset_nb);
+ goto clk_err;
+ }
}
hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
hcor = (struct ehci_hcor *)((uintptr_t)hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
- return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+ err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+ if (err)
+ goto reset_err;
+
+ return 0;
+
+reset_err:
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ error("failed to assert all resets\n");
+clk_err:
+ ret = clk_disable_all(priv->clocks, priv->clock_count);
+ if (ret)
+ error("failed to disable all clocks\n");
+
+ return err;
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+ struct generic_ehci *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
+
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ return ret;
+
+ return clk_disable_all(priv->clocks, priv->clock_count);
}
static const struct udevice_id ehci_usb_ids[] = {
@@ -67,7 +141,7 @@ U_BOOT_DRIVER(ehci_generic) = {
.id = UCLASS_USB,
.of_match = ehci_usb_ids,
.probe = ehci_usb_probe,
- .remove = ehci_deregister,
+ .remove = ehci_usb_remove,
.ops = &ehci_usb_ops,
.priv_auto_alloc_size = sizeof(struct generic_ehci),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 07/10] usb: host: ehci-generic: add generic PHY support
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (5 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
` (3 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
Extend ehci-generic driver with generic PHY framework
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ rework error path by propagating the initial error code until the end of probe()
v7: _ none
v6: _ none
v5: _ none
v4: _ update the memory allocation for deasserted resets and enabled
clocks reference list. Replace lists by arrays.
_ usage of new RESET and CLOCK methods clk_count(), reset_count(),
reset_assert_all() and clk_disable_all().
v3: _ keep enabled clocks and deasserted resets reference in list in order to
disable clock or assert resets in error path or in .remove callback
_ use struct generic_ehci * instead of struct udevice * as parameter for
ehci_release_resets() and ehci_release_clocks()
drivers/usb/host/ehci-generic.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 5cc7f2a..1f55b92 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <clk.h>
#include <dm/ofnode.h>
+#include <generic-phy.h>
#include <reset.h>
#include <asm/io.h>
#include <dm.h>
@@ -21,6 +22,7 @@ struct generic_ehci {
struct ehci_ctrl ctrl;
struct clk *clocks;
struct reset_ctl *resets;
+ struct phy phy;
int clock_count;
int reset_count;
};
@@ -93,16 +95,37 @@ static int ehci_usb_probe(struct udevice *dev)
}
}
+ err = generic_phy_get_by_index(dev, 0, &priv->phy);
+ if (err) {
+ if (err != -ENOENT) {
+ error("failed to get usb phy\n");
+ goto reset_err;
+ }
+ }
+
+ err = generic_phy_init(&priv->phy);
+ if (err) {
+ error("failed to init usb phy\n");
+ goto reset_err;
+ }
+
hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
hcor = (struct ehci_hcor *)((uintptr_t)hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
if (err)
- goto reset_err;
+ goto phy_err;
return 0;
+phy_err:
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ error("failed to release phy\n");
+ }
+
reset_err:
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
@@ -124,6 +147,12 @@ static int ehci_usb_remove(struct udevice *dev)
if (ret)
return ret;
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ return ret;
+ }
+
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
return ret;
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (6 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 07/10] usb: host: ehci-generic: add generic PHY support patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-07-06 4:48 ` Simon Glass
2017-06-21 7:50 ` [U-Boot] [PATCH v8 09/10] usb: host: ohci-generic: add RESET support patrice.chotard at st.com
` (2 subsequent siblings)
10 siblings, 1 reply; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
use array to save enabled clocks reference in order to
disabled them in case of error during probe() or during
driver removal.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ rework error path by propagating the initial error code until the end of probe()
v7: _ replace clk_count() by ofnode_count_phandle_with_args()
v6: _ none
v5: _ none
v4: _ use generic_phy_valid() before generic_phy_exit() call
v3: _ extract in this patch the CLOCK support add-on from previous patch 5
_ keep enabled clocks reference in list in order to
disable clocks in error path or in .remove callback
v2: _ add error path management
_ add .remove callback
drivers/usb/host/ohci-generic.c | 59 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index f85738f..15d1d60 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -5,7 +5,9 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
+#include <dm/ofnode.h>
#include "ohci.h"
#if !defined(CONFIG_USB_OHCI_NEW)
@@ -14,18 +16,71 @@
struct generic_ohci {
ohci_t ohci;
+ struct clk *clocks;
+ int clock_count;
};
static int ohci_usb_probe(struct udevice *dev)
{
struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
+ struct generic_ohci *priv = dev_get_priv(dev);
+ int i, err, ret, clock_nb;
- return ohci_register(dev, regs);
+ err = 0;
+ priv->clock_count = 0;
+ clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
+ "#clock-cells");
+ if (clock_nb > 0) {
+ priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
+ GFP_KERNEL);
+ if (!priv->clocks)
+ return -ENOMEM;
+
+ for (i = 0; i < clock_nb; i++) {
+ err = clk_get_by_index(dev, i, &priv->clocks[i]);
+ if (err < 0)
+ break;
+
+ err = clk_enable(&priv->clocks[i]);
+ if (err) {
+ error("failed to enable clock %d\n", i);
+ clk_free(&priv->clocks[i]);
+ goto clk_err;
+ }
+ priv->clock_count++;
+ clk_free(&priv->clocks[i]);
+ }
+ } else {
+ if (clock_nb != -ENOENT) {
+ error("failed to get clock phandle(%d)\n", clock_nb);
+ return clock_nb;
+ }
+ }
+
+ err = ohci_register(dev, regs);
+ if (err)
+ goto clk_err;
+
+ return 0;
+
+clk_err:
+ ret = clk_disable_all(priv->clocks, priv->clock_count);
+ if (ret)
+ error("failed to disable all clocks\n");
+
+ return err;
}
static int ohci_usb_remove(struct udevice *dev)
{
- return ohci_deregister(dev);
+ struct generic_ohci *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = ohci_deregister(dev);
+ if (ret)
+ return ret;
+
+ return clk_disable_all(priv->clocks, priv->clock_count);
}
static const struct udevice_id ohci_usb_ids[] = {
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-21 7:50 ` [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
@ 2017-07-06 4:48 ` Simon Glass
2017-07-06 7:09 ` Patrice CHOTARD
0 siblings, 1 reply; 16+ messages in thread
From: Simon Glass @ 2017-07-06 4:48 UTC (permalink / raw)
To: u-boot
On 21 June 2017 at 01:50, <patrice.chotard@st.com> wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
>
> use array to save enabled clocks reference in order to
> disabled them in case of error during probe() or during
> driver removal.
>
> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
> ---
> v8: _ rework error path by propagating the initial error code until the end of probe()
>
> v7: _ replace clk_count() by ofnode_count_phandle_with_args()
>
> v6: _ none
>
> v5: _ none
>
> v4: _ use generic_phy_valid() before generic_phy_exit() call
>
> v3: _ extract in this patch the CLOCK support add-on from previous patch 5
> _ keep enabled clocks reference in list in order to
> disable clocks in error path or in .remove callback
>
> v2: _ add error path management
> _ add .remove callback
>
> drivers/usb/host/ohci-generic.c | 59 +++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 57 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
Nits below (sorry) for a respin or follow-on.
>
> diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
> index f85738f..15d1d60 100644
> --- a/drivers/usb/host/ohci-generic.c
> +++ b/drivers/usb/host/ohci-generic.c
> @@ -5,7 +5,9 @@
> */
>
> #include <common.h>
> +#include <clk.h>
> #include <dm.h>
> +#include <dm/ofnode.h>
> #include "ohci.h"
>
> #if !defined(CONFIG_USB_OHCI_NEW)
> @@ -14,18 +16,71 @@
>
> struct generic_ohci {
> ohci_t ohci;
> + struct clk *clocks;
> + int clock_count;
> };
Please can you comment this struct?
>
> static int ohci_usb_probe(struct udevice *dev)
> {
> struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
> + struct generic_ohci *priv = dev_get_priv(dev);
> + int i, err, ret, clock_nb;
>
> - return ohci_register(dev, regs);
> + err = 0;
> + priv->clock_count = 0;
> + clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
> + "#clock-cells");
Could we have a dev_read_...() version of this?
> + if (clock_nb > 0) {
> + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
> + GFP_KERNEL);
> + if (!priv->clocks)
> + return -ENOMEM;
> +
> + for (i = 0; i < clock_nb; i++) {
> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
> + if (err < 0)
> + break;
> +
> + err = clk_enable(&priv->clocks[i]);
> + if (err) {
> + error("failed to enable clock %d\n", i);
> + clk_free(&priv->clocks[i]);
> + goto clk_err;
> + }
> + priv->clock_count++;
> + clk_free(&priv->clocks[i]);
> + }
> + } else {
> + if (clock_nb != -ENOENT) {
} else if (...
?
> + error("failed to get clock phandle(%d)\n", clock_nb);
> + return clock_nb;
> + }
> + }
> +
> + err = ohci_register(dev, regs);
> + if (err)
> + goto clk_err;
> +
> + return 0;
> +
> +clk_err:
> + ret = clk_disable_all(priv->clocks, priv->clock_count);
> + if (ret)
> + error("failed to disable all clocks\n");
> +
> + return err;
> }
>
> static int ohci_usb_remove(struct udevice *dev)
> {
> - return ohci_deregister(dev);
> + struct generic_ohci *priv = dev_get_priv(dev);
> + int ret;
> +
> + ret = ohci_deregister(dev);
> + if (ret)
> + return ret;
> +
> + return clk_disable_all(priv->clocks, priv->clock_count);
> }
>
> static const struct udevice_id ohci_usb_ids[] = {
> --
> 1.9.1
>
Regards,
Simon
^ permalink raw reply [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support
2017-07-06 4:48 ` Simon Glass
@ 2017-07-06 7:09 ` Patrice CHOTARD
0 siblings, 0 replies; 16+ messages in thread
From: Patrice CHOTARD @ 2017-07-06 7:09 UTC (permalink / raw)
To: u-boot
Hi Simon
On 07/06/2017 06:48 AM, Simon Glass wrote:
> On 21 June 2017 at 01:50, <patrice.chotard@st.com> wrote:
>> From: Patrice Chotard <patrice.chotard@st.com>
>>
>> use array to save enabled clocks reference in order to
>> disabled them in case of error during probe() or during
>> driver removal.
>>
>> Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
>> ---
>> v8: _ rework error path by propagating the initial error code until the end of probe()
>>
>> v7: _ replace clk_count() by ofnode_count_phandle_with_args()
>>
>> v6: _ none
>>
>> v5: _ none
>>
>> v4: _ use generic_phy_valid() before generic_phy_exit() call
>>
>> v3: _ extract in this patch the CLOCK support add-on from previous patch 5
>> _ keep enabled clocks reference in list in order to
>> disable clocks in error path or in .remove callback
>>
>> v2: _ add error path management
>> _ add .remove callback
>>
>> drivers/usb/host/ohci-generic.c | 59 +++++++++++++++++++++++++++++++++++++++--
>> 1 file changed, 57 insertions(+), 2 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Nits below (sorry) for a respin or follow-on.
>
>>
>> diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
>> index f85738f..15d1d60 100644
>> --- a/drivers/usb/host/ohci-generic.c
>> +++ b/drivers/usb/host/ohci-generic.c
>> @@ -5,7 +5,9 @@
>> */
>>
>> #include <common.h>
>> +#include <clk.h>
>> #include <dm.h>
>> +#include <dm/ofnode.h>
>> #include "ohci.h"
>>
>> #if !defined(CONFIG_USB_OHCI_NEW)
>> @@ -14,18 +16,71 @@
>>
>> struct generic_ohci {
>> ohci_t ohci;
>> + struct clk *clocks;
>> + int clock_count;
>> };
>
> Please can you comment this struct?
>
>>
>> static int ohci_usb_probe(struct udevice *dev)
>> {
>> struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
>> + struct generic_ohci *priv = dev_get_priv(dev);
>> + int i, err, ret, clock_nb;
>>
>> - return ohci_register(dev, regs);
>> + err = 0;
>> + priv->clock_count = 0;
>> + clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
>> + "#clock-cells");
>
> Could we have a dev_read_...() version of this?
Yes, i will add it
>
>> + if (clock_nb > 0) {
>> + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
>> + GFP_KERNEL);
>> + if (!priv->clocks)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < clock_nb; i++) {
>> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
>> + if (err < 0)
>> + break;
>> +
>> + err = clk_enable(&priv->clocks[i]);
>> + if (err) {
>> + error("failed to enable clock %d\n", i);
>> + clk_free(&priv->clocks[i]);
>> + goto clk_err;
>> + }
>> + priv->clock_count++;
>> + clk_free(&priv->clocks[i]);
>> + }
>> + } else {
>> + if (clock_nb != -ENOENT) {
>
> } else if (...
ok
>
> ?
>
>> + error("failed to get clock phandle(%d)\n", clock_nb);
>> + return clock_nb;
>> + }
>> + }
>> +
>> + err = ohci_register(dev, regs);
>> + if (err)
>> + goto clk_err;
>> +
>> + return 0;
>> +
>> +clk_err:
>> + ret = clk_disable_all(priv->clocks, priv->clock_count);
>> + if (ret)
>> + error("failed to disable all clocks\n");
>> +
>> + return err;
>> }
>>
>> static int ohci_usb_remove(struct udevice *dev)
>> {
>> - return ohci_deregister(dev);
>> + struct generic_ohci *priv = dev_get_priv(dev);
>> + int ret;
>> +
>> + ret = ohci_deregister(dev);
>> + if (ret)
>> + return ret;
>> +
>> + return clk_disable_all(priv->clocks, priv->clock_count);
>> }
>>
>> static const struct udevice_id ohci_usb_ids[] = {
>> --
>> 1.9.1
>>
>
> Regards,
> Simon
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [U-Boot] [PATCH v8 09/10] usb: host: ohci-generic: add RESET support
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (7 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 7:50 ` [U-Boot] [PATCH v8 10/10] usb: host: ohci-generic: add generic PHY support patrice.chotard at st.com
2017-06-21 8:35 ` [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers Patrice CHOTARD
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
use array to save deasserted resets reference in order to
assert them in case of error during probe() or during driver
removal.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ rework error path by propagating the initial error code until the end of probe()
_ replace devm_kmalloc() by devm_kcalloc()
v7: _ replace reset_count() by ofnode_count_phandle_with_args()
v6: _ none
v5: _ none
v4: _ update the memory allocation for deasserted resets. Replace lists by arrays.
_ usage of new RESET methods reset_assert_all() and clk_disable_all().
v3: _ extract in this patch the RESET support add-on from previous patch 5
_ keep deasserted resets reference in list in order to
assert resets in error path or in .remove callback
v2: _ add error path management
_ add .remove callback
drivers/usb/host/ohci-generic.c | 46 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index 15d1d60..1dc7449 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -8,6 +8,7 @@
#include <clk.h>
#include <dm.h>
#include <dm/ofnode.h>
+#include <reset.h>
#include "ohci.h"
#if !defined(CONFIG_USB_OHCI_NEW)
@@ -17,14 +18,16 @@
struct generic_ohci {
ohci_t ohci;
struct clk *clocks;
+ struct reset_ctl *resets;
int clock_count;
+ int reset_count;
};
static int ohci_usb_probe(struct udevice *dev)
{
struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
struct generic_ohci *priv = dev_get_priv(dev);
- int i, err, ret, clock_nb;
+ int i, err, ret, clock_nb, reset_nb;
err = 0;
priv->clock_count = 0;
@@ -57,12 +60,47 @@ static int ohci_usb_probe(struct udevice *dev)
}
}
+ priv->reset_count = 0;
+ reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
+ "#reset-cells");
+ if (reset_nb > 0) {
+ priv->resets = devm_kcalloc(dev, reset_nb,
+ sizeof(struct reset_ctl),
+ GFP_KERNEL);
+ if (!priv->resets)
+ return -ENOMEM;
+
+ for (i = 0; i < reset_nb; i++) {
+ err = reset_get_by_index(dev, i, &priv->resets[i]);
+ if (err < 0)
+ break;
+
+ err = reset_deassert(&priv->resets[i]);
+ if (err) {
+ error("failed to deassert reset %d\n", i);
+ reset_free(&priv->resets[i]);
+ goto reset_err;
+ }
+ priv->reset_count++;
+ reset_free(&priv->resets[i]);
+ }
+ } else {
+ if (reset_nb != -ENOENT) {
+ error("failed to get reset phandle(%d)\n", reset_nb);
+ goto clk_err;
+ }
+ }
+
err = ohci_register(dev, regs);
if (err)
- goto clk_err;
+ goto reset_err;
return 0;
+reset_err:
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ error("failed to assert all resets\n");
clk_err:
ret = clk_disable_all(priv->clocks, priv->clock_count);
if (ret)
@@ -80,6 +118,10 @@ static int ohci_usb_remove(struct udevice *dev)
if (ret)
return ret;
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ return ret;
+
return clk_disable_all(priv->clocks, priv->clock_count);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 10/10] usb: host: ohci-generic: add generic PHY support
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (8 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 09/10] usb: host: ohci-generic: add RESET support patrice.chotard at st.com
@ 2017-06-21 7:50 ` patrice.chotard at st.com
2017-06-21 8:35 ` [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers Patrice CHOTARD
10 siblings, 0 replies; 16+ messages in thread
From: patrice.chotard at st.com @ 2017-06-21 7:50 UTC (permalink / raw)
To: u-boot
From: Patrice Chotard <patrice.chotard@st.com>
Extend ohci-generic driver with generic PHY framework
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
---
v8: _ rework error path by propagating the initial error code until the end of probe()
v7: _ none
v6: _ none
v5: _ none
v4: _ use generic_phy_valid() before generic_phy_exit() call
v3: _ extract in this patch the PHY support add-on from previous patch 5
drivers/usb/host/ohci-generic.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index 1dc7449..03f2234 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -8,6 +8,7 @@
#include <clk.h>
#include <dm.h>
#include <dm/ofnode.h>
+#include <generic-phy.h>
#include <reset.h>
#include "ohci.h"
@@ -19,6 +20,7 @@ struct generic_ohci {
ohci_t ohci;
struct clk *clocks;
struct reset_ctl *resets;
+ struct phy phy;
int clock_count;
int reset_count;
};
@@ -91,12 +93,33 @@ static int ohci_usb_probe(struct udevice *dev)
}
}
+ err = generic_phy_get_by_index(dev, 0, &priv->phy);
+ if (err) {
+ if (err != -ENOENT) {
+ error("failed to get usb phy\n");
+ goto reset_err;
+ }
+ }
+
+ err = generic_phy_init(&priv->phy);
+ if (err) {
+ error("failed to init usb phy\n");
+ goto reset_err;
+ }
+
err = ohci_register(dev, regs);
if (err)
- goto reset_err;
+ goto phy_err;
return 0;
+phy_err:
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ error("failed to release phy\n");
+ }
+
reset_err:
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
@@ -118,6 +141,12 @@ static int ohci_usb_remove(struct udevice *dev)
if (ret)
return ret;
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ return ret;
+ }
+
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
return ret;
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers
2017-06-21 7:50 [U-Boot] [PATCH v8 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (9 preceding siblings ...)
2017-06-21 7:50 ` [U-Boot] [PATCH v8 10/10] usb: host: ohci-generic: add generic PHY support patrice.chotard at st.com
@ 2017-06-21 8:35 ` Patrice CHOTARD
10 siblings, 0 replies; 16+ messages in thread
From: Patrice CHOTARD @ 2017-06-21 8:35 UTC (permalink / raw)
To: u-boot
Don't take care of this series, I need to resend a new one
Sorry
On 06/21/2017 09:50 AM, patrice.chotard at st.com wrote:
> From: Patrice Chotard <patrice.chotard@st.com>
>
> This series improves generic ehci and ohci drivers by addition of :
> _ error path during probe (clocks, resets and phy release)
> _ .remove callback
> _ add generic PHY framework for both generic ehci and ohci drivers
> _ add RESET and CLOCK framework for generic ohci driver
>
> To implement these features, some new methods are needed in reset, clock and
> in dm/core framework:
> _ add reset_request() and reset_assert_all() methods in RESET framework
> _ add clk_count() and clk_disable_all() methods in CLOCK framework
> _ add ofnode_count_phandle_with_args() in dm/core
>
> v8: _ rework error path by propagating the initial error code until the end of probe()
> _ replace devm_kmalloc() with devm_kcalloc()
> _ fix cosmetics remarks
>
> v7: _ replace clk_count() and reset_count() methods by
> ofnode_count_phandle_with_args() in patches 3, 4 and 5
>
> v6: _ replace clk_get_by_index() by dev_read_phandle_with_args() in
> clk_count() in patch 4
> _ add Reviewed-by Simon Glass for patch 2 and 5
>
> v5: _ rebase on top of dm/master requested by Simon Glass in order to use
> livetree update
> _ replace fdtdec_parse_phandle_with_args() by dev_read_phandle_with_args() in patch 2
>
> v4: _ add clk_disable_all() and reset_assert_all() methods into CLOCK and
> RESET framework as suggested by Simon Glass and Marek Vasut
> _ add reset_count() and clk_count() methods which returns respectively the
> number of resets and clocks declared into "resets" and "clocks" DT properties.
> This allows to allocate the right amount of memory to keep resets and clocks
> reference
> _ update the memory allocation for deasserted resets and enabled
> clocks reference list. Replace lists by arrays.
>
> v3: _ keep enabled clocks and deasserted resets reference in list in order to
> disable clock or assert resets in error path or in .remove callback
> _ add missing commit message
> _ use struct generic_ehci * instead of struct udevice * as parameter for
> ehci_release_resets() and ehci_release_clocks()
> _ test return value on generic_phy_get_by_index() and
> generic_phy_init()
> _ split previous patch 5 in 3 independant patch for CLOCK, RESET and PHY support
>
> v2: _ add needed reset_request() in RESET framework
> _ add error path in ehci/ohci-generic to disable clocks and to assert
> resets
> _ add .remove callback with clocks, resets and phy release
> _ split the replacement of printf() by error() in an independant patch
>
>
> Patrice Chotard (10):
> reset: add reset_request()
> reset: add reset_assert_all()
> clk: add clk_disable_all()
> dm: core: add ofnode_count_phandle_with_args()
> usb: host: ehci-generic: replace printf() by error()
> usb: host: ehci-generic: add error path and .remove callback
> usb: host: ehci-generic: add generic PHY support
> usb: host: ohci-generic: add CLOCK support
> usb: host: ohci-generic: add RESET support
> usb: host: ohci-generic: add generic PHY support
>
> drivers/clk/clk-uclass.c | 22 ++++++
> drivers/core/of_access.c | 7 ++
> drivers/core/ofnode.c | 12 ++++
> drivers/reset/reset-uclass.c | 31 +++++++++
> drivers/usb/host/ehci-generic.c | 149 +++++++++++++++++++++++++++++++++-------
> drivers/usb/host/ohci-generic.c | 130 ++++++++++++++++++++++++++++++++++-
> include/clk.h | 10 +++
> include/dm/of_access.h | 18 +++++
> include/dm/ofnode.h | 17 +++++
> include/reset.h | 26 +++++++
> 10 files changed, 397 insertions(+), 25 deletions(-)
>
^ permalink raw reply [flat|nested] 16+ messages in thread