Re: [PATCH] usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub

2018-05-21 Thread Doug Anderson
Hi,

On Mon, May 21, 2018 at 3:12 AM, William Wu  wrote:
> The dwc2_get_ls_map() use ttport to reference into the
> bitmap if we're on a multi_tt hub. But the bitmaps index
> from 0 to (hub->maxchild - 1), while the ttport index from
> 1 to hub->maxchild. This will cause invalid memory access
> when the number of ttport is hub->maxchild.
>
> Without this patch, I can easily meet a Kernel panic issue
> if connect a low-speed USB mouse with the max port of FE2.1
> multi-tt hub (1a40:0201) on rk3288 platform.
>
> Signed-off-by: William Wu 
> ---
>  drivers/usb/dwc2/hcd_queue.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
> index d7c3d6c..9c55d1a 100644
> --- a/drivers/usb/dwc2/hcd_queue.c
> +++ b/drivers/usb/dwc2/hcd_queue.c
> @@ -383,7 +383,7 @@ static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg 
> *hsotg,
> /* Get the map and adjust if this is a multi_tt hub */
> map = qh->dwc_tt->periodic_bitmaps;
> if (qh->dwc_tt->usb_tt->multi)
> -   map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
> +   map += DWC2_ELEMENTS_PER_LS_BITMAP * (qh->ttport - 1);

Oops, thanks for the fix.

Fixes: 9f9f09b048f5 ("usb: dwc2: host: Totally redo the microframe scheduler")
Cc: sta...@vger.kernel.org
Reviewed-by: Douglas Anderson 

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


Re: [PATCH 01/33] usb: phy: use match_string() helper

2018-05-21 Thread Andy Shevchenko
On Mon, May 21, 2018 at 2:57 PM, Yisheng Xie  wrote:
> match_string() returns the index of an array for a matching string,
> which can be used intead of open coded variant.

> -   int err, i;
> +   int ret;

int err;

would still work.

-- 
With Best Regards,
Andy Shevchenko
--
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: Not enough bandwidth with Magewell XI100DUSB-HDMI

2018-05-21 Thread Curt Meyers


On 05/16/2018 04:55 AM, Mathias Nyman wrote:

On 15.05.2018 12:22, Michael Tretter wrote:

Hi Mathias,

On Tue, 10 Apr 2018 18:22:03 +0300, Mathias Nyman wrote:

On 09.04.2018 11:21, Michael Tretter wrote:

On Tue, 20 Feb 2018 15:29:28 +0200, Mathias Nyman wrote:

On 16.02.2018 15:28, Michael Tretter wrote:

On Mon, 29 Jan 2018 14:02:57 +0200, Mathias Nyman wrote:

On 19.01.2018 22:12, Philipp Zabel wrote:

On Fri, Jan 19, 2018 at 2:10 PM, Michael Tretter
 wrote:
I found the old thread and it sounds exactly like my issue. 
Different

camera, but same xHCI controller.


I have exactly the same issue with the xHCI controller of my 
laptop and

"Oculus Sensor" USB3 isochronous mostly-UVC cameras:

00:14.0 USB controller: Intel Corporation Wildcat Point-LP USB 
xHCI

Controller (rev 03) (prog-if 30 [XHCI])
    Subsystem: Lenovo Wildcat Point-LP USB xHCI Controller
    Flags: bus master, medium devsel, latency 0, IRQ 44
    Memory at f222 (64-bit, non-prefetchable) [size=64K]
    Capabilities: [70] Power Management version 2
    Capabilities: [80] MSI: Enable+ Count=1/8 Maskable- 64bit+
    Kernel driver in use: xhci_hcd
    Kernel modules: xhci_pci

T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=5000 MxCh= 0
D:  Ver= 3.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs=  1
P:  Vendor=2833 ProdID=0211 Rev= 0.00
S:  Manufacturer=Oculus VR
S:  Product=Rift Sensor
S:  SerialNumber=WMTD3034300BCT
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=800mA
A:  FirstIf#= 0 IfCount= 2 Cls=ff(vend.) Sub=03 Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=01 Prot=00 
Driver=uvcvideo

E:  Ad=83(I) Atr=03(Int.) MxPS=  32 Ivl=128ms
I:* If#= 1 Alt= 0 #EPs= 0 Cls=ff(vend.) Sub=02 Prot=00 
Driver=uvcvideo
I:  If#= 1 Alt= 1 #EPs= 1 Cls=ff(vend.) Sub=02 Prot=00 
Driver=uvcvideo

E:  Ad=81(I) Atr=05(Isoc) MxPS=1024 Ivl=125us
I:  If#= 1 Alt= 2 #EPs= 1 Cls=ff(vend.) Sub=02 Prot=00 
Driver=uvcvideo

E:  Ad=81(I) Atr=05(Isoc) MxPS=1024 Ivl=125us

Any USB2 or USB3 device that I plug in while the first camera 
is streaming in
altsetting 1 or 2 causes the bandwidth error. The same happens 
when I try to
change the altsetting on an isochronous endpoint of an already 
plugged device.
While the camera is in altsetting 0, other devices can be 
probed and work.
For some tests, I changed the xhci_change_max_exit_latency() 
function
to ignore the requested MEL and set the MEL to 0. Now the USB 
devices

are detected correctly.


Exactly the same thing helps here, as well. With this hack, 
streaming from two
of those cameras at the same time works without any apparent 
problem:


--8<--
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 297536c9fd00..3cb4a60d8822 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4025,7 +4025,7 @@ static int __maybe_unused
xhci_change_max_exit_latency(struct xhci_hcd *xhci,
    ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
    slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx);
    slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT));
-   slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency);
+   slot_ctx->dev_info2 |= cpu_to_le32(0);
    slot_ctx->dev_state = 0;

    xhci_dbg_trace(xhci, trace_xhci_dbg_context_change,
-->8--


Ok, back after a week on sickleave.
I'm getting the magewell capture device and try to reproduce 
this myself.


I don't think that the issue is specific to the magewell capture
device, but rather should be reproducible with any USB3 device with
isochronous endpoints.

Anyway, please tell me, if I can somehow help you to get this 
properly

fixed.


I'm currently looking at device reset issues after suspend, but 
this is on the

todo list.

I got a magewell device, (haven't unboxed it yet)
Maybe step by step instructions to reproduce it could speed things 
up.


Did you have time to unbox and test the Magewell device?


This seems to always get postponed due to other work,

I just tried it out once today on a nearby laptop, gst-launch seems 
to work
but couldn't reproduce the bandwidth issue when connecting a second 
usb device.


But I haven't really tested it out properly yet.


I just tested with 4.17-rc5 and the behavior remains the same. Is there
anything else I could do to get this fixed?



Briefed Zhengjun about this issue, one more brain on it.
Adding him to the thread.



Isochronous has been a problem for me for 2 years. I am using a rare 3D 
stereo camera from Etron and had Isochronous problems and recently I 
have discovered that the Logitech Brio also has what appears to be the 
same issue. The Logitech Brio is the first Logitech USB3 camera that 
uses Isochronous mode and you can do a search and find that linux users 
are having problems with it.


My suggestion would be for the USB3 team to order several Logitech Brio 
cameras and debug the Isochronous problems. My company paid for someone 
to try and debug 

Re: [PATCH 02/12] usb: usbtmc: Support Read Status Byte with SRQ per file handle

2018-05-21 Thread guido


Zitat von Greg KH :

@@ -122,7 +141,7 @@ static int usbtmc_open(struct inode *inode,  
struct file *filp)

 {
struct usb_interface *intf;
struct usbtmc_device_data *data;
-   int retval = 0;
+   struct usbtmc_file_data *file_data;

intf = usb_find_interface(_driver, iminor(inode));
if (!intf) {
@@ -130,21 +149,54 @@ static int usbtmc_open(struct inode *inode,  
struct file *filp)

return -ENODEV;
}

+   file_data = kzalloc(sizeof(*file_data), GFP_KERNEL);
+   if (!file_data)
+   return -ENOMEM;
+
+   pr_debug("%s - called\n", __func__);


Please do not add "tracing" functions like this.  The kernel has a
wonderful built-in function tracing functionality, don't try to write
your own.  These lines should just be removed.



+
data = usb_get_intfdata(intf);
/* Protect reference to data from file structure until release */
kref_get(>kref);

+   mutex_lock(>io_mutex);
+   file_data->data = data;
+
+   /* copy default values from device settings */
+   file_data->TermChar = data->TermChar;
+   file_data->TermCharEnabled = data->TermCharEnabled;
+   file_data->auto_abort = data->auto_abort;
+
+   INIT_LIST_HEAD(_data->file_elem);
+   spin_lock_irq(>dev_lock);
+   list_add_tail(_data->file_elem, >file_list);
+   spin_unlock_irq(>dev_lock);
+   mutex_unlock(>io_mutex);
+
/* Store pointer in file structure's private data field */
-   filp->private_data = data;
+   filp->private_data = file_data;

-   return retval;
+   return 0;
 }

 static int usbtmc_release(struct inode *inode, struct file *file)
 {
-   struct usbtmc_device_data *data = file->private_data;
+   struct usbtmc_file_data *file_data = file->private_data;

-   kref_put(>kref, usbtmc_delete);
+   pr_debug("%s - called\n", __func__);


Again, these all need to be dropped.


+
+   /* prevent IO _AND_ usbtmc_interrupt */
+   mutex_lock(_data->data->io_mutex);
+   spin_lock_irq(_data->data->dev_lock);
+
+   list_del(_data->file_elem);
+
+   spin_unlock_irq(_data->data->dev_lock);
+   mutex_unlock(_data->data->io_mutex);


You protect the list, but what about removing the data itself?


+
+   kref_put(_data->data->kref, usbtmc_delete);


What protects this from being called at the same time a kref_get is
being called?

Yeah, it previously probably already had this race, sorry I never
noticed that.



I looked for a race here, but I do not find a race between open and release,
since a refcount of "file_data->data->kref" is always hold by
usbtmc_probe/disconnect.

However I see a race between usbtmc_open and usbtmc_disconnect. Are these
callback functions called mutual exclusive?
I'm not sure, but if not, then I think we have the same problem in  
usb-skeleton.c






+   file_data->data = NULL;
+   kfree(file_data);
return 0;
 }



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: [PATCH 06/12] usb: usbtmc: Add vendor specific/asynchronous read/write ioctls

2018-05-21 Thread guido


Zitat von Greg KH :


On Fri, May 18, 2018 at 02:48:11PM +, gu...@kiener-muenchen.de wrote:


Zitat von Greg KH :

> On Thu, May 17, 2018 at 07:03:30PM +0200, Guido Kiener wrote:
> > +/*
> > + * usbtmc_message->flags:
> > + */
> > +#define USBTMC_FLAG_ASYNC0x0001
> > +#define USBTMC_FLAG_APPEND   0x0002
> > +#define USBTMC_FLAG_IGNORE_TRAILER   0x0004
> > +
> > +struct usbtmc_message {
> > + void __user *message; /* pointer to header and data */
> > + __u64 transfer_size; /* size of bytes to transfer */
> > + __u64 transferred; /* size of received/written bytes */
> > + __u32 flags; /* bit 0: 0 = synchronous; 1 = asynchronous */
> > +} __attribute__ ((packed));
>
> Very odd structure.  Your userspace pointer is going to be totally out
> of alignment on 32bit systems running on a 64bit kernel.  Why have a
> separate pointer at all?  Why not just put the mesage at the end of this
> structure directly with something like:
>__u8 message[0];
> ?
>


Using a __u8 message[0] ends up with an extra malloc, memcpy, and free
operation in userland, since we always have to append the data of a given
user pointer to this struct. E.g. when I send 4 MByte on my (old) laptop
this takes about plus 6 ms, and decreases bandwidth from 31,0 MByte/s
to 29,5 MByte/s with USB 2.0.

I hope this struct looks better (in compat mode):

struct usbtmc_message {
__u64 transfer_size; /* size of bytes to transfer */
__u64 transferred; /* size of received/written bytes */
void __user *message; /* pointer to header and data */
__u32 flags; /* bit 0: 0 = synchronous; 1 = asynchronous */
} __attribute__ ((packed));

BTW the driver has no .compat_ioctl entry. So I wonder how it could work
with 32 bit applications on 64 bit systems before submission of our patches.
Do I miss something?



Oh yes, I should know that from another project. Indead we did not test it
with 32 bit applications on 64 platforms.

When we use your proposal then we just can use
#define USBTMC_IOCTL_WRITE _IO(USBTMC_IOC_NR, 13)?


Why 13?  Use the structure please, that way you know you always get it
right.

thanks,

greg k-h




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


[PATCH v2] usb: dwc2: Fix HiKey regression caused by power_down feature

2018-05-21 Thread John Stultz
In 4.17-rc, commit 03ea6d6e9e1f ("usb: dwc2: Enable power down")
caused the HiKey board to not correctly handle switching between
usb-gadget and usb-host mode.

Unplugging the OTG port would result in:
[   42.240973] dwc2 f72c.usb: dwc2_restore_host_registers: no host 
registers to restore
[   42.249066] dwc2 f72c.usb: dwc2_host_exit_hibernation: failed to restore 
host registers

And the USB-host ports would not function.

And plugging in the OTG port, we would see:
[   46.046557] WARNING: CPU: 3 PID: 6 at drivers/usb/dwc2/gadget.c:260 
dwc2_hsotg_init_fifo+0x194/0x1a0
[   46.055761] CPU: 3 PID: 6 Comm: kworker/u16:0 Not tainted 
4.17.0-rc5-00030-ge67da8c #231
[   46.055767] Hardware name: HiKey Development Board (DT)
[   46.055784] Workqueue: dwc2 dwc2_conn_id_status_change
...

Thus, this patch sets the hisi params to disable the power_down
flag by default, and gets thing working again.

Cc: John Youn 
Cc: Minas Harutyunyan 
Cc: Artur Petrosyan 
Cc: Grigor Tovmasyan 
Cc: Felipe Balbi 
Cc: linux-usb@vger.kernel.org
Signed-off-by: John Stultz 
---
v2: Use DWC2_POWER_DOWN_PARAM_NONE as suggested by Minas
---
 drivers/usb/dwc2/params.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index f03e418..d38871c 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -70,6 +70,7 @@ static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
GAHBCFG_HBSTLEN_SHIFT;
p->uframe_sched = false;
p->change_speed_quirk = true;
+   p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
 }
 
 static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg)
-- 
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


Re: [PATCH] usb: dwc2: Fix HiKey regression caused by power_down feature

2018-05-21 Thread John Stultz
On Mon, May 21, 2018 at 1:45 AM, Minas Harutyunyan
 wrote:
> Hi John,
>
> On 5/19/2018 4:49 AM, John Stultz wrote:
>> In 4.17-rc, commit 03ea6d6e9e1f ("usb: dwc2: Enable power down")
>> caused the HiKey board to not correctly handle switching between
>> usb-gadget and usb-host mode.
>>
>> Unplugging the OTG port would result in:
>> [   42.240973] dwc2 f72c.usb: dwc2_restore_host_registers: no host 
>> registers to restore
>> [   42.249066] dwc2 f72c.usb: dwc2_host_exit_hibernation: failed to 
>> restore host registers
>>
>> And the USB-host ports would not function.
>>
>> And plugging in the OTG port, we would see:
>> [   46.046557] WARNING: CPU: 3 PID: 6 at drivers/usb/dwc2/gadget.c:260 
>> dwc2_hsotg_init_fifo+0x194/0x1a0
>> [   46.055761] CPU: 3 PID: 6 Comm: kworker/u16:0 Not tainted 
>> 4.17.0-rc5-00030-ge67da8c #231
>> [   46.055767] Hardware name: HiKey Development Board (DT)
>> [   46.055784] Workqueue: dwc2 dwc2_conn_id_status_change
>> ...
>>
> Could you please send full log to debug.

Full dmesg log attached.

I unplugged the usb-otg port at 136
and replugged it back in at 141


>>   p->uframe_sched = false;
>>   p->change_speed_quirk = true;
>> + p->power_down = false;
>
> power_down declared as int, suggested to update as follow:
> p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
>
> This can be accepted as temporary solution until we will fully debug
> hibernation feature for HiKey platform.

Ok, will re-send with the suggested change above.

thanks
-john


dmesg.log
Description: Binary data


Re: [PATCH v2 0/2] Re: usb-storage: Add quirks to make G-Technology "G-Drive" work

2018-05-21 Thread Alan Stern
On Fri, 18 May 2018, Alexander Kappner wrote:

> v2 of this patch implements the FL_ALWAYS_SYNC flag in the UAS driver, and 
> then
> adds the flag as quirks for the device at issue. This allows the G-Drive to 
> work
> under both UAS and usb-storage.
> 
> Alexander Kappner (2):
>   [usb-storage] Add support for FL_ALWAYS_SYNC flag in the UAS driver
>   [usb-storage] Add compatibility quirk flags for G-Technologies G-Drive
> 
>  drivers/usb/storage/uas.c  | 6 ++
>  drivers/usb/storage/unusual_devs.h | 9 +
>  drivers/usb/storage/unusual_uas.h  | 9 +
>  3 files changed, 24 insertions(+)

Acked-by: Alan Stern 

This is okay with me.  Oliver, what do you think?

Alan Stern

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


Re: [PATCH] usb: xhci: force all memory allocations to node

2018-05-21 Thread Adam Wallis
On 5/21/2018 9:53 AM, Mathias Nyman wrote:
> On 21.05.2018 15:56, Adam Wallis wrote:
> Not sure if if there's any benefit in allocating the scratchpad structures 
> from
> a closer node, or any harm? xhci driver doesn't really access scratchpad that
> frequently.

I don't see how it would hurt and I think it's easier to keep all of the
allocations consistent...however, let me know if you want those backed out.

> The port related structures are changing completely, so xhci->usb2_ports
> xhci->usb3_ports
> and other related are going away. Just sent a series for that. So some 
> rebasing
> is needed.

Would it be easier to just rebase on top of your for-usb-next branch in that
case? I had been only testing on top of 4.17rc5.

Let me know what you think is best/easiest for you.


-- 
Adam Wallis
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, 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: [PATCH] tty: add missing const to termios hw-change helper

2018-05-21 Thread Greg Kroah-Hartman
On Mon, May 21, 2018 at 01:08:44PM +0200, Johan Hovold wrote:
> Add missing const qualifiers to the termios hw-change helper parameters,
> which is used by few USB serial drivers. This specifically allows the
> pl2303 driver to use const arguments in one of its helper as well.
> 
> Cc: Greg Kroah-Hartman 
> Cc: Jiri Slaby 
> Signed-off-by: Johan Hovold 
> ---
> 
> Greg, are you fine with me taking this one through my tree, or do prefer
> I split out the pl2303 bits?
> 
> Note that this helper is only used by a few USB serial drivers and that
> the pl2303 bits depend on a new patch targeted for -next.

Your tree is fine:

Acked-by: Greg Kroah-Hartman 

--
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] typec: tcpm: Provide of_node pointer as part of psy_cfg

2018-05-21 Thread Adam Thomson
On 21 May 2018 15:56, Heikki Krogerus wrote:

> On Mon, May 21, 2018 at 01:58:16PM +, Adam Thomson wrote:
> > Hi Heikki,
> >
> > On 21 May 2018 14:20, Heikki Krogerus wrote:
> >
> > > On Wed, May 16, 2018 at 05:00:46PM +0100, Adam Thomson wrote:
> > > > For supply registration, provide of_node pointer of the port device,
> > > > via the power_supply_config structure, to allow other psy drivers
> > > > to add us as a supplier using the 'power-supplies' DT property.
> > > >
> > > > Signed-off-by: Adam Thomson 
> > > > ---
> > > >  drivers/usb/typec/tcpm.c | 1 +
> > > >  1 file changed, 1 insertion(+)
> > > >
> > > > diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> > > > index 72996cc..e7c0b95 100644
> > > > --- a/drivers/usb/typec/tcpm.c
> > > > +++ b/drivers/usb/typec/tcpm.c
> > > > @@ -4500,6 +4500,7 @@ static int devm_tcpm_psy_register(struct tcpm_port
> > > *port)
> > > > char *psy_name;
> > > >
> > > > psy_cfg.drv_data = port;
> > > > +   psy_cfg.of_node = port->dev->of_node;
> > > > psy_name = devm_kzalloc(port->dev, psy_name_len, GFP_KERNEL);
> > > > if (!psy_name)
> > > > return -ENOMEM;
> > >
> > > Would it be possible to use fwnode here instead? It would mean that
> > > you add a member for it to the struct power_supply_config, and handle
> > > it separately in power_supply_core.c. You could just convert it to
> > > of_node there for now.
> > >
> > > That is just a request, I'm fine with this, but it would prepare this
> > > driver for all types of platforms, so less patching would be needed
> > > once we add ACPI support to the power_supply_core.c.
> >
> > Would the following commit from Hans, already present in 
> > power_supply_core.c,
> > not fit the bill:
> >
> > [58a36bb06891ee779074db6ef84e98347c634d38]
> > power: supply: core: Add support for supplied-from device-property
> >
> > Or was that just meant as a stop gap for something more?
> 
> I think the main idea with that patch was that it allows us to take
> advantage of build-in device properties, but I think we could actually
> improve also it if we had the fwnode handle assigned to the psy. We
> would not have to assume the parent has those device properties then.
> 
> But ACPI actually defines a specific object called _PCL (power
> consumer list) for power source objects that we should one day check
> in power_supply_core.c. That's what I meant by ACPI support.

Ok, fair enough. Makes sense to me. Thanks for clarifying.

> > I have no problems adding something further, but I don't have a means to 
> > verify
> > anything ACPI based, beyond a simple build test, so would ideally want 
> > someone
> > to verify that path through the code.
> 
> This is not really about ACPI. By using fwnode handle instead of
> of_node, we would continue to keep tcpm.c agnostic about the type of
> hw description.
> 
> So I don't expect any ACPI support to be added to the
> power_supply_code.c at this point. You can use to_of_node(cfg->fwnode)
> in __power_supply_register() for now:
> 
> psy->of_node = cfg->of_node;
> if (cfg->fwnode)
> psy->of_node = to_of_node(cfg->fwnode);

OK, no problem. Will take a look and add that in.
--
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] typec: tcpm: Provide of_node pointer as part of psy_cfg

2018-05-21 Thread Heikki Krogerus
On Mon, May 21, 2018 at 01:58:16PM +, Adam Thomson wrote:
> Hi Heikki,
> 
> On 21 May 2018 14:20, Heikki Krogerus wrote:
> 
> > On Wed, May 16, 2018 at 05:00:46PM +0100, Adam Thomson wrote:
> > > For supply registration, provide of_node pointer of the port device,
> > > via the power_supply_config structure, to allow other psy drivers
> > > to add us as a supplier using the 'power-supplies' DT property.
> > >
> > > Signed-off-by: Adam Thomson 
> > > ---
> > >  drivers/usb/typec/tcpm.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> > > index 72996cc..e7c0b95 100644
> > > --- a/drivers/usb/typec/tcpm.c
> > > +++ b/drivers/usb/typec/tcpm.c
> > > @@ -4500,6 +4500,7 @@ static int devm_tcpm_psy_register(struct tcpm_port
> > *port)
> > >   char *psy_name;
> > >
> > >   psy_cfg.drv_data = port;
> > > + psy_cfg.of_node = port->dev->of_node;
> > >   psy_name = devm_kzalloc(port->dev, psy_name_len, GFP_KERNEL);
> > >   if (!psy_name)
> > >   return -ENOMEM;
> > 
> > Would it be possible to use fwnode here instead? It would mean that
> > you add a member for it to the struct power_supply_config, and handle
> > it separately in power_supply_core.c. You could just convert it to
> > of_node there for now.
> > 
> > That is just a request, I'm fine with this, but it would prepare this
> > driver for all types of platforms, so less patching would be needed
> > once we add ACPI support to the power_supply_core.c.
> 
> Would the following commit from Hans, already present in power_supply_core.c,
> not fit the bill:
> 
> [58a36bb06891ee779074db6ef84e98347c634d38]
> power: supply: core: Add support for supplied-from device-property
> 
> Or was that just meant as a stop gap for something more?

I think the main idea with that patch was that it allows us to take
advantage of build-in device properties, but I think we could actually
improve also it if we had the fwnode handle assigned to the psy. We
would not have to assume the parent has those device properties then.

But ACPI actually defines a specific object called _PCL (power
consumer list) for power source objects that we should one day check
in power_supply_core.c. That's what I meant by ACPI support.

> I have no problems adding something further, but I don't have a means to 
> verify
> anything ACPI based, beyond a simple build test, so would ideally want someone
> to verify that path through the code.

This is not really about ACPI. By using fwnode handle instead of
of_node, we would continue to keep tcpm.c agnostic about the type of
hw description.

So I don't expect any ACPI support to be added to the
power_supply_code.c at this point. You can use to_of_node(cfg->fwnode)
in __power_supply_register() for now:

psy->of_node = cfg->of_node;
if (cfg->fwnode)
psy->of_node = to_of_node(cfg->fwnode);


Thanks,

-- 
heikki
--
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] typec: tcpm: Provide of_node pointer as part of psy_cfg

2018-05-21 Thread Adam Thomson
Hi Heikki,

On 21 May 2018 14:20, Heikki Krogerus wrote:

> On Wed, May 16, 2018 at 05:00:46PM +0100, Adam Thomson wrote:
> > For supply registration, provide of_node pointer of the port device,
> > via the power_supply_config structure, to allow other psy drivers
> > to add us as a supplier using the 'power-supplies' DT property.
> >
> > Signed-off-by: Adam Thomson 
> > ---
> >  drivers/usb/typec/tcpm.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> > index 72996cc..e7c0b95 100644
> > --- a/drivers/usb/typec/tcpm.c
> > +++ b/drivers/usb/typec/tcpm.c
> > @@ -4500,6 +4500,7 @@ static int devm_tcpm_psy_register(struct tcpm_port
> *port)
> > char *psy_name;
> >
> > psy_cfg.drv_data = port;
> > +   psy_cfg.of_node = port->dev->of_node;
> > psy_name = devm_kzalloc(port->dev, psy_name_len, GFP_KERNEL);
> > if (!psy_name)
> > return -ENOMEM;
> 
> Would it be possible to use fwnode here instead? It would mean that
> you add a member for it to the struct power_supply_config, and handle
> it separately in power_supply_core.c. You could just convert it to
> of_node there for now.
> 
> That is just a request, I'm fine with this, but it would prepare this
> driver for all types of platforms, so less patching would be needed
> once we add ACPI support to the power_supply_core.c.

Would the following commit from Hans, already present in power_supply_core.c,
not fit the bill:

[58a36bb06891ee779074db6ef84e98347c634d38]
power: supply: core: Add support for supplied-from device-property

Or was that just meant as a stop gap for something more?

I have no problems adding something further, but I don't have a means to verify
anything ACPI based, beyond a simple build test, so would ideally want someone
to verify that path through the code.
--
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: xhci: force all memory allocations to node

2018-05-21 Thread Mathias Nyman

On 21.05.2018 15:56, Adam Wallis wrote:

On 5/16/2018 2:02 AM, Greg Kroah-Hartman wrote:

On Tue, May 15, 2018 at 04:51:53PM -0400, Adam Wallis wrote:

Ok, fair enough, I was hoping that "modern" systems would have better
NUMA memory interconnects.  I guess that isn't the case still :(


