USB gadget : generic functionfs function has no os_desc while rndis function has, why?

2018-01-03 Thread Jun Sun
Hi, all,

I'm playing with USB gadget with configfs on raspberry pi zero w.  My
goal is to setup a generic functionfs function that uses Windows OS
descriptor so that windows would automatically install winusb driver.
It seems I would have to

- enable MS-specific os descriptor
- specify the compatiblity id to be "WINUSB"
- specify interface GUID (optional?)

It seems simple enough.

However, the first problem I'm having is that I can't find the
os_desc/ directory for the ffs function I created.  If, following
other example, I create a RNDIS function, then everything seems to be
right.  See the console output below.

Did I do anything wrongly?  Is my goal achievable?

Many thanks.

Jun

==

root@raspberrypi:/sys/kernel/config/usb_gadget/g1# cat os_desc/use
1
root@raspberrypi:/sys/kernel/config/usb_gadget/g1# tree functions/
functions/
├── ffs.usb0
└── rndis.usb0
├── dev_addr
├── host_addr
├── ifname
├── os_desc
│   └── interface.rndis
│   ├── compatible_id
│   └── sub_compatible_id
└── qmult

4 directories, 6 files
--
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 v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-03 Thread Thang Q. Nguyen
Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:
> From: Tung Nguyen 
>
> Currently, hcd->shared_hcd always creates and registers to the usb-core.
> If, for some reasons, USB3 downstream port is disabled, no roothub port for
> USB3.0 is found. This causes kernel to display an error:
> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
> This patch checks, creates and registers shared_hcd if USB3.0 downstream
> port is available.
>
> Signed-off-by: Tung Nguyen 
> Signed-off-by: Thang Q. Nguyen 
> ---
>  drivers/usb/host/xhci-mem.c  |  2 +-
>  drivers/usb/host/xhci-plat.c | 26 +++--
>  drivers/usb/host/xhci.c  | 54 
> 
>  3 files changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 554a8a5..157d1e7 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
> *xhci,
> struct usb_device *top_dev;
> struct usb_hcd *hcd;
>
> -   if (udev->speed >= USB_SPEED_SUPER)
> +   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
> hcd = xhci->shared_hcd;
> else
> hcd = xhci->main_hcd;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 6f03830..e812e3d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
>
> xhci->clk = clk;
> xhci->main_hcd = hcd;
> -   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
> -   dev_name(>dev), hcd);
> -   if (!xhci->shared_hcd) {
> -   ret = -ENOMEM;
> -   goto disable_clk;
> -   }
>
> if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
> xhci->quirks |= XHCI_HW_LPM_DISABLE;
> @@ -290,12 +284,20 @@ static int xhci_plat_probe(struct platform_device *pdev)
> if (ret)
> goto disable_usb_phy;
>
> -   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
> -   xhci->shared_hcd->can_do_streams = 1;
> -
> -   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
> -   if (ret)
> -   goto dealloc_usb2_hcd;
> +   if (xhci->num_usb3_ports > 0) {
> +   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, 
> >dev,
> +   dev_name(>dev), hcd);
> +   if (!xhci->shared_hcd) {
> +   ret = -ENOMEM;
> +   goto disable_clk;
> +   }
> +   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
> +   xhci->shared_hcd->can_do_streams = 1;
> +
> +   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
> +   if (ret)
> +   goto dealloc_usb2_hcd;
> +   }
>
> device_enable_async_suspend(>dev);
> pm_runtime_put_noidle(>dev);
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 05104bd..4824bf6 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list 
> *t)
> i + 1);
> xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
> "Attempting compliance mode 
> recovery");
> -   hcd = xhci->shared_hcd;
> +   if (xhci->shared_hcd) {
> +   hcd = xhci->shared_hcd;
>
> -   if (hcd->state == HC_STATE_SUSPENDED)
> -   usb_hcd_resume_root_hub(hcd);
> +   if (hcd->state == HC_STATE_SUSPENDED)
> +   usb_hcd_resume_root_hub(hcd);
>
> -   usb_hcd_poll_rh_status(hcd);
> +   usb_hcd_poll_rh_status(hcd);
> +   }
> }
> }
>
> @@ -611,6 +613,18 @@ int xhci_run(struct usb_hcd *hcd)
> if (ret)
> xhci_free_command(xhci, command);
> }
> +   /*
> +* Execute xhci_start() in case xhci->shared_hcd is not registered.
> +* If the xhci->shared_hcd doesn't exist, no one triggers to start
> +* the xhci which should be done before exitting run function
> +*/
> +   if (!xhci->shared_hcd) {
> +   if (xhci_start(xhci)) {
> +   xhci_halt(xhci);
> +   return -ENODEV;
> +   }
> +   xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
> +   }
> xhci_dbg_trace(xhci, trace_xhci_dbg_init,
> "Finished xhci_run for USB2 roothub");

Re: [BUG] USB mass storage device incomplete read command sequence

2018-01-03 Thread Matthew Dharm
The TUR commands come from the sd_mod (I think).  Definitely not from
usb-storage.  So I would take it up at that level.

Matt

On Wed, Jan 3, 2018 at 4:25 PM, Eduardo Trápani  wrote:
> Usually the kernel reads the pendrive like this:
>
> TEST UNIT READY
> READ(10)
> ...
> READ(10)
> TEST UNIT READY
>
> But under some conditions, the last TEST UNIT READY is not being sent
> and because of that, on this device: Kingston DT 101 G2, the drive's
> activity light keeps on blinking even though nothing is being done (no
> read/writes/inquiries).
>
> When that happens, manually sending a TEST UNIT READY stops the blinking
> and turns off the light.
>
> # sg_turs /dev/sdc
>
> For example this works alright (light blinks for a moment and then it's
> off):
>
> # dd if=/dev/sdc of=/dev/null bs=512 count=96
>
> But this doesn't (the light keeps on blinking forever)
>
> # dd if=/dev/sdb of=/dev/null bs=512 count=97
>
> I checked with usbmon and I noticed the lack of the final TEST UNIT
> READY in the cases where the light keeps on blinking.
>
> For the tests the drive was unmounted. As soon as I mount it and start
> working on it, the light will blink non-stop.
>
> I also tested this with a Raspberry (Linux frambo 4.1.17+ #838 Tue Feb 9
> 12:57:10 GMT 2016 armv6l GNU/Linux), and the device behaves normally,
> that is, blinking stops as soon as traffic stops.
>
>
> Find attached the pcap file for both cases and part of the kernel dmesg.
> This is the kernel with the problem: Linux arbo 4.9.0-4-amd64 #1 SMP
> Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64 GNU/Linux
>
> Eduardo.
>



-- 
Matthew Dharm
Former Maintainer, USB Mass Storage driver for Linux
--
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/5] usb: serial: f81534: add auto RTS direction support

2018-01-03 Thread Ji-Ze Hong (Peter Hong)
The F81532/534 had auto RTS direction support for RS485 mode.
We'll read it from internal Flash with address 0x2f01~0x2f04 for 4 ports.
There are 4 conditions below:
0: F81534_PORT_CONF_RS232.
1: F81534_PORT_CONF_RS485.
2: value error, default to F81534_PORT_CONF_RS232.
3: F81534_PORT_CONF_RS485_INVERT.

F81532/534 Clock register (offset +08h)

Bit0:   UART Enable (always on)
Bit2-1: Clock source selector
00: 1.846MHz.
01: 18.46MHz.
10: 24MHz.
11: 14.77MHz.
Bit4:   Auto direction(RTS) control (RTS pin Low when TX)
Bit5:   Invert direction(RTS) when Bit4 enabled (RTS pin high when TX)

Signed-off-by: Ji-Ze Hong (Peter Hong) 
---
V2:
1: Read the configure data from flash and save it to shadow clock
   register.

 drivers/usb/serial/f81534.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 758ef0424164..8a778bc1d492 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -98,11 +98,16 @@
 
 #define F81534_DEFAULT_BAUD_RATE   9600
 
+#define F81534_PORT_CONF_RS232 0
+#define F81534_PORT_CONF_RS485 BIT(0)
+#define F81534_PORT_CONF_RS485_INVERT  (BIT(0) | BIT(1))
 #define F81534_PORT_CONF_DISABLE_PORT  BIT(3)
 #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7)
 #define F81534_PORT_UNAVAILABLE\
(F81534_PORT_CONF_DISABLE_PORT | F81534_PORT_CONF_NOT_EXIST_PORT)
 
+#define F81534_UART_MODE_MASK  (BIT(0) | BIT(1))
+
 #define F81534_1X_RXTRIGGER0xc3
 #define F81534_8X_RXTRIGGER0xcf
 
@@ -115,6 +120,8 @@
  * 01: 18.46MHz.
  * 10: 24MHz.
  * 11: 14.77MHz.
+ * Bit4:   Auto direction(RTS) control (RTS pin Low when TX)
+ * Bit5:   Invert direction(RTS) when Bit4 enabled (RTS pin high when TX)
  */
 
 #define F81534_UART_EN BIT(0)
@@ -123,6 +130,9 @@
 #define F81534_CLK_24_MHZ  (F81534_UART_EN | BIT(2))
 #define F81534_CLK_14_77_MHZ   (F81534_UART_EN | BIT(1) | BIT(2))
 
+#define F81534_CLK_RS485_MODE  BIT(4)
+#define F81534_CLK_RS485_INVERTBIT(5)
+
 static const struct usb_device_id f81534_id_table[] = {
{ USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) },
{ USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) },
@@ -517,7 +527,8 @@ static int f81534_set_port_config(struct usb_serial_port 
*port,
}
 
port_priv->baud_base = baudrate_table[idx];
-   port_priv->shadow_clk = clock_table[idx];
+   port_priv->shadow_clk &= ~F81534_CLK_14_77_MHZ;
+   port_priv->shadow_clk |= clock_table[idx];
 
status = f81534_set_port_register(port, F81534_CLOCK_REG,
port_priv->shadow_clk);
@@ -1269,9 +1280,12 @@ static void f81534_lsr_worker(struct work_struct *work)
 
 static int f81534_port_probe(struct usb_serial_port *port)
 {
+   struct f81534_serial_private *serial_priv;
struct f81534_port_private *port_priv;
int ret;
+   u8 value;
 
+   serial_priv = usb_get_serial_data(port->serial);
port_priv = devm_kzalloc(>dev, sizeof(*port_priv), GFP_KERNEL);
if (!port_priv)
return -ENOMEM;
@@ -1303,6 +1317,24 @@ static int f81534_port_probe(struct usb_serial_port 
*port)
if (ret)
return ret;
 
+   value = serial_priv->conf_data[port_priv->phy_num];
+   switch (value & F81534_UART_MODE_MASK) {
+   case F81534_PORT_CONF_RS485_INVERT:
+   port_priv->shadow_clk = F81534_CLK_RS485_MODE |
+   F81534_CLK_RS485_INVERT;
+   dev_info(>dev, "RS485 invert mode.\n");
+   break;
+   case F81534_PORT_CONF_RS485:
+   port_priv->shadow_clk = F81534_CLK_RS485_MODE;
+   dev_info(>dev, "RS485 mode.\n");
+   break;
+
+   default:
+   case F81534_PORT_CONF_RS232:
+   dev_info(>dev, "RS232 mode.\n");
+   break;
+   }
+
return 0;
 }
 
