Re: Huawei integrated modem causes instant resume from suspend on Acer P648-G3

2017-09-27 Thread Oliver Neukum
Am Mittwoch, den 27.09.2017, 14:14 +0800 schrieb Daniel Drake:
> There are no errors in the logs showing any suspend/resume-related issues.
> When the system wakes up due to the modem, log-wise it appears to be a
> normal resume.
> 
> Does anyone have any suggestions for how we can investigate further, or how
> we should workaround this issue in upstreamable form?

Hi,

unfortunately you left out the most important information

1) kernel version?
2) driver used?
3) device descriptors (lsusb)
4) s2idle or S3?

Regards
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] r8152: add Linksys USB3GIGV1 id

2017-09-27 Thread Oliver Neukum
Am Dienstag, den 26.09.2017, 08:19 -0700 schrieb Doug Anderson:
> 
> I know that for at least some of the adapters in the CDC Ethernet
> blacklist it was claimed that the CDC Ethernet support in the adapter
> was kinda broken anyway so the blacklist made sense.  ...but for the
> Linksys Gigabit adapter the CDC Ethernet driver seems to work OK, it's
> just not quite as full featured / efficient as the R8152 driver.
> 
> Is that not a concern?  I guess you could tell people in this
> situation that they simply need to enable the R8152 driver to get
> continued support for their Ethernet adapter?

Hi,

yes, it is a valid concern. An #ifdef will be needed.

Regards
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Issue with Gadget UVC and dummy_hcd

2017-09-27 Thread Felipe Balbi

Hi,

Alan Stern  writes:
> On Tue, 26 Sep 2017, Felipe Balbi wrote:
>
>> > Does uvc use isochronous transfers?  I assume it would, since it's a 
>> > video protocol.
>> 
>> yes, it does :-)
>> 
>> > dummy-hcd does not support isochronous.  I don't know what would happen 
>> 
>> really? Then why is it registering iso endpoints to the gadget layer?
>> 
>> static const struct {
>>  const char *name;
>>  const struct usb_ep_caps caps;
>> } ep_info[] = {
>> #define EP_INFO(_name, _caps) \
>>  { \
>>  .name = _name, \
>>  .caps = _caps, \
>>  }
>> 
>>  /* everyone has ep0 */
>>  EP_INFO(ep0name,
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)),
>>  /* act like a pxa250: fifteen fixed function endpoints */
>>  EP_INFO("ep1in-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep2out-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep3in-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep4out-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep5in-int",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep6in-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep7out-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep8in-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep9out-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep10in-int",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep11in-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep12out-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep13in-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep14out-iso",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep15in-int",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
>>  /* or like sa1100: two fixed function endpoints */
>>  EP_INFO("ep1out-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep2in-bulk",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
>>  /* and now some generic EPs so we have enough in multi config */
>>  EP_INFO("ep3out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep4in",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep5out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep6out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep7in",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep8out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep9in",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep10out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep11out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep12in",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep13out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>>  EP_INFO("ep14in",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)),
>>  EP_INFO("ep15out",
>>  USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)),
>> 
>> #undef EP_INFO
>> };
>> 
>> > if you tried it, but one way or another it would not work the way you 
>> > want.
>> 
>> if that's really the case, then maybe we should remove all the iso
>> endpoints from dummy. Right?
>
> Or comment them out, in case somebody decides to add isochronous

Kinda pointless to leave commented out code, but fine.

> support in the future.  Yes, there's no point having them in the
> driver, given the way it works currently.  All isochronous URBs
> complete with a -ENOSYS error status:
>
>   switch (usb_pipetype(urb->pipe)) {
>   case PIPE_ISOCHRONOUS:
>   /* FIXME is it urb->interval since the last xfer?
>* use urb->iso_frame_desc[i].
>* complete whether or not ep has requests queued.
>* report random errors, to debug drivers.
>*/
>   limit = max(limit, periodic_bytes(dum, ep));
>   status = -ENOSYS;
>   

Re: Type-C port on the Asmedia ASM1142

2017-09-27 Thread Mathias Nyman

On 26.09.2017 22:08, Adrian Bocaniciu wrote:

On Tue, 26 Sep 2017 09:53:23 +0300
Mathias Nyman  wrote:



Do you have any more details, logs or documentation about these 10Gbps ASM1142 
bugs in xHCI driver?
I'd be interested in getting that fixed

Thanks
Mathias


I know exactly what must be changed in the XHCI driver, but I did not have time 
to implement it. If I will succeed soon to have a weekend in which I will not 
be busy, I could submit a complete patch. I can test the support for 10 Gb/s on 
6 different kinds of motherboards, 2 with ASM 1142 and 4 with the USB 3.1 
controllers from Intel Thunderbolt 3, and also with 3 or 4 different kinds of 
USB 10 GB/s to SATA 6 Gb/s bridges.


The problem in the current XHCI driver was created by a patch from 2 years ago, 
which added SuperSpeedPlus detection. However, the method used is wrong, 
according to both the Intel XHCI specification and the ASMedia datasheets.

The only explanation for the origin of the wrong detection method that I can 
imagine is that probably this method was correct for some of the first ASMedia 
USB 3.1 controllers, maybe for ASM 1042. I suppose that the first ASMedia XHCI 
controllers did not implement correctly the XHCI specification, but later they 
were corrected, at least starting with ASM 1142. Of course, the Intel USB 3.1 
controllers must have implemented the Intel specification since the beginning.

So the status is that the current Linux XHCI driver cannot detect the SuperSpeedPlus support in any 
not very old motherboard, i.e. any motherboard with ASM 1142 or newer, or any motherboard with 
Intel Thunderbolt 3. (The current XHCI driver tries to read a "3.1" value from a register 
that according to all specifications and datasheets and also according to my experiments can have 
only the "3.0" value, even in USB 3.1 controllers. The correct SuperSpeedPlus detection 
involves other registers and it is more complex.)


In have already implemented the part that detects the capabilities of the XHCI 
controller but there are also some changes that must be done to detect 
correctly the capabilities of a SuperSpeedPlus device after it is connected to 
a USB 3.1 port, otherwise the 10 Gb/s link is not established.

Best regards !



Ok, please let me know which register you refer to, I'd like to get this fixed 
as soon as possible.
Based on what you say I suspect that you talk about the SBRN (Serial bus 
release number).

The early xhci 1.1 spec that was used to write USB3.1 SSP support stated that 
SBRN contain
the serial bus specification release, (in hex) with examples of 30h for USB 3.0 
and 31h for USB 3.1

Driver uses this to determine if hosts supports USB 3.0 or usb 3.1

I see that the current public xhci spec only mention 30h (USB 3.0), and in a 
way that it can be
interpreted as 30 being the only option.
If this is the case then SBRN itself would be completely useless.
Why have a register with the purpose of telling which serial bus release number 
the hardware
supports always forced to 30h?

Yes, the first Intel Alpine ridge based USB 3.1 SSP 10Gbps xHCI hosts had this 
as 30,
Newer Intel USB 3.1 SSP capable 10Gbps xHCI hosts have it set to 31h

If vendors have interpreted it as "SBRN must equal 30h" then we need to work
around that in the driver.

We can check if the host supports USB 3.1 from the ports supported protocol 
capability,
see xhci 7.2 xHCI supported protocol capability, major and minor revision 
fields. These
should at least contain major=3 and minor=1 for USB 3.1 capable ports.

That at least is unambiguous in all xhci specs (early, and current public)

-Mathias



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: renesas_usbhs: fix usbhsf_fifo_clear() behavior

2017-09-27 Thread Yoshihiro Shimoda
This patch fixes two issues:
 - the usbhsf_fifo_clear() is possible to cause 10 msec delay if
   the pipe is RX direction and empty because the FRDY bit will never
   be set to 1 in such case.
 - sets the BCLR of {C,Dn}FIFOCTR to 1 even when it's non-DCP pipe and
   the FRDY bit sets to 0.

Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.")
Cc:  # v3.1+
Signed-off-by: Yoshihiro Shimoda 
---
 This patch set is based on the Felipe's usb.git / testing/fixes branch
 (The commit is 7661ca09b2ff98f48693f431bb01fed62830e433).

 drivers/usb/renesas_usbhs/fifo.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index d1af831..68f2690 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -282,11 +282,26 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
  struct usbhs_fifo *fifo)
 {
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+   int ret = 0;
 
-   if (!usbhs_pipe_is_dcp(pipe))
-   usbhsf_fifo_barrier(priv, fifo);
+   if (!usbhs_pipe_is_dcp(pipe)) {
+   /*
+* This driver checks the pipe condition first to avoid -EBUSY
+* from usbhsf_fifo_barrier() with about 10 msec delay in
+* the interrupt handler if the pipe is RX direction and empty.
+*/
+   if (usbhs_pipe_is_dir_in(pipe))
+   ret = usbhs_pipe_is_accessible(pipe);
+   if (!ret)
+   ret = usbhsf_fifo_barrier(priv, fifo);
+   }
 
-   usbhs_write(priv, fifo->ctr, BCLR);
+   /*
+* if non-DCP pipe, this driver should set BCLR when
+* usbhsf_fifo_barrier() returns 0.
+*/
+   if (!ret)
+   usbhs_write(priv, fifo->ctr, BCLR);
 }
 
 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 8/8] tty/serial: atmel: Prevent a warning on suspend

2017-09-27 Thread Romain Izard
The atmel serial port driver reported the following warning on suspend:
atmel_usart f802.serial: ttyS1: Unable to drain transmitter

As the ATMEL_US_TXEMPTY status bit in ATMEL_US_CSR is always cleared
when the transmitter is disabled, we need to know the transmitter's
state to return the real fifo state. And as ATMEL_US_CR is write-only,
it is necessary to save the state of the transmitter in a local
variable, and update the variable when TXEN and TXDIS is written in
ATMEL_US_CR.

After those changes, atmel_tx_empty can return "empty" on suspend, the
warning in uart_suspend_port disappears, and suspending is 20ms shorter
for each enabled Atmel serial port.

Signed-off-by: Romain Izard 
Tested-by: Nicolas Ferre 
Acked-by: Nicolas Ferre 
Acked-by: Richard Genoud 
---
 drivers/tty/serial/atmel_serial.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
index 7551cab438ff..ce45b4ada0bf 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -171,6 +171,7 @@ struct atmel_uart_port {
boolhas_hw_timer;
struct timer_list   uart_timer;
 
+   booltx_stopped;
boolsuspended;
unsigned intpending;
unsigned intpending_status;
@@ -380,6 +381,10 @@ static int atmel_config_rs485(struct uart_port *port,
  */
 static u_int atmel_tx_empty(struct uart_port *port)
 {
+   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+   if (atmel_port->tx_stopped)
+   return TIOCSER_TEMT;
return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ?
TIOCSER_TEMT :
0;
@@ -485,6 +490,7 @@ static void atmel_stop_tx(struct uart_port *port)
 * is fully transmitted.
 */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
+   atmel_port->tx_stopped = true;
 
/* Disable interrupts */
atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
@@ -521,6 +527,7 @@ static void atmel_start_tx(struct uart_port *port)
 
/* re-enable the transmitter */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
+   atmel_port->tx_stopped = false;
 }
 
 /*
@@ -1866,6 +1873,7 @@ static int atmel_startup(struct uart_port *port)
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
/* enable xmit & rcvr */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
+   atmel_port->tx_stopped = false;
 
setup_timer(&atmel_port->uart_timer,
atmel_uart_timer_callback,
@@ -2122,6 +2130,7 @@ static void atmel_set_termios(struct uart_port *port, 
struct ktermios *termios,
 
/* disable receiver and transmitter */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
+   atmel_port->tx_stopped = true;
 
/* mode */
if (port->rs485.flags & SER_RS485_ENABLED) {
@@ -2207,6 +2216,7 @@ static void atmel_set_termios(struct uart_port *port, 
struct ktermios *termios,
atmel_uart_writel(port, ATMEL_US_BRGR, quot);
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
+   atmel_port->tx_stopped = false;
 
/* restore interrupts */
atmel_uart_writel(port, ATMEL_US_IER, imr);
@@ -2450,6 +2460,7 @@ static void atmel_console_write(struct console *co, const 
char *s, u_int count)
 
/* Make sure that tx path is actually able to send characters */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
+   atmel_port->tx_stopped = false;
 
uart_console_write(port, s, count, atmel_console_putchar);
 
@@ -2511,6 +2522,7 @@ static int __init atmel_console_setup(struct console *co, 
char *options)
 {
int ret;
struct uart_port *port = &atmel_ports[co->index].uart;
+   struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
int baud = 115200;
int bits = 8;
int parity = 'n';
@@ -2528,6 +2540,7 @@ static int __init atmel_console_setup(struct console *co, 
char *options)
atmel_uart_writel(port, ATMEL_US_IDR, -1);
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
+   atmel_port->tx_stopped = false;
 
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: renesas_usbhs: fix usbhsf_fifo_clear() behavior

2017-09-27 Thread Greg KH
On Wed, Sep 27, 2017 at 05:04:05PM +0900, Yoshihiro Shimoda wrote:
> This patch fixes two issues:
>  - the usbhsf_fifo_clear() is possible to cause 10 msec delay if
>the pipe is RX direction and empty because the FRDY bit will never
>be set to 1 in such case.
>  - sets the BCLR of {C,Dn}FIFOCTR to 1 even when it's non-DCP pipe and
>the FRDY bit sets to 0.

Should this be two different patches because of this?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 7/8] atmel_flexcom: Support backup mode

2017-09-27 Thread Romain Izard
The controller used by a flexcom module is configured at boot, and left
alone after this. As the configuration will be lost after backup mode,
restore the state of the flexcom driver on resume.

Signed-off-by: Romain Izard 
Acked-by: Nicolas Ferre 
Tested-by: Nicolas Ferre 
---
 drivers/mfd/atmel-flexcom.c | 65 ++---
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c
index 064bde9cff5a..ef1235c4a179 100644
--- a/drivers/mfd/atmel-flexcom.c
+++ b/drivers/mfd/atmel-flexcom.c
@@ -39,34 +39,44 @@
 #define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) &  \
 FLEX_MR_OPMODE_MASK)
 
+struct atmel_flexcom {
+   void __iomem *base;
+   u32 opmode;
+   struct clk *clk;
+};
 
 static int atmel_flexcom_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
-   struct clk *clk;
struct resource *res;
-   void __iomem *base;
-   u32 opmode;
+   struct atmel_flexcom *afc;
int err;
+   u32 val;
+
+   afc = devm_kzalloc(&pdev->dev, sizeof(*afc), GFP_KERNEL);
+   if (!afc)
+   return -ENOMEM;
 
-   err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode);
+   platform_set_drvdata(pdev, afc);
+
+   err = of_property_read_u32(np, "atmel,flexcom-mode", &afc->opmode);
if (err)
return err;
 
-   if (opmode < ATMEL_FLEXCOM_MODE_USART ||
-   opmode > ATMEL_FLEXCOM_MODE_TWI)
+   if (afc->opmode < ATMEL_FLEXCOM_MODE_USART ||
+   afc->opmode > ATMEL_FLEXCOM_MODE_TWI)
return -EINVAL;
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   base = devm_ioremap_resource(&pdev->dev, res);
-   if (IS_ERR(base))
-   return PTR_ERR(base);
+   afc->base = devm_ioremap_resource(&pdev->dev, res);
+   if (IS_ERR(afc->base))
+   return PTR_ERR(afc->base);
 
-   clk = devm_clk_get(&pdev->dev, NULL);
-   if (IS_ERR(clk))
-   return PTR_ERR(clk);
+   afc->clk = devm_clk_get(&pdev->dev, NULL);
+   if (IS_ERR(afc->clk))
+   return PTR_ERR(afc->clk);
 
-   err = clk_prepare_enable(clk);
+   err = clk_prepare_enable(afc->clk);
if (err)
return err;
 
@@ -76,9 +86,10 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
 * inaccessible and are read as zero. Also the external I/O lines of the
 * Flexcom are muxed to reach the selected device.
 */
-   writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR);
+   val = FLEX_MR_OPMODE(afc->opmode);
+   writel(val, afc->base + FLEX_MR);
 
-   clk_disable_unprepare(clk);
+   clk_disable_unprepare(afc->clk);
 
return devm_of_platform_populate(&pdev->dev);
 }
@@ -89,10 +100,34 @@ static const struct of_device_id atmel_flexcom_of_match[] 
= {
 };
 MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
 
+#ifdef CONFIG_PM_SLEEP
+static int atmel_flexcom_resume(struct device *dev)
+{
+   struct atmel_flexcom *afc = dev_get_drvdata(dev);
+   int err;
+   u32 val;
+
+   err = clk_prepare_enable(afc->clk);
+   if (err)
+   return err;
+
+   val = FLEX_MR_OPMODE(afc->opmode),
+   writel(val, afc->base + FLEX_MR);
+
+   clk_disable_unprepare(afc->clk);
+
+   return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL,
+atmel_flexcom_resume);
+
 static struct platform_driver atmel_flexcom_driver = {
.probe  = atmel_flexcom_probe,
.driver = {
.name   = "atmel_flexcom",
+   .pm = &atmel_flexcom_pm_ops,
.of_match_table = atmel_flexcom_of_match,
},
 };
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 6/8] pwm: atmel-tcb: Support backup mode

2017-09-27 Thread Romain Izard
Save and restore registers for the PWM on suspend and resume, which
makes hibernation and backup modes possible.

Signed-off-by: Romain Izard 
Acked-by: Nicolas Ferre 
---
 drivers/pwm/pwm-atmel-tcb.c | 63 +++--
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index 75db585a2a94..acd3ce8ecf3f 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -37,11 +37,20 @@ struct atmel_tcb_pwm_device {
unsigned period;/* PWM period expressed in clk cycles */
 };
 
+struct atmel_tcb_channel {
+   u32 enabled;
+   u32 cmr;
+   u32 ra;
+   u32 rb;
+   u32 rc;
+};
+
 struct atmel_tcb_pwm_chip {
struct pwm_chip chip;
spinlock_t lock;
struct atmel_tc *tc;
struct atmel_tcb_pwm_device *pwms[NPWM];
+   struct atmel_tcb_channel bkup[NPWM / 2];
 };
 
 static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip)
@@ -175,12 +184,15 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
 * Use software trigger to apply the new setting.
 * If both PWM devices in this group are disabled we stop the clock.
 */
-   if (!(cmr & (ATMEL_TC_ACPC | ATMEL_TC_BCPC)))
+   if (!(cmr & (ATMEL_TC_ACPC | ATMEL_TC_BCPC))) {
__raw_writel(ATMEL_TC_SWTRG | ATMEL_TC_CLKDIS,
 regs + ATMEL_TC_REG(group, CCR));
-   else
+   tcbpwmc->bkup[group].enabled = 1;
+   } else {
__raw_writel(ATMEL_TC_SWTRG, regs +
 ATMEL_TC_REG(group, CCR));
+   tcbpwmc->bkup[group].enabled = 0;
+   }
 
spin_unlock(&tcbpwmc->lock);
 }
@@ -263,6 +275,7 @@ static int atmel_tcb_pwm_enable(struct pwm_chip *chip, 
struct pwm_device *pwm)
/* Use software trigger to apply the new setting */
__raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG,
 regs + ATMEL_TC_REG(group, CCR));
+   tcbpwmc->bkup[group].enabled = 1;
spin_unlock(&tcbpwmc->lock);
return 0;
 }
@@ -445,10 +458,56 @@ static const struct of_device_id atmel_tcb_pwm_dt_ids[] = 
{
 };
 MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids);
 
+#ifdef CONFIG_PM_SLEEP
+static int atmel_tcb_pwm_suspend(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
+   void __iomem *base = tcbpwm->tc->regs;
+   int i;
+
+   for (i = 0; i < (NPWM / 2); i++) {
+   struct atmel_tcb_channel *chan = &tcbpwm->bkup[i];
+
+   chan->cmr = readl(base + ATMEL_TC_REG(i, CMR));
+   chan->ra = readl(base + ATMEL_TC_REG(i, RA));
+   chan->rb = readl(base + ATMEL_TC_REG(i, RB));
+   chan->rc = readl(base + ATMEL_TC_REG(i, RC));
+   }
+   return 0;
+}
+
+static int atmel_tcb_pwm_resume(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
+   void __iomem *base = tcbpwm->tc->regs;
+   int i;
+
+   for (i = 0; i < (NPWM / 2); i++) {
+   struct atmel_tcb_channel *chan = &tcbpwm->bkup[i];
+
+   writel(chan->cmr, base + ATMEL_TC_REG(i, CMR));
+   writel(chan->ra, base + ATMEL_TC_REG(i, RA));
+   writel(chan->rb, base + ATMEL_TC_REG(i, RB));
+   writel(chan->rc, base + ATMEL_TC_REG(i, RC));
+   if (chan->enabled) {
+   writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG,
+   base + ATMEL_TC_REG(i, CCR));
+   }
+   }
+   return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(atmel_tcb_pwm_pm_ops, atmel_tcb_pwm_suspend,
+atmel_tcb_pwm_resume);
+
 static struct platform_driver atmel_tcb_pwm_driver = {
.driver = {
.name = "atmel-tcb-pwm",
.of_match_table = atmel_tcb_pwm_dt_ids,
+   .pm = &atmel_tcb_pwm_pm_ops,
},
.probe = atmel_tcb_pwm_probe,
.remove = atmel_tcb_pwm_remove,
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/8] clk: at91: pmc: Wait for clocks when resuming

2017-09-27 Thread Romain Izard
Wait for the syncronization of all clocks when resuming, not only the
UPLL clock. Do not use regmap_read_poll_timeout, as it will call BUG()
when interrupts are masked, which is the case in here.

Signed-off-by: Romain Izard 
Acked-by: Ludovic Desroches 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/pmc.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 775af473fe11..5c2b26de303e 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -107,10 +107,20 @@ static int pmc_suspend(void)
return 0;
 }
 
+static bool pmc_ready(unsigned int mask)
+{
+   unsigned int status;
+
+   regmap_read(pmcreg, AT91_PMC_SR, &status);
+
+   return ((status & mask) == mask) ? 1 : 0;
+}
+
 static void pmc_resume(void)
 {
-   int i, ret = 0;
+   int i;
u32 tmp;
+   u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA;
 
regmap_read(pmcreg, AT91_PMC_MCKR, &tmp);
if (pmc_cache.mckr != tmp)
@@ -134,13 +144,11 @@ static void pmc_resume(void)
 AT91_PMC_PCR_CMD);
}
 
-   if (pmc_cache.uckr & AT91_PMC_UPLLEN) {
-   ret = regmap_read_poll_timeout(pmcreg, AT91_PMC_SR, tmp,
-  !(tmp & AT91_PMC_LOCKU),
-  10, 5000);
-   if (ret)
-   pr_crit("USB PLL didn't lock when resuming\n");
-   }
+   if (pmc_cache.uckr & AT91_PMC_UPLLEN)
+   mask |= AT91_PMC_LOCKU;
+
+   while (!pmc_ready(mask))
+   cpu_relax();
 }
 
 static struct syscore_ops pmc_syscore_ops = {
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/8] mtd: nand: atmel: Avoid ECC errors when leaving backup mode

2017-09-27 Thread Romain Izard
During backup mode, the contents of all registers will be cleared as the
SoC will be completely powered down. For a product that boots on NAND
Flash memory, the bootloader will obviously use the related controller
to read the Flash and correct any detected error in the memory, before
handling back control to the kernel's resuming entry point.

But it does not clean the NAND controller registers after use and on its
side the kernel driver expects the error locator to be powered down and
in a clean state. Add a resume hook for the PMECC error locator, and
reset its registers.

Signed-off-by: Romain Izard 
---
Change in v3:
* keep the PMECC disabled when not in use, and use atmel_pmecc_resume to
  reset the controller after the bootloader has left it enabled.

 drivers/mtd/nand/atmel/nand-controller.c |  3 +++
 drivers/mtd/nand/atmel/pmecc.c   | 22 ++
 drivers/mtd/nand/atmel/pmecc.h   |  1 +
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/atmel/nand-controller.c 
b/drivers/mtd/nand/atmel/nand-controller.c
index f25eca79f4e5..86c2199380c2 100644
--- a/drivers/mtd/nand/atmel/nand-controller.c
+++ b/drivers/mtd/nand/atmel/nand-controller.c
@@ -2530,6 +2530,9 @@ static __maybe_unused int 
atmel_nand_controller_resume(struct device *dev)
struct atmel_nand_controller *nc = dev_get_drvdata(dev);
struct atmel_nand *nand;
 
+   if (nand->pmecc)
+   atmel_pmecc_resume(nand->pmecc);
+
list_for_each_entry(nand, &nc->chips, node) {
int i;
 
diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
index 146af8218314..ff09c0f25dd4 100644
--- a/drivers/mtd/nand/atmel/pmecc.c
+++ b/drivers/mtd/nand/atmel/pmecc.c
@@ -765,6 +765,12 @@ void atmel_pmecc_get_generated_eccbytes(struct 
atmel_pmecc_user *user,
 }
 EXPORT_SYMBOL_GPL(atmel_pmecc_get_generated_eccbytes);
 
+void atmel_pmecc_reset(struct atmel_pmecc *pmecc)
+{
+   writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
+   writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
+}
+
 int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op)
 {
struct atmel_pmecc *pmecc = user->pmecc;
@@ -797,14 +803,17 @@ EXPORT_SYMBOL_GPL(atmel_pmecc_enable);
 
 void atmel_pmecc_disable(struct atmel_pmecc_user *user)
 {
-   struct atmel_pmecc *pmecc = user->pmecc;
-
-   writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
-   writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
+   atmel_pmecc_reset(user->pmecc);
mutex_unlock(&user->pmecc->lock);
 }
 EXPORT_SYMBOL_GPL(atmel_pmecc_disable);
 
+void atmel_pmecc_resume(struct atmel_pmecc_user *user)
+{
+   atmel_pmecc_reset(user->pmecc);
+}
+EXPORT_SYMBOL_GPL(atmel_pmecc_resume);
+
 int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user)
 {
struct atmel_pmecc *pmecc = user->pmecc;
@@ -855,10 +864,7 @@ static struct atmel_pmecc *atmel_pmecc_create(struct 
platform_device *pdev,
 
/* Disable all interrupts before registering the PMECC handler. */
writel(0x, pmecc->regs.base + ATMEL_PMECC_IDR);
-
-   /* Reset the ECC engine */
-   writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
-   writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
+   atmel_pmecc_reset(pmecc);
 
return pmecc;
 }
diff --git a/drivers/mtd/nand/atmel/pmecc.h b/drivers/mtd/nand/atmel/pmecc.h
index a8ddbfca2ea5..488a90f1965d 100644
--- a/drivers/mtd/nand/atmel/pmecc.h
+++ b/drivers/mtd/nand/atmel/pmecc.h
@@ -63,6 +63,7 @@ void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
 
 int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
 void atmel_pmecc_disable(struct atmel_pmecc_user *user);
+void atmel_pmecc_resume(struct atmel_pmecc_user *user);
 int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user);
 int atmel_pmecc_correct_sector(struct atmel_pmecc_user *user, int sector,
   void *data, void *ecc);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/8] ehci-atmel: Power down during suspend is normal

2017-09-27 Thread Romain Izard
When an Atmel SoC is suspended with the backup mode, the USB bus will be
powered down. As this is expected, do not return an error to the driver
core when ehci_resume detects it.

Signed-off-by: Romain Izard 
Acked-by: Nicolas Ferre 
---
 drivers/usb/host/ehci-atmel.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 7440722bfbf0..2a8b9bdc0e57 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -205,7 +205,8 @@ static int __maybe_unused ehci_atmel_drv_resume(struct 
device *dev)
struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
 
atmel_start_clock(atmel_ehci);
-   return ehci_resume(hcd, false);
+   ehci_resume(hcd, false);
+   return 0;
 }
 
 #ifdef CONFIG_OF
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/8] Various patches for SAMA5D2 backup mode

2017-09-27 Thread Romain Izard
While the core of the backup mode for SAMA5D2 has been integrated in
v4.13, it is far from complete. Individual controllers in the chip have
drivers that do not support the reset of the registers during suspend,
and they need to be adapted to handle it.