Things will keep improving, I'm sure.

Mathias, did you have anything you need reworked with this patch or any specific
comments on the overall patch?



If there's a performance benefit in adding these then I'm all for it.
for ring related allocations it makes sense.

Not sure if if there's any benefit in allocating the scratchpad structures from
a closer node, or any harm? xhci driver doesn't really access scratchpad that 
frequently.

The port related structures are changing completely, so xhci->usb2_ports 
xhci->usb3_ports
and other related are going away. Just sent a series for that. So some rebasing 
is needed.

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


[PATCH 09/14] usb: musb: break the huge isr musb_stage0_irq() into small functions

2018-05-21 Thread Bin Liu
musb_stage0_irq() is 400+ lines long. Break its interrupt events
handling into each individual functions to make it easy to read.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.c | 730 +++
 1 file changed, 384 insertions(+), 346 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index ce54f48314e1..a3a716197dc1 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -523,6 +523,383 @@ void musb_hnp_stop(struct musb *musb)
 
 static void musb_recover_from_babble(struct musb *musb);
 
+static void musb_handle_intr_resume(struct musb *musb, u8 devctl)
+{
+   musb_dbg(musb, "RESUME (%s)",
+   usb_otg_state_string(musb->xceiv->otg->state));
+
+   if (devctl & MUSB_DEVCTL_HM) {
+   switch (musb->xceiv->otg->state) {
+   case OTG_STATE_A_SUSPEND:
+   /* remote wakeup? */
+   musb->port1_status |=
+   (USB_PORT_STAT_C_SUSPEND << 16)
+   | MUSB_PORT_STAT_RESUME;
+   musb->rh_timer = jiffies
+   + msecs_to_jiffies(USB_RESUME_TIMEOUT);
+   musb->xceiv->otg->state = OTG_STATE_A_HOST;
+   musb->is_active = 1;
+   musb_host_resume_root_hub(musb);
+   schedule_delayed_work(>finish_resume_work,
+   msecs_to_jiffies(USB_RESUME_TIMEOUT));
+   break;
+   case OTG_STATE_B_WAIT_ACON:
+   musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
+   musb->is_active = 1;
+   MUSB_DEV_MODE(musb);
+   break;
+   default:
+   WARNING("bogus %s RESUME (%s)\n",
+   "host",
+   usb_otg_state_string(musb->xceiv->otg->state));
+   }
+   } else {
+   switch (musb->xceiv->otg->state) {
+   case OTG_STATE_A_SUSPEND:
+   /* possibly DISCONNECT is upcoming */
+   musb->xceiv->otg->state = OTG_STATE_A_HOST;
+   musb_host_resume_root_hub(musb);
+   break;
+   case OTG_STATE_B_WAIT_ACON:
+   case OTG_STATE_B_PERIPHERAL:
+   /* disconnect while suspended?  we may
+* not get a disconnect irq...
+*/
+   if ((devctl & MUSB_DEVCTL_VBUS)
+   != (3 << MUSB_DEVCTL_VBUS_SHIFT)
+   ) {
+   musb->int_usb |= MUSB_INTR_DISCONNECT;
+   musb->int_usb &= ~MUSB_INTR_SUSPEND;
+   break;
+   }
+   musb_g_resume(musb);
+   break;
+   case OTG_STATE_B_IDLE:
+   musb->int_usb &= ~MUSB_INTR_SUSPEND;
+   break;
+   default:
+   WARNING("bogus %s RESUME (%s)\n",
+   "peripheral",
+   usb_otg_state_string(musb->xceiv->otg->state));
+   }
+   }
+}
+
+/* return IRQ_HANDLED to tell the caller to return immediately */
+static irqreturn_t musb_handle_intr_sessreq(struct musb *musb, u8 devctl)
+{
+   void __iomem *mbase = musb->mregs;
+
+   if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS
+   && (devctl & MUSB_DEVCTL_BDEVICE)) {
+   musb_dbg(musb, "SessReq while on B state");
+   return IRQ_HANDLED;
+   }
+
+   musb_dbg(musb, "SESSION_REQUEST (%s)",
+   usb_otg_state_string(musb->xceiv->otg->state));
+
+   /* IRQ arrives from ID pin sense or (later, if VBUS power
+* is removed) SRP.  responses are time critical:
+*  - turn on VBUS (with silicon-specific mechanism)
+*  - go through A_WAIT_VRISE
+*  - ... to A_WAIT_BCON.
+* a_wait_vrise_tmout triggers VBUS_ERROR transitions
+*/
+   musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
+   musb->ep0_stage = MUSB_EP0_START;
+   musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+   MUSB_HST_MODE(musb);
+   musb_platform_set_vbus(musb, 1);
+
+   return IRQ_NONE;
+}
+
+static void musb_handle_intr_vbuserr(struct musb *musb, u8 devctl)
+{
+   int ignore = 0;
+
+   /* During connection as an A-Device, we may see a short
+* current spikes causing voltage drop, because of cable
+* and peripheral capacitance combined with vbus draw.
+* (So: less common with truly self-powered devices, where
+* vbus doesn't act like a power supply.)
+   

[PATCH 07/14] usb: musb: remove duplicated port mode enum

2018-05-21 Thread Bin Liu
include/linux/usb/musb.h already defines enum for musb port mode, so
remove the duplicate in musb_core.h and use the definition in musb.h.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.c| 8 
 drivers/usb/musb/musb_core.h| 8 +---
 drivers/usb/musb/musb_dsps.c| 6 +++---
 drivers/usb/musb/musb_gadget.c  | 2 +-
 drivers/usb/musb/musb_host.c| 4 ++--
 drivers/usb/musb/musb_virthub.c | 2 +-
 drivers/usb/musb/sunxi.c| 8 
 7 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 84f25a2b078d..ce54f48314e1 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1038,7 +1038,7 @@ void musb_start(struct musb *musb)
 * (b) vbus present/connect IRQ, peripheral mode;
 * (c) peripheral initiates, using SRP
 */
-   if (musb->port_mode != MUSB_PORT_MODE_HOST &&
+   if (musb->port_mode != MUSB_HOST &&
musb->xceiv->otg->state != OTG_STATE_A_WAIT_BCON &&
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
musb->is_active = 1;
@@ -2323,19 +2323,19 @@ static void musb_deassert_reset(struct work_struct 
*work)
}
 
switch (musb->port_mode) {
-   case MUSB_PORT_MODE_HOST:
+   case MUSB_HOST:
status = musb_host_setup(musb, plat->power);
if (status < 0)
goto fail3;
status = musb_platform_set_mode(musb, MUSB_HOST);
break;
-   case MUSB_PORT_MODE_GADGET:
+   case MUSB_PERIPHERAL:
status = musb_gadget_setup(musb);
if (status < 0)
goto fail3;
status = musb_platform_set_mode(musb, MUSB_PERIPHERAL);
break;
-   case MUSB_PORT_MODE_DUAL_ROLE:
+   case MUSB_OTG:
status = musb_host_setup(musb, plat->power);
if (status < 0)
goto fail3;
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f57323e50e44..04203b7126d5 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -53,12 +53,6 @@
 #define is_peripheral_active(m)(!(m)->is_host)
 #define is_host_active(m)  ((m)->is_host)
 
-enum {
-   MUSB_PORT_MODE_HOST = 1,
-   MUSB_PORT_MODE_GADGET,
-   MUSB_PORT_MODE_DUAL_ROLE,
-};
-
 /** CONSTANTS /
 
 #ifndef MUSB_C_NUM_EPS
@@ -351,7 +345,7 @@ struct musb {
 
u8  min_power;  /* vbus for periph, in mA/2 */
 
-   int port_mode;  /* MUSB_PORT_MODE_* */
+   enum musb_mode  port_mode;
boolsession;
unsigned long   quirk_retries;
boolis_host;
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index c513ecebc35a..71aec85b9bd4 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -183,7 +183,7 @@ static void dsps_musb_enable(struct musb *musb)
musb_writel(reg_base, wrp->coreintr_set, coremask);
/* start polling for ID change in dual-role idle mode */
if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
-   musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
+   musb->port_mode == MUSB_OTG)
dsps_mod_timer(glue, -1);
 }
 
@@ -231,7 +231,7 @@ static int dsps_check_status(struct musb *musb, void 
*unused)
break;
case OTG_STATE_A_WAIT_BCON:
/* keep VBUS on for host-only mode */
-   if (musb->port_mode == MUSB_PORT_MODE_HOST) {
+   if (musb->port_mode == MUSB_HOST) {
dsps_mod_timer_optional(glue);
break;
}
@@ -1028,7 +1028,7 @@ static int dsps_resume(struct device *dev)
musb_writel(mbase, wrp->tx_mode, glue->context.tx_mode);
musb_writel(mbase, wrp->rx_mode, glue->context.rx_mode);
if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
-   musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
+   musb->port_mode == MUSB_OTG)
dsps_mod_timer(glue, -1);
 
pm_runtime_put(dev);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 71c5835ea9cd..d082b0cbea93 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1823,7 +1823,7 @@ int musb_gadget_setup(struct musb *musb)
 
 void musb_gadget_cleanup(struct musb *musb)
 {
-   if (musb->port_mode == MUSB_PORT_MODE_HOST)
+   if (musb->port_mode == MUSB_HOST)
return;
 
cancel_delayed_work_sync(>gadget_work);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 15a42cee0a9c..c8d0617da849 100644
--- 

[PATCH 08/14] usb: musb: remove unused members in struct musb_hdrc_config

2018-05-21 Thread Bin Liu
The following members in struct musb_hdrc_config are not used,
so remove them.

soft_con
utm_16
big_endian
mult_bulk_tx
mult_bulk_rx
high_iso_tx
high_iso_rx
dma
dma_channels
dyn_fifo_size
vendor_ctrl
vendor_stat
vendor_req
dma_req_chan
musb_hdrc_eps_bits

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/sunxi.c |  4 
 include/linux/usb/musb.h | 15 ---
 2 files changed, 19 deletions(-)

diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 8f7d378b7e7e..62ab2ca03779 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -651,10 +651,8 @@ static void sunxi_musb_writew(void __iomem *addr, unsigned 
offset, u16 data)
.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg),
.multipoint = true,
.dyn_fifo   = true,
-   .soft_con   = true,
.num_eps= SUNXI_MUSB_MAX_EP_NUM,
.ram_bits   = SUNXI_MUSB_RAM_BITS,
-   .dma= 0,
 };
 
 static struct musb_hdrc_config sunxi_musb_hdrc_config_h3 = {
@@ -662,10 +660,8 @@ static void sunxi_musb_writew(void __iomem *addr, unsigned 
offset, u16 data)
.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg_h3),
.multipoint = true,
.dyn_fifo   = true,
-   .soft_con   = true,
.num_eps= SUNXI_MUSB_MAX_EP_NUM_H3,
.ram_bits   = SUNXI_MUSB_RAM_BITS,
-   .dma= 0,
 };
 
 
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 9eb908a98033..fc6c77918481 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -67,28 +67,13 @@ struct musb_hdrc_config {
/* MUSB configuration-specific details */
unsignedmultipoint:1;   /* multipoint device */
unsigneddyn_fifo:1 __deprecated; /* supports dynamic fifo 
sizing */
-   unsignedsoft_con:1 __deprecated; /* soft connect required */
-   unsignedutm_16:1 __deprecated; /* utm data witdh is 16 bits */
-   unsignedbig_endian:1;   /* true if CPU uses big-endian */
-   unsignedmult_bulk_tx:1; /* Tx ep required for multbulk pkts */
-   unsignedmult_bulk_rx:1; /* Rx ep required for multbulk pkts */
-   unsignedhigh_iso_tx:1;  /* Tx ep required for HB iso */
-   unsignedhigh_iso_rx:1;  /* Rx ep required for HD iso */
-   unsigneddma:1 __deprecated; /* supports DMA */
-   unsignedvendor_req:1 __deprecated; /* vendor registers required 
*/
 
/* need to explicitly de-assert the port reset after resume? */
unsignedhost_port_deassert_reset_at_resume:1;
 
u8  num_eps;/* number of endpoints _with_ ep0 */
-   u8  dma_channels __deprecated; /* number of dma channels */
-   u8  dyn_fifo_size;  /* dynamic size in bytes */
-   u8  vendor_ctrl __deprecated; /* vendor control reg width */
-   u8  vendor_stat __deprecated; /* vendor status reg witdh */
-   u8  dma_req_chan __deprecated; /* bitmask for required dma 
channels */
u8  ram_bits;   /* ram address size */
 
-   struct musb_hdrc_eps_bits *eps_bits __deprecated;
u32 maximum_speed;
 };
 
-- 
1.9.1

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


[PATCH 13/14] usb: musb: gadget: fix to_musb_request() to not return NULL

2018-05-21 Thread Bin Liu
The gadget function drivers should ensure the usb_request parameter
passed in is not NULL. UDC core doesn't check if it is NULL, so MUSB
driver shouldn't have to check it either.

Convert to_musb_request() to a simple macro to not directly return NULL
to avoid warnings from code static analysis tools.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_gadget.h | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
index 9c34aca06db6..466877b471ef 100644
--- a/drivers/usb/musb/musb_gadget.h
+++ b/drivers/usb/musb/musb_gadget.h
@@ -60,10 +60,7 @@ struct musb_request {
enum buffer_map_state map_state;
 };
 
-static inline struct musb_request *to_musb_request(struct usb_request *req)
-{
-   return req ? container_of(req, struct musb_request, request) : NULL;
-}
+#define to_musb_request(r) container_of((r), struct musb_request, request)
 
 extern struct usb_request *
 musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
-- 
1.9.1

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


[PATCH 06/14] usb: musb: dsps: remove duplicated get_musb_port_mode()

2018-05-21 Thread Bin Liu
musb_core already has musb_get_mode(), so remove the duplicate from
musb_dsps.c.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_dsps.c | 21 +
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 6a60bc0490c5..c513ecebc35a 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -729,25 +729,6 @@ static int get_int_prop(struct device_node *dn, const char 
*s)
return val;
 }
 
