public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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


      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