The first patch uses the clock wakeup code from the prototype backup
mode instead of the version integrated in the mainline, as the mainline
version is not stable. During a test loop with two-second backup
suspend, the mainline version will hang in less than one day, whereas
the prototype version has been running the same test for more than a
week without hanging.

While all these patches are provided in a series, the clock, mtd,
usb, pwm and mfd patch do not depend on each other.

Changes in v2:
* drop the IIO patch duplicating existing code
* determine the number of programmable clocks to save dynamically
* declare a required local variable in the tty/serial patch

Changes in v3:
* drop dev_printk changes for PMECC
* rework the resume code for PMECC
* improve comments on PMC clock handling

Romain Izard (8):
  clk: at91: pmc: Wait for clocks when resuming
  clk: at91: pmc: Save SCSR during suspend
  clk: at91: pmc: Support backup for programmable clocks
  mtd: nand: atmel: Avoid ECC errors when leaving backup mode
  ehci-atmel: Power down during suspend is normal
  pwm: atmel-tcb: Support backup mode
  atmel_flexcom: Support backup mode
  tty/serial: atmel: Prevent a warning on suspend

 drivers/clk/at91/clk-programmable.c  |  2 +
 drivers/clk/at91/pmc.c   | 63 ++-
 drivers/clk/at91/pmc.h   |  2 +
 drivers/mfd/atmel-flexcom.c  | 65 
 drivers/mtd/nand/atmel/nand-controller.c |  3 ++
 drivers/mtd/nand/atmel/pmecc.c   | 22 +++
 drivers/mtd/nand/atmel/pmecc.h   |  1 +
 drivers/pwm/pwm-atmel-tcb.c  | 63 ++-
 drivers/tty/serial/atmel_serial.c| 13 +++
 drivers/usb/host/ehci-atmel.c|  3 +-
 10 files changed, 201 insertions(+), 36 deletions(-)

-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: renesas_usbhs: fix usbhsf_fifo_clear() behavior

2017-09-27 Thread Yoshihiro Shimoda
Hi Greg,

> -Original Message-
> From: Greg KH
> Sent: Wednesday, September 27, 2017 5:37 PM
> 
> On Wed, Sep 27, 2017 at 05:04:05PM +0900, Yoshihiro Shimoda wrote:
> > This patch fixes two issues:
> >  - the usbhsf_fifo_clear() is possible to cause 10 msec delay if
> >the pipe is RX direction and empty because the FRDY bit will never
> >be set to 1 in such case.
> >  - sets the BCLR of {C,Dn}FIFOCTR to 1 even when it's non-DCP pipe and
> >the FRDY bit sets to 0.
> 
> Should this be two different patches because of this?

I got it. I will make two patches from this patch.

Best regards,
Yoshihiro Shimoda

> thanks,
> 
> greg k-h
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/8] clk: at91: pmc: Save SCSR during suspend

2017-09-27 Thread Romain Izard
The contents of the System Clock Status Register (SCSR) needs to be
restored into the System Clock Enable Register (SCER).

As the bootloader will restore some clocks by itself, the issue can be
missed as only the USB controller, the LCD controller, the Image Sensor
controller and the programmable clocks will be impacted.

Fix the obvious typo in the suspend/resume code, as the IMR register
does not need to be saved twice.

Signed-off-by: Romain Izard 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/pmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 5c2b26de303e..07dc2861ad3f 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -86,7 +86,7 @@ static int pmc_suspend(void)
 {
int i;
 
-   regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.scsr);
+   regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr);
regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr);
regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor);
@@ -129,7 +129,7 @@ static void pmc_resume(void)
if (pmc_cache.pllar != tmp)
pr_warn("PLLAR was not configured properly by the firmware\n");
 
-   regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.scsr);
+   regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr);
regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0);
regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr);
regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/8] clk: at91: pmc: Support backup for programmable clocks

2017-09-27 Thread Romain Izard
From: Romain Izard 

When an AT91 programmable clock is declared in the device tree, register
it into the Power Management Controller driver. On entering suspend mode,
the driver saves and restores the Programmable Clock registers to support
the backup mode for these clocks.

Signed-off-by: Romain Izard 
Acked-by: Nicolas Ferre 
---
Changes in v2:
* register PCKs on clock startup
Chnages in v3:
* improve comments on hanling 0 in pmc_register_id and pmc_register_pck
* declare local variables earlier for checkpatch

 drivers/clk/at91/clk-programmable.c |  2 ++
 drivers/clk/at91/pmc.c  | 35 +++
 drivers/clk/at91/pmc.h  |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/drivers/clk/at91/clk-programmable.c 
b/drivers/clk/at91/clk-programmable.c
index 85a449cf61e3..0e6aab1252fc 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -204,6 +204,8 @@ at91_clk_register_programmable(struct regmap *regmap,
if (ret) {
kfree(prog);
hw = ERR_PTR(ret);
+   } else {
+   pmc_register_pck(id);
}
 
return hw;
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 07dc2861ad3f..1fa27f4ea538 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -22,6 +22,7 @@
 #include "pmc.h"
 
 #define PMC_MAX_IDS 128
+#define PMC_MAX_PCKS 8
 
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
  struct clk_range *range)
@@ -50,6 +51,7 @@ EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
 static struct regmap *pmcreg;
 
 static u8 registered_ids[PMC_MAX_IDS];
+static u8 registered_pcks[PMC_MAX_PCKS];
 
 static struct
 {
@@ -66,8 +68,13 @@ static struct
u32 pcr[PMC_MAX_IDS];
u32 audio_pll0;
u32 audio_pll1;
+   u32 pckr[PMC_MAX_PCKS];
 } pmc_cache;
 
+/*
+ * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored
+ * without alteration in the table, and 0 is for unused clocks.
+ */
 void pmc_register_id(u8 id)
 {
int i;
@@ -82,9 +89,28 @@ void pmc_register_id(u8 id)
}
 }
 
+/*
+ * As Programmable Clock 0 is valid on AT91 chips, there is an offset
+ * of 1 between the stored value and the real clock ID.
+ */
+void pmc_register_pck(u8 pck)
+{
+   int i;
+
+   for (i = 0; i < PMC_MAX_PCKS; i++) {
+   if (registered_pcks[i] == 0) {
+   registered_pcks[i] = pck + 1;
+   break;
+   }
+   if (registered_pcks[i] == (pck + 1))
+   break;
+   }
+}
+
 static int pmc_suspend(void)
 {
int i;
+   u8 num;
 
regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr);
regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
@@ -103,6 +129,10 @@ static int pmc_suspend(void)
regmap_read(pmcreg, AT91_PMC_PCR,
&pmc_cache.pcr[registered_ids[i]]);
}
+   for (i = 0; registered_pcks[i]; i++) {
+   num = registered_pcks[i] - 1;
+   regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]);
+   }
 
return 0;
 }
@@ -119,6 +149,7 @@ static bool pmc_ready(unsigned int mask)
 static void pmc_resume(void)
 {
int i;
+   u8 num;
u32 tmp;
u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA;
 
@@ -143,6 +174,10 @@ static void pmc_resume(void)
 pmc_cache.pcr[registered_ids[i]] |
 AT91_PMC_PCR_CMD);
}
+   for (i = 0; registered_pcks[i]; i++) {
+   num = registered_pcks[i] - 1;
+   regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]);
+   }
 
if (pmc_cache.uckr & AT91_PMC_UPLLEN)
mask |= AT91_PMC_LOCKU;
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 858e8ef7e8db..d22b1fa9ecdc 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -31,8 +31,10 @@ int of_at91_get_clk_range(struct device_node *np, const char 
*propname,
 
 #ifdef CONFIG_PM
 void pmc_register_id(u8 id);
+void pmc_register_pck(u8 pck);
 #else
 static inline void pmc_register_id(u8 id) {}
+static inline void pmc_register_pck(u8 pck) {}
 #endif
 
 #endif /* __PMC_H_ */
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 00/17] Support for Qualcomm QUSBv2 and QMPv3 USB PHYs

2017-09-27 Thread Manu Gautam
QUSB-v2 and QMP-v3 USB PHYs are present on Qualcomm's 14nm
and 10nm SOCs.
This patch series adds support for runtime PM for these
USB PHYs and adds fixes in drivers to follow PHY reset and
initialization sequence as per hardware programming manual.

Changes since v1:
- Incorporated review comments.
- Fixes to align with hardware programming manual.
- Added support for QUSBv2 and QMPv3 PHYs.
- Enable DP/DM asynchronous interrupts from QUSB2 USB2 PHY
  for remote-wakeup.
- Enable LFPS and RX-TERM detection for attach and detach
  events from QMP USB3 PHY for remotewakeup.
- Update sw-vbus overide in PHY wrapper for device mode.
- Dropped one dwc3 patch from this series which I will submit
  with other dwc3 patches. ("usb: dwc3: core: Notify USB3 PHY as
  well for DRD modes")

Manu Gautam (15):
  phy: qcom-qmp: Power-on PHY before initialization
  phy: qcom-qusb2: Power-on PHY before initialization
  phy: qcom-qmp: Fix PHY block reset sequence
  phy: qcom-qmp: Move SERDES/PCS START after PHY reset
  phy: qcom-qusb2: Add support for different register layouts
  dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version
  phy: qcom-qusb2: Add support for QUSB2 V2 version
  phy: qcom-qmp: Move register offsets to header file
  phy: qcom-qmp: Add register offsets for QMP V3 PHY
  dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY
  phy: qcom-qmp: Add support for QMP V3 USB3 PHY
  phy: qcom-qusb2: Set vbus sw-override signal in device mode
  phy: qcom-qusb2: Add support for runtime PM
  phy: qcom-qmp: Override lane0_power_present signal in device mode
  phy: qcom-qmp: Add support for runtime PM

Vivek Gautam (2):
  phy: qcom-qmp: Fix phy pipe clock gating
  phy: qcom-qmp: Adapt to clk_bulk_* APIs

 .../devicetree/bindings/phy/qcom-qmp-phy.txt   |   6 +-
 .../devicetree/bindings/phy/qcom-qusb2-phy.txt |   5 +-
 drivers/phy/qualcomm/phy-qcom-qmp.c| 696 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h| 289 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 412 ++--
 5 files changed, 1148 insertions(+), 260 deletions(-)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 16/17] phy: qcom-qmp: Override lane0_power_present signal in device mode

2017-09-27 Thread Manu Gautam
lane0_power_present signal must be asserted of hardware to
operate properly in SS device mode. On some platforms where VBUS
line is not connected to SS QMP PHY there is SS_PHY_CTRL register
in QSCRATCH wrapper that can be used by software to override VBUS.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 38 +
 1 file changed, 38 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index d4e1436..1403de3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -61,6 +61,9 @@
 #define USB3_MODE  BIT(0) /* enables USB3 mode */
 #define DP_MODEBIT(1) /* enables DP 
mode */
 
+/* QSCRATCH register bits */
+#define QSCRATCH_SS_PHY_CTRL   0x30
+#define LANE0_PWR_PRESENT  BIT(24)
 
 #define PHY_INIT_COMPLETE_TIMEOUT  1000
 #define POWER_DOWN_DELAY_US_MIN10
@@ -558,6 +561,7 @@ struct qmp_phy {
  * @dev: device
  * @serdes: iomapped memory space for phy's serdes
  * @dp_com: iomapped memory space for phy's dp_com control block
+ * @qscratch_base: iomapped memory space for qscratch region
  *
  * @clks: array of clocks required by phy
  * @resets: array of resets required by phy
@@ -572,6 +576,7 @@ struct qcom_qmp {
struct device *dev;
void __iomem *serdes;
void __iomem *dp_com;
+   void __iomem *qscratch_base;
 
struct clk_bulk_data *clks;
struct reset_control **resets;
@@ -582,6 +587,7 @@ struct qcom_qmp {
 
struct mutex phy_mutex;
int init_count;
+   enum phy_mode mode;
 };
 
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -1024,6 +1030,26 @@ static int qcom_qmp_phy_exit(struct phy *phy)
return 0;
 }
 
+static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+   struct qmp_phy *qphy = phy_get_drvdata(phy);
+   struct qcom_qmp *qmp = qphy->qmp;
+
+   qmp->mode = mode;
+
+   /* Update VBUS override in qscratch register */
+   if (qmp->qscratch_base) {
+   if (mode == PHY_MODE_USB_DEVICE)
+   qphy_setbits(qmp->qscratch_base, QSCRATCH_SS_PHY_CTRL,
+LANE0_PWR_PRESENT);
+   else
+   qphy_clrbits(qmp->qscratch_base, QSCRATCH_SS_PHY_CTRL,
+LANE0_PWR_PRESENT);
+   }
+
+   return 0;
+}
+
 static int qcom_qmp_phy_vreg_init(struct device *dev)
 {
struct qcom_qmp *qmp = dev_get_drvdata(dev);
@@ -1133,6 +1159,7 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
 static const struct phy_ops qcom_qmp_phy_gen_ops = {
.init   = qcom_qmp_phy_init,
.exit   = qcom_qmp_phy_exit,
+   .set_mode   = qcom_qmp_phy_set_mode,
.owner  = THIS_MODULE,
 };
 
@@ -1273,7 +1300,18 @@ static int qcom_qmp_phy_probe(struct platform_device 
*pdev)
qmp->dp_com = base;
}
 
+   /* Check if platform uses qscratch wrapper */
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qscratch");
+   if (res) {
+   /* Can't request region as used by other phy and glue drivers */
+   qmp->qscratch_base = devm_ioremap(dev, res->start,
+  resource_size(res));
+   if (IS_ERR(qmp->qscratch_base))
+   return PTR_ERR(qmp->qscratch_base);
+   }
+
mutex_init(&qmp->phy_mutex);
+   qmp->mode = PHY_MODE_INVALID;
 
ret = qcom_qmp_phy_clk_init(dev);
if (ret)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 17/17] phy: qcom-qmp: Add support for runtime PM

2017-09-27 Thread Manu Gautam
Disable clocks as part of PHY suspend. This also requires enabling
PHY autonomous mode to detect lfps/rx_det in suspend state.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 182 +++-
 drivers/phy/qualcomm/phy-qcom-qmp.h |   3 +
 2 files changed, 184 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 1403de3..a04ba28 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -61,6 +61,20 @@
 #define USB3_MODE  BIT(0) /* enables USB3 mode */
 #define DP_MODEBIT(1) /* enables DP 
mode */
 
+/* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
+#define ARCVR_DTCT_EN  BIT(0)
+#define ALFPS_DTCT_EN  BIT(1)
+#define ARCVR_DTCT_EVENT_SEL   BIT(4)
+
+/* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
+#define IRQ_CLEAR  BIT(0)
+
+/* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
+#define RCVR_DETECTBIT(0)
+
+/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
+#define CLAMP_EN   BIT(0) /* enables i/o clamp_n */
+
 /* QSCRATCH register bits */
 #define QSCRATCH_SS_PHY_CTRL   0x30
 #define LANE0_PWR_PRESENT  BIT(24)