-static int get_musb_port_mode(struct device *dev)
-{
-   enum usb_dr_mode mode;
-
-   mode = usb_get_dr_mode(dev);
-   switch (mode) {
-   case USB_DR_MODE_HOST:
-   return MUSB_PORT_MODE_HOST;
-
-   case USB_DR_MODE_PERIPHERAL:
-   return MUSB_PORT_MODE_GADGET;
-
-   case USB_DR_MODE_UNKNOWN:
-   case USB_DR_MODE_OTG:
-   default:
-   return MUSB_PORT_MODE_DUAL_ROLE;
-   }
-}
-
 static int dsps_create_musb_pdev(struct dsps_glue *glue,
struct platform_device *parent)
 {
@@ -807,7 +788,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
config->num_eps = get_int_prop(dn, "mentor,num-eps");
config->ram_bits = get_int_prop(dn, "mentor,ram-bits");
config->host_port_deassert_reset_at_resume = 1;
-   pdata.mode = get_musb_port_mode(dev);
+   pdata.mode = musb_get_mode(dev);
/* DT keeps this entry in mA, musb expects it as per USB spec */
pdata.power = get_int_prop(dn, "mentor,power") / 2;
 
-- 
1.9.1

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


[PATCH 12/14] USB: musb: dsps: propagate device-tree node

2018-05-21 Thread Bin Liu
From: Johan Hovold 

To be able to use DSPS-based controllers with device-tree descriptions
of the USB topology, we need to associate the glue device's device-tree
node with the child controller device.

Note that this can also be used to eventually let USB core manage
generic phys.

Also note that the other glue drivers will require similar changes to be
able to describe their buses in DT.

Signed-off-by: Johan Hovold 
Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_dsps.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 34e4dda1d6ac..cfe6bfcbeb5d 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -765,6 +765,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
musb->dev.parent= dev;
musb->dev.dma_mask  = _dmamask;
musb->dev.coherent_dma_mask = musb_dmamask;
+   device_set_of_node_from_dev(>dev, >dev);
 
glue->musb = musb;
 
-- 
1.9.1

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


[PATCH 03/14] usb: musb: remove adjust_channel_params() callback from musb_platform_ops

2018-05-21 Thread Bin Liu
Now Blackfin support is removed, nobody uses adjust_channel_params() any
more, so remove it from struct musb_platform_ops.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.h | 4 
 drivers/usb/musb/musbhsdma.c | 8 
 2 files changed, 12 deletions(-)

diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index a4bf1e9e2d2c..f57323e50e44 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -138,7 +138,6 @@ enum musb_g_ep0_state {
  * @recover:   platform-specific babble recovery
  * @vbus_status: returns vbus status if possible
  * @set_vbus:  forces vbus status
- * @adjust_channel_params: pre check for standard dma channel_program func
  * @pre_root_reset_end: called before the root usb port reset flag gets cleared
  * @post_root_reset_end: called after the root usb port reset flag gets cleared
  * @phy_callback: optional callback function for the phy to call
@@ -184,9 +183,6 @@ struct musb_platform_ops {
int (*vbus_status)(struct musb *musb);
void(*set_vbus)(struct musb *musb, int on);
 
-   int (*adjust_channel_params)(struct dma_channel *channel,
-   u16 packet_sz, u8 *mode,
-   dma_addr_t *dma_addr, u32 *len);
void(*pre_root_reset_end)(struct musb *musb);
void(*post_root_reset_end)(struct musb *musb);
int (*phy_callback)(enum musb_vbus_id_status status);
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 57d416a110a5..a688f7f87829 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -199,14 +199,6 @@ static int dma_channel_program(struct dma_channel *channel,
BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
channel->status == MUSB_DMA_STATUS_BUSY);
 
-   /* Let targets check/tweak the arguments */
-   if (musb->ops->adjust_channel_params) {
-   int ret = musb->ops->adjust_channel_params(channel,
-   packet_sz, , _addr, );
-   if (ret)
-   return ret;
-   }
-
/*
 * The DMA engine in RTL1.8 and above cannot handle
 * DMA addresses that are not aligned to a 4 byte boundary.
-- 
1.9.1

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


[PATCH 01/14] usb: musb: merge musbhsdma.h into musbhsdma.c

2018-05-21 Thread Bin Liu
Now Blackfin support is removed, header musbhsdma.h is only included in
musbhsdma.c. So let's merge the content in musbhsdma.h to musbhsdma.c
and delete musbhsdma.h.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musbhsdma.c | 66 +++-
 drivers/usb/musb/musbhsdma.h | 72 
 2 files changed, 65 insertions(+), 73 deletions(-)
 delete mode 100644 drivers/usb/musb/musbhsdma.h

diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 4389fc3422bd..57d416a110a5 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -10,7 +10,71 @@
 #include 
 #include 
 #include "musb_core.h"
-#include "musbhsdma.h"
+
+#define MUSB_HSDMA_BASE0x200
+#define MUSB_HSDMA_INTR(MUSB_HSDMA_BASE + 0)
+#define MUSB_HSDMA_CONTROL 0x4
+#define MUSB_HSDMA_ADDRESS 0x8
+#define MUSB_HSDMA_COUNT   0xc
+
+#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)  \
+   (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
+
+#define musb_read_hsdma_addr(mbase, bchannel)  \
+   musb_readl(mbase,   \
+  MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
+
+#define musb_write_hsdma_addr(mbase, bchannel, addr) \
+   musb_writel(mbase, \
+   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
+   addr)
+
+#define musb_read_hsdma_count(mbase, bchannel) \
+   musb_readl(mbase,   \
+  MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
+
+#define musb_write_hsdma_count(mbase, bchannel, len) \
+   musb_writel(mbase, \
+   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
+   len)
+/* control register (16-bit): */
+#define MUSB_HSDMA_ENABLE_SHIFT0
+#define MUSB_HSDMA_TRANSMIT_SHIFT  1
+#define MUSB_HSDMA_MODE1_SHIFT 2
+#define MUSB_HSDMA_IRQENABLE_SHIFT 3
+#define MUSB_HSDMA_ENDPOINT_SHIFT  4
+#define MUSB_HSDMA_BUSERROR_SHIFT  8
+#define MUSB_HSDMA_BURSTMODE_SHIFT 9
+#define MUSB_HSDMA_BURSTMODE   (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
+#define MUSB_HSDMA_BURSTMODE_UNSPEC0
+#define MUSB_HSDMA_BURSTMODE_INCR4 1
+#define MUSB_HSDMA_BURSTMODE_INCR8 2
+#define MUSB_HSDMA_BURSTMODE_INCR163
+
+#define MUSB_HSDMA_CHANNELS8
+
+struct musb_dma_controller;
+
+struct musb_dma_channel {
+   struct dma_channel  channel;
+   struct musb_dma_controller  *controller;
+   u32 start_addr;
+   u32 len;
+   u16 max_packet_sz;
+   u8  idx;
+   u8  epnum;
+   u8  transmit;
+};
+
+struct musb_dma_controller {
+   struct dma_controller   controller;
+   struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS];
+   void*private_data;
+   void __iomem*base;
+   u8  channel_count;
+   u8  used_channels;
+   int irq;
+};
 
 static void dma_channel_release(struct dma_channel *channel);
 
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h
deleted file mode 100644
index 93665135aff1..
--- a/drivers/usb/musb/musbhsdma.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * MUSB OTG driver - support for Mentor's DMA controller
- *
- * Copyright 2005 Mentor Graphics Corporation
- * Copyright (C) 2005-2007 by Texas Instruments
- */
-
-#define MUSB_HSDMA_BASE0x200
-#define MUSB_HSDMA_INTR(MUSB_HSDMA_BASE + 0)
-#define MUSB_HSDMA_CONTROL 0x4
-#define MUSB_HSDMA_ADDRESS 0x8
-#define MUSB_HSDMA_COUNT   0xc
-
-#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)  \
-   (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
-
-#define musb_read_hsdma_addr(mbase, bchannel)  \
-   musb_readl(mbase,   \
-  MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
-
-#define musb_write_hsdma_addr(mbase, bchannel, addr) \
-   musb_writel(mbase, \
-   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
-   addr)
-
-#define musb_read_hsdma_count(mbase, bchannel) \
-   musb_readl(mbase,   \
-  MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
-
-#define musb_write_hsdma_count(mbase, bchannel, len) \
-   musb_writel(mbase, \
-   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
-   len)
-/* control register (16-bit): */
-#define MUSB_HSDMA_ENABLE_SHIFT0
-#define MUSB_HSDMA_TRANSMIT_SHIFT  1
-#define 

[PATCH 11/14] usb: musb: disable otg protocol support

2018-05-21 Thread Bin Liu
As decided in the discussion [1] we are deleting the otg protocol
support from the musb drivers.

First this patch disables the flags for enabling the otg protocols. We
will later gradually delete the otg protocol code from the musb drivers.

[1] https://www.spinics.net/lists/linux-usb/msg167003.html

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_gadget.c | 5 +
 drivers/usb/musb/musb_host.c   | 3 ++-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 5b8e6297ebed..eae8b1b1b45b 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1798,11 +1798,8 @@ int musb_gadget_setup(struct musb *musb)
 
/* this "gadget" abstracts/virtualizes the controller */
musb->g.name = musb_driver_name;
-#if IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE)
-   musb->g.is_otg = 1;
-#elif IS_ENABLED(CONFIG_USB_MUSB_GADGET)
+   /* don't support otg protocols */
musb->g.is_otg = 0;
-#endif
INIT_DELAYED_WORK(>gadget_work, musb_gadget_work);
musb_g_init_endpoints(musb);
 
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index cd611a97f59e..8000c7c02f79 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2755,7 +2755,8 @@ int musb_host_setup(struct musb *musb, int power_budget)
musb->xceiv->otg->state = OTG_STATE_A_IDLE;
}
otg_set_host(musb->xceiv->otg, >self);
-   hcd->self.otg_port = 1;
+   /* don't support otg protocols */
+   hcd->self.otg_port = 0;
musb->xceiv->otg->host = >self;
hcd->power_budget = 2 * (power_budget ? : 250);
hcd->skip_phy_initialization = 1;
-- 
1.9.1

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


[PATCH 14/14] usb: musb: gadget: fix to_musb_ep() to not return NULL

2018-05-21 Thread Bin Liu
UDC core ensures the usb_ep parameter passed in is not NULL, so
checking if (ep != NULL) is pointless.

Convert to_musb_ep() to a simple macro to not directly return NULL to
avoid warnings from code static analysis tools.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_gadget.h | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
index 466877b471ef..aaae24bb3c10 100644
--- a/drivers/usb/musb/musb_gadget.h
+++ b/drivers/usb/musb/musb_gadget.h
@@ -96,10 +96,7 @@ struct musb_ep {
u8  hb_mult;
 };
 
-static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
-{
-   return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
-}
+#define to_musb_ep(ep) container_of((ep), struct musb_ep, end_point)
 
 static inline struct musb_request *next_request(struct musb_ep *ep)
 {
-- 
1.9.1

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


[PATCH 04/14] usb: musb: remove some register access wrapper functions

2018-05-21 Thread Bin Liu
The following wrappers were defined because of Blackfin support. Now
Blackfin support is removed, these wrappers are no longer needed, so
remove them.

musb_write_txfifosz
musb_write_txfifoadd
musb_write_rxfifosz
musb_write_rxfifoadd
musb_write_ulpi_buscontrol
musb_read_txfifosz
musb_read_txfifoadd
musb_read_rxfifosz
musb_read_rxfifoadd
musb_read_ulpi_buscontrol
musb_read_hwvers

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.c | 42 -
 drivers/usb/musb/musb_regs.h | 55 
 2 files changed, 21 insertions(+), 76 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 4ff6da1aa775..d3f9f7e5f353 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1240,25 +1240,25 @@ void musb_stop(struct musb *musb)
/* REVISIT error check:  be sure ep0 can both rx and tx ... */
switch (cfg->style) {
case FIFO_TX:
-   musb_write_txfifosz(mbase, c_size);
-   musb_write_txfifoadd(mbase, c_off);
+   musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
+   musb_writew(mbase, MUSB_TXFIFOADD, c_off);
hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
hw_ep->max_packet_sz_tx = maxpacket;
break;
case FIFO_RX:
-   musb_write_rxfifosz(mbase, c_size);
-   musb_write_rxfifoadd(mbase, c_off);
+   musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
+   musb_writew(mbase, MUSB_RXFIFOADD, c_off);
hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
hw_ep->max_packet_sz_rx = maxpacket;
break;
case FIFO_RXTX:
-   musb_write_txfifosz(mbase, c_size);
-   musb_write_txfifoadd(mbase, c_off);
+   musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
+   musb_writew(mbase, MUSB_TXFIFOADD, c_off);
hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
hw_ep->max_packet_sz_rx = maxpacket;
 
-   musb_write_rxfifosz(mbase, c_size);
-   musb_write_rxfifoadd(mbase, c_off);
+   musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
+   musb_writew(mbase, MUSB_RXFIFOADD, c_off);
hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
hw_ep->max_packet_sz_tx = maxpacket;
 
@@ -1466,7 +1466,7 @@ static int musb_core_init(u16 musb_type, struct musb 
*musb)
}
 
/* log release info */
-   musb->hwvers = musb_read_hwvers(mbase);
+   musb->hwvers = musb_readw(mbase, MUSB_HWVERS);
pr_debug("%s: %sHDRC RTL version %d.%d%s\n",
 musb_driver_name, type, MUSB_HWVERS_MAJOR(musb->hwvers),
 MUSB_HWVERS_MINOR(musb->hwvers),
@@ -2311,9 +2311,9 @@ static void musb_deassert_reset(struct work_struct *work)
 
/* program PHY to use external vBus if required */
if (plat->extvbus) {
-   u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
+   u8 busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL);
busctl |= MUSB_ULPI_USE_EXTVBUS;
-   musb_write_ulpi_buscontrol(musb->mregs, busctl);
+   musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl);
}
 
if (musb->xceiv->otg->default_a) {
@@ -2482,7 +2482,7 @@ static void musb_save_context(struct musb *musb)
 
musb->context.frame = musb_readw(musb_base, MUSB_FRAME);
musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
-   musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
+   musb->context.busctl = musb_readb(musb_base, MUSB_ULPI_BUSCONTROL);
musb->context.power = musb_readb(musb_base, MUSB_POWER);
musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
musb->context.index = musb_readb(musb_base, MUSB_INDEX);
@@ -2511,13 +2511,13 @@ static void musb_save_context(struct musb *musb)
 
if (musb->dyn_fifo) {
musb->context.index_regs[i].txfifoadd =
-   musb_read_txfifoadd(musb_base);
+   musb_readw(musb_base, MUSB_TXFIFOADD);
musb->context.index_regs[i].rxfifoadd =
-   musb_read_rxfifoadd(musb_base);
+   musb_readw(musb_base, MUSB_RXFIFOADD);
musb->context.index_regs[i].txfifosz =
-   musb_read_txfifosz(musb_base);
+   musb_readb(musb_base, MUSB_TXFIFOSZ);
musb->context.index_regs[i].rxfifosz =
-   musb_read_rxfifosz(musb_base);
+

[PATCH 00/14] musb patches for v4.18-rc1

2018-05-21 Thread Bin Liu
Hi Greg,

Here are the musb patches for v4.18 rc1, mainly cleaning up the drivers after
BLACKFIN arch support is deleted, also having one patch from Johan to prepare
the USB PHY framework further work.

Please let me know if any change is needed.

Regards,
-Bin.


Bin Liu (13):
  usb: musb: merge musbhsdma.h into musbhsdma.c
  usb: musb: remove readl/writel from struct musb_platform_ops
  usb: musb: remove adjust_channel_params() callback from musb_platform_ops
  usb: musb: remove some register access wrapper functions
  usb: musb: remove duplicated quirks flag
  usb: musb: dsps: remove duplicated get_musb_port_mode()
  usb: musb: remove duplicated port mode enum
  usb: musb: remove unused members in struct musb_hdrc_config
  usb: musb: break the huge isr musb_stage0_irq() into small functions
  usb: musb: remove references to default_a of struct usb_otg
  usb: musb: disable otg protocol support
  usb: musb: gadget: fix to_musb_request() to not return NULL
  usb: musb: gadget: fix to_musb_ep() to not return NULL

Johan Hovold (1):
  USB: musb: dsps: propagate device-tree node

 drivers/usb/musb/am35x.c|   3 -
 drivers/usb/musb/da8xx.c|   2 -
 drivers/usb/musb/davinci.c  |  49 ++-
 drivers/usb/musb/musb_core.c| 833 
 drivers/usb/musb/musb_core.h|  16 +-
 drivers/usb/musb/musb_cppi41.c  |   4 +-
 drivers/usb/musb/musb_dma.h |  10 +-
 drivers/usb/musb/musb_dsps.c|  30 +-
 drivers/usb/musb/musb_gadget.c  |   8 +-
 drivers/usb/musb/musb_gadget.h  |  10 +-
 drivers/usb/musb/musb_host.c|   8 +-
 drivers/usb/musb/musb_io.h  |   6 +-
 drivers/usb/musb/musb_regs.h|  55 ---
 drivers/usb/musb/musb_virthub.c |   2 +-
 drivers/usb/musb/musbhsdma.c|  74 +++-
 drivers/usb/musb/musbhsdma.h|  72 
 drivers/usb/musb/omap2430.c |   5 -
 drivers/usb/musb/sunxi.c|  14 +-
 drivers/usb/musb/ux500.c|   2 -
 include/linux/usb/musb.h|  15 -
 20 files changed, 543 insertions(+), 675 deletions(-)
 delete mode 100644 drivers/usb/musb/musbhsdma.h

-- 
1.9.1

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


[PATCH 05/14] usb: musb: remove duplicated quirks flag

2018-05-21 Thread Bin Liu
Both musb_io and musb_platform_ops in struct musb define a quirks flag
for the same purpose.  Let's remove the one in struct musb_io, and use
that in struct musb_platform_ops instead.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.c   | 10 --
 drivers/usb/musb/musb_cppi41.c |  4 ++--
 drivers/usb/musb/musb_dma.h| 10 +-
 drivers/usb/musb/musb_io.h |  2 --
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index d3f9f7e5f353..84f25a2b078d 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1493,7 +1493,7 @@ static int musb_core_init(u16 musb_type, struct musb 
*musb)
 
hw_ep->fifo = musb->io.fifo_offset(i) + mbase;
 #if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010)
-   if (musb->io.quirks & MUSB_IN_TUSB) {
+   if (musb->ops->quirks & MUSB_IN_TUSB) {
hw_ep->fifo_async = musb->async + 0x400 +
musb->io.fifo_offset(i);
hw_ep->fifo_sync = musb->sync + 0x400 +
@@ -2176,11 +2176,9 @@ static void musb_deassert_reset(struct work_struct *work)
goto fail2;
}
 
-   if (musb->ops->quirks)
-   musb->io.quirks = musb->ops->quirks;
 
/* Most devices use indexed offset or flat offset */
-   if (musb->io.quirks & MUSB_INDEXED_EP) {
+   if (musb->ops->quirks & MUSB_INDEXED_EP) {
musb->io.ep_offset = musb_indexed_ep_offset;
musb->io.ep_select = musb_indexed_ep_select;
} else {
@@ -2188,7 +2186,7 @@ static void musb_deassert_reset(struct work_struct *work)
musb->io.ep_select = musb_flat_ep_select;
}
 
-   if (musb->io.quirks & MUSB_G_NO_SKB_RESERVE)
+   if (musb->ops->quirks & MUSB_G_NO_SKB_RESERVE)
musb->g.quirk_avoids_skb_reserve = 1;
 
/* At least tusb6010 has its own offsets */
@@ -2647,7 +2645,7 @@ static int musb_suspend(struct device *dev)
;
musb->flush_irq_work = false;
 
-   if (!(musb->io.quirks & MUSB_PRESERVE_SESSION))
+   if (!(musb->ops->quirks & MUSB_PRESERVE_SESSION))
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 
WARN_ON(!list_empty(>pending_list));
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index d0dd4f470bbe..7fbb8a307145 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -614,7 +614,7 @@ static int cppi41_dma_channel_abort(struct dma_channel 
*channel)
}
 
/* DA8xx Advisory 2.3.27: wait 250 ms before to start the teardown */
-   if (musb->io.quirks & MUSB_DA8XX)
+   if (musb->ops->quirks & MUSB_DA8XX)
mdelay(250);
 
tdbit = 1 << cppi41_channel->port_num;
@@ -773,7 +773,7 @@ struct dma_controller *
controller->controller.is_compatible = cppi41_is_compatible;
controller->controller.musb = musb;
 
-   if (musb->io.quirks & MUSB_DA8XX) {
+   if (musb->ops->quirks & MUSB_DA8XX) {
controller->tdown_reg = DA8XX_USB_TEARDOWN;
controller->autoreq_reg = DA8XX_USB_AUTOREQ;
controller->set_dma_mode = da8xx_set_dma_mode;
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 0fc8cd0c2a5c..8f60271c0a9d 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -44,31 +44,31 @@
 #endif
 
 #ifdef CONFIG_USB_UX500_DMA
-#define musb_dma_ux500(musb)   (musb->io.quirks & MUSB_DMA_UX500)
+#define musb_dma_ux500(musb)   (musb->ops->quirks & MUSB_DMA_UX500)
 #else
 #define musb_dma_ux500(musb)   0
 #endif
 
 #ifdef CONFIG_USB_TI_CPPI41_DMA
-#define musb_dma_cppi41(musb)  (musb->io.quirks & MUSB_DMA_CPPI41)
+#define musb_dma_cppi41(musb)  (musb->ops->quirks & MUSB_DMA_CPPI41)
 #else
 #define musb_dma_cppi41(musb)  0
 #endif
 
 #ifdef CONFIG_USB_TI_CPPI_DMA
-#define musb_dma_cppi(musb)(musb->io.quirks & MUSB_DMA_CPPI)
+#define musb_dma_cppi(musb)(musb->ops->quirks & MUSB_DMA_CPPI)
 #else
 #define musb_dma_cppi(musb)0
 #endif
 
 #ifdef CONFIG_USB_TUSB_OMAP_DMA
-#define tusb_dma_omap(musb)(musb->io.quirks & MUSB_DMA_TUSB_OMAP)
+#define tusb_dma_omap(musb)(musb->ops->quirks & MUSB_DMA_TUSB_OMAP)
 #else
 #define tusb_dma_omap(musb)0
 #endif
 
 #ifdef CONFIG_USB_INVENTRA_DMA
-#define musb_dma_inventra(musb)(musb->io.quirks & 
MUSB_DMA_INVENTRA)
+#define musb_dma_inventra(musb)(musb->ops->quirks & 
MUSB_DMA_INVENTRA)
 #else
 #define musb_dma_inventra(musb)0
 #endif
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index b4d870b836aa..8058a58092cf 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -16,7 +16,6 @@
 
 /**
  * struct musb_io - IO 

[PATCH 02/14] usb: musb: remove readl/writel from struct musb_platform_ops

2018-05-21 Thread Bin Liu
Now Blackfin support is removed, we no longer need function pointers for
musb_readl() and musb_writel().

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/musb_core.c | 34 --
 drivers/usb/musb/musb_core.h |  4 
 drivers/usb/musb/musb_io.h   |  4 ++--
 3 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index fb5e4523dc28..4ff6da1aa775 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -274,20 +274,6 @@ static void musb_default_writew(void __iomem *addr, 
unsigned offset, u16 data)
__raw_writew(data, addr + offset);
 }
 
-static u32 musb_default_readl(const void __iomem *addr, unsigned offset)
-{
-   u32 data = __raw_readl(addr + offset);
-
-   trace_musb_readl(__builtin_return_address(0), addr, offset, data);
-   return data;
-}
-
-static void musb_default_writel(void __iomem *addr, unsigned offset, u32 data)
-{
-   trace_musb_writel(__builtin_return_address(0), addr, offset, data);
-   __raw_writel(data, addr + offset);
-}
-
 /*
  * Load an endpoint's FIFO
  */
@@ -390,10 +376,20 @@ static void musb_default_read_fifo(struct musb_hw_ep 
*hw_ep, u16 len, u8 *dst)
 void (*musb_writew)(void __iomem *addr, unsigned offset, u16 data);
 EXPORT_SYMBOL_GPL(musb_writew);
 
-u32 (*musb_readl)(const void __iomem *addr, unsigned offset);
+u32 musb_readl(const void __iomem *addr, unsigned offset)
+{
+   u32 data = __raw_readl(addr + offset);
+
+   trace_musb_readl(__builtin_return_address(0), addr, offset, data);
+   return data;
+}
 EXPORT_SYMBOL_GPL(musb_readl);
 
-void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data);
+void musb_writel(void __iomem *addr, unsigned offset, u32 data)
+{
+   trace_musb_writel(__builtin_return_address(0), addr, offset, data);
+   __raw_writel(data, addr + offset);
+}
 EXPORT_SYMBOL_GPL(musb_writel);
 
 #ifndef CONFIG_MUSB_PIO_ONLY
@@ -2158,8 +2154,6 @@ static void musb_deassert_reset(struct work_struct *work)
musb_writeb = musb_default_writeb;
musb_readw = musb_default_readw;
musb_writew = musb_default_writew;
-   musb_readl = musb_default_readl;
-   musb_writel = musb_default_writel;
 
/* The musb_platform_init() call:
 *   - adjusts musb->mregs
@@ -2226,10 +2220,6 @@ static void musb_deassert_reset(struct work_struct *work)
musb_readw = musb->ops->readw;
if (musb->ops->writew)
musb_writew = musb->ops->writew;
-   if (musb->ops->readl)
-   musb_readl = musb->ops->readl;
-   if (musb->ops->writel)
-   musb_writel = musb->ops->writel;
 
 #ifndef CONFIG_MUSB_PIO_ONLY
if (!musb->ops->dma_init || !musb->ops->dma_exit) {
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 8a74cb2907f8..a4bf1e9e2d2c 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -127,8 +127,6 @@ enum musb_g_ep0_state {
  * @writeb:write 8 bits
  * @readw: read 16 bits
  * @writew:write 16 bits
- * @readl: read 32 bits
- * @writel:write 32 bits
  * @read_fifo: reads the fifo
  * @write_fifo:writes to fifo
  * @dma_init:  platform specific dma init function
@@ -174,8 +172,6 @@ struct musb_platform_ops {
void(*writeb)(void __iomem *addr, unsigned offset, u8 data);
u16 (*readw)(const void __iomem *addr, unsigned offset);
void(*writew)(void __iomem *addr, unsigned offset, u16 data);
-   u32 (*readl)(const void __iomem *addr, unsigned offset);
-   void(*writel)(void __iomem *addr, unsigned offset, u32 data);
void(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
void(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
struct dma_controller *
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index b7025b2e6e00..b4d870b836aa 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -39,7 +39,7 @@ struct musb_io {
 extern void (*musb_writeb)(void __iomem *addr, unsigned offset, u8 data);
 extern u16 (*musb_readw)(const void __iomem *addr, unsigned offset);
 extern void (*musb_writew)(void __iomem *addr, unsigned offset, u16 data);
-extern u32 (*musb_readl)(const void __iomem *addr, unsigned offset);
-extern void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data);
+extern u32 musb_readl(const void __iomem *addr, unsigned offset);
+extern void musb_writel(void __iomem *addr, unsigned offset, u32 data);
 
 #endif
-- 
1.9.1

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


[PATCH 10/14] usb: musb: remove references to default_a of struct usb_otg

2018-05-21 Thread Bin Liu
musb drivers do not use the otg fsm framework, so referencing to
otg->default_a doesn't have any effect, so remove the references.

But tusb6010 glue driver uses it locally to control the vbus power, so
keep the references in tusb6010 only.

Signed-off-by: Bin Liu 
---
 drivers/usb/musb/am35x.c   |  3 ---
 drivers/usb/musb/da8xx.c   |  2 --
 drivers/usb/musb/davinci.c | 49 --
 drivers/usb/musb/musb_core.c   |  9 ++--
 drivers/usb/musb/musb_dsps.c   |  2 --
 drivers/usb/musb/musb_gadget.c |  1 -
 drivers/usb/musb/musb_host.c   |  1 -
 drivers/usb/musb/omap2430.c|  5 -
 drivers/usb/musb/sunxi.c   |  2 --
 drivers/usb/musb/ux500.c   |  2 --
 10 files changed, 25 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 0ad664efda6b..660641ab1545 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -201,7 +201,6 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
-   struct usb_otg *otg = musb->xceiv->otg;
unsigned long flags;
irqreturn_t ret = IRQ_NONE;
u32 epintr, usbintr;
@@ -264,14 +263,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void 
*hci)
WARNING("VBUS error workaround (delay coming)\n");
} else if (drvvbus) {
MUSB_HST_MODE(musb);
-   otg->default_a = 1;
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
del_timer(>dev_timer);
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
-   otg->default_a = 0;
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index b8295ce7c4fe..0e5929e81d26 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -280,7 +280,6 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
WARNING("VBUS error workaround (delay coming)\n");
} else if (drvvbus) {
MUSB_HST_MODE(musb);
-   otg->default_a = 1;
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
del_timer(>dev_timer);
@@ -295,7 +294,6 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
 */
musb->is_active = 0;
MUSB_DEV_MODE(musb);
-   otg->default_a = 0;
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 2ad39dcd2f4c..fb6bbd254ab7 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -311,14 +311,12 @@ static irqreturn_t davinci_musb_interrupt(int irq, void 
*__hci)
WARNING("VBUS error workaround (delay coming)\n");
} else if (drvvbus) {
MUSB_HST_MODE(musb);
-   otg->default_a = 1;
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
del_timer(>dev_timer);
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
-   otg->default_a = 0;
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
@@ -425,6 +423,9 @@ static int davinci_musb_init(struct musb *musb)
 
 static int davinci_musb_exit(struct musb *musb)
 {
+   int maxdelay = 30;
+   u8  devctl, warn = 0;
+
del_timer_sync(>dev_timer);
 
/* force VBUS off */
@@ -438,31 +439,27 @@ static int davinci_musb_exit(struct musb *musb)
 
davinci_musb_source_power(musb, 0 /*off*/, 1);
 
-   /* delay, to avoid problems with module reload */
-   if (musb->xceiv->otg->default_a) {
-   int maxdelay = 30;
-   u8  devctl, warn = 0;
+   /*
+* delay, to avoid problems with module reload.
+* if there's no peripheral connected, this can take a
+* long time to fall, especially on EVM with huge C133.
+*/
+   do {
+

[PATCH 10/18] xhci: rename faked_port_index to hcd_portnum

2018-05-21 Thread Mathias Nyman
hcd_portnum is a better desctiption than faked_port_index, and
is in line with the name the port structure uses.

No functional changes

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-ring.c | 41 +++--
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4d2d0e8..31b7213 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1525,7 +1525,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
u32 portsc, cmd_reg;
int max_ports;
int slot_id;
-   unsigned int faked_port_index;
+   unsigned int hcd_portnum;
struct xhci_bus_state *bus_state;
__le32 __iomem **port_array;
bool bogus_port_status = false;
@@ -1560,10 +1560,10 @@ static void handle_port_status(struct xhci_hcd *xhci,
else
port_array = xhci->usb2_ports;
 
-   faked_port_index = port->hcd_portnum;
+   hcd_portnum = port->hcd_portnum;
portsc = readl(port->addr);
 
-   trace_xhci_handle_port_status(faked_port_index, portsc);
+   trace_xhci_handle_port_status(hcd_portnum, portsc);
 
if (hcd->state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, "resume root hub\n");
@@ -1571,7 +1571,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
}
 
if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE)
-   bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
+   bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);
 
if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) {
xhci_dbg(xhci, "port resume event for port %d\n", port_id);
@@ -1588,29 +1588,28 @@ static void handle_port_status(struct xhci_hcd *xhci,
 * so we can tell the difference between the end of
 * device and host initiated resume.
 */
-   bus_state->port_remote_wakeup |= 1 << faked_port_index;
+   bus_state->port_remote_wakeup |= 1 << hcd_portnum;
xhci_test_and_clear_bit(xhci, port_array,
-   faked_port_index, PORT_PLC);
-   xhci_set_link_state(xhci, port_array, faked_port_index,
+   hcd_portnum, PORT_PLC);
+   xhci_set_link_state(xhci, port_array, hcd_portnum,
XDEV_U0);
/* Need to wait until the next link state change
 * indicates the device is actually in U0.
 */
bogus_port_status = true;
goto cleanup;
-   } else if (!test_bit(faked_port_index,
-_state->resuming_ports)) {
+   } else if (!test_bit(hcd_portnum, _state->resuming_ports)) {
xhci_dbg(xhci, "resume HS port %d\n", port_id);
-   bus_state->resume_done[faked_port_index] = jiffies +
+   bus_state->resume_done[hcd_portnum] = jiffies +
msecs_to_jiffies(USB_RESUME_TIMEOUT);
-   set_bit(faked_port_index, _state->resuming_ports);
+   set_bit(hcd_portnum, _state->resuming_ports);
/* Do the rest in GetPortStatus after resume time delay.
 * Avoid polling roothub status before that so that a
 * usb device auto-resume latency around ~40ms.
 */
set_bit(HCD_FLAG_POLL_RH, >flags);
mod_timer(>rh_timer,
- bus_state->resume_done[faked_port_index]);
+ bus_state->resume_done[hcd_portnum]);
bogus_port_status = true;
}
}
@@ -1625,17 +1624,15 @@ static void handle_port_status(struct xhci_hcd *xhci,
 * so the roothub behavior is consistent with external
 * USB 3.0 hub behavior.
 */
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   faked_port_index + 1);
+   slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1);
if (slot_id && xhci->devs[slot_id])
xhci_ring_device(xhci, slot_id);
-   if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
-   bus_state->port_remote_wakeup &=
-   ~(1 << faked_port_index);
+   if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) {
+   bus_state->port_remote_wakeup &= ~(1 << hcd_portnum);

[PATCH 07/18] xhci: xhci-hub: use new port structures to get port address instead of port array

2018-05-21 Thread Mathias Nyman
Use the new port structures for functions in xhci-hub.c to get
port mmio address of portsc register instead of the port array

xhci_get_port_io_addr() is no longer needeed and is removed.
Plan is to get rid of the mmio port array completely.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c | 140 
 1 file changed, 78 insertions(+), 62 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index b6fd26f..0796f08 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -189,9 +189,10 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
__u8 port_removable[(USB_MAXCHILDREN + 1 + 7) / 8];
u32 portsc;
unsigned int i;
+   struct xhci_hub *rhub;
 
-   ports = xhci->num_usb2_ports;
-
+   rhub = >usb2_rhub;
+   ports = rhub->num_ports;
xhci_common_hub_descriptor(xhci, desc, ports);
desc->bDescriptorType = USB_DT_HUB;
temp = 1 + (ports / 8);
@@ -202,7 +203,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
 */
memset(port_removable, 0, sizeof(port_removable));
for (i = 0; i < ports; i++) {
-   portsc = readl(xhci->usb2_ports[i]);
+   portsc = readl(rhub->ports[i]->addr);
/* If a device is removable, PORTSC reports a 0, same as in the
 * hub descriptor DeviceRemovable bits.
 */
@@ -241,8 +242,10 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
u16 port_removable;
u32 portsc;
unsigned int i;
+   struct xhci_hub *rhub;
 
-   ports = xhci->num_usb3_ports;
+   rhub = >usb3_rhub;
+   ports = rhub->num_ports;
xhci_common_hub_descriptor(xhci, desc, ports);
desc->bDescriptorType = USB_DT_SS_HUB;
desc->bDescLength = USB_DT_SS_HUB_SIZE;
@@ -256,7 +259,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, 
struct xhci_hcd *xhci,
port_removable = 0;
/* bit 0 is reserved, bit 1 is for port 1, etc. */
for (i = 0; i < ports; i++) {
-   portsc = readl(xhci->usb3_ports[i]);
+   portsc = readl(rhub->ports[i]->addr);
if (portsc & PORT_DEV_REMOVE)
port_removable |= 1 << (i + 1);
}
@@ -563,14 +566,6 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd)
return >usb2_rhub;
 }
 
-static __le32 __iomem *xhci_get_port_io_addr(struct usb_hcd *hcd, int index)
-{
-   __le32 __iomem **port_array;
-
-   xhci_get_ports(hcd, _array);
-   return port_array[index];
-}
-
 /*
  * xhci_set_port_power() must be called with xhci->lock held.
  * It will release and re-aquire the lock while calling ACPI
@@ -579,21 +574,23 @@ static __le32 __iomem *xhci_get_port_io_addr(struct 
usb_hcd *hcd, int index)
 static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,
u16 index, bool on, unsigned long *flags)
 {
-   __le32 __iomem *addr;
+   struct xhci_hub *rhub;
+   struct xhci_port *port;
u32 temp;
 
-   addr = xhci_get_port_io_addr(hcd, index);
-   temp = readl(addr);
+   rhub = xhci_get_rhub(hcd);
+   port = rhub->ports[index];
+   temp = readl(port->addr);
temp = xhci_port_state_to_neutral(temp);
if (on) {
/* Power on */
-   writel(temp | PORT_POWER, addr);
-   temp = readl(addr);
+   writel(temp | PORT_POWER, port->addr);
+   temp = readl(port->addr);
xhci_dbg(xhci, "set port power, actual port %d status  = 
0x%x\n",
index, temp);
} else {
/* Power off */
-   writel(temp & ~PORT_POWER, addr);
+   writel(temp & ~PORT_POWER, port->addr);
}
 
spin_unlock_irqrestore(>lock, *flags);
@@ -609,13 +606,13 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
u16 test_mode, u16 wIndex)
 {
u32 temp;
-   __le32 __iomem *addr;
+   struct xhci_port *port;
 
-   /* xhci only supports test mode for usb2 ports, i.e. xhci->main_hcd */
-   addr = xhci_get_port_io_addr(xhci->main_hcd, wIndex);
-   temp = readl(addr + PORTPMSC);
+   /* xhci only supports test mode for usb2 ports */
+   port = xhci->usb2_rhub.ports[wIndex];
+   temp = readl(port->addr + PORTPMSC);
temp |= test_mode << PORT_TEST_MODE_SHIFT;
-   writel(temp, addr + PORTPMSC);
+   writel(temp, port->addr + PORTPMSC);
xhci->test_mode = test_mode;
if (test_mode == TEST_FORCE_EN)
xhci_start(xhci);
@@ -642,10 +639,10 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci,
/* Put all ports to the Disable state by clear PP */

[PATCH 09/18] xhci: xhci-ring: use port structures for port event handler

2018-05-21 Thread Mathias Nyman
use port structures in the port event handler.
Getting the right hcd and hcd portnumber from the hardware port number
is a lot easier with port structures, and allows us to remove a lot
of the previous code, including the find_faked_portnum_from_hw_index()
function

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-ring.c | 79 +---
 1 file changed, 8 insertions(+), 71 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 91a1a82..4d2d0e8 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1497,44 +1497,6 @@ static void handle_vendor_event(struct xhci_hcd *xhci,
handle_cmd_completion(xhci, >event_cmd);
 }
 
-/* @port_id: the one-based port ID from the hardware (indexed from array of all
- * port registers -- USB 3.0 and USB 2.0).
- *
- * Returns a zero-based port number, which is suitable for indexing into each 
of
- * the split roothubs' port arrays and bus state arrays.
- * Add one to it in order to call xhci_find_slot_id_by_port.
- */
-static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
-   struct xhci_hcd *xhci, u32 port_id)
-{
-   unsigned int i;
-   unsigned int num_similar_speed_ports = 0;
-
-   /* port_id from the hardware is 1-based, but port_array[], usb3_ports[],
-* and usb2_ports are 0-based indexes.  Count the number of similar
-* speed ports, up to 1 port before this port.
-*/
-   for (i = 0; i < (port_id - 1); i++) {
-   u8 port_speed = xhci->port_array[i];
-
-   /*
-* Skip ports that don't have known speeds, or have duplicate
-* Extended Capabilities port speed entries.
-*/
-   if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
-   continue;
-
-   /*
-* USB 3.0 ports are always under a USB 3.0 hub.  USB 2.0 and
-* 1.1 ports are under the USB 2.0 hub.  If the port speed
-* matches the device speed, it's a similar speed port.
-*/
-   if ((port_speed == 0x03) == (hcd->speed >= HCD_USB3))
-   num_similar_speed_ports++;
-   }
-   return num_similar_speed_ports;
-}
-
 static void handle_device_notification(struct xhci_hcd *xhci,
union xhci_trb *event)
 {
@@ -1564,10 +1526,10 @@ static void handle_port_status(struct xhci_hcd *xhci,
int max_ports;
int slot_id;
unsigned int faked_port_index;
-   u8 major_revision;
struct xhci_bus_state *bus_state;
__le32 __iomem **port_array;
bool bogus_port_status = false;
+   struct xhci_port *port;
 
/* Port status change events always have a successful completion code */
if (GET_COMP_CODE(le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS)
@@ -1584,47 +1546,22 @@ static void handle_port_status(struct xhci_hcd *xhci,
return;
}
 
-   /* Figure out which usb_hcd this port is attached to:
-* is it a USB 3.0 port or a USB 2.0/1.1 port?
-*/
-   major_revision = xhci->port_array[port_id - 1];
-
-   /* Find the right roothub. */
-   hcd = xhci_to_hcd(xhci);
-   if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3))
-   hcd = xhci->shared_hcd;
-
-   if (major_revision == 0) {
-   xhci_warn(xhci, "Event for port %u not in "
-   "Extended Capabilities, ignoring.\n",
-   port_id);
-   bogus_port_status = true;
-   goto cleanup;
-   }
-   if (major_revision == DUPLICATE_ENTRY) {
-   xhci_warn(xhci, "Event for port %u duplicated in"
-   "Extended Capabilities, ignoring.\n",
-   port_id);
+   port = >hw_ports[port_id - 1];
+   if (!port || !port->rhub || port->hcd_portnum == DUPLICATE_ENTRY) {
+   xhci_warn(xhci, "Event for invalid port %u\n", port_id);
bogus_port_status = true;
goto cleanup;
}
 
-   /*
-* Hardware port IDs reported by a Port Status Change Event include USB
-* 3.0 and USB 2.0 ports.  We want to check if the port has reported a
-* resume event, but we first need to translate the hardware port ID
-* into the index into the ports on the correct split roothub, and the
-* correct bus_state structure.
-*/
+   hcd = port->rhub->hcd;
bus_state = >bus_state[hcd_index(hcd)];
if (hcd->speed >= HCD_USB3)
port_array = xhci->usb3_ports;
else
port_array = xhci->usb2_ports;
-   /* Find the faked port hub number */
-   faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci,
-   port_id);

[PATCH 11/18] xhci: change xhci_set_link_state() to work with port structures

2018-05-21 Thread Mathias Nyman
Remove old iomem port array and index as parameters, just
send a ponter to a port strucure instread

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c  | 34 --
 drivers/usb/host/xhci-ring.c |  3 +--
 drivers/usb/host/xhci.h  |  4 ++--
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 372b448..e3be8d1 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -678,16 +678,16 @@ static int xhci_exit_test_mode(struct xhci_hcd *xhci)
return xhci_reset(xhci);
 }
 
-void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
-   int port_id, u32 link_state)
+void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
+u32 link_state)
 {
u32 temp;
 
-   temp = readl(port_array[port_id]);
+   temp = readl(port->addr);
temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
-   writel(temp, port_array[port_id]);
+   writel(temp, port->addr);
 }
 
 static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
