[U-Boot] [PATCH v3 5/7] usb: host: ohci-generic: add CLOCK support
Marek Vasut
marex at denx.de
Sat May 20 16:16:28 UTC 2017
On 05/19/2017 02:16 PM, Patrice CHOTARD wrote:
> On 05/19/2017 01:51 PM, Marek Vasut wrote:
>> On 05/19/2017 01:27 PM, Patrice CHOTARD wrote:
>>> Hi Marek
>>>
>>> On 05/18/2017 11:29 AM, Marek Vasut wrote:
>>>> On 05/17/2017 03:34 PM, patrice.chotard at st.com wrote:
>>>>> From: Patrice Chotard <patrice.chotard at st.com>
>>>>>
>>>>> use list to save reference to enabled clocks in order to
>>>>> disabled them in case of error during probe() or
>>>>> during driver removal.
>>>>>
>>>>> Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
>>>>> ---
>>>>>
>>>>> 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 | 81 ++++++++++++++++++++++++++++++++++++++++-
>>>>> 1 file changed, 80 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
>>>>> index f3307f4..a6d89a8 100644
>>>>> --- a/drivers/usb/host/ohci-generic.c
>>>>> +++ b/drivers/usb/host/ohci-generic.c
>>>>> @@ -5,6 +5,7 @@
>>>>> */
>>>>>
>>>>> #include <common.h>
>>>>> +#include <clk.h>
>>>>> #include <dm.h>
>>>>> #include "ohci.h"
>>>>>
>>>>> @@ -12,20 +13,98 @@
>>>>> # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
>>>>> #endif
>>>>>
>>>>> +struct ohci_clock {
>>>>> + struct clk *clk;
>>>>> + struct list_head list;
>>>>> +};
>>>>> +
>>>>> struct generic_ohci {
>>>>> ohci_t ohci;
>>>>> + struct list_head clks;
>>>>> };
>>>>>
>>>>> +static int ohci_release_clocks(struct generic_ohci *priv)
>>>>> +{
>>>>> + struct ohci_clock *ohci_clock, *tmp;
>>>>> + struct clk *clk;
>>>>> + int ret;
>>>>> +
>>>>> + list_for_each_entry_safe(ohci_clock, tmp, &priv->clks, list) {
>>>>> + clk = ohci_clock->clk;
>>>>> +
>>>>> + clk_request(clk->dev, clk);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + clk_disable(clk);
>>>>> +
>>>>> + ret = clk_free(clk);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + list_del(&ohci_clock->list);
>>>>> + }
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> static int ohci_usb_probe(struct udevice *dev)
>>>>> {
>>>>> struct ohci_regs *regs = (struct ohci_regs *)dev_get_addr(dev);
>>>>> + struct generic_ohci *priv = dev_get_priv(dev);
>>>>> + int i, ret;
>>>>> +
>>>>> + INIT_LIST_HEAD(&priv->clks);
>>>>> +
>>>>> + for (i = 0; ; i++) {
>>>>> + struct ohci_clock *ohci_clock;
>>>>> + struct clk *clk;
>>>>> +
>>>>> + clk = devm_kmalloc(dev, sizeof(*clk), GFP_KERNEL);
>>>>
>>>> Since you know how many entries the clock phandle has, you can allocate
>>>> an array and drop this while list handling and this per-element kmalloc,
>>>> which fragments the allocator pool.
>>>
>>> I disagree, at this point we don't know how many entries the clock
>>> phandle has.
>>
>> I know you can do it in less then 2 mallocs, in fact in exactly 1 ,
>> which is already better.
>
> Can you elaborate ?
>
>>
>>> But, following your idea to avoid allocator pool fragmentation, in order
>>> to get the phandle number for array allocation, i can, for example add a
>>> new fdt API :
>>>
>>> int fdtdec_get_phandle_nb(const void *blob, int src_node,
>>> const char *list_name,
>>> const char *cells_name,
>>> int cell_count,
>>> int phandle_nb);
>>
>> Uh, why ?
>>
>>> Then, with phandle_nb,, we 'll be able to allocate the right array size
>>> for clocks and resets before populating them.
>>
>> Just query the number of elements up front and then allocate the array ?
>
> Can you indicate me with which API please ?
fdt.*count() or somesuch .
--
Best regards,
Marek Vasut
More information about the U-Boot
mailing list