@@ -111,6 +125,9 @@ enum qphy_reg_layout {
QPHY_SW_RESET,
QPHY_START_CTRL,
QPHY_PCS_READY_STATUS,
+   QPHY_PCS_AUTONOMOUS_MODE_CTRL,
+   QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
+   QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
 };
 
 static const unsigned int pciephy_regs_layout[] = {
@@ -138,12 +155,18 @@ enum qphy_reg_layout {
[QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL]   = 0x08,
[QPHY_PCS_READY_STATUS] = 0x17c,
+   [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
+   [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
+   [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
 };
 
 static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
[QPHY_SW_RESET] = 0x00,
[QPHY_START_CTRL]   = 0x08,
[QPHY_PCS_READY_STATUS] = 0x174,
+   [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
+   [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
+   [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
 };
 
 static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
@@ -539,6 +562,7 @@ struct qmp_phy_cfg {
  * @tx: iomapped memory space for lane's tx
  * @rx: iomapped memory space for lane's rx
  * @pcs: iomapped memory space for lane's pcs
+ * @pcs_misc: iomapped memory space for lane's pcs_misc
  * @pipe_clk: pipe lock
  * @index: lane index
  * @qmp: QMP phy to which this lane belongs
@@ -549,6 +573,7 @@ struct qmp_phy {
void __iomem *tx;
void __iomem *rx;
void __iomem *pcs;
+   void __iomem *pcs_misc;
struct clk *pipe_clk;
unsigned int index;
struct qcom_qmp *qmp;
@@ -587,6 +612,7 @@ struct qcom_qmp {
 
struct mutex phy_mutex;
int init_count;
+   bool phy_initialized;
enum phy_mode mode;
 };
 
@@ -784,6 +810,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 {
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *serdes = qmp->serdes;
+   void __iomem *dp_com = qmp->dp_com;
int ret, i;
 
mutex_lock(&qmp->phy_mutex);
@@ -993,6 +1020,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
goto err_pcs_ready;
}
+   qmp->phy_initialized = true;
 
return 0;
 
@@ -1027,6 +1055,135 @@ static int qcom_qmp_phy_exit(struct phy *phy)
 
qcom_qmp_phy_com_exit(qmp);
 
+   qmp->phy_initialized = false;
+
+   return 0;
+}
+
+static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy)
+{
+   struct qcom_qmp *qmp = qphy->qmp;
+   const struct qmp_phy_cfg *cfg = qmp->cfg;
+   void __iomem *pcs = qphy->pcs;
+   void __iomem *pcs_misc = qphy->pcs_misc;
+   unsigned int reg;
+
+   /* Clear previous PHY int_status before checking rx_det */
+   qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+   /* Writing 1 followed by 0 clears the interrupt */
+   qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
+
+   /* Enable PHY autonomous mode to detect lfps and rx_det detach */
+   qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
+ARCVR_DTCT_EN | ALFPS_DTCT_EN);
+
+   /* Enable i/o clamp_n for autonomous mode */
+   if (pcs_misc)
+   qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
+
+   /* Add delay for int_status to reflect current rx_det state */
+   usleep_range(1, 12000);
+   reg = readl(pcs + cfg->r

[PATCH v2 15/17] phy: qcom-qusb2: Add support for runtime PM

2017-09-27 Thread Manu Gautam
Disable clocks and dp/dm asynchronous interrupts from
PHY as part of runtime suspend.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 159 ++
 1 file changed, 159 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 0e9d88b..7414272 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -56,6 +56,18 @@
 
 #define PHY_CLK_SCHEME_SEL BIT(0)
 
+/* QUSB2PHY_INTR_CTRL register bits */
+#define DMSE_INTR_HIGH_SEL BIT(4)
+#define DPSE_INTR_HIGH_SEL BIT(3)
+#define CHG_DET_INTR_ENBIT(2)
+#define DMSE_INTR_EN   BIT(1)
+#define DPSE_INTR_EN   BIT(0)
+
+/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register bits */
+#define CORE_PLL_EN_FROM_RESET BIT(4)
+#define CORE_RESET BIT(5)
+#define CORE_RESET_MUX BIT(6)
+
 #defineQUSB2PHY_PLL_ANALOG_CONTROLS_TWO0x04
 #defineQUSB2PHY_PLL_CLOCK_INVERTERS0x18c
 #defineQUSB2PHY_PLL_CMODE  0x2c
@@ -73,6 +85,10 @@
 #define UTMI_OTG_VBUS_VALIDBIT(20)
 #define SW_SESSVLD_SEL BIT(28)
 
+#define QSCRATCH_CHARGING_DET_OUTPUT   0x1C
+#define LINESTATE_DP   BIT(8)
+#define LINESTATE_DM   BIT(9)
+
 struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
@@ -98,6 +114,7 @@ struct qusb2_phy_init_tbl {
 
 /* set of registers with offsets different per-PHY */
 enum qusb2phy_reg_layout {
+   QUSB2PHY_PLL_CORE_INPUT_OVERRIDE,
QUSB2PHY_PLL_STATUS,
QUSB2PHY_PORT_TUNE1,
QUSB2PHY_PORT_TUNE2,
@@ -117,8 +134,10 @@ enum qusb2phy_reg_layout {
[QUSB2PHY_PORT_TUNE3]   = 0x88,
[QUSB2PHY_PORT_TUNE4]   = 0x8c,
[QUSB2PHY_PORT_TUNE5]   = 0x90,
+   [QUSB2PHY_PORT_TEST1]   = 0xb8,
[QUSB2PHY_PORT_TEST2]   = 0x9c,
[QUSB2PHY_PORT_POWERDOWN]   = 0xb4,
+   [QUSB2PHY_INTR_CTRL]= 0xbc,
 };
 
 static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
@@ -138,14 +157,17 @@ enum qusb2phy_reg_layout {
 };
 
 static const unsigned int qusb2_v2_regs_layout[] = {
+   [QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
[QUSB2PHY_PLL_STATUS]   = 0x1a0,
[QUSB2PHY_PORT_TUNE1]   = 0x240,
[QUSB2PHY_PORT_TUNE2]   = 0x244,
[QUSB2PHY_PORT_TUNE3]   = 0x248,
[QUSB2PHY_PORT_TUNE4]   = 0x24c,
[QUSB2PHY_PORT_TUNE5]   = 0x250,
+   [QUSB2PHY_PORT_TEST1]   = 0x254,
[QUSB2PHY_PORT_TEST2]   = 0x258,
[QUSB2PHY_PORT_POWERDOWN]   = 0x210,
+   [QUSB2PHY_INTR_CTRL]= 0x230,
 };
 
 static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
@@ -180,9 +202,13 @@ struct qusb2_phy_cfg {
const unsigned int *regs;
unsigned int mask_core_ready;
unsigned int disable_ctrl;
+   unsigned int autoresume_en;
 
/* true if PHY has PLL_TEST register to select clk_scheme */
bool has_pll_test;
+
+   /* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
+   bool has_pll_override;
 };
 
 static const struct qusb2_phy_cfg msm8996_phy_cfg = {
@@ -193,6 +219,7 @@ struct qusb2_phy_cfg {
.has_pll_test   = true,
.disable_ctrl   = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
.mask_core_ready = PLL_LOCKED,
+   .autoresume_en   = BIT(3),
 };
 
 static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
@@ -203,6 +230,8 @@ struct qusb2_phy_cfg {
.disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
   POWER_DOWN),
.mask_core_ready = CORE_READY_STATUS,
+   .has_pll_override = true,
+   .autoresume_en= BIT(0),
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
@@ -229,6 +258,7 @@ struct qusb2_phy_cfg {
  *
  * @cfg: phy config data
  * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ * @phy_initialized: indicate if PHY has been initialized
  * @mode: indicate current PHY mode of operation e.g. HOST or DEVICE
  */
 struct qusb2_phy {
@@ -247,6 +277,7 @@ struct qusb2_phy {
 
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
+   bool phy_initialized;
enum phy_mode mode;
 };
 
@@ -335,6 +366,115 @@ static int qusb2_phy_set_mode(struct phy *phy, enum 
phy_mode mode)
return 0;
 }
 
+static int __maybe_unused qusb2_phy_runtime_suspend(struct device *dev)
+{
+   struct qusb2_phy *qphy = dev_get_drvdata(dev);
+   const struct qusb2_phy_cfg *cfg = qphy->cfg;
+   u32 linestate = 0, intr_mask;
+
+   dev_vdbg(dev, "Suspending QUSB2 Phy, mode:%d\

[PATCH v2 13/17] phy: qcom-qmp: Add support for QMP V3 USB3 PHY

2017-09-27 Thread Manu Gautam
QMP V3 USB3 PHY is a DP USB combo PHY with
dual RX/TX lanes to support type-c. There is a
separate block DP_COM for configuration related
to type-c or DP. Add support for dp_com region
and secondary rx/tx lanes initialization.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 222 +++-
 1 file changed, 219 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 15a734f..d4e1436 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -47,6 +47,21 @@
 /* QPHY_COM_PCS_READY_STATUS bit */
 #define PCS_READY  BIT(0)
 
+/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
+/* DP PHY soft reset */
+#define SW_DPPHY_RESET BIT(0)
+/* mux to select DP PHY reset control, 0:HW control, 1: software reset */
+#define SW_DPPHY_RESET_MUX BIT(1)
+/* USB3 PHY soft reset */
+#define SW_USB3PHY_RESET   BIT(2)
+/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
+#define SW_USB3PHY_RESET_MUX   BIT(3)
+
+/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
+#define USB3_MODE  BIT(0) /* enables USB3 mode */
+#define DP_MODEBIT(1) /* enables DP 
mode */
+
+
 #define PHY_INIT_COMPLETE_TIMEOUT  1000
 #define POWER_DOWN_DELAY_US_MIN10
 #define POWER_DOWN_DELAY_US_MAX11
@@ -122,6 +137,12 @@ enum qphy_reg_layout {
[QPHY_PCS_READY_STATUS] = 0x17c,
 };
 
+static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
+   [QPHY_SW_RESET] = 0x00,
+   [QPHY_START_CTRL]   = 0x08,
+   [QPHY_PCS_READY_STATUS] = 0x174,
+};
+
 static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
@@ -350,6 +371,112 @@ enum qphy_reg_layout {
QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
 };
 
+static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x0a),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
+   QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = {
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
+   QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06),
+};
+
+static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = {
+   QMP_PHY_IN

[PATCH v2 14/17] phy: qcom-qusb2: Set vbus sw-override signal in device mode

2017-09-27 Thread Manu Gautam
VBUS signal coming from PHY must be asserted in device for
controller to start operation or assert pull-up. For some
platforms where VBUS line is not connected to PHY there is
HS_PHY_CTRL register in QSCRATCH wrapper that can be used
by software to override VBUS signal going to controller.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index bda1f4c..0e9d88b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -68,6 +68,11 @@
 #defineQUSB2PHY_IMP_CTRL2  0x224
 #defineQUSB2PHY_CHG_CTRL2  0x23c
 
+/* QSCRATCH register bits */
+#define QSCRATCH_HS_PHY_CTRL   0x10
+#define UTMI_OTG_VBUS_VALIDBIT(20)
+#define SW_SESSVLD_SEL BIT(28)
+
 struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
@@ -211,6 +216,7 @@ struct qusb2_phy_cfg {
  *
  * @phy: generic phy
  * @base: iomapped memory space for qubs2 phy
+ * @qscratch_base: iomapped memory space for qscratch region
  *
  * @cfg_ahb_clk: AHB2PHY interface clock
  * @ref_clk: phy reference clock
@@ -223,10 +229,12 @@ struct qusb2_phy_cfg {
  *
  * @cfg: phy config data
  * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ * @mode: indicate current PHY mode of operation e.g. HOST or DEVICE
  */
 struct qusb2_phy {
struct phy *phy;
void __iomem *base;
+   void __iomem *qscratch_base;
 
struct clk *cfg_ahb_clk;
struct clk *ref_clk;
@@ -239,6 +247,7 @@ struct qusb2_phy {
 
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
+   enum phy_mode mode;
 };
 
 static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
@@ -307,6 +316,25 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
 }
 
+static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+   struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+   qphy->mode = mode;
+
+   /* Update VBUS override in qscratch register */
+   if (qphy->qscratch_base) {
+   if (mode == PHY_MODE_USB_DEVICE)
+   qusb2_setbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
+ UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
+   else
+   qusb2_clrbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
+ UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
+   }
+
+   return 0;
+}
+
 static int qusb2_phy_init(struct phy *phy)
 {
struct qusb2_phy *qphy = phy_get_drvdata(phy);
@@ -473,6 +501,7 @@ static int qusb2_phy_exit(struct phy *phy)
 static const struct phy_ops qusb2_phy_gen_ops = {
.init   = qusb2_phy_init,
.exit   = qusb2_phy_exit,
+   .set_mode   = qusb2_phy_set_mode,
.owner  = THIS_MODULE,
 };
 
@@ -507,6 +536,16 @@ static int qusb2_phy_probe(struct platform_device *pdev)
if (IS_ERR(qphy->base))
return PTR_ERR(qphy->base);
 
+   /* Check if platform uses qscratch wrapper */
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qscratch");
+   if (res) {
+   /* Can't request region as used by other phy and glue drivers */
+   qphy->qscratch_base = devm_ioremap(dev, res->start,
+  resource_size(res));
+   if (IS_ERR(qphy->qscratch_base))
+   return PTR_ERR(qphy->qscratch_base);
+   }
+
qphy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb");
if (IS_ERR(qphy->cfg_ahb_clk)) {
ret = PTR_ERR(qphy->cfg_ahb_clk);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 12/17] dt-bindings: phy-qcom-qmp: Update bindings for QMP V3 USB PHY

2017-09-27 Thread Manu Gautam
Update compatible string and clock names for QMP version V3
USB PHY.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
index b6a9f2b..dcf1b8f 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -8,7 +8,8 @@ Required properties:
  - compatible: compatible list, contains:
   "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074
   "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
-  "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
+  "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996,
+  "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy.
 
  - reg: offset and length of register set for PHY's common serdes block.
 
@@ -25,10 +26,13 @@ Required properties:
  - clock-names: "cfg_ahb" for phy config clock,
"aux" for phy aux clock,
"ref" for 19.2 MHz ref clk,
+   "com_aux" for phy common block aux clock,
For "qcom,msm8996-qmp-pcie-phy" must contain:
"aux", "cfg_ahb", "ref".
For "qcom,msm8996-qmp-usb3-phy" must contain:
"aux", "cfg_ahb", "ref".
+   For "qcom,qmp-v3-usb3-phy" must contain:
+   "aux", "cfg_ahb", "ref", "com_aux".
 
  - resets: a list of phandles and reset controller specifier pairs,
   one for each entry in reset-names.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 10/17] phy: qcom-qmp: Move register offsets to header file

2017-09-27 Thread Manu Gautam
New revision (v3) of QMP PHY uses different offsets
for almost all of the registers. Hence, move these
definitions to header file so that updated offsets
can be added for QMP v3.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 119 +--
 drivers/phy/qualcomm/phy-qcom-qmp.h | 137 
 2 files changed, 138 insertions(+), 118 deletions(-)
 create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.h

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 263cf50..15a734f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -31,124 +31,7 @@
 
 #include 
 
-/* QMP PHY QSERDES COM registers */
-#define QSERDES_COM_BG_TIMER   0x00c
-#define QSERDES_COM_SSC_EN_CENTER  0x010
-#define QSERDES_COM_SSC_ADJ_PER1   0x014
-#define QSERDES_COM_SSC_ADJ_PER2   0x018
-#define QSERDES_COM_SSC_PER1   0x01c
-#define QSERDES_COM_SSC_PER2   0x020
-#define QSERDES_COM_SSC_STEP_SIZE1 0x024
-#define QSERDES_COM_SSC_STEP_SIZE2 0x028
-#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN0x034
-#define QSERDES_COM_CLK_ENABLE10x038
-#define QSERDES_COM_SYS_CLK_CTRL   0x03c
-#define QSERDES_COM_SYSCLK_BUF_ENABLE  0x040
-#define QSERDES_COM_PLL_IVCO   0x048
-#define QSERDES_COM_LOCK_CMP1_MODE00x04c
-#define QSERDES_COM_LOCK_CMP2_MODE00x050
-#define QSERDES_COM_LOCK_CMP3_MODE00x054
-#define QSERDES_COM_LOCK_CMP1_MODE10x058
-#define QSERDES_COM_LOCK_CMP2_MODE10x05c
-#define QSERDES_COM_LOCK_CMP3_MODE10x060
-#define QSERDES_COM_BG_TRIM0x070
-#define QSERDES_COM_CLK_EP_DIV 0x074
-#define QSERDES_COM_CP_CTRL_MODE0  0x078
-#define QSERDES_COM_CP_CTRL_MODE1  0x07c
-#define QSERDES_COM_PLL_RCTRL_MODE00x084
-#define QSERDES_COM_PLL_RCTRL_MODE10x088
-#define QSERDES_COM_PLL_CCTRL_MODE00x090
-#define QSERDES_COM_PLL_CCTRL_MODE10x094
-#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM0x0a8
-#define QSERDES_COM_SYSCLK_EN_SEL  0x0ac
-#define QSERDES_COM_RESETSM_CNTRL  0x0b4
-#define QSERDES_COM_RESTRIM_CTRL   0x0bc
-#define QSERDES_COM_RESCODE_DIV_NUM0x0c4
-#define QSERDES_COM_LOCK_CMP_EN0x0c8
-#define QSERDES_COM_LOCK_CMP_CFG   0x0cc
-#define QSERDES_COM_DEC_START_MODE00x0d0
-#define QSERDES_COM_DEC_START_MODE10x0d4
-#define QSERDES_COM_DIV_FRAC_START1_MODE0  0x0dc
-#define QSERDES_COM_DIV_FRAC_START2_MODE0  0x0e0
-#define QSERDES_COM_DIV_FRAC_START3_MODE0  0x0e4
-#define QSERDES_COM_DIV_FRAC_START1_MODE1  0x0e8
-#define QSERDES_COM_DIV_FRAC_START2_MODE1  0x0ec
-#define QSERDES_COM_DIV_FRAC_START3_MODE1  0x0f0
-#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0  0x108
-#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0  0x10c
-#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1  0x110
-#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1  0x114
-#define QSERDES_COM_VCO_TUNE_CTRL  0x124
-#define QSERDES_COM_VCO_TUNE_MAP   0x128
-#define QSERDES_COM_VCO_TUNE1_MODE00x12c
-#define QSERDES_COM_VCO_TUNE2_MODE00x130
-#define QSERDES_COM_VCO_TUNE1_MODE10x134
-#define QSERDES_COM_VCO_TUNE2_MODE10x138
-#define QSERDES_COM_VCO_TUNE_TIMER10x144
-#define QSERDES_COM_VCO_TUNE_TIMER20x148
-#define QSERDES_COM_BG_CTRL0x170
-#define QSERDES_COM_CLK_SELECT 0x174
-#define QSERDES_COM_HSCLK_SEL  0x178
-#define QSERDES_COM_CORECLK_DIV0x184
-#define QSERDES_COM_CORE_CLK_EN0x18c
-#define QSERDES_COM_C_READY_STATUS 0x190
-#define QSERDES_COM_CMN_CONFIG 0x194
-#define QSERDES_COM_SVS_MODE_CLK_SEL   0x19c
-#define QSERDES_COM_DEBUG_BUS0 0x1a0
-#define QSERDES_COM_DEBUG_BUS1 0x1a4
-#define QSERDES_COM_DEBUG_BUS2 0x1a8
-#define QSERDES_COM_DEBUG_BUS3 0x1ac
-#define QSERDES_COM_DEBUG_BUS_SEL  0x1b0
-#define QSERDES_COM_CORECLK_DIV_MODE1   

[PATCH v2 11/17] phy: qcom-qmp: Add register offsets for QMP V3 PHY

2017-09-27 Thread Manu Gautam
Registers offsets for QMP V3 PHY are changed from
previous versions (1/2), update same in header file.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.h | 149 
 1 file changed, 149 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h 
b/drivers/phy/qualcomm/phy-qcom-qmp.h
index d930ca7..f7d4c2a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -134,4 +134,153 @@
 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB   0x1DC
 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB   0x1E0
 
+/* Only for QMP V3 PHY - DP COM registers */
+#define QPHY_V3_DP_COM_PHY_MODE_CTRL   0x00
+#define QPHY_V3_DP_COM_SW_RESET0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL  0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c
+
+/* Only for QMP V3 PHY - QSERDES COM registers */
+#define QSERDES_V3_COM_BG_TIMER0x00c
+#define QSERDES_V3_COM_SSC_EN_CENTER   0x010
+#define QSERDES_V3_COM_SSC_ADJ_PER10x014
+#define QSERDES_V3_COM_SSC_ADJ_PER20x018
+#define QSERDES_V3_COM_SSC_PER10x01c
+#define QSERDES_V3_COM_SSC_PER20x020
+#define QSERDES_V3_COM_SSC_STEP_SIZE1  0x024
+#define QSERDES_V3_COM_SSC_STEP_SIZE2  0x028
+#define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN 0x034
+#define QSERDES_V3_COM_CLK_ENABLE1 0x038
+#define QSERDES_V3_COM_SYS_CLK_CTRL0x03c
+#define QSERDES_V3_COM_SYSCLK_BUF_ENABLE   0x040
+#define QSERDES_V3_COM_PLL_IVCO0x048
+#define QSERDES_V3_COM_LOCK_CMP1_MODE0 0x098
+#define QSERDES_V3_COM_LOCK_CMP2_MODE0 0x09c
+#define QSERDES_V3_COM_LOCK_CMP3_MODE0 0x0a0
+#define QSERDES_V3_COM_LOCK_CMP1_MODE1 0x0a4
+#define QSERDES_V3_COM_LOCK_CMP2_MODE1 0x0a8
+#define QSERDES_V3_COM_LOCK_CMP3_MODE1 0x0ac
+#define QSERDES_V3_COM_CLK_EP_DIV  0x05c
+#define QSERDES_V3_COM_CP_CTRL_MODE0   0x060
+#define QSERDES_V3_COM_CP_CTRL_MODE1   0x064
+#define QSERDES_V3_COM_PLL_RCTRL_MODE0 0x068
+#define QSERDES_V3_COM_PLL_RCTRL_MODE1 0x06c
+#define QSERDES_V3_COM_PLL_CCTRL_MODE0 0x070
+#define QSERDES_V3_COM_PLL_CCTRL_MODE1 0x074
+#define QSERDES_V3_COM_SYSCLK_EN_SEL   0x080
+#define QSERDES_V3_COM_RESETSM_CNTRL   0x088
+#define QSERDES_V3_COM_RESETSM_CNTRL2  0x08c
+#define QSERDES_V3_COM_LOCK_CMP_EN 0x090
+#define QSERDES_V3_COM_LOCK_CMP_CFG0x094
+#define QSERDES_V3_COM_DEC_START_MODE0 0x0b0
+#define QSERDES_V3_COM_DEC_START_MODE1 0x0b4
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE0   0x0b8
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE0   0x0bc
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE0   0x0c0
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE1   0x0c4
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE1   0x0c8
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE1   0x0cc
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0   0x0d8
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0   0x0dc
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1   0x0e0
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1   0x0e4
+#define QSERDES_V3_COM_VCO_TUNE_CTRL   0x0ec
+#define QSERDES_V3_COM_VCO_TUNE_MAP0x0f0
+#define QSERDES_V3_COM_VCO_TUNE1_MODE0 0x0f4
+#define QSERDES_V3_COM_VCO_TUNE2_MODE0 0x0f8
+#define QSERDES_V3_COM_VCO_TUNE1_MODE1 0x0fc
+#define QSERDES_V3_COM_VCO_TUNE2_MODE1 0x100
+#define QSERDES_V3_COM_VCO_TUNE_TIMER1 0x11c
+#define QSERDES_V3_COM_VCO_TUNE_TIMER2 0x120
+#define QSERDES_V3_COM_CLK_SELECT  0x138
+#define QSERDES_V3_COM_HSCLK_SEL   0x13c
+#define QSERDES_V3_COM_CORECLK_DIV_MODE0   0x148
+#define QSERDES_V3_COM_CORECLK_DIV_MODE1   0x14c
+#define QSERDES_V3_COM_CORE_CLK_EN 0x154
+#define QSERDES_V3_COM_C_READY_STATUS  0x158
+#define QSERDES_V3_COM_CMN_CONFIG  0x15c
+#define QSERDES_V3_COM_SVS_MODE_CLK_SEL0x164
+#define QSERDES_V3_COM_DEBUG_BUS0  0x168
+#define QSERDES_V3_COM_DEBUG_BUS1  0x16c
+#define QSERDES_V3_COM_D

[PATCH v2 07/17] phy: qcom-qusb2: Add support for different register layouts

2017-09-27 Thread Manu Gautam
New version of QUSB2 PHY has some registers offset changed.
Add support to have register layout for a target and update
the same in phy_configuration.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 131 --
 1 file changed, 95 insertions(+), 36 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 4a5b2a1..c0c5358 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -37,17 +37,10 @@
 #define QUSB2PHY_PLL_AUTOPGM_CTL1  0x1c
 #define QUSB2PHY_PLL_PWR_CTRL  0x18
 
-#define QUSB2PHY_PLL_STATUS0x38
+/* QUSB2PHY_PLL_STATUS register bits */
 #define PLL_LOCKED BIT(5)
 
-#define QUSB2PHY_PORT_TUNE10x80
-#define QUSB2PHY_PORT_TUNE20x84
-#define QUSB2PHY_PORT_TUNE30x88
-#define QUSB2PHY_PORT_TUNE40x8c
-#define QUSB2PHY_PORT_TUNE50x90
-#define QUSB2PHY_PORT_TEST20x9c
-
-#define QUSB2PHY_PORT_POWERDOWN0xb4
+/* QUSB2PHY_PORT_POWERDOWN register bits */
 #define CLAMP_N_EN BIT(5)
 #define FREEZIO_N  BIT(1)
 #define POWER_DOWN BIT(0)
@@ -59,6 +52,11 @@
 struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
+   /*
+* register part of layout ?
+* if yes, then offset gives index in the reg-layout
+*/
+   int in_layout;
 };
 
 #define QUSB2_PHY_INIT_CFG(o, v) \
@@ -67,15 +65,50 @@ struct qusb2_phy_init_tbl {
.val = v,   \
}
 
+#define QUSB2_PHY_INIT_CFG_L(o, v) \
+   {   \
+   .offset = o,\
+   .val = v,   \
+   .in_layout = 1, \
+   }
+
+/* set of registers with offsets different per-PHY */
+enum qusb2phy_reg_layout {
+   QUSB2PHY_PLL_STATUS,
+   QUSB2PHY_PORT_TUNE1,
+   QUSB2PHY_PORT_TUNE2,
+   QUSB2PHY_PORT_TUNE3,
+   QUSB2PHY_PORT_TUNE4,
+   QUSB2PHY_PORT_TUNE5,
+   QUSB2PHY_PORT_TEST1,
+   QUSB2PHY_PORT_TEST2,
+   QUSB2PHY_PORT_POWERDOWN,
+   QUSB2PHY_INTR_CTRL,
+};
+
+static const unsigned int msm8996_regs_layout[] = {
+   [QUSB2PHY_PLL_STATUS]   = 0x38,
+   [QUSB2PHY_PORT_TUNE1]   = 0x80,
+   [QUSB2PHY_PORT_TUNE2]   = 0x84,
+   [QUSB2PHY_PORT_TUNE3]   = 0x88,
+   [QUSB2PHY_PORT_TUNE4]   = 0x8c,
+   [QUSB2PHY_PORT_TUNE5]   = 0x90,
+   [QUSB2PHY_PORT_TEST2]   = 0x9c,
+   [QUSB2PHY_PORT_POWERDOWN]   = 0xb4,
+};
+
 static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
-   QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE1, 0xf8),
-   QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE2, 0xb3),
-   QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE3, 0x83),
-   QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TUNE4, 0xc0),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0),
+
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
-   QUSB2_PHY_INIT_CFG(QUSB2PHY_PORT_TEST2, 0x14),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
+
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
 };
@@ -86,11 +119,24 @@ struct qusb2_phy_cfg {
unsigned int tbl_num;
/* offset to PHY_CLK_SCHEME register in TCSR map */
unsigned int clk_scheme_offset;
+
+   /* array of registers with different offsets */
+   const unsigned int *regs;
+   unsigned int mask_core_ready;
+   unsigned int disable_ctrl;
+
+   /* true if PHY has PLL_TEST register to select clk_scheme */
+   bool has_pll_test;
 };
 
 static const struct qusb2_phy_cfg msm8996_phy_cfg = {
-   .tbl = msm8996_init_tbl,
-   .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+   .tbl= msm8996_init_tbl,
+   .tbl_num= ARRAY_SIZE(msm8996_init_tbl),
+   .regs   = msm8996_regs_layout,
+
+   .has_pll_test   = true,
+   .disable_ctrl   = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
+   .mask_core_ready = PLL_LOCKED,
 };
 
 static const char * const qusb2_phy_vreg_names[] = {
@@ -160,12 +206,17 @@ static inline void qusb2_clrbits(void __iomem *base, u32 
offset, u32 val)
 
 static inline
 void qcom_qusb2_phy_configure(void __iomem *base,
+ const unsigned int *regs,
  const struct qusb2_phy_init_tbl tbl[], int num)
 {
int i;
 
-   for (i = 0; i < num; i++)
-   writel(tbl[i].val, base + tbl[i].offset);
+   for (i = 0; i < num; i++) {
+   if (tbl[i].in

[PATCH v2 09/17] phy: qcom-qusb2: Add support for QUSB2 V2 version

2017-09-27 Thread Manu Gautam
Use register layout to add additional registers present
on QUSB2 PHY V2 version for PHY initialization.
Other than new registers on V2, following two register's
offset and bit definitions are different: POWERDOWN control
and PLL_STATUS.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 64 +++
 1 file changed, 64 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index c0c5358..bda1f4c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -40,15 +40,34 @@
 /* QUSB2PHY_PLL_STATUS register bits */
 #define PLL_LOCKED BIT(5)
 
+/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
+#define CORE_READY_STATUS  BIT(0)
+
 /* QUSB2PHY_PORT_POWERDOWN register bits */
 #define CLAMP_N_EN BIT(5)
 #define FREEZIO_N  BIT(1)
 #define POWER_DOWN BIT(0)
 
+/* QUSB2PHY_PWR_CTRL1 register bits */
+#define PWR_CTRL1_VREF_SUPPLY_TRIM BIT(5)
+#define PWR_CTRL1_CLAMP_N_EN   BIT(1)
+
 #define QUSB2PHY_REFCLK_ENABLE BIT(0)
 
 #define PHY_CLK_SCHEME_SEL BIT(0)
 
+#defineQUSB2PHY_PLL_ANALOG_CONTROLS_TWO0x04
+#defineQUSB2PHY_PLL_CLOCK_INVERTERS0x18c
+#defineQUSB2PHY_PLL_CMODE  0x2c
+#defineQUSB2PHY_PLL_LOCK_DELAY 0x184
+#defineQUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
+#defineQUSB2PHY_PLL_BIAS_CONTROL_1 0x194
+#defineQUSB2PHY_PLL_BIAS_CONTROL_2 0x198
+#defineQUSB2PHY_PWR_CTRL2  0x214
+#defineQUSB2PHY_IMP_CTRL1  0x220
+#defineQUSB2PHY_IMP_CTRL2  0x224
+#defineQUSB2PHY_CHG_CTRL2  0x23c
+
 struct qusb2_phy_init_tbl {
unsigned int offset;
unsigned int val;
@@ -113,6 +132,38 @@ enum qusb2phy_reg_layout {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
 };
 
+static const unsigned int qusb2_v2_regs_layout[] = {
+   [QUSB2PHY_PLL_STATUS]   = 0x1a0,
+   [QUSB2PHY_PORT_TUNE1]   = 0x240,
+   [QUSB2PHY_PORT_TUNE2]   = 0x244,
+   [QUSB2PHY_PORT_TUNE3]   = 0x248,
+   [QUSB2PHY_PORT_TUNE4]   = 0x24c,
+   [QUSB2PHY_PORT_TUNE5]   = 0x250,
+   [QUSB2PHY_PORT_TEST2]   = 0x258,
+   [QUSB2PHY_PORT_POWERDOWN]   = 0x210,
+};
+
+static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+   QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+   QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
 struct qusb2_phy_cfg {
const struct qusb2_phy_init_tbl *tbl;
/* number of entries in the table */
@@ -139,6 +190,16 @@ struct qusb2_phy_cfg {
.mask_core_ready = PLL_LOCKED,
 };
 
+static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
+   .tbl= qusb2_v2_init_tbl,
+   .tbl_num= ARRAY_SIZE(qusb2_v2_init_tbl),
+   .regs   = qusb2_v2_regs_layout,
+
+   .disable_ctrl   = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+  POWER_DOWN),
+   .mask_core_ready = CORE_READY_STATUS,
+};
+
 static const char * const qusb2_phy_vreg_names[] = {
"vdda-pll", "vdda-phy-dpdm",
 };
@@ -419,6 +480,9 @@ static int qusb2_phy_exit(struct phy *phy)
{
.compatible = "qcom,msm8996-qusb2-phy",
.data   = &msm8996_phy_cfg,
+   }, {
+   .compatible = "qcom,qusb2-v2-phy",
+   .data   = &qusb2_v2_phy_cfg,
},
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 05/17] phy: qcom-qmp: Fix PHY block reset sequence

2017-09-27 Thread Manu Gautam
PHY block or asynchronous reset requires signal
to be asserted before de-asserting. Driver is only
de-asserting signal which is already low, hence
reset operation is a no-op. Fix this by asserting
signal first. Also, resetting requires PHY clocks
to be turned ON only after reset is finished. Fix
that as well.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2f427e3..aa27757 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -739,13 +739,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
return ret;
}
 
-   ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
-   if (ret) {
-   dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
-   goto err_clk_enable;
+   for (i = 0; i < cfg->num_resets; i++) {
+   ret = reset_control_assert(qmp->resets[i]);
+   if (ret) {
+   dev_err(qmp->dev, "%s reset assert failed\n",
+   cfg->reset_list[i]);
+   goto err_rst_assert;
+   }
}
 
-   for (i = 0; i < cfg->num_resets; i++) {
+   for (i = cfg->num_resets - 1; i >= 0; i--) {
ret = reset_control_deassert(qmp->resets[i]);
if (ret) {
dev_err(qmp->dev, "%s reset deassert failed\n",
@@ -754,6 +757,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
}
}
 
+   ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+   if (ret) {
+   dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+   goto err_rst;
+   }
+
if (cfg->has_phy_com_ctrl)
qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
 SW_PWRDN);
@@ -778,7 +787,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
if (ret) {
dev_err(qmp->dev,
"phy common block init timed-out\n");
-   goto err_rst;
+   goto err_com_init;
}
}
 
@@ -786,11 +795,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 
return 0;
 
+err_com_init:
+   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 err_rst:
-   while (--i >= 0)
+   while (++i < cfg->num_resets)
reset_control_assert(qmp->resets[i]);
-   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
-err_clk_enable:
+err_rst_assert:
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
mutex_unlock(&qmp->phy_mutex);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 06/17] phy: qcom-qmp: Move SERDES/PCS START after PHY reset

2017-09-27 Thread Manu Gautam
Driver is currently performing PHY reset after starting
SERDES/PCS. As per hardware datasheet reset must be done
before starting PHY. Hence, update the sequence.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index aa27757..263cf50 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -882,12 +882,12 @@ static int qcom_qmp_phy_init(struct phy *phy)
if (cfg->has_pwrdn_delay)
usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
 
-   /* start SerDes and Phy-Coding-Sublayer */
-   qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
-
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 
+   /* start SerDes and Phy-Coding-Sublayer */
+   qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
+
status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
mask = cfg->mask_pcs_ready;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 08/17] dt-bindings: phy-qcom-qusb2: Update binding for QUSB2 V2 version

2017-09-27 Thread Manu Gautam
Update generic compatible string for QUSB2 V2 PHY. This will allow
all targets using QUSB2 V2 use same string.

Signed-off-by: Manu Gautam 
---
 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt 
b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
index aa0fcb0..42c9742 100644
--- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt
@@ -4,7 +4,10 @@ Qualcomm QUSB2 phy controller
 QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
 
 Required properties:
- - compatible: compatible list, contains "qcom,msm8996-qusb2-phy".
+ - compatible: compatible list, contains
+  "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996,
+  "qcom,qusb2-v2-phy" for QUSB2 V2 PHY.
+
  - reg: offset and length of the PHY register set.
  - #phy-cells: must be 0.
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 04/17] phy: qcom-qusb2: Power-on PHY before initialization

2017-09-27 Thread Manu Gautam
PHY must be powered on before turning ON clocks and
attempting to initialize it. Driver is exposing
separate init and power_on routines for this.
Apparently USB dwc3 core driver performs power-on
after init. Also, poweron and init for QUSB2 PHY
need to be executed together always, hence remove
poweron callback from phy_ops and explicitly perform
this from init, similar changes needed for poweroff.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qusb2.c | 47 +++
 1 file changed, 15 insertions(+), 32 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 6c57524..4a5b2a1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -195,54 +195,31 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
qusb2_setbits(qphy->base, QUSB2PHY_PORT_TUNE2, val[0] << 0x4);
 }
 
-static int qusb2_phy_poweron(struct phy *phy)
+static int qusb2_phy_init(struct phy *phy)
 {
struct qusb2_phy *qphy = phy_get_drvdata(phy);
-   int num = ARRAY_SIZE(qphy->vregs);
+   unsigned int val;
+   unsigned int clk_scheme;
int ret;
 
-   dev_vdbg(&phy->dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+   dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
 
/* turn on regulator supplies */
-   ret = regulator_bulk_enable(num, qphy->vregs);
+   ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
if (ret)
return ret;
 
ret = clk_prepare_enable(qphy->iface_clk);
if (ret) {
dev_err(&phy->dev, "failed to enable iface_clk, %d\n", ret);
-   regulator_bulk_disable(num, qphy->vregs);
-   return ret;
+   goto poweroff_phy;
}
 
-   return 0;
-}
-
-static int qusb2_phy_poweroff(struct phy *phy)
-{
-   struct qusb2_phy *qphy = phy_get_drvdata(phy);
-
-   clk_disable_unprepare(qphy->iface_clk);
-
-   regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
-
-   return 0;
-}
-
-static int qusb2_phy_init(struct phy *phy)
-{
-   struct qusb2_phy *qphy = phy_get_drvdata(phy);
-   unsigned int val;
-   unsigned int clk_scheme;
-   int ret;
-
-   dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
-
/* enable ahb interface clock to program phy */
ret = clk_prepare_enable(qphy->cfg_ahb_clk);
if (ret) {
dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
-   return ret;
+   goto disable_iface_clk;
}
 
/* Perform phy reset */
@@ -344,6 +321,11 @@ static int qusb2_phy_init(struct phy *phy)
reset_control_assert(qphy->phy_reset);
 disable_ahb_clk:
clk_disable_unprepare(qphy->cfg_ahb_clk);
+disable_iface_clk:
+   clk_disable_unprepare(qphy->iface_clk);
+poweroff_phy:
+   regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
+
return ret;
 }
 
@@ -361,6 +343,9 @@ static int qusb2_phy_exit(struct phy *phy)
reset_control_assert(qphy->phy_reset);
 
clk_disable_unprepare(qphy->cfg_ahb_clk);
+   clk_disable_unprepare(qphy->iface_clk);
+
+   regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
 
return 0;
 }
@@ -368,8 +353,6 @@ static int qusb2_phy_exit(struct phy *phy)
 static const struct phy_ops qusb2_phy_gen_ops = {
.init   = qusb2_phy_init,
.exit   = qusb2_phy_exit,
-   .power_on   = qusb2_phy_poweron,
-   .power_off  = qusb2_phy_poweroff,
.owner  = THIS_MODULE,
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 02/17] phy: qcom-qmp: Adapt to clk_bulk_* APIs

2017-09-27 Thread Manu Gautam
From: Vivek Gautam 

Move from using array of clocks to clk_bulk_* APIs that
are available now.

Signed-off-by: Vivek Gautam 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 50 -
 1 file changed, 16 insertions(+), 34 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 76acaec..90794dd 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -555,7 +555,7 @@ struct qcom_qmp {
struct device *dev;
void __iomem *serdes;
 
-   struct clk **clks;
+   struct clk_bulk_data *clks;
struct reset_control **resets;
struct regulator_bulk_data *vregs;
 
@@ -848,22 +848,19 @@ static int qcom_qmp_phy_init(struct phy *phy)
void __iomem *pcs = qphy->pcs;
void __iomem *status;
unsigned int mask, val;
-   int ret, i;
+   int ret;
 
dev_vdbg(qmp->dev, "Initializing QMP phy\n");
 
-   for (i = 0; i < qmp->cfg->num_clks; i++) {
-   ret = clk_prepare_enable(qmp->clks[i]);
-   if (ret) {
-   dev_err(qmp->dev, "failed to enable %s clk, err=%d\n",
-   qmp->cfg->clk_list[i], ret);
-   goto err_clk;
-   }
+   ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+   if (ret) {
+   dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+   return ret;
}
 
ret = qcom_qmp_phy_com_init(qmp);
if (ret)
-   goto err_clk;
+   goto err_com_init;
 
if (cfg->has_lane_rst) {
ret = reset_control_deassert(qphy->lane_rst);
@@ -918,9 +915,8 @@ static int qcom_qmp_phy_init(struct phy *phy)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
qcom_qmp_phy_com_exit(qmp);
-err_clk:
-   while (--i >= 0)
-   clk_disable_unprepare(qmp->clks[i]);
+err_com_init:
+   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 
return ret;
 }
@@ -930,7 +926,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
const struct qmp_phy_cfg *cfg = qmp->cfg;
-   int i = cfg->num_clks;
 
clk_disable_unprepare(qphy->pipe_clk);
 
@@ -948,8 +943,7 @@ static int qcom_qmp_phy_exit(struct phy *phy)
 
qcom_qmp_phy_com_exit(qmp);
 
-   while (--i >= 0)
-   clk_disable_unprepare(qmp->clks[i]);
+   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 
return 0;
 }
@@ -998,29 +992,17 @@ static int qcom_qmp_phy_reset_init(struct device *dev)
 static int qcom_qmp_phy_clk_init(struct device *dev)
 {
struct qcom_qmp *qmp = dev_get_drvdata(dev);
-   int ret, i;
+   int num = qmp->cfg->num_clks;
+   int i;
 
-   qmp->clks = devm_kcalloc(dev, qmp->cfg->num_clks,
-sizeof(*qmp->clks), GFP_KERNEL);
+   qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
if (!qmp->clks)
return -ENOMEM;
 
-   for (i = 0; i < qmp->cfg->num_clks; i++) {
-   struct clk *_clk;
-   const char *name = qmp->cfg->clk_list[i];
-
-   _clk = devm_clk_get(dev, name);
-   if (IS_ERR(_clk)) {
-   ret = PTR_ERR(_clk);
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "failed to get %s clk, %d\n",
-   name, ret);
-   return ret;
-   }
-   qmp->clks[i] = _clk;
-   }
+   for (i = 0; i < num; i++)
+   qmp->clks->id = qmp->cfg->clk_list[i];
 
-   return 0;
+   return devm_clk_bulk_get(dev, num, qmp->clks);
 }
 
 /*
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 01/17] phy: qcom-qmp: Fix phy pipe clock gating

2017-09-27 Thread Manu Gautam
From: Vivek Gautam 

Pipe clock comes out of the phy and is available as long as
the phy is turned on. Clock controller fails to gate this
clock after the phy is turned off and generates a warning.

/ # [   33.048561] gcc_usb3_phy_pipe_clk status stuck at 'on'
[   33.048585] [ cut here ]
[   33.052621] WARNING: CPU: 1 PID: 18 at ../drivers/clk/qcom/clk-branch.c:97 
clk_branch_wait+0xf0/0x108
[   33.057384] Modules linked in:
[   33.066497] CPU: 1 PID: 18 Comm: kworker/1:0 Tainted: GW   
4.12.0-rc7-00024-gfe926e34c36d-dirty #96
[   33.069451] Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
...
[   33.278565] [] clk_branch_wait+0xf0/0x108
[   33.286375] [] clk_branch2_disable+0x28/0x34
[   33.291761] [] clk_core_disable+0x5c/0x88
[   33.297660] [] clk_core_disable_lock+0x20/0x34
[   33.303129] [] clk_disable+0x1c/0x24
[   33.309384] [] qcom_qmp_phy_poweroff+0x20/0x48
[   33.314328] [] phy_power_off+0x80/0xdc
[   33.320492] [] dwc3_core_exit+0x94/0xa0
[   33.325784] [] dwc3_suspend_common+0x50/0x60
[   33.331080] [] dwc3_runtime_suspend+0x48/0x6c
[   33.336810] [] pm_generic_runtime_suspend+0x28/0x38
[   33.342627] [] __rpm_callback+0x150/0x254
[   33.349222] [] rpm_callback+0x24/0x78
[   33.354604] [] rpm_suspend+0xe0/0x4e4
[   33.359813] [] pm_runtime_work+0xdc/0xf0
[   33.365028] [] process_one_work+0x12c/0x28c
[   33.370576] [] worker_thread+0x58/0x3b8
[   33.376393] [] kthread+0x100/0x12c
[   33.381776] [] ret_from_fork+0x10/0x50

Fix this by enabling pipe clock at the end of phy_init(), and disabling
it as the first thing in phy_exit().

Fixes: e78f3d15e115 ("phy: qcom-qmp: new qmp phy driver for qcom-chipsets")
Signed-off-by: Vivek Gautam 
Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index e17f035..76acaec 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -731,19 +731,10 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
 
/* turn on regulator supplies */
ret = regulator_bulk_enable(num, qmp->vregs);
-   if (ret) {
+   if (ret)
dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
-   return ret;
-   }
-
-   ret = clk_prepare_enable(qphy->pipe_clk);
-   if (ret) {
-   dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
-   regulator_bulk_disable(num, qmp->vregs);
-   return ret;
-   }
 
-   return 0;
+   return ret;
 }
 
 static int qcom_qmp_phy_poweroff(struct phy *phy)
@@ -751,8 +742,6 @@ static int qcom_qmp_phy_poweroff(struct phy *phy)
struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp;
 
-   clk_disable_unprepare(qphy->pipe_clk);
-
regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
 
return 0;
@@ -915,7 +904,14 @@ static int qcom_qmp_phy_init(struct phy *phy)
goto err_pcs_ready;
}
 
-   return ret;
+   /* phy is initialized; we can turn on the pipe clock now */
+   ret = clk_prepare_enable(qphy->pipe_clk);
+   if (ret) {
+   dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
+   goto err_pcs_ready;
+   }
+
+   return 0;
 
 err_pcs_ready:
if (cfg->has_lane_rst)
@@ -936,6 +932,8 @@ static int qcom_qmp_phy_exit(struct phy *phy)
const struct qmp_phy_cfg *cfg = qmp->cfg;
int i = cfg->num_clks;
 
+   clk_disable_unprepare(qphy->pipe_clk);
+
/* PHY reset */
qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 03/17] phy: qcom-qmp: Power-on PHY before initialization

2017-09-27 Thread Manu Gautam
PHY must be powered on before turning ON clocks and
attempting to initialize it. Driver is exposing
separate init and power_on routines for this.
Apparently USB dwc3 core driver performs power-on after
init. Also, poweron and init for QMP PHY need to be
executed together always, hence remove poweron callback
from phy_ops and explicitly perform this from com_init,
similar changes needed for poweroff. On similar lines move
clk_enable from init to com_init which can be called once
for multi lane PHYs.

Signed-off-by: Manu Gautam 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 61 +
 1 file changed, 21 insertions(+), 40 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 90794dd..2f427e3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -720,33 +720,6 @@ static void qcom_qmp_phy_configure(void __iomem *base,
}
 }
 