@@ -932,8 +932,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 
xhci_test_and_clear_bit(xhci, port_array, wIndex,
PORT_PLC);
-   xhci_set_link_state(xhci, port_array, wIndex,
-   XDEV_U0);
+   xhci_set_link_state(xhci, port, XDEV_U0);
 
spin_unlock_irqrestore(>lock, flags);
time_left = wait_for_completion_timeout(
@@ -1142,7 +1141,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
temp = readl(ports[wIndex]->addr);
if ((temp & PORT_PLS_MASK) != XDEV_U0) {
/* Resume the port to U0 first */
-   xhci_set_link_state(xhci, port_array, wIndex,
+   xhci_set_link_state(xhci, ports[wIndex],
XDEV_U0);
spin_unlock_irqrestore(>lock, flags);
msleep(10);
@@ -1170,7 +1169,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
xhci_stop_device(xhci, slot_id, 1);
spin_lock_irqsave(>lock, flags);
 
-   xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
+   xhci_set_link_state(xhci, ports[wIndex], XDEV_U3);
 
spin_unlock_irqrestore(>lock, flags);
msleep(10); /* wait device to enter */
@@ -1200,8 +1199,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
/* Put link in RxDetect (enable port) */
if (link_state == USB_SS_PORT_LS_RX_DETECT) {
xhci_dbg(xhci, "Enable port %d\n", wIndex);
-   xhci_set_link_state(xhci, port_array, wIndex,
-   link_state);
+   xhci_set_link_state(xhci, ports[wIndex],
+   link_state);
temp = readl(ports[wIndex]->addr);
break;
}
@@ -1233,8 +1232,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
 
xhci_dbg(xhci, "Enable compliance mode 
transition for port %d\n",
wIndex);
-   xhci_set_link_state(xhci, port_array, wIndex,
+   xhci_set_link_state(xhci, ports[wIndex],
link_state);
+
temp = readl(ports[wIndex]->addr);
break;
}
@@ -1262,8 +1262,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
}
}
 
-   xhci_set_link_state(xhci, port_array, wIndex,
-   link_state);
+   xhci_set_link_state(xhci, ports[wIndex], link_state);
 
spin_unlock_irqrestore(>lock, flags);
msleep(20); /* wait device to enter */
@@ -1357,12 +1356,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
goto error;
 
set_bit(wIndex, _state->resuming_ports);
-   xhci_set_link_state(xhci, port_array, wIndex,
-

[PATCH 12/18] xhci: change xhci_test_and_clear_bit() to use new port structure

2018-05-21 Thread Mathias Nyman
Don't use pointers to port array and port index as function parameters
in xhci_test_and_clear_bit(), just use a pointer to the right port
structure.

xhci_test_and_clear_bit() was the last port_array user in
xhci_get_port_status() and handle_port_status(), so remove the
port_array from them as well.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c  | 22 ++
 drivers/usb/host/xhci-ring.c | 15 +++
 drivers/usb/host/xhci.h  |  4 ++--
 3 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index e3be8d1..05115b8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -717,16 +717,16 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd 
*xhci,
 }
 
 /* Test and clear port RWC bit */
-void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem 
**port_array,
-   int port_id, u32 port_bit)
+void xhci_test_and_clear_bit(struct xhci_hcd *xhci, struct xhci_port *port,
+u32 port_bit)
 {
u32 temp;
 
-   temp = readl(port_array[port_id]);
+   temp = readl(port->addr);
if (temp & port_bit) {
temp = xhci_port_state_to_neutral(temp);
temp |= port_bit;
-   writel(temp, port_array[port_id]);
+   writel(temp, port->addr);
}
 }
 
@@ -846,8 +846,7 @@ static u32 xhci_get_ext_port_status(u32 raw_port_status, 
u32 port_li)
  */
 static u32 xhci_get_port_status(struct usb_hcd *hcd,
struct xhci_bus_state *bus_state,
-   __le32 __iomem **port_array,
-   u16 wIndex, u32 raw_port_status,
+   u16 wIndex, u32 raw_port_status,
unsigned long flags)
__releases(>lock)
__acquires(>lock)
@@ -930,8 +929,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 
set_bit(wIndex, _state->rexit_ports);
 
-   xhci_test_and_clear_bit(xhci, port_array, wIndex,
-   PORT_PLC);
+   xhci_test_and_clear_bit(xhci, port, PORT_PLC);
xhci_set_link_state(xhci, port, XDEV_U0);
 
spin_unlock_irqrestore(>lock, flags);
@@ -1091,8 +1089,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
break;
}
trace_xhci_get_port_status(wIndex, temp);
-   status = xhci_get_port_status(hcd, bus_state, port_array,
-   wIndex, temp, flags);
+   status = xhci_get_port_status(hcd, bus_state, wIndex, temp,
+ flags);
if (status == 0x)
goto error;
 
@@ -1673,7 +1671,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
for_each_set_bit(port_index, _state->bus_suspended,
 BITS_PER_LONG) {
/* Clear PLC to poll it later for U0 transition */
-   xhci_test_and_clear_bit(xhci, port_array, port_index,
+   xhci_test_and_clear_bit(xhci, ports[port_index],
PORT_PLC);
xhci_set_link_state(xhci, ports[port_index], XDEV_U0);
}
@@ -1688,7 +1686,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
  port_index);
continue;
}
-   xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC);
+   xhci_test_and_clear_bit(xhci, ports[port_index], PORT_PLC);
slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1);
if (slot_id)
xhci_ring_device(xhci, slot_id);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6e4211e..f0a99aa 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1527,7 +1527,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
int slot_id;
unsigned int hcd_portnum;
struct xhci_bus_state *bus_state;
-   __le32 __iomem **port_array;
bool bogus_port_status = false;
struct xhci_port *port;
 
@@ -1555,11 +1554,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
 
hcd = port->rhub->hcd;
bus_state = >bus_state[hcd_index(hcd)];
-   if (hcd->speed >= HCD_USB3)
-   port_array = xhci->usb3_ports;
-   else
-   port_array = xhci->usb2_ports;
-
hcd_portnum = port->hcd_portnum;
portsc = readl(port->addr);
 
@@ -1589,8 +1583,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 * device and host initiated resume.
 */
bus_state->port_remote_wakeup |= 1 

[PATCH 13/18] xhci: use port structures instead of port arrays in xhci.c functions

2018-05-21 Thread Mathias Nyman
get rid of port iomem arrays and use port structures in the following
functions:
xhci_find_raw_port_number()
xhci_disable_port_wake_on_bits()
xhci_set_usb2_hardware_lpm()
xhci_all_ports_seen_u0()
compliance_mode_recovery()

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci.c | 50 ++---
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f614ba1..02e2697 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -400,13 +400,15 @@ static void compliance_mode_recovery(struct timer_list *t)
 {
struct xhci_hcd *xhci;
struct usb_hcd *hcd;
+   struct xhci_hub *rhub;
u32 temp;
int i;
 
xhci = from_timer(xhci, t, comp_mode_recovery_timer);
+   rhub = >usb3_rhub;
 
-   for (i = 0; i < xhci->num_usb3_ports; i++) {
-   temp = readl(xhci->usb3_ports[i]);
+   for (i = 0; i < rhub->num_ports; i++) {
+   temp = readl(rhub->ports[i]->addr);
if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
/*
 * Compliance Mode Detected. Letting USB Core
@@ -426,7 +428,7 @@ static void compliance_mode_recovery(struct timer_list *t)
}
}
 
-   if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1))
+   if (xhci->port_status_u0 != ((1 << rhub->num_ports) - 1))
mod_timer(>comp_mode_recovery_timer,
jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS));
 }
@@ -483,7 +485,7 @@ static bool 
xhci_compliance_mode_recovery_timer_quirk_check(void)
 
 static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci)
 {
-   return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1));
+   return (xhci->port_status_u0 == ((1 << xhci->usb3_rhub.num_ports) - 1));
 }
 
 
@@ -812,33 +814,33 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
 
 static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
 {
+   struct xhci_port **ports;
int port_index;
-   __le32 __iomem **port_array;
unsigned long flags;
u32 t1, t2;
 
spin_lock_irqsave(>lock, flags);
 
/* disable usb3 ports Wake bits */
-   port_index = xhci->num_usb3_ports;
-   port_array = xhci->usb3_ports;
+   port_index = xhci->usb3_rhub.num_ports;
+   ports = xhci->usb3_rhub.ports;
while (port_index--) {
-   t1 = readl(port_array[port_index]);
+   t1 = readl(ports[port_index]->addr);
t1 = xhci_port_state_to_neutral(t1);
t2 = t1 & ~PORT_WAKE_BITS;
if (t1 != t2)
-   writel(t2, port_array[port_index]);
+   writel(t2, ports[port_index]->addr);
}
 
/* disable usb2 ports Wake bits */
-   port_index = xhci->num_usb2_ports;
-   port_array = xhci->usb2_ports;
+   port_index = xhci->usb2_rhub.num_ports;
+   ports = xhci->usb2_rhub.ports;
while (port_index--) {
-   t1 = readl(port_array[port_index]);
+   t1 = readl(ports[port_index]->addr);
t1 = xhci_port_state_to_neutral(t1);
t2 = t1 & ~PORT_WAKE_BITS;
if (t1 != t2)
-   writel(t2, port_array[port_index]);
+   writel(t2, ports[port_index]->addr);
}
 
spin_unlock_irqrestore(>lock, flags);
@@ -3976,18 +3978,10 @@ static int xhci_enable_device(struct usb_hcd *hcd, 
struct usb_device *udev)
  */
 int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
 {
-   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-   __le32 __iomem *base_addr = >op_regs->port_status_base;
-   __le32 __iomem *addr;
-   int raw_port;
-
-   if (hcd->speed < HCD_USB3)
-   addr = xhci->usb2_ports[port1 - 1];
-   else
-   addr = xhci->usb3_ports[port1 - 1];
+   struct xhci_hub *rhub;
 
-   raw_port = (addr - base_addr)/NUM_PORT_REGS + 1;
-   return raw_port;
+   rhub = xhci_get_rhub(hcd);
+   return rhub->ports[port1 - 1]->hw_portnum + 1;
 }
 
 /*
@@ -4120,7 +4114,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
struct usb_device *udev, int enable)
 {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-   __le32 __iomem  **port_array;
+   struct xhci_port **ports;
__le32 __iomem  *pm_addr, *hlpm_addr;
u32 pm_val, hlpm_val, field;
unsigned intport_num;
@@ -4141,11 +4135,11 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd 
*hcd,
 
spin_lock_irqsave(>lock, flags);
 
-   port_array = xhci->usb2_ports;
+   ports = xhci->usb2_rhub.ports;
port_num = udev->portnum - 1;
-   pm_addr = port_array[port_num] + PORTPMSC;
+   pm_addr = ports[port_num]->addr + PORTPMSC;

[PATCH 14/18] xhci: xhci-hub: use port structure members instead of xhci_get_ports()

2018-05-21 Thread Mathias Nyman
xhci_get_ports() is one of the last functions using port_arrays in
xhci-hub.c. We get the same data directly from hub and port structures
instead, so convert and remove both xhci_get_ports() and port_arrays from
all function that no longer need it.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c | 28 
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 05115b8..a4b95d0 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -541,22 +541,6 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
port_change_bit, wIndex, port_status);
 }
 
-static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array)
-{
-   int max_ports;
-   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
-   if (hcd->speed >= HCD_USB3) {
-   max_ports = xhci->num_usb3_ports;
-   *port_array = xhci->usb3_ports;
-   } else {
-   max_ports = xhci->num_usb2_ports;
-   *port_array = xhci->usb2_ports;
-   }
-
-   return max_ports;
-}
-
 struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd)
 {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -1032,7 +1016,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
unsigned long flags;
u32 temp, status;
int retval = 0;
-   __le32 __iomem **port_array;
int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
@@ -1044,7 +1027,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
 
rhub = xhci_get_rhub(hcd);
ports = rhub->ports;
-   max_ports = xhci_get_ports(hcd, _array);
+   max_ports = rhub->num_ports;
bus_state = >bus_state[hcd_index(hcd)];
 
spin_lock_irqsave(>lock, flags);
@@ -1425,7 +1408,6 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
int i, retval;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int max_ports;
-   __le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
bool reset_change = false;
struct xhci_hub *rhub;
@@ -1433,7 +1415,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 
rhub = xhci_get_rhub(hcd);
ports = rhub->ports;
-   max_ports = xhci_get_ports(hcd, _array);
+   max_ports = rhub->num_ports;
bus_state = >bus_state[hcd_index(hcd)];
 
/* Initial status is no changes */
@@ -1483,7 +1465,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int max_ports, port_index;
-   __le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
unsigned long flags;
struct xhci_hub *rhub;
@@ -1491,7 +1472,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 
rhub = xhci_get_rhub(hcd);
ports = rhub->ports;
-   max_ports = xhci_get_ports(hcd, _array);
+   max_ports = rhub->num_ports;
bus_state = >bus_state[hcd_index(hcd)];
 
spin_lock_irqsave(>lock, flags);
@@ -1592,7 +1573,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_bus_state *bus_state;
-   __le32 __iomem **port_array;
unsigned long flags;
int max_ports, port_index;
int slot_id;
@@ -1604,7 +1584,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 
rhub = xhci_get_rhub(hcd);
ports = rhub->ports;
-   max_ports = xhci_get_ports(hcd, _array);
+   max_ports = rhub->num_ports;
bus_state = >bus_state[hcd_index(hcd)];
 
if (time_before(jiffies, bus_state->next_statechange))
-- 
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 16/18] xhci: xhci-mem: remove port_arrays and the code initializing them

2018-05-21 Thread Mathias Nyman
As we are now using the new port strtuctes the port_arrays
are no longer needed, remove them completely

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-mem.c | 100 +---
 drivers/usb/host/xhci.h |   8 
 2 files changed, 11 insertions(+), 97 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 8819286..0b61b77 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1054,8 +1054,7 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd 
*xhci,
 
 /*
  * The xHCI roothub may have ports of differing speeds in any order in the port
- * status registers.  xhci->port_array provides an array of the port speed for
- * each offset into the port status registers.
+ * status registers.
  *
  * The xHCI hardware wants to know the roothub port number that the USB device
  * is attached to (or the roothub port its ancestor hub is attached to).  All 
we
@@ -1890,23 +1889,15 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 
 no_bw:
xhci->cmd_ring_reserved_trbs = 0;
-   xhci->num_usb2_ports = 0;
-   xhci->num_usb3_ports = 0;
xhci->usb2_rhub.num_ports = 0;
xhci->usb3_rhub.num_ports = 0;
xhci->num_active_eps = 0;
-   kfree(xhci->usb2_ports);
-   kfree(xhci->usb3_ports);
-   kfree(xhci->port_array);
kfree(xhci->usb2_rhub.ports);
kfree(xhci->usb3_rhub.ports);
kfree(xhci->hw_ports);
kfree(xhci->rh_bw);
kfree(xhci->ext_caps);
 
-   xhci->usb2_ports = NULL;
-   xhci->usb3_ports = NULL;
-   xhci->port_array = NULL;
xhci->usb2_rhub.ports = NULL;
xhci->usb3_rhub.ports = NULL;
xhci->hw_ports = NULL;
@@ -2196,25 +2187,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
for (i = port_offset; i < (port_offset + port_count); i++) {
struct xhci_port *hw_port = >hw_ports[i];
/* Duplicate entry.  Ignore the port if the revisions differ. */
-   if (xhci->port_array[i] != 0 ||
-   hw_port->rhub) {
+   if (hw_port->rhub) {
xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
" port %u\n", addr, i);
xhci_warn(xhci, "Port was marked as USB %u, "
"duplicated as USB %u\n",
-   xhci->port_array[i], major_revision);
+   hw_port->rhub->maj_rev, major_revision);
/* Only adjust the roothub port counts if we haven't
 * found a similar duplicate.
 */
-   if (xhci->port_array[i] != major_revision &&
-   xhci->port_array[i] != DUPLICATE_ENTRY) {
-   if (xhci->port_array[i] == 0x03)
-   xhci->num_usb3_ports--;
-   else
-   xhci->num_usb2_ports--;
-   xhci->port_array[i] = DUPLICATE_ENTRY;
-   }
-   /* FIXME: Should we disable the port? */
if (hw_port->rhub != rhub &&
 hw_port->hcd_portnum != DUPLICATE_ENTRY) {
hw_port->rhub->num_ports--;
@@ -,13 +2203,8 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
}
continue;
}
-   xhci->port_array[i] = major_revision;
hw_port->rhub = rhub;
rhub->num_ports++;
-   if (major_revision == 0x03)
-   xhci->num_usb3_ports++;
-   else
-   xhci->num_usb2_ports++;
}
/* FIXME: Should we disable ports not in the Extended Capabilities? */
 }
@@ -2266,14 +2242,13 @@ static int xhci_setup_port_arrays(struct xhci_hcd 
*xhci, gfp_t flags)
void __iomem *base;
u32 offset;
unsigned int num_ports;
-   int i, j, port_index;
+   int i, j;
int cap_count = 0;
u32 cap_start;
 
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
-   xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
xhci->hw_ports = kcalloc(num_ports, sizeof(*xhci->hw_ports), flags);
-   if (!xhci->port_array)
+   if (!xhci->hw_ports)
return -ENOMEM;
 
for (i = 0; i < num_ports; i++) {
@@ -2317,41 +2292,34 @@ static int xhci_setup_port_arrays(struct xhci_hcd 
*xhci, gfp_t flags)
 
while (offset) {
xhci_add_in_port(xhci, num_ports, base + offset, cap_count);
-   if (xhci->num_usb2_ports + xhci->num_usb3_ports == num_ports)
-  

[PATCH 18/18] xhci: debugfs: add debugfs interface to enable compliance mode for a port

2018-05-21 Thread Mathias Nyman
Enable compliance transition for a port by writing "compliance" to the
ports portsc file in debugfs.
port must be "Not-connected" and Link must be in RxDetect state to enable
compliance mode.

Only needed for host that have CTC flag set.
Allows state transitioning to compliance at 1st LFPS timeout.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-debugfs.c | 39 ++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 76e446a..cadc013 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 
 #include "xhci.h"
 #include "xhci-debugfs.h"
@@ -351,8 +352,44 @@ static int xhci_port_open(struct inode *inode, struct file 
*file)
return single_open(file, xhci_portsc_show, inode->i_private);
 }
 
+static ssize_t xhci_port_write(struct file *file,  const char __user *ubuf,
+  size_t count, loff_t *ppos)
+{
+   struct seq_file *s = file->private_data;
+   struct xhci_port*port = s->private;
+   struct xhci_hcd *xhci = hcd_to_xhci(port->rhub->hcd);
+   charbuf[32];
+   u32 portsc;
+   unsigned long   flags;
+
+   if (copy_from_user(, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+   return -EFAULT;
+
+   if (!strncmp(buf, "compliance", 10)) {
+   /* If CTC is clear, compliance is enabled by default */
+   if (!HCC2_CTC(xhci->hcc_params2))
+   return count;
+   spin_lock_irqsave(>lock, flags);
+   /* compliance mode can only be enabled on ports in RxDetect */
+   portsc = readl(port->addr);
+   if ((portsc & PORT_PLS_MASK) != XDEV_RXDETECT) {
+   spin_unlock_irqrestore(>lock, flags);
+   return -EPERM;
+   }
+   portsc = xhci_port_state_to_neutral(portsc);
+   portsc &= ~PORT_PLS_MASK;
+   portsc |= PORT_LINK_STROBE | XDEV_COMP_MODE;
+   writel(portsc, port->addr);
+   spin_unlock_irqrestore(>lock, flags);
+   } else {
+   return -EINVAL;
+   }
+   return count;
+}
+
 static const struct file_operations port_fops = {
.open   = xhci_port_open,
+   .write  = xhci_port_write,
.read   = seq_read,
.llseek = seq_lseek,
.release= single_release,
@@ -491,7 +528,7 @@ static void xhci_debugfs_create_ports(struct xhci_hcd *xhci,
  num_ports + 1);
dir = debugfs_create_dir(port_name, parent);
port = >hw_ports[num_ports];
-   debugfs_create_file("portsc", 0444, dir, port, _fops);
+   debugfs_create_file("portsc", 0644, dir, port, _fops);
}
 }
 
-- 
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 08/18] xhci: xhci-hub: use new port structures for cas and wake mask functions.

2018-05-21 Thread Mathias Nyman
Use port structures instead of mmio port arrays for
xhci_port_missing_cas_quirk() and xhci_set_remote_wake_mask() in
xhci-hub.c

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0796f08..372b448 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -691,11 +691,11 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 
__iomem **port_array,
 }
 
 static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
-   __le32 __iomem **port_array, int port_id, u16 wake_mask)
+ struct xhci_port *port, u16 wake_mask)
 {
u32 temp;
 
-   temp = readl(port_array[port_id]);
+   temp = readl(port->addr);
temp = xhci_port_state_to_neutral(temp);
 
if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
@@ -713,7 +713,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
else
temp &= ~PORT_WKOC_E;
 
-   writel(temp, port_array[port_id]);
+   writel(temp, port->addr);
 }
 
 /* Test and clear port RWC bit */
@@ -1290,8 +1290,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
xhci_dbg(xhci, "set port reset, actual port %d status  
= 0x%x\n", wIndex, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
-   xhci_set_remote_wake_mask(xhci, port_array,
-   wIndex, wake_mask);
+   xhci_set_remote_wake_mask(xhci, ports[wIndex],
+ wake_mask);
temp = readl(ports[wIndex]->addr);
xhci_dbg(xhci, "set port remote wake mask, "
"actual port %d status  = 0x%x\n",
@@ -1568,12 +1568,11 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
  * warm reset a USB3 device stuck in polling or compliance mode after resume.
  * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
  */
-static bool xhci_port_missing_cas_quirk(int port_index,
-__le32 __iomem **port_array)
+static bool xhci_port_missing_cas_quirk(struct xhci_port *port)
 {
u32 portsc;
 
-   portsc = readl(port_array[port_index]);
+   portsc = readl(port->addr);
 
/* if any of these are set we are not stuck */
if (portsc & (PORT_CONNECT | PORT_CAS))
@@ -1586,9 +1585,9 @@ static bool xhci_port_missing_cas_quirk(int port_index,
/* clear wakeup/change bits, and do a warm port reset */
portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
portsc |= PORT_WR;
-   writel(portsc, port_array[port_index]);
+   writel(portsc, port->addr);
/* flush write */
-   readl(port_array[port_index]);
+   readl(port->addr);
return true;
 }
 
@@ -1638,7 +1637,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* warm reset CAS limited ports stuck in polling/compliance */
if ((xhci->quirks & XHCI_MISSING_CAS) &&
(hcd->speed >= HCD_USB3) &&
-   xhci_port_missing_cas_quirk(port_index, port_array)) {
+   xhci_port_missing_cas_quirk(ports[port_index])) {
xhci_dbg(xhci, "reset stuck port %d\n", port_index);
clear_bit(port_index, _state->bus_suspended);
continue;
-- 
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 06/18] xhci: Add helper to get xhci roothub from hcd

2018-05-21 Thread Mathias Nyman
quick way to get the xhci roothub and thus all the ports
belonging to a certain hcd

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-hub.c | 9 +
 drivers/usb/host/xhci.h | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 32cd52c..b6fd26f 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -554,6 +554,15 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 
__iomem ***port_array)
return max_ports;
 }
 
+struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd)
+{
+   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+   if (hcd->speed >= HCD_USB3)
+   return >usb3_rhub;
+   return >usb2_rhub;
+}
+
 static __le32 __iomem *xhci_get_port_io_addr(struct usb_hcd *hcd, int index)
 {
__le32 __iomem **port_array;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 38aa8a6..cdf8e1a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2110,6 +2110,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue, u16 wIndex,
char *buf, u16 wLength);
 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
 int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
+struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd);
+
 void xhci_hc_died(struct xhci_hcd *xhci);
 
 #ifdef CONFIG_PM
-- 
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 17/18] xhci: debugfs: add usb ports to xhci debugfs

2018-05-21 Thread Mathias Nyman
Add ports/portxx/portsc for each xHC hardware usb port to debugfs.
Showing the content of the port status and control register for
each port (PORTSC)

Portxx is numbered starting from 1 for historical reasons to better
match port numbering shown by lsusb and other places.