-- 
2.7.4

--
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 5/5] usb: serial: f81534: fix tx error on some baud rate

2018-01-03 Thread Ji-Ze Hong (Peter Hong)
The F81532/534 had 4 clocksource 1.846/18.46/14.77/24MHz and baud rates
can be up to 1.5Mbits with 24MHz. But on some baud rate (384~500kps), the
TX side will send the data frame too close to treat frame error on RX
side. This patch will force all TX data frame with delay 1bit gap.

Signed-off-by: Ji-Ze Hong (Peter Hong) 
---
V2:
1: First introduced in this series patches.

 drivers/usb/serial/f81534.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index a4666171239a..513805eeae6a 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -130,6 +130,7 @@
 #define F81534_CLK_18_46_MHZ   (F81534_UART_EN | BIT(1))
 #define F81534_CLK_24_MHZ  (F81534_UART_EN | BIT(2))
 #define F81534_CLK_14_77_MHZ   (F81534_UART_EN | BIT(1) | BIT(2))
+#define F81534_CLK_TX_DELAY_1BIT   BIT(3)
 
 #define F81534_CLK_RS485_MODE  BIT(4)
 #define F81534_CLK_RS485_INVERTBIT(5)
@@ -1438,6 +1439,11 @@ static int f81534_port_probe(struct usb_serial_port 
*port)
break;
}
 
+   /*
+* We'll make tx frame error when baud rate from 384~500kps. So we'll
+* delay all tx data frame with 1bit.
+*/
+   port_priv->shadow_clk |= F81534_CLK_TX_DELAY_1BIT;
return f81534_set_port_output_pin(port);
 }
 
-- 
2.7.4

--
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/5] usb: serial: f81534: add high baud rate support

2018-01-03 Thread Ji-Ze Hong (Peter Hong)
The F81532/534 had 4 clocksource 1.846/18.46/14.77/24MHz and baud rates
can be up to 1.5Mbits with 24MHz.

This device may generate data overrun when baud rate setting to 921600bps
or higher with old UART trigger level setting (8x14=112) with full
loading. We'll change trigger level from 8x14=112 to 8x8=64 to avoid data
overrun.

Also the read/write of EP0 will be affected by this patch. The worst case
of responding time is 20s when all serial port are full loading and trying
to access EP0, so we change EP0 timeout from 10 to 20s.

F81532/534 Clock register (offset +08h)

Bit0:   UART Enable (always on)
Bit2-1: Clock source selector
00: 1.846MHz.
01: 18.46MHz.
10: 24MHz.
11: 14.77MHz.

Signed-off-by: Ji-Ze Hong (Peter Hong) 
---
v2:
1: Add commit message for F81534_USB_TIMEOUT from 1000 to 2000 and
   trigger level from UART_FCR_R_TRIG_11 to UART_FCR_TRIGGER_8.
2: Separate UART Enable bit from clock sources.
3: Add help function "f81534_find_clk()" to calculate baud rate and
   clock source
4: Add shadow clock register for future use. 

 drivers/usb/serial/f81534.c | 87 -
 1 file changed, 71 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index e4573b4c8935..758ef0424164 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -41,6 +41,7 @@
 #define F81534_MODEM_CONTROL_REG   (0x04 + F81534_UART_BASE_ADDRESS)
 #define F81534_LINE_STATUS_REG (0x05 + F81534_UART_BASE_ADDRESS)
 #define F81534_MODEM_STATUS_REG(0x06 + 
F81534_UART_BASE_ADDRESS)
+#define F81534_CLOCK_REG   (0x08 + F81534_UART_BASE_ADDRESS)
 #define F81534_CONFIG1_REG (0x09 + F81534_UART_BASE_ADDRESS)
 
 #define F81534_DEF_CONF_ADDRESS_START  0x3000
@@ -57,7 +58,7 @@
 
 /* Default URB timeout for USB operations */
 #define F81534_USB_MAX_RETRY   10
-#define F81534_USB_TIMEOUT 1000
+#define F81534_USB_TIMEOUT 2000
 #define F81534_SET_GET_REGISTER0xA0
 
 #define F81534_NUM_PORT4
@@ -96,7 +97,6 @@
 #define F81534_CMD_READ0x03
 
 #define F81534_DEFAULT_BAUD_RATE   9600
-#define F81534_MAX_BAUDRATE115200
 
 #define F81534_PORT_CONF_DISABLE_PORT  BIT(3)
 #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7)
@@ -106,6 +106,23 @@
 #define F81534_1X_RXTRIGGER0xc3
 #define F81534_8X_RXTRIGGER0xcf
 
+/*
+ * F81532/534 Clock registers (offset +08h)
+ *
+ * Bit0:   UART Enable (always on)
+ * Bit2-1: Clock source selector
+ * 00: 1.846MHz.
+ * 01: 18.46MHz.
+ * 10: 24MHz.
+ * 11: 14.77MHz.
+ */
+
+#define F81534_UART_EN BIT(0)
+#define F81534_CLK_1_846_MHZ   F81534_UART_EN
+#define F81534_CLK_18_46_MHZ   (F81534_UART_EN | BIT(1))
+#define F81534_CLK_24_MHZ  (F81534_UART_EN | BIT(2))
+#define F81534_CLK_14_77_MHZ   (F81534_UART_EN | BIT(1) | BIT(2))
+
 static const struct usb_device_id f81534_id_table[] = {
{ USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) },
{ USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) },
@@ -129,12 +146,18 @@ struct f81534_port_private {
struct usb_serial_port *port;
unsigned long tx_empty;
spinlock_t msr_lock;
+   u32 baud_base;
u8 shadow_mcr;
u8 shadow_lcr;
u8 shadow_msr;
+   u8 shadow_clk;
u8 phy_num;
 };
 
+static u32 const baudrate_table[] = {115200, 921600, 1152000, 150};
+static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, F81534_CLK_14_77_MHZ,
+   F81534_CLK_18_46_MHZ, F81534_CLK_24_MHZ};
+
 static int f81534_logic_to_phy_port(struct usb_serial *serial,
struct usb_serial_port *port)
 {
@@ -460,13 +483,48 @@ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 
clockrate)
return DIV_ROUND_CLOSEST(clockrate, baudrate);
 }
 
-static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate,
-   u8 lcr)
+static int f81534_find_clk(u32 baudrate)
+{
+   int idx;
+
+   for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) {
+   if (baudrate <= baudrate_table[idx] &&
+   baudrate_table[idx] % baudrate == 0)
+   return idx;
+   }
+
+   return -EINVAL;
+}
+
+static int f81534_set_port_config(struct usb_serial_port *port,
+   struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr)
 {
struct f81534_port_private *port_priv = usb_get_serial_port_data(port);
u32 divisor;
int status;
+   int i;
+

[PATCH V2 3/5] usb: serial: f81534: add output pin control

2018-01-03 Thread Ji-Ze Hong (Peter Hong)
The F81532/534 had 3 output pin (M0/SD, M1, M2) with open-drain mode to
control transceiver. We'll read it from internal Flash with address
0x2f05~0x2f08 for 4 ports. The value is range from 0 to 7. The M0/SD is
MSB of this value. For a examples, If read value is 6, we'll write M0/SD,
M1, M2 as 1, 1, 0.

Signed-off-by: Ji-Ze Hong (Peter Hong) 
---
V2:
1: Fix for space between brace.
2: Remain the old pin control method.

 drivers/usb/serial/f81534.c | 67 -
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 8a778bc1d492..7f175f39a171 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -52,6 +52,7 @@
 #define F81534_CUSTOM_NO_CUSTOM_DATA   0xff
 #define F81534_CUSTOM_VALID_TOKEN  0xf0
 #define F81534_CONF_OFFSET 1
+#define F81534_CONF_GPIO_OFFSET4
 
 #define F81534_MAX_DATA_BLOCK  64
 #define F81534_MAX_BUS_RETRY   20
@@ -164,6 +165,23 @@ struct f81534_port_private {
u8 phy_num;
 };
 
+struct f81534_pin_data {
+   const u16 reg_addr;
+   const u16 reg_mask;
+};
+
+struct f81534_port_out_pin {
+   struct f81534_pin_data pin[3];
+};
+
+/* Pin output value for M2/M1/M0(SD) */
+static const struct f81534_port_out_pin f81534_port_out_pins[] = {
+{ { {0x2ae8, BIT(7)}, {0x2a90, BIT(5)}, {0x2a90, BIT(4) } } },
+{ { {0x2ae8, BIT(6)}, {0x2ae8, BIT(0)}, {0x2ae8, BIT(3) } } },
+{ { {0x2a90, BIT(0)}, {0x2ae8, BIT(2)}, {0x2a80, BIT(6) } } },
+{ { {0x2a90, BIT(3)}, {0x2a90, BIT(2)}, {0x2a90, BIT(1) } } },
+};
+
 static u32 const baudrate_table[] = {115200, 921600, 1152000, 150};
 static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, F81534_CLK_14_77_MHZ,
F81534_CLK_18_46_MHZ, F81534_CLK_24_MHZ};
@@ -273,6 +291,22 @@ static int f81534_get_register(struct usb_serial *serial, 
u16 reg, u8 *data)
return status;
 }
 
+static int f81534_set_mask_register(struct usb_serial *serial, u16 reg,
+   u8 mask, u8 data)
+{
+   int status;
+   u8 tmp;
+
+   status = f81534_get_register(serial, reg, );
+   if (status)
+   return status;
+
+   tmp &= ~mask;
+   tmp |= (mask & data);
+
+   return f81534_set_register(serial, reg, tmp);
+}
+
 static int f81534_set_port_register(struct usb_serial_port *port, u16 reg,
u8 data)
 {
@@ -1278,6 +1312,37 @@ static void f81534_lsr_worker(struct work_struct *work)
dev_warn(>dev, "read LSR failed: %d\n", status);
 }
 
+static int f81534_set_port_output_pin(struct usb_serial_port *port)
+{
+   struct f81534_serial_private *serial_priv;
+   struct f81534_port_private *port_priv;
+   struct usb_serial *serial;
+   const struct f81534_port_out_pin *pins;
+   int status;
+   int i;
+   u8 value;
+   u8 idx;
+
+   serial = port->serial;
+   serial_priv = usb_get_serial_data(serial);
+   port_priv = usb_get_serial_port_data(port);
+
+   idx = F81534_CONF_GPIO_OFFSET + port_priv->phy_num;
+   value = serial_priv->conf_data[idx];
+   pins = _port_out_pins[port_priv->phy_num];
+
+   for (i = 0; i < ARRAY_SIZE(pins->pin); ++i) {
+   status = f81534_set_mask_register(serial,
+   pins->pin[i].reg_addr, pins->pin[i].reg_mask,
+   value & BIT(i) ? pins->pin[i].reg_mask : 0);
+   if (status)
+   return status;
+   }
+
+   dev_dbg(>dev, "Output pin (M0/M1/M2): %d\n", value);
+   return 0;
+}
+
 static int f81534_port_probe(struct usb_serial_port *port)
 {
struct f81534_serial_private *serial_priv;
@@ -1335,7 +1400,7 @@ static int f81534_port_probe(struct usb_serial_port *port)
break;
}
 