-static int qcom_qmp_phy_poweron(struct phy *phy)
-{
-   struct qmp_phy *qphy = phy_get_drvdata(phy);
-   struct qcom_qmp *qmp = qphy->qmp;
-   int num = qmp->cfg->num_vregs;
-   int ret;
-
-   dev_vdbg(&phy->dev, "Powering on QMP phy\n");
-
-   /* turn on regulator supplies */
-   ret = regulator_bulk_enable(num, qmp->vregs);
-   if (ret)
-   dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
-
-   return ret;
-}
-
-static int qcom_qmp_phy_poweroff(struct phy *phy)
-{
-   struct qmp_phy *qphy = phy_get_drvdata(phy);
-   struct qcom_qmp *qmp = qphy->qmp;
-
-   regulator_bulk_disable(qmp->cfg->num_vregs, qmp->vregs);
-
-   return 0;
-}
-
 static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 {
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -759,6 +732,19 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
return 0;
}
 
+   /* turn on regulator supplies */
+   ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
+   if (ret) {
+   mutex_unlock(&qmp->phy_mutex);
+   return ret;
+   }
+
+   ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+   if (ret) {
+   dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+   goto err_clk_enable;
+   }
+
for (i = 0; i < cfg->num_resets; i++) {
ret = reset_control_deassert(qmp->resets[i]);
if (ret) {
@@ -803,6 +789,9 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 err_rst:
while (--i >= 0)
reset_control_assert(qmp->resets[i]);
+   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+err_clk_enable:
+   regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
mutex_unlock(&qmp->phy_mutex);
 
return ret;
@@ -832,6 +821,10 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp)
while (--i >= 0)
reset_control_assert(qmp->resets[i]);
 
+   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
+
+   regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
+
mutex_unlock(&qmp->phy_mutex);
 
return 0;
@@ -852,15 +845,9 @@ static int qcom_qmp_phy_init(struct phy *phy)
 
dev_vdbg(qmp->dev, "Initializing QMP phy\n");
 
-   ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
-   if (ret) {
-   dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
-   return ret;
-   }
-
ret = qcom_qmp_phy_com_init(qmp);
if (ret)
-   goto err_com_init;
+   return ret;
 
if (cfg->has_lane_rst) {
ret = reset_control_deassert(qphy->lane_rst);
@@ -915,8 +902,6 @@ static int qcom_qmp_phy_init(struct phy *phy)
reset_control_assert(qphy->lane_rst);
 err_lane_rst:
qcom_qmp_phy_com_exit(qmp);
-err_com_init:
-   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 
return ret;
 }
@@ -943,8 +928,6 @@ static int qcom_qmp_phy_exit(struct phy *phy)
 
qcom_qmp_phy_com_exit(qmp);
 
-   clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
-
return 0;
 }
 
@@ -1057,8 +1040,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
 static const struct phy_ops qcom_qmp_phy_gen_ops = {
.init   = qcom_qmp_phy_init,
.exit   = qcom_qmp_phy_exit,
-   .power_on   = qcom_qmp_phy_poweron,
-   .power_off  = qcom_qmp_phy_poweroff,
.owner  = THIS_MODULE,
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/9] usb: xhci-mtk: check clock stability of U3_MAC

2017-09-27 Thread Chunfeng Yun
This is useful to find out the root cause when the Super Speed doesn't
work. Such as when the T-PHY is switched to PCIe or SATA, and affects
Super Speed function, the check will fail.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 9502ca4..7a92bb7 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -43,6 +43,7 @@
 
 /* ip_pw_sts1 register */
 #define STS1_IP_SLEEP_STS  BIT(30)
+#define STS1_U3_MAC_RSTBIT(16)
 #define STS1_XHCI_RST  BIT(11)
 #define STS1_SYS125_RSTBIT(10)
 #define STS1_REF_RST   BIT(8)
@@ -125,6 +126,9 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
STS1_SYS125_RST | STS1_XHCI_RST;
 
+   if (mtk->num_u3_ports)
+   check_val |= STS1_U3_MAC_RST;
+
ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
  (check_val == (value & check_val)), 100, 2);
if (ret) {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/9] usb: xhci-mtk: add optional mcu and dma bus clocks

2017-09-27 Thread Chunfeng Yun
There are mcu_bus and dma_bus clocks needed to be controlled by
driver on some SoCs, so add them as optional ones

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c |   79 ---
 drivers/usb/host/xhci-mtk.h |2 ++
 2 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index d60463c..e5caabe 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -221,6 +221,44 @@ static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk)
return xhci_mtk_host_enable(mtk);
 }
 
+/* ignore the error if the clock does not exist */
+static struct clk *optional_clk_get(struct device *dev, const char *id)
+{
+   struct clk *opt_clk;
+
+   opt_clk = devm_clk_get(dev, id);
+   /* ignore error number except EPROBE_DEFER */
+   if (IS_ERR(opt_clk) && (PTR_ERR(opt_clk) != -EPROBE_DEFER))
+   opt_clk = NULL;
+
+   return opt_clk;
+}
+
+static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk)
+{
+   struct device *dev = mtk->dev;
+
+   mtk->sys_clk = devm_clk_get(dev, "sys_ck");
+   if (IS_ERR(mtk->sys_clk)) {
+   dev_err(dev, "fail to get sys_ck\n");
+   return PTR_ERR(mtk->sys_clk);
+   }
+
+   mtk->ref_clk = optional_clk_get(dev, "ref_ck");
+   if (IS_ERR(mtk->ref_clk))
+   return PTR_ERR(mtk->ref_clk);
+
+   mtk->mcu_clk = optional_clk_get(dev, "mcu_ck");
+   if (IS_ERR(mtk->mcu_clk))
+   return PTR_ERR(mtk->mcu_clk);
+
+   mtk->dma_clk = optional_clk_get(dev, "dma_ck");
+   if (IS_ERR(mtk->dma_clk))
+   return PTR_ERR(mtk->dma_clk);
+
+   return 0;
+}
+
 static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
 {
int ret;
@@ -237,16 +275,34 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
goto sys_clk_err;
}
 
+   ret = clk_prepare_enable(mtk->mcu_clk);
+   if (ret) {
+   dev_err(mtk->dev, "failed to enable mcu_clk\n");
+   goto mcu_clk_err;
+   }
+
+   ret = clk_prepare_enable(mtk->dma_clk);
+   if (ret) {
+   dev_err(mtk->dev, "failed to enable dma_clk\n");
+   goto dma_clk_err;
+   }
+
return 0;
 
+dma_clk_err:
+   clk_disable_unprepare(mtk->mcu_clk);
+mcu_clk_err:
+   clk_disable_unprepare(mtk->sys_clk);
 sys_clk_err:
clk_disable_unprepare(mtk->ref_clk);
 ref_clk_err:
-   return -EINVAL;
+   return ret;
 }
 
 static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
 {
+   clk_disable_unprepare(mtk->dma_clk);
+   clk_disable_unprepare(mtk->mcu_clk);
clk_disable_unprepare(mtk->sys_clk);
clk_disable_unprepare(mtk->ref_clk);
 }
@@ -529,24 +585,9 @@ static int xhci_mtk_probe(struct platform_device *pdev)
return PTR_ERR(mtk->vusb33);
}
 
-   mtk->sys_clk = devm_clk_get(dev, "sys_ck");
-   if (IS_ERR(mtk->sys_clk)) {
-   dev_err(dev, "fail to get sys_ck\n");
-   return PTR_ERR(mtk->sys_clk);
-   }
-
-   /*
-* reference clock is usually a "fixed-clock", make it optional
-* for backward compatibility and ignore the error if it does
-* not exist.
-*/
-   mtk->ref_clk = devm_clk_get(dev, "ref_ck");
-   if (IS_ERR(mtk->ref_clk)) {
-   if (PTR_ERR(mtk->ref_clk) == -EPROBE_DEFER)
-   return -EPROBE_DEFER;
-
-   mtk->ref_clk = NULL;
-   }
+   ret = xhci_mtk_clks_get(mtk);
+   if (ret)
+   return ret;
 
mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
/* optional property, ignore the error if it does not exist */
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 67783a7..45ff5c6 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -126,6 +126,8 @@ struct xhci_hcd_mtk {
struct regulator *vbus;
struct clk *sys_clk;/* sys and mac clock */
struct clk *ref_clk;
+   struct clk *mcu_clk;
+   struct clk *dma_clk;
struct regmap *pericfg;
struct phy **phys;
int num_phys;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 8/9] dt-bindings: usb: mtk-xhci: add a optional property to disable u3ports

2017-09-27 Thread Chunfeng Yun
Add a new optional property to disable u3ports

Signed-off-by: Chunfeng Yun 
---
 .../devicetree/bindings/usb/mediatek,mtk-xhci.txt  |2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
index 5611a2e..2d9b459 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
@@ -38,6 +38,8 @@ Optional properties:
mode;
  - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
control register, it depends on "mediatek,wakeup-src".
+ - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
+   bit1 for u3port1, ... etc;
  - vbus-supply : reference to the VBUS regulator;
  - usb3-lpm-capable : supports USB3.0 LPM
  - pinctrl-names : a pinctrl state named "default" must be defined
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 9/9] dt-bindings: usb: mtk-xhci: remove dummy clocks and add optional ones

2017-09-27 Thread Chunfeng Yun
Remove dummy clocks for usb wakeup and add optional ones for
MCU_BUS_CK and DMA_BUS_CK.

Signed-off-by: Chunfeng Yun 
---
 .../devicetree/bindings/usb/mediatek,mtk-xhci.txt  |   18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
index 2d9b459..3059596 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
@@ -26,10 +26,11 @@ Required properties:
  - clocks : a list of phandle + clock-specifier pairs, one for each
entry in clock-names
  - clock-names : must contain
-   "sys_ck": for clock of xHCI MAC
-   "ref_ck": for reference clock of xHCI MAC
-   "wakeup_deb_p0": for USB wakeup debounce clock of port0
-   "wakeup_deb_p1": for USB wakeup debounce clock of port1
+   "sys_ck": controller clock used by normal mode,
+   the following ones are optional:
+   "ref_ck": reference clock used by low power mode etc,
+   "mcu_ck": mcu_bus clock for register access,
+   "dma_ck": dma_bus clock for data transfer by DMA
 
  - phys : a list of phandle + phy specifier pairs
 
@@ -57,9 +58,7 @@ usb30: usb@1127 {
clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>,
 <&pericfg CLK_PERI_USB0>,
 <&pericfg CLK_PERI_USB1>;
-   clock-names = "sys_ck", "ref_ck",
- "wakeup_deb_p0",
- "wakeup_deb_p1";
+   clock-names = "sys_ck", "ref_ck";
phys = <&phy_port0 PHY_TYPE_USB3>,
   <&phy_port1 PHY_TYPE_USB2>;
vusb33-supply = <&mt6397_vusb_reg>;
@@ -91,9 +90,8 @@ Required properties:
 
  - clocks : a list of phandle + clock-specifier pairs, one for each
entry in clock-names
- - clock-names : must be
-   "sys_ck": for clock of xHCI MAC
-   "ref_ck": for reference clock of xHCI MAC
+ - clock-names : must contain "sys_ck", and the following ones are optional:
+   "ref_ck", "mcu_ck" and "dma_ck"
 
 Optional properties:
  - vbus-supply : reference to the VBUS regulator;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 7/9] usb: host: modify description for MTK xHCI config

2017-09-27 Thread Chunfeng Yun
Due to all MediaTek SoCs with xHCI host controller use this
driver, remove limitation for specific SoCs

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/Kconfig |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index fa5692d..bc09a2e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -45,12 +45,12 @@ config USB_XHCI_PLATFORM
  If unsure, say N.
 
 config USB_XHCI_MTK
-   tristate "xHCI support for Mediatek MT65xx/MT7621"
+   tristate "xHCI support for MediaTek SoCs"
select MFD_SYSCON
depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST
---help---
  Say 'Y' to enable the support for the xHCI host controller
- found in Mediatek MT65xx SoCs.
+ found in MediaTek SoCs.
  If unsure, say N.
 
 config USB_XHCI_MVEBU
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/9] usb: xhci-mtk: remove dummy wakeup debounce clocks

2017-09-27 Thread Chunfeng Yun
The wakeup debounce clocks for each ports in fact are not
needed, so remove them.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c |   33 -
 drivers/usb/host/xhci-mtk.h |2 --
 2 files changed, 35 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 97ba51e..d60463c 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -237,25 +237,8 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
goto sys_clk_err;
}
 
-   if (mtk->wakeup_src) {
-   ret = clk_prepare_enable(mtk->wk_deb_p0);
-   if (ret) {
-   dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
-   goto usb_p0_err;
-   }
-
-   ret = clk_prepare_enable(mtk->wk_deb_p1);
-   if (ret) {
-   dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
-   goto usb_p1_err;
-   }
-   }
return 0;
 
-usb_p1_err:
-   clk_disable_unprepare(mtk->wk_deb_p0);
-usb_p0_err:
-   clk_disable_unprepare(mtk->sys_clk);
 sys_clk_err:
clk_disable_unprepare(mtk->ref_clk);
 ref_clk_err:
@@ -264,10 +247,6 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
 
 static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
 {
-   if (mtk->wakeup_src) {
-   clk_disable_unprepare(mtk->wk_deb_p1);
-   clk_disable_unprepare(mtk->wk_deb_p0);
-   }
clk_disable_unprepare(mtk->sys_clk);
clk_disable_unprepare(mtk->ref_clk);
 }