Ports in debugfs are in the order XHC controller has them,
In most cases USB2 ports come first, followed by USB3 ports.
i.e. USB2 ports are port01-portxx, and USB3 portxx-portmax.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-debugfs.c | 48 +
 1 file changed, 48 insertions(+)

diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 5851052..76e446a 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -333,6 +333,31 @@ static const struct file_operations xhci_context_fops = {
.release= single_release,
 };
 
+
+
+static int xhci_portsc_show(struct seq_file *s, void *unused)
+{
+   struct xhci_port*port = s->private;
+   u32 portsc;
+
+   portsc = readl(port->addr);
+   seq_printf(s, "%s\n", xhci_decode_portsc(portsc));
+
+   return 0;
+}
+
+static int xhci_port_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, xhci_portsc_show, inode->i_private);
+}
+
+static const struct file_operations port_fops = {
+   .open   = xhci_port_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
 static void xhci_debugfs_create_files(struct xhci_hcd *xhci,
  struct xhci_file_map *files,
  size_t nentries, void *data,
@@ -449,6 +474,27 @@ void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int 
slot_id)
dev->debugfs_private = NULL;
 }
 
+static void xhci_debugfs_create_ports(struct xhci_hcd *xhci,
+ struct dentry *parent)
+{
+   unsigned intnum_ports;
+   charport_name[8];
+   struct xhci_port*port;
+   struct dentry   *dir;
+
+   num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+
+   parent = debugfs_create_dir("ports", parent);
+
+   while (num_ports--) {
+   scnprintf(port_name, sizeof(port_name), "port%02d",
+ num_ports + 1);
+   dir = debugfs_create_dir(port_name, parent);
+   port = >hw_ports[num_ports];
+   debugfs_create_file("portsc", 0444, dir, port, _fops);
+   }
+}
+
 void xhci_debugfs_init(struct xhci_hcd *xhci)
 {
struct device   *dev = xhci_to_hcd(xhci)->self.controller;
@@ -497,6 +543,8 @@ void xhci_debugfs_init(struct xhci_hcd *xhci)
 xhci->debugfs_root);
 
xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root);
+
+   xhci_debugfs_create_ports(xhci, xhci->debugfs_root);
 }
 
 void xhci_debugfs_exit(struct xhci_hcd *xhci)
-- 
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 15/18] xhci-mtk: use xhci hub structures to get number of ports in roothubs

2018-05-21 Thread Mathias Nyman
Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-mtk-sch.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index eea7360..fa33d6e 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -58,7 +58,7 @@ static int get_bw_index(struct xhci_hcd *xhci, struct 
usb_device *udev,
bw_index = (virt_dev->real_port - 1) * 2 + 1;
} else {
/* add one more for each SS port */
-   bw_index = virt_dev->real_port + xhci->num_usb3_ports - 1;
+   bw_index = virt_dev->real_port + xhci->usb3_rhub.num_ports - 1;
}
 
return bw_index;
@@ -284,7 +284,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
int i;
 
/* ss IN and OUT are separated */
-   num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
+   num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
 
sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
if (sch_array == NULL)
-- 
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 04/18] xhci: Create new structures to store xhci port information

2018-05-21 Thread Mathias Nyman
Current way of having one array telling only the port speed,
and then two separate arrays with mmio addresses for usb2 and usb3 ports
requeres helper functions to transate  hw to hcd, and hcd to hw port
numbers, and is hard to expand.

Instead create a structure describing a port, including the mmio address,
the port hardware index, hcd port index, and a pointer to the roothub
it belongs to.

Create one array containing all port structures in the same order the
hardware controller sees them. Then add an array of port pointers to
each xhci hub structure pointing to the ports that belonging to the
roothub.

This way we can easily convert hw indexed port events to usb core
hcd port numbers, and vice versa usb core hub hcd port numbers
to hw index and mmio address.

Other benefit is that we can easily find the parent hcd and xhci
structure of a port structure. This is useful in debugfs where
we can give one port structure pointer as parameter and get both
the correct mmio address and xhci lock needed to set some port
parameter.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-mem.c | 58 -
 drivers/usb/host/xhci.h | 21 
 2 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index e5ace89..8819286 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1892,16 +1892,24 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->cmd_ring_reserved_trbs = 0;
xhci->num_usb2_ports = 0;
xhci->num_usb3_ports = 0;
+   xhci->usb2_rhub.num_ports = 0;
+   xhci->usb3_rhub.num_ports = 0;
xhci->num_active_eps = 0;
kfree(xhci->usb2_ports);
kfree(xhci->usb3_ports);
kfree(xhci->port_array);
+   kfree(xhci->usb2_rhub.ports);
+   kfree(xhci->usb3_rhub.ports);
+   kfree(xhci->hw_ports);
kfree(xhci->rh_bw);
kfree(xhci->ext_caps);
 
xhci->usb2_ports = NULL;
xhci->usb3_ports = NULL;
xhci->port_array = NULL;
+   xhci->usb2_rhub.ports = NULL;
+   xhci->usb3_rhub.ports = NULL;
+   xhci->hw_ports = NULL;
xhci->rh_bw = NULL;
xhci->ext_caps = NULL;
 
@@ -2186,8 +2194,10 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
 
port_offset--;
for (i = port_offset; i < (port_offset + port_count); i++) {
+   struct xhci_port *hw_port = >hw_ports[i];
/* Duplicate entry.  Ignore the port if the revisions differ. */
-   if (xhci->port_array[i] != 0) {
+   if (xhci->port_array[i] != 0 ||
+   hw_port->rhub) {
xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
" port %u\n", addr, i);
xhci_warn(xhci, "Port was marked as USB %u, "
@@ -2205,9 +2215,16 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
xhci->port_array[i] = DUPLICATE_ENTRY;
}
/* FIXME: Should we disable the port? */
+   if (hw_port->rhub != rhub &&
+hw_port->hcd_portnum != DUPLICATE_ENTRY) {
+   hw_port->rhub->num_ports--;
+   hw_port->hcd_portnum = DUPLICATE_ENTRY;
+   }
continue;
}
xhci->port_array[i] = major_revision;
+   hw_port->rhub = rhub;
+   rhub->num_ports++;
if (major_revision == 0x03)
xhci->num_usb3_ports++;
else
@@ -2216,6 +2233,27 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, 
unsigned int num_ports,
/* FIXME: Should we disable ports not in the Extended Capabilities? */
 }
 
+static void xhci_create_rhub_port_array(struct xhci_hcd *xhci,
+   struct xhci_hub *rhub, gfp_t flags)
+{
+   int port_index = 0;
+   int i;
+
+   if (!rhub->num_ports)
+   return;
+   rhub->ports = kcalloc(rhub->num_ports, sizeof(rhub->ports), flags);
+   for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
+   if (xhci->hw_ports[i].rhub != rhub ||
+   xhci->hw_ports[i].hcd_portnum == DUPLICATE_ENTRY)
+   continue;
+   xhci->hw_ports[i].hcd_portnum = port_index;
+   rhub->ports[port_index] = >hw_ports[i];
+   port_index++;
+   if (port_index == rhub->num_ports)
+   break;
+   }
+}
+
 /*
  * Scan the Extended Capabilities for the "Supported Protocol Capabilities" 
that
  * specify what speeds each port is supposed to be.  We can't count on the port
@@ -2234,9 +2272,16 @@ static int 

[PATCH 03/18] xhci: hisilicon: support HiSilicon STB xHCI host controller

2018-05-21 Thread Mathias Nyman
From: Jianguo Sun 

This commit adds support for HiSilicon STB xHCI host controller.
There are two xHCI host controllers on HiSilicon STB SoCs. Each
one requires additional configuration before exposing interface
compliant with xHCI.

Reviewed-by: Chunfeng Yun 
Signed-off-by: Jianguo Sun 
Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/Kconfig  |   7 +
 drivers/usb/host/Makefile |   1 +
 drivers/usb/host/xhci-histb.c | 410 ++
 3 files changed, 418 insertions(+)
 create mode 100644 drivers/usb/host/xhci-histb.c

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5d958da..c813fc4 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -52,6 +52,13 @@ config USB_XHCI_PLATFORM
 
  If unsure, say N.
 
+config USB_XHCI_HISTB
+   tristate "xHCI support for HiSilicon STB SoCs"
+   depends on USB_XHCI_PLATFORM && (ARCH_HISI || COMPILE_TEST)
+   help
+ Say 'Y' to enable the support for the xHCI host controller
+ found in HiSilicon STB SoCs.
+
 config USB_XHCI_MTK
tristate "xHCI support for MediaTek SoCs"
select MFD_SYSCON
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 8a8cffe..9b669c9 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_USB_FHCI_HCD)+= fhci.o
 obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
 obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
 obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
+obj-$(CONFIG_USB_XHCI_HISTB)   += xhci-histb.o
 obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
 obj-$(CONFIG_USB_XHCI_TEGRA)   += xhci-tegra.o
 obj-$(CONFIG_USB_SL811_HCD)+= sl811-hcd.o
diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c
new file mode 100644
index 000..27f0016
--- /dev/null
+++ b/drivers/usb/host/xhci-histb.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * xHCI host controller driver for HiSilicon STB SoCs
+ *
+ * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
+ *
+ * Authors: Jianguo Sun 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xhci.h"
+
+#define GTXTHRCFG  0xc108
+#define GRXTHRCFG  0xc10c
+#define REG_GUSB2PHYCFG0   0xc200
+#define BIT_UTMI_8_16  BIT(3)
+#define BIT_UTMI_ULPI  BIT(4)
+#define BIT_FREECLK_EXIST  BIT(30)
+
+#define REG_GUSB3PIPECTL0  0xc2c0
+#define USB3_DEEMPHASIS_MASK   GENMASK(2, 1)
+#define USB3_DEEMPHASIS0   BIT(1)
+#define USB3_TX_MARGIN1BIT(4)
+
+struct xhci_hcd_histb {
+   struct device   *dev;
+   struct usb_hcd  *hcd;
+   void __iomem*ctrl;
+   struct clk  *bus_clk;
+   struct clk  *utmi_clk;
+   struct clk  *pipe_clk;
+   struct clk  *suspend_clk;
+   struct reset_control*soft_reset;
+};
+
+static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
+{
+   return dev_get_drvdata(hcd->self.controller);
+}
+
+static int xhci_histb_config(struct xhci_hcd_histb *histb)
+{
+   struct device_node *np = histb->dev->of_node;
+   u32 regval;
+
+   if (of_property_match_string(np, "phys-names", "inno") >= 0) {
+   /* USB2 PHY chose ulpi 8bit interface */
+   regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
+   regval &= ~BIT_UTMI_ULPI;
+   regval &= ~(BIT_UTMI_8_16);
+   regval &= ~BIT_FREECLK_EXIST;
+   writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
+   }
+
+   if (of_property_match_string(np, "phys-names", "combo") >= 0) {
+   /*
+* write 0x010c0012 to GUSB3PIPECTL0
+* GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
+* decrease TX voltage
+* GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
+* refer to xHCI spec
+*/
+   regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
+   regval &= ~USB3_DEEMPHASIS_MASK;
+   regval |= USB3_DEEMPHASIS0;
+   regval |= USB3_TX_MARGIN1;
+   writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
+   }
+
+   writel(0x2310, histb->ctrl + GTXTHRCFG);
+   writel(0x2310, histb->ctrl + GRXTHRCFG);
+
+   return 0;
+}
+
+static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
+{
+   struct device *dev = histb->dev;
+
+   histb->bus_clk = devm_clk_get(dev, "bus");
+   if (IS_ERR(histb->bus_clk)) {
+   dev_err(dev, "fail to get bus clk\n");
+   return PTR_ERR(histb->bus_clk);
+   }
+
+   histb->utmi_clk = devm_clk_get(dev, "utmi");
+   if (IS_ERR(histb->utmi_clk)) {
+   

[PATCH 00/18] xhci features for usb-next

2018-05-21 Thread Mathias Nyman
Hi Greg

This series adds support for HiSilicon STB xHCI,
reworks the xhci driver port structures, and adds ports
to debugfs

-Mathias

Jianguo Sun (2):
  dt-bindings: usb: add bindings doc for HiSilicon STB xHCI host
controller
  xhci: hisilicon: support HiSilicon STB xHCI host controller

Lu Baolu (1):
  usb: xhci: dbc: Add SPDX identifiers to dbc files

Mathias Nyman (15):
  xhci: Create new structures to store xhci port information
  xhci: set hcd pointers for xhci usb2 and usb3 roothub structures
  xhci: Add helper to get xhci roothub from hcd
  xhci: xhci-hub: use new port structures to get port address instead of
port array
  xhci: xhci-hub: use new port structures for cas and wake mask
functions.
  xhci: xhci-ring: use port structures for port event handler
  xhci: rename faked_port_index to hcd_portnum
  xhci: change xhci_set_link_state() to work with port structures
  xhci: change xhci_test_and_clear_bit() to use new port structure
  xhci: use port structures instead of port arrays in xhci.c functions
  xhci: xhci-hub: use port structure members instead of xhci_get_ports()
  xhci-mtk: use xhci hub structures to get number of ports in roothubs
  xhci: xhci-mem: remove port_arrays and the code initializing them
  xhci: debugfs: add usb ports to xhci debugfs
  xhci: debugfs: add debugfs interface to enable compliance mode for a
port

 .../bindings/usb/hisilicon,histb-xhci.txt  |  45 +++
 drivers/usb/host/Kconfig   |   7 +
 drivers/usb/host/Makefile  |   1 +
 drivers/usb/host/xhci-dbgcap.c |   1 +
 drivers/usb/host/xhci-dbgcap.h |   2 +-
 drivers/usb/host/xhci-dbgtty.c |   1 +
 drivers/usb/host/xhci-debugfs.c|  85 +
 drivers/usb/host/xhci-histb.c  | 410 +
 drivers/usb/host/xhci-hub.c| 244 ++--
 drivers/usb/host/xhci-mem.c| 140 +++
 drivers/usb/host/xhci-mtk-sch.c|   4 +-
 drivers/usb/host/xhci-ring.c   | 126 ++-
 drivers/usb/host/xhci.c|  52 ++-
 drivers/usb/host/xhci.h|  39 +-
 14 files changed, 805 insertions(+), 352 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/usb/hisilicon,histb-xhci.txt
 create mode 100644 drivers/usb/host/xhci-histb.c

-- 
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 05/18] xhci: set hcd pointers for xhci usb2 and usb3 roothub structures

2018-05-21 Thread Mathias Nyman
Allows us to know the correct hcd a xhci roothub and its ports
belong to.

Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 711da33..f614ba1 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4858,6 +4858,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t 
get_quirks)
 
if (usb_hcd_is_primary_hcd(hcd)) {
xhci->main_hcd = hcd;
+   xhci->usb2_rhub.hcd = hcd;
/* Mark the first roothub as being USB 2.0.
 * The xHCI driver will register the USB 3.0 roothub.
 */
@@ -4883,6 +4884,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t 
get_quirks)
  minor_rev,
  minor_rev ? "Enhanced" : "");
 
+   xhci->usb3_rhub.hcd = hcd;
/* xHCI private pointer was set in xhci_pci_probe for the second
 * registered roothub.
 */
-- 
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 02/18] dt-bindings: usb: add bindings doc for HiSilicon STB xHCI host controller

2018-05-21 Thread Mathias Nyman
From: Jianguo Sun 

This commit adds bindings doc for HiSilicon STB xHCI host controller.

Signed-off-by: Jianguo Sun 
Signed-off-by: Mathias Nyman 
---
 .../bindings/usb/hisilicon,histb-xhci.txt  | 45 ++
 1 file changed, 45 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/hisilicon,histb-xhci.txt

diff --git a/Documentation/devicetree/bindings/usb/hisilicon,histb-xhci.txt 
b/Documentation/devicetree/bindings/usb/hisilicon,histb-xhci.txt
new file mode 100644
index 000..f463349
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/hisilicon,histb-xhci.txt
@@ -0,0 +1,45 @@
+HiSilicon STB xHCI
+
+The device node for HiSilicon STB xHCI host controller
+
+Required properties:
+ - compatible: should be "hisilicon,hi3798cv200-xhci"
+ - reg: specifies physical base address and size of the registers
+ - interrupts : interrupt used by the controller
+ - clocks: a list of phandle + clock-specifier pairs, one for each
+   entry in clock-names
+ - clock-names: must contain
+   "bus": for bus clock
+   "utmi": for utmi clock
+   "pipe": for pipe clock
+   "suspend": for suspend clock
+ - resets: a list of phandle and reset specifier pairs as listed in
+   reset-names property.
+ - reset-names: must contain
+   "soft": for soft reset
+ - phys: a list of phandle + phy specifier pairs
+ - phy-names: must contain at least one of following:
+   "inno": for inno phy
+   "combo": for combo phy
+
+Optional properties:
+  - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
+  - usb3-lpm-capable: determines if platform is USB3 LPM capable
+  - imod-interval-ns: default interrupt moderation interval is 4ns
+
+Example:
+
+xhci0: xchi@f98a {
+   compatible = "hisilicon,hi3798cv200-xhci";
+   reg = <0xf98a 0x1>;
+   interrupts = ;
+   clocks = < HISTB_USB3_BUS_CLK>,
+< HISTB_USB3_UTMI_CLK>,
+< HISTB_USB3_PIPE_CLK>,
+< HISTB_USB3_SUSPEND_CLK>;
+   clock-names = "bus", "utmi", "pipe", "suspend";
+   resets = < 0xb0 12>;
+   reset-names = "soft";
+   phys = <_phy1_port1 0>, < PHY_TYPE_USB3>;
+   phy-names = "inno", "combo";
+};
-- 
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 01/18] usb: xhci: dbc: Add SPDX identifiers to dbc files

2018-05-21 Thread Mathias Nyman
From: Lu Baolu 

Update the xhci dbc files with the correct SPDX license identifiers.

Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver")
Cc: Philippe Ombredanne 
Signed-off-by: Lu Baolu 
Reviewed-by: Philippe Ombredanne 
Signed-off-by: Mathias Nyman 
---
 drivers/usb/host/xhci-dbgcap.c | 1 +
 drivers/usb/host/xhci-dbgcap.h | 2 +-
 drivers/usb/host/xhci-dbgtty.c | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index c359bae..1fbfd89 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * xhci-dbgcap.c - xHCI debug capability support
  *
diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h
index e66ea07..ce0c607 100644
--- a/drivers/usb/host/xhci-dbgcap.h
+++ b/drivers/usb/host/xhci-dbgcap.h
@@ -1,4 +1,4 @@
-
+/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * xhci-dbgcap.h - xHCI debug capability support
  *
diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c
index eb494ec5..aff79ff 100644
--- a/drivers/usb/host/xhci-dbgtty.c
+++ b/drivers/usb/host/xhci-dbgtty.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * xhci-dbgtty.c - tty glue for xHCI debug capability
  *
-- 
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


Re: [PATCH] typec: tcpm: Provide of_node pointer as part of psy_cfg

2018-05-21 Thread Heikki Krogerus
Hi Adam,

On Wed, May 16, 2018 at 05:00:46PM +0100, Adam Thomson wrote:
> For supply registration, provide of_node pointer of the port device,
> via the power_supply_config structure, to allow other psy drivers
> to add us as a supplier using the 'power-supplies' DT property.
> 
> Signed-off-by: Adam Thomson 
> ---
>  drivers/usb/typec/tcpm.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index 72996cc..e7c0b95 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -4500,6 +4500,7 @@ static int devm_tcpm_psy_register(struct tcpm_port 
> *port)
>   char *psy_name;
>  
>   psy_cfg.drv_data = port;
> + psy_cfg.of_node = port->dev->of_node;
>   psy_name = devm_kzalloc(port->dev, psy_name_len, GFP_KERNEL);
>   if (!psy_name)
>   return -ENOMEM;

Would it be possible to use fwnode here instead? It would mean that
you add a member for it to the struct power_supply_config, and handle
it separately in power_supply_core.c. You could just convert it to
of_node there for now.

That is just a request, I'm fine with this, but it would prepare this
driver for all types of platforms, so less patching would be needed
once we add ACPI support to the power_supply_core.c.


Thanks,

-- 
heikki
--
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 v5 05/14] usb: typec: add API to get typec basic port power and data config

2018-05-21 Thread Heikki Krogerus
Hi Jun,

Sorry for the delay.

On Thu, May 17, 2018 at 02:41:31PM +, Jun Li wrote:
> Hi
> > -Original Message-
> > From: Heikki Krogerus [mailto:heikki.kroge...@linux.intel.com]
> > Sent: 2018??5??17?? 22:24
> > To: Jun Li 
> > Cc: Mats Karrman ; robh...@kernel.org;
> > gre...@linuxfoundation.org; li...@roeck-us.net; a.ha...@samsung.com;
> > cw00.c...@samsung.com; shufan_...@richtek.com; Peter Chen
> > ; gso...@gmail.com; devicet...@vger.kernel.org;
> > linux-usb@vger.kernel.org; dl-linux-imx 
> > Subject: Re: [PATCH v5 05/14] usb: typec: add API to get typec basic port 
> > power
> > and data config
> > 
> > On Thu, May 17, 2018 at 02:05:41PM +, Jun Li wrote:
> > > Hi Heikki,
> > >
> > > > > I reread this patch and tried to see it more in the context of the
> > > > > other patches and the existing code. The naming of the existing
> > > > > string tables doesn't help in getting this right, however I have a 
> > > > > proposal:
> > > > >
> > > > > typec_find_port_power_role() to get to TYPEC_PORT_SRC/SNK/DRP
> > > > > typec_find_port_data_role() to get to TYPEC_PORT_DFP/UFP/DRD
> > > > > typec_find_power_role() to get to TYPEC_SINK/SOURCE
> > > > >
> > > > > and sometime, if the use should arise
> > > > >
> > > > > typec_find_data_role() to get to TYPEC_DEVICE/HOST
> > > > >
> > > > > I think it is fairly comprehensible, *_port_* concerns a
> > > > > capability and without *_port_* it is an actual state. Plus it
> > > > > matches the names of the constants.
> > > >
> > > > Well, there are now four things to consider:
> > > >
> > > > 1) the roles (power and data) the port is capable of supporting
> > > > 2) Try.SRC and Try.SNK, i.e. the preferred role
> > > > 3) the current roles
> > > > 4) the role(s) the user want's to limit the use of a port with DRP
> > > > ports
> > > >
> > > > The last one I don't know if it's relevant with these functions.
> > > > It's not information that we would get for example from firmware.
> > > >
> > > > I also don't think we need to use these functions with the current
> > > > roles the port is in.
> > > >
> > > > If the preferred role is "sink" or "source", so just like the power
> > > > role, we don't need separate function for it here.
> > > >
> > > > So isn't two functions all we need here: one for the power and one
> > > > for data role?
> > >
> > > Take power as an example, can we use one function to only look up
> > > typec_port_types[]? as capability(typec_port_type) and
> > > state(typec_role) are different enum, and the allowed strings are 
> > > different.
> > >
> > > static const char * const typec_roles[] = {
> > >   [TYPEC_SINK]= "sink",
> > >   [TYPEC_SOURCE]  = "source",
> > > };
> > >
> > > static const char * const typec_port_types[] = {
> > >   [TYPEC_PORT_SRC] = "source",
> > >   [TYPEC_PORT_SNK] = "sink",
> > >   [TYPEC_PORT_DRP] = "dual",
> > > };
> > 
> > Where out side the class code we need to convert the current role, the 
> > "state",
> > with these functions?
> 
> Currently, the only call site is getting the preferred power role from 
> firmware.

My point was that if we used enum typec_port_type with the prefered
role, we could use the helper for power role with prefered role. But
never mind.


Thanks,

-- 
heikki
--
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: [RFC PATCH 1/7] usb: typec: Generalize mux mode names

2018-05-21 Thread Heikki Krogerus
On Fri, May 18, 2018 at 07:26:40AM +0200, Mats Karrman wrote:
> On 2018-05-17 13:50, Heikki Krogerus wrote:
> 
> > On Wed, May 16, 2018 at 11:11:02PM +0200, Mats Karrman wrote:
> > > On 05/16/2018 01:43 PM, Heikki Krogerus wrote:
> > > 
> > > > On Tue, May 15, 2018 at 11:24:07PM +0200, Mats Karrman wrote:
> > > > > Hi Heikki,
> > > > > 
> > > > > On 05/15/2018 09:30 AM, Heikki Krogerus wrote:
> > > > > 
> > > > > > Hi Mats,
> > > > > > 
> > > > > > On Fri, May 11, 2018 at 09:28:04PM +0200, Mats Karrman wrote:
> > > > > > > On 2018-05-11 13:14, Heikki Krogerus wrote:
> > > > > > > 
> > > > > > > > On Fri, May 11, 2018 at 11:05:55AM +0200, Mats Karrman wrote:
> > > > > > > > > On 2018-05-10 19:49, Heikki Krogerus wrote:
> > > > > > > > > 
> > > > > > > > > > On Thu, May 10, 2018 at 10:04:21AM +0200, Mats Karrman 
> > > > > > > > > > wrote:
> > > > > > > > > > > Hi,
> > > > > > > > > > > 
> > > > > > > > > > > On 05/09/2018 02:49 PM, Heikki Krogerus wrote:
> > > > > > > > > > > 
> > > > > > > > > > > > On Tue, May 08, 2018 at 09:10:13PM +0200, Mats Karrman 
> > > > > > > > > > > > wrote:
> > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > 
> > > > > > > > > > > > > On 05/08/2018 04:25 PM, Heikki Krogerus wrote:
> > > > > > > > > > > > > 
> > > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > On Mon, May 07, 2018 at 11:19:40PM +0200, Mats 
> > > > > > > > > > > > > > Karrman wrote:
> > > > > > > > > > > > > > > > > Even so, when the mux driver "set" function 
> > > > > > > > > > > > > > > > > is called, it will just get the
> > > > > > > > > > > > > > > > > mode argument but since the mode 
> > > > > > > > > > > > > > > > > (TYPEC_STATE_...) is overlapping for different
> > > > > > > > > > > > > > > > > AMs if I understand your proposal correctly, 
> > > > > > > > > > > > > > > > > the mux also needs to know what AM
> > > > > > > > > > > > > > > > > is active.
> > > > > > > > > > > > > > > > > Does this imply that the mux set function 
> > > > > > > > > > > > > > > > > signature need to change?
> > > > > > > > > > > > > > > > My plan was actually to propose we get rid of 
> > > > > > > > > > > > > > > > the current mux handling
> > > > > > > > > > > > > > > > (just leave the orientation switch) in favour 
> > > > > > > > > > > > > > > > of the notifications I'm
> > > > > > > > > > > > > > > > introducing with the type-c bus for the 
> > > > > > > > > > > > > > > > alternate modes. The current
> > > > > > > > > > > > > > > > mux handling is definitely not enough, and does 
> > > > > > > > > > > > > > > > not work in every
> > > > > > > > > > > > > > > > scenario, like also you pointed out.
> > > > > > > > > > > > > > > So, the mux need to subscribe to each svid:mode 
> > > > > > > > > > > > > > > pair it is interested in using
> > > > > > > > > > > > > > > typec_altmode_register_notifier() and then use 
> > > > > > > > > > > > > > > those callbacks to switch the correct
> > > > > > > > > > > > > > > signals to the connector. And a driver for an 
> > > > > > > > > > > > > > > off-the-shelf mux device could have
> > > > > > > > > > > > > > > the translation between svid:mode pairs and mux 
> > > > > > > > > > > > > > > device specific control specified by
> > > > > > > > > > > > > > > of/acpi properties. Right?
> > > > > > > > > > > > > > Yes. That is the plan. Would it work for you?
> > > > > > > > > > > > > I think so. I'll give it a go. When about do you 
> > > > > > > > > > > > > think you'll post the next version
> > > > > > > > > > > > > of your RFC? Or do you have an updated series 
> > > > > > > > > > > > > available somewhere public?
> > > > > > > > > > > > I'll try to put together and post the next version 
> > > > > > > > > > > > tomorrow.
> > > > > > > > > > > > 
> > > > > > > > > > > > My original plan was actually to use just the 
> > > > > > > > > > > > notifications with the
> > > > > > > > > > > > muxes, but one thing to consider with the notifications 
> > > > > > > > > > > > is that in
> > > > > > > > > > > > practice we have to increment the ref count for the alt 
> > > > > > > > > > > > mode devices
> > > > > > > > > > > > when ever something registers a notifier.
> > > > > > > > > > > > 
> > > > > > > > > > > > To me that does not feel ideal. The dependency should 
> > > > > > > > > > > > go the other way
> > > > > > > > > > > > around in case of the muxes. That is why I liked the 
> > > > > > > > > > > > separate API and
> > > > > > > > > > > > handling for the muxes felt better, as it will do just 
> > > > > > > > > > > > that. The mux
> > > > > > > > > > > > is then a "service" that the port driver can as for, 
> > > > > > > > > > > > and if it gets a
> > > > > > > > > > > > handle to a mux, the mux will have its ref count 
> > > > > > > > > > > > incremented.
> > > > > > > > > > > > 
> > > > > > > > > > > > So I think fixing the mux API would perhaps be better 
> > > > > > > > > > > > after all.
> > > > > > > > > > > > Thoughts?
> > > > > > > > > > 