-   return 0;
+   return f81534_set_port_output_pin(port);
 }
 
 static int f81534_port_remove(struct usb_serial_port *port)
-- 
2.7.4

--
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 4/5] usb: serial: f81534: add H/W disable port support

2018-01-03 Thread Ji-Ze Hong (Peter Hong)
The F81532/534 can be disable port by manufacturer with
following H/W design.
1: Connect DCD/DSR/CTS/RI pin to ground.
2: Connect RX pin to ground.

In driver, we'll implements some detect method likes following:
1: Read MSR.
2: Turn MCR LOOP bit on, off and read LSR after delay with 60ms.
   It'll contain BREAK status in LSR.

Signed-off-by: Ji-Ze Hong (Peter Hong) 
---
V2:
1: f81534_check_port_hw_disabled() change return type from int to bool.
2: Add help function f81534_set_phy_port_register() /
   f81534_get_phy_port_register() for f81534_check_port_hw_disabled()
   to read register without port.
3: Re-write f81534_calc_num_ports() & f81534_attach() to reduce the
   f81534_check_port_hw_disabled() repeatedly called.

 drivers/usb/serial/f81534.c | 160 +++-
 1 file changed, 99 insertions(+), 61 deletions(-)

diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 7f175f39a171..a4666171239a 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -307,6 +307,20 @@ static int f81534_set_mask_register(struct usb_serial 
*serial, u16 reg,
return f81534_set_register(serial, reg, tmp);
 }
 
+static int f81534_set_phy_port_register(struct usb_serial *serial, int phy,
+   u16 reg, u8 data)
+{
+   return f81534_set_register(serial, reg + F81534_UART_OFFSET * phy,
+   data);
+}
+
+static int f81534_get_phy_port_register(struct usb_serial *serial, int phy,
+   u16 reg, u8 *data)
+{
+   return f81534_get_register(serial, reg + F81534_UART_OFFSET * phy,
+   data);
+}
+
 static int f81534_set_port_register(struct usb_serial_port *port, u16 reg,
u8 data)
 {
@@ -730,6 +744,70 @@ static int f81534_find_config_idx(struct usb_serial 
*serial, u8 *index)
 }
 
 /*
+ * The F81532/534 will not report serial port to USB serial subsystem when
+ * H/W DCD/DSR/CTS/RI/RX pin connected to ground.
+ *
+ * To detect RX pin status, we'll enable MCR interal loopback, disable it and
+ * delayed for 60ms. It connected to ground If LSR register report UART_LSR_BI.
+ */
+static bool f81534_check_port_hw_disabled(struct usb_serial *serial, int phy)
+{
+   int status;
+   u8 old_mcr;
+   u8 msr;
+   u8 lsr;
+   u8 msr_mask;
+
+   msr_mask = UART_MSR_DCD | UART_MSR_RI | UART_MSR_DSR | UART_MSR_CTS;
+
+   status = f81534_get_phy_port_register(serial, phy,
+   F81534_MODEM_STATUS_REG, );
+   if (status)
+   return false;
+
+   if ((msr & msr_mask) != msr_mask)
+   return false;
+
+   status = f81534_set_phy_port_register(serial, phy,
+   F81534_FIFO_CONTROL_REG, UART_FCR_ENABLE_FIFO |
+   UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+   if (status)
+   return false;
+
+   status = f81534_get_phy_port_register(serial, phy,
+   F81534_MODEM_CONTROL_REG, _mcr);
+   if (status)
+   return false;
+
+   status = f81534_set_phy_port_register(serial, phy,
+   F81534_MODEM_CONTROL_REG, UART_MCR_LOOP);
+   if (status)
+   return false;
+
+   status = f81534_set_phy_port_register(serial, phy,
+   F81534_MODEM_CONTROL_REG, 0x0);
+   if (status)
+   return false;
+
+   msleep(60);
+
+   status = f81534_get_phy_port_register(serial, phy,
+   F81534_LINE_STATUS_REG, );
+   if (status)
+   return false;
+
+   status = f81534_set_phy_port_register(serial, phy,
+   F81534_MODEM_CONTROL_REG, old_mcr);
+   if (status)
+   return false;
+
+   if ((lsr & UART_LSR_BI) == UART_LSR_BI)
+   return true;
+
+   return false;
+}
+
+/*
  * We had 2 generation of F81532/534 IC. All has an internal storage.
  *
  * 1st is pure USB-to-TTL RS232 IC and designed for 4 ports only, no any
@@ -750,11 +828,10 @@ static int f81534_find_config_idx(struct usb_serial 
*serial, u8 *index)
 static int f81534_calc_num_ports(struct usb_serial *serial,
struct usb_serial_endpoints *epds)
 {
+   struct f81534_serial_private *serial_priv;
struct device *dev = >interface->dev;
int size_bulk_in = usb_endpoint_maxp(epds->bulk_in[0]);
int size_bulk_out = usb_endpoint_maxp(epds->bulk_out[0]);
-   u8 setting[F81534_CUSTOM_DATA_SIZE];
-   u8 setting_idx;
u8 num_port = 0;
int status;
size_t i;
@@ -765,8 +842,15 @@ static int f81534_calc_num_ports(struct usb_serial *serial,
return -ENODEV;
   

[PATCH] usb: do not reset if a low-speed device timed out

2018-01-03 Thread Maxim Moseychuk
Some low-speed devices (for example, bluetooth) do not have
time to initialize. For them, ETIMEDOUT is a valid error.
We need to give them another try. Otherwise, they will
never be initialized correctly and in dmesg will be messages
"Bluetooth: hci0 command 0x1002 tx timeout" or similars.

Fixes: 264904ccc33c ("usb: retry reset if a device times out")
Signed-off-by: Maxim Moseychuk 
---
 drivers/usb/core/hub.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index cf7bbcb9a63c..46366c73f0df 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4524,7 +4524,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device 
*udev, int port1,
 * reset. But only on the first attempt,
 * lest we get into a time out/reset loop
 */
-   if (r == 0  || (r == -ETIMEDOUT && retries == 
0))
+   if (r == 0 ||
+   r == -ETIMEDOUT
+   && retries == 0
+   && udev->speed > USB_SPEED_FULL)
break;
}
udev->descriptor.bMaxPacketSize0 =
-- 
2.15.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] USB: UDC core: fix double-free in usb_add_gadget_udc_release

