[PATCH v6 2/2] phy: rockchip-inno-usb2: add a new driver for Rockchip usb2phy
Frank Wang
frank.wang at rock-chips.com
Tue Jun 21 00:52:45 PDT 2016
Hi Heiko,
On 2016/6/20 12:56, Guenter Roeck wrote:
> Hi Frank,
>
> On Sun, Jun 19, 2016 at 8:32 PM, Frank Wang <frank.wang at rock-chips.com> wrote:
>> Hi Heiko & Guenter,
>>
>>
>> On 2016/6/20 11:00, Guenter Roeck wrote:
>>> On Sun, Jun 19, 2016 at 6:27 PM, Frank Wang <frank.wang at rock-chips.com>
>>> wrote:
>>>> Hi Guenter,
>>>>
>>>>
>>>> On 2016/6/17 21:20, Guenter Roeck wrote:
>>>>> Hi Frank,
>>>>>
>>>>> On 06/16/2016 11:43 PM, Frank Wang wrote:
>>>>>> Hi Guenter,
>>>>>>
>>>>>> On 2016/6/17 12:59, Guenter Roeck wrote:
>>>>>>> On 06/16/2016 07:09 PM, Frank Wang wrote:
>>>>>>>> The newer SoCs (rk3366, rk3399) take a different usb-phy IP block
>>>>>>>> than rk3288 and before, and most of phy-related registers are also
>>>>>>>> different from the past, so a new phy driver is required necessarily.
>>>>>>>>
>>>>>>>> Signed-off-by: Frank Wang <frank.wang at rock-chips.com>
>>>>>>>> Suggested-by: Guenter Roeck <linux at roeck-us.net>
>>>>>>>> Suggested-by: Doug Anderson <dianders at chromium.org>
>>>>>>>> Reviewed-by: Heiko Stuebner <heiko at sntech.de>
>>>>>>>> Tested-by: Heiko Stuebner <heiko at sntech.de>
>>>>>>>> ---
>>>>>>>
>>>>>>> [ ... ]
>>>>>>>
>>>>>>>> +
>>>>>>>> +static int rockchip_usb2phy_resume(struct phy *phy)
>>>>>>>> +{
>>>>>>>> + struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
>>>>>>>> + struct rockchip_usb2phy *rphy =
>>>>>>>> dev_get_drvdata(phy->dev.parent);
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + dev_dbg(&rport->phy->dev, "port resume\n");
>>>>>>>> +
>>>>>>>> + ret = clk_prepare_enable(rphy->clk480m);
>>>>>>>> + if (ret)
>>>>>>>> + return ret;
>>>>>>>> +
>>>>>>> If suspend can be called multiple times, resume can be called
>>>>>>> multiple times as well. Doesn't this cause a clock imbalance
>>>>>>> if you call clk_prepare_enable() multiple times on resume,
>>>>>>> but clk_disable_unprepare() only once on suspend ?
>>>>>>>
>>>>>> Well, what you said is reasonable, How does something like below?
>>>>>>
>>>>>> @@ -307,6 +307,9 @@ static int rockchip_usb2phy_resume(struct phy *phy)
>>>>>>
>>>>>> dev_dbg(&rport->phy->dev, "port resume\n");
>>>>>>
>>>>>> + if (!rport->suspended)
>>>>>> + return 0;
>>>>>> +
>>>>>> ret = clk_prepare_enable(rphy->clk480m);
>>>>>> if (ret)
>>>>>> return ret;
>>>>>> @@ -327,12 +330,16 @@ static int rockchip_usb2phy_suspend(struct phy
>>>>>> *phy)
>>>>>>
>>>>>> dev_dbg(&rport->phy->dev, "port suspend\n");
>>>>>>
>>>>>> + if (rport->suspended)
>>>>>> + return 0;
>>>>>> +
>>>>>> ret = property_enable(rphy, &rport->port_cfg->phy_sus, true);
>>>>>> if (ret)
>>>>>> return ret;
>>>>>>
>>>>>> rport->suspended = true;
>>>>>> clk_disable_unprepare(rphy->clk480m);
>>>>>> +
>>>>>> return 0;
>>>>>> }
>>>>>>
>>>>>> @@ -485,6 +492,7 @@ static int rockchip_usb2phy_host_port_init(struct
>>>>>> rockchip_usb2phy *rphy,
>>>>>>
>>>>>> rport->port_id = USB2PHY_PORT_HOST;
>>>>>> rport->port_cfg =
>>>>>> &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
>>>>>> + rport->suspended = true;
>>>>>>
>>>>> Why does it start in suspended mode ? That seems odd.
>>>>>
>>>> This is an initialization. Using above design which make 'suspended' as a
>>>> condition both in *_usb2phy_resume and *_usb2phy_suspend, I believe if it
>>>> is
>>>> not initialized as suspended mode, the first resume process will be
>>>> skipped.
>>> I had to re-read the entire patch.
>>>
>>> Turns out my problem was one of terminology. Using "suspend" and
>>> "resume" to me suggested the common use of suspend and resume
>>> functions. That is not the case here. After mentally replacing
>>> "suspend" with "power_off" and "resume" with "power_on", you are
>>> right, no problem exists. Sorry for the noise.
>>>
>>> Maybe it would be useful to replace "resume" with "power_on" and
>>> "suspend" with "power_off" in the function and variable names to
>>> reduce confusion and misunderstandings.
>>>
>>> Thanks,
>>> Guenter
>>
>> Well, it does have a bits confusion, however, the phy-port always just goes
>> to suspend and resume mode (Not power off and power on) in a fact. So must
>> it be renamed?
>>
> Other phy drivers name the functions _power_off and _power_on and
> avoid the confusion. The callbacks are named .power_off and .power_on,
> which gives a clear indication of its intended purpose. Other drivers
> implementing suspend/resume (such as the omap usb phy driver) tie
> those functions not into the power_off/power_on callbacks, but into
> the driver's suspend/resume callbacks. At least the omap driver has
> separate power management functions.
>
> Do the functions _have_ to be renamed ? Surely not. But, if the
> functions are really suspend/resume functions and not
> power_off/power_on functions, maybe they should tie to the
> suspend/resume functions and not register themselves as
> power_off/power_on functions ?
>
> Thanks,
> Guenter
As Guenter mentioned above, I doped out two solutions, one is that keep
current process but renaming *_resume/*_suspend to
*_power_on/*_power_off; another is that do not assign power_on/power_off
functions for phy_ops at phy creating time, then, shorten
_SCHEDULE_DELAY_ delay time less that 10 Seconds, and the phy-port
suspend/resume mechanism depend on _sm_work_ completely.
So which is the better way from your view? or would you like to give
other unique perceptions please?
BR.
Frank
>>
>>>> Theoretically, the phy-port in suspended mode make sense when it is at
>>>> start
>>>> time, then the upper layer controller will invoke phy_power_on (See
>>>> phy-core.c), and it further call back *_usb2phy_resume to make phy-port
>>>> work
>>>> properly.
>>>>
>>>> So could you tell me what make you feeling odd or would you like to give
>>>> another appropriate way please? :-)
>>>>
>>>> BR.
>>>> Frank
>>>>
>>>>
>>>>>> mutex_init(&rport->mutex);
>>>>>> INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
>>>>>>
More information about the Linux-rockchip
mailing list