Re: [PATCH] usb: xhci: force all memory allocations to node

2018-05-21 Thread Adam Wallis
On 5/16/2018 2:02 AM, Greg Kroah-Hartman wrote:
> On Tue, May 15, 2018 at 04:51:53PM -0400, Adam Wallis wrote:
> 
> Ok, fair enough, I was hoping that "modern" systems would have better
> NUMA memory interconnects.  I guess that isn't the case still :(

Things will keep improving, I'm sure.

Mathias, did you have anything you need reworked with this patch or any specific
comments on the overall patch?

Thanks!


-- 
Adam Wallis
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, 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: [PATCH v2] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Felipe Balbi

Hi Greg,

Yoshihiro Shimoda  writes:
> When printer_write() calls usb_ep_queue(), a udc driver (e.g.
> renesas_usbhs driver) may call usb_gadget_giveback_request() in
> the udc .queue ops immediately. Then, printer_write() calls
> list_add(>list, >tx_reqs_active) wrongly. After that,
> if we do unbind the printer driver, WARN_ON() happens in
> printer_func_unbind() because the list entry is not removed.
>
> So, this patch moves list_add(>list, >tx_reqs_active)
> calling before usb_ep_queue().
>
> Signed-off-by: Yoshihiro Shimoda 
> Acked-by: Felipe Balbi 

I'm not sure if you're still taking bug fixes for current -rc cycle, but
if you are, please take this directly. If you're done with v4.17, please
apply this on top of my pull request which I sent an hour or so ago.

Thanks

-- 
balbi


signature.asc
Description: PGP signature


[PATCH] usb: typec: Fix htmldocs warning

2018-05-21 Thread Heikki Krogerus
Fix htmldocs warning:

drivers/usb/typec/mux.c:186: warning: Function parameter or member 'mux' not 
described in
'typec_mux_unregister'

Reported-by: kbuild test robot 
Fixes: bdecb33af34f ("usb: typec: API for controlling USB Type-C Multiplexers")
Signed-off-by: Heikki Krogerus 
---
 drivers/usb/typec/mux.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 7446d6d1e424..ddaac63ecf12 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -178,7 +178,7 @@ EXPORT_SYMBOL_GPL(typec_mux_register);
 
 /**
  * typec_mux_unregister - Unregister Multiplexer Switch
- * @sw: USB Type-C Connector Multiplexer/DeMultiplexer
+ * @mux: USB Type-C Connector Multiplexer/DeMultiplexer
  *
  * Unregister mux that was registered with typec_mux_register().
  */
-- 
2.17.0

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


[PATCH 01/33] usb: phy: use match_string() helper

2018-05-21 Thread Yisheng Xie
match_string() returns the index of an array for a matching string,
which can be used intead of open coded variant.

Cc: linux-usb@vger.kernel.org
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
Signed-off-by: Yisheng Xie 
---
 drivers/usb/phy/of.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/phy/of.c b/drivers/usb/phy/of.c
index 1ab134f..5777c9f 100644
--- a/drivers/usb/phy/of.c
+++ b/drivers/usb/phy/of.c
@@ -28,16 +28,14 @@
 enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np)
 {
const char *phy_type;
-   int err, i;
+   int ret;
 
-   err = of_property_read_string(np, "phy_type", _type);
-   if (err < 0)
+   ret = of_property_read_string(np, "phy_type", _type);
+   if (ret < 0)
return USBPHY_INTERFACE_MODE_UNKNOWN;
 
-   for (i = 0; i < ARRAY_SIZE(usbphy_modes); i++)
-   if (!strcmp(phy_type, usbphy_modes[i]))
-   return i;
+   ret = match_string(usbphy_modes, ARRAY_SIZE(usbphy_modes), phy_type);
 
-   return USBPHY_INTERFACE_MODE_UNKNOWN;
+   return (ret < 0) ? USBPHY_INTERFACE_MODE_UNKNOWN : ret;
 }
 EXPORT_SYMBOL_GPL(of_usb_get_phy_mode);
-- 
1.7.12.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 v1 3/4] usb: dwc2: replace ioread32/iowrite32_rep with dwc2_readl/writel_rep

2018-05-21 Thread Gevorg Sahakyan
dwc2_readl_rep/dwc2_writel_rep functions using readl/writel in a
loop.

Signed-off-by: Gevorg Sahakyan 
---
 drivers/usb/dwc2/core.h   | 61 ++-
 drivers/usb/dwc2/gadget.c |  6 ++---
 2 files changed, 26 insertions(+), 41 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index c24cf9b6140d..a32ff26386c2 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1040,60 +1040,45 @@ struct dwc2_hsotg {
 #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
 };
 
-#ifdef CONFIG_MIPS
-/*
- * There are some MIPS machines that can run in either big-endian
- * or little-endian mode and that use the dwc2 register without
- * a byteswap in both ways.
- * Unlike other architectures, MIPS apparently does not require a
- * barrier before the __raw_writel() to synchronize with DMA but does
- * require the barrier after the __raw_writel() to serialize a set of
- * writes. This set of operations was added specifically for MIPS and
- * should only be used there.
- */
+/* Normal architectures just use readl/write */
 static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset)
 {
-   u32 value = __raw_readl(hsotg->regs + offset);
-
-   /* In order to preserve endianness __raw_* operation is used. Therefore
-* a barrier is needed to ensure IO access is not re-ordered across
-* reads or writes
-*/
-   mb();
-   return value;
+   return readl(hsotg->regs + offset);
 }
 
 static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset)
 {
-   __raw_writel(value, hsotg->regs + offset);
-
-   /*
-* In order to preserve endianness __raw_* operation is used. Therefore
-* a barrier is needed to ensure IO access is not re-ordered across
-* reads or writes
-*/
-   mb();
+   writel(value, hsotg->regs + offset);
+
 #ifdef DWC2_LOG_WRITES
-   pr_info("INFO:: wrote %08x to %p\n", value, hsotg->regs + offset);
+   pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset);
 #endif
 }
-#else
 
-/* Normal architectures just use readl/write */
-static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset)
+static inline void dwc2_readl_rep(struct dwc2_hsotg *hsotg, u32 offset,
+ void *buffer, unsigned int count)
 {
-   return readl(hsotg->regs + offset);
+   if (count) {
+   u32 *buf = buffer;
+
+   do {
+   u32 x = dwc2_readl(hsotg, offset);
+   *buf++ = x;
+   } while (--count);
+   }
 }
 
-static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset)
+static inline void dwc2_writel_rep(struct dwc2_hsotg *hsotg, u32 offset,
+  const void *buffer, unsigned int count)
 {
-   writel(value, hsotg->regs + offset);
+   if (count) {
+   const u32 *buf = buffer;
 
-#ifdef DWC2_LOG_WRITES
-   pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset);
-#endif
+   do {
+   dwc2_writel(hsotg, *buf++, offset);
+   } while (--count);
+   }
 }
-#endif
 
 /* Reasons for halting a host channel */
 enum dwc2_halt_status {
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 3cde8a01baa6..651db5cfc644 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -593,7 +593,7 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
to_write = DIV_ROUND_UP(to_write, 4);
data = hs_req->req.buf + buf_pos;
 
-   iowrite32_rep(hsotg->regs + EPFIFO(hs_ep->index), data, to_write);
+   dwc2_writel_rep(hsotg, EPFIFO(hs_ep->index), data, to_write);
 
return (to_write >= can_write) ? -ENOSPC : 0;
 }
@@ -2174,8 +2174,8 @@ static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, 
int ep_idx, int size)
 * note, we might over-write the buffer end by 3 bytes depending on
 * alignment of the data.
 */
-   ioread32_rep(hsotg->regs + EPFIFO(ep_idx),
-hs_req->req.buf + read_ptr, to_read);
+   dwc2_readl_rep(hsotg, EPFIFO(ep_idx),
+  hs_req->req.buf + read_ptr, to_read);
 }
 
 /**
-- 
2.11.0

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


[PATCH v1 4/4] usb: dwc2: Make dwc2_readl/writel functions endianness-agnostic.

2018-05-21 Thread Gevorg Sahakyan
Declared dwc2_check_core_endianness() function for dynamicly check
core endianness.
Added needs_byte_swap flag to hsotg structure, and depending on
flag swap value inside dwc2_readl/writel functions.

Signed-off-by: Gevorg Sahakyan 
---
 drivers/usb/dwc2/core.h | 22 --
 drivers/usb/dwc2/platform.c | 19 +++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index a32ff26386c2..7e5690e27cdd 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -96,6 +96,13 @@ static const char * const dwc2_hsotg_supply_names[] = {
  */
 #define EP0_MPS_LIMIT   64
 
+#define swap32(x) (\
+   {typeof(x) x_ = (x); \
+   (((u32)(x_) << 24) & (u32)0xFF00) | \
+   (((u32)(x_) <<  8) & (u32)0x00FF) | \
+   (((u32)(x_) >>  8) & (u32)0xFF00) | \
+   (((u32)(x_) >> 24) & (u32)0x00FF); })
+
 struct dwc2_hsotg;
 struct dwc2_hsotg_req;
 
@@ -781,6 +788,7 @@ struct dwc2_hregs_backup {
  * @gregs_backup: Backup of global registers during suspend
  * @dregs_backup: Backup of device registers during suspend
  * @hregs_backup: Backup of host registers during suspend
+ * @needs_byte_swap:   Specifies whether the opposite endianness.
  *
  * These are for host mode:
  *
@@ -928,6 +936,7 @@ struct dwc2_hsotg {
 
struct dentry *debug_root;
struct debugfs_regset32 *regset;
+   bool needs_byte_swap;
 
/* DWC OTG HW Release versions */
 #define DWC2_CORE_REV_2_71a0x4f54271a
@@ -1043,12 +1052,21 @@ struct dwc2_hsotg {
 /* Normal architectures just use readl/write */
 static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset)
 {
-   return readl(hsotg->regs + offset);
+   u32 val;
+
+   val = readl(hsotg->regs + offset);
+   if (hsotg->needs_byte_swap)
+   return swap32(val);
+   else
+   return val;
 }
 
 static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset)
 {
-   writel(value, hsotg->regs + offset);
+   if (hsotg->needs_byte_swap)
+   writel(swap32(value), hsotg->regs + offset);
+   else
+   writel(value, hsotg->regs + offset);
 
 #ifdef DWC2_LOG_WRITES
pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset);
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 4c0819554bcd..9a53a58e676e 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -352,6 +352,23 @@ static void dwc2_driver_shutdown(struct platform_device 
*dev)
disable_irq(hsotg->irq);
 }
 
+/**
+ * dwc2_check_core_endianness() - Returns true if core and AHB have
+ * opposite endianness.
+ * @hsotg: Programming view of the DWC_otg controller.
+ */
+static bool dwc2_check_core_endianness(struct dwc2_hsotg *hsotg)
+{
+   u32 snpsid;
+
+   snpsid = ioread32(hsotg->regs + GSNPSID);
+   if ((snpsid & GSNPSID_ID_MASK) == DWC2_OTG_ID ||
+   (snpsid & GSNPSID_ID_MASK) == DWC2_FS_IOT_ID ||
+   (snpsid & GSNPSID_ID_MASK) == DWC2_HS_IOT_ID)
+   return false;
+   return true;
+}
+
 /**
  * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
  * driver
@@ -395,6 +412,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
dev_dbg(>dev, "mapped PA %08lx to VA %p\n",
(unsigned long)res->start, hsotg->regs);
 
+   hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
+
retval = dwc2_lowlevel_hw_init(hsotg);
if (retval)
return retval;
-- 
2.11.0

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


[PATCH v1 1/4] usb: dwc2: Move dwc2_readl/writel functions after hsotg structure

2018-05-21 Thread Gevorg Sahakyan
Moved dwc2_readl/writel functions after hsotg declaration for
adding hsotg structure to dwc2_readl/writel function prototypes.

Signed-off-by: Gevorg Sahakyan 
---
 drivers/usb/dwc2/core.h | 108 
 1 file changed, 54 insertions(+), 54 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d83be5651f87..275b63b08e0f 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -65,60 +65,6 @@
DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt),\
dev_name(hsotg->dev), ##__VA_ARGS__)
 
-#ifdef CONFIG_MIPS
-/*
- * There are some MIPS machines that can run in either big-endian
- * or little-endian mode and that use the dwc2 register without
- * a byteswap in both ways.
- * Unlike other architectures, MIPS apparently does not require a
- * barrier before the __raw_writel() to synchronize with DMA but does
- * require the barrier after the __raw_writel() to serialize a set of
- * writes. This set of operations was added specifically for MIPS and
- * should only be used there.
- */
-static inline u32 dwc2_readl(const void __iomem *addr)
-{
-   u32 value = __raw_readl(addr);
-
-   /* In order to preserve endianness __raw_* operation is used. Therefore
-* a barrier is needed to ensure IO access is not re-ordered across
-* reads or writes
-*/
-   mb();
-   return value;
-}
-
-static inline void dwc2_writel(u32 value, void __iomem *addr)
-{
-   __raw_writel(value, addr);
-
-   /*
-* In order to preserve endianness __raw_* operation is used. Therefore
-* a barrier is needed to ensure IO access is not re-ordered across
-* reads or writes
-*/
-   mb();
-#ifdef DWC2_LOG_WRITES
-   pr_info("INFO:: wrote %08x to %p\n", value, addr);
-#endif
-}
-#else
-/* Normal architectures just use readl/write */
-static inline u32 dwc2_readl(const void __iomem *addr)
-{
-   return readl(addr);
-}
-
-static inline void dwc2_writel(u32 value, void __iomem *addr)
-{
-   writel(value, addr);
-
-#ifdef DWC2_LOG_WRITES
-   pr_info("info:: wrote %08x to %p\n", value, addr);
-#endif
-}
-#endif
-
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS   16
 
@@ -1094,6 +1040,60 @@ struct dwc2_hsotg {
 #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
 };
 
+#ifdef CONFIG_MIPS
+/*
+ * There are some MIPS machines that can run in either big-endian
+ * or little-endian mode and that use the dwc2 register without
+ * a byteswap in both ways.
+ * Unlike other architectures, MIPS apparently does not require a
+ * barrier before the __raw_writel() to synchronize with DMA but does
+ * require the barrier after the __raw_writel() to serialize a set of
+ * writes. This set of operations was added specifically for MIPS and
+ * should only be used there.
+ */
+static inline u32 dwc2_readl(const void __iomem *addr)
+{
+   u32 value = __raw_readl(addr);
+
+   /* In order to preserve endianness __raw_* operation is used. Therefore
+* a barrier is needed to ensure IO access is not re-ordered across
+* reads or writes
+*/
+   mb();
+   return value;
+}
+
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+   __raw_writel(value, addr);
+
+   /*
+* In order to preserve endianness __raw_* operation is used. Therefore
+* a barrier is needed to ensure IO access is not re-ordered across
+* reads or writes
+*/
+   mb();
+#ifdef DWC2_LOG_WRITES
+   pr_info("INFO:: wrote %08x to %p\n", value, addr);
+#endif
+}
+#else
+/* Normal architectures just use readl/write */
+static inline u32 dwc2_readl(const void __iomem *addr)
+{
+   return readl(addr);
+}
+
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+   writel(value, addr);
+
+#ifdef DWC2_LOG_WRITES
+   pr_info("info:: wrote %08x to %p\n", value, addr);
+#endif
+}
+#endif
+
 /* Reasons for halting a host channel */
 enum dwc2_halt_status {
DWC2_HC_XFER_NO_HALT_STATUS,
-- 
2.11.0

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


[PATCH v1 0/4] usb: dwc2: Make dwc2 endianness agnostic

2018-05-21 Thread Gevorg Sahakyan
This series contains patches which are make dwc2 core endianness agnostic

Changes from v0:

Moved dwc2_check_core_endianness() call after devm_ioremap_resource() 
to avoid ioread32() call on null pointer.

Gevorg Sahakyan (4):
  usb: dwc2: Move dwc2_readl/writel functions after hsotg structure
  usb: dwc2: Modify dwc2_readl/writel functions prototype
  usb: dwc2: replace ioread32/iowrite32_rep with dwc2_readl/writel_rep
  usb: dwc2: Make dwc2_readl/writel functions endianness-agnostic.

 drivers/usb/dwc2/core.c  | 241 ++--
 drivers/usb/dwc2/core.h  | 116 +-
 drivers/usb/dwc2/core_intr.c | 114 +-
 drivers/usb/dwc2/debugfs.c   |  55 +++--
 drivers/usb/dwc2/gadget.c| 518 +--
 drivers/usb/dwc2/hcd.c   | 461 +++---
 drivers/usb/dwc2/hcd.h   |  10 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  96 
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 drivers/usb/dwc2/params.c|  20 +-
 drivers/usb/dwc2/platform.c  |  19 ++
 12 files changed, 844 insertions(+), 826 deletions(-)

-- 
2.11.0

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


[PATCH v2] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Yoshihiro Shimoda
When printer_write() calls usb_ep_queue(), a udc driver (e.g.
renesas_usbhs driver) may call usb_gadget_giveback_request() in
the udc .queue ops immediately. Then, printer_write() calls
list_add(>list, >tx_reqs_active) wrongly. After that,
if we do unbind the printer driver, WARN_ON() happens in
printer_func_unbind() because the list entry is not removed.

So, this patch moves list_add(>list, >tx_reqs_active)
calling before usb_ep_queue().

Signed-off-by: Yoshihiro Shimoda 
Acked-by: Felipe Balbi 
---
 Changes from RFC (v1):
  - Modify the implementation to fix the issue.
  - Add "Acked-by Felipe Balbi".
  - Remove RFC.
  - Revise commit log.

 drivers/usb/gadget/function/f_printer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/function/f_printer.c 
b/drivers/usb/gadget/function/f_printer.c
index d359efe..9c7ed25 100644
--- a/drivers/usb/gadget/function/f_printer.c
+++ b/drivers/usb/gadget/function/f_printer.c
@@ -631,19 +631,19 @@ static void tx_complete(struct usb_ep *ep, struct 
usb_request *req)
return -EAGAIN;
}
 
+   list_add(>list, >tx_reqs_active);
+
/* here, we unlock, and only unlock, to avoid deadlock. */
spin_unlock(>lock);
value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
spin_lock(>lock);
if (value) {
+   list_del(>list);
list_add(>list, >tx_reqs);
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>lock_printer_io);
return -EAGAIN;
}
-
-   list_add(>list, >tx_reqs_active);
-
}
 
spin_unlock_irqrestore(>lock, flags);
-- 
1.9.1

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


RE: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Yoshihiro Shimoda
Hi,

> From: Felipe Balbi, Sent: Monday, May 21, 2018 7:19 PM
> 
> Hi,
> 
> Yoshihiro Shimoda  writes:
> > Hi,
> >
> >> From: Felipe Balbi, Sent: Monday, May 21, 2018 5:05 PM
> > 
> >> seems like it would be better to just move this like before
> >> usb_ep_queue():
> >>
> >> modified   drivers/usb/gadget/function/f_printer.c
> >> @@ -631,19 +631,19 @@ printer_write(struct file *fd, const char __user 
> >> *buf, size_t len, loff_t *ptr)
> >>return -EAGAIN;
> >>}
> >>
> >> +  list_add(>list, >tx_reqs_active);
> >> +
> >>/* here, we unlock, and only unlock, to avoid deadlock. */
> >>spin_unlock(>lock);
> >>value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
> >>spin_lock(>lock);
> >>if (value) {
> >> +  list_del(>list);
> >>list_add(>list, >tx_reqs);
> >>spin_unlock_irqrestore(>lock, flags);
> >>mutex_unlock(>lock_printer_io);
> >>return -EAGAIN;
> >>}
> >> -
> >> -  list_add(>list, >tx_reqs_active);
> >> -
> >>}
> >>
> >>spin_unlock_irqrestore(>lock, flags);
> >>
> >> --
> >
> > Thank you very much for your patch! This could resolve the issue.
> > So, should I submit this your patch as your author?
> 
> you can send it with your authorship, it's totally fine :-)

I got it :)

> You can also add my:
> 
> Acked-by: Felipe Balbi 

Thank you for your Acked-by! I'll submit v2 patch soon.

Best regards,
Yoshihiro Shimoda

> thanks
> 
> --
> balbi
--
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] tty: add missing const to termios hw-change helper

2018-05-21 Thread Johan Hovold
Add missing const qualifiers to the termios hw-change helper parameters,
which is used by few USB serial drivers. This specifically allows the
pl2303 driver to use const arguments in one of its helper as well.

Cc: Greg Kroah-Hartman 
Cc: Jiri Slaby 
Signed-off-by: Johan Hovold 
---

Greg, are you fine with me taking this one through my tree, or do prefer
I split out the pl2303 bits?

Note that this helper is only used by a few USB serial drivers and that
the pl2303 bits depend on a new patch targeted for -next.

Thanks,
Johan


 drivers/tty/tty_ioctl.c | 2 +-
 drivers/usb/serial/pl2303.c | 2 +-
 include/linux/tty.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index d9b561d89432..d99fec44036c 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(tty_termios_copy_hw);
  * between the two termios structures, or a speed change is needed.
  */
 
-int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
+int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b)
 {
if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
return 1;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ac231cdf48a6..5d1a1931967e 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -533,7 +533,7 @@ static int pl2303_set_line_request(struct usb_serial_port 
*port,
return 0;
 }
 
-static bool pl2303_termios_change(struct ktermios *a, struct ktermios *b)
+static bool pl2303_termios_change(const struct ktermios *a, const struct 
ktermios *b)
 {
bool ixon_change;
 
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1dd587ba6d88..955cd0c93d84 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -527,7 +527,7 @@ static inline speed_t tty_get_baud_rate(struct tty_struct 
*tty)
 }
 
 extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old);
-extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b);
+extern int tty_termios_hw_change(const struct ktermios *a, const struct 
ktermios *b);
 extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt);
 
 extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
-- 
2.17.0

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


Re: [PATCH v2] usbserial: pl2303 tx xon/xoff flow control

2018-05-21 Thread Johan Hovold
On Sun, May 20, 2018 at 02:23:12AM +0200, Florian Zumbiehl wrote:
> Support hardware-level Xon/Xoff flow control in transmit direction with
> pl2303.
> 
> I only know how to get the hardware to do IXON/!IXANY with ^S/^Q as control
> characters, so I preserve the old behaviour for all other cases.
> 
> Signed-off-by: Florian Zumbiehl 
> ---
> --- linux-4.16.9/drivers/usb/serial/pl2303.c.orig 2018-05-20 
> 00:51:34.580966124 +0200
> +++ linux-4.16.9/drivers/usb/serial/pl2303.c  2018-05-20 01:16:49.532730098 
> +0200
> @@ -539,12 +539,18 @@
>   struct usb_serial *serial = port->serial;
>   struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
>   struct pl2303_private *priv = usb_get_serial_port_data(port);
> + bool termios_unchanged;
>   unsigned long flags;
>   unsigned char *buf;
>   int ret;
>   u8 control;
>  
> - if (old_termios && !tty_termios_hw_change(>termios, old_termios))
> + termios_unchanged = old_termios &&
> + !(tty_termios_hw_change(>termios, old_termios) ||
> +   ((tty->termios.c_iflag ^ old_termios->c_iflag) & (IXON | 
> IXANY)) ||
> +   tty->termios.c_cc[VSTOP] != old_termios->c_cc[VSTOP] ||
> +   tty->termios.c_cc[VSTART] != old_termios->c_cc[VSTART]);
> + if (termios_unchanged)

This is slightly more readable, but you still violate indentation rules
(e.g. two tabs for continuation lines) and the expression is just
generally hard to parse.

I played around with an ixon_changed intermediate (which what I had in
mind when I suggested an intermediate), but in the end I settled on a
helper function.

The result, which I've applied for -next, can be found below.

Thanks,
Johan


>From 1f09807ed52bc530a1139c6ae6092b9176ded45f Mon Sep 17 00:00:00 2001
From: Florian Zumbiehl 
Date: Sun, 20 May 2018 02:23:12 +0200
Subject: [PATCH] USB: serial: pl2303: add support for tx xon/xoff flow control

Support hardware-level Xon/Xoff flow control in transmit direction with
pl2303.

I only know how to get the hardware to do IXON/!IXANY with ^S/^Q as control
characters, so I preserve the old behaviour for all other cases.

Signed-off-by: Florian Zumbiehl 
[ johan: rewrite logic using pl2303_termios_change() helper ]
Signed-off-by: Johan Hovold 
---
 drivers/usb/serial/pl2303.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 46dd09da2434..ac231cdf48a6 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -533,6 +533,17 @@ static int pl2303_set_line_request(struct usb_serial_port 
*port,
return 0;
 }
 