2018-01-03 Thread Peter Chen
On Wed, Jan 03, 2018 at 12:51:51PM -0500, Alan Stern wrote:
> The error-handling pathways in usb_add_gadget_udc_release() are messed
> up.  Aside from the uninformative statement labels, they can deallocate
> the udc structure after calling put_device(), which is a double-free.
> This was observed by KASAN in automatic testing.
> 
> This patch cleans up the routine.  It preserves the requirement that
> when any failure occurs, we call put_device(>dev).
> 
> Signed-off-by: Alan Stern 
> Reported-by: Fengguang Wu 
> CC: 
> 
> ---
> 
> Not having received any feedback on this patch for a while, I have 
> decided to submit it.  The problem it fixes is quite obviously a real 
> one, when you look at the existing code.
> 
> Alan Stern
> 
> 
> [as1856]
> 
> 
>  drivers/usb/gadget/udc/core.c |   28 +---
>  1 file changed, 13 insertions(+), 15 deletions(-)
> 
> Index: usb-4.x/drivers/usb/gadget/udc/core.c
> ===
> --- usb-4.x.orig/drivers/usb/gadget/udc/core.c
> +++ usb-4.x/drivers/usb/gadget/udc/core.c
> @@ -1147,11 +1147,7 @@ int usb_add_gadget_udc_release(struct de
>  
>   udc = kzalloc(sizeof(*udc), GFP_KERNEL);
>   if (!udc)
> - goto err1;
> -
> - ret = device_add(>dev);
> - if (ret)
> - goto err2;
> + goto err_put_gadget;
>  
>   device_initialize(>dev);
>   udc->dev.release = usb_udc_release;
> @@ -1160,7 +1156,11 @@ int usb_add_gadget_udc_release(struct de
>   udc->dev.parent = parent;
>   ret = dev_set_name(>dev, "%s", kobject_name(>kobj));
>   if (ret)
> - goto err3;
> + goto err_put_udc;
> +
> + ret = device_add(>dev);
> + if (ret)
> + goto err_put_udc;
>  
>   udc->gadget = gadget;
>   gadget->udc = udc;
> @@ -1170,7 +1170,7 @@ int usb_add_gadget_udc_release(struct de
>  
>   ret = device_add(>dev);
>   if (ret)
> - goto err4;
> + goto err_unlist_udc;
>  
>   usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
>   udc->vbus = true;
> @@ -1178,27 +1178,25 @@ int usb_add_gadget_udc_release(struct de
>   /* pick up one of pending gadget drivers */
>   ret = check_pending_gadget_drivers(udc);
>   if (ret)
> - goto err5;
> + goto err_del_udc;
>  
>   mutex_unlock(_lock);
>  
>   return 0;
>  
> -err5:
> + err_del_udc:
>   device_del(>dev);
>  
> -err4:
> + err_unlist_udc:
>   list_del(>list);
>   mutex_unlock(_lock);
>  
> -err3:
> - put_device(>dev);
>   device_del(>dev);
>  
> -err2:
> - kfree(udc);
> + err_put_udc:
> + put_device(>dev);
>  
> -err1:
> + err_put_gadget:
>   put_device(>dev);
>   return ret;
>  }
> 

Reviewed-by: Peter Chen 

-- 

Best Regards,
Peter Chen
--
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: kernel BUG at ./include/linux/mm.h:LINE! (3)

2018-01-03 Thread Pete Zaitcev
On Wed, 3 Jan 2018 13:08:12 -0800
Matthew Wilcox  wrote:

> > +   mutex_lock(>fetch_lock);
> > offset = vmf->pgoff << PAGE_SHIFT;
> > if (offset >= rp->b_size)
> > +   mutex_unlock(>fetch_lock);
> > return VM_FAULT_SIGBUS;
> > chunk_idx = offset / CHUNK_SIZE;  
> 
> missing braces ... maybe you'd rather a 'goto sigbus' approach?

Thanks. What a way to return to kernel programming for me. I'm going
to test it anyway, already started to unpacking a PC, but yeah...

-- Pete
--
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


[BUG] USB mass storage device incomplete read command sequence

2018-01-03 Thread Eduardo Trápani
Usually the kernel reads the pendrive like this:

TEST UNIT READY
READ(10)
...
READ(10)
TEST UNIT READY

But under some conditions, the last TEST UNIT READY is not being sent
and because of that, on this device: Kingston DT 101 G2, the drive's
activity light keeps on blinking even though nothing is being done (no
read/writes/inquiries).

When that happens, manually sending a TEST UNIT READY stops the blinking
and turns off the light.

# sg_turs /dev/sdc

For example this works alright (light blinks for a moment and then it's
off):

# dd if=/dev/sdc of=/dev/null bs=512 count=96

But this doesn't (the light keeps on blinking forever)

# dd if=/dev/sdb of=/dev/null bs=512 count=97

I checked with usbmon and I noticed the lack of the final TEST UNIT
READY in the cases where the light keeps on blinking.

For the tests the drive was unmounted. As soon as I mount it and start
working on it, the light will blink non-stop.

I also tested this with a Raspberry (Linux frambo 4.1.17+ #838 Tue Feb 9
12:57:10 GMT 2016 armv6l GNU/Linux), and the device behaves normally,
that is, blinking stops as soon as traffic stops.


Find attached the pcap file for both cases and part of the kernel dmesg.
This is the kernel with the problem: Linux arbo 4.9.0-4-amd64 #1 SMP
Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64 GNU/Linux

Eduardo.



dd-512x96.pcapng.gz
Description: application/gzip


dd-512x97.pcapng.gz
Description: application/gzip
[10507.724040] usb 6-2: new high-speed USB device number 11 using ehci-pci
[10507.874862] usb 6-2: New USB device found, idVendor=0951, idProduct=1642
[10507.874869] usb 6-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10507.874874] usb 6-2: Product: DT 101 G2
[10507.874878] usb 6-2: Manufacturer: Kingston
[10507.874883] usb 6-2: SerialNumber: 001CC0EC3509FBA0E5FA2390
[10507.875478] usb-storage 6-2:1.0: USB Mass Storage device detected
[10507.877087] scsi host5: usb-storage 6-2:1.0
[10508.984943] scsi 5:0:0:0: Direct-Access Kingston DT 101 G21.00 
PQ: 0 ANSI: 0 CCS
[10508.985800] sd 5:0:0:0: Attached scsi generic sg2 type 0
[10508.986390] sd 5:0:0:0: [sdb] 15644912 512-byte logical blocks: (8.01 
GB/7.46 GiB)
[10508.987281] sd 5:0:0:0: [sdb] Write Protect is off
[10508.987286] sd 5:0:0:0: [sdb] Mode Sense: 0b 00 00 08
[10508.988003] sd 5:0:0:0: [sdb] No Caching mode page found
[10508.988017] sd 5:0:0:0: [sdb] Assuming drive cache: write through
[10508.993180]  sdb: sdb1
[10508.997264] sd 5:0:0:0: [sdb] Attached SCSI removable disk



Re: kernel BUG at ./include/linux/mm.h:LINE! (3)

2018-01-03 Thread Matthew Wilcox
On Wed, Jan 03, 2018 at 03:04:19PM -0600, Pete Zaitcev wrote:
> @@ -1231,12 +1233,15 @@ static int mon_bin_vma_fault(struct vm_fault *vmf)
>   unsigned long offset, chunk_idx;
>   struct page *pageptr;
>  
> + mutex_lock(>fetch_lock);
>   offset = vmf->pgoff << PAGE_SHIFT;
>   if (offset >= rp->b_size)
> + mutex_unlock(>fetch_lock);
>   return VM_FAULT_SIGBUS;
>   chunk_idx = offset / CHUNK_SIZE;

missing braces ... maybe you'd rather a 'goto sigbus' approach?

>   pageptr = rp->b_vec[chunk_idx].pg;
>   get_page(pageptr);
> + mutex_unlock(>fetch_lock);
>   vmf->page = pageptr;
>   return 0;
>  }
> 
> -- Pete
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 
--
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: kernel BUG at ./include/linux/mm.h:LINE! (3)

2018-01-03 Thread Pete Zaitcev
On Wed, 3 Jan 2018 12:26:04 +0300
"Kirill A. Shutemov"  wrote:

> > > +++ b/drivers/usb/mon/mon_bin.c
> > > @@ -1228,15 +1228,24 @@ static void mon_bin_vma_close(struct 
> > > vm_area_struct *vma)
> > >  static int mon_bin_vma_fault(struct vm_fault *vmf)
> > >  {
> > >   struct mon_reader_bin *rp = vmf->vma->vm_private_data;
> > > - unsigned long offset, chunk_idx;
> > > + unsigned long offset, chunk_idx, flags;
> > >   struct page *pageptr;
> > >  
> > > + mutex_lock(>fetch_lock);
> > > + spin_lock_irqsave(>b_lock, flags);
> > >   offset = vmf->pgoff << PAGE_SHIFT;
> > > - if (offset >= rp->b_size)
> > > + if (offset >= rp->b_size) {
> > > + spin_unlock_irqrestore(>b_lock, flags);
> > > + mutex_unlock(>fetch_lock);
> > >   return VM_FAULT_SIGBUS;
> > > + }
> > >   chunk_idx = offset / CHUNK_SIZE;
> > > +
> > >   pageptr = rp->b_vec[chunk_idx].pg;
> > >   get_page(pageptr);
> > > + spin_unlock_irqrestore(>b_lock, flags);
> > > + mutex_unlock(>fetch_lock);
> > > +
> > >   vmf->page = pageptr;
> > >   return 0;
> > >  }  
> > 
> > I think that grabbing the spinlock is not really necessary in
> > this case. [...]
> 
> Please, double check everything. I remember that the mutex wasn't enough
> to stop bug from triggering. But I didn't spend much time understanding
> the code.

I just don't understand why. The only two fields that are used
in the fault routine are rp->b_vec and rp->b_size. They are
protected by the mutex rp->fetch_lock. I don't see anything else
can spill into these fields by dirtying adjacent words in memory,
either except this:

case MON_IOCQ_RING_SIZE:
ret = rp->b_size;
break;

In the old days, this was safe, but who knows what CPUs do today.
It needs the same mutex taken around the read-only reference too.
How about this:

diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index f6ae753ab99b..cb3612f28804 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1004,7 +1004,9 @@ static long mon_bin_ioctl(struct file *file, unsigned int 
cmd, unsigned long arg
break;
 
case MON_IOCQ_RING_SIZE:
+   mutex_lock(>fetch_lock);
ret = rp->b_size;
+   mutex_unlock(>fetch_lock);
break;
 
case MON_IOCT_RING_SIZE:
@@ -1231,12 +1233,15 @@ static int mon_bin_vma_fault(struct vm_fault *vmf)
unsigned long offset, chunk_idx;
struct page *pageptr;
 
+   mutex_lock(>fetch_lock);
offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= rp->b_size)
+   mutex_unlock(>fetch_lock);
return VM_FAULT_SIGBUS;
chunk_idx = offset / CHUNK_SIZE;
pageptr = rp->b_vec[chunk_idx].pg;
get_page(pageptr);
+   mutex_unlock(>fetch_lock);
vmf->page = pageptr;
return 0;
 }

-- Pete
--
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: cp210x Add new device ID ELV ALC 8xxx

2018-01-03 Thread Christian Holl
This adds the ELV ALC 8xxx Battery Charging device
to the list of USB IDs of drivers/usb/serial/cp210x.c