@@ -371,18 +350,6 @@ static int usb_wakeup_of_property_parse(struct 
xhci_hcd_mtk *mtk,
if (!mtk->wakeup_src)
return 0;
 
-   mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
-   if (IS_ERR(mtk->wk_deb_p0)) {
-   dev_err(dev, "fail to get wakeup_deb_p0\n");
-   return PTR_ERR(mtk->wk_deb_p0);
-   }
-
-   mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
-   if (IS_ERR(mtk->wk_deb_p1)) {
-   dev_err(dev, "fail to get wakeup_deb_p1\n");
-   return PTR_ERR(mtk->wk_deb_p1);
-   }
-
mtk->pericfg = syscon_regmap_lookup_by_phandle(dn,
"mediatek,syscon-wakeup");
if (IS_ERR(mtk->pericfg)) {
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index db55a12..67783a7 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -126,8 +126,6 @@ struct xhci_hcd_mtk {
struct regulator *vbus;
struct clk *sys_clk;/* sys and mac clock */
struct clk *ref_clk;
-   struct clk *wk_deb_p0;  /* port0's wakeup debounce clock */
-   struct clk *wk_deb_p1;
struct regmap *pericfg;
struct phy **phys;
int num_phys;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/9] usb: xhci-mtk: use dma_set_mask_and_coherent() in probe function

2017-09-27 Thread Chunfeng Yun
This patch uses the simpler dma_set_mask_and_coherent() instead of
doing these as separate steps

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c |7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 8fb6065..c197a6d 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -606,15 +606,10 @@ static int xhci_mtk_probe(struct platform_device *pdev)
}
 
/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-   ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
goto disable_clk;
 
-   if (!dev->dma_mask)
-   dev->dma_mask = &dev->coherent_dma_mask;
-   else
-   dma_set_mask(dev, DMA_BIT_MASK(32));
-
hcd = usb_create_hcd(driver, dev, dev_name(dev));
if (!hcd) {
ret = -ENOMEM;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/9] usb: xhci-mtk: use ports count from xhci in xhci_mtk_sch_init()

2017-09-27 Thread Chunfeng Yun
Make use of ports count from xhci but not from ippc in
xhci_mtk_sch_init()

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk-sch.c |3 ++-
 drivers/usb/host/xhci-mtk.c |3 ---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 6e7ddf6..bfc51bc 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -287,12 +287,13 @@ static bool need_bw_sch(struct usb_host_endpoint *ep,
 
 int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 {
+   struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
struct mu3h_sch_bw_info *sch_array;
int num_usb_bus;
int i;
 
/* ss IN and OUT are separated */
-   num_usb_bus = mtk->num_u3_ports * 2 + mtk->num_u2_ports;
+   num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
 
sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
if (sch_array == NULL)
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index c197a6d..9502ca4 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -492,7 +492,6 @@ static void xhci_mtk_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 /* called during probe() after chip reset completes */
 static int xhci_mtk_setup(struct usb_hcd *hcd)
 {
-   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
int ret;
 
@@ -507,8 +506,6 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
return ret;
 
if (usb_hcd_is_primary_hcd(hcd)) {
-   mtk->num_u3_ports = xhci->num_usb3_ports;
-   mtk->num_u2_ports = xhci->num_usb2_ports;
ret = xhci_mtk_sch_init(mtk);
if (ret)
return ret;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/9] usb: xhci-mtk: support option to disable usb3 ports

2017-09-27 Thread Chunfeng Yun
Add support to disable specific usb3 ports, it's useful when
usb3 phy is shared with PCIe or SATA, because we should disable
the corresponding usb3 port if the phy is used by PCIe or SATA.
Sometimes it's helpful to analyse and solve problems.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c |   18 +++---
 drivers/usb/host/xhci-mtk.h |1 +
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 7a92bb7..97ba51e 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -92,6 +92,7 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
 {
struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
u32 value, check_val;
+   int u3_ports_disabed = 0;
int ret;
int i;
 
@@ -103,8 +104,13 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
value &= ~CTRL1_IP_HOST_PDN;
writel(value, &ippc->ip_pw_ctr1);
 
-   /* power on and enable all u3 ports */
+   /* power on and enable u3 ports except skipped ones */
for (i = 0; i < mtk->num_u3_ports; i++) {
+   if ((0x1 << i) & mtk->u3p_dis_msk) {
+   u3_ports_disabed++;
+   continue;
+   }
+
value = readl(&ippc->u3_ctrl_p[i]);
value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
value |= CTRL_U3_PORT_HOST_SEL;
@@ -126,7 +132,7 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
STS1_SYS125_RST | STS1_XHCI_RST;
 
-   if (mtk->num_u3_ports)
+   if (mtk->num_u3_ports > u3_ports_disabed)
check_val |= STS1_U3_MAC_RST;
 
ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
@@ -149,8 +155,11 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
if (!mtk->has_ippc)
return 0;
 
-   /* power down all u3 ports */
+   /* power down u3 ports except skipped ones */
for (i = 0; i < mtk->num_u3_ports; i++) {
+   if ((0x1 << i) & mtk->u3p_dis_msk)
+   continue;
+
value = readl(&ippc->u3_ctrl_p[i]);
value |= CTRL_U3_PORT_PDN;
writel(value, &ippc->u3_ctrl_p[i]);
@@ -573,6 +582,9 @@ static int xhci_mtk_probe(struct platform_device *pdev)
}
 
mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
+   /* optional property, ignore the error if it does not exist */
+   of_property_read_u32(node, "mediatek,u3p-dis-msk",
+&mtk->u3p_dis_msk);
 
ret = usb_wakeup_of_property_parse(mtk, node);
if (ret)
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 3aa5e1d..db55a12 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -121,6 +121,7 @@ struct xhci_hcd_mtk {
bool has_ippc;
int num_u2_ports;
int num_u3_ports;
+   int u3p_dis_msk;
struct regulator *vusb33;
struct regulator *vbus;
struct clk *sys_clk;/* sys and mac clock */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/2] usb: renesas_usbhs: bugfix for v4.14

2017-09-27 Thread Yoshihiro Shimoda
 This patch set is based on the Felipe's usb.git / testing/fixes branch
 (The commit is 7661ca09b2ff98f48693f431bb01fed62830e433).

Changes from v1:
 - Devides two fix things in a patch to two patches.

Yoshihiro Shimoda (2):
  usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe
  usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction

 drivers/usb/renesas_usbhs/fifo.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction

2017-09-27 Thread Yoshihiro Shimoda
This patch fixes an issue that the usbhsf_fifo_clear() is possible
to cause 10 msec delay if the pipe is RX direction and empty because
the FRDY bit will never be set to 1 in such case.

Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.")
Cc:  # v3.1+
Signed-off-by: Yoshihiro Shimoda 
---
 drivers/usb/renesas_usbhs/fifo.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 03cac07..68f2690 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -284,8 +284,17 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
int ret = 0;
 
-   if (!usbhs_pipe_is_dcp(pipe))
-   ret = usbhsf_fifo_barrier(priv, fifo);
+   if (!usbhs_pipe_is_dcp(pipe)) {
+   /*
+* This driver checks the pipe condition first to avoid -EBUSY
+* from usbhsf_fifo_barrier() with about 10 msec delay in
+* the interrupt handler if the pipe is RX direction and empty.
+*/
+   if (usbhs_pipe_is_dir_in(pipe))
+   ret = usbhs_pipe_is_accessible(pipe);
+   if (!ret)
+   ret = usbhsf_fifo_barrier(priv, fifo);
+   }
 
/*
 * if non-DCP pipe, this driver should set BCLR when
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe

2017-09-27 Thread Yoshihiro Shimoda
This patch fixes an issue that the driver sets the BCLR bit of
{C,Dn}FIFOCTR register to 1 even when it's non-DCP pipe and
the FRDY bit of {C,Dn}FIFOCTR register is set to 1.

Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.")
Cc:  # v3.1+
Signed-off-by: Yoshihiro Shimoda 
---
 drivers/usb/renesas_usbhs/fifo.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index d1af831..03cac07 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -282,11 +282,17 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
  struct usbhs_fifo *fifo)
 {
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+   int ret = 0;
 
if (!usbhs_pipe_is_dcp(pipe))
-   usbhsf_fifo_barrier(priv, fifo);
+   ret = usbhsf_fifo_barrier(priv, fifo);
 
-   usbhs_write(priv, fifo->ctr, BCLR);
+   /*
+* if non-DCP pipe, this driver should set BCLR when
+* usbhsf_fifo_barrier() returns 0.
+*/
+   if (!ret)
+   usbhs_write(priv, fifo->ctr, BCLR);
 }
 
 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: musb: Check for host-mode using is_host_active() on reset interrupt

2017-09-27 Thread Jonathan Liu
The sunxi musb has a bug where sometimes it will generate a babble
error on device disconnect instead of a disconnect IRQ. When this
happens the musb controller switches from host mode to device mode
(it clears MUSB_DEVCTL_HM/MUSB_DEVCTL_SESSION and sets
MUSB_DEVCTL_BDEVICE) and gets stuck in this state.

The babble error is misdetected as a bus reset because MUSB_DEVCTL_HM
was cleared.

To fix this, use is_host_active() rather than (devctl & MUSB_DEVCTL_HM)
to detect babble error so that sunxi musb babble recovery can handle it
by restoring the mode. This information is provided by the driver logic
and does not rely on register contents.

Cc: sta...@vger.kernel.org # v4.1+
Signed-off-by: Jonathan Liu 
---
 drivers/usb/musb/musb_core.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 029692053dd3..1bce7df3e110 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -906,7 +906,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 
int_usb,
 */
if (int_usb & MUSB_INTR_RESET) {
handled = IRQ_HANDLED;
-   if (devctl & MUSB_DEVCTL_HM) {
+   if (is_host_active(musb)) {
/*
 * When BABBLE happens what we can depends on which
 * platform MUSB is running, because some platforms
@@ -916,9 +916,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 
int_usb,
 * drop the session.
 */
dev_err(musb->controller, "Babble\n");
-
-   if (is_host_active(musb))
-   musb_recover_from_babble(musb);
+   musb_recover_from_babble(musb);
} else {
musb_dbg(musb, "BUS RESET as %s",
usb_otg_state_string(musb->xceiv->otg->state));
-- 
2.13.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Mouse freezes on button depression

2017-09-27 Thread Christian Bullow

Hi Oliver thank you for your reply.

Apologies for now replying from gmail. I'm being told my crjb.net 
address is failing SPF and that I have to shoehorn this email into 
plain-text for you. Here we go :)


I must correct/clarify that the browser forward and back buttons seem to 
work in chrome and that in testing this evening, they have not frozen or 
crashed anything. The output I provided before was simply the dmesg 
record of the mouse being detected on boot or plugin, not any dmesg 
records produced on the depression of the buttons of concern (which are 
primarily the DPI+ and DPI- buttons).


*Relevant output from usbmon (cat /sys/kernel/debug/usb/usbmon/0u)*

I was able to capture my pressing the dpi+ button twice before the mouse 
driver crashed.


a0b1fca52240 1143494193 C Ii:1:015:2 0:1 8 =  
a0b1fca52240 1143494212 S Ii:1:015:2 -115:1 8 <
a0b1fca52240 1144099217 C Ii:1:015:2 0:1 8 =  
a0b1fca52240 1144099233 S Ii:1:015:2 -115:1 8 <

*From lsusb*

Bus 001 Device 015: ID 1044:7a13 Chu Yuen Enterprise Co., Ltd

*From cat /sys/kernel/debug/usb/devices*

T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#=  15 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=1044 ProdID=7a13 Rev= 2.00
S:  Manufacturer=Texas Instruments
S:  Product=MSP430-USB Mouse
S:  SerialNumber=8C2F0C5132000C00
C:* #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=15ms
E:  Ad=01(O) Atr=03(Int.) MxPS=   8 Ivl=15ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=1ms
E:  Ad=02(O) Atr=03(Int.) MxPS=   8 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=83(I) Atr=03(Int.) MxPS=   8 Ivl=20ms
E:  Ad=03(O) Atr=03(Int.) MxPS=   8 Ivl=20ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=84(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
E:  Ad=04(O) Atr=03(Int.) MxPS=  64 Ivl=1ms

Unplugging and re-plugging the mouse in, it moves to Bus 01, Device 16 
and I captured the following:


*usbmon output from the DPI - button*

a0b20247ab40 1348549098 C Ii:1:016:2 0:1 8 =  
a0b20247ab40 1348549123 S Ii:1:016:2 -115:1 8 <*
*

I can confirm that while the mouse cursor became unresponsive/frozen on 
the computer after pressing this button, when I re-inserted it in, the 
mouse movement across the screen reflected that the DPI - button had 
been pressed, as it was sluggish now. So at least the device is 
reflecting the button being pressed and is responding as such.


*usbmon output from the browser-forward button*

I pressed thus button three times and the mouse appears to still work! 
(of course we're now at bus 01, device 017


a0b25856b980 1565643086 C Ii:1:017:2 0:1 8 = 1000 
a0b25856b980 1565643113 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1565810091 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1565810113 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1566953154 C Ii:1:017:2 0:1 8 = 1000 
a0b25856b980 1566953181 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1567113163 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1567113185 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1567762196 C Ii:1:017:2 0:1 8 = 1000 
a0b25856b980 1567762215 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1567890202 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1567890225 S Ii:1:017:2 -115:1 8 <

*usbmon output from the browser-backward button*

still not frozen ...

a0b25856b980 1710325920 C Ii:1:017:2 0:1 8 = 00ff ff00
a0b25856b980 1710325950 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1710343901 C Ii:1:017:2 0:1 8 = 0800 
a0b25856b980 1710343919 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1710506929 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1710506952 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1710609934 C Ii:1:017:2 0:1 8 = 0800 
a0b25856b980 1710609956 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1710720943 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1710720965 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1710981955 C Ii:1:017:2 0:1 8 = 0800 
a0b25856b980 1710981977 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1711079959 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1711079981 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1711615989 C Ii:1:017:2 0:1 8 = 0800 
a0b25856b980 1711616014 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1711730998 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1711731020 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1712017010 C Ii:1:017:2 0:1 8 = 0800 
a0b25856b980 1712017033 S Ii:1:017:2 -115:1 8 <
a0b25856b980 1712089016 C Ii:1:017:2 0:1 8 =  
a0b25856b980 1712089038 S Ii:1:017:2 -115:1 8 <

Pressing the DPI+ button made the mouse cursor unresponsive t

[PATCH 08/12] usb: mtu3: get optional vbus for host only mode

2017-09-27 Thread Chunfeng Yun
When dr_mode is set as USB_DR_MODE_HOST, it's better to try to
get optional vbus, this can increase flexibility, although we
can set vbus as always on for regulator or put it in host driver
to turn it on.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3_plat.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 1e473b0..7ca81f4e 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -300,10 +300,6 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
of_property_read_u32(node, "mediatek,u3p-dis-msk",
 &ssusb->u3p_dis_msk);
 
-   if (ssusb->dr_mode != USB_DR_MODE_OTG)
-   return 0;
-
-   /* if dual-role mode is supported */
vbus = devm_regulator_get(&pdev->dev, "vbus");
if (IS_ERR(vbus)) {
dev_err(dev, "failed to get vbus\n");
@@ -311,6 +307,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
}
otg_sx->vbus = vbus;
 
+   if (ssusb->dr_mode == USB_DR_MODE_HOST)
+   return 0;
+
+   /* if dual-role mode is supported */
otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd");
otg_sx->manual_drd_enabled =
of_property_read_bool(node, "enable-manual-drd");
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/12] usb: mtu3: set invalid dr_mode as dual-role mode

2017-09-27 Thread Chunfeng Yun
Treat dr_mode of USB_DR_MODE_UNKNOWN as USB_DR_MODE_OTG to
enhance functional robustness.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3_plat.c |6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 7ca81f4e..9ff3357 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -283,10 +283,8 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
return PTR_ERR(ssusb->ippc_base);
 
ssusb->dr_mode = usb_get_dr_mode(dev);
-   if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN) {
-   dev_err(dev, "dr_mode is error\n");
-   return -EINVAL;
-   }
+   if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN)
+   ssusb->dr_mode = USB_DR_MODE_OTG;
 
if (ssusb->dr_mode == USB_DR_MODE_PERIPHERAL)
return 0;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/12] usb: mtu3: support 36-bit DMA address

2017-09-27 Thread Chunfeng Yun
add support for 36-bit DMA address

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h |   17 ++-
 drivers/usb/mtu3/mtu3_core.c|   34 -
 drivers/usb/mtu3/mtu3_hw_regs.h |   10 
 drivers/usb/mtu3/mtu3_qmu.c |  102 ---
 4 files changed, 142 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 2795294..ef2dc92 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -46,6 +46,9 @@
 #defineMU3D_EP_RXCR1(epnum)(U3D_RX1CSR1 + (((epnum) - 1) * 0x10))
 #defineMU3D_EP_RXCR2(epnum)(U3D_RX1CSR2 + (((epnum) - 1) * 0x10))
 
+#define USB_QMU_TQHIAR(epnum)  (U3D_TXQHIAR1 + (((epnum) - 1) * 0x4))
+#define USB_QMU_RQHIAR(epnum)  (U3D_RXQHIAR1 + (((epnum) - 1) * 0x4))
+
 #define USB_QMU_RQCSR(epnum)   (U3D_RXQCSR1 + (((epnum) - 1) * 0x10))
 #define USB_QMU_RQSAR(epnum)   (U3D_RXQSAR1 + (((epnum) - 1) * 0x10))
 #define USB_QMU_RQCPR(epnum)   (U3D_RXQCPR1 + (((epnum) - 1) * 0x10))
@@ -138,23 +141,33 @@ struct mtu3_fifo_info {
  * Checksum value is calculated over the 16 bytes of the GPD by default;
  * @data_buf_len (RX ONLY): This value indicates the length of
  * the assigned data buffer
+ * @tx_ext_addr (TX ONLY): [3:0] are 4 extension bits of @buffer,
+ * [7:4] are 4 extension bits of @next_gpd
  * @next_gpd: Physical address of the next GPD
  * @buffer: Physical address of the data buffer
  * @buf_len:
  * (TX): This value indicates the length of the assigned data buffer
  * (RX): The total length of data received
  * @ext_len: reserved
+ * @rx_ext_addr(RX ONLY): [3:0] are 4 extension bits of @buffer,
+ * [7:4] are 4 extension bits of @next_gpd
  * @ext_flag:
  * bit5 (TX ONLY): Zero Length Packet (ZLP),
  */
 struct qmu_gpd {
__u8 flag;
__u8 chksum;
-   __le16 data_buf_len;
+   union {
+   __le16 data_buf_len;
+   __le16 tx_ext_addr;
+   };
__le32 next_gpd;
__le32 buffer;
__le16 buf_len;
-   __u8 ext_len;
+   union {
+   __u8 ext_len;
+   __u8 rx_ext_addr;
+   };
__u8 ext_flag;
 } __packed;
 
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 9475798..cd4528f 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -17,6 +17,7 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -759,7 +760,31 @@ static void mtu3_hw_exit(struct mtu3 *mtu)
mtu3_mem_free(mtu);
 }
 
-/*-*/
+/**
+ * we set 32-bit DMA mask by default, here check whether the controller
+ * supports 36-bit DMA or not, if it does, set 36-bit DMA mask.
+ */
+static int mtu3_set_dma_mask(struct mtu3 *mtu)
+{
+   struct device *dev = mtu->dev;
+   bool is_36bit = false;
+   int ret = 0;
+   u32 value;
+
+   value = mtu3_readl(mtu->mac_base, U3D_MISC_CTRL);
+   if (value & DMA_ADDR_36BIT) {
+   is_36bit = true;
+   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
+   /* If set 36-bit DMA mask fails, fall back to 32-bit DMA mask */
+   if (ret) {
+   is_36bit = false;
+   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+   }
+   }
+   dev_info(dev, "dma mask: %s bits\n", is_36bit ? "36" : "32");
+
+   return ret;
+}
 
 int ssusb_gadget_init(struct ssusb_mtk *ssusb)
 {
@@ -820,6 +845,12 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
return ret;
}
 
+   ret = mtu3_set_dma_mask(mtu);
+   if (ret) {
+   dev_err(dev, "mtu3 set dma_mask failed:%d\n", ret);
+   goto dma_mask_err;
+   }
+
ret = devm_request_irq(dev, mtu->irq, mtu3_irq, 0, dev_name(dev), mtu);
if (ret) {
dev_err(dev, "request irq %d failed!\n", mtu->irq);
@@ -845,6 +876,7 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
 gadget_err:
device_init_wakeup(dev, false);
 
+dma_mask_err:
 irq_err:
mtu3_hw_exit(mtu);
ssusb->u3d = NULL;
diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
index 06b2966..b605975 100644
--- a/drivers/usb/mtu3/mtu3_hw_regs.h
+++ b/drivers/usb/mtu3/mtu3_hw_regs.h
@@ -58,6 +58,8 @@
 #define U3D_QCR1   (SSUSB_DEV_BASE + 0x0404)
 #define U3D_QCR2   (SSUSB_DEV_BASE + 0x0408)
 #define U3D_QCR3   (SSUSB_DEV_BASE + 0x040C)
+#define U3D_TXQHIAR1   (SSUSB_DEV_BASE + 0x0484)
+#define U3D_RXQHIAR1   (SSUSB_DEV_BASE + 0x04C4)
 
 #define U3D_TXQCSR1(SSUSB_DEV_BASE + 0x0510)
 #define U3D_TXQSAR1(SSUSB_DEV_BASE + 0x0514)
@@ -189,6 +191,13 @@
 #define QMU_RX_COZ(x)  (BIT(16) << (x))
 #define QMU_RX_ZLP(x)  (BIT(0) << (x))
 
+/* U3D_TXQHIAR1 */
+/* U3D_RXQHIAR1 */
+#define QMU_LAS

[PATCH 04/12] usb: mtu3: add optional mcu and dma bus clocks

2017-09-27 Thread Chunfeng Yun
There are mcu_bus and dma_bus clocks needed to be turned on/off by
driver on some SoCs, so add them as optional ones

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h  |5 ++
 drivers/usb/mtu3/mtu3_plat.c |  121 --
 2 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 6d3278e..2795294 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -206,6 +206,9 @@ struct otg_switch_mtk {
  * @ippc_base: register base address of IP Power and Clock interface (IPPC)
  * @vusb33: usb3.3V shared by device/host IP
  * @sys_clk: system clock of mtu3, shared by device/host IP
+ * @ref_clk: reference clock
+ * @mcu_clk: mcu_bus_ck clock for AHB bus etc
+ * @dma_clk: dma_bus_ck clock for AXI bus etc
  * @dr_mode: works in which mode:
  * host only, device only or dual-role mode
  * @u2_ports: number of usb2.0 host ports
@@ -226,6 +229,8 @@ struct ssusb_mtk {
struct regulator *vusb33;
struct clk *sys_clk;
struct clk *ref_clk;
+   struct clk *mcu_clk;
+   struct clk *dma_clk;
/* otg */
struct otg_switch_mtk otg_switch;
enum usb_dr_mode dr_mode;
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 9edad30..fb89920 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -110,15 +110,9 @@ static void ssusb_phy_power_off(struct ssusb_mtk *ssusb)
phy_power_off(ssusb->phys[i]);
 }
 
-static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
+static int ssusb_clks_enable(struct ssusb_mtk *ssusb)
 {
-   int ret = 0;
-
-   ret = regulator_enable(ssusb->vusb33);
-   if (ret) {
-   dev_err(ssusb->dev, "failed to enable vusb33\n");
-   goto vusb33_err;
-   }
+   int ret;
 
ret = clk_prepare_enable(ssusb->sys_clk);
if (ret) {
@@ -132,6 +126,52 @@ static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
goto ref_clk_err;
}
 
+   ret = clk_prepare_enable(ssusb->mcu_clk);
+   if (ret) {
+   dev_err(ssusb->dev, "failed to enable mcu_clk\n");
+   goto mcu_clk_err;
+   }
+
+   ret = clk_prepare_enable(ssusb->dma_clk);
+   if (ret) {
+   dev_err(ssusb->dev, "failed to enable dma_clk\n");
+   goto dma_clk_err;
+   }
+
+   return 0;
+
+dma_clk_err:
+   clk_disable_unprepare(ssusb->mcu_clk);
+mcu_clk_err:
+   clk_disable_unprepare(ssusb->ref_clk);
+ref_clk_err:
+   clk_disable_unprepare(ssusb->sys_clk);
+sys_clk_err:
+   return ret;
+}
+
+static void ssusb_clks_disable(struct ssusb_mtk *ssusb)
+{
+   clk_disable_unprepare(ssusb->dma_clk);
+   clk_disable_unprepare(ssusb->mcu_clk);
+   clk_disable_unprepare(ssusb->ref_clk);
+   clk_disable_unprepare(ssusb->sys_clk);
+}
+
+static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
+{
+   int ret = 0;
+
+   ret = regulator_enable(ssusb->vusb33);
+   if (ret) {
+   dev_err(ssusb->dev, "failed to enable vusb33\n");
+   goto vusb33_err;
+   }
+
+   ret = ssusb_clks_enable(ssusb);
+   if (ret)
+   goto clks_err;
+
ret = ssusb_phy_init(ssusb);
if (ret) {
dev_err(ssusb->dev, "failed to init phy\n");
@@ -149,20 +189,16 @@ static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
 phy_err:
ssusb_phy_exit(ssusb);
 phy_init_err:
-   clk_disable_unprepare(ssusb->ref_clk);
-ref_clk_err:
-   clk_disable_unprepare(ssusb->sys_clk);
-sys_clk_err:
+   ssusb_clks_disable(ssusb);
+clks_err:
regulator_disable(ssusb->vusb33);
 vusb33_err:
-
return ret;
 }
 
 static void ssusb_rscs_exit(struct ssusb_mtk *ssusb)
 {
-   clk_disable_unprepare(ssusb->sys_clk);
-   clk_disable_unprepare(ssusb->ref_clk);
+   ssusb_clks_disable(ssusb);
regulator_disable(ssusb->vusb33);
ssusb_phy_power_off(ssusb);
ssusb_phy_exit(ssusb);
@@ -203,6 +239,19 @@ static int get_iddig_pinctrl(struct ssusb_mtk *ssusb)
return 0;
 }
 
+/* ignore the error if the clock does not exist */
+static struct clk *get_optional_clk(struct device *dev, const char *id)
+{
+   struct clk *opt_clk;
+
+   opt_clk = devm_clk_get(dev, id);
+   /* ignore error number except EPROBE_DEFER */
+   if (IS_ERR(opt_clk) && (PTR_ERR(opt_clk) != -EPROBE_DEFER))
+   opt_clk = NULL;
+
+   return opt_clk;
+}
+
 static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk 
*ssusb)
 {
struct device_node *node = pdev->dev.of_node;
@@ -225,18 +274,17 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
return PTR_ERR(ssusb->sys_clk);
}
 
-   /*
-* reference clock is usually a "fixed-clock", make it optional
-* for backward compatibility and ignore the error if it d

[PATCH 01/12] usb: mtu3: fix error return code in ssusb_gadget_init()

2017-09-27 Thread Chunfeng Yun
When fail to get irq number, platform_get_irq() may return
-EPROBE_DEFER, but we ignore it and always return -ENODEV,
so fix it.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3_core.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 99c65b0..9475798 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -774,9 +774,9 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
return -ENOMEM;
 
mtu->irq = platform_get_irq(pdev, 0);
-   if (mtu->irq <= 0) {
+   if (mtu->irq < 0) {
dev_err(dev, "fail to get irq number\n");
-   return -ENODEV;
+   return mtu->irq;
}
dev_info(dev, "irq %d\n", mtu->irq);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/12] usb: mtu3: use FORCE/RG_IDDIG to implement manual DRD switch

2017-09-27 Thread Chunfeng Yun
In order to keep manual DRD switch independent on IDDIG interrupt,
make use of FORCE/RG_IDDIG instead of IDDIG EINT interrupt to
implement manual DRD switch function.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h |   18 
 drivers/usb/mtu3/mtu3_dr.c  |   61 +--
 drivers/usb/mtu3/mtu3_dr.h  |6 
 drivers/usb/mtu3/mtu3_host.c|5 
 drivers/usb/mtu3/mtu3_hw_regs.h |2 ++
 drivers/usb/mtu3/mtu3_plat.c|   38 ++--
 6 files changed, 74 insertions(+), 56 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index ef2dc92..b0c2b5d 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -115,6 +115,19 @@ enum mtu3_g_ep0_state {
 };
 
 /**
+ * MTU3_DR_FORCE_NONE: automatically switch host and periperal mode
+ * by IDPIN signal.
+ * MTU3_DR_FORCE_HOST: force to enter host mode and override OTG
+ * IDPIN signal.
+ * MTU3_DR_FORCE_DEVICE: force to enter peripheral mode.
+ */
+enum mtu3_dr_force_mode {
+   MTU3_DR_FORCE_NONE = 0,
+   MTU3_DR_FORCE_HOST,
+   MTU3_DR_FORCE_DEVICE,
+};
+
+/**
  * @base: the base address of fifo
  * @limit: the bitmap size in bits
  * @bitmap: fifo bitmap in unit of @MTU3_EP_FIFO_UNIT
@@ -196,7 +209,6 @@ struct mtu3_gpd_ring {
 *  xHCI driver initialization, it's necessary for system bootup
 *  as device.
 * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not
-* @id_*: used to maually switch between host and device modes by idpin
 * @manual_drd_enabled: it's true when supports dual-role device by debugfs
 *  to switch host/device modes depending on user input.
 */
@@ -207,10 +219,6 @@ struct otg_switch_mtk {
struct notifier_block id_nb;
struct delayed_work extcon_reg_dwork;
bool is_u3_drd;
-   /* dual-role switch by debugfs */
-   struct pinctrl *id_pinctrl;
-   struct pinctrl_state *id_float;
-   struct pinctrl_state *id_ground;
bool manual_drd_enabled;
 };
 
diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c
index 5602561..ec442cd 100644
--- a/drivers/usb/mtu3/mtu3_dr.c
+++ b/drivers/usb/mtu3/mtu3_dr.c
@@ -261,21 +261,22 @@ static void extcon_register_dwork(struct work_struct 
*work)
  * depending on user input.
  * This is useful in special cases, such as uses TYPE-A receptacle but also
  * wants to support dual-role mode.
- * It generates cable state changes by pulling up/down IDPIN and
- * notifies driver to switch mode by "extcon-usb-gpio".
- * NOTE: when use MICRO receptacle, should not enable this interface.
  */
 static void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host)
 {
struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 
-   if (to_host)
-   pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_ground);
-   else
-   pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_float);
+   if (to_host) {
+   ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
+   ssusb_set_mailbox(otg_sx, MTU3_VBUS_OFF);
+   ssusb_set_mailbox(otg_sx, MTU3_ID_GROUND);
+   } else {
+   ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_DEVICE);
+   ssusb_set_mailbox(otg_sx, MTU3_ID_FLOAT);
+   ssusb_set_mailbox(otg_sx, MTU3_VBUS_VALID);
+   }
 }
 
-
 static int ssusb_mode_show(struct seq_file *sf, void *unused)
 {
struct ssusb_mtk *ssusb = sf->private;
@@ -388,17 +389,45 @@ static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb)
debugfs_remove_recursive(ssusb->dbgfs_root);
 }
 
+void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
+ enum mtu3_dr_force_mode mode)
+{
+   u32 value;
+
+   value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0));
+   switch (mode) {
+   case MTU3_DR_FORCE_DEVICE:
+   value |= SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG;
+   break;
+   case MTU3_DR_FORCE_HOST:
+   value |= SSUSB_U2_PORT_FORCE_IDDIG;
+   value &= ~SSUSB_U2_PORT_RG_IDDIG;
+   break;
+   case MTU3_DR_FORCE_NONE:
+   value &= ~(SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG);
+   break;
+   default:
+   return;
+   }
+   mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value);
+}
+
 int ssusb_otg_switch_init(struct ssusb_mtk *ssusb)
 {
struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
 
-   INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork, extcon_register_dwork);
-
-   if (otg_sx->manual_drd_enabled)
+   if (otg_sx->manual_drd_enabled) {
ssusb_debugfs_init(ssusb);
-
-   /* It is enough to delay 1s for waiting for host initialization */
-   schedule_delayed_work(&otg_sx->extcon_reg_dwork, HZ);
+   } else {
+   INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork,
+   

[PATCH 07/12] usb: mtu3: add support for usb3.1 IP

2017-09-27 Thread Chunfeng Yun
Support SuperSpeedPlus for usb3.1 device IP

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h|1 +
 drivers/usb/mtu3/mtu3_core.c   |   14 +++---
 drivers/usb/mtu3/mtu3_gadget.c |3 ++-
 drivers/usb/mtu3/mtu3_gadget_ep0.c |   16 
 drivers/usb/mtu3/mtu3_hw_regs.h|1 +
 5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index b0c2b5d..d80e4e8 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -94,6 +94,7 @@ enum mtu3_speed {
MTU3_SPEED_FULL = 1,
MTU3_SPEED_HIGH = 3,
MTU3_SPEED_SUPER = 4,
+   MTU3_SPEED_SUPER_PLUS = 5,
 };
 
 /**
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index cd4528f..67f7a30 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -237,7 +237,7 @@ void mtu3_ep_stall_set(struct mtu3_ep *mep, bool set)
 
 void mtu3_dev_on_off(struct mtu3 *mtu, int is_on)
 {
-   if (mtu->is_u3_ip && (mtu->max_speed == USB_SPEED_SUPER))
+   if (mtu->is_u3_ip && mtu->max_speed >= USB_SPEED_SUPER)
mtu3_ss_func_set(mtu, is_on);
else
mtu3_hs_softconn_set(mtu, is_on);
@@ -547,6 +547,9 @@ static void mtu3_set_speed(struct mtu3 *mtu)
mtu3_clrbits(mbase, U3D_USB3_CONFIG, USB3_EN);
/* HS/FS detected by HW */
mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+   } else if (mtu->max_speed == USB_SPEED_SUPER) {
+   mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+SSUSB_U3_PORT_SSP_SPEED);
}
 
dev_info(mtu->dev, "max_speed: %s\n",
@@ -624,6 +627,10 @@ static irqreturn_t mtu3_link_isr(struct mtu3 *mtu)
udev_speed = USB_SPEED_SUPER;
maxpkt = 512;
break;
+   case MTU3_SPEED_SUPER_PLUS:
+   udev_speed = USB_SPEED_SUPER_PLUS;
+   maxpkt = 512;
+   break;
default:
udev_speed = USB_SPEED_UNKNOWN;
break;
@@ -825,14 +832,15 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
case USB_SPEED_FULL:
case USB_SPEED_HIGH:
case USB_SPEED_SUPER:
+   case USB_SPEED_SUPER_PLUS:
break;
default:
dev_err(dev, "invalid max_speed: %s\n",
usb_speed_string(mtu->max_speed));
/* fall through */
case USB_SPEED_UNKNOWN:
-   /* default as SS */
-   mtu->max_speed = USB_SPEED_SUPER;
+   /* default as SSP */
+   mtu->max_speed = USB_SPEED_SUPER_PLUS;
break;
}
 
diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 434fca5..b495471 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -89,6 +89,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 
switch (mtu->g.speed) {
case USB_SPEED_SUPER:
+   case USB_SPEED_SUPER_PLUS:
if (usb_endpoint_xfer_int(desc) ||
usb_endpoint_xfer_isoc(desc)) {
interval = desc->bInterval;
@@ -456,7 +457,7 @@ static int mtu3_gadget_wakeup(struct usb_gadget *gadget)
return  -EOPNOTSUPP;
 
spin_lock_irqsave(&mtu->lock, flags);
-   if (mtu->g.speed == USB_SPEED_SUPER) {
+   if (mtu->g.speed >= USB_SPEED_SUPER) {
mtu3_setbits(mtu->mac_base, U3D_LINK_POWER_CONTROL, UX_EXIT);
} else {
mtu3_setbits(mtu->mac_base, U3D_POWER_MANAGEMENT, RESUME);
diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c 
b/drivers/usb/mtu3/mtu3_gadget_ep0.c
index 958d74d..1ca77e8 100644
--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -212,8 +212,8 @@ static int ep0_set_sel(struct mtu3 *mtu, struct 
usb_ctrlrequest *setup)
case USB_RECIP_DEVICE:
result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
-   /* superspeed only */
-   if (mtu->g.speed == USB_SPEED_SUPER) {
+
+   if (mtu->g.speed >= USB_SPEED_SUPER) {
result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
}
@@ -329,8 +329,8 @@ static int ep0_handle_feature_dev(struct mtu3 *mtu,
handled = handle_test_mode(mtu, setup);
break;
case USB_DEVICE_U1_ENABLE:
-   if (mtu->g.speed != USB_SPEED_SUPER ||
-   mtu->g.state != USB_STATE_CONFIGURED)
+   if (mtu->g.speed <= USB_SPEED_SUPER ||
+   mtu->g.state != USB_STATE_CONFIGURED)
break;
 
lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTRO

[PATCH 03/12] usb: mtu3: remove dummy wakeup debounce clocks

2017-09-27 Thread Chunfeng Yun
The wakeup debounce clocks for each ports in fact are not
needed, so remove them.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h  |4 ---
 drivers/usb/mtu3/mtu3_host.c |   57 +++---
 2 files changed, 4 insertions(+), 57 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 112723d..6d3278e 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -214,8 +214,6 @@ struct otg_switch_mtk {
  * disable u3port0, bit1==1 to disable u3port1,... etc
  * @dbgfs_root: only used when supports manual dual-role switch via debugfs
  * @wakeup_en: it's true when supports remote wakeup in host mode
- * @wk_deb_p0: port0's wakeup debounce clock
- * @wk_deb_p1: it's optional, and depends on port1 is supported or not
  */
 struct ssusb_mtk {
struct device *dev;
@@ -238,8 +236,6 @@ struct ssusb_mtk {
struct dentry *dbgfs_root;
/* usb wakeup for host mode */
bool wakeup_en;
-   struct clk *wk_deb_p0;
-   struct clk *wk_deb_p1;
struct regmap *pericfg;
 };
 
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
index 4dd9508..edcc591 100644
--- a/drivers/usb/mtu3/mtu3_host.c
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -79,20 +79,6 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
if (!ssusb->wakeup_en)
return 0;
 
-   ssusb->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
-   if (IS_ERR(ssusb->wk_deb_p0)) {
-   dev_err(dev, "fail to get wakeup_deb_p0\n");
-   return PTR_ERR(ssusb->wk_deb_p0);
-   }
-
-   if (of_property_read_bool(dn, "wakeup_deb_p1")) {
-   ssusb->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
-   if (IS_ERR(ssusb->wk_deb_p1)) {
-   dev_err(dev, "fail to get wakeup_deb_p1\n");
-   return PTR_ERR(ssusb->wk_deb_p1);
-   }
-   }
-
ssusb->pericfg = syscon_regmap_lookup_by_phandle(dn,
"mediatek,syscon-wakeup");
if (IS_ERR(ssusb->pericfg)) {
@@ -103,36 +89,6 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
return 0;
 }
 
-static int ssusb_wakeup_clks_enable(struct ssusb_mtk *ssusb)
-{
-   int ret;
-
-   ret = clk_prepare_enable(ssusb->wk_deb_p0);
-   if (ret) {
-   dev_err(ssusb->dev, "failed to enable wk_deb_p0\n");
-   goto usb_p0_err;
-   }
-
-   ret = clk_prepare_enable(ssusb->wk_deb_p1);
-   if (ret) {
-   dev_err(ssusb->dev, "failed to enable wk_deb_p1\n");
-   goto usb_p1_err;
-   }
-
-   return 0;
-
-usb_p1_err:
-   clk_disable_unprepare(ssusb->wk_deb_p0);
-usb_p0_err:
-   return -EINVAL;
-}
-
-static void ssusb_wakeup_clks_disable(struct ssusb_mtk *ssusb)
-{
-   clk_disable_unprepare(ssusb->wk_deb_p1);
-   clk_disable_unprepare(ssusb->wk_deb_p0);
-}
-
 static void host_ports_num_get(struct ssusb_mtk *ssusb)
 {
u32 xhci_cap;
@@ -286,19 +242,14 @@ void ssusb_host_exit(struct ssusb_mtk *ssusb)
 
 int ssusb_wakeup_enable(struct ssusb_mtk *ssusb)
 {
-   int ret = 0;
-
-   if (ssusb->wakeup_en) {
-   ret = ssusb_wakeup_clks_enable(ssusb);
+   if (ssusb->wakeup_en)
ssusb_wakeup_ip_sleep_en(ssusb);
-   }
-   return ret;
+
+   return 0;
 }
 
 void ssusb_wakeup_disable(struct ssusb_mtk *ssusb)
 {
-   if (ssusb->wakeup_en) {
+   if (ssusb->wakeup_en)
ssusb_wakeup_ip_sleep_dis(ssusb);
-   ssusb_wakeup_clks_disable(ssusb);
-   }
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/12] usb: mtu3: support option to disable usb3 ports

2017-09-27 Thread Chunfeng Yun
Add support to disable specific usb3 ports, it's useful when
usb3 phy is shared with PCIe or SATA, because we should disable
the corresponding usb3 port if the phy is used by PCIe or SATA.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h  |3 +++
 drivers/usb/mtu3/mtu3_host.c |   16 +---
 drivers/usb/mtu3/mtu3_plat.c |8 ++--
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index b26fffc..112723d 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -210,6 +210,8 @@ struct otg_switch_mtk {
  * host only, device only or dual-role mode
  * @u2_ports: number of usb2.0 host ports
  * @u3_ports: number of usb3.0 host ports
+ * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
+ * disable u3port0, bit1==1 to disable u3port1,... etc
  * @dbgfs_root: only used when supports manual dual-role switch via debugfs
  * @wakeup_en: it's true when supports remote wakeup in host mode
  * @wk_deb_p0: port0's wakeup debounce clock
@@ -232,6 +234,7 @@ struct ssusb_mtk {
bool is_host;
int u2_ports;
int u3_ports;
+   int u3p_dis_msk;
struct dentry *dbgfs_root;
/* usb wakeup for host mode */
bool wakeup_en;
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
index e42d308..4dd9508 100644
--- a/drivers/usb/mtu3/mtu3_host.c
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -151,6 +151,7 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
void __iomem *ibase = ssusb->ippc_base;
int num_u3p = ssusb->u3_ports;
int num_u2p = ssusb->u2_ports;
+   int u3_ports_disabed;
u32 check_clk;
u32 value;
int i;
@@ -158,8 +159,14 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
/* power on host ip */
mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
 
-   /* power on and enable all u3 ports */
+   /* power on and enable u3 ports except skipped ones */
+   u3_ports_disabed = 0;
for (i = 0; i < num_u3p; i++) {
+   if ((0x1 << i) & ssusb->u3p_dis_msk) {
+   u3_ports_disabed++;
+   continue;
+   }
+
value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
value |= SSUSB_U3_PORT_HOST_SEL;
@@ -175,7 +182,7 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
}
 
check_clk = SSUSB_XHCI_RST_B_STS;
-   if (num_u3p)
+   if (num_u3p > u3_ports_disabed)
check_clk = SSUSB_U3_MAC_RST_B_STS;
 
return ssusb_check_clocks(ssusb, check_clk);
@@ -190,8 +197,11 @@ int ssusb_host_disable(struct ssusb_mtk *ssusb, bool 
suspend)
int ret;
int i;
 
-   /* power down and disable all u3 ports */
+   /* power down and disable u3 ports except skipped ones */
for (i = 0; i < num_u3p; i++) {
+   if ((0x1 << i) & ssusb->u3p_dis_msk)
+   continue;
+
value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
value |= SSUSB_U3_PORT_PDN;
value |= suspend ? 0 : SSUSB_U3_PORT_DIS;
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 088e3e6..9edad30 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -276,6 +276,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
if (ret)
return ret;
 
+   /* optional property, ignore the error if it does not exist */
+   of_property_read_u32(node, "mediatek,u3p-dis-msk",
+&ssusb->u3p_dis_msk);
+
if (ssusb->dr_mode != USB_DR_MODE_OTG)
return 0;
 
@@ -304,8 +308,8 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
}
}
 
-   dev_info(dev, "dr_mode: %d, is_u3_dr: %d\n",
-   ssusb->dr_mode, otg_sx->is_u3_drd);
+   dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk:%x\n",
+   ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk);
 
return 0;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 3/3] usb: dwc3: core: Notify current USB mode to USB3 PHY as well

2017-09-27 Thread Manu Gautam
Driver currently notifies only USB2 PHY on USB mode change.
Extend this to USB3 PHY so that PHY drivers based on the
mode can release system resources - clocks, regulators etc.
Additionally Qualcomm QMP and QUSB2 PHY drivers need to
override VBUS signal in PHY wrapper in device mode as USB
VBUS line is not connected to PHYs. Also, remove NULL checks
for PHY when calling phy_set_mode as PHY ops already check this.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 23bb192..dabfa16 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -156,9 +156,8 @@ static void __dwc3_set_mode(struct work_struct *work)
} else {
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
-   if (dwc->usb2_generic_phy)
-   phy_set_mode(dwc->usb2_generic_phy, 
PHY_MODE_USB_HOST);
-
+   phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
+   phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
}
break;
case DWC3_GCTL_PRTCAP_DEVICE:
@@ -166,8 +165,8 @@ static void __dwc3_set_mode(struct work_struct *work)
 
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, false);
-   if (dwc->usb2_generic_phy)
-   phy_set_mode(dwc->usb2_generic_phy, 
PHY_MODE_USB_DEVICE);
+   phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE);
+   phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE);
 
ret = dwc3_gadget_init(dwc);
if (ret)
@@ -932,8 +931,8 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, false);
-   if (dwc->usb2_generic_phy)
-   phy_set_mode(dwc->usb2_generic_phy, 
PHY_MODE_USB_DEVICE);
+   phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE);
+   phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE);
 
ret = dwc3_gadget_init(dwc);
if (ret) {
@@ -948,8 +947,8 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
-   if (dwc->usb2_generic_phy)
-   phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
+   phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
+   phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
 
ret = dwc3_host_init(dwc);
if (ret) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 1/3] usb: dwc3: Don't reinitialize core during host bus-suspend/resume

2017-09-27 Thread Manu Gautam
Driver powers-off PHYs and reinitializes DWC3 core and gadget on
resume. While this works fine for gadget mode but in host
mode there is not re-initialization of host stack. Also, resetting
bus as part of bus_suspend/resume is not correct which could affect
(or disconnect) connected devices.
Fix this by not reinitializing core on suspend/resume in host mode
for HOST only and OTG/drd configurations.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c | 43 ---
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 03474d3..f75613f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -927,6 +927,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 
switch (dwc->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
+   dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
 
if (dwc->usb2_phy)
@@ -942,6 +943,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
}
break;
case USB_DR_MODE_HOST:
+   dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST;
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
 
if (dwc->usb2_phy)
@@ -1293,21 +1295,19 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
 {
unsigned long   flags;
 
-   switch (dwc->dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dwc->current_dr_role) {
+   case DWC3_GCTL_PRTCAP_DEVICE:
spin_lock_irqsave(&dwc->lock, flags);
dwc3_gadget_suspend(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
+   dwc3_core_exit(dwc);
break;
-   case USB_DR_MODE_HOST:
+   case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
}
 
-   dwc3_core_exit(dwc);
-
return 0;
 }
 
@@ -1316,18 +1316,17 @@ static int dwc3_resume_common(struct dwc3 *dwc)
unsigned long   flags;
int ret;
 
-   ret = dwc3_core_init(dwc);
-   if (ret)
-   return ret;
+   switch (dwc->current_dr_role) {
+   case DWC3_GCTL_PRTCAP_DEVICE:
+   ret = dwc3_core_init(dwc);
+   if (ret)
+   return ret;
 
-   switch (dwc->dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
spin_lock_irqsave(&dwc->lock, flags);
dwc3_gadget_resume(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
-   /* FALLTHROUGH */
-   case USB_DR_MODE_HOST:
+   break;
+   case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
@@ -1338,7 +1337,7 @@ static int dwc3_resume_common(struct dwc3 *dwc)
 
 static int dwc3_runtime_checks(struct dwc3 *dwc)
 {
-   switch (dwc->dr_mode) {
+   switch (dwc->current_dr_role) {
case USB_DR_MODE_PERIPHERAL:
case USB_DR_MODE_OTG:
if (dwc->connected)
@@ -1381,12 +1380,11 @@ static int dwc3_runtime_resume(struct device *dev)
if (ret)
return ret;
 
-   switch (dwc->dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dwc->current_dr_role) {
+   case DWC3_GCTL_PRTCAP_DEVICE:
dwc3_gadget_process_pending_events(dwc);
break;
-   case USB_DR_MODE_HOST:
+   case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
@@ -1402,13 +1400,12 @@ static int dwc3_runtime_idle(struct device *dev)
 {
struct dwc3 *dwc = dev_get_drvdata(dev);
 
-   switch (dwc->dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dwc->current_dr_role) {
+   case DWC3_GCTL_PRTCAP_DEVICE:
if (dwc3_runtime_checks(dwc))
return -EBUSY;
break;
-   case USB_DR_MODE_HOST:
+   case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 2/3] usb: dwc3: pci: Runtime resume child device from wq

2017-09-27 Thread Manu Gautam
Driver currently resumes and increments pm usage_count
of its child device (dwc3 main) from its runtime_resume
handler. This requires dwc3 runtime_resume to perform
pm_runtime_put to decrement the pm usage_count. However
runtime_put from dwc3 happens for non pci drivers
(e.g. dwc3-if-simple.c) as well which results in dwc3
pm usage_count becoming negative after couple of
runtime suspend resume iterations. Fix this by
performing runtime_get/put from dwc3-pci driver only
using workqueue.

Signed-off-by: Manu Gautam 
---
 drivers/usb/dwc3/core.c |  1 -
 drivers/usb/dwc3/dwc3-pci.c | 29 +++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f75613f..23bb192 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1391,7 +1391,6 @@ static int dwc3_runtime_resume(struct device *dev)
}
 
pm_runtime_mark_last_busy(dev);
-   pm_runtime_put(dev);
 
return 0;
 }
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 7e995df..74e4cd3 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -61,6 +62,7 @@ struct dwc3_pci {
guid_t guid;
 
unsigned int has_dsm_for_pm:1;
+   struct work_struct wakeup_work;
 };
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
@@ -174,6 +176,22 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
return 0;
 }
 
+#ifdef CONFIG_PM
+static void dwc3_pci_resume_work(struct work_struct *work)
+{
+   struct dwc3_pci *dwc = container_of(work, struct dwc3_pci, wakeup_work);
+   struct platform_device *dwc3 = dwc->dwc3;
+   int ret;
+
+   ret = pm_runtime_get_sync(&dwc3->dev);
+   if (ret)
+   return;
+
+   pm_runtime_mark_last_busy(&dwc3->dev);
+   pm_runtime_put_sync_autosuspend(&dwc3->dev);
+}
+#endif
+
 static int dwc3_pci_probe(struct pci_dev *pci,
const struct pci_device_id *id)
 {
@@ -232,6 +250,9 @@ static int dwc3_pci_probe(struct pci_dev *pci,
device_init_wakeup(dev, true);
pci_set_drvdata(pci, dwc);
pm_runtime_put(dev);
+#ifdef CONFIG_PM
+   INIT_WORK(&dwc->wakeup_work, dwc3_pci_resume_work);
+#endif
 
return 0;
 err:
@@ -243,6 +264,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
 {
struct dwc3_pci *dwc = pci_get_drvdata(pci);
 
+#ifdef CONFIG_PM
+   cancel_work_sync(&dwc->wakeup_work);
+#endif
device_init_wakeup(&pci->dev, false);
pm_runtime_get(&pci->dev);
platform_device_unregister(dwc->dwc3);
@@ -318,14 +342,15 @@ static int dwc3_pci_runtime_suspend(struct device *dev)
 static int dwc3_pci_runtime_resume(struct device *dev)
 {
struct dwc3_pci *dwc = dev_get_drvdata(dev);
-   struct platform_device  *dwc3 = dwc->dwc3;
int ret;
 
ret = dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
if (ret)
return ret;
 
-   return pm_runtime_get(&dwc3->dev);
+   queue_work(pm_wq, &dwc->wakeup_work);
+
+   return 0;
 }
 #endif /* CONFIG_PM */
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFT] lan78xx: FIX use-after-free in lan78xx_write_reg

2017-09-27 Thread Arvind Yadav
We are not releasing 'buf' memory on failure or disconnect a device.

Adding 'u8 *buf' as part of 'lan78xx_net' structure to make proper
handle for 'buf'.
Now releasing 'buf' memory on failure. It's allocate first in
lan78xx_probe() and it should be freed last in lan78xx_disconnect().

Signed-off-by: Arvind Yadav 
---
 drivers/net/usb/lan78xx.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index b99a7fb..e653982 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -402,6 +402,7 @@ struct lan78xx_net {
struct statstagestats;
 
struct irq_domain_data  domain_data;
+   u8 *buf;
 };
 
 /* define external phy id */
@@ -3470,6 +3471,9 @@ static void lan78xx_disconnect(struct usb_interface *intf)
 
usb_scuttle_anchored_urbs(&dev->deferred);
 
+   kfree(dev->buf);
+   dev->buf = NULL;
+
lan78xx_unbind(dev, intf);
 
usb_kill_urb(dev->urb_intr);
@@ -3520,7 +3524,6 @@ static int lan78xx_probe(struct usb_interface *intf,
int ret;
unsigned maxp;
unsigned period;
-   u8 *buf = NULL;
 
udev = interface_to_usbdev(intf);
udev = usb_get_dev(udev);
@@ -3588,16 +3591,15 @@ static int lan78xx_probe(struct usb_interface *intf,
period = dev->ep_intr->desc.bInterval;
 
maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0);
-   buf = kmalloc(maxp, GFP_KERNEL);
-   if (buf) {
+   dev->buf = kmalloc(maxp, GFP_KERNEL);
+   if (dev->buf) {
dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->urb_intr) {
ret = -ENOMEM;
-   kfree(buf);
goto out3;
} else {
usb_fill_int_urb(dev->urb_intr, dev->udev,
-dev->pipe_intr, buf, maxp,
+dev->pipe_intr, dev->buf, maxp,
 intr_complete, dev, period);
}
}
@@ -3626,6 +3628,8 @@ static int lan78xx_probe(struct usb_interface *intf,
return 0;
 
 out3:
+   kfree(dev->buf);
+   dev->buf = NULL;
lan78xx_unbind(dev, intf);
 out2:
free_netdev(netdev);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFT] lan78xx: FIX use-after-free in lan78xx_write_reg

2017-09-27 Thread Andrey Konovalov
On Wed, Sep 27, 2017 at 1:18 PM, Arvind Yadav  wrote:
> We are not releasing 'buf' memory on failure or disconnect a device.
>
> Adding 'u8 *buf' as part of 'lan78xx_net' structure to make proper
> handle for 'buf'.
> Now releasing 'buf' memory on failure. It's allocate first in
> lan78xx_probe() and it should be freed last in lan78xx_disconnect().
>
> Signed-off-by: Arvind Yadav 

Hi Arvind,

I've tried your patch and still see a crash.

Thanks!

lan78xx 1-1:90.0 (unnamed net_device) (uninitialized): can't register MDIO bus
lan78xx: probe of 1-1:90.0 failed with error -5
usb 1-1: USB disconnect, device number 2
==
BUG: KASAN: use-after-free in lan78xx_write_reg.isra.21+0x1a8/0x1b0
Read of size 8 at addr 880063dfac40 by task kworker/1:1/1152

CPU: 1 PID: 1152 Comm: kworker/1:1 Not tainted
4.14.0-rc2-42660-g24b7bd59eec0-dirty #274
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: events lan78xx_deferred_multicast_write
Call Trace:
 __dump_stack lib/dump_stack.c:16
 dump_stack+0x292/0x395 lib/dump_stack.c:52
 print_address_description+0x78/0x280 mm/kasan/report.c:252
 kasan_report_error mm/kasan/report.c:351
 kasan_report+0x23d/0x350 mm/kasan/report.c:409
 __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:430
 lan78xx_write_reg.isra.21+0x1a8/0x1b0 drivers/net/usb/lan78xx.c:459
 lan78xx_deferred_multicast_write+0x10d/0x1a0 drivers/net/usb/lan78xx.c:1043
 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
 worker_thread+0x221/0x1850 kernel/workqueue.c:2253
 kthread+0x3a1/0x470 kernel/kthread.c:231
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431

Allocated by task 1848:
 save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
 set_track mm/kasan/kasan.c:459
 kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
 __kmalloc_node+0x192/0x480 mm/slub.c:3827
 kmalloc_node ./include/linux/slab.h:535
 kvmalloc_node+0x69/0xd0 mm/util.c:397
 kvmalloc ./include/linux/mm.h:529
 kvzalloc ./include/linux/mm.h:537
 alloc_netdev_mqs+0x173/0xea0 net/core/dev.c:8023
 alloc_etherdev_mqs+0x38/0x40 net/ethernet/eth.c:391
 lan78xx_probe+0x13a/0x3020 drivers/net/usb/lan78xx.c:3545
 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
 hub_port_connect drivers/usb/core/hub.c:4903
 hub_port_connect_change drivers/usb/core/hub.c:5009
 port_event drivers/usb/core/hub.c:5115
 hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
 worker_thread+0x221/0x1850 kernel/workqueue.c:2253
 kthread+0x3a1/0x470 kernel/kthread.c:231
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431

Freed by task 1848:
 save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
 set_track mm/kasan/kasan.c:459
 kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
 slab_free_hook mm/slub.c:1390
 slab_free_freelist_hook mm/slub.c:1412
 slab_free mm/slub.c:2988
 kfree+0xf6/0x2f0 mm/slub.c:3919
 kvfree+0x3b/0x60 mm/util.c:416
 netdev_freemem net/core/dev.c:7975
 free_netdev+0x304/0x3c0 net/core/dev.c:8137
 lan78xx_probe+0x21a4/0x3020 drivers/net/usb/lan78xx.c:3649
 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa0

Re: [RFT] lan78xx: FIX use-after-free in lan78xx_write_reg

2017-09-27 Thread Andrey Konovalov
On Wed, Sep 27, 2017 at 2:06 PM, Andrey Konovalov  wrote:
> On Wed, Sep 27, 2017 at 1:18 PM, Arvind Yadav  
> wrote:
>> We are not releasing 'buf' memory on failure or disconnect a device.
>>
>> Adding 'u8 *buf' as part of 'lan78xx_net' structure to make proper
>> handle for 'buf'.
>> Now releasing 'buf' memory on failure. It's allocate first in
>> lan78xx_probe() and it should be freed last in lan78xx_disconnect().
>>
>> Signed-off-by: Arvind Yadav 
>
> Hi Arvind,
>
> I've tried your patch and still see a crash.
>
> Thanks!
>
> lan78xx 1-1:90.0 (unnamed net_device) (uninitialized): can't register MDIO bus
> lan78xx: probe of 1-1:90.0 failed with error -5
> usb 1-1: USB disconnect, device number 2
> ==
> BUG: KASAN: use-after-free in lan78xx_write_reg.isra.21+0x1a8/0x1b0
> Read of size 8 at addr 880063dfac40 by task kworker/1:1/1152

It seems that the bug is caused by the fact that the
lan78xx_deferred_multicast_write() work is not shut down on
lan78xx_probe() failure.

>
> CPU: 1 PID: 1152 Comm: kworker/1:1 Not tainted
> 4.14.0-rc2-42660-g24b7bd59eec0-dirty #274
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Workqueue: events lan78xx_deferred_multicast_write
> Call Trace:
>  __dump_stack lib/dump_stack.c:16
>  dump_stack+0x292/0x395 lib/dump_stack.c:52
>  print_address_description+0x78/0x280 mm/kasan/report.c:252
>  kasan_report_error mm/kasan/report.c:351
>  kasan_report+0x23d/0x350 mm/kasan/report.c:409
>  __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:430
>  lan78xx_write_reg.isra.21+0x1a8/0x1b0 drivers/net/usb/lan78xx.c:459
>  lan78xx_deferred_multicast_write+0x10d/0x1a0 drivers/net/usb/lan78xx.c:1043
>  process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
>  worker_thread+0x221/0x1850 kernel/workqueue.c:2253
>  kthread+0x3a1/0x470 kernel/kthread.c:231
>  ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
>
> Allocated by task 1848:
>  save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x43/0xd0 mm/kasan/kasan.c:447
>  set_track mm/kasan/kasan.c:459
>  kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
>  __kmalloc_node+0x192/0x480 mm/slub.c:3827
>  kmalloc_node ./include/linux/slab.h:535
>  kvmalloc_node+0x69/0xd0 mm/util.c:397
>  kvmalloc ./include/linux/mm.h:529
>  kvzalloc ./include/linux/mm.h:537
>  alloc_netdev_mqs+0x173/0xea0 net/core/dev.c:8023
>  alloc_etherdev_mqs+0x38/0x40 net/ethernet/eth.c:391
>  lan78xx_probe+0x13a/0x3020 drivers/net/usb/lan78xx.c:3545
>  usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
>  really_probe drivers/base/dd.c:413
>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>  usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
>  generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
>  usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
>  really_probe drivers/base/dd.c:413
>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>  usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
>  hub_port_connect drivers/usb/core/hub.c:4903
>  hub_port_connect_change drivers/usb/core/hub.c:5009
>  port_event drivers/usb/core/hub.c:5115
>  hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
>  process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
>  worker_thread+0x221/0x1850 kernel/workqueue.c:2253
>  kthread+0x3a1/0x470 kernel/kthread.c:231
>  ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
>
> Freed by task 1848:
>  save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
>  save_stack+0x43/0xd0 mm/kasan/kasan.c:447
>  set_track mm/kasan/kasan.c:459
>  kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
>  slab_free_hook mm/slub.c:1390
>  slab_free_freelist_hook mm/slub.c:1412
>  slab_free mm/slub.c:2988
>  kfree+0xf6/0x2f0 mm/slub.c:3919
>  kvfree+0x3b/0x60 mm/util.c:416
>  netdev_freemem net/core/dev.c:7975
>  free_netdev+0x304/0x3c0 net/core/dev.c:8137
>  lan78xx_probe+0x21a4/0x3020 drivers/net/usb/lan78xx.c:3649
>  usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
>  really_probe drivers/base/dd.c:413
>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>  device_initi

Re: Mouse freezes on button depression

2017-09-27 Thread Christian Bullow

apologies, trying to sort out the SPF errors I've been getting


On 25/09/17 22:22, Oliver Neukum wrote:

Am Sonntag, den 24.09.2017, 13:14 +1000 schrieb Christian Bullow:

Upon depressing the DIP switch or forward/backward buttons, the mouse
freezes and is unresponsive. The only way to fix this is my unplugging
it, and putting it into a /different/ USB port.

I am happy to be guided as to how to inform you of the issue and/or
capture the messaging from the mouse buttons.

*dmesg output*

[ 1386.760402] usb 1-1.1: USB disconnect, device number 3
[ 1389.758884] usb 1-1.1: new full-speed USB device number 4 using ehci-pci
[ 1389.872812] usb 1-1.1: New USB device found, idVendor=1044,
idProduct=7a13
[ 1389.872816] usb 1-1.1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[ 1389.872818] usb 1-1.1: Product: MSP430-USB Mouse
[ 1389.872820] usb 1-1.1: Manufacturer: Texas Instruments
[ 1389.872822] usb 1-1.1: SerialNumber: 8C2F0C5132000C00
[ 1389.903323] input: Texas Instruments MSP430-USB Mouse as
/devices/pci:00/:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:1044:7A13.0007/input/input27
[ 1389.963586] hid-generic 0003:1044:7A13.0007: input,hidraw0: USB HID
v1.01 Keyboard [Texas Instruments MSP430-USB Mouse] on
usb-:00:1a.0-1.1/input0
[ 1389.966651] input: Texas Instruments MSP430-USB Mouse as
/devices/pci:00/:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.1/0003:1044:7A13.0008/input/input28
[ 1390.027363] hid-generic 0003:1044:7A13.0008: input,hidraw2: USB HID
v1.01 Mouse [Texas Instruments MSP430-USB Mouse] on
usb-:00:1a.0-1.1/input1
[ 1390.031052] input: Texas Instruments MSP430-USB Mouse as
/devices/pci:00/:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.2/0003:1044:7A13.0009/input/input29
[ 1390.091874] hid-generic 0003:1044:7A13.0009: input,hiddev0,hidraw3:
USB HID v1.01 Mouse [Texas Instruments MSP430-USB Mouse] on
usb-:00:1a.0-1.1/input2
[ 1400.113061] hid-generic 0003:1044:7A13.000A: timeout initializing reports
[ 1400.113386] hid-generic 0003:1044:7A13.000A: hiddev0,hidraw5: USB HID
v1.01 Device [Texas Instruments MSP430-USB Mouse] on
usb-:00:1a.0-1.1/input3


Hi,

this dmesg as such is pretty uninformative. Is that what you get as you
plug in the mouse or as you push the button? If the latter, we will
need a usbmon trace.

Regards
Oliver



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] HID: usbhid: fix out-of-bounds bug

2017-09-27 Thread Alan Stern
On Wed, 27 Sep 2017, Michel Hermier wrote:

> Le 27 sept. 2017 07:42, "Alan Stern"  a écrit :

> > -   for (n = 0; n < hdesc->bNumDescriptors; n++)
> > +   num_descriptors = min_t(int, hdesc->bNumDescriptors,
> > +   (hdesc->bLength - 6) / 3);
> > +   for (n = 0; n < num_descriptors; n++)
> > if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
> > rsize = le16_to_cpu(hdesc->desc[n].
> wDescriptorLength);
> 
> Yes, this is a lot better.
> 
> 
> Is it possible to explicit the magic number 6 and 3 in the code. Currently,
> it looks like it comes from no where.

Yes, it is possible.  The 6 is equal to

offsetof(struct hid_descriptor, desc)

and the 3 is equal to

sizeof(struct hid_class_descriptor)

(at least, I think it is -- the structure is marked as packed so its 
size should be 3).

In this case I found the numbers to be more readable, but other people 
may have different opinions.

> I'm also wondering if this change will not affect some devices in the wild,
> by rejecting hid descriptors with num descriptors == 0 ?

It's possible, but I doubt it.  If such devices do exist, they should
never have worked in the first place.  Certainly they would generate
warnings or errors during enumeration because of their invalid
descriptors.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH resend 09/12] usb: typec: tcpm: only drives the connected cc line when attached

2017-09-27 Thread kbuild test robot
Hi Li,

[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v4.14-rc2 next-20170927]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Li-Jun/staging-typec-tcpci-move-out-of-staging/20170927-190852
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

Note: the 
linux-review/Li-Jun/staging-typec-tcpci-move-out-of-staging/20170927-190852 
HEAD 9e1467d3603f3cee8f039d52010dfb8d33e2b29c builds fine.
  It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/staging/typec/tcpci.c: In function 'tcpci_probe':
>> drivers/staging/typec/tcpci.c:574:21: error: assignment from incompatible 
>> pointer type [-Werror=incompatible-pointer-types]
 tcpci->tcpc.set_cc = tcpci_set_cc;
^
   cc1: some warnings being treated as errors

vim +574 drivers/staging/typec/tcpci.c

74e656d6 Guenter Roeck 2017-04-27  553  
74e656d6 Guenter Roeck 2017-04-27  554  static int tcpci_probe(struct 
i2c_client *client,
74e656d6 Guenter Roeck 2017-04-27  555 const struct 
i2c_device_id *i2c_id)
74e656d6 Guenter Roeck 2017-04-27  556  {
74e656d6 Guenter Roeck 2017-04-27  557  struct tcpci *tcpci;
74e656d6 Guenter Roeck 2017-04-27  558  int err;
74e656d6 Guenter Roeck 2017-04-27  559  
74e656d6 Guenter Roeck 2017-04-27  560  tcpci = 
devm_kzalloc(&client->dev, sizeof(*tcpci), GFP_KERNEL);
74e656d6 Guenter Roeck 2017-04-27  561  if (!tcpci)
74e656d6 Guenter Roeck 2017-04-27  562  return -ENOMEM;
74e656d6 Guenter Roeck 2017-04-27  563  
74e656d6 Guenter Roeck 2017-04-27  564  tcpci->client = client;
74e656d6 Guenter Roeck 2017-04-27  565  tcpci->dev = &client->dev;
74e656d6 Guenter Roeck 2017-04-27  566  i2c_set_clientdata(client, 
tcpci);
74e656d6 Guenter Roeck 2017-04-27  567  tcpci->regmap = 
devm_regmap_init_i2c(client, &tcpci_regmap_config);
74e656d6 Guenter Roeck 2017-04-27  568  if (IS_ERR(tcpci->regmap))
74e656d6 Guenter Roeck 2017-04-27  569  return 
PTR_ERR(tcpci->regmap);
74e656d6 Guenter Roeck 2017-04-27  570  
74e656d6 Guenter Roeck 2017-04-27  571  tcpci->tcpc.init = tcpci_init;
74e656d6 Guenter Roeck 2017-04-27  572  tcpci->tcpc.get_vbus = 
tcpci_get_vbus;
74e656d6 Guenter Roeck 2017-04-27  573  tcpci->tcpc.set_vbus = 
tcpci_set_vbus;
74e656d6 Guenter Roeck 2017-04-27 @574  tcpci->tcpc.set_cc = 
tcpci_set_cc;
74e656d6 Guenter Roeck 2017-04-27  575  tcpci->tcpc.get_cc = 
tcpci_get_cc;
74e656d6 Guenter Roeck 2017-04-27  576  tcpci->tcpc.set_polarity = 
tcpci_set_polarity;
74e656d6 Guenter Roeck 2017-04-27  577  tcpci->tcpc.set_vconn = 
tcpci_set_vconn;
74e656d6 Guenter Roeck 2017-04-27  578  tcpci->tcpc.start_drp_toggling 
= tcpci_start_drp_toggling;
74e656d6 Guenter Roeck 2017-04-27  579  
74e656d6 Guenter Roeck 2017-04-27  580  tcpci->tcpc.set_pd_rx = 
tcpci_set_pd_rx;
74e656d6 Guenter Roeck 2017-04-27  581  tcpci->tcpc.set_roles = 
tcpci_set_roles;
74e656d6 Guenter Roeck 2017-04-27  582  tcpci->tcpc.pd_transmit = 
tcpci_pd_transmit;
74e656d6 Guenter Roeck 2017-04-27  583  
74e656d6 Guenter Roeck 2017-04-27  584  err = tcpci_parse_config(tcpci);
74e656d6 Guenter Roeck 2017-04-27  585  if (err < 0)
74e656d6 Guenter Roeck 2017-04-27  586  return err;
74e656d6 Guenter Roeck 2017-04-27  587  
74e656d6 Guenter Roeck 2017-04-27  588  /* Disable chip interrupts */
74e656d6 Guenter Roeck 2017-04-27  589  tcpci_write16(tcpci, 
TCPC_ALERT_MASK, 0);
74e656d6 Guenter Roeck 2017-04-27  590  
d94372b5 Li Jun2017-09-26  591  tcpci->port = 
tcpm_register_port(tcpci->dev, &tcpci->tcpc);
d94372b5 Li Jun2017-09-26  592  if (IS_ERR(tcpci->port))
d94372b5 Li Jun2017-09-26  593  return 
PTR_ERR(tcpci->port);
d94372b5 Li Jun2017-09-26  594  
d94372b5 Li Jun2017-09-26  595  return 
devm_request_threaded_irq(tcpci->dev, client->irq, NULL,
74e656d6 Guenter Roeck 2017-04-27  596  
tcpci_irq,
74e656d6 Guenter Roeck 2017-04-27  597  
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
74e656d6 Guenter Roeck 2017-04-27  598  
dev_name(tcpci->dev), tcpci);
74e656d6 Guenter Roeck 2017-04-27  599  }
74e656d6 Guenter Roeck 2017-04-27  600  

:: The code at line 574 was first introduced by commit
:: 74e656d6b0551999194b5ab1e45ff8b1e82b898e staging: typec: Type-C Port 
Con

usb/misc/rio500: double-free or invalid-free in disconnect_rio

2017-09-27 Thread Andrey Konovalov
Hi!

I've got the following report while fuzzing the kernel with syzkaller.

On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).

gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 2 using dummy_hcd
gadgetfs: connected
gadgetfs: disconnected
gadgetfs: connected
usb 1-1: config 3 has an invalid interface number: 220 but max is 0
usb 1-1: config 3 has an invalid interface number: 199 but max is 0
usb 1-1: config 3 has 2 interfaces, different from the descriptor's value: 1
usb 1-1: config 3 has no interface number 0
usb 1-1: config 3 has no interface number 1
usb 1-1: too many endpoints for config 3 interface 199 altsetting 74:
151, using maximum allowed: 30
usb 1-1: config 3 interface 199 altsetting 74 has 0 endpoint
descriptors, different from the interface d
escriptor's value: 151
usb 1-1: config 3 interface 199 has no altsetting 0
usb 1-1: New USB device found, idVendor=0841, idProduct=0001
usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
gadgetfs: configuration #3
rio500 1-1:3.220: USB Rio found at address 2
rio500 1-1:3.199: USB Rio found at address 2
gadgetfs: disconnected
usb 1-1: USB disconnect, device number 2
rio500 1-1:3.220: USB Rio disconnected.
==
BUG: KASAN: double-free or invalid-free in disconnect_rio+0xef/0x200

CPU: 0 PID: 24 Comm: kworker/0:1 Not tainted 4.14.0-rc2-42660-g24b7bd59eec0 #277
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
 __dump_stack lib/dump_stack.c:16
 dump_stack+0x292/0x395 lib/dump_stack.c:52
 print_address_description+0x78/0x280 mm/kasan/report.c:252
 kasan_report_double_free+0x5a/0x80 mm/kasan/report.c:333
 kasan_slab_free+0xa4/0xc0 mm/kasan/kasan.c:514
 slab_free_hook mm/slub.c:1390
 slab_free_freelist_hook mm/slub.c:1412
 slab_free mm/slub.c:2988
 kfree+0xf6/0x2f0 mm/slub.c:3919
 disconnect_rio+0xef/0x200 drivers/usb/misc/rio500.c:519
 usb_unbind_interface+0x21c/0xa90 drivers/usb/core/driver.c:423
 __device_release_driver drivers/base/dd.c:861
 device_release_driver_internal+0x4f4/0x5c0 drivers/base/dd.c:893
 device_release_driver+0x1e/0x30 drivers/base/dd.c:918
 bus_remove_device+0x2f4/0x4b0 drivers/base/bus.c:565
 device_del+0x5c4/0xab0 drivers/base/core.c:1985
 usb_disable_device+0x1e9/0x680 drivers/usb/core/message.c:1170
 usb_disconnect+0x260/0x7a0 drivers/usb/core/hub.c:2124
 hub_port_connect drivers/usb/core/hub.c:4754
 hub_port_connect_change drivers/usb/core/hub.c:5009
 port_event drivers/usb/core/hub.c:5115
 hub_event+0x1318/0x3740 drivers/usb/core/hub.c:5195
 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
 worker_thread+0x221/0x1850 kernel/workqueue.c:2253
 kthread+0x3a1/0x470 kernel/kthread.c:231
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431

Allocated by task 24:
 save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
 set_track mm/kasan/kasan.c:459
 kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
 kmem_cache_alloc_trace+0x11e/0x2d0 mm/slub.c:2772
 kmalloc ./include/linux/slab.h:493
 probe_rio+0x100/0x230 drivers/usb/misc/rio500.c:484
 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
 hub_port_connect drivers/usb/core/hub.c:4903
 hub_port_connect_change drivers/usb/core/hub.c:5009
 port_event drivers/usb/core/hub.c:5115
 hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
 worker_thread+0x221/0x1850 kernel/workqueue.c:2253
 kthread+0x3a1/0x470 kernel/kthread.c:231
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431

Freed by task 24:
 save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
 set_track mm/kasan/kasan.c:459
 kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
 slab_free_hook mm/slub.c:1390
 slab_free_freelist_hook mm/slub.c:1412
 slab_free m

usb/serial: use-after-free in usb_serial_disconnect/__lock_acquire

2017-09-27 Thread Andrey Konovalov
Hi!

I've got the following report while fuzzing the kernel with syzkaller.

On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).

gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 2 using dummy_hcd
gadgetfs: connected
gadgetfs: disconnected
gadgetfs: connected
usb 1-1: config 4 has an invalid interface number: 1 but max is 0
usb 1-1: config 4 has an invalid interface number: 153 but max is 0
usb 1-1: config 4 has 2 interfaces, different from the descriptor's value: 1
usb 1-1: config 4 has no interface number 0
usb 1-1: config 4 interface 1 altsetting 255 has an invalid endpoint
with address 0x0, skipping
usb 1-1: config 4 interface 1 altsetting 255 has an invalid endpoint
with address 0xFF, skipping
usb 1-1: config 4 interface 1 altsetting 255 has an invalid endpoint
with address 0x56, skipping
usb 1-1: too many endpoints for config 4 interface 153 altsetting 67:
174, using maximum allowed: 30
usb 1-1: config 4 interface 153 altsetting 67 has 0 endpoint
descriptors, different from the interface d
escriptor's value: 174
usb 1-1: config 4 interface 1 has no altsetting 0
usb 1-1: config 4 interface 153 has no altsetting 0
usb 1-1: New USB device found, idVendor=1199, idProduct=6832
usb 1-1: New USB device strings: Mfr=4, Product=20, SerialNumber=3
usb 1-1: Product: a
usb 1-1: Manufacturer: a
usb 1-1: SerialNumber: a
gadgetfs: configuration #4
sierra 1-1:4.1: Sierra USB modem converter detected
usb 1-1: Sierra USB modem converter now attached to ttyUSB0
sierra 1-1:4.153: Sierra USB modem converter detected
gadgetfs: disconnected
usb 1-1: USB disconnect, device number 2
sierra ttyUSB0: Sierra USB modem converter now disconnected from ttyUSB0
sierra 1-1:4.1: device disconnected
==
BUG: KASAN: use-after-free in __lock_acquire+0x4504/0x4550
Read of size 8 at addr 8800674df790 by task kworker/1:2/1846

CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
4.14.0-rc2-42660-g24b7bd59eec0 #277
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
 __dump_stack lib/dump_stack.c:16
 dump_stack+0x292/0x395 lib/dump_stack.c:52
 print_address_description+0x78/0x280 mm/kasan/report.c:252
 kasan_report_error mm/kasan/report.c:351
 kasan_report+0x23d/0x350 mm/kasan/report.c:409
 __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:430
 __lock_acquire+0x4504/0x4550 kernel/locking/lockdep.c:3376
 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002
 __mutex_lock_common kernel/locking/mutex.c:756
 __mutex_lock+0x18e/0x1a50 kernel/locking/mutex.c:893
 mutex_lock_nested+0x1b/0x20 kernel/locking/mutex.c:908
 usb_serial_disconnect+0x69/0x2e0 drivers/usb/serial/usb-serial.c:1084
 usb_unbind_interface+0x21c/0xa90 drivers/usb/core/driver.c:423
 __device_release_driver drivers/base/dd.c:861
 device_release_driver_internal+0x4f4/0x5c0 drivers/base/dd.c:893
 device_release_driver+0x1e/0x30 drivers/base/dd.c:918
 bus_remove_device+0x2f4/0x4b0 drivers/base/bus.c:565
 device_del+0x5c4/0xab0 drivers/base/core.c:1985
 usb_disable_device+0x1e9/0x680 drivers/usb/core/message.c:1170
 usb_disconnect+0x260/0x7a0 drivers/usb/core/hub.c:2124
 hub_port_connect drivers/usb/core/hub.c:4754
 hub_port_connect_change drivers/usb/core/hub.c:5009
 port_event drivers/usb/core/hub.c:5115
 hub_event+0x1318/0x3740 drivers/usb/core/hub.c:5195
 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
 worker_thread+0x221/0x1850 kernel/workqueue.c:2253
 kthread+0x3a1/0x470 kernel/kthread.c:231
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431

Allocated by task 1846:
 save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
 set_track mm/kasan/kasan.c:459
 kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
 kmem_cache_alloc_trace+0x11e/0x2d0 mm/slub.c:2772
 kmalloc ./include/linux/slab.h:493
 kzalloc ./include/linux/slab.h:666
 create_serial drivers/usb/serial/usb-serial.c:605
 usb_serial_probe+0x36f/0x4090 drivers/usb/serial/usb-serial.c:892
 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+

Re: [PATCH v3 4/8] mtd: nand: atmel: Avoid ECC errors when leaving backup mode

2017-09-27 Thread Boris Brezillon
On Wed, 27 Sep 2017 10:35:51 +0200
Romain Izard  wrote:

> During backup mode, the contents of all registers will be cleared as the
> SoC will be completely powered down. For a product that boots on NAND
> Flash memory, the bootloader will obviously use the related controller
> to read the Flash and correct any detected error in the memory, before
> handling back control to the kernel's resuming entry point.
> 
> But it does not clean the NAND controller registers after use and on its
> side the kernel driver expects the error locator to be powered down and
> in a clean state. Add a resume hook for the PMECC error locator, and
> reset its registers.
> 
> Signed-off-by: Romain Izard 
> ---
> Change in v3:
> * keep the PMECC disabled when not in use, and use atmel_pmecc_resume to
>   reset the controller after the bootloader has left it enabled.
> 
>  drivers/mtd/nand/atmel/nand-controller.c |  3 +++
>  drivers/mtd/nand/atmel/pmecc.c   | 22 ++
>  drivers/mtd/nand/atmel/pmecc.h   |  1 +
>  3 files changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mtd/nand/atmel/nand-controller.c 
> b/drivers/mtd/nand/atmel/nand-controller.c
> index f25eca79f4e5..86c2199380c2 100644
> --- a/drivers/mtd/nand/atmel/nand-controller.c
> +++ b/drivers/mtd/nand/atmel/nand-controller.c
> @@ -2530,6 +2530,9 @@ static __maybe_unused int 
> atmel_nand_controller_resume(struct device *dev)
>   struct atmel_nand_controller *nc = dev_get_drvdata(dev);
>   struct atmel_nand *nand;
>  
> + if (nand->pmecc)
> + atmel_pmecc_resume(nand->pmecc);
> +

nand is used uninitialized here, and atmel_pmecc_resume() should be
passed a atmel_pmecc object not a atmel_pmecc_user.

if (nc->pmecc)
atmel_pmecc_resume(nc->pmecc);

>   list_for_each_entry(nand, &nc->chips, node) {
>   int i;
>  
> diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
> index 146af8218314..ff09c0f25dd4 100644
> --- a/drivers/mtd/nand/atmel/pmecc.c
> +++ b/drivers/mtd/nand/atmel/pmecc.c
> @@ -765,6 +765,12 @@ void atmel_pmecc_get_generated_eccbytes(struct 
> atmel_pmecc_user *user,
>  }
>  EXPORT_SYMBOL_GPL(atmel_pmecc_get_generated_eccbytes);
>  
> +void atmel_pmecc_reset(struct atmel_pmecc *pmecc)
> +{
> + writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
> + writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
> +}

It's not used outside of this file, so it should have a static
specifier. Anyway, I wonder why you don't expose atmel_pmecc_reset()
directly instead of creating this atmel_pmecc_resume() wrapper.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 4/8] mtd: nand: atmel: Avoid ECC errors when leaving backup mode

2017-09-27 Thread Romain Izard
2017-09-27 17:08 GMT+02:00 Boris Brezillon :
> On Wed, 27 Sep 2017 10:35:51 +0200
> Romain Izard  wrote:
>
>> During backup mode, the contents of all registers will be cleared as the
>> SoC will be completely powered down. For a product that boots on NAND
>> Flash memory, the bootloader will obviously use the related controller
>> to read the Flash and correct any detected error in the memory, before
>> handling back control to the kernel's resuming entry point.
>>
>> But it does not clean the NAND controller registers after use and on its
>> side the kernel driver expects the error locator to be powered down and
>> in a clean state. Add a resume hook for the PMECC error locator, and
>> reset its registers.
>>
>> Signed-off-by: Romain Izard 
>> ---
>> Change in v3:
>> * keep the PMECC disabled when not in use, and use atmel_pmecc_resume to
>>   reset the controller after the bootloader has left it enabled.
>>
>>  drivers/mtd/nand/atmel/nand-controller.c |  3 +++
>>  drivers/mtd/nand/atmel/pmecc.c   | 22 ++
>>  drivers/mtd/nand/atmel/pmecc.h   |  1 +
>>  3 files changed, 18 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/atmel/nand-controller.c 
>> b/drivers/mtd/nand/atmel/nand-controller.c
>> index f25eca79f4e5..86c2199380c2 100644
>> --- a/drivers/mtd/nand/atmel/nand-controller.c
>> +++ b/drivers/mtd/nand/atmel/nand-controller.c
>> @@ -2530,6 +2530,9 @@ static __maybe_unused int 
>> atmel_nand_controller_resume(struct device *dev)
>>   struct atmel_nand_controller *nc = dev_get_drvdata(dev);
>>   struct atmel_nand *nand;
>>
>> + if (nand->pmecc)
>> + atmel_pmecc_resume(nand->pmecc);
>> +
>
> nand is used uninitialized here, and atmel_pmecc_resume() should be
> passed a atmel_pmecc object not a atmel_pmecc_user.
>
> if (nc->pmecc)
> atmel_pmecc_resume(nc->pmecc);
>
And yet I thought I correctly tested this code...

:(

>>   list_for_each_entry(nand, &nc->chips, node) {
>>   int i;
>>
>> diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
>> index 146af8218314..ff09c0f25dd4 100644
>> --- a/drivers/mtd/nand/atmel/pmecc.c
>> +++ b/drivers/mtd/nand/atmel/pmecc.c
>> @@ -765,6 +765,12 @@ void atmel_pmecc_get_generated_eccbytes(struct 
>> atmel_pmecc_user *user,
>>  }
>>  EXPORT_SYMBOL_GPL(atmel_pmecc_get_generated_eccbytes);
>>
>> +void atmel_pmecc_reset(struct atmel_pmecc *pmecc)
>> +{
>> + writel(PMECC_CTRL_RST, pmecc->regs.base + ATMEL_PMECC_CTRL);
>> + writel(PMECC_CTRL_DISABLE, pmecc->regs.base + ATMEL_PMECC_CTRL);
>> +}
>
> It's not used outside of this file, so it should have a static
> specifier. Anyway, I wonder why you don't expose atmel_pmecc_reset()
> directly instead of creating this atmel_pmecc_resume() wrapper.

I will fix this...

-- 
Romain Izard
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Continuous reset of USB device with new USB chip "[AMD] Device 43b9" / AMD X370 chipset

2017-09-27 Thread Andreas Hartmann
On 09/17/2017 at 09:32 AM, Andreas Hartmann wrote:
> Hello again!
> 
> I can add now some more information about this problem:
> 
> - I can see it w/ Fedora 26 boot medium, too.
> - I added an usb wireshark trace - hopefully this can be used to detect the 
> problem.

It turned out, that the device is broken. It doesn't work anymore with
another old USB chipset, too.


Sorry for the noise,
regards,
Andreas
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] r8152: add Linksys USB3GIGV1 id

2017-09-27 Thread Grant Grundler
On Wed, Sep 27, 2017 at 12:15 AM, Oliver Neukum  wrote:
> Am Dienstag, den 26.09.2017, 08:19 -0700 schrieb Doug Anderson:
>>
>> I know that for at least some of the adapters in the CDC Ethernet
>> blacklist it was claimed that the CDC Ethernet support in the adapter
>> was kinda broken anyway so the blacklist made sense.  ...but for the
>> Linksys Gigabit adapter the CDC Ethernet driver seems to work OK, it's
>> just not quite as full featured / efficient as the R8152 driver.
>>
>> Is that not a concern?  I guess you could tell people in this
>> situation that they simply need to enable the R8152 driver to get
>> continued support for their Ethernet adapter?
>
> Hi,
>
> yes, it is a valid concern. An #ifdef will be needed.

Good idea - I will post V3 shortly.

I'm assuming you mean to add #ifdef CONFIG_USB_RTL8152 around the
blacklist entry in cdc_ether driver.

cheers,
grant
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write to a UVC device

2017-09-27 Thread Rail Shafigulin
On Mon, Sep 25, 2017 at 7:29 PM, Jaejoong Kim  wrote:
> Hi,
>
> The below link will help.
>
> http://git.ideasonboard.org/uvc-gadget.git
> https://lwn.net/Articles/203924/
>
> Jaejoong
>

Thanks for the reply.  But I need some clarification. Usually when a
character device (which as far as I understand what UVC is) is read or
written, all the user does is open, read/write, close. The details are
taken care by the driver. Am I correct in understanding that this is
not a way to do it with UVC, i.e. the sequence of steps is different
(open, some different steps, close) ?

-- 
Rail Shafigulin
Software Engineer
Esencia Technologies

-- 




*ESENCIA TECHNOLOGIES, INC.*3945 Freedom Circle, Suite #360,
Santa Clara CA 95054


Phone: +1 408 736 8284 Fax: +1 408 519 3475 
http://www.esenciatech.com | http://www.lnttechservices.com


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: gadget: f_uvc: make uvc_v4l2_fops const

2017-09-27 Thread Bhumika Goyal
Make this const as it is only stored in the const field of a structure
video_device in the file referencing it. Make the declaration const too.

Done using Coccinelle.

Signed-off-by: Bhumika Goyal 
---
 drivers/usb/gadget/function/uvc_v4l2.c | 2 +-
 drivers/usb/gadget/function/uvc_v4l2.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/function/uvc_v4l2.c 
b/drivers/usb/gadget/function/uvc_v4l2.c
index 3e22b45..6612402 100644
--- a/drivers/usb/gadget/function/uvc_v4l2.c
+++ b/drivers/usb/gadget/function/uvc_v4l2.c
@@ -354,7 +354,7 @@ static unsigned long uvcg_v4l2_get_unmapped_area(struct 
file *file,
 }
 #endif
 
-struct v4l2_file_operations uvc_v4l2_fops = {
+const struct v4l2_file_operations uvc_v4l2_fops = {
.owner  = THIS_MODULE,
.open   = uvc_v4l2_open,
.release= uvc_v4l2_release,
diff --git a/drivers/usb/gadget/function/uvc_v4l2.h 
b/drivers/usb/gadget/function/uvc_v4l2.h
index 2683b92..ad6ca06 100644
--- a/drivers/usb/gadget/function/uvc_v4l2.h
+++ b/drivers/usb/gadget/function/uvc_v4l2.h
@@ -17,6 +17,6 @@
 #define __UVC_V4L2_H__
 
 extern const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops;
-extern struct v4l2_file_operations uvc_v4l2_fops;
+extern const struct v4l2_file_operations uvc_v4l2_fops;
 
 #endif /* __UVC_V4L2_H__ */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3] r8152: add Linksys USB3GIGV1 id

2017-09-27 Thread Grant Grundler
This linksys dongle by default comes up in cdc_ether mode.
This patch allows r8152 to claim the device:
   Bus 002 Device 002: ID 13b1:0041 Linksys

Signed-off-by: Grant Grundler 
---
 drivers/net/usb/cdc_ether.c | 10 ++
 drivers/net/usb/r8152.c |  2 ++
 2 files changed, 12 insertions(+)

V3: for backwards compat, add #ifdef CONFIG_USB_RTL8152 around
the cdc_ether blacklist entry so the cdc_ether driver can
still claim the device if r8152 driver isn't configured.

V2: add LINKSYS_VENDOR_ID to cdc_ether blacklist

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 8ab281b478f2..446dcc0f1f70 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -546,6 +546,7 @@ static const struct driver_info wwan_info = {
 #define DELL_VENDOR_ID 0x413C
 #define REALTEK_VENDOR_ID  0x0bda
 #define SAMSUNG_VENDOR_ID  0x04e8
+#define LINKSYS_VENDOR_ID  0x13b1
 #define LENOVO_VENDOR_ID   0x17ef
 #define NVIDIA_VENDOR_ID   0x0955
 #define HP_VENDOR_ID   0x03f0
@@ -737,6 +738,15 @@ static const struct usb_device_id  products[] = {
.driver_info = 0,
 },
 
+#ifdef CONFIG_USB_RTL8152
+/* Linksys USB3GIGV1 Ethernet Adapter */
+{
+   USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM,
+   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   .driver_info = 0,
+},
+#endif
+
 /* ThinkPad USB-C Dock (based on Realtek RTL8153) */
 {
USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM,
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ceb78e2ea4f0..941ece08ba78 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -613,6 +613,7 @@ enum rtl8152_flags {
 #define VENDOR_ID_MICROSOFT0x045e
 #define VENDOR_ID_SAMSUNG  0x04e8
 #define VENDOR_ID_LENOVO   0x17ef
+#define VENDOR_ID_LINKSYS  0x13b1
 #define VENDOR_ID_NVIDIA   0x0955
 
 #define MCU_TYPE_PLA   0x0100
@@ -5316,6 +5317,7 @@ static const struct usb_device_id rtl8152_table[] = {
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7205)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x720c)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7214)},
+   {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
{REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA,  0x09ff)},
{}
 };
-- 
2.14.2.822.g60be5d43e6-goog

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 14/17] phy: qcom-qusb2: Set vbus sw-override signal in device mode

2017-09-27 Thread Jack Pham
Hi Manu,

On Wed, Sep 27, 2017 at 02:29:10PM +0530, Manu Gautam wrote:
> VBUS signal coming from PHY must be asserted in device for
> controller to start operation or assert pull-up. For some
> platforms where VBUS line is not connected to PHY there is
> HS_PHY_CTRL register in QSCRATCH wrapper that can be used
> by software to override VBUS signal going to controller.
> 
> Signed-off-by: Manu Gautam 
> ---
>  
> +static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
> +{
> + struct qusb2_phy *qphy = phy_get_drvdata(phy);
> +
> + qphy->mode = mode;
> +
> + /* Update VBUS override in qscratch register */
> + if (qphy->qscratch_base) {
> + if (mode == PHY_MODE_USB_DEVICE)
> + qusb2_setbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
> +   UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
> + else
> + qusb2_clrbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
> +   UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);

Wouldn't this be better off handled in the controller glue driver? Two
reasons I think this patch is unattractive:

- qscratch_base is part of the controller's register space. Your later
  patch 16/17 ("phy: qcom-qmp: Override lane0_power_present signal in
  device mode") does a similar thing and hence both drivers have to
  ioremap() the same register resource while at the same time avoiding
  request_mem_region() (called by devm_ioremap_resource) to allow it to
  be mapped in both places.

- VBUS override bit becomes asserted simply because the mode is changed
  to device mode but this is irrespective of the actual VBUS state. This
  could break some test setups which perform a logical disconnect by
  switching off/on VBUS while leaving data lines connected. Controller
  would go merrily along thinking it is still attached to the host.

Instead maybe this could be tied to EXTCON_USB handling in the glue
driver; though it would need to be an additional notifier on top of
dwc3/drd.c which already handles extcon for host/device mode.

Jack
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 13/17] phy: qcom-qmp: Add support for QMP V3 USB3 PHY

2017-09-27 Thread Jack Pham
On Wed, Sep 27, 2017 at 02:29:09PM +0530, Manu Gautam wrote:
> QMP V3 USB3 PHY is a DP USB combo PHY with
> dual RX/TX lanes to support type-c. There is a
> separate block DP_COM for configuration related
> to type-c or DP. Add support for dp_com region
> and secondary rx/tx lanes initialization.

Clarify "DP" as DisplayPort here?

Jack
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 14/17] phy: qcom-qusb2: Set vbus sw-override signal in device mode

2017-09-27 Thread Jack Pham
On Wed, Sep 27, 2017 at 10:57:41AM -0700, Jack Pham wrote:
> Hi Manu,
> 
> On Wed, Sep 27, 2017 at 02:29:10PM +0530, Manu Gautam wrote:
> > VBUS signal coming from PHY must be asserted in device for
> > controller to start operation or assert pull-up. For some
> > platforms where VBUS line is not connected to PHY there is
> > HS_PHY_CTRL register in QSCRATCH wrapper that can be used
> > by software to override VBUS signal going to controller.
> > 
> > Signed-off-by: Manu Gautam 
> > ---
> >  
> > +static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
> > +{
> > +   struct qusb2_phy *qphy = phy_get_drvdata(phy);
> > +
> > +   qphy->mode = mode;
> > +
> > +   /* Update VBUS override in qscratch register */
> > +   if (qphy->qscratch_base) {
> > +   if (mode == PHY_MODE_USB_DEVICE)
> > +   qusb2_setbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
> > + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
> > +   else
> > +   qusb2_clrbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
> > + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
> 
> Wouldn't this be better off handled in the controller glue driver? Two
> reasons I think this patch is unattractive:
> 
> - qscratch_base is part of the controller's register space. Your later
>   patch 16/17 ("phy: qcom-qmp: Override lane0_power_present signal in
>   device mode") does a similar thing and hence both drivers have to
>   ioremap() the same register resource while at the same time avoiding
>   request_mem_region() (called by devm_ioremap_resource) to allow it to
>   be mapped in both places.
> 
> - VBUS override bit becomes asserted simply because the mode is changed
>   to device mode but this is irrespective of the actual VBUS state. This
>   could break some test setups which perform a logical disconnect by
>   switching off/on VBUS while leaving data lines connected. Controller
>   would go merrily along thinking it is still attached to the host.
> 
> Instead maybe this could be tied to EXTCON_USB handling in the glue
> driver; though it would need to be an additional notifier on top of
> dwc3/drd.c which already handles extcon for host/device mode.

That is to say, we'd probably need to split out dwc3-qcom from
dwc3-of-simple.c into its own driver (again) in order to add this.

Jack
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Type-C port on the Asmedia ASM1142

2017-09-27 Thread Adrian Bocaniciu
On Wed, 27 Sep 2017 11:03:41 +0300
Mathias Nyman  wrote:

> Ok, please let me know which register you refer to, I'd like to get this 
> fixed as soon as possible.
> Based on what you say I suspect that you talk about the SBRN (Serial bus 
> release number).
> 
> The early xhci 1.1 spec that was used to write USB3.1 SSP support stated that 
> SBRN contain
> the serial bus specification release, (in hex) with examples of 30h for USB 
> 3.0 and 31h for USB 3.1
> 
> Driver uses this to determine if hosts supports USB 3.0 or usb 3.1
> 
> I see that the current public xhci spec only mention 30h (USB 3.0), and in a 
> way that it can be
> interpreted as 30 being the only option.
> If this is the case then SBRN itself would be completely useless.
> Why have a register with the purpose of telling which serial bus release 
> number the hardware
> supports always forced to 30h?
> 
> Yes, the first Intel Alpine ridge based USB 3.1 SSP 10Gbps xHCI hosts had 
> this as 30,
> Newer Intel USB 3.1 SSP capable 10Gbps xHCI hosts have it set to 31h
> 
> If vendors have interpreted it as "SBRN must equal 30h" then we need to work
> around that in the driver.
> 
> We can check if the host supports USB 3.1 from the ports supported protocol 
> capability,
> see xhci 7.2 xHCI supported protocol capability, major and minor revision 
> fields. These
> should at least contain major=3 and minor=1 for USB 3.1 capable ports.
> 
> That at least is unambiguous in all xhci specs (early, and current public)


Yes, indeed, your guess is correct. I was writing about SBRN.

In the function "xhci_pci_setup", from the file "drivers/usb/host/xhci-pci.c", 
SBRN is read and stored in "xhci->sbrn".

Then, in the function "xhci_gen_setup", from the file 
"drivers/usb/host/xhci.c", the value of "xhci->sbrn" is checked. If it is 0x31, 
then support for 10 Gb/s is assumed.

This check was introduced in a patch from the 1st October 2015. It must have 
worked once, because I have seen some Linux screen shots with the output of 
lsusb showing some xHCI controller with 10 Gb/s support.

I am not aware of any USB 3.1 controllers that existed in 2015 and that could 
have SBRN equal to 0x31, except for some earlier ASMedia controllers. AFAIK, 
there were at least 2 versions before ASM 1142, so one or both of them must 
have had SBRN equal to 0x31.

I have verified on many motherboards that both Alpine Ridge and ASM 1142 have 
SBRN equal to 0x30. Moreover, the ASM 1142 datasheet says clearly that SBRN is 
0x30. Therefore, I believe that ASMedia has understood the xHCI specification 
exactly as it is written, i.e. that SBRN must be 0x30, and they have reverted 
its value from the earlier 0x31 to 0x30. There are at least 2 newer ASMedia USB 
3.1 controllers (2142 & 3142). I do not know what value they use for SBRN, but 
0x30 is likely.


Nevertheless, even if we ignore this history of unpredictable SBRN values, it 
is wrong to believe that any USB 3.1 controller supports 10 Gb/s operation. The 
evidence for this is all the b*s*t advertising about "USB 3.1 Gen 1", i.e. 5 
Gb/s (4 Gb/s actually) speed.

Moreover, very soon USB 3.2 devices will appear. USB 3.2 introduces 2 more 
speeds, so a USB 3.2 xHCI controller will support some or all of 4 speeds: 1 * 
5 Gb/s (actually 4 Gb/s), 2 * 5 Gb/s (actually 8 Gb/s), 1 * 10 Gb/s (i.e. 10 
Gb/s) and 2 * 10 Gb/s (i.e. 20 Gb/s). It is very likely that some USB 3.2 xHCI 
controllers will not support all speeds, especially because the 2-lane speeds 
are possible only over Type C connectors, so the same controller will support 
all speeds on some motherboards but only some of them when used with Type A 
connectors.

In conclusion, the supported speeds must be detected independently of the USB 
release number.

The xHCI Specification describes an appropriate source for this information, at 
the "xHCI Supported Protocol Capability", in the "Protocol Speed ID" Dwords.

There are chances that I might have time during this weekend to test some USB 
3.1 xHCI controllers to see how this works.

If you can work on this sooner, you are welcome.


While reading the extra capability registers should be easy, what should be 
thought carefully is how to change the existing structures which store 
information about the xHCI controller, to accomodate the extra speeds that will 
be available soon and the fact that the set of supported speeds is not 
necessarily determined by the USB version number.

Like I said, while I patched my kernel and now my xHCI controllers are 
recognized as supporting 10 Gb/s, the SSDs with USB-SATA bridges that I have 
connected are still not recognized as also supporting 10 Gb/s. I believe that 
the problem is caused by other parts of the xHCI specification that are not 
implemented, but I did not have time yet to identify them.


Best regards !






























--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo 

[PATCH] rndis_host: support Novatel Verizon USB730L

2017-09-27 Thread Aleksander Morgado
Treat the ef/04/01 interface class/subclass/protocol combination used
by the Novatel Verizon USB730L (1410:9030) as a possible RNDIS
interface.

 T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 17 Spd=480 MxCh= 0
 D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  3
 P:  Vendor=1410 ProdID=9030 Rev=03.10
 S:  Manufacturer=Novatel Wireless
 S:  Product=MiFi USB730L
 S:  SerialNumber=0123456789ABCDEF
 C:  #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=500mA
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host
 I:  If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
 I:  If#= 2 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid

Once the network interface is brought up, the user just needs to run a
DHCP client to get IP address and routing setup.

As a side note, other Novatel Verizon USB730L models with the same
vid:pid end up exposing a standard ECM interface which doesn't require
any other kernel update to make it work.

Signed-off-by: Aleksander Morgado 
---

Hey,

I'm not sure if binding this logic to a specific vid:pid (1410:9030) would be 
more appropriate here, or if it's ok to just bind class/subclass/protocol (as 
in the activesync case).
Let me know what you think.

---
 drivers/net/usb/cdc_ether.c  | 11 ++-
 drivers/net/usb/rndis_host.c |  4 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 8ab281b478f2..2df0bcc6d30b 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -54,11 +54,19 @@ static int is_wireless_rndis(struct 
usb_interface_descriptor *desc)
desc->bInterfaceProtocol == 3);
 }

+static int is_novatel_rndis(struct usb_interface_descriptor *desc)
+{
+   return (desc->bInterfaceClass == USB_CLASS_MISC &&
+   desc->bInterfaceSubClass == 4 &&
+   desc->bInterfaceProtocol == 1);
+}
+
 #else

 #define is_rndis(desc) 0
 #define is_activesync(desc)0
 #define is_wireless_rndis(desc)0
+#define is_novatel_rndis(desc) 0

 #endif

@@ -150,7 +158,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct 
usb_interface *intf)
 */
rndis = (is_rndis(&intf->cur_altsetting->desc) ||
 is_activesync(&intf->cur_altsetting->desc) ||
-is_wireless_rndis(&intf->cur_altsetting->desc));
+is_wireless_rndis(&intf->cur_altsetting->desc) ||
+is_novatel_rndis(&intf->cur_altsetting->desc));

memset(info, 0, sizeof(*info));
info->control = intf;
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index a151f267aebb..b807c91abe1d 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -632,6 +632,10 @@ static const struct usb_device_id  products [] = {
/* RNDIS for tethering */
USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
.driver_info = (unsigned long) &rndis_info,
+}, {
+   /* Novatel Verizon USB730L */
+   USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
+   .driver_info = (unsigned long) &rndis_info,
 },
{ },// END
 };
--
2.14.1
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3] r8152: add Linksys USB3GIGV1 id

2017-09-27 Thread Doug Anderson
Hi,

On Wed, Sep 27, 2017 at 10:28 AM, Grant Grundler  wrote:
> This linksys dongle by default comes up in cdc_ether mode.
> This patch allows r8152 to claim the device:
>Bus 002 Device 002: ID 13b1:0041 Linksys
>
> Signed-off-by: Grant Grundler 
> ---
>  drivers/net/usb/cdc_ether.c | 10 ++
>  drivers/net/usb/r8152.c |  2 ++
>  2 files changed, 12 insertions(+)
>
> V3: for backwards compat, add #ifdef CONFIG_USB_RTL8152 around
> the cdc_ether blacklist entry so the cdc_ether driver can
> still claim the device if r8152 driver isn't configured.
>
> V2: add LINKSYS_VENDOR_ID to cdc_ether blacklist
>
> diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
> index 8ab281b478f2..446dcc0f1f70 100644
> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -546,6 +546,7 @@ static const struct driver_info wwan_info = {
>  #define DELL_VENDOR_ID 0x413C
>  #define REALTEK_VENDOR_ID  0x0bda
>  #define SAMSUNG_VENDOR_ID  0x04e8
> +#define LINKSYS_VENDOR_ID  0x13b1
>  #define LENOVO_VENDOR_ID   0x17ef

Slight nit that "LI" sorts after "LE".  You got it right in the other case...


>  #define NVIDIA_VENDOR_ID   0x0955
>  #define HP_VENDOR_ID   0x03f0
> @@ -737,6 +738,15 @@ static const struct usb_device_id  products[] = {
> .driver_info = 0,
>  },
>
> +#ifdef CONFIG_USB_RTL8152
> +/* Linksys USB3GIGV1 Ethernet Adapter */
> +{
> +   USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, 
> USB_CLASS_COMM,
> +   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
> +   .driver_info = 0,
> +},
> +#endif

I believe you want to use IS_ENABLED(), don't you?

There's still a weird esoteric side case where kernel modules don't
all need to be included in the filesystem just because they were built
at the same time.  ...but IMHO that seems like enough of a nit that we
can probably ignore it unless someone has a better idea.


-Doug
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3] r8152: add Linksys USB3GIGV1 id

2017-09-27 Thread Grant Grundler
Hi Doug!

On Wed, Sep 27, 2017 at 4:47 PM, Doug Anderson  wrote:
> Hi,
>
> On Wed, Sep 27, 2017 at 10:28 AM, Grant Grundler  
> wrote:
>> This linksys dongle by default comes up in cdc_ether mode.
>> This patch allows r8152 to claim the device:
>>Bus 002 Device 002: ID 13b1:0041 Linksys
>>
>> Signed-off-by: Grant Grundler 
>> ---
>>  drivers/net/usb/cdc_ether.c | 10 ++
>>  drivers/net/usb/r8152.c |  2 ++
>>  2 files changed, 12 insertions(+)
>>
>> V3: for backwards compat, add #ifdef CONFIG_USB_RTL8152 around
>> the cdc_ether blacklist entry so the cdc_ether driver can
>> still claim the device if r8152 driver isn't configured.
>>
>> V2: add LINKSYS_VENDOR_ID to cdc_ether blacklist
>>
>> diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
>> index 8ab281b478f2..446dcc0f1f70 100644
>> --- a/drivers/net/usb/cdc_ether.c
>> +++ b/drivers/net/usb/cdc_ether.c
>> @@ -546,6 +546,7 @@ static const struct driver_info wwan_info = {
>>  #define DELL_VENDOR_ID 0x413C
>>  #define REALTEK_VENDOR_ID  0x0bda
>>  #define SAMSUNG_VENDOR_ID  0x04e8
>> +#define LINKSYS_VENDOR_ID  0x13b1
>>  #define LENOVO_VENDOR_ID   0x17ef
>
> Slight nit that "LI" sorts after "LE".  You got it right in the other case...

The list isn't sorted by any rational thing I can see.  I managed to
check my OCD reaction to sort the list numerically. :)

>>  #define NVIDIA_VENDOR_ID   0x0955
>>  #define HP_VENDOR_ID   0x03f0
>> @@ -737,6 +738,15 @@ static const struct usb_device_id  products[] = {
>> .driver_info = 0,
>>  },
>>
>> +#ifdef CONFIG_USB_RTL8152
>> +/* Linksys USB3GIGV1 Ethernet Adapter */
>> +{
>> +   USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, 
>> USB_CLASS_COMM,
>> +   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
>> +   .driver_info = 0,
>> +},
>> +#endif
>
> I believe you want to use IS_ENABLED(), don't you?

Ah yes - I wasn't aware IS_ENABLED existed.  Will respin V4 with this
if there isn't any other feedback.


> There's still a weird esoteric side case where kernel modules don't
> all need to be included in the filesystem just because they were built
> at the same time.  ...but IMHO that seems like enough of a nit that we
> can probably ignore it unless someone has a better idea.

I think that would require a run time check. I'm perfectly willing to
ignore that case. :)

thanks!
grant

>
>
> -Doug
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/12] dt-bindings: usb: mtu3: remove dummy clocks and add optional ones

2017-09-27 Thread Chunfeng Yun
Remove dummy clocks for usb wakeup and add optional ones for
mcu_bus and dma_bus bus.

Signed-off-by: Chunfeng Yun 
---
 .../devicetree/bindings/usb/mediatek,mtu3.txt  |   10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
index 7c611d1..49c982b 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
@@ -14,9 +14,9 @@ Required properties:
  - vusb33-supply : regulator of USB avdd3.3v
  - clocks : a list of phandle + clock-specifier pairs, one for each
entry in clock-names
- - clock-names : must contain "sys_ck" and "ref_ck" for clock of controller;
-   "wakeup_deb_p0" and "wakeup_deb_p1" are optional, they are
-   depends on "mediatek,enable-wakeup"
+ - clock-names : must contain "sys_ck" for clock of controller,
+   the following clocks are optional:
+   "ref_ck", "mcu_ck" and "dam_ck";
  - phys : a list of phandle + phy specifier pairs
  - dr_mode : should be one of "host", "peripheral" or "otg",
refer to usb/generic.txt
@@ -65,9 +65,7 @@ ssusb: usb@11271000 {
clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>,
 <&pericfg CLK_PERI_USB0>,
 <&pericfg CLK_PERI_USB1>;
-   clock-names = "sys_ck", "ref_ck",
- "wakeup_deb_p0",
- "wakeup_deb_p1";
+   clock-names = "sys_ck", "ref_ck";
vusb33-supply = <&mt6397_vusb_reg>;
vbus-supply = <&usb_p0_vbus>;
extcon = <&extcon_usb>;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/12] dt-bindings: usb: mtu3: remove optional pinctrls

2017-09-27 Thread Chunfeng Yun
Remove optional pinctrls due to using FORCE/RG_IDDIG to implement
manual switch function.

Signed-off-by: Chunfeng Yun 
---
 .../devicetree/bindings/usb/mediatek,mtu3.txt  |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
index 49c982b..b2271d8 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
@@ -30,9 +30,10 @@ Optional properties:
when supports dual-role mode.
  - vbus-supply : reference to the VBUS regulator, needed when supports
dual-role mode.
- - pinctl-names : a pinctrl state named "default" must be defined,
-   "id_float" and "id_ground" are optinal which depends on
-   "mediatek,enable-manual-drd"
+ - pinctrl-names : a pinctrl state named "default" is optional, and need be
+   defined if auto drd switch is enabled, that means the property dr_mode
+   is set as "otg", and meanwhile the property "mediatek,enable-manual-drd"
+   is not set.
  - pinctrl-0 : pin control group
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/12] dt-bindings: usb: mtu3: add a optional property to disable u3ports