+static bool pl2303_termios_change(struct ktermios *a, struct ktermios *b)
+{
+   bool ixon_change;
+
+   ixon_change = ((a->c_iflag ^ b->c_iflag) & (IXON | IXANY)) ||
+   a->c_cc[VSTART] != b->c_cc[VSTART] ||
+   a->c_cc[VSTOP] != b->c_cc[VSTOP];
+
+   return tty_termios_hw_change(a, b) || ixon_change;
+}
+
 static void pl2303_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
 {
@@ -544,7 +555,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
int ret;
u8 control;
 
-   if (old_termios && !tty_termios_hw_change(>termios, old_termios))
+   if (old_termios && !pl2303_termios_change(>termios, old_termios))
return;
 
buf = kzalloc(7, GFP_KERNEL);
@@ -662,6 +673,9 @@ static void pl2303_set_termios(struct tty_struct *tty,
pl2303_vendor_write(serial, 0x0, 0x41);
else
pl2303_vendor_write(serial, 0x0, 0x61);
+   } else if (I_IXON(tty) && !I_IXANY(tty) && START_CHAR(tty) == 0x11 &&
+   STOP_CHAR(tty) == 0x13) {
+   pl2303_vendor_write(serial, 0x0, 0xc0);
} else {
pl2303_vendor_write(serial, 0x0, 0x0);
}
-- 
2.17.0

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


RE: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Felipe Balbi

Hi,

Yoshihiro Shimoda  writes:
> Hi,
>
>> From: Felipe Balbi, Sent: Monday, May 21, 2018 5:05 PM
> 
>> seems like it would be better to just move this like before
>> usb_ep_queue():
>> 
>> modified   drivers/usb/gadget/function/f_printer.c
>> @@ -631,19 +631,19 @@ printer_write(struct file *fd, const char __user *buf, 
>> size_t len, loff_t *ptr)
>>  return -EAGAIN;
>>  }
>> 
>> +list_add(>list, >tx_reqs_active);
>> +
>>  /* here, we unlock, and only unlock, to avoid deadlock. */
>>  spin_unlock(>lock);
>>  value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
>>  spin_lock(>lock);
>>  if (value) {
>> +list_del(>list);
>>  list_add(>list, >tx_reqs);
>>  spin_unlock_irqrestore(>lock, flags);
>>  mutex_unlock(>lock_printer_io);
>>  return -EAGAIN;
>>  }
>> -
>> -list_add(>list, >tx_reqs_active);
>> -
>>  }
>> 
>>  spin_unlock_irqrestore(>lock, flags);
>> 
>> --
>
> Thank you very much for your patch! This could resolve the issue.
> So, should I submit this your patch as your author?

you can send it with your authorship, it's totally fine :-)

You can also add my:

Acked-by: Felipe Balbi 

thanks

-- 
balbi


signature.asc
Description: PGP signature


[PATCH] usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub

2018-05-21 Thread William Wu
The dwc2_get_ls_map() use ttport to reference into the
bitmap if we're on a multi_tt hub. But the bitmaps index
from 0 to (hub->maxchild - 1), while the ttport index from
1 to hub->maxchild. This will cause invalid memory access
when the number of ttport is hub->maxchild.

Without this patch, I can easily meet a Kernel panic issue
if connect a low-speed USB mouse with the max port of FE2.1
multi-tt hub (1a40:0201) on rk3288 platform.

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd_queue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index d7c3d6c..9c55d1a 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -383,7 +383,7 @@ static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg 
*hsotg,
/* Get the map and adjust if this is a multi_tt hub */
map = qh->dwc_tt->periodic_bitmaps;
if (qh->dwc_tt->usb_tt->multi)
-   map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
+   map += DWC2_ELEMENTS_PER_LS_BITMAP * (qh->ttport - 1);
 
return map;
 }
-- 
2.0.0


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


RE: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Yoshihiro Shimoda
Hi,

> From: Felipe Balbi, Sent: Monday, May 21, 2018 5:05 PM

> seems like it would be better to just move this like before
> usb_ep_queue():
> 
> modified   drivers/usb/gadget/function/f_printer.c
> @@ -631,19 +631,19 @@ printer_write(struct file *fd, const char __user *buf, 
> size_t len, loff_t *ptr)
>   return -EAGAIN;
>   }
> 
> + list_add(>list, >tx_reqs_active);
> +
>   /* here, we unlock, and only unlock, to avoid deadlock. */
>   spin_unlock(>lock);
>   value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
>   spin_lock(>lock);
>   if (value) {
> + list_del(>list);
>   list_add(>list, >tx_reqs);
>   spin_unlock_irqrestore(>lock, flags);
>   mutex_unlock(>lock_printer_io);
>   return -EAGAIN;
>   }
> -
> - list_add(>list, >tx_reqs_active);
> -
>   }
> 
>   spin_unlock_irqrestore(>lock, flags);
> 
> --

Thank you very much for your patch! This could resolve the issue.
So, should I submit this your patch as your author?

Best regards,
Yoshihiro Shimoda

> balbi
--
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: dwc2: Fix HiKey regression caused by power_down feature

2018-05-21 Thread Minas Harutyunyan
Hi John,

On 5/19/2018 4:49 AM, John Stultz wrote:
> In 4.17-rc, commit 03ea6d6e9e1f ("usb: dwc2: Enable power down")
> caused the HiKey board to not correctly handle switching between
> usb-gadget and usb-host mode.
> 
> Unplugging the OTG port would result in:
> [   42.240973] dwc2 f72c.usb: dwc2_restore_host_registers: no host 
> registers to restore
> [   42.249066] dwc2 f72c.usb: dwc2_host_exit_hibernation: failed to 
> restore host registers
> 
> And the USB-host ports would not function.
> 
> And plugging in the OTG port, we would see:
> [   46.046557] WARNING: CPU: 3 PID: 6 at drivers/usb/dwc2/gadget.c:260 
> dwc2_hsotg_init_fifo+0x194/0x1a0
> [   46.055761] CPU: 3 PID: 6 Comm: kworker/u16:0 Not tainted 
> 4.17.0-rc5-00030-ge67da8c #231
> [   46.055767] Hardware name: HiKey Development Board (DT)
> [   46.055784] Workqueue: dwc2 dwc2_conn_id_status_change
> ...
> 
Could you please send full log to debug.


> Thus, this patch sets the hisi params to disable the power_down
> flag by default, and gets thing working again.
> 
> Cc: John Youn 
> Cc: Vardan Mikayelyan 
> Cc: Artur Petrosyan 
> Cc: Grigor Tovmasyan 
> Cc: Felipe Balbi 
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: John Stultz 
> ---
>   drivers/usb/dwc2/params.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
> index f03e418..96b1b25 100644
> --- a/drivers/usb/dwc2/params.c
> +++ b/drivers/usb/dwc2/params.c
> @@ -70,6 +70,7 @@ static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
>   GAHBCFG_HBSTLEN_SHIFT;
>   p->uframe_sched = false;
>   p->change_speed_quirk = true;
> + p->power_down = false;

power_down declared as int, suggested to update as follow:
p->power_down = DWC2_POWER_DOWN_PARAM_NONE;

This can be accepted as temporary solution until we will fully debug 
hibernation feature for HiKey platform.

>   }
>   
>   static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg)
> 

--
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] usbserial: pl2303 tx xon/xoff flow control

2018-05-21 Thread Johan Hovold
On Sun, May 20, 2018 at 02:22:27AM +0200, Florian Zumbiehl wrote:

> Before I investigated how to implement this patch I just saw that s/w flow
> control "didn't work", but my assumption was that that was due to buffering
> latencies, not because the kernel just ignored the request. But then,
> chances are a software implementation indeed wouldn't work very well anyway
> for exactly that reason?!

Indeed, the deep queues might prevent a software implementation from
being very useful.

> > The line discipline implementation kicks in whenever IXON is set, and
> > can be used as a fallback for devices where automatic hardware and
> > software flow control cannot be enabled concurrently in hardware for
> > example.
> 
> Well, yeah, my guess would be that to actually make it work (well), one
> would need more than that? Like, implement rate control in software to keep
> the hardware buffers empty in order to achieve short reaction times? Which
> one would probably want to disable though when it's not needed in order to
> take advantage of the buffers?

Maybe, but chances are none of this is worth the added complexity. If
you need XON/XOFF you should get a device which supports it in hardware.

> > While non-hardware assisted usb serial XON/XOFF is currently broken in
> > that transmission would not be halted, the line discipline would still
> > swallow any escape characters.
> 
> Actually, that is required even for the pl2303, as it does not swallow the
> control characters itself.

Yeah, I noticed that too.

Thanks,
Johan
--
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 v4] NFC: pn533: don't send USB data off of the stack

2018-05-21 Thread Johan Hovold
On Sun, May 20, 2018 at 03:19:46PM +0200, Greg Kroah-Hartman wrote:
> It's amazing that this driver ever worked, but now that x86 doesn't
> allow USB data to be sent off of the stack, it really does not work at
> all.  Fix this up by properly allocating the data for the small
> "commands" that get sent to the device off of the stack.
> 
> We do this for one command by having a whole urb just for ack messages,
> as they can be submitted in interrupt context, so we can not use
> usb_bulk_msg().  But the poweron command can sleep (and does), so use
> usb_bulk_msg() for that transfer.
> 
> Reported-by: Carlos Manuel Santos 
> Cc: Samuel Ortiz 
> Cc: Stephen Hemminger 
> Cc: stable 
> Signed-off-by: Greg Kroah-Hartman 
> ---
> v4: don't use urb transfer buffer flags as the memory is tied to the urb
> (thanks to Johan)  Now we have a new static urb, and we use
> usb_bulk_msg() for the other message.
> v3: actually use the correct buffer (thanks to Arend van Spriel)
> use kmemdup (thanks to Johannes Berg and Julia Lawall)
> v2: set the urb flags correctly

Your changes look correct now so feel free to add:

Reviewed-by: Johan Hovold 

It seems we could end up returning an errno from probe with active urbs
(if pn533_finalize_setup() fails) in which case the ack buffer would
leak. But freeing the urbs while active would then be the bigger
problem, and that wasn't introduced by this patch.

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


[PATCH 3/3] usb: gadget: uvc: Move trace parameter to function module

2018-05-21 Thread Laurent Pinchart
The trace module parameter controls output of debugging messages in the
UVC function driver. Move it from the webcam module to the UVC function
module where it belongs. This allows ConfigFS-based UVC gadgets to
control tracing.

Signed-off-by: Laurent Pinchart 
---
 drivers/usb/gadget/function/f_uvc.c | 2 ++
 drivers/usb/gadget/function/u_uvc.h | 4 
 drivers/usb/gadget/legacy/webcam.c  | 4 
 3 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uvc.c 
b/drivers/usb/gadget/function/f_uvc.c
index 54f04d321829..1d2feac5c532 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -31,6 +31,8 @@
 #include "uvc_video.h"
 
 unsigned int uvc_gadget_trace_param;
+module_param_named(trace, uvc_gadget_trace_param, uint, 0644);
+MODULE_PARM_DESC(trace, "Trace level bitmask");
 
 /* --
  * Function descriptors
diff --git a/drivers/usb/gadget/function/u_uvc.h 
b/drivers/usb/gadget/function/u_uvc.h
index a6fdde6b162b..2ed292e94fbc 100644
--- a/drivers/usb/gadget/function/u_uvc.h
+++ b/drivers/usb/gadget/function/u_uvc.h
@@ -21,7 +21,6 @@
 
 struct f_uvc_opts {
struct usb_function_instancefunc_inst;
-   unsigned intuvc_gadget_trace_param;
unsigned intstreaming_interval;
unsigned intstreaming_maxpacket;
unsigned intstreaming_maxburst;
@@ -81,7 +80,4 @@ struct f_uvc_opts {
int refcnt;
 };
 
-void uvc_set_trace_param(unsigned int trace);
-
 #endif /* U_UVC_H */
-
diff --git a/drivers/usb/gadget/legacy/webcam.c 
b/drivers/usb/gadget/legacy/webcam.c
index 6b86568c9157..a9f8eb8e1c76 100644
--- a/drivers/usb/gadget/legacy/webcam.c
+++ b/drivers/usb/gadget/legacy/webcam.c
@@ -30,9 +30,6 @@ static unsigned int streaming_maxburst;
 module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
 
-static unsigned int trace;
-module_param(trace, uint, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(trace, "Trace level bitmask");
 /* --
  * Device descriptor
  */
@@ -379,7 +376,6 @@ webcam_bind(struct usb_composite_dev *cdev)
uvc_opts->streaming_interval = streaming_interval;
uvc_opts->streaming_maxpacket = streaming_maxpacket;
uvc_opts->streaming_maxburst = streaming_maxburst;
-   uvc_set_trace_param(trace);
 
uvc_opts->fs_control = uvc_fs_control_cls;
uvc_opts->ss_control = uvc_ss_control_cls;
-- 
Regards,

Laurent Pinchart

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


[PATCH 2/3] usb: gadget: uvc: Minimize #include in headers

2018-05-21 Thread Laurent Pinchart
In order to speed up compilation, only include the headers that are
strictly required within other headers. To that end, use forward
structure declaration and move #include statements to .c file as
appropriate.

While at it, sort headers alphabetically, and remove unneeded __KERNEL__
guards.

Signed-off-by: Laurent Pinchart 
---
 drivers/usb/gadget/function/f_uvc.c |  5 +++--
 drivers/usb/gadget/function/f_uvc.h |  6 +-
 drivers/usb/gadget/function/u_uvc.h |  1 +
 drivers/usb/gadget/function/uvc.h   | 14 ++
 drivers/usb/gadget/function/uvc_queue.h | 12 ++--
 drivers/usb/gadget/function/uvc_v4l2.c  |  3 ++-
 drivers/usb/gadget/function/uvc_video.h |  2 ++
 7 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uvc.c 
b/drivers/usb/gadget/function/f_uvc.c
index 439eba660e95..54f04d321829 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -6,16 +6,17 @@
  * Laurent Pinchart (laurent.pinch...@ideasonboard.com)
  */
 
-#include 
-#include 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/drivers/usb/gadget/function/f_uvc.h 
b/drivers/usb/gadget/function/f_uvc.h
index 81defe4557fe..a81a17765558 100644
--- a/drivers/usb/gadget/function/f_uvc.h
+++ b/drivers/usb/gadget/function/f_uvc.h
@@ -9,10 +9,7 @@
 #ifndef _F_UVC_H_
 #define _F_UVC_H_
 
-#include 
-#include 
-
-#include "uvc.h"
+struct uvc_device;
 
 void uvc_function_setup_continue(struct uvc_device *uvc);
 
@@ -21,4 +18,3 @@ void uvc_function_connect(struct uvc_device *uvc);
 void uvc_function_disconnect(struct uvc_device *uvc);
 
 #endif /* _F_UVC_H_ */
-
diff --git a/drivers/usb/gadget/function/u_uvc.h 
b/drivers/usb/gadget/function/u_uvc.h
index d00d3ded71c0..a6fdde6b162b 100644
--- a/drivers/usb/gadget/function/u_uvc.h
+++ b/drivers/usb/gadget/function/u_uvc.h
@@ -13,6 +13,7 @@
 #ifndef U_UVC_H
 #define U_UVC_H
 
+#include 
 #include 
 #include 
 
diff --git a/drivers/usb/gadget/function/uvc.h 
b/drivers/usb/gadget/function/uvc.h
index 053e4b72039d..93cf78b420fe 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -9,16 +9,22 @@
 #ifndef _UVC_GADGET_H_
 #define _UVC_GADGET_H_
 
-#include  /* For usb_endpoint_* */
+#include 
+#include 
+#include 
 #include 
-#include 
-#include 
 #include 
-#include 
+
 #include 
+#include 
+#include 
 
 #include "uvc_queue.h"
 
+struct usb_ep;
+struct usb_request;
+struct uvc_descriptor_header;
+
 /* 
  * Debugging, printing and logging
  */
diff --git a/drivers/usb/gadget/function/uvc_queue.h 
b/drivers/usb/gadget/function/uvc_queue.h
index f9f65b5c1062..2f0fff769843 100644
--- a/drivers/usb/gadget/function/uvc_queue.h
+++ b/drivers/usb/gadget/function/uvc_queue.h
@@ -2,13 +2,15 @@
 #ifndef _UVC_QUEUE_H_
 #define _UVC_QUEUE_H_
 
-#ifdef __KERNEL__
-
-#include 
+#include 
 #include 
-#include 
+#include 
+
 #include 
 
+struct file;
+struct mutex;
+
 /* Maximum frame size in bytes, for sanity checking. */
 #define UVC_MAX_FRAME_SIZE (16*1024*1024)
 /* Maximum number of video buffers. */
@@ -91,7 +93,5 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct 
uvc_video_queue *queue,
 
 struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue);
 
-#endif /* __KERNEL__ */
-
 #endif /* _UVC_QUEUE_H_ */
 
diff --git a/drivers/usb/gadget/function/uvc_v4l2.c 
b/drivers/usb/gadget/function/uvc_v4l2.c
index 9a9019625496..7f1ca3b57823 100644
--- a/drivers/usb/gadget/function/uvc_v4l2.c
+++ b/drivers/usb/gadget/function/uvc_v4l2.c
@@ -6,10 +6,11 @@
  * Laurent Pinchart (laurent.pinch...@ideasonboard.com)
  */
 
-#include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/drivers/usb/gadget/function/uvc_video.h 
b/drivers/usb/gadget/function/uvc_video.h
index 6c20aa75f966..7d77122b0ff9 100644
--- a/drivers/usb/gadget/function/uvc_video.h
+++ b/drivers/usb/gadget/function/uvc_video.h
@@ -12,6 +12,8 @@
 #ifndef __UVC_VIDEO_H__
 #define __UVC_VIDEO_H__
 
+struct uvc_video;
+
 int uvcg_video_pump(struct uvc_video *video);
 
 int uvcg_video_enable(struct uvc_video *video, int enable);
-- 
Regards,

Laurent Pinchart

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


[PATCH 1/3] usb: gadget: uvc: Move userspace API definition to public header

2018-05-21 Thread Laurent Pinchart
The UVC gadget userspace API (V4L2 events and custom ioctls) is defined
in a header internal to the kernel. Move it to a new public header to
make it accessible to userspace.

The UVC_INTF_CONTROL and UVC_INTF_STREAMING macros are not used, so
remove them in the process.

Signed-off-by: Laurent Pinchart 
---
 MAINTAINERS   |  1 +
 drivers/usb/gadget/function/uvc.h | 45 +--
 include/uapi/linux/usb/g_uvc.h| 39 +
 3 files changed, 45 insertions(+), 40 deletions(-)
 create mode 100644 include/uapi/linux/usb/g_uvc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 58b9861ccf99..1ff4fa34febd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14772,6 +14772,7 @@ L:  linux-usb@vger.kernel.org
 S: Maintained
 F: drivers/usb/gadget/function/*uvc*
 F: drivers/usb/gadget/legacy/webcam.c
+F: include/uapi/linux/usb/g_uvc.h
 
 USB WIRELESS RNDIS DRIVER (rndis_wlan)
 M: Jussi Kivilinna 
diff --git a/drivers/usb/gadget/function/uvc.h 
b/drivers/usb/gadget/function/uvc.h
index a64e07e61f8c..053e4b72039d 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -9,52 +9,20 @@
 #ifndef _UVC_GADGET_H_
 #define _UVC_GADGET_H_
 
-#include 
-#include 
-#include 
-
-#define UVC_EVENT_FIRST(V4L2_EVENT_PRIVATE_START + 0)
-#define UVC_EVENT_CONNECT  (V4L2_EVENT_PRIVATE_START + 0)
-#define UVC_EVENT_DISCONNECT   (V4L2_EVENT_PRIVATE_START + 1)
-#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2)
-#define UVC_EVENT_STREAMOFF(V4L2_EVENT_PRIVATE_START + 3)
-#define UVC_EVENT_SETUP(V4L2_EVENT_PRIVATE_START + 4)
-#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
-#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5)
-
-struct uvc_request_data {
-   __s32 length;
-   __u8 data[60];
-};
-
-struct uvc_event {
-   union {
-   enum usb_device_speed speed;
-   struct usb_ctrlrequest req;
-   struct uvc_request_data data;
-   };
-};
-
-#define UVCIOC_SEND_RESPONSE   _IOW('U', 1, struct uvc_request_data)
-
-#define UVC_INTF_CONTROL   0
-#define UVC_INTF_STREAMING 1
-
-/* 
- * Debugging, printing and logging
- */
-
-#ifdef __KERNEL__
-
 #include  /* For usb_endpoint_* */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
 #include "uvc_queue.h"
 
+/* 
+ * Debugging, printing and logging
+ */
+
 #define UVC_TRACE_PROBE(1 << 0)
 #define UVC_TRACE_DESCR(1 << 1)
 #define UVC_TRACE_CONTROL  (1 << 2)
@@ -184,7 +152,4 @@ extern void uvc_endpoint_stream(struct uvc_device *dev);
 extern void uvc_function_connect(struct uvc_device *uvc);
 extern void uvc_function_disconnect(struct uvc_device *uvc);
 
-#endif /* __KERNEL__ */
-
 #endif /* _UVC_GADGET_H_ */
-
diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h
new file mode 100644
index ..3c9ee3020cbb
--- /dev/null
+++ b/include/uapi/linux/usb/g_uvc.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * g_uvc.h  --  USB Video Class Gadget driver API
+ *
+ * Copyright (C) 2009-2010 Laurent Pinchart 
+ */
+
+#ifndef __LINUX_USB_G_UVC_H
+#define __LINUX_USB_G_UVC_H
+
+#include 
+#include 
+#include 
+
+#define UVC_EVENT_FIRST(V4L2_EVENT_PRIVATE_START + 0)
+#define UVC_EVENT_CONNECT  (V4L2_EVENT_PRIVATE_START + 0)
+#define UVC_EVENT_DISCONNECT   (V4L2_EVENT_PRIVATE_START + 1)
+#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2)
+#define UVC_EVENT_STREAMOFF(V4L2_EVENT_PRIVATE_START + 3)
+#define UVC_EVENT_SETUP(V4L2_EVENT_PRIVATE_START + 4)
+#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
+#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5)
+
+struct uvc_request_data {
+   __s32 length;
+   __u8 data[60];
+};
+
+struct uvc_event {
+   union {
+   enum usb_device_speed speed;
+   struct usb_ctrlrequest req;
+   struct uvc_request_data data;
+   };
+};
+
+#define UVCIOC_SEND_RESPONSE   _IOW('U', 1, struct uvc_request_data)
+
+#endif /* __LINUX_USB_G_UVC_H */
-- 
Regards,

Laurent Pinchart

--
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 0/3] usb: gadget: uvc: Expose UAPI & miscellaneous cleanups

2018-05-21 Thread Laurent Pinchart
Hello,

Here are a few miscellaneous patches prompted by drive-by fixes.

The first patch moves the definition of the UVC function userspace API
to a public header in include/uapi/ for consumption by userspace. This
should remove the need to manually copy the file when compiling
userspace applications, or, worse, to use relative include paths that
point within the kernel source tree.

The next two patches are small cleanups for miscellaneous things that
bothered me while writing the first patch. There isn't much of a design
to comment on, please see individual patches for details.

Laurent Pinchart (3):
  usb: gadget: uvc: Move userspace API definition to public header
  usb: gadget: uvc: Minimize #include in headers
  usb: gadget: uvc: Move trace parameter to function module

 MAINTAINERS |  1 +
 drivers/usb/gadget/function/f_uvc.c |  7 +++--
 drivers/usb/gadget/function/f_uvc.h |  6 +---
 drivers/usb/gadget/function/u_uvc.h |  5 +---
 drivers/usb/gadget/function/uvc.h   | 53 -
 drivers/usb/gadget/function/uvc_queue.h | 12 
 drivers/usb/gadget/function/uvc_v4l2.c  |  3 +-
 drivers/usb/gadget/function/uvc_video.h |  2 ++
 drivers/usb/gadget/legacy/webcam.c  |  4 ---
 include/uapi/linux/usb/g_uvc.h  | 39 
 10 files changed, 69 insertions(+), 63 deletions(-)
 create mode 100644 include/uapi/linux/usb/g_uvc.h

-- 
Regards,

Laurent Pinchart

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


[GIT PULL] USB for v4.18 merge window

2018-05-21 Thread Felipe Balbi

Hi Greg,

Here's my pull request for v4.18 merge window. Let me know if you want
anything to be changed.

For the rest of the week I'll have very scarce access to email, so
replies may be delayed.

Cheers

The following changes since commit 6d08b06e67cd117f6992c46611dfb4ce267cd71e:

  Linux 4.17-rc2 (2018-04-22 19:20:09 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git tags/usb-for-v4.18

for you to fetch changes up to 47265c067c0d129f3a0e94bc221293a780af9d78:

  usb: dwc2: gadget: Fix coverity issue (2018-05-21 10:40:16 +0300)


usb: changes for v4.18 merge window

A total of 98 non-merge commits, the biggest part being in dwc3 this
time around with a large refactoring of dwc3's transfer handling code.

We also have a new driver for Aspeed virtual hub controller.

Apart from that, just a list of miscellaneous fixes all over the place.


Alan Stern (1):
  usb: gadget: udc: core: Document the relation between usb_ep_queue() and 
completion callback

Andrzej Hajda (1):
  USB: dwc3: get extcon device by OF graph bindings

Anurag Kumar Vulisha (2):
  usb: dwc3: gadget: Correct handling of scattergather lists
  usb: dwc3: gadget: Correct the logic for queuing sgs

Artur Petrosyan (3):
  usb: dwc2: Fix crash in incomplete isoc intr handlers.
  usb: dwc2: Change reading of current frame number flow.
  usb: dwc2: WA for Full speed ISOC IN in DDMA mode.

Benjamin Herrenschmidt (2):
  usb/gadget: Constify usb_gadget_get_string "table" argument
  usb/gadget: Add driver for Aspeed SoC virtual hub

Chunfeng Yun (6):
  usb: mtu3: avoid TX data length truncated in SS/SSP mode
  usb: mtu3: remove repeated setting of gadget state
  usb: mtu3: fix an unrecognized issue when connected with PC
  usb: mtu3: fix operation failure when test TEST_J/K
  usb: mtu3: make USB_MTU3_DUAL_ROLE depend on EXTCON but not USB_MTU3
  usb: gadget: composite: fill bcdUSB as 0x0320 for SuperSpeed or higher 
speeds

Dmitry Osipenko (3):
  usb: phy: tegra: Cleanup error messages
  usb: tegra: Move utmi-pads reset from ehci-tegra to tegra-phy
  usb: phy: Add Kconfig entry for Tegra PHY driver

Felipe Balbi (43):
  usb: dwc3: gadget: pre-issue Start Transfer for Interrupt EPs too
  usb: dwc3: gadget: XferNotReady is Isoc-only
  usb: dwc3: gadget: XferComplete only for EP0
  usb: dwc3: gadget: rename dwc3_endpoint_transfer_complete()
  usb: dwc3: gadget: don't kick transfer all the time
  usb: dwc3: gadget: rename done_trbs and done_reqs
  usb: dwc3: gadget: remove allocated/queued request tracking
  usb: dwc3: gadget: remove some pointless checks
  usb: dwc3: gadget: rename dwc3_gadget_start_isoc()
  usb: dwc3: gadget: move handler closer to calling site
  usb: dwc3: gadget: remove unnecessary 'dwc' parameter
  usb: dwc3: gadget: always use frame number from XferNotReady
  usb: dwc3: gadget: update dep->frame_number from XferInprogress too
  usb: dwc3: gadget: start removing BUSY flag
  usb: dwc3: gadget: remove DWC3_EP_BUSY flag
  usb: dwc3: gadget: make cleanup_completed_requests() return nothing
  usb: dwc3: gadget: remove unnecessary 'ioc' variable
  usb: dwc3: gadget: check for Missed Isoc from event status
  usb: dwc3: gadget: remove duplicated missed isoc handling
  usb: dwc3: gadget: simplify queueing of isoc transfers
  usb: dwc3: gadget: simplify isoc case on cleanup_completed_requests
  usb: dwc3: gadget: split scatterlist and linear handlers
  usb: dwc3: gadget: remove PENDING handling from cleanup_completed
  usb: dwc3: gadget: remove unnecessary 'chain' variable
  usb: dwc3: gadget: simplify unaligned and zlp handling
  usb: dwc3: trace: print out event status too
  usb: dwc3: gadget: simplify short packet event
  usb: dwc3: gadget: simplify IOC handling
  usb: dwc3: gadget: one declaration per line
  usb: dwc3: gadget: reduce scope of ret variable
  usb: dwc3: gadget: get rid of the length variable
  usb: dwc3: gadget: split dwc3_gadget_ep_cleanup_completed_requests()
  usb: dwc3: gadget: refactor dwc3_gadget_init_endpoints()
  usb: dwc3: gadget: combine modify & restore into single argument
  usb: dwc3: gadget: remove a few more dwc arguments
  usb: dwc3: gadget: move set_xfer_resource() in place of prototype
  usb: dwc3: gadget: move dwc3_calc_trbs_left() in place of prototype
  usb: dwc3: debug: decode uFrame from event too
  usb: dwc3: gadget: don't issue End Transfer if we have started reqs
  usb: dwc3: gadget: always start isochronous aligned to dep->interval
  usb: dwc3: gadget: assign resource_index inside get_transfer_index()
  usb: dwc3: gadget: initialize transfer index from send_gadget_ep_cmd()
 

Re: [PATCH v2 2/3] xhci: Add quirk to zero 64bit registers on Renesas PCIe controllers

2018-05-21 Thread Mathias Nyman

On 18.05.2018 19:29, Marc Zyngier wrote:

Some Renesas controllers get into a weird state if they are reset while
programmed with 64bit addresses (they will preserve the top half of the
address in internal, non visible registers).

You end up with half the address coming from the kernel, and the other
half coming from the firmware.


Should those registers be zeroed in resume from hibernate where we also
reset the host controller?



Also, changing the programming leads to extra accesses even if the
controller is supposed to be halted. The controller ends up with a fatal
fault, and is then ripe for being properly reset. On the flip side,
this is completely unsafe if the defvice isn't behind an IOMMU, so
we have to make sure that this is the case. Can you say "broken"?

This is an alternative method to the one introduced in 8466489ef5ba
("xhci: Reset Renesas uPD72020x USB controller for 32-bit DMA issue"),
which will subsequently be removed.

Signed-off-by: Marc Zyngier 
---
  drivers/usb/host/xhci-pci.c |  8 --
  drivers/usb/host/xhci.c | 59 +
  drivers/usb/host/xhci.h |  1 +
  3 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 85ffda85f8ab..e0a0a12871e2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -196,11 +196,15 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
xhci->quirks |= XHCI_BROKEN_STREAMS;
}
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
-   pdev->device == 0x0014)
+   pdev->device == 0x0014) {
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+   xhci->quirks |= XHCI_ZERO_64B_REGS;
+   }
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
-   pdev->device == 0x0015)
+   pdev->device == 0x0015) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
+   xhci->quirks |= XHCI_ZERO_64B_REGS;
+   }
if (pdev->vendor == PCI_VENDOR_ID_VIA)
xhci->quirks |= XHCI_RESET_ON_RESUME;
  
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c

