Hi Heiko, On 2016/6/14 21:27, Heiko St?bner wrote: > Am Montag, 13. Juni 2016, 10:10:10 schrieb Frank Wang: >> 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> >> --- >> >> Changes in v5: >> - Added 'reg' in the data block to match the different phy-blocks in dt. >> >> Changes in v4: >> - Removed some processes related to 'vbus_host-supply'. >> >> Changes in v3: >> - Resolved the mapping defect between fixed value in driver and the >> property in devicetree. >> - Optimized 480m output clock register function. >> - Code cleanup. >> >> Changes in v2: >> - Changed vbus_host operation from gpio to regulator in *_probe. >> - Improved the fault treatment relate to 480m clock register. >> - Cleaned up some meaningless codes in *_clk480m_disable. >> - made more clear the comment of *_sm_work. >> >> drivers/phy/Kconfig | 7 + >> drivers/phy/Makefile | 1 + >> drivers/phy/phy-rockchip-inno-usb2.c | 645 >> ++++++++++++++++++++++++++++++++++ 3 files changed, 653 insertions(+) >> >> [...] >> >> + >> +static int rockchip_usb2phy_exit(struct phy *phy) >> +{ >> + struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); >> + > if (!rport->port_cfg) > return 0; > >> + if (rport->port_id == USB2PHY_PORT_HOST) >> + cancel_delayed_work_sync(&rport->sm_work); >> + > you will also need to resume the port here, if it is suspended at this point, > as phy_power_off gets called after phy_exit and would probably produce clk > enable/disable mismatches otherwise. > Hmm, from my personal point of view, when canceling sm_work here, it may not cause the port goes to suspend, isn't it? besides, clk only prepared in *_usb2phy_resume(), and unprepared in *_usb2phy_suspend(), so if we resume port here, the prepare_count of clk will be increased again, I am afraid this is not correct, and am I wrong? would you like to tell me more details? >> + return 0; >> +} >> >> [...] >> >> +static int rockchip_usb2phy_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct device_node *np = dev->of_node; >> + struct device_node *child_np; >> >> [...] >> >> + index = 0; >> + for_each_available_child_of_node(np, child_np) { >> + struct rockchip_usb2phy_port *rport = &rphy->ports[index]; >> + struct phy *phy; >> + >> + phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); >> + if (IS_ERR(phy)) { >> + dev_err(dev, "failed to create phy\n"); >> + ret = PTR_ERR(phy); >> + goto put_child; >> + } >> + >> + rport->phy = phy; > phy_set_drvdata(rport->phy, rport); > >> + >> + /* initialize otg/host port separately */ >> + if (!of_node_cmp(child_np->name, "host-port")) { >> + ret = rockchip_usb2phy_host_port_init(rphy, rport, >> + child_np); >> + if (ret) >> + goto put_child; >> + } >> + >> + phy_set_drvdata(rport->phy, rport); > move this to the location above to prevent null-pointer dereferences with > devices plugged in on boot. OK, I will fix it. > > I've tested this a bit on a rk3036 (which is lacking the disconnect-detection > it seems), so in general (apart from the stuff mentioned above) this looks > nice now. So with the stuff above fixed: > > Reviewed-by: Heiko Stuebner <heiko at sntech.de> > Tested-by: Heiko Stuebner <heiko at sntech.de> BR. Frank