Signed-off-by: Christian Holl 
---
 drivers/usb/serial/cp210x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 7c6273b..ea6e752 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -174,6 +174,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+   { USB_DEVICE(0x18EF, 0xE030) }, /* ELV ALC 8xxx Battery Charger */
{ USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
-- 
2.7.4

--
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: UDC core: fix double-free in usb_add_gadget_udc_release

2018-01-03 Thread Alan Stern
The error-handling pathways in usb_add_gadget_udc_release() are messed
up.  Aside from the uninformative statement labels, they can deallocate
the udc structure after calling put_device(), which is a double-free.
This was observed by KASAN in automatic testing.

This patch cleans up the routine.  It preserves the requirement that
when any failure occurs, we call put_device(>dev).

Signed-off-by: Alan Stern 
Reported-by: Fengguang Wu 
CC: 

---

Not having received any feedback on this patch for a while, I have 
decided to submit it.  The problem it fixes is quite obviously a real 
one, when you look at the existing code.

Alan Stern


[as1856]


 drivers/usb/gadget/udc/core.c |   28 +---
 1 file changed, 13 insertions(+), 15 deletions(-)

Index: usb-4.x/drivers/usb/gadget/udc/core.c
===
--- usb-4.x.orig/drivers/usb/gadget/udc/core.c
+++ usb-4.x/drivers/usb/gadget/udc/core.c
@@ -1147,11 +1147,7 @@ int usb_add_gadget_udc_release(struct de
 
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
if (!udc)
-   goto err1;
-
-   ret = device_add(>dev);
-   if (ret)
-   goto err2;
+   goto err_put_gadget;
 
device_initialize(>dev);
udc->dev.release = usb_udc_release;
@@ -1160,7 +1156,11 @@ int usb_add_gadget_udc_release(struct de
udc->dev.parent = parent;
ret = dev_set_name(>dev, "%s", kobject_name(>kobj));
if (ret)
-   goto err3;
+   goto err_put_udc;
+
+   ret = device_add(>dev);
+   if (ret)
+   goto err_put_udc;
 
udc->gadget = gadget;
gadget->udc = udc;
@@ -1170,7 +1170,7 @@ int usb_add_gadget_udc_release(struct de
 
ret = device_add(>dev);
if (ret)
-   goto err4;
+   goto err_unlist_udc;
 
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
@@ -1178,27 +1178,25 @@ int usb_add_gadget_udc_release(struct de
/* pick up one of pending gadget drivers */
ret = check_pending_gadget_drivers(udc);
if (ret)
-   goto err5;
+   goto err_del_udc;
 
mutex_unlock(_lock);
 
return 0;
 
-err5:
+ err_del_udc:
device_del(>dev);
 
-err4:
+ err_unlist_udc:
list_del(>list);
mutex_unlock(_lock);
 
-err3:
-   put_device(>dev);
device_del(>dev);
 
-err2:
-   kfree(udc);
+ err_put_udc:
+   put_device(>dev);
 
-err1:
+ err_put_gadget:
put_device(>dev);
return ret;
 }

--
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: cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have been dropped

2018-01-03 Thread Greg KH
On Wed, Jan 03, 2018 at 12:59:53PM -0300, Cristian wrote:
> Hello,
> 
> I am testing the development version:
> 4.15.0-041500rc6-generic
> 
> [  116.907874] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
> [  116.907892] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped

Your device is being really noisy and so it was not able to schedule to
handle some data with the networking stack.  Are you seeing any data
loss across this network connection?  If not, don't worry about it.  If
so, maybe there's some way to make it "quiet down"?

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


Re: cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have been dropped

2018-01-03 Thread Cristian
Hello,

All the technical information with the kernel version 4.10:
https://bugs.launchpad.net/bugs/1741080

Regards,
--
Cristian





2018-01-03 12:59 GMT-03:00 Cristian :
> Hello,
>
> I am testing the development version:
> 4.15.0-041500rc6-generic
>
> [  116.907874] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
> [  116.907892] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
> [  118.670851] usbcore: registered new interface driver usbserial_generic
> [  118.670907] usbserial: USB Serial support registered for generic
> [  118.682469] usbcore: registered new interface driver option
> [  118.682502] usbserial: USB Serial support registered for GSM modem (1-port)
> [  121.800651] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
> [  123.518282] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
> [  124.996098] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
> been dropped
>
>
> Regards,
> --
> Cristian
>
>
>
> 2018-01-03 12:49 GMT-03:00 Cristian :
>> Hello,
>>
>> Testing kernel: 4.14.11
>>
>> Regards,
>> --
>> Cristian
>>
>>
>>
>>
>> 2017-12-27 17:05 GMT-03:00 Greg KH :
>>> On Wed, Dec 27, 2017 at 04:07:36PM -0300, Cristian wrote:
 Hello,

 Report:
 https://bugzilla.kernel.org/show_bug.cgi?id=198291

 dmesg:
 [ 5519.779175] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
 [ 5519.779186] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
 [ 5519.779193] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
 [ 5519.785793] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
 [ 5519.785803] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
 [ 5519.819250] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
 been dropped
>>>
>>> 4.13 is long end-of-life, does this happen on 4.14?
>>>
>>> thanks,
>>
>>
>>
>> --
>> Cristian
>
>
>
> --
> Cristian



-- 
Cristian
--
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: cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have been dropped

2018-01-03 Thread Cristian
Hello,

I am testing the development version:
4.15.0-041500rc6-generic

[  116.907874] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
been dropped
[  116.907892] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
been dropped
[  118.670851] usbcore: registered new interface driver usbserial_generic
[  118.670907] usbserial: USB Serial support registered for generic
[  118.682469] usbcore: registered new interface driver option
[  118.682502] usbserial: USB Serial support registered for GSM modem (1-port)
[  121.800651] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
been dropped
[  123.518282] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
been dropped
[  124.996098] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
been dropped


Regards,
--
Cristian



2018-01-03 12:49 GMT-03:00 Cristian :
> Hello,
>
> Testing kernel: 4.14.11
>
> Regards,
> --
> Cristian
>
>
>
>
> 2017-12-27 17:05 GMT-03:00 Greg KH :
>> On Wed, Dec 27, 2017 at 04:07:36PM -0300, Cristian wrote:
>>> Hello,
>>>
>>> Report:
>>> https://bugzilla.kernel.org/show_bug.cgi?id=198291
>>>
>>> dmesg:
>>> [ 5519.779175] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>> [ 5519.779186] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>> [ 5519.779193] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>> [ 5519.785793] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>> [ 5519.785803] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>> [ 5519.819250] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>>> been dropped
>>
>> 4.13 is long end-of-life, does this happen on 4.14?
>>
>> thanks,
>
>
>
> --
> Cristian



-- 
Cristian
[0.00] microcode: microcode updated early to revision 0x29, date = 
2013-06-12
[0.00] Linux version 4.15.0-041500rc6-generic (kernel@kathleen) (gcc 
version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)) #201712312330 SMP Sun Dec 31 23:31:15 
UTC 2017
[0.00] Command line: 
BOOT_IMAGE=/@/boot/vmlinuz-4.15.0-041500rc6-generic 
root=UUID=707d0f89-4b1d-4432-9d50-6058dc4c1ee9 ro rootflags=subvol=@ quiet 
splash vt.handoff=7
[0.00] KERNEL supported cpus:
[0.00]   Intel GenuineIntel
[0.00]   AMD AuthenticAMD
[0.00]   Centaur CentaurHauls
[0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, 
using 'standard' format.
[0.00] e820: BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x-0x0009d7ff] usable
[0.00] BIOS-e820: [mem 0x0009d800-0x0009] reserved
[0.00] BIOS-e820: [mem 0x000e-0x000f] reserved
[0.00] BIOS-e820: [mem 0x0010-0x1fff] usable
[0.00] BIOS-e820: [mem 0x2000-0x201f] reserved
[0.00] BIOS-e820: [mem 0x2020-0x3fff] usable
[0.00] BIOS-e820: [mem 0x4000-0x401f] reserved
[0.00] BIOS-e820: [mem 0x4020-0xc42a9fff] usable
[0.00] BIOS-e820: [mem 0xc42aa000-0xc44abfff] reserved
[0.00] BIOS-e820: [mem 0xc44ac000-0xd33eefff] usable
[0.00] BIOS-e820: [mem 0xd33ef000-0xdaeeefff] reserved
[0.00] BIOS-e820: [mem 0xdaeef000-0xdaf9efff] ACPI NVS
[0.00] BIOS-e820: [mem 0xdaf9f000-0xdaffefff] ACPI data
[0.00] BIOS-e820: [mem 0xdafff000-0xdaff] usable
[0.00] BIOS-e820: [mem 0xdb00-0xdf9f] reserved
[0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved
[0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved
[0.00] BIOS-e820: [mem 0xfed08000-0xfed08fff] reserved
[0.00] BIOS-e820: [mem 0xfed1-0xfed19fff] reserved
[0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
[0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved
[0.00] BIOS-e820: [mem 0xffd0-0x] reserved
[0.00] BIOS-e820: [mem 0x0001-0x00031f5f] usable
[0.00] BIOS-e820: [mem 0x00031f60-0x00031f7f] reserved
[0.00] NX (Execute Disable) protection: active
[0.00] random: fast init done
[0.00] SMBIOS 2.7 present.
[0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. 
530U3C/530U4C/SAMSUNG_NP1234567890, BIOS P14AAJ 04/15/2013
[0.00] e820: update [mem 

Re: cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have been dropped

2018-01-03 Thread Cristian
Hello,

Testing kernel: 4.14.11

Regards,
--
Cristian




2017-12-27 17:05 GMT-03:00 Greg KH :
> On Wed, Dec 27, 2017 at 04:07:36PM -0300, Cristian wrote:
>> Hello,
>>
>> Report:
>> https://bugzilla.kernel.org/show_bug.cgi?id=198291
>>
>> dmesg:
>> [ 5519.779175] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>> [ 5519.779186] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>> [ 5519.779193] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>> [ 5519.785793] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>> [ 5519.785803] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>> [ 5519.819250] cdc_ether 3-2:1.0 enx0c5b8f279a64: kevent 12 may have
>> been dropped
>
> 4.13 is long end-of-life, does this happen on 4.14?
>
> thanks,



-- 
Cristian
[0.00] microcode: microcode updated early to revision 0x29, date = 
2013-06-12
[0.00] Linux version 4.14.11-041411-generic (kernel@kathleen) (gcc 
version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)) #201801022143 SMP Tue Jan 2 21:44:21 UTC 
2018
[0.00] Command line: BOOT_IMAGE=/@/boot/vmlinuz-4.14.11-041411-generic 
root=UUID=707d0f89-4b1d-4432-9d50-6058dc4c1ee9 ro rootflags=subvol=@ quiet 
splash vt.handoff=7
[0.00] KERNEL supported cpus:
[0.00]   Intel GenuineIntel
[0.00]   AMD AuthenticAMD
[0.00]   Centaur CentaurHauls
[0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, 
using 'standard' format.
[0.00] e820: BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x-0x0009d7ff] usable
[0.00] BIOS-e820: [mem 0x0009d800-0x0009] reserved
[0.00] BIOS-e820: [mem 0x000e-0x000f] reserved
[0.00] BIOS-e820: [mem 0x0010-0x1fff] usable
[0.00] BIOS-e820: [mem 0x2000-0x201f] reserved
[0.00] BIOS-e820: [mem 0x2020-0x3fff] usable
[0.00] BIOS-e820: [mem 0x4000-0x401f] reserved
[0.00] BIOS-e820: [mem 0x4020-0xc42a9fff] usable
[0.00] BIOS-e820: [mem 0xc42aa000-0xc44abfff] reserved
[0.00] BIOS-e820: [mem 0xc44ac000-0xd33eefff] usable
[0.00] BIOS-e820: [mem 0xd33ef000-0xdaeeefff] reserved
[0.00] BIOS-e820: [mem 0xdaeef000-0xdaf9efff] ACPI NVS
[0.00] BIOS-e820: [mem 0xdaf9f000-0xdaffefff] ACPI data
[0.00] BIOS-e820: [mem 0xdafff000-0xdaff] usable
[0.00] BIOS-e820: [mem 0xdb00-0xdf9f] reserved
[0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved
[0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved
[0.00] BIOS-e820: [mem 0xfed08000-0xfed08fff] reserved
[0.00] BIOS-e820: [mem 0xfed1-0xfed19fff] reserved
[0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
[0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved
[0.00] BIOS-e820: [mem 0xffd0-0x] reserved
[0.00] BIOS-e820: [mem 0x0001-0x00031f5f] usable
[0.00] BIOS-e820: [mem 0x00031f60-0x00031f7f] reserved
[0.00] NX (Execute Disable) protection: active
[0.00] random: fast init done
[0.00] SMBIOS 2.7 present.
[0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. 
530U3C/530U4C/SAMSUNG_NP1234567890, BIOS P14AAJ 04/15/2013
[0.00] tsc: Fast TSC calibration using PIT
[0.00] e820: update [mem 0x-0x0fff] usable ==> reserved
[0.00] e820: remove [mem 0x000a-0x000f] usable
[0.00] e820: last_pfn = 0x31f600 max_arch_pfn = 0x4
[0.00] MTRR default type: uncachable
[0.00] MTRR fixed ranges enabled:
[0.00]   0-9 write-back
[0.00]   A-B uncachable
[0.00]   C-F write-protect
[0.00] MTRR variable ranges enabled:
[0.00]   0 base 0FFC0 mask FFFC0 write-protect
[0.00]   1 base 0 mask F8000 write-back
[0.00]   2 base 08000 mask FC000 write-back
[0.00]   3 base 0C000 mask FE000 write-back
[0.00]   4 base 0DC00 mask FFC00 uncachable
[0.00]   5 base 0DB00 mask FFF00 uncachable
[0.00]   6 base 1 mask F write-back
[0.00]   7 base 

Re: [-next PATCH 2/4] treewide: Use DEVICE_ATTR_RW

2018-01-03 Thread Bartlomiej Zolnierkiewicz
On Tuesday, December 19, 2017 10:15:07 AM Joe Perches wrote:
> Convert DEVICE_ATTR uses to DEVICE_ATTR_RW where possible.
> 
> Done with perl script:
> 
> $ git grep -w --name-only DEVICE_ATTR | \
>   xargs perl -i -e 'local $/; while (<>) { 
> s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(\s*S_IRUGO\s*\|\s*S_IWUSR|\s*S_IWUSR\s*\|\s*S_IRUGO\s*|\s*0644\s*)\)?\s*,\s*\1_show\s*,\s*\1_store\s*\)/DEVICE_ATTR_RW(\1)/g;
>  print;}'
> 
> Signed-off-by: Joe Perches 
> ---
>  arch/s390/kernel/topology.c  |  3 +--
>  arch/tile/kernel/sysfs.c |  2 +-
>  drivers/gpu/drm/i915/i915_sysfs.c|  6 ++---
>  drivers/platform/x86/compal-laptop.c | 18 +--
>  drivers/s390/cio/device.c|  2 +-
>  drivers/scsi/lpfc/lpfc_attr.c| 43 
> 
>  drivers/thermal/thermal_sysfs.c  |  9 
>  drivers/tty/serial/sh-sci.c  |  2 +-
>  drivers/usb/host/xhci-dbgcap.c   |  2 +-
>  drivers/usb/phy/phy-tahvo.c  |  2 +-
>  drivers/video/fbdev/auo_k190x.c  |  4 ++--
>  drivers/video/fbdev/w100fb.c |  4 ++--
>  lib/test_firmware.c  | 14 +---
>  lib/test_kmod.c  | 14 +---
>  sound/soc/omap/mcbsp.c   |  4 ++--
>  15 files changed, 49 insertions(+), 80 deletions(-)

For fbdev changes:

Acked-by: Bartlomiej Zolnierkiewicz 

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R Institute Poland
Samsung Electronics

--
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 v4 02/16] phy: qcom-qmp: Adapt to clk_bulk_* APIs

2018-01-03 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 2526971..5fed1ae 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;
 
@@ -857,22 +857,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);
@@ -920,9 +917,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;
 }
@@ -932,7 +928,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);
 
@@ -950,8 +945,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;
 }
@@ -1000,29 +994,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[i].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 v4 01/16] phy: qcom-qmp: Fix phy pipe clock gating

2018-01-03 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 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 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index e17f035..2526971 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -751,8 +751,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;
@@ -936,6 +934,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 v4 05/16] phy: qcom-qmp: Fix PHY block reset sequence

2018-01-03 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 1b82cea..ecff261 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -752,13 +752,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
goto err_reg_enable;
}
 
-   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",
@@ -767,6 +770,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);
@@ -791,7 +800,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;
}
}
 
@@ -799,11 +808,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);
 err_reg_enable:
mutex_unlock(>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 v4 03/16] phy: qcom-qmp: Power-on PHY before initialization

2018-01-03 Thread Manu Gautam
PHY regulators which are enabled from power_on() must be ON
before turning-on clocks and initializing it as part of init().
As most of the core drivers perform power_on() after init(), move
PHY regulators enable to com_init() and use power_on() to
only enable pipe_clk. This pipe_clk is output from PHY and some
core drivers e.g. PCIe follow specific sequence after phy_init()
that mandates pipe_clk to be enabled from power_on() only.
On similar lines move clk_enable from init() to com_init() which
executes once for multi lane PHYs.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 5fed1ae..1b82cea 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -724,36 +724,13 @@ 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(>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;
-   }
-
ret = clk_prepare_enable(qphy->pipe_clk);
-   if (ret) {
+   if (ret)
dev_err(qmp->dev, "pipe_clk enable failed, err=%d\n", ret);
-   regulator_bulk_disable(num, qmp->vregs);
-   return ret;
-   }
 
-   return 0;
-}
-
-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;
+   return ret;
 }
 
 static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
@@ -768,6 +745,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) {
+   dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
+   goto err_reg_enable;
+   }
+
+   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) {
@@ -812,6 +802,10 @@ 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);
+err_reg_enable:
mutex_unlock(>phy_mutex);
 
return ret;
@@ -841,6 +835,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(>phy_mutex);
 
return 0;
@@ -861,15 +859,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);
@@ -917,8 +909,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;
 }
@@ -945,8 +935,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;
 }
 
@@ -1060,7 +1048,6 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, 
struct device_node *np)
.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 

[PATCH v4 04/16] phy: qcom-qusb2: Power-on PHY before initialization

2018-01-03 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(>dev, "%s(): Powering-on QUSB2 phy\n", __func__);
+   dev_vdbg(>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(>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(>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(>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 v4 06/16] phy: qcom-qmp: Move SERDES/PCS START after PHY reset

2018-01-03 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 ecff261..edb6bbe 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -896,12 +896,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 v4 07/16] phy: qcom-qusb2: Add support for different register layouts

2018-01-03 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 | 149 +-
 1 file changed, 109 insertions(+), 40 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 4a5b2a1..b65635f 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,27 @@ 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;
+
+   /* true if TUNE1 register must be updated by fused value, else TUNE2 */
+   bool update_tune1_with_efuse;
 };
 
 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,26 +209,32 @@ 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 

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

2018-01-03 Thread Manu Gautam
Update compatible string and clock names for QMP version V3
USB PHY.

Acked-by: Rob Herring 
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 v4 10/16] phy: qcom-qmp: Move register offsets to header file

2018-01-03 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 edb6bbe..2a1117b 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 

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

2018-01-03 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 b65635f..8d0579e 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 */
@@ -142,6 +193,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",
 };
@@ -429,6 +490,9 @@ static int qusb2_phy_exit(struct phy *phy)
{
.compatible = "qcom,msm8996-qusb2-phy",
.data   = _phy_cfg,
+   }, {
+   .compatible = "qcom,qusb2-v2-phy",
+   .data   = _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 v4 11/16] phy: qcom-qmp: Add register offsets for QMP V3 PHY

2018-01-03 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

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

2018-01-03 Thread Manu Gautam
Update generic compatible string for QUSB2 V2 PHY. This will allow
all targets using QUSB2 V2 use same string.

Acked-by: Rob Herring 
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 v4 14/16] phy: Add USB speed related PHY modes

2018-01-03 Thread Manu Gautam
Add following USB speed related PHY modes:
LS (Low Speed), FS (Full Speed), HS (High Speed), SS (Super Speed)

Speed related information is required by some QCOM PHY drivers
to program PHY monitor resume/remote-wakeup events in suspended
state. Speed is needed in order to set correct polarity of wakeup
events for detection. E.g. QUSB2 PHY monitors DP/DM line state
depending on whether speed is LS or FS/HS to detect resume.
Similarly QMP USB3 PHY in SS mode should monitor RX terminations
attach/detach and LFPS events depending on SSPHY is active or not.

Signed-off-by: Manu Gautam 
---
 drivers/phy/phy-core.c  | 15 +++
 include/linux/phy/phy.h | 32 
 2 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index b4964b0..e4f0525 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -357,6 +357,21 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode)
 }
 EXPORT_SYMBOL_GPL(phy_set_mode);
 