2017-09-27 Thread Chunfeng Yun
Add a new optional property to disable u3ports

Signed-off-by: Chunfeng Yun 
---
 .../devicetree/bindings/usb/mediatek,mtu3.txt  |2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
index 49f5476..7c611d1 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
@@ -44,6 +44,8 @@ Optional properties:
  - mediatek,enable-wakeup : supports ip sleep wakeup used by host mode
  - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
control register, it depends on "mediatek,enable-wakeup".
+ - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
+   bit1 for u3port1, ... etc;
 
 Sub-nodes:
 The xhci should be added as subnode to mtu3 as shown in the following example
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write to a UVC device

2017-09-27 Thread Jaejoong Kim
2017-09-28 2:07 GMT+09:00 Rail Shafigulin :
> On Mon, Sep 25, 2017 at 7:29 PM, Jaejoong Kim  wrote:
>> Hi,
>>
>> The below link will help.
>>
>> http://git.ideasonboard.org/uvc-gadget.git
>> https://lwn.net/Articles/203924/
>>
>> Jaejoong
>>
>
> Thanks for the reply.  But I need some clarification. Usually when a
> character device (which as far as I understand what UVC is) is read or
> written, all the user does is open, read/write, close.

All of the character devices is not working properly with low level I/O.

The details are
> taken care by the driver. Am I correct in understanding that this is
> not a way to do it with UVC, i.e. the sequence of steps is different
> (open, some different steps, close) ?

