From: "Stanley Chang[昌育德]" <stanley_chang@realtek.com>
To: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Conor Dooley <conor+dt@kernel.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH v4 1/2] usb: dwc3: add Realtek DHC RTD SoC dwc3 glue layer driver
Date: Fri, 18 Aug 2023 07:43:26 +0000 [thread overview]
Message-ID: <8b4f8ba8685c43df9f297fefcc53edb1@realtek.com> (raw)
In-Reply-To: <20230818003752.3ghaw4vprnqs6s2f@synopsys.com>
Hi Thinh,
>
> On Tue, Aug 15, 2023, Stanley Chang wrote:
> > Realtek DHC RTD SoCs integrate dwc3 IP and has some customizations to
> > support different generations of SoCs.
>
> Please provide a summary of what "customizations" are done here.
>
I will add description:
The RTD1619b subclass SoC only supports USB 2.0 from dwc3.
The driver can set a maximum speed to support this.
Add role switching function, that can switch USB roles through other drivers,
or switch USB roles through user space through set /sys/class/usb_role/.
> > +struct dwc3_rtk {
> > + struct device *dev;
> > + void __iomem *regs;
> > + size_t regs_size;
> > + void __iomem *pm_base;
> > +
> > + struct dwc3 *dwc;
> > +
> > + int cur_dr_mode; /* current dr mode */
>
> Why not use enum for dr_mode? And I don't think you need the comment.
I will remove comment.
I will modify to use enumeration and define usb_role uniformly instead of
dr_mode to avoid confusing dr_mode and usb_role.
> > + struct usb_role_switch *role_switch; };
> > +
> > +static void switch_usb2_dr_mode(struct dwc3_rtk *rtk, int dr_mode) {
> > + switch (dr_mode) {
> > + case USB_DR_MODE_PERIPHERAL:
> > + writel(USB2_PHY_SWITCH_DEVICE |
> > + (~USB2_PHY_SWITCH_MASK &
> > + readl(rtk->regs + WRAP_USB2_PHY_REG)),
> > + rtk->regs + WRAP_USB2_PHY_REG);
>
> Please split the register read and write to separate operations here and
> everywhere else. ie:
> val = readl(offset);
> writel(val | mod, offset);
Okay.
> > + break;
> > + case USB_DR_MODE_HOST:
> > + writel(USB2_PHY_SWITCH_HOST |
> > + (~USB2_PHY_SWITCH_MASK &
> > + readl(rtk->regs + WRAP_USB2_PHY_REG)),
> > + rtk->regs + WRAP_USB2_PHY_REG);
> > + break;
> > + default:
> > + dev_dbg(rtk->dev, "%s: dr_mode=%d\n", __func__,
> dr_mode);
> > + break;
> > + }
> > +}
> > +
> > +static void switch_dwc3_dr_mode(struct dwc3_rtk *rtk, int dr_mode) {
> > + if (!rtk->dwc->role_sw)
> > + goto out;
> > +
> > + switch (dr_mode) {
> > + case USB_DR_MODE_PERIPHERAL:
> > + usb_role_switch_set_role(rtk->dwc->role_sw,
> USB_ROLE_DEVICE);
> > + break;
> > + case USB_DR_MODE_HOST:
> > + usb_role_switch_set_role(rtk->dwc->role_sw,
> USB_ROLE_HOST);
> > + break;
> > + default:
> > + dev_dbg(rtk->dev, "%s dr_mode=%d\n", __func__,
> dr_mode);
> > + break;
> > + }
> > +
> > +out:
> > + return;
> > +}
> > +
> > +static int dwc3_rtk_get_dr_mode(struct dwc3_rtk *rtk) {
> > + enum usb_role role;
> > +
> > + role = rtk->cur_dr_mode;
> > +
> > + if (rtk->dwc && rtk->dwc->role_sw)
> > + role = usb_role_switch_get_role(rtk->dwc->role_sw);
> > + else
> > + dev_dbg(rtk->dev, "%s not usb_role_switch role=%d\n",
> > + __func__, role);
> > +
> > + return role;
> > +}
> > +
> > +static void dwc3_rtk_set_dr_mode(struct dwc3_rtk *rtk, int dr_mode) {
> > + rtk->cur_dr_mode = dr_mode;
> > +
> > + switch_dwc3_dr_mode(rtk, dr_mode);
> > + mdelay(10);
> > + switch_usb2_dr_mode(rtk, dr_mode); }
> > +
> > +#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
> > +static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, enum
> > +usb_role role) {
> > + struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw);
> > +
> > + switch (role) {
> > + case USB_ROLE_HOST:
> > + dwc3_rtk_set_dr_mode(rtk, USB_DR_MODE_HOST);
> > + break;
> > + case USB_ROLE_DEVICE:
> > + dwc3_rtk_set_dr_mode(rtk, USB_DR_MODE_PERIPHERAL);
> > + break;
> > + default:
> > + dwc3_rtk_set_dr_mode(rtk, 0);
>
> Any other value should be invalid and should not invoke
> dwc3_rtk_set_dr_mode().
I will remove it.
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch
> > +*sw) {
> > + struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw);
> > + enum usb_role role = USB_ROLE_NONE;
> > + int dr_mode;
> > +
> > + dr_mode = dwc3_rtk_get_dr_mode(rtk);
>
> dwc3_rtk_get_dr_mode() returns int converted from enum usb_role. Now
> you're mixing dr_mode with usb_role. Please use enum and avoid casting.
This is my fault. cur_dr_mode mixes dr_mode and usb_role, although they have the same value.
I will use cur_role and enum usb_role types uniformly.
> > + switch (dr_mode) {
> > + case USB_DR_MODE_HOST:
> > + role = USB_ROLE_HOST;
> > + break;
> > + case USB_DR_MODE_PERIPHERAL:
> > + role = USB_ROLE_DEVICE;
> > + break;
> > + default:
> > + dev_dbg(rtk->dev, "%s dr_mode=%d", __func__, dr_mode);
> > + break;
> > + }
> > + return role;
> > +}
> > +
> > +static int dwc3_rtk_setup_role_switch(struct dwc3_rtk *rtk) {
> > + struct usb_role_switch_desc dwc3_role_switch = {NULL};
> > +
> > + dwc3_role_switch.name = strchrnul(dev_name(rtk->dev), '.') + 1;
>
> Why not just use dev_name(rtk->dev)?
>
I want to remove the address.
For example,
Original:
98020000.dwc3_u2drd-role-switch
I want:
dwc3_u2drd-role-switch
> > + dwc3_role_switch.driver_data = rtk;
> > + dwc3_role_switch.allow_userspace_control = true;
> > + dwc3_role_switch.fwnode = dev_fwnode(rtk->dev);
> > + dwc3_role_switch.set = dwc3_usb_role_switch_set;
> > + dwc3_role_switch.get = dwc3_usb_role_switch_get;
> > + rtk->role_switch = usb_role_switch_register(rtk->dev,
> &dwc3_role_switch);
> > + if (IS_ERR(rtk->role_switch))
> > + return PTR_ERR(rtk->role_switch);
> > +
> > + return 0;
> > +}
> > +
> > +static int dwc3_rtk_remove_role_switch(struct dwc3_rtk *rtk) {
> > + if (rtk->role_switch)
> > + usb_role_switch_unregister(rtk->role_switch);
> > +
> > + rtk->role_switch = NULL;
> > +
> > + return 0;
> > +}
> > +#else
> > +#define dwc3_rtk_setup_role_switch(x) 0 #define
> > +dwc3_rtk_remove_role_switch(x) 0 #endif
> > +
> > +static int dwc3_rtk_probe(struct platform_device *pdev) {
> > + struct dwc3_rtk *rtk;
> > + struct device *dev = &pdev->dev;
> > + struct resource *res;
> > + void __iomem *regs;
> > + int ret = 0;
> > + unsigned long probe_time = jiffies;
> > +
> > + rtk = devm_kzalloc(dev, sizeof(*rtk), GFP_KERNEL);
> > + if (!rtk) {
> > + ret = -ENOMEM;
> > + goto err1;
> > + }
> > +
> > + platform_set_drvdata(pdev, rtk);
> > +
> > + rtk->dev = dev;
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + if (!res) {
> > + dev_err(dev, "missing memory resource\n");
> > + ret = -ENODEV;
> > + goto err1;
> > + }
> > +
> > + regs = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(regs)) {
> > + ret = PTR_ERR(regs);
> > + goto err1;
> > + }
> > +
> > + rtk->regs = regs;
> > + rtk->regs_size = resource_size(res);
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > + if (res) {
> > + rtk->pm_base = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(rtk->pm_base)) {
> > + ret = PTR_ERR(rtk->pm_base);
> > + goto err1;
> > + }
> > + }
> > +
> > + ret = dwc3_rtk_probe_dwc3_core(rtk);
> > + if (ret)
> > + goto err1;
> > +
> > + dev_dbg(dev, "%s ok! (take %d ms)\n", __func__,
> > + jiffies_to_msecs(jiffies - probe_time));
>
> This debug message doesn't look like it should be here unless it's early in the
> development cycle. Do we need this debug message?
I only want to print time of probe.
I will remove it.
> > +
> > + return 0;
> > +
> > +err1:
>
> Where's err2? If there are multiple gotos, provide more descriptive names
> instead of just numbers.
Okay I will revise this.
>
> > + return ret;
> > +}
> > +
Thanks,
Stanley
prev parent reply other threads:[~2023-08-18 7:44 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-15 9:54 [PATCH v4 1/2] usb: dwc3: add Realtek DHC RTD SoC dwc3 glue layer driver Stanley Chang
2023-08-15 9:54 ` [PATCH v4 2/2] dt-bindings: usb: dwc3: Add Realtek DHC RTD SoC DWC3 USB Stanley Chang
2023-08-21 19:27 ` Rob Herring
2023-08-22 7:10 ` Stanley Chang[昌育德]
2023-08-18 0:38 ` [PATCH v4 1/2] usb: dwc3: add Realtek DHC RTD SoC dwc3 glue layer driver Thinh Nguyen
2023-08-18 7:43 ` Stanley Chang[昌育德] [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8b4f8ba8685c43df9f297fefcc53edb1@realtek.com \
--to=stanley_chang@realtek.com \
--cc=Thinh.Nguyen@synopsys.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox