All of lore.kernel.org
 help / color / mirror / Atom feed
From: cchiluve@codeaurora.org
To: Matthias Kaehlcke <mka@chromium.org>
Cc: balbi@kernel.org, agross@kernel.org, david.brown@linaro.org,
	linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org
Subject: Re: [PATCH V2 2/3] usb: dwc3: qcom: Add interconnect support in dwc3 driver
Date: Tue, 17 Sep 2019 16:39:20 +0530	[thread overview]
Message-ID: <7762a32f08a297e47a45dc9840b62d02@codeaurora.org> (raw)
In-Reply-To: <20190916222446.GG133864@google.com>

Hi Matthias,

Thanks for the review. I Will address below comments and post changes in 
new version.

On 2019-09-17 03:54, Matthias Kaehlcke wrote:
> Hi Chandana,
> 
> On Mon, Sep 16, 2019 at 05:11:00PM +0530, Chandana Kishori Chiluveru 
> wrote:
>> Add interconnect support in dwc3-qcom driver to vote for bus
>> bandwidth.
>> 
>> This requires for two different paths - from USB master to
>> DDR slave. The other is from APPS master to USB slave.
>> 
>> Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
>> ---
>>  drivers/usb/dwc3/dwc3-qcom.c | 145 
>> ++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 143 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/usb/dwc3/dwc3-qcom.c 
>> b/drivers/usb/dwc3/dwc3-qcom.c
>> index 184df4d..4f6c9736 100644
>> --- a/drivers/usb/dwc3/dwc3-qcom.c
>> +++ b/drivers/usb/dwc3/dwc3-qcom.c
>> @@ -14,6 +14,7 @@
>>  #include <linux/extcon.h>
>>  #include <linux/of_platform.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/interconnect.h>
> 
> please use alphabetical order, i.e. this should be after 
> 'linux/extcon.h'.
> 
>>  #include <linux/phy/phy.h>
>>  #include <linux/usb/of.h>
>>  #include <linux/reset.h>
>> @@ -59,8 +60,13 @@ struct dwc3_qcom {
>>  	enum usb_dr_mode	mode;
>>  	bool			is_suspended;
>>  	bool			pm_suspended;
>> +	struct icc_path		*usb_ddr_icc_path;
>> +	struct icc_path		*apps_usb_icc_path;
>>  };
>> 
>> +static int usb_interconnect_enable(struct dwc3_qcom *qcom);
>> +static int usb_interconnect_disable(struct dwc3_qcom *qcom);
>> +
>>  static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, 
>> u32 val)
>>  {
>>  	u32 reg;
>> @@ -222,7 +228,7 @@ static void dwc3_qcom_enable_interrupts(struct 
>> dwc3_qcom *qcom)
>>  static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
>>  {
>>  	u32 val;
>> -	int i;
>> +	int i, ret;
>> 
>>  	if (qcom->is_suspended)
>>  		return 0;
>> @@ -234,6 +240,11 @@ static int dwc3_qcom_suspend(struct dwc3_qcom 
>> *qcom)
>>  	for (i = qcom->num_clocks - 1; i >= 0; i--)
>>  		clk_disable_unprepare(qcom->clks[i]);
>> 
>> +	/* Remove bus voting */
> 
> IMO the comment doesn't add much, especially since there is a log in
> case of failure.
> 
>> +	ret = usb_interconnect_disable(qcom);
>> +	if (ret)
>> +		dev_err(qcom->dev, "bus bw voting failed %d\n", ret);
> 
> This should probably be a warning, since the function continues with
> normal execution.
> 
> nit: the function is called usb_interconnect_disable(), but the
> message says "bus bw voting failed". The function name encapsulates
> what the function does, but the message talks about implementation
> details. To be consistent either the function should have something
> about 'voting' in it's name, or the message should be "failed to
> disable interconnect" or similar.
> 
>> +
>>  	qcom->is_suspended = true;
>>  	dwc3_qcom_enable_interrupts(qcom);
>> 
>> @@ -259,6 +270,11 @@ static int dwc3_qcom_resume(struct dwc3_qcom 
>> *qcom)
>>  		}
>>  	}
>> 
>> +	/* Add bus voting */
>> +	ret = usb_interconnect_enable(qcom);
>> +	if (ret)
>> +		dev_err(qcom->dev, "bus bw voting failed %d\n", ret);
>> +
> 
> same comments as for suspend()
> 
>>  	/* Clear existing events from PHY related to L2 in/out */
>>  	dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
>>  			  PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
>> @@ -268,6 +284,117 @@ static int dwc3_qcom_resume(struct dwc3_qcom 
>> *qcom)
>>  	return 0;
>>  }
>> 
>> +/* Interconnect path bandwidths in MBps */
>> +#define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
>> +#define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
>> +#define USB_MEMORY_AVG_SS_BW  MBps_to_icc(1000)
>> +#define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
>> +#define APPS_USB_AVG_BW 0
>> +#define APPS_USB_PEAK_BW MBps_to_icc(40)
>> +
>> +/**
>> + * usb_interconnect_init() -
> 
> A function named 'usb_*' is typically associated to be a USB core
> function. I would suggest to use the 'dwc3_qcom_' prefix like all
> other functions in this file. Applicable to all new functions.
> 
>> Request to get interconnect path handle
> 
> nit: handles
> 
> Get rid of "Request to"?
> 
>> + * @qcom:			Pointer to the concerned usb core.
>> + *
>> + */
>> +static int usb_interconnect_init(struct dwc3_qcom *qcom)
>> +{
>> +	struct device *dev = qcom->dev;
>> +
>> +	qcom->usb_ddr_icc_path = of_icc_get(dev, "usb-ddr");
>> +	if (IS_ERR(qcom->usb_ddr_icc_path)) {
>> +		dev_err(dev, "Error: (%ld) failed getting %s path\n",
>> +			PTR_ERR(qcom->usb_ddr_icc_path), "usb-ddr");
> 
> Why not put 'usb-ddr' in the format string, instead of using '%s'?
> 
>> +		return PTR_ERR(qcom->usb_ddr_icc_path);
>> +	}
>> +
>> +	qcom->apps_usb_icc_path = of_icc_get(dev, "apps-usb");
>> +	if (IS_ERR(qcom->apps_usb_icc_path)) {
>> +		dev_err(dev, "Error: (%ld) failed getting %s path\n",
>> +				PTR_ERR(qcom->apps_usb_icc_path), "apps-usb");
> 
> same comment as above.
> 
>      	     	icc_put(qcom->usb_ddr_icc_path);
> 
>> +		return PTR_ERR(qcom->usb_ddr_icc_path);
> 
> should be 'qcom->apps_usb_icc_path'
> 
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * geni_interconnect_exit() -
> 
> wrong prefix
> 
>> Request to release interconnect path handle
> 
> nit: handles
> 
> Get rid of "Request to"?
> 
>> + * @qcom:			Pointer to the concerned usb core.
>> + *
>> + * This function is used to release interconnect path handle.
>> + */
>> +static void usb_interconnect_exit(struct dwc3_qcom *qcom)
>> +{
>> +	icc_put(qcom->usb_ddr_icc_path);
>> +	icc_put(qcom->apps_usb_icc_path);
>> +}
>> +
>> +/* Currently we only use bandwidth level, so just "enable" 
>> interconnects */
>> +static int usb_interconnect_enable(struct dwc3_qcom *qcom)
>> +{
>> +	struct dwc3 *dwc;
>> +	int ret;
>> +
>> +	dwc = platform_get_drvdata(qcom->dwc3);
>> +	if (!dwc) {
>> +		dev_err(qcom->dev, "Failed to get dwc3 device\n");
>> +		return -EPROBE_DEFER;
>> +	}
> 
> This should never happen, drvdata is set in _probe(). If it happens
> -EPROBE_DEFER doesn't seem to be an appropriate error code. I suggest
> to remove the condition entirely.
> 
In my testing i have seen a null pointer crash with 
"dwc->maximum_speed". To prevent the crash i have added this logic.
Agree that drvdata is set in dwc3_probe(). Sometimes i can see that 
dwc3_probe never getting completed before it can go and access 
dwc->maximum_speed pointer here.
This is leading to null pointer access crash. if i defer the probe and 
try again i can see that drvdata getting updated successfully in 
dwc3_probe.

>> +
>> +	if (dwc->maximum_speed == USB_SPEED_SUPER) {
>> +		ret = icc_set_bw(qcom->usb_ddr_icc_path,
>> +			USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
>> +		if (ret)
>> +			return ret;
>> +	} else {
>> +		ret = icc_set_bw(qcom->usb_ddr_icc_path,
>> +			USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	ret = icc_set_bw(qcom->apps_usb_icc_path,
>> +		APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
>> +	if (ret)
>> +		goto err_disable_mem_path;
>> +
>> +	return 0;
>> +
>> +err_disable_mem_path:
>> +	icc_set_bw(qcom->usb_ddr_icc_path, 0, 0);
>> +
>> +	return ret;
>> +}
>> +
>> +/* To disable an interconnect, we just set its bandwidth to 0 */
>> +static int usb_interconnect_disable(struct dwc3_qcom *qcom)
>> +{
>> +	struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
>> +	int ret;
>> +
>> +	ret = icc_set_bw(qcom->usb_ddr_icc_path, 0, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = icc_set_bw(qcom->apps_usb_icc_path, 0, 0);
>> +	if (ret)
>> +		goto err_reenable_memory_path;
>> +
>> +	return 0;
>> +
>> +	/* Re-enable things in the event of an error */
>> +err_reenable_memory_path:
>> +	if (dwc->maximum_speed == USB_SPEED_SUPER)
>> +		icc_set_bw(qcom->usb_ddr_icc_path,
>> +			USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
>> +	else
>> +		icc_set_bw(qcom->usb_ddr_icc_path,
>> +			USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
>> +
>> +	return ret;
>> +}
>> +
>>  static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
>>  {
>>  	struct dwc3_qcom *qcom = data;
>> @@ -494,6 +621,17 @@ static int dwc3_qcom_probe(struct platform_device 
>> *pdev)
>>  		goto depopulate;
>>  	}
>> 
>> +	ret = usb_interconnect_init(qcom);
>> +	if (ret) {
>> +		dev_err(dev, "failed to get interconnect handle ret:%d\n", ret);
> 
> similar to my comment above, the function name adds an abstraction,
> but the comment talks about implementation details. I'd suggest
> something like 'failed to init interconnect'.
> 
>> +		goto depopulate;
>> +	}
>> +	ret = usb_interconnect_enable(qcom);
>> +	if (ret) {
>> +		dev_err(qcom->dev, "bus bw voting failed %d\n", ret);
> 
> same comment as for 'dwc3_qcom_suspend' above.
> 
> I think the _interconnect_enable() call should be part of
> _interconnect_init(). I was earlier considering to suggest to
> change the name of _interconnect_init() to something else, since
> it doesn't really do any interconnect initialization, but didn't have
> a good suggestion for an alternative name. Moving the _enable() call
> into _init() would make _init() and actual init routine, besides
> removing clutter from _probe().
> 
>> +		goto interconnect_exit;
>> +	}
>> +
>>  	qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
>> 
>>  	/* enable vbus override for device mode */
>> @@ -503,7 +641,7 @@ static int dwc3_qcom_probe(struct platform_device 
>> *pdev)
>>  	/* register extcon to override sw_vbus on Vbus change later */
>>  	ret = dwc3_qcom_register_extcon(qcom);
>>  	if (ret)
>> -		goto depopulate;
>> +		goto interconnect_exit;
>> 
>>  	device_init_wakeup(&pdev->dev, 1);
>>  	qcom->is_suspended = false;
>> @@ -513,6 +651,8 @@ static int dwc3_qcom_probe(struct platform_device 
>> *pdev)
>> 
>>  	return 0;
>> 
>> +interconnect_exit:
>> +	usb_interconnect_exit(qcom);
>>  depopulate:
>>  	of_platform_depopulate(&pdev->dev);
>>  clk_disable:
>> @@ -540,6 +680,7 @@ static int dwc3_qcom_remove(struct platform_device 
>> *pdev)
>>  	}
>>  	qcom->num_clocks = 0;
>> 
>> +	usb_interconnect_exit(qcom);
>>  	reset_control_assert(qcom->resets);
>> 
>>  	pm_runtime_allow(dev);
> 
> Cheers
> 
> Matthias

  reply	other threads:[~2019-09-17 11:09 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-16 11:40 [PATCH V2 0/3] ADD interconnect support for USB Chandana Kishori Chiluveru
2019-09-16 11:40 ` [PATCH V2 1/3] dt-bindings: Introduce interconnect bindings for usb Chandana Kishori Chiluveru
2019-09-16 11:41 ` [PATCH V2 2/3] usb: dwc3: qcom: Add interconnect support in dwc3 driver Chandana Kishori Chiluveru
2019-09-16 22:24   ` Matthias Kaehlcke
2019-09-17 11:09     ` cchiluve [this message]
2019-09-17 17:58       ` Matthias Kaehlcke
2019-09-16 11:41 ` [PATCH V2 3/3] arm64: dts: sdm845: Add interconnect properties for USB Chandana Kishori Chiluveru
2019-09-16 22:56   ` Matthias Kaehlcke
2019-09-17  3:54 ` [PATCH V2 0/3] ADD interconnect support " Manu Gautam

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=7762a32f08a297e47a45dc9840b62d02@codeaurora.org \
    --to=cchiluve@codeaurora.org \
    --cc=agross@kernel.org \
    --cc=balbi@kernel.org \
    --cc=david.brown@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mka@chromium.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.