yes. you need to know how to talk with UVC.
This article will be help.

https://lwn.net/Articles/203924/

Jaejoong

>
> --
> Rail Shafigulin
> Software Engineer
> Esencia Technologies
>
> --
>
>
>
>
> *ESENCIA TECHNOLOGIES, INC.*3945 Freedom Circle, Suite #360,
> Santa Clara CA 95054
> 
>
> Phone: +1 408 736 8284 Fax: +1 408 519 3475
> http://www.esenciatech.com | http://www.lnttechservices.com
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 14/17] phy: qcom-qusb2: Set vbus sw-override signal in device mode

2017-09-27 Thread Manu Gautam
Hi Jack,


On 9/28/2017 12:46 AM, Jack Pham wrote:
> On Wed, Sep 27, 2017 at 10:57:41AM -0700, Jack Pham wrote:
>> Hi Manu,
>>
>> On Wed, Sep 27, 2017 at 02:29:10PM +0530, Manu Gautam wrote:
>>> VBUS signal coming from PHY must be asserted in device for
>>> controller to start operation or assert pull-up. For some
>>> platforms where VBUS line is not connected to PHY there is
>>> HS_PHY_CTRL register in QSCRATCH wrapper that can be used
>>> by software to override VBUS signal going to controller.
>>>
>>> Signed-off-by: Manu Gautam 
>>> ---
>>>  
>>> +static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
>>> +{
>>> +   struct qusb2_phy *qphy = phy_get_drvdata(phy);
>>> +
>>> +   qphy->mode = mode;
>>> +
>>> +   /* Update VBUS override in qscratch register */
>>> +   if (qphy->qscratch_base) {
>>> +   if (mode == PHY_MODE_USB_DEVICE)
>>> +   qusb2_setbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
>>> + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
>>> +   else
>>> +   qusb2_clrbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
>>> + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
>> Wouldn't this be better off handled in the controller glue driver? Two
>> reasons I think this patch is unattractive:
>>
>> - qscratch_base is part of the controller's register space. Your later
>>   patch 16/17 ("phy: qcom-qmp: Override lane0_power_present signal in
>>   device mode") does a similar thing and hence both drivers have to
>>   ioremap() the same register resource while at the same time avoiding
>>   request_mem_region() (called by devm_ioremap_resource) to allow it to
>>   be mapped in both places.

Right. There is one more reason why qusb2 driver needs qscratch:
- During runtime suspend, it has to check linestate to set correct  polarity 
for dp/dm
  wakeup interrupt in order to detect disconnect/resume ion LS and FS/HS modes.

>> - VBUS override bit becomes asserted simply because the mode is changed
>>   to device mode but this is irrespective of the actual VBUS state. This
>>   could break some test setups which perform a logical disconnect by
>>   switching off/on VBUS while leaving data lines connected. Controller
>>   would go merrily along thinking it is still attached to the host.
>>
>> Instead maybe this could be tied to EXTCON_USB handling in the glue
>> driver; though it would need to be an additional notifier on top of
>> dwc3/drd.c which already handles extcon for host/device mode.

Yes, dwc3/drd.c currently deals with only EXTCON_USB_HOST. So, for platforms
where role swap happens using only Vbus or single GPIO this should take care of.


> That is to say, we'd probably need to split out dwc3-qcom from
> dwc3-of-simple.c into its own driver (again) in order to add this.
>
> Jack

However, I agree that more appropriate place for lane0-pwr-present and
vbus override update is dwc3 glue driver. Since we don't have one right now,

IMO once we have dwc3-qcom driver in place, this handling can be moved from
PHY to glue driver. Until then we can use this approach to get USB device mode
working on qcom platforms which are using dwc3-of-simple.c e.g. sdm820
dragonboard.


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Mouse freezes on button depression

2017-09-27 Thread Oliver Neukum
Am Mittwoch, den 27.09.2017, 20:49 +1000 schrieb Christian Bullow:
> Hi Oliver thank you for your reply.
> 
> Apologies for now replying from gmail. I'm being told my crjb.net 
> address is failing SPF and that I have to shoehorn this email into 
> plain-text for you. Here we go :)
> 
> I must correct/clarify that the browser forward and back buttons seem to 
> work in chrome and that in testing this evening, they have not frozen or 
> crashed anything. The output I provided before was simply the dmesg 
> record of the mouse being detected on boot or plugin, not any dmesg 
> records produced on the depression of the buttons of concern (which are 
> primarily the DPI+ and DPI- buttons).
> 
> *Relevant output from usbmon (cat /sys/kernel/debug/usb/usbmon/0u)*
> 
> I was able to capture my pressing the dpi+ button twice before the mouse 
> driver crashed.
> 
> a0b1fca52240 1143494193 C Ii:1:015:2 0:1 8 =  
> a0b1fca52240 1143494212 S Ii:1:015:2 -115:1 8 <
> a0b1fca52240 1144099217 C Ii:1:015:2 0:1 8 =  
> a0b1fca52240 1144099233 S Ii:1:015:2 -115:1 8 <
> 
> *From lsusb*
> 
> Bus 001 Device 015: ID 1044:7a13 Chu Yuen Enterprise Co., Ltd
> 
> *From cat /sys/kernel/debug/usb/devices*
> 
> T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#=  15 Spd=12   MxCh= 0
> D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
> P:  Vendor=1044 ProdID=7a13 Rev= 2.00
> S:  Manufacturer=Texas Instruments
> S:  Product=MSP430-USB Mouse
> S:  SerialNumber=8C2F0C5132000C00
> C:* #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=100mA
> I:* If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
> E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=15ms
> E:  Ad=01(O) Atr=03(Int.) MxPS=   8 Ivl=15ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
> E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=1ms
> E:  Ad=02(O) Atr=03(Int.) MxPS=   8 Ivl=1ms
> I:* If#= 2 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
> E:  Ad=83(I) Atr=03(Int.) MxPS=   8 Ivl=20ms
> E:  Ad=03(O) Atr=03(Int.) MxPS=   8 Ivl=20ms
> I:* If#= 3 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
> E:  Ad=84(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
> E:  Ad=04(O) Atr=03(Int.) MxPS=  64 Ivl=1ms
> 
> Unplugging and re-plugging the mouse in, it moves to Bus 01, Device 16 
> and I captured the following:
> 
> *usbmon output from the DPI - button*
> 
> a0b20247ab40 1348549098 C Ii:1:016:2 0:1 8 =  
> a0b20247ab40 1348549123 S Ii:1:016:2 -115:1 8 <*
> *

That tells us practically nothing. If you press any button nothing
happens? Anything in dmesg?

Regards
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html