+enum phy_mode phy_get_mode(struct phy *phy)
+{
+   enum phy_mode ret;
+
+   if (!phy || !phy->ops->get_mode)
+   return PHY_MODE_INVALID;
+
+   mutex_lock(>mutex);
+   ret = phy->ops->get_mode(phy);
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode);
+
 int phy_reset(struct phy *phy)
 {
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index d8da3e5..4a5cbd0 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -25,7 +25,15 @@
 enum phy_mode {
PHY_MODE_INVALID,
PHY_MODE_USB_HOST,
+   PHY_MODE_USB_HOST_LS,
+   PHY_MODE_USB_HOST_FS,
+   PHY_MODE_USB_HOST_HS,
+   PHY_MODE_USB_HOST_SS,
PHY_MODE_USB_DEVICE,
+   PHY_MODE_USB_DEVICE_LS,
+   PHY_MODE_USB_DEVICE_FS,
+   PHY_MODE_USB_DEVICE_HS,
+   PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
PHY_MODE_SGMII,
PHY_MODE_10GKR,
@@ -40,19 +48,21 @@ enum phy_mode {
  * @power_on: powering on the phy
  * @power_off: powering off the phy
  * @set_mode: set the mode of the phy
+ * @get_mode: get current mode of PHY
  * @reset: resetting the phy
  * @calibrate: calibrate the phy
  * @owner: the module owner containing the ops
  */
 struct phy_ops {
-   int (*init)(struct phy *phy);
-   int (*exit)(struct phy *phy);
-   int (*power_on)(struct phy *phy);
-   int (*power_off)(struct phy *phy);
-   int (*set_mode)(struct phy *phy, enum phy_mode mode);
-   int (*reset)(struct phy *phy);
-   int (*calibrate)(struct phy *phy);
-   struct module *owner;
+   int (*init)(struct phy *phy);
+   int (*exit)(struct phy *phy);
+   int (*power_on)(struct phy *phy);
+   int (*power_off)(struct phy *phy);
+   int (*set_mode)(struct phy *phy, enum phy_mode mode);
+   enum phy_mode   (*get_mode)(struct phy *phy);
+   int (*reset)(struct phy *phy);
+   int (*calibrate)(struct phy *phy);
+   struct module   *owner;
 };
 
 /**
@@ -144,6 +154,7 @@ static inline void *phy_get_drvdata(struct phy *phy)
 int phy_power_on(struct phy *phy);
 int phy_power_off(struct phy *phy);
 int phy_set_mode(struct phy *phy, enum phy_mode mode);
+enum phy_mode phy_get_mode(struct phy *phy);
 int phy_reset(struct phy *phy);
 int phy_calibrate(struct phy *phy);
 static inline int phy_get_bus_width(struct phy *phy)
@@ -260,6 +271,11 @@ static inline int phy_set_mode(struct phy *phy, enum 
phy_mode mode)
return -ENOSYS;
 }
 
+static inline enum phy_mode phy_get_mode(struct phy *phy)
+{
+   return PHY_MODE_INVALID;
+}
+
 static inline int phy_reset(struct phy *phy)
 {
if (!phy)
-- 
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 v4 16/16] phy: qcom-qmp: Add support for runtime PM

2018-01-03 Thread Manu Gautam
Disable clocks and enable PHY autonomous mode to detect
wakeup events when PHY is suspended.
Core driver should notify speed to PHY driver to enable
LFPS and/or RX_DET interrupts.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 55b8397..ad3251b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -61,6 +61,19 @@
 #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 */
 
 #define PHY_INIT_COMPLETE_TIMEOUT  1000
 #define POWER_DOWN_DELAY_US_MIN10
@@ -108,6 +121,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[] = {
@@ -135,12 +151,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[] = {
@@ -536,6 +558,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
@@ -546,6 +569,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;
@@ -567,6 +591,8 @@ struct qmp_phy {
  * @phys: array of per-lane phy descriptors
  * @phy_mutex: mutex lock for PHY common block initialization
  * @init_count: phy common block initialization count
+ * @phy_initialized: indicate if PHY has been initialized
+ * @mode: current PHY mode
  */
 struct qcom_qmp {
struct device *dev;
@@ -582,6 +608,8 @@ struct qcom_qmp {
 
struct mutex phy_mutex;
int init_count;
+   bool phy_initialized;
+   enum phy_mode mode;
 };
 
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -995,6 +1023,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
dev_err(qmp->dev, "phy initialization timed-out\n");
goto err_pcs_ready;
}
+   qmp->phy_initialized = true;
 
return ret;
 
@@ -1029,6 +1058,136 @@ static int qcom_qmp_phy_exit(struct phy *phy)
 
qcom_qmp_phy_com_exit(qmp);
 
+   qmp->phy_initialized = false;
+
+   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;
+
+   return 0;
+}
+
+static enum phy_mode qcom_qmp_phy_get_mode(struct phy *phy)
+{
+   struct qmp_phy *qphy = phy_get_drvdata(phy);
+   struct qcom_qmp *qmp = qphy->qmp;
+
+   return qmp->mode;
+}
+
+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;
+   u32 intr_mask;
+
+   if (qmp->mode == PHY_MODE_USB_HOST_SS ||
+   qmp->mode == PHY_MODE_USB_DEVICE_SS)
+   intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
+   else
+   

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

2018-01-03 Thread Manu Gautam
QMP V3 USB3 PHY is a DisplayPort (DP) and 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 | 223 +++-
 1 file changed, 220 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2a1117b..55b8397 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 

[PATCH v4 15/16] phy: qcom-qusb2: Add support for runtime PM

2018-01-03 Thread Manu Gautam
Disable clocks and enable DP/DM wakeup interrupts when
suspending PHY.
Core driver should notify speed to PHY driver to enable
appropriate DP/DM wakeup interrupts polarity in suspend state.

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

diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c 
b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 8d0579e..3a9e4bd 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
@@ -93,6 +105,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,
@@ -112,8 +125,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[] = {
@@ -133,14 +148,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[] = {
@@ -175,12 +193,16 @@ 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 TUNE1 register must be updated by fused value, else TUNE2 */
bool update_tune1_with_efuse;
+
+   /* 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 = {
@@ -191,6 +213,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 = {
@@ -201,6 +224,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[] = {
@@ -226,6 +251,8 @@ 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: current PHY mode
  */
 struct qusb2_phy {
struct phy *phy;
@@ -242,6 +269,8 @@ struct qusb2_phy {
 
const struct qusb2_phy_cfg *cfg;
bool has_se_clk_scheme;
+   bool phy_initialized;
+   enum phy_mode mode;
 };
 
 static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
@@ -317,6 +346,140 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy 
*qphy)
 
 }
 
+static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+   struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+   qphy->mode = mode;
+
+   return 0;
+}
+
+static enum phy_mode qusb2_phy_get_mode(struct phy *phy)
+{
+   struct qusb2_phy *qphy = phy_get_drvdata(phy);
+
+   return qphy->mode;
+}
+
+static int __maybe_unused 

[PATCH v4 00/16] Support for Qualcomm QUSBv2 and QMPv3 USB PHYs

2018-01-03 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 v3:
- Add extra PHY_MODEs for updating USB speed instead of adding
  new callback.
- Continue to use power_on() for QMP driver as pci-qcom driver
  initialization sequence requires pipe_clk to enabled as part
  of power_on().
- Fix bug in the usage clk_bulk_ APIs in QMP driver.
- Update handling of fuse values for tune1 parameter in QUSB2
  driver for v2 PHY.
- Incorporated other review comments.

Changes since v2:
- Drop sw-vbus override related patches as dwc3 glue driver to
  take care of same.
- Don't read current linestate but rather rely on current speed
  which will be notified by core driver. This is required to
  have correct polarity of wakeup events detection in PHY.

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 override 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 (14):
  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: Add USB speed related PHY modes
  phy: qcom-qusb2: Add support for runtime PM
  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/phy-core.c |  15 +
 drivers/phy/qualcomm/phy-qcom-qmp.c| 645 +++--
 drivers/phy/qualcomm/phy-qcom-qmp.h| 289 +
 drivers/phy/qualcomm/phy-qcom-qusb2.c  | 416 +++--
 include/linux/phy/phy.h|  32 +-
 7 files changed, 1149 insertions(+), 259 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


Re: kernel BUG at ./include/linux/mm.h:LINE! (3)

2018-01-03 Thread Kirill A. Shutemov
On Wed, Jan 03, 2018 at 01:02:38AM -0600, Pete Zaitcev wrote:
> On Fri, 29 Dec 2017 16:24:20 +0300
> "Kirill A. Shutemov"  wrote:
> 
> > Looks like MON_IOCT_RING_SIZE reallocates ring buffer without any
> > serialization wrt mon_bin_vma_fault(). By the time of get_page() the page
> > may be freed.
> 
> Okay. Who knew that you could fork while holding an open descriptor. :-)

It's threads. But yeah.

> > The patch below seems help the crash to go away, but I *think* more work
> > is required. For instance, after ring buffer reallocation the old pages
> > will stay mapped. Nothing pulls them.
> 
> You know, this bothered me all these years too, but I was assured
> back in the day (as much as I can remember), that doing get_page()
> in the .fault() is just the right thing. In my defense, you can
> see other drivers doing it, such as:
> 
> ./drivers/char/agp/alpha-agp.c
> ./drivers/hsi/clients/cmt_speech.c
> 
> I'd appreciate insight from someone who knows how VM subsystem works.

get_page() is not a problem. It's right thing to do in ->fault.

After more thought, I think it's not a problem at all. As long as
userspace is aware that old mapping is no good after changing size of the
buffer everything would work fine. Even if userspace would use old mapping
nothing bad would happen from kernel POV.  Just userspace may see
old/inconsistent data. But there's no crashes or such.

> Now, about the code:
> 
> > diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
> > index f6ae753ab99b..ac168fecf04f 100644
> > --- a/drivers/usb/mon/mon_bin.c
> > +++ b/drivers/usb/mon/mon_bin.c
> > @@ -1228,15 +1228,24 @@ static void mon_bin_vma_close(struct vm_area_struct 
> > *vma)
> >  static int mon_bin_vma_fault(struct vm_fault *vmf)
> >  {
> > struct mon_reader_bin *rp = vmf->vma->vm_private_data;
> > -   unsigned long offset, chunk_idx;
> > +   unsigned long offset, chunk_idx, flags;
> > struct page *pageptr;
> >  
> > +   mutex_lock(>fetch_lock);
> > +   spin_lock_irqsave(>b_lock, flags);
> > offset = vmf->pgoff << PAGE_SHIFT;
> > -   if (offset >= rp->b_size)
> > +   if (offset >= rp->b_size) {
> > +   spin_unlock_irqrestore(>b_lock, flags);
> > +   mutex_unlock(>fetch_lock);
> > return VM_FAULT_SIGBUS;
> > +   }
> > chunk_idx = offset / CHUNK_SIZE;
> > +
> > pageptr = rp->b_vec[chunk_idx].pg;
> > get_page(pageptr);
> > +   spin_unlock_irqrestore(>b_lock, flags);
> > +   mutex_unlock(>fetch_lock);
> > +
> > vmf->page = pageptr;
> > return 0;
> >  }
> 
> I think that grabbing the spinlock is not really necessary in
> this case. The ->b_lock is designed for things that are accessed
> from interrupts that Host Controller Driver serves -- mostly
> various pointers. By defintion it's not covering things that
> are related to re-allocation. Now, the re-allocation itself
> grabs it, because it resets indexes into the new buffer, but
> does not appear to apply here, does it now?

Please, double check everything. I remember that the mutex wasn't enough
to stop bug from triggering. But I didn't spend much time understanding
the code.

-- 
 Kirill A. Shutemov
--
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][next] usbip: vhci: fix spelling mistake: "synchronuously" -> "synchronously"

2018-01-03 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake in dev_dbg debug message.

Signed-off-by: Colin Ian King 
---
 drivers/usb/usbip/vhci_rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c
index 112ebb90d8c9..44cd64518925 100644
--- a/drivers/usb/usbip/vhci_rx.c
+++ b/drivers/usb/usbip/vhci_rx.c
@@ -30,7 +30,7 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device 
*vdev, __u32 seqnum)
/* fall through */
case -ECONNRESET:
dev_dbg(>dev->dev,
-"urb seq# %u was unlinked %ssynchronuously\n",
+"urb seq# %u was unlinked %ssynchronously\n",
 seqnum, status == -ENOENT ? "" : "a");
break;
case -EINPROGRESS:
-- 
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


[v2 PATCH 5/6] dt-bindings: usb: mtk-xhci: update USB wakeup properties

2018-01-03 Thread Chunfeng Yun
Add two arguments in "mediatek,syscon-wakeup" to support multi
wakeup glue layer between SSUSB and SPM, and use standard property
"wakeup-source" to replace the private "mediatek,wakeup-src"

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

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
index 3059596..5842868 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
@@ -35,10 +35,14 @@ Required properties:
  - phys : a list of phandle + phy specifier pairs
 
 Optional properties:
- - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
-   mode;
- - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
-   control register, it depends on "mediatek,wakeup-src".
+ - wakeup-source : enable USB remote wakeup;
+ - mediatek,syscon-wakeup : phandle to syscon used to access the register
+   of the USB wakeup glue layer between xHCI and SPM; it depends on
+   "wakeup-source", and has two arguments:
+   - the first one : register base address of the glue layer in syscon;
+   - the second one : hardware version of the glue layer
+   - 1 : used by mt8173 etc
+   - 2 : used by mt2712 etc
  - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
bit1 for u3port1, ... etc;
  - vbus-supply : reference to the VBUS regulator;
@@ -64,8 +68,8 @@ usb30: usb@1127 {
vusb33-supply = <_vusb_reg>;
vbus-supply = <_p1_vbus>;
usb3-lpm-capable;
-   mediatek,syscon-wakeup = <>;
-   mediatek,wakeup-src = <1>;
+   mediatek,syscon-wakeup = < 0x400 1>;
+   wakeup-source;
 };
 
 2nd: dual-role mode with xHCI driver
-- 
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


[v2 PATCH 4/6] usb: xhci-mtk: supports remote wakeup for mt2712 with two xHCI IPs

2018-01-03 Thread Chunfeng Yun
The old way of usb wakeup only supports platform with single xHCI IP,
such as mt8173, but mt2712 has two xHCI IPs, so rebuild its flow and
supports the new glue layer of usb wakeup on mt2712 which is different
from mt8173.
Due to there is a hardware bug with the LINE STATE wakeup mode on
mt8173 which causes wakeup failure by low speed devices, and also
because IP SLEEP mode can cover all functions of LINE STATE mode,
it is unused in fact, and will not support it later, so remove it at
the same time.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/host/xhci-mtk.c | 177 +++-
 drivers/usb/host/xhci-mtk.h |   6 +-
 2 files changed, 65 insertions(+), 118 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index b62a1d2..53187ff 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -57,26 +57,21 @@
 /* u2_phy_pll register */
 #define CTRL_U2_FORCE_PLL_STB  BIT(28)
 
-#define PERI_WK_CTRL0  0x400
-#define UWK_CTR0_0P_LS_PE  BIT(8)  /* posedge */
-#define UWK_CTR0_0P_LS_NE  BIT(7)  /* negedge for 0p linestate*/
-#define UWK_CTL1_1P_LS_C(x)(((x) & 0xf) << 1)
-#define UWK_CTL1_1P_LS_E   BIT(0)
-
-#define PERI_WK_CTRL1  0x404
-#define UWK_CTL1_IS_C(x)   (((x) & 0xf) << 26)
-#define UWK_CTL1_IS_E  BIT(25)
-#define UWK_CTL1_0P_LS_C(x)(((x) & 0xf) << 21)
-#define UWK_CTL1_0P_LS_E   BIT(20)
-#define UWK_CTL1_IDDIG_C(x)(((x) & 0xf) << 11)  /* cycle debounce */
-#define UWK_CTL1_IDDIG_E   BIT(10) /* enable debounce */
-#define UWK_CTL1_IDDIG_P   BIT(9)  /* polarity */
-#define UWK_CTL1_0P_LS_P   BIT(7)
-#define UWK_CTL1_IS_P  BIT(6)  /* polarity for ip sleep */
-
-enum ssusb_wakeup_src {
-   SSUSB_WK_IP_SLEEP = 1,
-   SSUSB_WK_LINE_STATE = 2,
+/* usb remote wakeup registers in syscon */
+/* mt8173 etc */
+#define PERI_WK_CTRL1  0x4
+#define WC1_IS_C(x)(((x) & 0xf) << 26)  /* cycle debounce */
+#define WC1_IS_EN  BIT(25)
+#define WC1_IS_P   BIT(6)  /* polarity for ip sleep */
+
+/* mt2712 etc */
+#define PERI_SSUSB_SPM_CTRL0x0
+#define SSC_IP_SLEEP_ENBIT(4)
+#define SSC_SPM_INT_EN BIT(1)
+
+enum ssusb_uwk_vers {
+   SSUSB_UWK_V1 = 1,
+   SSUSB_UWK_V2,
 };
 
 static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
@@ -296,112 +291,58 @@ static void xhci_mtk_clks_disable(struct xhci_hcd_mtk 
*mtk)
 }
 
 /* only clocks can be turn off for ip-sleep wakeup mode */
-static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
+static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable)
 {
-   u32 tmp;
-   struct regmap *pericfg = mtk->pericfg;
-
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   tmp &= ~UWK_CTL1_IS_P;
-   tmp &= ~(UWK_CTL1_IS_C(0xf));
-   tmp |= UWK_CTL1_IS_C(0x8);
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp);
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
-
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
-   __func__, tmp);
+   u32 reg, msk, val;
+
+   switch (mtk->uwk_vers) {
+   case SSUSB_UWK_V1:
+   reg = mtk->uwk_reg_base + PERI_WK_CTRL1;
+   msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
+   val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
+   break;
+   case SSUSB_UWK_V2:
+   reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
+   msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
+   val = enable ? msk : 0;
+   break;
+   default:
+   return;
+   };
+   regmap_update_bits(mtk->uwk, reg, msk, val);
 }
 