index 8dba26d3de07..07272d1ce32a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4921,6 +4921,65 @@ int xhci_gen_setup(struct usb_hcd *hcd, 
xhci_get_quirks_t get_quirks)
if (retval)
return retval;
  
+	/*

+* Some Renesas controllers get into a weird state if they are
+* reset while programmed with 64bit addresses (they will preserve
+* the top half of the address in internal, non visible
+* registers). You end up with half the address coming from the
+* kernel, and the other half coming from the firmware. Also,
+* changing the programming leads to extra accesses even if the
+* controller is supposed to be halted. The controller ends up with
+* a fatal fault, and is then ripe for being properly reset.
+*
+* Special care is taken to only apply this if the device is behind
+* an iommu. Doing anything when there is no iommu is definitely
+* unsafe...
+*/
+   if ((xhci->quirks & XHCI_ZERO_64B_REGS) && dev->iommu_group) {
+   u64 val;
+   int i;
+
+   xhci_info(xhci,
+ "Zeroing 64bit base registers, expecting fault\n");
+
+   /* Clear HSEIE so that faults do not get signaled */
+   val = readl(>op_regs->command);
+   val &= ~CMD_HSEIE;
+   writel(val, >op_regs->command);
+
+   /* Clear HSE (aka FATAL) */
+   val = readl(>op_regs->status);
+   val |= STS_FATAL;
+   writel(val, >op_regs->status);
+
+   /* Now zero the registers, and brace for impact */
+   val = xhci_read_64(xhci, >op_regs->dcbaa_ptr);
+   if (upper_32_bits(val))
+   xhci_write_64(xhci, 0, >op_regs->dcbaa_ptr);
+   val = xhci_read_64(xhci, >op_regs->cmd_ring);
+   if (upper_32_bits(val))
+   xhci_write_64(xhci, 0, >op_regs->cmd_ring);
+
+   for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) {
+   struct xhci_intr_reg __iomem *ir;
+
+   ir = >run_regs->ir_set[i];
+   val = xhci_read_64(xhci, >erst_base);
+   if (upper_32_bits(val))
+   xhci_write_64(xhci, 0, >erst_base);
+   val= xhci_read_64(xhci, >erst_dequeue);
+   if (upper_32_bits(val))
+   xhci_write_64(xhci, 0, >erst_dequeue);
+   }
+
+   /* Wait for the fault to appear. It will be cleared on reset */
+   retval = xhci_handshake(>op_regs->status,
+

Re: Some questions about the UVC gadget

2018-05-21 Thread Laurent Pinchart
Hello Kelly,

Sorry for the late reply, your e-mail got buried in my inbox :-/

On Friday, 23 February 2018 05:36:55 EEST Kelly Huang wrote:
> Dear Mr.Pinchart,
> 
> > I'm afraid the Linux UVC gadget driver doesn't support H.264. While H.264
> > support could be implemented using UVC 1.1, I wouldn't recommend this as
> > the UVC 1.1 H.264 specification is a hack that is not and will not be
> > supported in the Linux UVC host driver. UVC 1.5 is the way to go for
> > H.264.
> 
> I have a  Logitech C920 usb camera which claims H.264 support. When I used
> it under my usb protocol analyzer, I found that one of the CS_INTERFACE
> descriptor had a VS_FORMAT_FRAME_BASED subtype, and the guidFormat is
> '48323634-1000-80AA-389B71', including the 'H264' symbols.
> 
> I don't know if that is the way you talked about implementing H.264 using
> UVC 1.1? It seems that I need to rename some descriptors of the UVC gadget
> driver and write a userspace application to fill /dev/videoX with H.264
> streams. If so, can it work correctly?

I spoke a bit too fast in my previous e-mail. H.264 support with UVC 1.1 
should be OK, as long as you don't use the H.264 UVC 1.1 stream multiplexing 
method that allows transmitting multiple video streams over a single endpoint.

The support H.264 with UVC 1.1 you will need to create the corresponding 
descriptors, and to implement support in the userspace helper application for 
the H.264 extension unit (XU) defined in the UVC 1.1 specification.

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH v2 0/3] usb: gadget: uvc: fix racing between uvc_function_set_alt and streamon/off

2018-05-21 Thread Laurent Pinchart
Hi Paul,

On Tuesday, 24 April 2018 23:59:33 EEST Paul Elder wrote:
> Down the call stack from the ioctl handler for VIDIOC_STREAMON,
> uvc_video_alloc_requests contains a BUG_ON, which in the high level,
> triggers when VIDIOC_STREAMON ioctl is issued without VIDIOC_STREAMOFF
> being issued previously.
> 
> This can happen in a few ways, such as if the userspace uvc gadget
> application simply doesn't issue VIDIOC_STREAMOFF. Another way is if
> uvc_function_set_alt with alt 0 is called after it is called with 1 but
> before VIDIOC_STREAMON is called; in this case, UVC_EVENT_STREAMOFF will
> not be queued to userspace, and therefore userspace will never call
> VIDIOC_STREAMOFF.
> 
> To fix this, add two more uvc states: starting and stopping. The
> starting state is entered when uvc_function_set_alt 1 is called, and is
> exited in uvc_v4l2_streamon, when the state is changed to streaming. The
> stopping state is entered when uvc_function_set_alt 0 is called, and is
> exited in uvc_v4l2_streamoff, when the state is changed to connected.

It would be useful to capture this in kerneldoc as a documentation of the 
states enum. I believe writing the description of state transitions down will 
also help you understand the potential race conditions.

> The status phase of the SET_INTERFACE request doesn't need to be delayed
> by the uvc gadget driver, so that is removed.
> 
> Finally, there is another way to trigger the aforementioned BUG: start
> streaming and (physically) disconnect usb. To fix this, call
> uvcg_video_enable 0 in uvc_function_disable.
> 
> Changes in v2:
>   1. Remove delay usb status phase
> 
> Paul Elder (3):
>   usb: gadget: uvc: synchronize streamon/off with uvc_function_set_alt
>   usb: gadget: uvc: remove delay usb status phase from uvc
>   usb: gadget: uvc: disable stream when disconnected
> 
>  drivers/usb/gadget/function/f_uvc.c| 14 +++---
>  drivers/usb/gadget/function/uvc.h  |  2 ++
>  drivers/usb/gadget/function/uvc_v4l2.c | 21 +++--
>  3 files changed, 28 insertions(+), 9 deletions(-)

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH v2 3/3] usb: gadget: uvc: disable stream when disconnected

2018-05-21 Thread Laurent Pinchart
Hi Paul,

Thank you for the patch.

On Tuesday, 24 April 2018 23:59:36 EEST Paul Elder wrote:
> Down the call stack from the ioctl handler for VIDIOC_STREAMON,
> uvc_video_alloc_requests contains a BUG_ON, which in the high level,
> triggers when VIDIOC_STREAMON ioctl is issued without VIDIOC_STREAMOFF
> being issued previously.
> 
> This can also be triggered by starting the stream and then physically
> disconnecting usb. To fix this, do the streamoff procedures on usb
> disconnect.
> 
> Signed-off-by: Paul Elder 
> ---
> Changes in v2: Nothing
> 
>  drivers/usb/gadget/function/f_uvc.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/usb/gadget/function/f_uvc.c
> b/drivers/usb/gadget/function/f_uvc.c index fa34dcbe1197..5bb79888e3f7
> 100644
> --- a/drivers/usb/gadget/function/f_uvc.c
> +++ b/drivers/usb/gadget/function/f_uvc.c
> @@ -374,9 +374,12 @@ uvc_function_disable(struct usb_function *f)
>  {
>   struct uvc_device *uvc = to_uvc(f);
>   struct v4l2_event v4l2_event;
> + struct uvc_video *video = >video;
> 
>   INFO(f->config->cdev, "uvc_function_disable\n");
> 
> + uvcg_video_enable(video, 0);
> +

As commented in my reply to patch 2/3, you will need to protect this with 
proper locking. You now have at least four events dealing with states and 
buffers allocation (VIDIOC_STREAMON, VIDIOC_STREAMOFF, uvc_function_set_alt 
and uvc_function_disable).

>   memset(_event, 0, sizeof(v4l2_event));
>   v4l2_event.type = UVC_EVENT_DISCONNECT;
>   v4l2_event_queue(>vdev, _event);

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH v2 1/3] usb: gadget: uvc: synchronize streamon/off with uvc_function_set_alt

2018-05-21 Thread Laurent Pinchart
Hi Paul,

Thank you for the patch.

On Tuesday, 24 April 2018 23:59:34 EEST Paul Elder wrote:
> Down the call stack from the ioctl handler for VIDIOC_STREAMON,
> uvc_video_alloc_requests contains a BUG_ON, which in the high level,
> triggers when VIDIOC_STREAMON ioctl is issued without VIDIOC_STREAMOFF
> being issued previously.
> 
> This could be triggered by uvc_function_set_alt 0 racing and
> winning against uvc_v4l2_streamon, or by userspace neglecting to issue
> the VIDIOC_STREAMOFF ioctl.
> 
> To fix this, add two more uvc states: starting and stopping. Use these
> to prevent the racing, and to detect when VIDIOC_STREAMON is issued
> without previously issuing VIDIOC_STREAMOFF.
> 
> Signed-off-by: Paul Elder 
> ---
> Changes in v2: Nothing
> 
>  drivers/usb/gadget/function/f_uvc.c|  8 ++--
>  drivers/usb/gadget/function/uvc.h  |  2 ++
>  drivers/usb/gadget/function/uvc_v4l2.c | 19 +--
>  3 files changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/gadget/function/f_uvc.c
> b/drivers/usb/gadget/function/f_uvc.c index 439eba660e95..9b63b28a1ee3
> 100644
> --- a/drivers/usb/gadget/function/f_uvc.c
> +++ b/drivers/usb/gadget/function/f_uvc.c
> @@ -325,17 +325,19 @@ uvc_function_set_alt(struct usb_function *f, unsigned
> interface, unsigned alt)
> 
>   switch (alt) {
>   case 0:
> - if (uvc->state != UVC_STATE_STREAMING)
> + if (uvc->state != UVC_STATE_STREAMING &&
> + uvc->state != UVC_STATE_STARTING)

Indentation is weird here, uvc should be aligned on the two lines.

>   return 0;
> 
>   if (uvc->video.ep)
>   usb_ep_disable(uvc->video.ep);
> 
> + uvc->state = UVC_STATE_STOPPING;
> +
>   memset(_event, 0, sizeof(v4l2_event));
>   v4l2_event.type = UVC_EVENT_STREAMOFF;
>   v4l2_event_queue(>vdev, _event);
> 
> - uvc->state = UVC_STATE_CONNECTED;
>   return 0;
> 
>   case 1:
> @@ -354,6 +356,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned
> interface, unsigned alt) return ret;
>   usb_ep_enable(uvc->video.ep);
> 
> + uvc->state = UVC_STATE_STARTING;
> +
>   memset(_event, 0, sizeof(v4l2_event));
>   v4l2_event.type = UVC_EVENT_STREAMON;
>   v4l2_event_queue(>vdev, _event);
> diff --git a/drivers/usb/gadget/function/uvc.h
> b/drivers/usb/gadget/function/uvc.h index a64e07e61f8c..afb2eac1f337 100644
> --- a/drivers/usb/gadget/function/uvc.h
> +++ b/drivers/usb/gadget/function/uvc.h
> @@ -131,6 +131,8 @@ enum uvc_state {
>   UVC_STATE_DISCONNECTED,
>   UVC_STATE_CONNECTED,
>   UVC_STATE_STREAMING,
> + UVC_STATE_STARTING,
> + UVC_STATE_STOPPING,

Let's order the states as theyr should normally occur, STARTING should come 
before STREAMING.

>  };
> 
>  struct uvc_device {
> diff --git a/drivers/usb/gadget/function/uvc_v4l2.c
> b/drivers/usb/gadget/function/uvc_v4l2.c index 9a9019625496..fdf02b6987c0
> 100644
> --- a/drivers/usb/gadget/function/uvc_v4l2.c
> +++ b/drivers/usb/gadget/function/uvc_v4l2.c
> @@ -193,6 +193,9 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum
> v4l2_buf_type type) struct uvc_video *video = >video;
>   int ret;
> 
> + if (uvc->state != UVC_STATE_STARTING)
> + return 0;

I would move this check after the next one, as the VIDIOC_STREAMON ioctl 
should fail if the type isn't valid, even if we're already streaming.

Furthermore, shouldn't we silently ignore the UVC_STATE_STREAMING only ? For 
other states, I think we should return an error, as starting the stream isn't 
valid for instance when the state is UVC_STATE_DISCONNECTED.

>   if (type != video->queue.queue.type)
>   return -EINVAL;
> 
> @@ -201,12 +204,13 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum
> v4l2_buf_type type) if (ret < 0)
>   return ret;
> 
> + uvc->state = UVC_STATE_STREAMING;
> +
>   /*
>* Complete the alternate setting selection setup phase now that
>* userspace is ready to provide video frames.
>*/
>   uvc_function_setup_continue(uvc);
> - uvc->state = UVC_STATE_STREAMING;
> 
>   return 0;
>  }
> @@ -217,11 +221,22 @@ uvc_v4l2_streamoff(struct file *file, void *fh, enum
> v4l2_buf_type type) struct video_device *vdev = video_devdata(file);
>   struct uvc_device *uvc = video_get_drvdata(vdev);
>   struct uvc_video *video = >video;
> + int ret;
> +
> + if (uvc->state != UVC_STATE_STOPPING)
> + return 0;

Same comment here, this should go after the next check.

While I think extending the state machine this way makes sense, I believe 
you're introducing race conditions. The VIDIOC_STREAMON and VIDIOC_STREAMOFF 
ioctls can be issued by userspace at any time, completely asynchronously to 
the reception of SET_INTERFACE requests. You 

RE: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Felipe Balbi

Hi,

Yoshihiro Shimoda  writes:

> Hi,
>
>> From: Felipe Balbi, Sent: Monday, May 21, 2018 3:57 PM
>> 
>> Hi,
>> 
>> Yoshihiro Shimoda  writes:
>> > The usb_ep_queue() in printer_write() is possible to call req->complete().
>> > In that case, since tx_complete() calls list_add(>list, 
>> > >tx_reqs),
>> > printer_write() should not call list_add(>list, >tx_reqs_active)
>> > because the transfer has already finished. So, this patch checks
>> > the condition of req->list before adding the list in printer_write().
>> >
>> > Signed-off-by: Yoshihiro Shimoda 
>> > ---
>> >  This issue can be caused by renesas_usbhs udc driver. I'm not sure
>> >  this patch is acceptable or not. So, I marked RFC on this patch.
>> 
>> can you explain this a little more? How do you trigger the problem?
>
> Sure. If printer_write() called usb_ep_queue() with 63 bytes or less data,
> the renesas_usbhs udc driver transfers data as PIO. In this case, the udc
> driver calls usb_gadget_giveback_reuqest() in .queue ops (usbhsg_ep_queue())
> immediately. Then, printer_write() calls list_add(>list, 
> >tx_reqs_active); wrongly.
> After that, if we do rmmod g_printer, 
> WARN_ON(!list_empty(>tx_reqs_active); happens in
> printer_func_unbind() because the list entry is not removed.
>
> < Reference: calltrace (very long though...) >
>   usb_ep_queue(...);  at f_printer.c / printer_write()
>   1-> usbhsg_ep_queue();  at renesas_usbhs/mod_gadget.c
>2-> usbhsg_queue_push();
> 3-> usbhs_pkt_start();at renesas_usbhs/fifo.c
>  4-> usbhsf_pkt_handler();
>   5-> func() = usbhsf_dma_prepare_push();
>6-> goto usbhsf_pio_prepare_push; // Because len is 63
> 7-> usbhsf_pio_prepare_push();
>  8-> usbhsf_pio_try_push();
> 5-> done() = usbhsg_queue_done(); at renesas_usbhs/mod_gadget.c
>6-> __usbsg_queue_pop();
> 7-> usb_gadget_giveback_reuqest();
>  8-> tx_complete();   at f_printer.c
> 9-> list_del_init(>list);
> 9-> list_add(>list, >tx_reqs);
>   list_add(>list, >tx_reqs_active); // Even if the 
> transaction already finished, this driver is possible to add the list to 
> "active".

seems like it would be better to just move this like before
usb_ep_queue():

modified   drivers/usb/gadget/function/f_printer.c
@@ -631,19 +631,19 @@ printer_write(struct file *fd, const char __user *buf, 
size_t len, loff_t *ptr)
return -EAGAIN;
}
 
+   list_add(>list, >tx_reqs_active);
+
/* here, we unlock, and only unlock, to avoid deadlock. */
spin_unlock(>lock);
value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
spin_lock(>lock);
if (value) {
+   list_del(>list);
list_add(>list, >tx_reqs);
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>lock_printer_io);
return -EAGAIN;
}
-
-   list_add(>list, >tx_reqs_active);
-
}
 
spin_unlock_irqrestore(>lock, flags);

-- 
balbi


signature.asc
Description: PGP signature


RE: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Yoshihiro Shimoda
Hi,

> From: Felipe Balbi, Sent: Monday, May 21, 2018 3:57 PM
> 
> Hi,
> 
> Yoshihiro Shimoda  writes:
> > The usb_ep_queue() in printer_write() is possible to call req->complete().
> > In that case, since tx_complete() calls list_add(>list, >tx_reqs),
> > printer_write() should not call list_add(>list, >tx_reqs_active)
> > because the transfer has already finished. So, this patch checks
> > the condition of req->list before adding the list in printer_write().
> >
> > Signed-off-by: Yoshihiro Shimoda 
> > ---
> >  This issue can be caused by renesas_usbhs udc driver. I'm not sure
> >  this patch is acceptable or not. So, I marked RFC on this patch.
> 
> can you explain this a little more? How do you trigger the problem?

Sure. If printer_write() called usb_ep_queue() with 63 bytes or less data,
the renesas_usbhs udc driver transfers data as PIO. In this case, the udc
driver calls usb_gadget_giveback_reuqest() in .queue ops (usbhsg_ep_queue())
immediately. Then, printer_write() calls list_add(>list, 
>tx_reqs_active); wrongly.
After that, if we do rmmod g_printer, 
WARN_ON(!list_empty(>tx_reqs_active); happens in
printer_func_unbind() because the list entry is not removed.

< Reference: calltrace (very long though...) >
usb_ep_queue(...);  at f_printer.c / printer_write()
1-> usbhsg_ep_queue();  at renesas_usbhs/mod_gadget.c
 2-> usbhsg_queue_push();
  3-> usbhs_pkt_start();at renesas_usbhs/fifo.c
   4-> usbhsf_pkt_handler();
5-> func() = usbhsf_dma_prepare_push();
 6-> goto usbhsf_pio_prepare_push; // Because len is 63
  7-> usbhsf_pio_prepare_push();
   8-> usbhsf_pio_try_push();
5-> done() = usbhsg_queue_done();   at renesas_usbhs/mod_gadget.c
 6-> __usbsg_queue_pop();
  7-> usb_gadget_giveback_reuqest();
   8-> tx_complete();   at f_printer.c
9-> list_del_init(>list);
9-> list_add(>list, >tx_reqs);
list_add(>list, >tx_reqs_active); // Even if the 
transaction already finished, this driver is possible to add the list to 
"active".

Best regards,
Yoshihiro Shimoda

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


Re: [PATCH v2 2/3] usb: gadget: uvc: remove delay usb status phase

2018-05-21 Thread Laurent Pinchart
Hi Paul,

Thank you for the patch.

On Tuesday, 24 April 2018 23:59:35 EEST Paul Elder wrote:
> The completion of the usb status phase doesn't need to be delayed
> from uvc_function_set_alt to uvc_v4l2_streamon/off.
> Remove USB_GADGET_DELAYED_STATUS and usb_composite_setup_delay from
> these two, respectively.

Did you mean uvc_function_setup_continue() ?

In addition to Roger's comment regarding the uvc_function_setup_continue() 
function that can now be removed (don't forget the header files), I think the 
commit message would benefit from more details. How about the following ?

usb: gadget: uvc: Don't delay the status phase of SET_INTERFACE requests

Reception of a SET_INTERFACE request with a non-zero alternate setting
signals the start of the video stream. The gadget has to enable the
video streaming endpoint and to signal stream start to userspace, in
order to start receiving video frames to transmit over USB. As userspace
can be slow to react, the UVC function driver delays the status phase of
the SET_INTERFACE control transfer until userspace is ready.

The status phase is delayed by returning USB_GADGET_DELAYED_STATUS from
the function's .set_alt() handler. This creates a race condition as the
userspace application could process the stream start event before the
composite layer processes the USB_GADGET_DELAYED_STATUS return value.
The race has been observed in practice, and can't be solved without a
change to the USB_GADGET_DELAYED_STATUS API.

Fortunately the UVC function driver doesn't strictly require delaying
the status phase, as the only requirement from a USB point of view is
that the streaming endpoint must be enabled before the status phase
completes, and that is already guaranteed by the current code. We can
thus complete the status phase synchronously, removing the race
condition at the same time.

Without delaying the status phase the host will likely start issuing
isochronous transfers before we queue the first USB requests. The UDC
will reply with NAKs which should be handled properly by the host. If
this ends up causing issues another option will be to modify the status
phase delay API to fix the race condition.

> Signed-off-by: Paul Elder 
> ---
> Changes in v2:
>   1. Remove delay usb status phase
> 
>  drivers/usb/gadget/function/f_uvc.c| 3 ++-
>  drivers/usb/gadget/function/uvc_v4l2.c | 6 --
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/usb/gadget/function/f_uvc.c
> b/drivers/usb/gadget/function/f_uvc.c index 9b63b28a1ee3..fa34dcbe1197
> 100644
> --- a/drivers/usb/gadget/function/f_uvc.c
> +++ b/drivers/usb/gadget/function/f_uvc.c
> @@ -361,7 +361,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned
> interface, unsigned alt) memset(_event, 0, sizeof(v4l2_event));
>   v4l2_event.type = UVC_EVENT_STREAMON;
>   v4l2_event_queue(>vdev, _event);
> - return USB_GADGET_DELAYED_STATUS;
> +
> + return 0;
> 
>   default:
>   return -EINVAL;
> diff --git a/drivers/usb/gadget/function/uvc_v4l2.c
> b/drivers/usb/gadget/function/uvc_v4l2.c index fdf02b6987c0..138d95b3b8d1
> 100644
> --- a/drivers/usb/gadget/function/uvc_v4l2.c
> +++ b/drivers/usb/gadget/function/uvc_v4l2.c
> @@ -206,12 +206,6 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum
> v4l2_buf_type type)
> 
>   uvc->state = UVC_STATE_STREAMING;
> 
> - /*
> -  * Complete the alternate setting selection setup phase now that
> -  * userspace is ready to provide video frames.
> -  */
> - uvc_function_setup_continue(uvc);
> -
>   return 0;
>  }

-- 
Regards,

Laurent Pinchart



--
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: usb: dwc2: gadget: Fix memory leak in dwc2_gadget_init()

2018-05-21 Thread Felipe Balbi

Hi,

Grigor Tovmasyan  writes:
> Hi Felipe,
>
> Please drop this patch from your next branch.
> I will provide another fix based on Marek's suggestion.

this time I'll rebase my 'next' branch. Next time, make sure this
doesn't happen anymore as I like my 'next' to be immutable.

-- 
balbi


signature.asc
Description: PGP signature


Re: [PATCH/RFC] usb: gadget: function: printer: avoid wrong list handling in printer_write()

2018-05-21 Thread Felipe Balbi

Hi,

Yoshihiro Shimoda  writes:
> The usb_ep_queue() in printer_write() is possible to call req->complete().
> In that case, since tx_complete() calls list_add(>list, >tx_reqs),
> printer_write() should not call list_add(>list, >tx_reqs_active)
> because the transfer has already finished. So, this patch checks
> the condition of req->list before adding the list in printer_write().
>
> Signed-off-by: Yoshihiro Shimoda 
> ---
>  This issue can be caused by renesas_usbhs udc driver. I'm not sure
>  this patch is acceptable or not. So, I marked RFC on this patch.

can you explain this a little more? How do you trigger the problem?

-- 
balbi


signature.asc
Description: PGP signature