* [U-Boot] [PATCH v7 01/10] reset: add reset_request()
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 02/10] reset: add reset_assert_all() patrice.chotard at st.com
` (8 subsequent siblings)
9 siblings, 0 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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] 24+ messages in thread* [U-Boot] [PATCH v7 02/10] reset: add reset_assert_all()
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 01/10] reset: add reset_request() patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all() patrice.chotard at st.com
` (7 subsequent siblings)
9 siblings, 0 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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] 24+ messages in thread* [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all()
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 01/10] reset: add reset_request() patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 02/10] reset: add reset_assert_all() patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 12:11 ` Lothar Waßmann
2017-06-20 9:59 ` [U-Boot] [PATCH v7 04/10] dm: core: add ofnode_count_phandle_with_args() patrice.chotard at st.com
` (6 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
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..e732514 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->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] 24+ messages in thread* [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all()
2017-06-20 9:59 ` [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all() patrice.chotard at st.com
@ 2017-06-20 12:11 ` Lothar Waßmann
2017-06-20 12:40 ` Patrice CHOTARD
0 siblings, 1 reply; 24+ messages in thread
From: Lothar Waßmann @ 2017-06-20 12:11 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 20 Jun 2017 11:59:04 +0200 patrice.chotard at st.com wrote:
> 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>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> 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..e732514 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->dev, &clk[i]);
>
Shouldn't this be:
ret = clk_request(clk[i].dev, &clk[i]);
Lothar Waßmann
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all()
2017-06-20 12:11 ` Lothar Waßmann
@ 2017-06-20 12:40 ` Patrice CHOTARD
0 siblings, 0 replies; 24+ messages in thread
From: Patrice CHOTARD @ 2017-06-20 12:40 UTC (permalink / raw)
To: u-boot
Hi Lothar
On 06/20/2017 02:11 PM, Lothar Waßmann wrote:
> Hi,
>
> On Tue, 20 Jun 2017 11:59:04 +0200 patrice.chotard at st.com wrote:
>> 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>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> 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..e732514 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->dev, &clk[i]);
>>
> Shouldn't this be:
> ret = clk_request(clk[i].dev, &clk[i]);
Yes, i will fix it
Thanks
Patrice
>
>
>
> Lothar Waßmann
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 04/10] dm: core: add ofnode_count_phandle_with_args()
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (2 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 03/10] clk: add clk_disable_all() patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 18:26 ` Simon Glass
2017-06-20 9:59 ` [U-Boot] [PATCH v7 05/10] usb: host: ehci-generic: replace printf() by error() patrice.chotard at st.com
` (5 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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] 24+ messages in thread* [U-Boot] [PATCH v7 04/10] dm: core: add ofnode_count_phandle_with_args()
2017-06-20 9:59 ` [U-Boot] [PATCH v7 04/10] dm: core: add ofnode_count_phandle_with_args() patrice.chotard at st.com
@ 2017-06-20 18:26 ` Simon Glass
0 siblings, 0 replies; 24+ messages in thread
From: Simon Glass @ 2017-06-20 18:26 UTC (permalink / raw)
To: u-boot
On 20 June 2017 at 03:59, <patrice.chotard@st.com> wrote:
> 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>
> ---
>
> 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(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 05/10] usb: host: ehci-generic: replace printf() by error()
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (3 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 04/10] dm: core: add ofnode_count_phandle_with_args() patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
` (4 subsequent siblings)
9 siblings, 0 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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] 24+ messages in thread* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (4 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 05/10] usb: host: ehci-generic: replace printf() by error() patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 10:09 ` Marek Vasut
2017-06-20 11:32 ` Lothar Waßmann
2017-06-20 9:59 ` [U-Boot] [PATCH v7 07/10] usb: host: ehci-generic: add generic PHY support patrice.chotard at st.com
` (3 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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 | 125 ++++++++++++++++++++++++++++++++--------
1 file changed, 101 insertions(+), 24 deletions(-)
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 2116ae1..388b242 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -11,6 +11,8 @@
#include <dm.h>
#include "ehci.h"
+#include <dm/ofnode.h>
+
/*
* Even though here we don't explicitly use "struct ehci_ctrl"
* ehci_register() expects it to be the first thing that resides in
@@ -18,43 +20,119 @@
*/
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_kmalloc(dev, sizeof(struct clk) * clock_nb,
+ GFP_KERNEL);
+ if (!priv->clocks) {
+ error("Can't allocate resource\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < clock_nb; i++) {
+ err = clk_get_by_index(dev, i, &priv->clocks[i]);
+
+ if (err < 0)
+ break;
- for (i = 0; ; i++) {
- struct reset_ctl reset;
- int ret;
+ priv->clock_count++;
- 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 (clk_enable(&priv->clocks[i])) {
+ error("failed to enable clock %d\n", i);
+ clk_free(&priv->clocks[i]);
+ goto clk_err;
+ }
+ clk_free(&priv->clocks[i]);
+ }
+ } else {
+ if (clock_nb != -ENOENT) {
+ error("failed to get clock phandle(%d)\n", clock_nb);
+ return clock_nb;
+ }
}
+ priv->reset_count = 0;
+ reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
+ "#reset-cells");
+ if (reset_nb > 0) {
+ priv->resets = devm_kmalloc(dev,
+ sizeof(struct reset_ctl) * reset_nb,
+ GFP_KERNEL);
+ if (!priv->resets) {
+ error("Can't allocate resource\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < reset_nb; i++) {
+ err = reset_get_by_index(dev, i, &priv->resets[i]);
+ if (err < 0)
+ break;
+
+ priv->reset_count++;
+
+ if (reset_deassert(&priv->resets[i])) {
+ error("failed to deassert reset %d\n", i);
+ reset_free(&priv->resets[i]);
+ goto reset_err;
+ }
+ 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)
+ return err;
+
+reset_err:
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ return ret;
+clk_err:
+ ret = clk_disable_all(priv->clocks, priv->clock_count);
+ if (ret)
+ return ret;
+
+ 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 +145,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] 24+ messages in thread* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 9:59 ` [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
@ 2017-06-20 10:09 ` Marek Vasut
2017-06-20 11:26 ` Lothar Waßmann
2017-06-20 12:22 ` Patrice CHOTARD
2017-06-20 11:32 ` Lothar Waßmann
1 sibling, 2 replies; 24+ messages in thread
From: Marek Vasut @ 2017-06-20 10:09 UTC (permalink / raw)
To: u-boot
On 06/20/2017 11:59 AM, patrice.chotard at st.com wrote:
> 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>
Nitpicks below
> ---
>
> 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 | 125 ++++++++++++++++++++++++++++++++--------
> 1 file changed, 101 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
> index 2116ae1..388b242 100644
> --- a/drivers/usb/host/ehci-generic.c
> +++ b/drivers/usb/host/ehci-generic.c
> @@ -11,6 +11,8 @@
> #include <dm.h>
> #include "ehci.h"
>
> +#include <dm/ofnode.h>
> +
> /*
> * Even though here we don't explicitly use "struct ehci_ctrl"
> * ehci_register() expects it to be the first thing that resides in
> @@ -18,43 +20,119 @@
> */
> 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
> + GFP_KERNEL);
devm_kzalloc()
> + if (!priv->clocks) {
> + error("Can't allocate resource\n");
If you run out of memory, you're screwed anyway, drop this print.
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < clock_nb; i++) {
> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
> +
> + if (err < 0)
> + break;
>
> - for (i = 0; ; i++) {
> - struct reset_ctl reset;
> - int ret;
> + priv->clock_count++;
>
> - 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 (clk_enable(&priv->clocks[i])) {
> + error("failed to enable clock %d\n", i);
> + clk_free(&priv->clocks[i]);
> + goto clk_err;
> + }
> + clk_free(&priv->clocks[i]);
> + }
> + } else {
> + if (clock_nb != -ENOENT) {
> + error("failed to get clock phandle(%d)\n", clock_nb);
> + return clock_nb;
> + }
> }
>
> + priv->reset_count = 0;
> + reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
> + "#reset-cells");
> + if (reset_nb > 0) {
> + priv->resets = devm_kmalloc(dev,
> + sizeof(struct reset_ctl) * reset_nb,
> + GFP_KERNEL);
> + if (!priv->resets) {
> + error("Can't allocate resource\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < reset_nb; i++) {
> + err = reset_get_by_index(dev, i, &priv->resets[i]);
> + if (err < 0)
> + break;
> +
> + priv->reset_count++;
> +
> + if (reset_deassert(&priv->resets[i])) {
> + error("failed to deassert reset %d\n", i);
> + reset_free(&priv->resets[i]);
> + goto reset_err;
> + }
> + reset_free(&priv->resets[i]);
> + }
> + } else {
> + if (reset_nb != -ENOENT) {
> + error("failed to get reset phandle(%d)\n", reset_nb);
> + goto clk_err;
> + }
> + }
Newline
> 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)
> + return err;
> +
> +reset_err:
> + ret = reset_assert_all(priv->resets, priv->reset_count);
> + if (ret)
> + return ret;
> +clk_err:
> + ret = clk_disable_all(priv->clocks, priv->clock_count);
> + if (ret)
> + return ret;
> +
> + 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 +145,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,
>
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 10:09 ` Marek Vasut
@ 2017-06-20 11:26 ` Lothar Waßmann
2017-06-20 12:22 ` Patrice CHOTARD
1 sibling, 0 replies; 24+ messages in thread
From: Lothar Waßmann @ 2017-06-20 11:26 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 20 Jun 2017 12:09:22 +0200 Marek Vasut wrote:
> On 06/20/2017 11:59 AM, patrice.chotard at st.com wrote:
> > 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>
>
> Nitpicks below
>
> > ---
> >
> > 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 | 125 ++++++++++++++++++++++++++++++++--------
> > 1 file changed, 101 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
> > index 2116ae1..388b242 100644
> > --- a/drivers/usb/host/ehci-generic.c
> > +++ b/drivers/usb/host/ehci-generic.c
> > @@ -11,6 +11,8 @@
> > #include <dm.h>
> > #include "ehci.h"
> >
> > +#include <dm/ofnode.h>
> > +
> > /*
> > * Even though here we don't explicitly use "struct ehci_ctrl"
> > * ehci_register() expects it to be the first thing that resides in
> > @@ -18,43 +20,119 @@
> > */
> > 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
> > + GFP_KERNEL);
>
> devm_kzalloc()
>
devm_kcalloc(dev, clock_nb, sizeof()...)
Lothar Waßmann
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 10:09 ` Marek Vasut
2017-06-20 11:26 ` Lothar Waßmann
@ 2017-06-20 12:22 ` Patrice CHOTARD
1 sibling, 0 replies; 24+ messages in thread
From: Patrice CHOTARD @ 2017-06-20 12:22 UTC (permalink / raw)
To: u-boot
Hi Marek
On 06/20/2017 12:09 PM, Marek Vasut wrote:
> On 06/20/2017 11:59 AM, patrice.chotard at st.com wrote:
>> 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>
>
> Nitpicks below
>
>> ---
>>
>> 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 | 125 ++++++++++++++++++++++++++++++++--------
>> 1 file changed, 101 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
>> index 2116ae1..388b242 100644
>> --- a/drivers/usb/host/ehci-generic.c
>> +++ b/drivers/usb/host/ehci-generic.c
>> @@ -11,6 +11,8 @@
>> #include <dm.h>
>> #include "ehci.h"
>>
>> +#include <dm/ofnode.h>
>> +
>> /*
>> * Even though here we don't explicitly use "struct ehci_ctrl"
>> * ehci_register() expects it to be the first thing that resides in
>> @@ -18,43 +20,119 @@
>> */
>> 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
>> + GFP_KERNEL);
>
> devm_kzalloc()
Ok
>
>> + if (!priv->clocks) {
>> + error("Can't allocate resource\n");
>
> If you run out of memory, you're screwed anyway, drop this print.
Ok, i will remove it
>
>> + return -ENOMEM;
>> + }
>> +
>> + for (i = 0; i < clock_nb; i++) {
>> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
>> +
>> + if (err < 0)
>> + break;
>>
>> - for (i = 0; ; i++) {
>> - struct reset_ctl reset;
>> - int ret;
>> + priv->clock_count++;
>>
>> - 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 (clk_enable(&priv->clocks[i])) {
>> + error("failed to enable clock %d\n", i);
>> + clk_free(&priv->clocks[i]);
>> + goto clk_err;
>> + }
>> + clk_free(&priv->clocks[i]);
>> + }
>> + } else {
>> + if (clock_nb != -ENOENT) {
>> + error("failed to get clock phandle(%d)\n", clock_nb);
>> + return clock_nb;
>> + }
>> }
>>
>> + priv->reset_count = 0;
>> + reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
>> + "#reset-cells");
>> + if (reset_nb > 0) {
>> + priv->resets = devm_kmalloc(dev,
>> + sizeof(struct reset_ctl) * reset_nb,
>> + GFP_KERNEL);
>> + if (!priv->resets) {
>> + error("Can't allocate resource\n");
>> + return -ENOMEM;
>> + }
>> +
>> + for (i = 0; i < reset_nb; i++) {
>> + err = reset_get_by_index(dev, i, &priv->resets[i]);
>> + if (err < 0)
>> + break;
>> +
>> + priv->reset_count++;
>> +
>> + if (reset_deassert(&priv->resets[i])) {
>> + error("failed to deassert reset %d\n", i);
>> + reset_free(&priv->resets[i]);
>> + goto reset_err;
>> + }
>> + reset_free(&priv->resets[i]);
>> + }
>> + } else {
>> + if (reset_nb != -ENOENT) {
>> + error("failed to get reset phandle(%d)\n", reset_nb);
>> + goto clk_err;
>> + }
>> + }
>
> Newline
ok
>
>> 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)
>> + return err;
>> +
>> +reset_err:
>> + ret = reset_assert_all(priv->resets, priv->reset_count);
>> + if (ret)
>> + return ret;
>> +clk_err:
>> + ret = clk_disable_all(priv->clocks, priv->clock_count);
>> + if (ret)
>> + return ret;
>> +
>> + 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 +145,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,
>>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 9:59 ` [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
2017-06-20 10:09 ` Marek Vasut
@ 2017-06-20 11:32 ` Lothar Waßmann
2017-06-20 12:28 ` Patrice CHOTARD
1 sibling, 1 reply; 24+ messages in thread
From: Lothar Waßmann @ 2017-06-20 11:32 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 20 Jun 2017 11:59:07 +0200 patrice.chotard at st.com wrote:
> 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>
> ---
>
> 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 | 125 ++++++++++++++++++++++++++++++++--------
> 1 file changed, 101 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
> index 2116ae1..388b242 100644
> --- a/drivers/usb/host/ehci-generic.c
> +++ b/drivers/usb/host/ehci-generic.c
> @@ -11,6 +11,8 @@
> #include <dm.h>
> #include "ehci.h"
>
> +#include <dm/ofnode.h>
> +
> /*
> * Even though here we don't explicitly use "struct ehci_ctrl"
> * ehci_register() expects it to be the first thing that resides in
> @@ -18,43 +20,119 @@
> */
> 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
> + GFP_KERNEL);
> + if (!priv->clocks) {
> + error("Can't allocate resource\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < clock_nb; i++) {
> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
> +
> + if (err < 0)
> + break;
>
> - for (i = 0; ; i++) {
> - struct reset_ctl reset;
> - int ret;
> + priv->clock_count++;
>
> - 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 (clk_enable(&priv->clocks[i])) {
> + error("failed to enable clock %d\n", i);
> + clk_free(&priv->clocks[i]);
>
You free the clock here and again with clk_disable_all() in the error
path. Also you do not have a valid error code in 'err' which is
returned at the end of the function!
> + goto clk_err;
> + }
> + clk_free(&priv->clocks[i]);
> + }
> + } else {
> + if (clock_nb != -ENOENT) {
> + error("failed to get clock phandle(%d)\n", clock_nb);
> + return clock_nb;
> + }
> }
>
> + priv->reset_count = 0;
> + reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
> + "#reset-cells");
> + if (reset_nb > 0) {
> + priv->resets = devm_kmalloc(dev,
> + sizeof(struct reset_ctl) * reset_nb,
> + GFP_KERNEL);
> + if (!priv->resets) {
> + error("Can't allocate resource\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < reset_nb; i++) {
> + err = reset_get_by_index(dev, i, &priv->resets[i]);
> + if (err < 0)
> + break;
> +
> + priv->reset_count++;
> +
> + if (reset_deassert(&priv->resets[i])) {
> + error("failed to deassert reset %d\n", i);
> + reset_free(&priv->resets[i]);
> + goto reset_err;
> + }
> + 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)
> + return err;
> +
> +reset_err:
> + ret = reset_assert_all(priv->resets, priv->reset_count);
> + if (ret)
> + return ret;
>
You should do the clock cleanup even though the reset cleanup failed.
> +clk_err:
> + ret = clk_disable_all(priv->clocks, priv->clock_count);
> + if (ret)
> + return ret;
>
You should return the error code of the operation that failed
initially (err), not some error code that has occured during cleanup.
> + 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 +145,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,
Lothar Waßmann
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback
2017-06-20 11:32 ` Lothar Waßmann
@ 2017-06-20 12:28 ` Patrice CHOTARD
0 siblings, 0 replies; 24+ messages in thread
From: Patrice CHOTARD @ 2017-06-20 12:28 UTC (permalink / raw)
To: u-boot
Hi Lothar
On 06/20/2017 01:32 PM, Lothar Waßmann wrote:
> Hi,
>
> On Tue, 20 Jun 2017 11:59:07 +0200 patrice.chotard at st.com wrote:
>> 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>
>> ---
>>
>> 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 | 125 ++++++++++++++++++++++++++++++++--------
>> 1 file changed, 101 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
>> index 2116ae1..388b242 100644
>> --- a/drivers/usb/host/ehci-generic.c
>> +++ b/drivers/usb/host/ehci-generic.c
>> @@ -11,6 +11,8 @@
>> #include <dm.h>
>> #include "ehci.h"
>>
>> +#include <dm/ofnode.h>
>> +
>> /*
>> * Even though here we don't explicitly use "struct ehci_ctrl"
>> * ehci_register() expects it to be the first thing that resides in
>> @@ -18,43 +20,119 @@
>> */
>> 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
>> + GFP_KERNEL);
>> + if (!priv->clocks) {
>> + error("Can't allocate resource\n");
>> + return -ENOMEM;
>> + }
>> +
>> + for (i = 0; i < clock_nb; i++) {
>> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
>> +
>> + if (err < 0)
>> + break;
>>
>> - for (i = 0; ; i++) {
>> - struct reset_ctl reset;
>> - int ret;
>> + priv->clock_count++;
>>
>> - 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 (clk_enable(&priv->clocks[i])) {
>> + error("failed to enable clock %d\n", i);
>> + clk_free(&priv->clocks[i]);
>>
> You free the clock here and again with clk_disable_all() in the error
> path. Also you do not have a valid error code in 'err' which is
> returned at the end of the function!
Good catch, to fix it, i will move the priv->clock_count++ after the
clk_enable statement. In this case, in the error path, only clocks which
have been previously correctly enabled will be requested/disabled/freed
Ok i will catch the error code in err and use it as return value.
>
>> + goto clk_err;
>> + }
>> + clk_free(&priv->clocks[i]);
>> + }
>> + } else {
>> + if (clock_nb != -ENOENT) {
>> + error("failed to get clock phandle(%d)\n", clock_nb);
>> + return clock_nb;
>> + }
>> }
>>
>> + priv->reset_count = 0;
>> + reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
>> + "#reset-cells");
>> + if (reset_nb > 0) {
>> + priv->resets = devm_kmalloc(dev,
>> + sizeof(struct reset_ctl) * reset_nb,
>> + GFP_KERNEL);
>> + if (!priv->resets) {
>> + error("Can't allocate resource\n");
>> + return -ENOMEM;
>> + }
>> +
>> + for (i = 0; i < reset_nb; i++) {
>> + err = reset_get_by_index(dev, i, &priv->resets[i]);
>> + if (err < 0)
>> + break;
>> +
>> + priv->reset_count++;
>> +
>> + if (reset_deassert(&priv->resets[i])) {
>> + error("failed to deassert reset %d\n", i);
>> + reset_free(&priv->resets[i]);
>> + goto reset_err;
>> + }
>> + 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)
>> + return err;
>> +
>> +reset_err:
>> + ret = reset_assert_all(priv->resets, priv->reset_count);
>> + if (ret)
>> + return ret;
>>
> You should do the clock cleanup even though the reset cleanup failed.
Agree, i will fix it
>
>> +clk_err:
>> + ret = clk_disable_all(priv->clocks, priv->clock_count);
>> + if (ret)
>> + return ret;
>>
> You should return the error code of the operation that failed
> initially (err), not some error code that has occured during cleanup.
Agree again
Thanks
Patrice
>
>> + 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 +145,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,
>
>
> Lothar Waßmann
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 07/10] usb: host: ehci-generic: add generic PHY support
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (5 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 06/10] usb: host: ehci-generic: add error path and .remove callback patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
` (2 subsequent siblings)
9 siblings, 0 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
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 | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 388b242..00a7772 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 <generic-phy.h>
#include <reset.h>
#include <asm/io.h>
#include <dm.h>
@@ -22,6 +23,7 @@ struct generic_ehci {
struct ehci_ctrl ctrl;
struct clk *clocks;
struct reset_ctl *resets;
+ struct phy phy;
int clock_count;
int reset_count;
};
@@ -99,6 +101,21 @@ static int ehci_usb_probe(struct udevice *dev)
goto clk_err;
}
}
+
+ 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;
+ }
+ } else {
+ 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)));
@@ -107,6 +124,12 @@ static int ehci_usb_probe(struct udevice *dev)
if (!err)
return err;
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ return ret;
+ }
+
reset_err:
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
@@ -128,6 +151,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] 24+ messages in thread* [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (6 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 07/10] usb: host: ehci-generic: add generic PHY support patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 12:06 ` Lothar Waßmann
2017-06-20 9:59 ` [U-Boot] [PATCH v7 09/10] usb: host: ohci-generic: add RESET support patrice.chotard at st.com
2017-06-20 9:59 ` [U-Boot] [PATCH v7 10/10] usb: host: ohci-generic: add generic PHY support patrice.chotard at st.com
9 siblings, 1 reply; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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..f76a1c2 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -5,27 +5,83 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include "ohci.h"
+#include <dm/ofnode.h>
+
#if !defined(CONFIG_USB_OHCI_NEW)
# error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
#endif
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;
+
+ 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
+ GFP_KERNEL);
+ if (!priv->clocks) {
+ error("Can't allocate resource\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < clock_nb; i++) {
+ err = clk_get_by_index(dev, i, &priv->clocks[i]);
+ if (err < 0)
+ break;
+
+ priv->clock_count++;
+
+ if (clk_enable(&priv->clocks[i])) {
+ error("failed to enable clock %d\n", i);
+ clk_free(&priv->clocks[i]);
+ goto clk_err;
+ }
+ clk_free(&priv->clocks[i]);
+ }
+ } else {
+ if (clock_nb != -ENOENT) {
+ error("failed to get clock phandle(%d)\n", clock_nb);
+ return clock_nb;
+ }
+ }
- return ohci_register(dev, regs);
+ err = ohci_register(dev, regs);
+ if (!err)
+ return err;
+
+clk_err:
+ ret = clk_disable_all(priv->clocks, priv->clock_count);
+ if (ret)
+ return ret;
+
+ 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] 24+ messages in thread* [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-20 9:59 ` [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
@ 2017-06-20 12:06 ` Lothar Waßmann
2017-06-20 12:56 ` Patrice CHOTARD
0 siblings, 1 reply; 24+ messages in thread
From: Lothar Waßmann @ 2017-06-20 12:06 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 20 Jun 2017 11:59:09 +0200 patrice.chotard at 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>
> ---
> 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..f76a1c2 100644
> --- a/drivers/usb/host/ohci-generic.c
> +++ b/drivers/usb/host/ohci-generic.c
> @@ -5,27 +5,83 @@
> */
>
> #include <common.h>
> +#include <clk.h>
> #include <dm.h>
> #include "ohci.h"
>
> +#include <dm/ofnode.h>
> +
> #if !defined(CONFIG_USB_OHCI_NEW)
> # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
> #endif
>
> 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;
> +
> + 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
> + GFP_KERNEL);
> + if (!priv->clocks) {
> + error("Can't allocate resource\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < clock_nb; i++) {
> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
> + if (err < 0)
> + break;
> +
> + priv->clock_count++;
> +
> + if (clk_enable(&priv->clocks[i])) {
> + error("failed to enable clock %d\n", i);
> + clk_free(&priv->clocks[i]);
> + goto clk_err;
> + }
> + clk_free(&priv->clocks[i]);
>
You free the freshly allocated clock right away and use it lateron?
> + } else {
> + if (clock_nb != -ENOENT) {
> + error("failed to get clock phandle(%d)\n", clock_nb);
> + return clock_nb;
> + }
> + }
>
> - return ohci_register(dev, regs);
> + err = ohci_register(dev, regs);
> + if (!err)
> + return err;
> +
if (err)
goto clk_err;
return 0;
would be more easy to follow.
> +clk_err:
> + ret = clk_disable_all(priv->clocks, priv->clock_count);
> + if (ret)
> + return ret;
> +
> + 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[] = {
Lothar Waßmann
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-20 12:06 ` Lothar Waßmann
@ 2017-06-20 12:56 ` Patrice CHOTARD
2017-06-21 7:56 ` Lothar Waßmann
0 siblings, 1 reply; 24+ messages in thread
From: Patrice CHOTARD @ 2017-06-20 12:56 UTC (permalink / raw)
To: u-boot
Hi Lothar
On 06/20/2017 02:06 PM, Lothar Waßmann wrote:
> Hi,
>
> On Tue, 20 Jun 2017 11:59:09 +0200 patrice.chotard at 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>
>> ---
>> 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..f76a1c2 100644
>> --- a/drivers/usb/host/ohci-generic.c
>> +++ b/drivers/usb/host/ohci-generic.c
>> @@ -5,27 +5,83 @@
>> */
>>
>> #include <common.h>
>> +#include <clk.h>
>> #include <dm.h>
>> #include "ohci.h"
>>
>> +#include <dm/ofnode.h>
>> +
>> #if !defined(CONFIG_USB_OHCI_NEW)
>> # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
>> #endif
>>
>> 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;
>> +
>> + 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
>> + GFP_KERNEL);
>> + if (!priv->clocks) {
>> + error("Can't allocate resource\n");
>> + return -ENOMEM;
>> + }
>> +
>> + for (i = 0; i < clock_nb; i++) {
>> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
>> + if (err < 0)
>> + break;
>> +
>> + priv->clock_count++;
>> +
>> + if (clk_enable(&priv->clocks[i])) {
>> + error("failed to enable clock %d\n", i);
>> + clk_free(&priv->clocks[i]);
>> + goto clk_err;
>> + }
>> + clk_free(&priv->clocks[i]);
>>
> You free the freshly allocated clock right away and use it lateron?
clk_free() didn't free clock resources, it's the opposite of
clk_request(), see comments in include.clk.h
>
>> + } else {
>> + if (clock_nb != -ENOENT) {
>> + error("failed to get clock phandle(%d)\n", clock_nb);
>> + return clock_nb;
>> + }
>> + }
>>
>> - return ohci_register(dev, regs);
>> + err = ohci_register(dev, regs);
>> + if (!err)
>> + return err;
>> +
> if (err)
> goto clk_err;
> return 0;
> would be more easy to follow.
ok, i will fix it
Thanks
Patrice
>
>> +clk_err:
>> + ret = clk_disable_all(priv->clocks, priv->clock_count);
>> + if (ret)
>> + return ret;
>> +
>> + 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[] = {
>
>
> Lothar Waßmann
>
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-20 12:56 ` Patrice CHOTARD
@ 2017-06-21 7:56 ` Lothar Waßmann
2017-06-21 8:36 ` Patrice CHOTARD
0 siblings, 1 reply; 24+ messages in thread
From: Lothar Waßmann @ 2017-06-21 7:56 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 20 Jun 2017 12:56:48 +0000 Patrice CHOTARD wrote:
> Hi Lothar
>
> On 06/20/2017 02:06 PM, Lothar Waßmann wrote:
> > Hi,
> >
> > On Tue, 20 Jun 2017 11:59:09 +0200 patrice.chotard at 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>
> >> ---
> >> 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..f76a1c2 100644
> >> --- a/drivers/usb/host/ohci-generic.c
> >> +++ b/drivers/usb/host/ohci-generic.c
> >> @@ -5,27 +5,83 @@
> >> */
> >>
> >> #include <common.h>
> >> +#include <clk.h>
> >> #include <dm.h>
> >> #include "ohci.h"
> >>
> >> +#include <dm/ofnode.h>
> >> +
> >> #if !defined(CONFIG_USB_OHCI_NEW)
> >> # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
> >> #endif
> >>
> >> 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;
> >> +
> >> + 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
> >> + GFP_KERNEL);
> >> + if (!priv->clocks) {
> >> + error("Can't allocate resource\n");
> >> + return -ENOMEM;
> >> + }
> >> +
> >> + for (i = 0; i < clock_nb; i++) {
> >> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
> >> + if (err < 0)
> >> + break;
> >> +
> >> + priv->clock_count++;
> >> +
> >> + if (clk_enable(&priv->clocks[i])) {
> >> + error("failed to enable clock %d\n", i);
> >> + clk_free(&priv->clocks[i]);
> >> + goto clk_err;
> >> + }
> >> + clk_free(&priv->clocks[i]);
> >>
> > You free the freshly allocated clock right away and use it lateron?
>
> clk_free() didn't free clock resources, it's the opposite of
> clk_request(), see comments in include.clk.h
>
But as long as you are working with some resource (whether it's a
clock, a gpio, a 'reset' or whatever), you should keep it requested and
free it only after you relinquished using it.
Otherwise the object you are using may be destroyed underneath your
feet.
Lothar Waßmann
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support
2017-06-21 7:56 ` Lothar Waßmann
@ 2017-06-21 8:36 ` Patrice CHOTARD
0 siblings, 0 replies; 24+ messages in thread
From: Patrice CHOTARD @ 2017-06-21 8:36 UTC (permalink / raw)
To: u-boot
Hi Lothar
On 06/21/2017 09:56 AM, Lothar Waßmann wrote:
> Hi,
>
> On Tue, 20 Jun 2017 12:56:48 +0000 Patrice CHOTARD wrote:
>> Hi Lothar
>>
>> On 06/20/2017 02:06 PM, Lothar Waßmann wrote:
>>> Hi,
>>>
>>> On Tue, 20 Jun 2017 11:59:09 +0200 patrice.chotard at 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>
>>>> ---
>>>> 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..f76a1c2 100644
>>>> --- a/drivers/usb/host/ohci-generic.c
>>>> +++ b/drivers/usb/host/ohci-generic.c
>>>> @@ -5,27 +5,83 @@
>>>> */
>>>>
>>>> #include <common.h>
>>>> +#include <clk.h>
>>>> #include <dm.h>
>>>> #include "ohci.h"
>>>>
>>>> +#include <dm/ofnode.h>
>>>> +
>>>> #if !defined(CONFIG_USB_OHCI_NEW)
>>>> # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
>>>> #endif
>>>>
>>>> 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;
>>>> +
>>>> + 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_kmalloc(dev, sizeof(struct clk) * clock_nb,
>>>> + GFP_KERNEL);
>>>> + if (!priv->clocks) {
>>>> + error("Can't allocate resource\n");
>>>> + return -ENOMEM;
>>>> + }
>>>> +
>>>> + for (i = 0; i < clock_nb; i++) {
>>>> + err = clk_get_by_index(dev, i, &priv->clocks[i]);
>>>> + if (err < 0)
>>>> + break;
>>>> +
>>>> + priv->clock_count++;
>>>> +
>>>> + if (clk_enable(&priv->clocks[i])) {
>>>> + error("failed to enable clock %d\n", i);
>>>> + clk_free(&priv->clocks[i]);
>>>> + goto clk_err;
>>>> + }
>>>> + clk_free(&priv->clocks[i]);
>>>>
>>> You free the freshly allocated clock right away and use it lateron?
>>
>> clk_free() didn't free clock resources, it's the opposite of
>> clk_request(), see comments in include.clk.h
>>
> But as long as you are working with some resource (whether it's a
> clock, a gpio, a 'reset' or whatever), you should keep it requested and
> free it only after you relinquished using it.
> Otherwise the object you are using may be destroyed underneath your
> feet.
Ah yes, my bad, i focused on the clk_free() inside the previous statement.
I will fix it
Thanks
>
>
> Lothar Waßmann
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 09/10] usb: host: ohci-generic: add RESET support
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (7 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 08/10] usb: host: ohci-generic: add CLOCK support patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
2017-06-20 18:26 ` Simon Glass
2017-06-20 9:59 ` [U-Boot] [PATCH v7 10/10] usb: host: ohci-generic: add generic PHY support patrice.chotard at st.com
9 siblings, 1 reply; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
---
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, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index f76a1c2..5bd52ff 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <reset.h>
#include "ohci.h"
#include <dm/ofnode.h>
@@ -18,14 +19,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;
@@ -60,10 +63,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_kmalloc(dev,
+ sizeof(struct reset_ctl) * reset_nb,
+ GFP_KERNEL);
+ if (!priv->resets) {
+ error("Can't allocate resource\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < reset_nb; i++) {
+ err = reset_get_by_index(dev, i, &priv->resets[i]);
+ if (err < 0)
+ break;
+
+ priv->reset_count++;
+
+ if (reset_deassert(&priv->resets[i])) {
+ error("failed to deassert reset %d\n", i);
+ reset_free(&priv->resets[i]);
+ goto reset_err;
+ }
+ 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)
return err;
+reset_err:
+ ret = reset_assert_all(priv->resets, priv->reset_count);
+ if (ret)
+ return ret;
clk_err:
ret = clk_disable_all(priv->clocks, priv->clock_count);
if (ret)
@@ -81,6 +121,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] 24+ messages in thread* [U-Boot] [PATCH v7 09/10] usb: host: ohci-generic: add RESET support
2017-06-20 9:59 ` [U-Boot] [PATCH v7 09/10] usb: host: ohci-generic: add RESET support patrice.chotard at st.com
@ 2017-06-20 18:26 ` Simon Glass
0 siblings, 0 replies; 24+ messages in thread
From: Simon Glass @ 2017-06-20 18:26 UTC (permalink / raw)
To: u-boot
On 20 June 2017 at 03:59, <patrice.chotard@st.com> wrote:
> 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>
> ---
> 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, 45 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH v7 10/10] usb: host: ohci-generic: add generic PHY support
2017-06-20 9:59 [U-Boot] [PATCH v7 00/10] usb: Extend ehci and ohci generic drivers patrice.chotard at st.com
` (8 preceding siblings ...)
2017-06-20 9:59 ` [U-Boot] [PATCH v7 09/10] usb: host: ohci-generic: add RESET support patrice.chotard at st.com
@ 2017-06-20 9:59 ` patrice.chotard at st.com
9 siblings, 0 replies; 24+ messages in thread
From: patrice.chotard at st.com @ 2017-06-20 9:59 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
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 | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index 5bd52ff..63cc25e 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <generic-phy.h>
#include <reset.h>
#include "ohci.h"
@@ -20,6 +21,7 @@ struct generic_ohci {
ohci_t ohci;
struct clk *clocks;
struct reset_ctl *resets;
+ struct phy phy;
int clock_count;
int reset_count;
};
@@ -96,10 +98,30 @@ 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;
+ }
+ } else {
+ 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)
return err;
+ if (generic_phy_valid(&priv->phy)) {
+ ret = generic_phy_exit(&priv->phy);
+ if (ret)
+ return ret;
+ }
+
reset_err:
ret = reset_assert_all(priv->resets, priv->reset_count);
if (ret)
@@ -121,6 +143,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] 24+ messages in thread