-static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
+static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
+   struct device_node *dn)
 {
-   u32 tmp;
+   struct of_phandle_args args;
+   int ret;
 
-   regmap_read(mtk->pericfg, PERI_WK_CTRL1, );
-   tmp &= ~UWK_CTL1_IS_E;
-   regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
-}
+   /* Wakeup function is optional */
+   mtk->uwk_en = of_property_read_bool(dn, "wakeup-source");
+   if (!mtk->uwk_en)
+   return 0;
 
-/*
-* for line-state wakeup mode, phy's power should not power-down
-* and only support cable plug in/out
-*/
-static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
-{
-   u32 tmp;
-   struct regmap *pericfg = mtk->pericfg;
-
-   /* line-state of u2-port0 */
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   tmp &= ~UWK_CTL1_0P_LS_P;
-   tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
-   tmp |= UWK_CTL1_0P_LS_C(0x8);
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp);
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
-
-   /* line-state of u2-port1 */
-   

[v2 PATCH 1/6] usb: mtu3: fix error code for getting extcon device

2018-01-03 Thread Chunfeng Yun
When failing to get extcon device, extcon_get_edev_by_phandle()
may return different error codes, but not only -EPROBE_DEFER,
so can't always return -EPROBE_DEFER, and fix it.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3_plat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 3650fd1..5b2110b 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -308,7 +308,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, 
struct ssusb_mtk *ssusb)
otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0);
if (IS_ERR(otg_sx->edev)) {
dev_err(ssusb->dev, "couldn't get extcon device\n");
-   return -EPROBE_DEFER;
+   return PTR_ERR(otg_sx->edev);
}
}
 
-- 
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


[v2 PATCH 2/6] usb: mtu3: supports remote wakeup for mt2712 with two SSUSB IPs

2018-01-03 Thread Chunfeng Yun
The old way of usb wakeup only supports platform with single SSUSB IP,
such as mt8173, but mt2712 has two SSUSB IPs, so rebuild its flow and
also supports the new glue layer of usb wakeup on mt2712 which is
different from mt8173.

Signed-off-by: Chunfeng Yun 
---
 drivers/usb/mtu3/mtu3.h  |  11 +++--
 drivers/usb/mtu3/mtu3_dr.h   |   3 +-
 drivers/usb/mtu3/mtu3_host.c | 115 +--
 drivers/usb/mtu3/mtu3_plat.c |   8 +--
 4 files changed, 70 insertions(+), 67 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 3c888d9..2cd00a2 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -229,7 +229,10 @@ struct otg_switch_mtk {
  * @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
+ * @uwk_en: it's true when supports remote wakeup in host mode
+ * @uwk: syscon including usb wakeup glue layer between SSUSB IP and SPM
+ * @uwk_reg_base: the base address of the wakeup glue layer in @uwk
+ * @uwk_vers: the version of the wakeup glue layer
  */
 struct ssusb_mtk {
struct device *dev;
@@ -253,8 +256,10 @@ struct ssusb_mtk {
int u3p_dis_msk;
struct dentry *dbgfs_root;
/* usb wakeup for host mode */
-   bool wakeup_en;
-   struct regmap *pericfg;
+   bool uwk_en;
+   struct regmap *uwk;
+   u32 uwk_reg_base;
+   u32 uwk_vers;
 };
 
 /**
diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h
index c179192..ae1598d 100644
--- a/drivers/usb/mtu3/mtu3_dr.h
+++ b/drivers/usb/mtu3/mtu3_dr.h
@@ -18,8 +18,7 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
struct device_node *dn);
 int ssusb_host_enable(struct ssusb_mtk *ssusb);
 int ssusb_host_disable(struct ssusb_mtk *ssusb, bool suspend);
-int ssusb_wakeup_enable(struct ssusb_mtk *ssusb);
-void ssusb_wakeup_disable(struct ssusb_mtk *ssusb);
+void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable);
 
 #else
 
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
index d237d7e..259beef 100644
--- a/drivers/usb/mtu3/mtu3_host.c
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -18,66 +18,77 @@
 #include "mtu3.h"
 #include "mtu3_dr.h"
 
-#define PERI_WK_CTRL1  0x404
-#define UWK_CTL1_IS_C(x)   (((x) & 0xf) << 26)
-#define UWK_CTL1_IS_E  BIT(25)
-#define UWK_CTL1_IDDIG_C(x)(((x) & 0xf) << 11)  /* cycle debounce */
-#define UWK_CTL1_IDDIG_E   BIT(10) /* enable debounce */
-#define UWK_CTL1_IDDIG_P   BIT(9)  /* polarity */
-#define UWK_CTL1_IS_P  BIT(6)  /* polarity for ip sleep */
+/* mt8173 etc */
+#define PERI_WK_CTRL1  0x4
+#define WC1_IS_C(x)(((x) & 0xf) << 26)  /* cycle debounce */
+#define WC1_IS_EN  BIT(25)
+#define WC1_IS_P   BIT(6)  /* polarity for ip sleep */
+
+/* mt2712 etc */
+#define PERI_SSUSB_SPM_CTRL0x0
+#define SSC_IP_SLEEP_ENBIT(4)
+#define SSC_SPM_INT_EN BIT(1)
+
+enum ssusb_uwk_vers {
+   SSUSB_UWK_V1 = 1,
+   SSUSB_UWK_V2,
+};
 
 /*
  * ip-sleep wakeup mode:
  * all clocks can be turn off, but power domain should be kept on
  */
-static void ssusb_wakeup_ip_sleep_en(struct ssusb_mtk *ssusb)
+static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable)
 {
-   u32 tmp;
-   struct regmap *pericfg = ssusb->pericfg;
-
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   tmp &= ~UWK_CTL1_IS_P;
-   tmp &= ~(UWK_CTL1_IS_C(0xf));
-   tmp |= UWK_CTL1_IS_C(0x8);
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp);
-   regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
-
-   regmap_read(pericfg, PERI_WK_CTRL1, );
-   dev_dbg(ssusb->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
-   __func__, tmp);
-}
-
-static void ssusb_wakeup_ip_sleep_dis(struct ssusb_mtk *ssusb)
-{
-   u32 tmp;
-
-   regmap_read(ssusb->pericfg, PERI_WK_CTRL1, );
-   tmp &= ~UWK_CTL1_IS_E;
-   regmap_write(ssusb->pericfg, PERI_WK_CTRL1, tmp);
+   u32 reg, msk, val;
+
+   switch (ssusb->uwk_vers) {
+   case SSUSB_UWK_V1:
+   reg = ssusb->uwk_reg_base + PERI_WK_CTRL1;
+   msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
+   val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
+   break;
+   case SSUSB_UWK_V2:
+   reg = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
+   msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
+   val = enable ? msk : 0;
+   break;
+   default:
+   return;
+   };
+   regmap_update_bits(ssusb->uwk, reg, msk, val);
 }
 
 int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
struct device_node *dn)
 {
-   struct 

[v2 PATCH 3/6] dt-bindings: usb: mtu3: update USB wakeup properties

2018-01-03 Thread Chunfeng Yun
Add two arguments in "mediatek,syscon-wakeup" to support multi
wakeup glue layer between SSUSB and SPM, and use standard property
"wakeup-source" to replace the private "mediatek,enable-wakeup"

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

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt 
b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
index b2271d8..d589a1e 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
@@ -42,9 +42,14 @@ Optional properties:
  - enable-manual-drd : supports manual dual-role switch via debugfs; usually
used when receptacle is TYPE-A and also wants to support dual-role
mode.
- - 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".
+ - wakeup-source: enable USB remote wakeup of host mode.
+ - mediatek,syscon-wakeup : phandle to syscon used to access the register
+   of the USB wakeup glue layer between SSUSB and SPM; it depends on
+   "wakeup-source", and has two arguments:
+   - the first one : register base address of the glue layer in syscon;
+   - the second one : hardware version of the glue layer
+   - 1 : used by mt8173 etc
+   - 2 : used by mt2712 etc
  - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
bit1 for u3port1, ... etc;
 
@@ -71,8 +76,8 @@ ssusb: usb@11271000 {
vbus-supply = <_p0_vbus>;
extcon = <_usb>;
dr_mode = "otg";
-   mediatek,enable-wakeup;
-   mediatek,syscon-wakeup = <>;
+   wakeup-source;
+   mediatek,syscon-wakeup = < 0x400 1>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
-- 
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


[v2 PATCH 6/6] arm64: dts: mt8173: update properties about USB wakeup

2018-01-03 Thread Chunfeng Yun
Use new binding about USB wakeup which now supports multi USB
wakeup glue layer between SSUSB and SPM.
Meanwhile remove dummy clocks of USB wakeup.

Signed-off-by: Chunfeng Yun 
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |  2 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi| 12 +++-
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 1c3634f..0acba1f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -505,7 +505,7 @@
vbus-supply = <_p0_vbus>;
extcon = <_usb>;
dr_mode = "otg";
-   mediatek,enable-wakeup;
+   wakeup-source;
pinctrl-names = "default", "id_float", "id_ground";
pinctrl-0 = <_id_pins_float>;
pinctrl-1 = <_id_pins_float>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 26396ef..9263d9f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -731,15 +731,9 @@
   < PHY_TYPE_USB3>,
   < PHY_TYPE_USB2>;
power-domains = < MT8173_POWER_DOMAIN_USB>;
-   clocks = < CLK_TOP_USB30_SEL>,
-<>,
-< CLK_PERI_USB0>,
-< CLK_PERI_USB1>;
-   clock-names = "sys_ck",
- "ref_ck",
- "wakeup_deb_p0",
- "wakeup_deb_p1";
-   mediatek,syscon-wakeup = <>;
+   clocks = < CLK_TOP_USB30_SEL>, <>;
+   clock-names = "sys_ck", "ref_ck";
+   mediatek,syscon-wakeup = < 0x400 1>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
-- 
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