Re: [PATCH] usb: cdc-wdm: avoid hanging on zero length reads
On Fri, 2013-12-20 at 14:07 +0100, Bjørn Mork wrote: > commit 73e06865ead1 ("USB: cdc-wdm: support back-to-back > USB_CDC_NOTIFY_RESPONSE_AVAILABLE notifications") implemented > queued response handling. This added a new requirement: The read > urb must be resubmitted every time we clear the WDM_READ flag if > the response counter indicates that the device is waiting for a > read. > > Fix by factoring out the code handling the WMD_READ clearing and > possible urb submission, calling it everywhere we clear the flag. > > Without this fix, the driver ends up in a state where the read urb > is inactive, but the response counter is positive after a zero > length read. This prevents the read urb from ever being submitted > again and the driver appears to be hanging. > > Fixes: 73e06865ead1 ("USB: cdc-wdm: support back-to-back > USB_CDC_NOTIFY_RESPONSE_AVAILABLE notifications") > Cc: Greg Suarez > Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum -- 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
Project
May I request for your partnership to execute a project in Asia, revert if interested -- 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
[RFC PATCH 2/4] usb: convert khubd to a workqueue
Both a cleanup, as khubd open codes several facilities that are provided by workqueue, and a prepation for running port resume events in khubd context. Running port recovery in khubd context allows coalescing / ordering port recovery actions with device recovery and it guarantees that hub_events is idle for the duration of a recovery event. Signed-off-by: Dan Williams --- drivers/usb/core/hub.c | 135 +++- drivers/usb/core/hub.h |4 - 2 files changed, 31 insertions(+), 108 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 48d5c8fff77f..83abaecfabfe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -22,11 +22,10 @@ #include #include #include -#include #include -#include #include #include +#include #include #include @@ -53,14 +52,7 @@ static inline int hub_is_superspeed(struct usb_device *hdev) * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ static DEFINE_SPINLOCK(device_state_lock); -/* khubd's worklist and its lock */ -static DEFINE_SPINLOCK(hub_event_lock); -static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ - -/* Wakes up khubd */ -static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); - -static struct task_struct *khubd_task; +static struct workqueue_struct *khubd_wq; /* cycle leds on hubs that aren't blinking for attention */ static bool blinkenlights = 0; @@ -577,18 +569,12 @@ static int hub_port_status(struct usb_hub *hub, int port1, static void kick_khubd(struct usb_hub *hub) { - unsigned long flags; - - spin_lock_irqsave(&hub_event_lock, flags); - if (!hub->disconnected && list_empty(&hub->event_list)) { - list_add_tail(&hub->event_list, &hub_event_list); + struct usb_interface *intf = to_usb_interface(hub->intfdev); - /* Suppress autosuspend until khubd runs */ - usb_autopm_get_interface_no_resume( - to_usb_interface(hub->intfdev)); - wake_up(&khubd_wait); - } - spin_unlock_irqrestore(&hub_event_lock, flags); + /* Suppress autosuspend until khubd runs */ + usb_autopm_get_interface_no_resume(intf); + if (!queue_work(khubd_wq, &hub->event_work)) + usb_autopm_put_interface_async(intf); } void usb_kick_khubd(struct usb_device *hdev) @@ -1591,10 +1577,8 @@ fail_keep_maxchild: return ret; } -static void hub_release(struct kref *kref) +static void hub_release(struct usb_hub *hub) { - struct usb_hub *hub = container_of(kref, struct usb_hub, kref); - usb_put_intf(to_usb_interface(hub->intfdev)); kfree(hub); } @@ -1607,19 +1591,13 @@ static void hub_disconnect(struct usb_interface *intf) struct usb_device *hdev = interface_to_usbdev(intf); int i; - /* Take the hub off the event list and don't let it be added again */ - spin_lock_irq(&hub_event_lock); - if (!list_empty(&hub->event_list)) { - list_del_init(&hub->event_list); - usb_autopm_put_interface_no_suspend(intf); - } - hub->disconnected = 1; - spin_unlock_irq(&hub_event_lock); - /* Disconnect all children and quiesce the hub */ hub->error = 0; hub_quiesce(hub, HUB_DISCONNECT); + if (cancel_work_sync(&hub->event_work)) + usb_autopm_put_interface(intf); + usb_set_intfdata (intf, NULL); for (i = 0; i < hdev->maxchild; i++) @@ -1636,9 +1614,10 @@ static void hub_disconnect(struct usb_interface *intf) kfree(hub->buffer); pm_suspend_ignore_children(&intf->dev, false); - kref_put(&hub->kref, hub_release); + hub_release(hub); } +static void hub_event(struct work_struct *); static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1728,8 +1707,7 @@ descriptor_error: return -ENOMEM; } - kref_init(&hub->kref); - INIT_LIST_HEAD(&hub->event_list); + INIT_WORK(&hub->event_work, hub_event); hub->intfdev = &intf->dev; hub->hdev = hdev; INIT_DELAYED_WORK(&hub->leds, led_work); @@ -4662,45 +4640,17 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, return connect_change; } -static void hub_events(void) +static void hub_event(struct work_struct *w) { - struct list_head *tmp; - struct usb_device *hdev; - struct usb_interface *intf; - struct usb_hub *hub; - struct device *hub_dev; - u16 hubstatus; - u16 hubchange; - u16 portstatus; - u16 portchange; - int i, ret; - int connect_change, wakeup_change; - - /* -* We restart the list every time to avoid a deadlock with -* deleting hubs downstream from this one. This should be -* safe since we delete the hub from th
[RFC PATCH 3/4] usb: reset resume in khubd context
Preparation patch for synchronizing port warm reset recovery with khubd and child device resume recovery. End goal is to ensure khubd does not run while port recovery in-progress (as the port is known to appear disconnected), and also arrange for any optional warm resets to complete before usb_port_resume() runs. Signed-off-by: Dan Williams --- drivers/usb/core/generic.c | 23 --- drivers/usb/core/hub.c | 11 +-- drivers/usb/core/usb.c |1 + drivers/usb/core/usb.h |6 ++ include/linux/usb.h|3 +++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index acbfeb0a0119..2925db4e3859 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -216,6 +216,16 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) return rc; } +/* port resume runs in khubd context to coalesce port recovery + * actions and synchronize with hub_events + */ +void usb_port_resume_work(struct work_struct *w) +{ + struct usb_device *udev = container_of(w, typeof(*udev), resume_work); + + udev->pm_result = usb_port_resume(udev, udev->pm_msg); +} + static int generic_resume(struct usb_device *udev, pm_message_t msg) { int rc; @@ -225,10 +235,17 @@ static int generic_resume(struct usb_device *udev, pm_message_t msg) * so we have to start up their downstream HC-to-USB * interfaces manually by doing a bus (or "global") resume. */ - if (!udev->parent) + if (!udev->parent) { rc = hcd_bus_resume(udev, msg); - else - rc = usb_port_resume(udev, msg); + } else { + /* See: usb_port_resume_work */ + udev->pm_msg = msg; + usb_kick_resume(udev); + flush_work(&udev->resume_work); + + rc = udev->pm_result; + } + return rc; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 83abaecfabfe..e7b2efef537d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -585,6 +585,11 @@ void usb_kick_khubd(struct usb_device *hdev) kick_khubd(hub); } +void usb_kick_resume(struct usb_device *dev) +{ + queue_work(khubd_wq, &dev->resume_work); +} + /* * Let the USB core know that a USB 3.0 device has sent a Function Wake Device * Notification, which indicates it had initiated remote wakeup. @@ -3186,10 +3191,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) if (status == 0 && !port_is_suspended(hub, portstatus)) goto SuspendCleared; - /* dev_dbg(hub->intfdev, "resume port %d\n", port1); */ - - set_bit(port1, hub->busy_bits); - /* see 7.1.7.7; affects power usage, but not budgeting */ if (hub_is_superspeed(hub->hdev)) status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0); @@ -3229,8 +3230,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) } } - clear_bit(port1, hub->busy_bits); - status = check_port_resume_type(udev, hub, port1, status, portchange, portstatus); if (status == 0) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4d1144990d4c..def10e4e1e0e 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -436,6 +436,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, atomic_set(&dev->urbnum, 0); INIT_LIST_HEAD(&dev->ep0.urb_list); + INIT_WORK(&dev->resume_work, usb_port_resume_work); dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; /* ep0 maxpacket comes later, from device descriptor */ diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index c49383669cd8..ea060cce6a0c 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -50,6 +50,7 @@ static inline unsigned usb_get_max_power(struct usb_device *udev, } extern void usb_kick_khubd(struct usb_device *dev); +extern void usb_kick_resume(struct usb_device *dev); extern int usb_match_one_id_intf(struct usb_device *dev, struct usb_host_interface *intf, const struct usb_device_id *id); @@ -79,6 +80,7 @@ extern int usb_resume_complete(struct device *dev); extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg); extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); +extern void usb_port_resume_work(struct work_struct *w); #else @@ -92,6 +94,10 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg) return 0; } +static inline void usb_port_resume_work(struct work_struct *w) +{ +} + #endif #ifdef CONFIG_PM_RUNTIME diff --git a/include/linux/usb.h b/include/linux/usb.h index 851917571a9e..fecd02495269 100644 --
[RFC PATCH 0/4] port warm reset recovery
Both the suspected quirky Synopsys xHC [1] and the port-pm-runtime-resume path need to issue warm resets to reliably bring ports back to an operational state. Per Alan's observation this also arranges for these warm resets to be queued asynchronously. Per my previous testing I found cases where khubd takes actions on ports that are known to still be in recovery (unintended disconnects). This set mitigates those interactions by pushing resume operations into khubd context by making khubd a workqueue. Please focus review on patch 4. usb_port_resume() running in khubd context may turn out to not be necessary, but I need to test more. The expected sequence of events for the hub_resume case is: 1/ hub_resume 2/ scan through all ports and queue (async) port warm resets if necessary 3/ kick_khubd 4/ hub_event() syncs all in-flight resets 5/ child device resume proceeds in parallel with hub_event as before (child device resume also syncs in-flight warm resets if it happens to occur before hub_event() runs) The sequence of events in the pm-runtime case is: 1/ usb_port_runtime_resume queues an async warm reset, and requests a reset-resume of the child device if present 2/ child device resume syncs the in-flight reset and optionally does reset-resume Note that this only implements the reset for the pm-runtime case. xhci_port_resume() is where the xHC quirk can be placed to do the same for the hub_resume() case. Only lightly tested. Looking for positive feedback before rebasing the rest of the port power rework on top of this approach. [1]: http://marc.info/?l=linux-usb&m=138683173421509&w=2 --- Dan Williams (4): usb: introduce hub->resume_bits and HCD_FLAG_RESET_RESUME usb: convert khubd to a workqueue usb: reset resume in khubd context usb: port pm recovery drivers/usb/core/driver.c| 40 +++- drivers/usb/core/generic.c | 23 - drivers/usb/core/hub.c | 211 +- drivers/usb/core/hub.h | 25 + drivers/usb/core/port.c | 80 +++- drivers/usb/core/usb.c |1 drivers/usb/core/usb.h |8 ++ drivers/usb/host/xhci-pci.c |1 drivers/usb/host/xhci-plat.c |1 drivers/usb/host/xhci.c |8 ++ drivers/usb/host/xhci.h |2 include/linux/usb.h |6 + include/linux/usb/hcd.h |7 + 13 files changed, 235 insertions(+), 178 deletions(-) ...not that I expect any review over the weekend, but wanted to get this out before heading home. -- Dan One more note, the udev->reset_resume to hub->resume_bit conversion also needs the below two patches, but I left them out of the series for now to keep the patch count lower. commit e724d476af11c1066d425fa64d2fedcc0a4415b0 Author: Dan Williams Date: Wed Dec 18 14:43:47 2013 -0800 p54usb: set USB_QUIRK_RESET_RESUME ...rather than scheduling a single shot at probe. Found by inspection not sure if this will cause regressions since only the first resume is guaranteed to trigger a reset. I.e. this device may now see more resets. Cc: Christian Lamparter Cc: linux-wirel...@vger.kernel.org Signed-off-by: Dan Williams diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index e328d3058c41..f27674c46c1b 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -1035,10 +1035,8 @@ static int p54u_probe(struct usb_interface *intf, priv->common.open = p54u_open; priv->common.stop = p54u_stop; if (recognized_pipes < P54U_PIPE_NUMBER) { -#ifdef CONFIG_PM /* ISL3887 needs a full reset on resume */ - udev->reset_resume = 1; -#endif /* CONFIG_PM */ + udev->quirks |= USB_QUIRK_RESET_RESUME; err = p54u_device_reset(dev); priv->hw_type = P54U_3887; commit 0dda95bd66c4a59d4c8dc247a998bbed658a26c4 Author: Dan Williams Date: Wed Dec 18 14:32:22 2013 -0800 ath9k_hif_usb: set USB_QUIRK_RESET_RESUME ...rather than scheduling a single shot at probe. Found by inspection not sure if this will cause regressions since only the first resume is guaranteed to trigger a reset. I.e. this device may now see more resets. Cc: Luis R. Rodriguez Cc: Jouni Malinen Cc: Vasanthakumar Thiagarajan Cc: Senthil Balasubramanian Cc: linux-wirel...@vger.kernel.org Cc: ath9k-de...@lists.ath9k.org Signed-off-by: Dan Williams diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 6d5d716adc1b..44e5b3ee2938 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -1205,9 +1205,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, hif_dev->udev = udev; hif_dev->interface = interface; hif_dev->usb_device_id = id; -#ifdef CON
[RFC PATCH 1/4] usb: introduce hub->resume_bits and HCD_FLAG_RESET_RESUME
Preparation for making reset_resume a port event. End goal is to trigger port recovery actions like warm reset when recovering a port power session. A usb_device may not be attached to the port, so the flag for requesting reset service can not be contained within the usb_device. Signed-off-by: Dan Williams --- drivers/usb/core/driver.c | 40 +++- drivers/usb/core/hub.c| 29 - drivers/usb/core/hub.h|2 ++ include/linux/usb.h |1 - include/linux/usb/hcd.h |1 + 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 8d989b1d3dc5..6447bfc3e4c1 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -29,7 +29,7 @@ #include #include -#include "usb.h" +#include "hub.h" /* @@ -1088,6 +1088,36 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) return status; } +#define clear_reset_resume(udev) op_reset_resume(udev, 0) +#define set_reset_resume(udev) op_reset_resume(udev, 1) +#define test_reset_resume(udev) op_reset_resume(udev, 2) +static int op_reset_resume(struct usb_device *udev, int op) +{ + unsigned long *addr; + int nr, rc = 0; + + if (udev->parent) { + struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); + + addr = hub->resume_bits; + nr = udev->portnum; + } else { + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + addr = &hcd->flags; + nr = HCD_FLAG_RESET_RESUME; + } + + if (op == 0) + clear_bit(nr, addr); + else if (op == 1) + set_bit(nr, addr); + else + rc = test_bit(nr, addr); + + return rc; +} + static int usb_resume_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver*udriver; @@ -1110,7 +1140,7 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg) &udev->bus->hs_companion->root_hub->dev); if (udev->quirks & USB_QUIRK_RESET_RESUME) - udev->reset_resume = 1; + set_reset_resume(udev); udriver = to_usb_device_driver(udev->dev.driver); status = udriver->resume(udev, msg); @@ -1318,7 +1348,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) udev->can_submit = 1; /* Resume the device */ - if (udev->state == USB_STATE_SUSPENDED || udev->reset_resume) + if (udev->state == USB_STATE_SUSPENDED || test_reset_resume(udev)) status = usb_resume_device(udev, msg); /* Resume the interfaces */ @@ -1326,7 +1356,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { intf = udev->actconfig->interface[i]; usb_resume_interface(udev, intf, msg, - udev->reset_resume); +test_reset_resume(udev)); } } usb_mark_last_busy(udev); @@ -1334,7 +1364,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) done: dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); if (!status) - udev->reset_resume = 0; + clear_reset_resume(udev); return status; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 162e94dbed53..48d5c8fff77f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1176,9 +1176,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) } else if (udev->persist_enabled) { struct usb_port *port_dev = hub->ports[port1 - 1]; -#ifdef CONFIG_PM - udev->reset_resume = 1; -#endif + set_bit(port1, hub->resume_bits); /* Don't set the change_bits when the device * was powered off. */ @@ -2784,9 +2782,10 @@ static int check_port_resume_type(struct usb_device *udev, /* Can't do a normal resume if the port isn't enabled, * so try a reset-resume instead. */ - else if (!(portstatus & USB_PORT_STAT_ENABLE) && !udev->reset_resume) { + else if (!(portstatus & USB_PORT_STAT_ENABLE) +&& !test_bit(port1, hub->resume_bits)) { if (udev->persist_enabled) - udev->reset_resume = 1; + set_bit(port1, hub->resume_bits); else status = -ENODEV; } @@ -2795,7 +2794,7 @@ static int check_port_resume_type(struct usb_device *udev, dev_dbg(hub->intfdev, "port %d stat
[RFC PATCH 4/4] usb: port pm recovery
Implement port power recovery via queuing warm reset requests in khubd context. There are two new cases where we want to trigger a warm reset to a port: 1/ Buggy xHCs that do not propagate warm reset to child ports when reset-resuming the root hub. [1] [hub_activate] 2/ Unconditionally when recovering a powered down port from pm_runtime_suspend. [usb_port_runtime_resume] In case (1), where we are presumably resetting all ports on the root hub we do not want to wait serially wait for each of those resets to complete. We arrange for the ports to be recovered asynchronously. Waiting for port recovery occurs if hub_event() is triggered or if a port has a child device and that device is resumed. In case (2) we do not want khubd to ever interpret a pm runtime powered down port as disconnected. Prior to this patch the code was getting lucky to clear the connection change event on port-power off and mitigate hub_event() from processing a disconnect. This is now explicit with hub->poweroff_bits. The ->poweroff_bits also gate hub_activate() from requesting port power recovery if the port power policy is off. Recovery in that case is queued via usb_port_runtime_resume(). Later cleanups: 1/ Asynchronous operation is sub-optimal in this patch because a usb_port is not the device model parent of its child usb_device, even though it is a power-management parent of the child device. Rectifying this allows all port recovery actions to be queued prior to starting usb_port_resume() for each attached child. 2/ The ->power_is_on flag is superseded by poweroff_bits and can be removed. [1]: http://marc.info/?l=linux-usb&m=138683173421509&w=2 Cc: Julius Werner Cc: Vikas Sajjan Signed-off-by: Dan Williams --- drivers/usb/core/generic.c |2 + drivers/usb/core/hub.c | 38 ++-- drivers/usb/core/hub.h | 19 ++ drivers/usb/core/port.c | 80 +- drivers/usb/core/usb.h |2 + drivers/usb/host/xhci-pci.c |1 + drivers/usb/host/xhci-plat.c |1 + drivers/usb/host/xhci.c |8 drivers/usb/host/xhci.h |2 + include/linux/usb.h |2 + include/linux/usb/hcd.h |6 +++ 11 files changed, 117 insertions(+), 44 deletions(-) diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 2925db4e3859..3da29cd8ca54 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -217,7 +217,7 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) } /* port resume runs in khubd context to coalesce port recovery - * actions and synchronize with hub_events + * actions and synchronize with hub_event */ void usb_port_resume_work(struct work_struct *w) { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e7b2efef537d..c4763f109113 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -590,6 +590,11 @@ void usb_kick_resume(struct usb_device *dev) queue_work(khubd_wq, &dev->resume_work); } +void usb_kick_port_resume(struct usb_port *port_dev) +{ + queue_work(khubd_wq, &port_dev->resume_work); +} + /* * Let the USB core know that a USB 3.0 device has sent a Function Wake Device * Notification, which indicates it had initiated remote wakeup. @@ -1083,6 +1088,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) struct usb_device *udev = hub->ports[port1 - 1]->child; u16 portstatus, portchange; + if (test_bit(port1, hub->poweroff_bits)) + continue; + portstatus = portchange = 0; status = hub_port_status(hub, port1, &portstatus, &portchange); if (udev || (portstatus & USB_PORT_STAT_CONNECTION)) @@ -1168,6 +1176,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) struct usb_port *port_dev = hub->ports[port1 - 1]; set_bit(port1, hub->resume_bits); + usb_kick_port_resume(port_dev); /* Don't set the change_bits when the device * was powered off. */ @@ -2712,6 +2721,21 @@ done: return status; } +int usb3_port_link_recover(struct usb_port *port_dev) +{ + int port1 = port_dev->portnum; + struct device *dev = &port_dev->dev; + struct usb_device *hdev = to_usb_device(dev->parent->parent); + struct usb_hub *hub = usb_hub_to_struct_hub(hdev); + + if (!hub) + return -EIO; + + /* trigger a warm reset to recover from power session loss events */ + return hub_port_reset(hub, port1, NULL, HUB_LONG_RESET_TIME, true); +} +EXPORT_SYMBOL_GPL(usb3_port_link_recover); + /* Check if a port is power on */ static int port_is_power_on(struct usb_hub *hub, unsigned portstatus) { @@ -3186,6 +3210,8 @@ int usb_port_resum
Re: [PATCH] USB: core: remove CONFIG_USB_DEBUG usage
On Fri, Dec 20, 2013 at 09:47:53PM -0500, Alan Stern wrote: > On Fri, 20 Dec 2013, Greg Kroah-Hartman wrote: > > > > > /* Check that the pipe's type matches the endpoint's type */ > > > > if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) > > > > > > It looks as though it ought to be possible to make that check: > > > if (unlikely(xfertype != urb->pipe->valid_xfertype)) > > > > You should almost never use unlikely() on your own, in a driver, as the > > compiler should make better code without it. > > Is that really true? If it is, what point is there in having the > likely()/unlikely() macros in the first place? At this point in time, with modern processors and the huge pipelines that they have, almost nothing. Andi Kleen did a bunch of benchmarks a few years ago that show that removing them all makes things work better, and we, as programmers, usually get the "guess" wrong. Maybe, in the scheduler, or on a _very_ hot path in the kernel (like locks), that can be properly benchmarked and validated, can they make a difference. But in USB, with our line speeds, it's not an issue. 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: "EHCI: BIOS handoff failed (BIOS bug?) 01010001" on Celeron N2805 (Bay Trail) / Gateway LT41P
On Thu, 19 Dec 2013, Ken Harris wrote: > David: > > I'm having trouble getting USB working on my Gateway LT41P laptop. > > I get an error message " EHCI: BIOS handoff failed (BIOS bug?) > 01010001" and I wonder if you can suggest any fixes or workarounds. > The EHCI controller works on MS Windows 8.1. This machine has an xHCI > controller as well, but there is no sign of that in the logs. > > Attached is a dmesg output with various dynamic debug options. > > Thanks, > Ken David Brownell passed away more than two years ago. 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: core: remove CONFIG_USB_DEBUG usage
On Fri, 20 Dec 2013, Greg Kroah-Hartman wrote: > > > /* Check that the pipe's type matches the endpoint's type */ > > > if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) > > > > It looks as though it ought to be possible to make that check: > > if (unlikely(xfertype != urb->pipe->valid_xfertype)) > > You should almost never use unlikely() on your own, in a driver, as the > compiler should make better code without it. Is that really true? If it is, what point is there in having the likely()/unlikely() macros in the first place? 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 v1] xhci: Switch Intel Lynx Point ports to EHCI on shutdown
On Fri, Dec 20, 2013 at 12:41:11PM +0200, Denis Turischev wrote: > > Also, which kernel are you experiencing this issue on? In 3.12, I > > queued a separate patch to deal with spurious reboot issues on Lynx > > Point: > > > > commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 > Sorry, I indeed tested not on the latest kernel version, Ubuntu 3.13-rc3 has > this patch and it works > for me. What does "Ubuntu 3.13-rc3" mean? Where did you get your kernel from? Also, do you have an HP system, or is this a different vendor? Sarah Sharp -- 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: xhci_hcd and Canon Lide 110 not playing well together
On Wed, Dec 18, 2013 at 09:59:33PM +0100, Matthias Bläsing wrote: > Hey all, > > On Fr, 2013-12-13 at 17:53 +0100, Holger Hans Peter Freyther wrote: > > On Tue, May 28, 2013 at 07:40:57PM +0200, Holger Hans Peter Freyther wrote: > > > > Is there a timeline when you think this could be fixed? > > > > > > I tried with 3.10.x and 3.12.5 and the symptoms remain the same. The first > > time it is working, the second time the scanning does not start. The scanner > > is still working fine on other machines (with the identical cable). > > > > as I'm facing a similar problem (Canon Lide, though 25 instead of 110), > I would also like to know if there are news about this. See > > > http://thread.gmane.org/gmane.linux.usb.general/99815 > > for details about the hardware. If something is missing I'll try to > provide it. Its strange, that the same hardware (notebook and scanner) > works on one port, but not on the other). > > I tried again today and all physical ports I can access are either > connected to Bus 03 (I suspect, that Bus 04 and Bus 03 are the same, > only differing in their speed) or Bus 02. > > Bus 02 (Driver=ehci-pci/2p, 480M) works, Bus 03 (Driver=xhci_hcd/4p, > 480M) fails. > > Any ideas? I still don't know exactly what's wrong with those particular scanners. usbmon bus traces haven't helped me figure out what's wrong. There are two potential outstanding issues that may (or may not) be the problem. Patches to fix those issues have been sent out, but the original submitters haven't followed up on either sending a second revision, or responding with whether a modified patch helped. The first one fixes an issue where userspace tries to reset a USB endpoint when it's not actually halted: http://marc.info/?l=linux-usb&m=138116117104619&w=2 The second one fixes an issue with the xHCI driver not reporting a zero-length control transfer properly: http://marc.info/?l=linux-usb&m=138247042431789&w=2 Try applying them to the latest kernel and see if they fix your issue. I suspect the first one might. If it doesn't, remove that patch and try the second one. If neither one work, I'm not sure what else to try. Sarah Sharp -- 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: "EHCI: BIOS handoff failed (BIOS bug?) 01010001" on Celeron N2805 (Bay Trail) / Gateway LT41P
On Wed, Dec 18, 2013 at 12:00 AM, Ken Harris wrote: > On Tue, Dec 17, 2013 at 6:47 PM, Ken Harris wrote: >> On Tue, Dec 17, 2013 at 5:33 PM, Ken Harris wrote: >>> On Tue, Dec 17, 2013 at 1:03 PM, Sarah Sharp >>> wrote: >>> > On Tue, 17 Dec 2013, Ken Harris wrote: >>> > > Sebastien: > > > > Thanks for the info. I just tried Linux 3.13.0-0.rc3.git5.1.fc21.i686 > > (from Fedora rawhide) and I still get the same error messages and USB > > still doesn't work. I saw a post about Atom Z3740D (Bay Trail-T) in a > > Dell Venue 8 Pro, and his USB works OK (but seems to use the xhci_hcd > > driver : > > > Whereas my Gateway LT41P uses ehci & ohci >>> Are you enabling CONFIG_USB_XHCI_HCD in your .config? Maybe the BIOS expects your OS to switch the ports over to xHCI, but you don't have the driver compiled? >>> If you do have CONFIG_USB_XHCI_HCD turned on for 3.13, please make sure CONFIG_USB_DEBUG is turned on as well, and send me the resulting dmesg, starting from boot. That should let me see which (if any) ports are being switched over from EHCI to xHCI. >>> Other things to look for in your BIOS settings are things labeled "xHCI mode". It may have options like "enabled", "disabled", "Auto", or "Smart Auto". You want it to be set to either "enabled" or one of the "auto" options. Sarah Sharp >>> >>> Sarah ! >>> >>> Thanks for looking at this. >>> >>> Yes, Fedora has CONFIG_USB_XHCI_HCD=y . When you say, "switch the >>> ports over to xHCI" ... I assume your mean this patch : >>> >>> [PATCH] xhci: Add BayTrail to list of Intel switchable hosts ( >>> http://www.spinics.net/lists/linux-usb/msg86204.html ). >>> >>> I don't see CONFIG_USB_DEBUG set in Fedora, but they do distribute >>> debug kernels (eg : kernel-PAEdebug-3.11.10-301.fc20.i686 ), so >>> perhaps that includes setting CONFIG_USB_DEBUG ? My original post has >>> the output of a debug kernel : >>> http://www.spinics.net/lists/linux-usb/msg99549.html . >>> >>> If that's not good enough, I can try to compile a kernel with >>> CONFIG_USB_DEBUG, but it looks like there is no "xHCI switch" code in >>> Fedora: >>> >>> From my (noobish) reading of the Fedora source ( >>> http://mirrors.kernel.org/fedora/development/rawhide/source/SRPMS/k/kernel-3.13.0-0.rc3.git5.1.fc21.src.rpm >>> : linux-3.12 patch-3.13-rc3 patch-3.13-rc3-git5 ), I don't see any >>> reference to the switchable code (ie : 'find -type f |xargs egrep >>> "PCI_DEVICE_ID_INTEL_LYNX_POINT|intel_switchabl"' returns nothing). >>> >>> FYI, I filed a Redhat bug : >>> https://bugzilla.redhat.com/show_bug.cgi?id=1039245 >>> >>> FYI, my BIOS doesn't have any USB options (just AHCI). >>> >>> FYI, the Dell Venue 8 Pro user (adam) is also using Fedora, but I >>> suspect that his BIOS has enabled xHCI, so he doesn't need the "xHCI >>> switchable" code. >>> >>> I haven't built a kernel in a while, but I can try to apply the patch >>> and see if that fixed the problem. >>> >>> Thanks again, >>> Ken >> >> Oops, >> >> I missed the newer "xHCI switch" patch : "Intel xhci: refactor >> EHCI/xHCI port switching" ( >> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=26b76798e0507429506b93cd49f8c4cfdab06896 >> ). That code is in Fedora 3.13-rc3-git5 source : >> > >> I tried kernel-PAEdebug-3.13.0-0.rc4.git0.1.fc21.i686 , but there is >> nothing about xhci (attached) >> >> What now? Perhaps I should try to compile with CONFIG_USB_DEBUG ? >> >> Thanks, >> Ken > > Sarah: > > I turned on "dynamic debug" and got a few more messages from ehci_hcd > , ehci-pci, ohci_hcd (see attached). > > FYI, my addition to the cmdline was : dyndbg="module xhci_hcd +p ; > module ehci_hcd +p ; module uhci_hcd +p ; module ohci_hcd +p ; module > ehci_pci +p ; module ohci_pci +p ; module pci_quirks +p" > > If there are other modules you'd like to see, let me know. > > FYI, there seems to be a bug in grub2 in Fedora (it transforms " " > into "\x20") , so I had to use gummiboot. > > Cheers, > Ken I noticed this message in dmesg : Some PCI device resources are unassigned, try booting with pci=realloc So I added "pci=realloc", but I still get : pci :00:1c.0: BAR 15: can't assign mem pref (size 0x20) pci :00:1c.2: BAR 14: can't assign mem (size 0x20) pci :00:1c.2: BAR 15: can't assign mem pref (size 0x20) pci :00:1c.0: BAR 15: can't assign mem pref (size 0x40) pci :00:1c.2: BAR 14: can't assign mem (size 0x40) pci :00:1c.2: BAR 15: can't assign mem pref (size 0x40) pci :00:1c.0: BAR 15: can't assign mem pref (size 0x20) pci :00:1c.2: BAR 14: can't assign mem (size 0x20) pci :00:1c.2: BAR 15: can't assign mem pref (size 0x20) Could this be the reason that the xHCI controller doesn't show up ? -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo
[GIT PULL] xhci: Cleanups, non-urgent fixes for 3.14.
The following changes since commit 3d724fa513cd1bd06d3457ccda36941f3606d048: USB: emi62: Provide the correct bitstream firmware (2013-12-10 22:38:45 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci.git tags/for-usb-next-2013-12-20 for you to fetch changes up to 9005355af23856c55a5538c9024355785424821b: usb: xhci: Check for XHCI_PLAT in xhci_cleanup_msix() (2013-12-19 13:23:56 -0800) xhci: Cleanups, non-urgent fixes for 3.14. Happy Holidays, Greg! Here's four patches to be queued to usb-next for 3.14. One adds a module parameter to the xHCI driver to allow users to enable xHCI quirks without recompiling their kernel, which you've already said is fine. The second patch is a bug fix for new usbtest code that's only in usb-next. The third patch is simple cleanup. The last patch is a non-urgent bug fix for xHCI platform devices. The bug has been in the code since 3.9. You've been asking me to hold off on non-urgent bug fixes after -rc4/-rc5, so it can go into usb-next, and be backported to stable once 3.14 is out. These have all been tested over the past week. I did run across one oops, but it turned out to be a bug in 3.12, and therefore not related to any of these patches. Please queue these for usb-next and 3.14. Thanks, Sarah Sharp Jack Pham (1): usb: xhci: Check for XHCI_PLAT in xhci_cleanup_msix() Lin Wang (1): xhci: Remove unused variable 'addr' in inc_deq() and inc_enq(). Sarah Sharp (1): usbtest: Fix BOS control test for USB 2.01 devices. Takashi Iwai (1): xhci: Add quirks module option drivers/usb/host/xhci-ring.c |6 -- drivers/usb/host/xhci.c |9 + drivers/usb/misc/usbtest.c |2 +- 3 files changed, 10 insertions(+), 7 deletions(-) -- 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/4] xhci: Add quirks module option
From: Takashi Iwai It makes easier for debugging some hardware specific issues. Note that this option won't override the value to be set. That is, you can turn quirks on by this option but cannot turn them off if set by the driver. Signed-off-by: Takashi Iwai Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d68ec1aa473d..6bc966cfb60e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -40,6 +40,10 @@ static int link_quirk; module_param(link_quirk, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); +static unsigned int quirks; +module_param(quirks, uint, S_IRUGO); +MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); + /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* * xhci_handshake - spin reading hc until handshake completes or fails @@ -4770,6 +4774,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) xhci->hcc_params = readl(&xhci->cap_regs->hcc_params); xhci_print_registers(xhci); + xhci->quirks = quirks; + get_quirks(dev, xhci); /* In xhci controllers which follow xhci 1.0 spec gives a spurious -- 1.8.3.3 -- 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/4] xhci: Remove unused variable 'addr' in inc_deq() and inc_enq().
From: Lin Wang This patch remove unused variable 'addr' in inc_deq() and inc_enq(). Signed-off-by: Lin Wang Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d26cd9474aa6..afa28ce8e591 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -156,8 +156,6 @@ static void next_trb(struct xhci_hcd *xhci, */ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) { - unsigned long long addr; - ring->deq_updates++; /* @@ -186,8 +184,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) ring->dequeue++; } } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); - - addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); } /* @@ -212,7 +208,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, { u32 chain; union xhci_trb *next; - unsigned long long addr; chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN; /* If this is not event ring, there is one less usable TRB */ @@ -264,7 +259,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, ring->enqueue = ring->enq_seg->trbs; next = ring->enqueue; } - addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); } /* -- 1.8.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] usb: xhci: Check for XHCI_PLAT in xhci_cleanup_msix()
From: Jack Pham If CONFIG_PCI is enabled, make sure xhci_cleanup_msix() doesn't try to free a bogus PCI IRQ or dereference an invalid pci_dev when the xHCI device is actually a platform_device. This patch should be backported to kernels as old as 3.9, that contain the commit 52fb61250a7a132b0cfb9f4a1060a1f3c49e5a25 "xhci-plat: Don't enable legacy PCI interrupts." Signed-off-by: Jack Pham Signed-off-by: Sarah Sharp Cc: sta...@vger.kernel.org --- drivers/usb/host/xhci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6bc966cfb60e..f8ffc512faf1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -325,6 +325,9 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci) struct usb_hcd *hcd = xhci_to_hcd(xhci); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + if (xhci->quirks & XHCI_PLAT) + return; + xhci_free_irq(xhci); if (xhci->msix_entries) { -- 1.8.3.3 -- 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/4] usbtest: Fix BOS control test for USB 2.01 devices.
Commit c952a8ba7136505cd1ca01735cc748ddc08c7d2f "usb: usbtest: add a test case to support bos for queue control" will cause USB 2.01 and USB 2.10 devices with a BOS descriptor to fail case 15 of the control test. The Link PM errata (released in 2007, updated in 2011) says: "The value of the bcdUSB field in the standard USB 2.0 Device Descriptor is used to indicate that the device supports the request to read the BOS Descriptor (i.e. GetDescriptor(BOS)). Devices that support the BOS descriptor must have a bcdUSB value of 0201H or larger." The current code says that non-SuperSpeed devices *must* return -EPIPE, as this comment shows: /* sign of this variable means: * -: tested code must return this (negative) error code * +: tested code may return this (negative too) error code */ int expected = 0; This means the test will fail with USB 2.01 and USB 2.10 devices that provide a BOS descriptor. Change it to only require a stall response if the USB device bcdUSB is less than 2.01. Signed-off-by: Sarah Sharp Acked-by: Huang Rui --- drivers/usb/misc/usbtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index bff058ea222e..446ff55e3c58 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1224,7 +1224,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) len = le16_to_cpu(udev->bos->desc->wTotalLength); else len = sizeof(struct usb_bos_descriptor); - if (udev->speed != USB_SPEED_SUPER) + if (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0201) expected = -EPIPE; break; default: -- 1.8.3.3 -- 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: phy: am335x: fix randconfig errors
On Fri, Dec 20, 2013 at 07:19:31PM -0200, Fabio Estevam wrote: > On Fri, Dec 20, 2013 at 7:05 PM, Felipe Balbi wrote: > > by using SET_SYSTEM_SLEEP_PM_OPS, we will make > > sure that we don't use undefined functions. > > > > Signed-off-by: Felipe Balbi > > You could optimize this a bit further: > > --- a/drivers/usb/phy/phy-am335x.c > +++ b/drivers/usb/phy/phy-am335x.c > @@ -122,16 +122,9 @@ static int am335x_phy_resume(struct device *dev) > > return 0; > } > -#define DEV_PM_OPS (&am335x_pm_ops) > -#else > -#define DEV_PM_OPS NULL > #endif > > - > -static const struct dev_pm_ops am335x_pm_ops = { > - .suspend = am335x_phy_suspend, > - .resume = am335x_phy_resume, > -}; > +static SIMPLE_DEV_PM_OPS(am335x_pm_ops, am335x_phy_suspend, > am335x_phy_resume); I rather keep it the other way, we have plans to add runtime pm soonish ;-) Thanks though :-) -- balbi signature.asc Description: Digital signature
Re: [PATCH] usb: phy: am335x: fix randconfig errors
On Fri, Dec 20, 2013 at 7:05 PM, Felipe Balbi wrote: > by using SET_SYSTEM_SLEEP_PM_OPS, we will make > sure that we don't use undefined functions. > > Signed-off-by: Felipe Balbi You could optimize this a bit further: --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -122,16 +122,9 @@ static int am335x_phy_resume(struct device *dev) return 0; } -#define DEV_PM_OPS (&am335x_pm_ops) -#else -#define DEV_PM_OPS NULL #endif - -static const struct dev_pm_ops am335x_pm_ops = { - .suspend = am335x_phy_suspend, - .resume = am335x_phy_resume, -}; +static SIMPLE_DEV_PM_OPS(am335x_pm_ops, am335x_phy_suspend, am335x_phy_resume); static const struct of_device_id am335x_phy_ids[] = { { .compatible = "ti,am335x-usb-phy" }, @@ -145,7 +138,7 @@ static struct platform_driver am335x_phy_driver = { .driver = { .name = "am335x-phy-driver", .owner = THIS_MODULE, - .pm = DEV_PM_OPS, + .pm = &am335x_pm_ops, .of_match_table = am335x_phy_ids, }, }; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: phy: am335x: fix randconfig errors
by using SET_SYSTEM_SLEEP_PM_OPS, we will make sure that we don't use undefined functions. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-am335x.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index e8088fa..12fc346 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -122,17 +122,16 @@ static int am335x_phy_resume(struct device *dev) return 0; } + +static const struct dev_pm_ops am335x_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(am335x_phy_suspend, am335x_phy_resume) +}; + #define DEV_PM_OPS (&am335x_pm_ops) #else #define DEV_PM_OPS NULL #endif - -static const struct dev_pm_ops am335x_pm_ops = { - .suspend = am335x_phy_suspend, - .resume = am335x_phy_resume, -}; - static const struct of_device_id am335x_phy_ids[] = { { .compatible = "ti,am335x-usb-phy" }, { } -- 1.8.4.GIT -- 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] phy: core: properly handle failure of pm_runtime_get functions
In case pm_runtime_get*() fails, it still increments pm usage counter, so we *must* make sure to pm_runtime_put() even in those cases. This patch fixes that mistake the same way usbcore treats those possible failures. Signed-off-by: Felipe Balbi --- drivers/phy/phy-core.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 03cf8fb..2804058 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -94,19 +94,31 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node) int phy_pm_runtime_get(struct phy *phy) { + int ret; + if (!pm_runtime_enabled(&phy->dev)) return -ENOTSUPP; - return pm_runtime_get(&phy->dev); + ret = pm_runtime_get(&phy->dev); + if (ret < 0 && ret != -EINPROGRESS) + pm_runtime_put_noidle(&phy->dev); + + return ret; } EXPORT_SYMBOL_GPL(phy_pm_runtime_get); int phy_pm_runtime_get_sync(struct phy *phy) { + int ret; + if (!pm_runtime_enabled(&phy->dev)) return -ENOTSUPP; - return pm_runtime_get_sync(&phy->dev); + ret = pm_runtime_get_sync(&phy->dev); + if (ret < 0) + pm_runtime_put_sync(&phy->dev); + + return ret; } EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync); -- 1.8.4.GIT -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: Fix oops on LPM disable failure.
If a control transfer to a parent hub to disable the U1/U2 timeout fails when usb_reset_and_verify_device() calls into usb_unlocked_disable_lpm(), the USB core will attempt to re-enable LPM. That will cause an oops in usb_enable_link_state: [ 1466.722795] usb 2-2.3: Failed to set U1 timeout to 0x0,error code -71 [ 1466.722817] BUG: unable to handle kernel NULL pointer dereference at 0010 [ 1466.722888] IP: [] usb_enable_link_state+0x2d/0x2f0 [ 1466.722969] PGD 0 [ 1466.722990] Oops: [#1] SMP [ 1466.723026] Modules linked in: pegasus mii ses enclosure usb_storage cuse dm_crypt uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev x86_pkg_temp_thermal coretemp ghash_clmu lni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd arc4 iwldvm mac80211 snd_hda_codec_hdmi microcode snd_hda_codec_realtek snd_usb_audio joydev thinkpad_acpi snd_hda_in tel iwlwifi snd_usbmidi_lib nvram snd_hda_codec snd_seq_midi snd_seq_midi_event psmouse snd_rawmidi snd_hwdep serio_raw snd_pcm cfg80211 snd_seq bnep rfcomm bluetooth snd_page_alloc snd_seq_devi ce ehci_pci snd_timer ehci_hcd lpc_ich snd soundcore tpm_tis binfmt_misc btrfs libcrc32c xor raid6_pq hid_generic usbhid hid i915 i2c_algo_bit drm_kms_helper sdhci_pci e1000e drm sdhci ahci liba hci xhci_hcd ptp pps_core video [ 1466.723790] CPU: 3 PID: 3516 Comm: usb-storage Tainted: GW 3.13.0-rc1+ #150 [ 1466.723861] Hardware name: LENOVO 2325AP7/2325AP7, BIOS G2ET82WW (2.02 ) 09/11/2012 [ 1466.723926] task: 8800b15ac120 ti: 880085e52000 task.ti: 880085e52000 [ 1466.723980] RIP: 0010:[] [] usb_enable_link_state+0x2d/0x2f0 [ 1466.724054] RSP: 0018:880085e53b98 EFLAGS: 00010246 [ 1466.724093] RAX: RBX: 88009eaed800 RCX: 0001 [ 1466.724144] RDX: 0001 RSI: 88009eaed800 RDI: 880031be6000 [ 1466.724199] RBP: 880085e53be8 R08: 0002 R09: 0001 [ 1466.724249] R10: R11: R12: 0001 [ 1466.724305] R13: 880082f86000 R14: 880031be6000 R15: 0003 [ 1466.724356] FS: () GS:88011e2c() knlGS: [ 1466.724418] CS: 0010 DS: ES: CR0: 80050033 [ 1466.724459] CR2: 0010 CR3: c628d000 CR4: 001407e0 [ 1466.724509] Stack: [ 1466.724525] ffb9 880085e53be0 [ 1466.724589] 814a677b 88009eaed800 880031be6000 880082f86000 [ 1466.724655] 0003 0003 880085e53c08 814a7811 [ 1466.724754] Call Trace: [ 1466.724782] [] ? usb_set_lpm_timeout+0x12b/0x140 [ 1466.724830] [] usb_enable_lpm+0x81/0xa0 [ 1466.724873] [] usb_disable_lpm+0xa8/0xc0 [ 1466.724922] [] usb_unlocked_disable_lpm+0x2e/0x50 [ 1466.724971] [] usb_reset_and_verify_device+0xc0/0x770 [ 1466.725022] [] ? trace_hardirqs_on+0xd/0x10 [ 1466.725075] [] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage] [ 1466.725129] [] ? __pm_runtime_resume+0x5c/0x90 [ 1466.725196] [] usb_reset_device+0xe8/0x1d0 [ 1466.725243] [] usb_stor_port_reset+0x6c/0x80 [usb_storage] [ 1466.725294] [] usb_stor_invoke_transport+0x8e/0x550 [usb_storage] [ 1466.725372] [] ? usb_stor_control_thread+0x96/0x290 [usb_storage] [ 1466.725447] [] usb_stor_transparent_scsi_command+0xe/0x10 [usb_storage] [ 1466.725509] [] usb_stor_control_thread+0x173/0x290 [usb_storage] [ 1466.725576] [] ? fill_inquiry_response+0x20/0x20 [usb_storage] [ 1466.725666] [] ? fill_inquiry_response+0x20/0x20 [usb_storage] [ 1466.725695] [] kthread+0xfc/0x120 [ 1466.725748] [] ? kthread_create_on_node+0x230/0x230 [ 1466.725834] [] ret_from_fork+0x7c/0xb0 [ 1466.725878] [] ? kthread_create_on_node+0x230/0x230 [ 1466.725930] Code: 44 00 00 55 48 89 e5 41 57 41 56 49 89 fe 41 55 41 54 41 89 d4 53 48 89 f3 48 83 ec 28 48 8b 86 98 04 00 00 41 83 fc 01 0f 94 c1 <48> 8b 40 10 0f b7 50 08 74 79 41 83 fc 02 40 0f 94 c6 75 17 66 [ 1466.729716] hub 2-0:1.0: port 2 not warm reset yet, waiting 200ms [ 1466.734229] RIP [] usb_enable_link_state+0x2d/0x2f0 [ 1466.737086] RSP [ 1466.739767] CR2: 0010 [ 1466.753046] ---[ end trace 258408fcefe55312 ]--- /* If the device says it doesn't have *any* exit latency to come out of * U1 or U2, it's probably lying. Assume it doesn't implement that link * state. */ if ((state == USB3_LPM_U1 && u1_mel == 0) || 814a74c6: 41 83 fc 01 cmp$0x1,%r12d | %r12 => 1 814a74ca: 0f 94 c1sete %cl */ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { int timeout, ret; __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; *814a74cd: 48 8b 40 10 mov0x10(%rax),%rax | %eax = 0 <--- faulting instruction __le16 u2
Re: [RFC/PATCH 1/3] pm: make PM macros more smart
On Fri, Dec 20, 2013 at 08:55:27PM +0100, Pavel Machek wrote: > On Sun 2013-12-15 11:25:08, David Cohen wrote: > > On Sun, Dec 15, 2013 at 06:51:12PM +0100, Pavel Machek wrote: > > > On Thu 2013-12-12 21:18:23, David Cohen wrote: > > > > This patch makes SET_SYSTEM_SLEEP_PM_OPS() and SET_RUNTIME_PM_OPS() more > > > > smart. > > > > > > > > Despite those macros check for '#ifdef CONFIG_PM_SLEEP/RUNTIME' to avoid > > > > setting the callbacks when such #ifdef's aren't defined, they don't > > > > handle compiler to avoid messages like that: > > > > > > > > drivers/usb/host/xhci-plat.c:200:12: warning: ???xhci_plat_suspend??? > > > > defined but not used [-Wunused-function] > > > > drivers/usb/host/xhci-plat.c:208:12: warning: ???xhci_plat_resume??? > > > > defined but not used [-Wunused-function] > > > > > > > > As result, those macros get rid of #ifdef's when setting callbacks but > > > > not when implementing them. > > > > > > > > With this patch, drivers using SET_*_PM_OPS() macros don't need to > > > > #ifdef > > > > the callbacks implementation as well. > > > > > > Well... Interesting trickery, but it means that resulting kernel > > > will be bigge due to the dead functions no? > > > > Actually, it doesn't get bigger. Before sending the patch I did this > > dummy test app: > > > > > > #include > > > > #define USE_IT_OR_LOOSE_IT(fn) ((void *)((unsigned long)(fn) - (unsigned > > long)(fn))) > > > > #ifdef MAKE_ME_NULL > > static int func1(int a) > > { > > printf("Hey!!\n"); > > return 0; > > } > > #endif > > I thought that point of this patch series was getting rid of the > #ifdefs around the function...? Now I'm confused. Maybe you're misinterpreting the test :) This #ifdef is used to make this same test code to replicate both scenarios according to -DMAKE_ME_NULL (just pay attention to actual resulting code after #ifdef's are tested. the #ifdef here is nor related to actual #ifdef on kernel). Here are both scenarios: (1) Not using my trickery (which needs the function to not be present). (2) Using my trickery (which needs to function to stay). With -DMAKE_ME_NULL we replicate (2), then the function *is* there but gcc gets rid of it on resulting binary without warnings if used with -O2. Without -DMAKE_ME_NULL we replicate (1). The #ifdef will fail and then remove the function which is an obvious scenario the function won't be part of resulting binary. If we use -S option to have human readable resulting assembly code (which is kind of 1:1 for resulting binary), we can compare the result of (1) and (2) and check they are pretty similar. This proves gcc behaves as expected with my patch: do not need #ifdef and do not generate dead codes to resulting binary. > > > struct global_data { > > int (*func)(int); > > }; > > > > static struct global_data gd = { > > #ifdef MAKE_ME_NULL > > .func = USE_IT_OR_LOOSE_IT(func1), > > If you have ifdef around the function, why do you need magic here? Why > not This #ifdef is necessary to prevent the function to be used when it doesn't exist due to above #ifdef. But once again: don't misinterpret the #ifdefs in this test app with the ones in kernel. They are not related at all. If it's still confusing you just make 2 test apps without #ifdeds out of this one where one keeps the code inside #ifdefs and the other doesn't. > > .func = func1 > > ? > > Basically the warning tells you that you want the ifdef around the > function, too... (Otherwise you waste space). That seems like good > warning. Just check my first explanation. Br, David Cohen > > Pavel > -- > (english) http://www.livejournal.com/~pavelmachek > (cesky, pictures) > http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 00/15] usb: phy: msm: Fixes, cleanups and DT support
On Thu, Dec 19, 2013 at 05:26:13PM -0600, Felipe Balbi wrote: it's getting quite late for me. I still want to leave my stuff soaking in linux-next for a while. I'll try my best, though, if you ack it ASAP Thanks. Patch 1 already has my Ack in it, and I've sent an ack for number 6. David -- sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- 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/3] pm: make PM macros more smart
On Sun 2013-12-15 11:25:08, David Cohen wrote: > On Sun, Dec 15, 2013 at 06:51:12PM +0100, Pavel Machek wrote: > > On Thu 2013-12-12 21:18:23, David Cohen wrote: > > > This patch makes SET_SYSTEM_SLEEP_PM_OPS() and SET_RUNTIME_PM_OPS() more > > > smart. > > > > > > Despite those macros check for '#ifdef CONFIG_PM_SLEEP/RUNTIME' to avoid > > > setting the callbacks when such #ifdef's aren't defined, they don't > > > handle compiler to avoid messages like that: > > > > > > drivers/usb/host/xhci-plat.c:200:12: warning: ???xhci_plat_suspend??? > > > defined but not used [-Wunused-function] > > > drivers/usb/host/xhci-plat.c:208:12: warning: ???xhci_plat_resume??? > > > defined but not used [-Wunused-function] > > > > > > As result, those macros get rid of #ifdef's when setting callbacks but > > > not when implementing them. > > > > > > With this patch, drivers using SET_*_PM_OPS() macros don't need to #ifdef > > > the callbacks implementation as well. > > > > Well... Interesting trickery, but it means that resulting kernel > > will be bigge due to the dead functions no? > > Actually, it doesn't get bigger. Before sending the patch I did this > dummy test app: > > > #include > > #define USE_IT_OR_LOOSE_IT(fn) ((void *)((unsigned long)(fn) - (unsigned > long)(fn))) > > #ifdef MAKE_ME_NULL > static int func1(int a) > { > printf("Hey!!\n"); > return 0; > } > #endif I thought that point of this patch series was getting rid of the #ifdefs around the function...? Now I'm confused. > struct global_data { > int (*func)(int); > }; > > static struct global_data gd = { > #ifdef MAKE_ME_NULL > .func = USE_IT_OR_LOOSE_IT(func1), If you have ifdef around the function, why do you need magic here? Why not .func = func1 ? Basically the warning tells you that you want the ifdef around the function, too... (Otherwise you waste space). That seems like good warning. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] uwb: move mutex_lock to error case in uwbd_evt_handle_rc_bp_slot_change
Only acquire rc->uwb_dev.mutex in the error case in uwbd_evt_handle_rc_bp_slot_change. This fixes a bug where establishing a reservation on a new channel will fail if we were unable to establish a reservation on the previous channel due to DRP conflict. If rc->uwb_dev.mutex is acquired in the non-error case when the uwb system is attempting to start beaconing, it will block because the start beaconing code is holding this mutex. This prevents any other notifications from the URC from being processed. In particular, the DRP_AVAILABILITY notification will not be processed during the start beaconing process which can result in a failure to establish a reservation. It is safe to not hold the mutex in the non-error case since the only other place rc->uwb_dev.beacon_slot is accessed is in the same worker thread that uwbd_evt_handle_rc_bp_slot_change executes in. Signed-off-by: Thomas Pugliese --- drivers/uwb/beacon.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 4190f29..57b5ff6 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -516,13 +516,13 @@ int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *evt) } bpsc = container_of(evt->notif.rceb, struct uwb_rc_evt_bp_slot_change, rceb); - mutex_lock(&rc->uwb_dev.mutex); if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) { dev_err(dev, "stopped beaconing: No free slots in BP\n"); + mutex_lock(&rc->uwb_dev.mutex); rc->beaconing = -1; + mutex_unlock(&rc->uwb_dev.mutex); } else rc->uwb_dev.beacon_slot = uwb_rc_evt_bp_slot_change_slot_num(bpsc); - mutex_unlock(&rc->uwb_dev.mutex); return 0; } -- 1.7.10.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] uwb: move mutex_lock to error case in uwbd_evt_handle_rc_bp_slot_change
On Fri, 20 Dec 2013, David Cohen wrote: > On Fri, Dec 20, 2013 at 11:55:53AM -0600, Thomas Pugliese wrote: > > Only acquire rc->uwb_dev.mutex in the error case in > > uwbd_evt_handle_rc_bp_slot_change. This fixes a bug where establishing > > a reservation on a new channel will fail if we were unable to establish > > a reservation on the previous channel due to DRP conflict. > > > > If rc->uwb_dev.mutex is acquired in the non-error case when the uwb > > system is attempting to start beaconing, it will block because the start > > beaconing code is holding this mutex. This prevents any other > > notifications from the URC from being processed. In particular, the > > DRP_AVAILABILITY notification will not be processed during the start > > beaconing process which can result in a failure to establish a > > reservation. It is safe to not hold the mutex in the non-error > > case since the only other place rc->uwb_dev.beacon_slot is accessed is > > in the same worker thread that uwbd_evt_handle_rc_bp_slot_change > > executes in. > > > > Signed-off-by: Thomas Pugliese > > --- > > drivers/uwb/beacon.c |4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c > > index 4190f29..92407e8 100644 > > --- a/drivers/uwb/beacon.c > > +++ b/drivers/uwb/beacon.c > > @@ -516,13 +516,13 @@ int uwbd_evt_handle_rc_bp_slot_change(struct > > uwb_event *evt) > > } > > bpsc = container_of(evt->notif.rceb, struct uwb_rc_evt_bp_slot_change, > > rceb); > > > > - mutex_lock(&rc->uwb_dev.mutex); > > if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) { > > + mutex_lock(&rc->uwb_dev.mutex); > > dev_err(dev, "stopped beaconing: No free slots in BP\n"); > > It could be just nitpicking, but I think it's a waste of resource to > unnecessarily print to console while holding a lock. > If you move this dev_err() to after mutex_unlock() you'd achieve the > same result with a cheaper lock. > That's a fair point. Might as well lock only what is absolutely necessary. > > rc->beaconing = -1; > > Although I'm not sure how useful it is to protect this single line of > code. > I'm not ready to get rid of the lock altogether in this function. There are other users of the beaconing flag that don't expect the value to change out from under them while holding the lock. > Br, David Cohen > > > + mutex_unlock(&rc->uwb_dev.mutex); > > } else > > rc->uwb_dev.beacon_slot = > > uwb_rc_evt_bp_slot_change_slot_num(bpsc); > > - mutex_unlock(&rc->uwb_dev.mutex); > > > > return 0; > > } > > -- I'll resend this with the lock surrounding just the variable assignment. Tom -- 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] uwb: move mutex_lock to error case in uwbd_evt_handle_rc_bp_slot_change
On Fri, Dec 20, 2013 at 11:55:53AM -0600, Thomas Pugliese wrote: > Only acquire rc->uwb_dev.mutex in the error case in > uwbd_evt_handle_rc_bp_slot_change. This fixes a bug where establishing > a reservation on a new channel will fail if we were unable to establish > a reservation on the previous channel due to DRP conflict. > > If rc->uwb_dev.mutex is acquired in the non-error case when the uwb > system is attempting to start beaconing, it will block because the start > beaconing code is holding this mutex. This prevents any other > notifications from the URC from being processed. In particular, the > DRP_AVAILABILITY notification will not be processed during the start > beaconing process which can result in a failure to establish a > reservation. It is safe to not hold the mutex in the non-error > case since the only other place rc->uwb_dev.beacon_slot is accessed is > in the same worker thread that uwbd_evt_handle_rc_bp_slot_change > executes in. > > Signed-off-by: Thomas Pugliese > --- > drivers/uwb/beacon.c |4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c > index 4190f29..92407e8 100644 > --- a/drivers/uwb/beacon.c > +++ b/drivers/uwb/beacon.c > @@ -516,13 +516,13 @@ int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event > *evt) > } > bpsc = container_of(evt->notif.rceb, struct uwb_rc_evt_bp_slot_change, > rceb); > > - mutex_lock(&rc->uwb_dev.mutex); > if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) { > + mutex_lock(&rc->uwb_dev.mutex); > dev_err(dev, "stopped beaconing: No free slots in BP\n"); It could be just nitpicking, but I think it's a waste of resource to unnecessarily print to console while holding a lock. If you move this dev_err() to after mutex_unlock() you'd achieve the same result with a cheaper lock. > rc->beaconing = -1; Although I'm not sure how useful it is to protect this single line of code. Br, David Cohen > + mutex_unlock(&rc->uwb_dev.mutex); > } else > rc->uwb_dev.beacon_slot = > uwb_rc_evt_bp_slot_change_slot_num(bpsc); > - mutex_unlock(&rc->uwb_dev.mutex); > > return 0; > } > -- > 1.7.10.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 -- 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] xhci: Allocate the td array and urb_priv together.
On Fri, Dec 20, 2013 at 09:26:35AM -, David Laight wrote: > > From: David Cohen > > On Wed, Dec 18, 2013 at 11:24:47AM -, David Laight wrote: > > > This saves a kzalloc() call on every transfer and some memory > > > indirections. > > > > > > The only possible downside is for isochronous tranfers with 64 td > > > when the allocate is 8+4096 bytes (on 64bit systems) so requires > > > an additional page. > > > > If you take this to embedded world there could be a bad side effect too. > > The free memory isn't abundant and the fragmentation may make a bigger > > kmalloc() to cost more than 2 smaller ones. > > The effect of this change is really to remove the first allocation and > add 8 bytes (or maybe a pointer) to the start of the second one. > So it is extremely unlikely to fail when the old code would work. Currently struct urb_priv has a dynamic array of pointers to struct xhci_td. You're replacing the pointer by structs itself. Now, instead of 2 kmallocs() (1 for urb_priv and another for size * xhci_td) we've 1 kmalloc() with urb_priv + size * xhci_td. The remaining kmalloc() is size * (sizeof(struct xhci_td) - sizeof(struct xhci *)) bigger. I don't know what's the regular value of 'size', but even if size=1 new kmalloc() extra size is already bigger than 8 bytes. > > It would, of course, be better to allocate a parallel 'software' ring > containing the required extra information and completely remove the > additional allocate/free on every USB request. Can't argue on that. I'm still new to USB subsystem. > > David You've got a nice name :P Br, David Cohen > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] uwb: whitespace and comment cleanups
various whitespace and comment cleanups Signed-off-by: Thomas Pugliese --- drivers/uwb/beacon.c |2 +- drivers/uwb/radio.c |2 +- drivers/uwb/rsv.c| 14 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 7b76361..4190f29 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -185,7 +185,7 @@ out: /* Find a beacon by dev addr in the cache */ static -struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc, +struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc, const struct uwb_mac_addr *mac_addr) { struct uwb_beca_e *bce, *next; diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c index 10adb98..fd23d98 100644 --- a/drivers/uwb/radio.c +++ b/drivers/uwb/radio.c @@ -93,7 +93,7 @@ static int uwb_radio_change_channel(struct uwb_rc *rc, int channel) * uwb_radio_start - request that the radio be started * @pal: the PAL making the request. * - * If the radio is not already active, aa suitable channel is selected + * If the radio is not already active, a suitable channel is selected * and beacons are started. */ int uwb_radio_start(struct uwb_pal *pal) diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 738e8a8..4e7e4bf 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -237,7 +237,7 @@ void uwb_rsv_backoff_win_increment(struct uwb_rc *rc) /* reset the timer associated variables */ timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US; bow->total_expired = 0; - mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us)); + mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us)); } static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) @@ -257,7 +257,7 @@ static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) sframes = 1; if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED) sframes = 0; - + } if (sframes > 0) { @@ -611,7 +611,7 @@ int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available) struct device *dev = &rc->uwb_dev.dev; struct uwb_rsv_move *mv; int ret = 0; - + if (bow->can_reserve_extra_mases == false) return -EBUSY; @@ -628,7 +628,7 @@ int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available) } else { dev_dbg(dev, "new allocation not found\n"); } - + return ret; } @@ -640,7 +640,7 @@ void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc) struct uwb_drp_backoff_win *bow = &rc->bow; struct uwb_rsv *rsv; struct uwb_mas_bm mas; - + if (bow->can_reserve_extra_mases == false) return; @@ -652,7 +652,7 @@ void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc) uwb_rsv_try_move(rsv, &mas); } } - + } /** @@ -916,7 +916,7 @@ static void uwb_rsv_alien_bp_work(struct work_struct *work) struct uwb_rsv *rsv; mutex_lock(&rc->rsvs_mutex); - + list_for_each_entry(rsv, &rc->reservations, rc_node) { if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) { rsv->callback(rsv); -- 1.7.10.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 1/3] uwb: add debug prints during channel change and beacon actions
Add debug prints during channel change and beacon actions. Signed-off-by: Thomas Pugliese --- drivers/uwb/beacon.c |3 ++- drivers/uwb/radio.c |4 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index dcdd59b..7b76361 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -117,6 +117,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) int result; struct device *dev = &rc->uwb_dev.dev; + dev_dbg(dev, "%s: channel = %d\n", __func__, channel); if (channel < 0) channel = -1; if (channel == -1) @@ -517,7 +518,7 @@ int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *evt) mutex_lock(&rc->uwb_dev.mutex); if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) { - dev_info(dev, "stopped beaconing: No free slots in BP\n"); + dev_err(dev, "stopped beaconing: No free slots in BP\n"); rc->beaconing = -1; } else rc->uwb_dev.beacon_slot = uwb_rc_evt_bp_slot_change_slot_num(bpsc); diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c index d58dfec..10adb98 100644 --- a/drivers/uwb/radio.c +++ b/drivers/uwb/radio.c @@ -62,6 +62,10 @@ static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel) static int uwb_radio_change_channel(struct uwb_rc *rc, int channel) { int ret = 0; + struct device *dev = &rc->uwb_dev.dev; + + dev_dbg(dev, "%s: channel = %d, rc->beaconing = %d\n", __func__, + channel, rc->beaconing); if (channel == -1) uwb_radio_channel_changed(rc, channel); -- 1.7.10.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] uwb: move mutex_lock to error case in uwbd_evt_handle_rc_bp_slot_change
Only acquire rc->uwb_dev.mutex in the error case in uwbd_evt_handle_rc_bp_slot_change. This fixes a bug where establishing a reservation on a new channel will fail if we were unable to establish a reservation on the previous channel due to DRP conflict. If rc->uwb_dev.mutex is acquired in the non-error case when the uwb system is attempting to start beaconing, it will block because the start beaconing code is holding this mutex. This prevents any other notifications from the URC from being processed. In particular, the DRP_AVAILABILITY notification will not be processed during the start beaconing process which can result in a failure to establish a reservation. It is safe to not hold the mutex in the non-error case since the only other place rc->uwb_dev.beacon_slot is accessed is in the same worker thread that uwbd_evt_handle_rc_bp_slot_change executes in. Signed-off-by: Thomas Pugliese --- drivers/uwb/beacon.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 4190f29..92407e8 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -516,13 +516,13 @@ int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *evt) } bpsc = container_of(evt->notif.rceb, struct uwb_rc_evt_bp_slot_change, rceb); - mutex_lock(&rc->uwb_dev.mutex); if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) { + mutex_lock(&rc->uwb_dev.mutex); dev_err(dev, "stopped beaconing: No free slots in BP\n"); rc->beaconing = -1; + mutex_unlock(&rc->uwb_dev.mutex); } else rc->uwb_dev.beacon_slot = uwb_rc_evt_bp_slot_change_slot_num(bpsc); - mutex_unlock(&rc->uwb_dev.mutex); return 0; } -- 1.7.10.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 0/3] uwb: minor cleanups
This patch set adds some debug prints, cleans up whitespace and comments and modifies one location to use the proper wrapper for calling reservation callbacks. Thomas Pugliese (3): uwb: add debug prints during channel change and beacon actions uwb: whitespace and comment cleanups uwb: use uwb_rsv_callback instead of calling rsv->callback directly drivers/uwb/beacon.c |5 +++-- drivers/uwb/radio.c |6 +- drivers/uwb/rsv.c| 16 3 files changed, 16 insertions(+), 11 deletions(-) -- 1.7.10.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 3/3] uwb: use uwb_rsv_callback instead of calling rsv->callback directly
Use uwb_rsv_callback wrapper instead of calling rsv->callback directly. uwb_rsv_callback checks for NULL and is used by other callers of the callback routine. Signed-off-by: Thomas Pugliese --- drivers/uwb/rsv.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 4e7e4bf..3fe6119 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -919,7 +919,7 @@ static void uwb_rsv_alien_bp_work(struct work_struct *work) list_for_each_entry(rsv, &rc->reservations, rc_node) { if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) { - rsv->callback(rsv); + uwb_rsv_callback(rsv); } } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] usb: wusbcore: add debug prints to reservation and channel change
This patch adds debug prints to the reservation and channel change sequence to help with debugging channel change problems. Signed-off-by: Thomas Pugliese --- drivers/usb/wusbcore/pal.c |1 + drivers/usb/wusbcore/reservation.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c index 59e100c..090f273 100644 --- a/drivers/usb/wusbcore/pal.c +++ b/drivers/usb/wusbcore/pal.c @@ -22,6 +22,7 @@ static void wusbhc_channel_changed(struct uwb_pal *pal, int channel) { struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal); + dev_dbg(wusbhc->dev, "%s: channel = %d\n", __func__, channel); if (channel < 0) wusbhc_stop(wusbhc); else diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index ead79f7..d5efd0f 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -51,6 +51,7 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) struct uwb_mas_bm mas; char buf[72]; + dev_dbg(dev, "%s: state = %d\n", __func__, rsv->state); switch (rsv->state) { case UWB_RSV_STATE_O_ESTABLISHED: uwb_rsv_get_usable_mas(rsv, &mas); -- 1.7.10.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: musb: Remove USB_GADGET driver dependency
On Fri, Dec 20, 2013 at 09:49:58AM -0600, Felipe Balbi wrote: > On Thu, Dec 19, 2013 at 10:20:48PM -0300, Ezequiel Garcia wrote: > > This USB controller is dual-role, but can also work in host-only mode. > > There's no reason to condition the entire driver to USB_GADGET. Fix this by > > removing the dependency. > > > > Tested on a Beaglebone black (AM335x) using a regular USB mass storage > > device. > > > > Signed-off-by: Ezequiel Garcia > > --- > > drivers/usb/musb/Kconfig | 1 - > > 1 file changed, 1 deletion(-) > > > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig > > index 57dfc0c..2119370 100644 > > --- a/drivers/usb/musb/Kconfig > > +++ b/drivers/usb/musb/Kconfig > > @@ -6,7 +6,6 @@ > > # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller > > config USB_MUSB_HDRC > > tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' > > - depends on USB_GADGET > > the correct patch would be to turn this into (USB || USB_GADGET) and fix > the mode selection just like dwc3 is doing. > Ah, I see now. Let me prepare a v2 then. -- Ezequiel García, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: wusbcore: add debug prints to reservation and channel change
On Fri, Dec 20, 2013 at 10:55:34AM -0600, Thomas Pugliese wrote: > This patch adds debug prints to the reservation and channel change > sequence to help with debugging channel change problems. > > Signed-off-by: Thomas Pugliese > --- > drivers/usb/wusbcore/pal.c |1 + > drivers/usb/wusbcore/reservation.c |1 + > 2 files changed, 2 insertions(+) > > diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c > index 59e100c..d427e62 100644 > --- a/drivers/usb/wusbcore/pal.c > +++ b/drivers/usb/wusbcore/pal.c > @@ -22,6 +22,7 @@ static void wusbhc_channel_changed(struct uwb_pal *pal, int > channel) > { > struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal); > > + pr_info("%s: channel = %d\n", __func__, channel); That's not a "debug" message, it's a "let's annoy all users" message. Please make it a dev_dbg() call if you want a debug message. 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] usb: wusbcore: add debug prints to reservation and channel change
This patch adds debug prints to the reservation and channel change sequence to help with debugging channel change problems. Signed-off-by: Thomas Pugliese --- drivers/usb/wusbcore/pal.c |1 + drivers/usb/wusbcore/reservation.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c index 59e100c..d427e62 100644 --- a/drivers/usb/wusbcore/pal.c +++ b/drivers/usb/wusbcore/pal.c @@ -22,6 +22,7 @@ static void wusbhc_channel_changed(struct uwb_pal *pal, int channel) { struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal); + pr_info("%s: channel = %d\n", __func__, channel); if (channel < 0) wusbhc_stop(wusbhc); else diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index ead79f7..438e175 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -51,6 +51,7 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) struct uwb_mas_bm mas; char buf[72]; + pr_info("%s: state = %d\n", __func__, rsv->state); switch (rsv->state) { case UWB_RSV_STATE_O_ESTABLISHED: uwb_rsv_get_usable_mas(rsv, &mas); -- 1.7.10.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: musb: Remove USB_GADGET driver dependency
On Thu, Dec 19, 2013 at 10:20:48PM -0300, Ezequiel Garcia wrote: > This USB controller is dual-role, but can also work in host-only mode. > There's no reason to condition the entire driver to USB_GADGET. Fix this by > removing the dependency. > > Tested on a Beaglebone black (AM335x) using a regular USB mass storage > device. > > Signed-off-by: Ezequiel Garcia > --- > drivers/usb/musb/Kconfig | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig > index 57dfc0c..2119370 100644 > --- a/drivers/usb/musb/Kconfig > +++ b/drivers/usb/musb/Kconfig > @@ -6,7 +6,6 @@ > # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller > config USB_MUSB_HDRC > tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' > - depends on USB_GADGET the correct patch would be to turn this into (USB || USB_GADGET) and fix the mode selection just like dwc3 is doing. -- balbi signature.asc Description: Digital signature
RE: [PATCH] USB: core: remove CONFIG_USB_DEBUG usage
> From: Greg Kroah-Hartman ... > > ... > > > /* Check that the pipe's type matches the endpoint's type */ > > > if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) > > > > It looks as though it ought to be possible to make that check: > > if (unlikely(xfertype != urb->pipe->valid_xfertype)) > > You should almost never use unlikely() on your own, in a driver, as the > compiler should make better code without it. If you can provide numbers > showing that this is faster, that would be great, otherwise I'll leave > it alone. The compiler has no information available to choose which side of the conditional to statically predict as true. At runtime the cpu's branch history might contain the information if the code path has been executed recently. Mispredicting branches can have a measurable performance penalty. One of the reasons the netburst P4 were so bad is that it was (IIRC) almost 40 clocks, and a lot of non-benchmark code has a lot of branches that don't get statically predicted correctly and are in long linear code paths. Even on a simple cpu where a predicted taken branch takes 1 extra clock and a mispredicted branch 3 extra clocks getting all the branches correctly statically predicted can make a significant difference. Even adding unlikely() isn't necessarily enough to force gcc to generate correctly statically predicted code. With the following: if (unlikely(...)) { asm volatile ("# unlikely\n"); continue; } Without the asm statement gcc won't generate a branch down the file to a jump back to teh top of the loop. The netdev people now just how much it matters. David -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/1] usb: gadget: f_fs: Add support for SuperSpeed Mode
On Fri, Dec 20 2013, Manu Gautam wrote: > Allow userspace to pass SuperSpeed descriptors and > handle them in the driver accordingly. > This change doesn't modify existing desc_header and thereby > keeps the ABI changes backward compatible i.e. existing > userspace drivers compiled with old header (functionfs.h) > would continue to work with the updated kernel. > > Signed-off-by: Manu Gautam > --- > drivers/usb/gadget/f_fs.c | 165 > > drivers/usb/gadget/u_fs.h | 8 +- > include/uapi/linux/usb/functionfs.h | 5 ++ > 3 files changed, 140 insertions(+), 38 deletions(-) > > diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c > index 306a2b5..65bc861 100644 > --- a/drivers/usb/gadget/f_fs.c > +++ b/drivers/usb/gadget/f_fs.c > @@ -122,8 +122,8 @@ struct ffs_ep { > struct usb_ep *ep;/* P: ffs->eps_lock */ > struct usb_request *req; /* P: epfile->mutex */ > > - /* [0]: full speed, [1]: high speed */ > - struct usb_endpoint_descriptor *descs[2]; > + /* [0]: full speed, [1]: high speed, [2]: super speed */ > + struct usb_endpoint_descriptor *descs[3]; > > u8 num; > > @@ -1184,9 +1184,12 @@ static void ffs_data_reset(struct ffs_data *ffs) > ffs->stringtabs = NULL; > > ffs->raw_descs_length = 0; > - ffs->raw_fs_descs_length = 0; > + ffs->raw_fs_hs_descs_length = 0; > + ffs->raw_ss_descs_offset = 0; > + ffs->raw_ss_descs_length = 0; > ffs->fs_descs_count = 0; > ffs->hs_descs_count = 0; > + ffs->ss_descs_count = 0; > > ffs->strings_count = 0; > ffs->interfaces_count = 0; > @@ -1329,7 +1332,20 @@ static int ffs_func_eps_enable(struct ffs_function > *func) > spin_lock_irqsave(&func->ffs->eps_lock, flags); > do { > struct usb_endpoint_descriptor *ds; > - ds = ep->descs[ep->descs[1] ? 1 : 0]; > + int desc_idx; > + > + if (ffs->gadget->speed == USB_SPEED_SUPER) > + desc_idx = 2; > + else if (ffs->gadget->speed == USB_SPEED_HIGH) > + desc_idx = 1; > + else > + desc_idx = 0; > + > + ds = ep->descs[desc_idx]; > + if (!ds) { > + ret = -EINVAL; > + break; > + } I don't like this. Why are we failing if descriptors for given speed are missing? If they are, we should fall back to lower speed. do { ds = ep->descs[desc_idx]; } while (!ds && --desc_idx >= 0); if (desc_idx < 0) { ret = -EINVAL; break; } Or something similar. Point is, why aren't we failing dawn to high/low speed if ep->descs[2] is NULL? > > ep->ep->driver_data = ep; > ep->ep->desc = ds; > @@ -1464,6 +1480,12 @@ static int __must_check ffs_do_desc(char *data, > unsigned len, > } > break; > > + case USB_DT_SS_ENDPOINT_COMP: > + pr_vdebug("EP SS companion descriptor\n"); > + if (length != sizeof(struct usb_ss_ep_comp_descriptor)) > + goto inv_length; > + break; > + > case USB_DT_OTHER_SPEED_CONFIG: > case USB_DT_INTERFACE_POWER: > case USB_DT_DEBUG: > @@ -1574,8 +1596,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type > type, > static int __ffs_data_got_descs(struct ffs_data *ffs, > char *const _data, size_t len) > { > - unsigned fs_count, hs_count; > - int fs_len, ret = -EINVAL; > + unsigned fs_count, hs_count, ss_count = 0; > + int fs_len, hs_len, ss_len, ss_magic, ret = -EINVAL; > char *data = _data; > > ENTER(); > @@ -1586,9 +1608,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, > fs_count = get_unaligned_le32(data + 8); > hs_count = get_unaligned_le32(data + 12); > > - if (!fs_count && !hs_count) > - goto einval; > - > data += 16; > len -= 16; > > @@ -1607,22 +1626,59 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, > } > > if (likely(hs_count)) { > - ret = ffs_do_descs(hs_count, data, len, > + hs_len = ffs_do_descs(hs_count, data, len, > __ffs_data_do_entity, ffs); > - if (unlikely(ret < 0)) > + if (unlikely(hs_len < 0)) { > + ret = hs_len; > + goto error; > + } data += hs_len; len -= hs_len; > + } else { > + hs_len = 0; > + } > + > + if ((len >= hs_len + 8)) { With the above len -= hs_len, this just becomes “len >= 8”. Nit: too many parenthesise. Having “((…))” makes me think there's assignment inside which there's no. > +
Re: poweroff during boot
On Fri, Dec 20, 2013 at 02:13:43PM +0100, Stefano Butti wrote: > Good morning > > I'm writing to you for a problem. I would like use live USB on a hardware > encrypted drive with onboard hardware numpad. > The > system power off usb during boot, so i must reinsert keycode on drive > and complete boot manually. Is it possible prevent usb poweroff during > boot? Sounds like a BIOS issue, Linux doesn't do anything at boot time to power off USB ports, sorry. 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] USB: core: remove CONFIG_USB_DEBUG usage
On Fri, Dec 20, 2013 at 10:04:00AM -, David Laight wrote: > > From: Greg Kroah-Hartman > > CONFIG_USB_DEBUG is going away, so remove the few places in the USB core > > that relied on them. > > > > This means that we always now do the "debug" checks for every urb > > submitted, which is a good idea, as who knows how many driver bugs we > > have been ignoring when people forget to enable this option. Also, with > > the overall speed of USB, doing these extra checks should not cause any > > additional overhead. > > Well USB3 isn't that slow, and the new version coming along soon is > even faster. > Running gigabit ethernet on usb3 shows a significantly higher cpu > cost than when using a normal ethernet adapter - and really the actual > operations required are very similar. Yes, but the checks here are trivial compared to the overall issues that higher bus speeds are going to require us to make, if anything. > ... > > /* Check that the pipe's type matches the endpoint's type */ > > if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) > > It looks as though it ought to be possible to make that check: > if (unlikely(xfertype != urb->pipe->valid_xfertype)) You should almost never use unlikely() on your own, in a driver, as the compiler should make better code without it. If you can provide numbers showing that this is faster, that would be great, otherwise I'll leave it alone. 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 v5 4/9] usb: ehci-s5p: Change to use phy provided by the generic phy framework
Change the phy provider used from the old one using the USB phy framework to a new one using the Generic phy framework. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park --- Documentation/devicetree/bindings/usb/usb-ehci.txt | 35 +++ drivers/usb/host/ehci-exynos.c | 97 +--- 2 files changed, 98 insertions(+), 34 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index fa18612..413f7cd 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt @@ -14,6 +14,10 @@ If controller implementation operates with big endian descriptors, If both big endian registers and descriptors are used by the controller implementation, "big-endian" property can be specified instead of having both "big-endian-regs" and "big-endian-desc". + - port: if in the SoC there are EHCI phys, they should be listed here. +One phy per port. Each port should have its reg entry with a consecutive +number. Also it should contain phys and phy-names entries specifying the +phy used by the port. Example (Sequoia 440EPx): ehci@e300 { @@ -23,3 +27,34 @@ Example (Sequoia 440EPx): reg = <0 e300 90 0 e390 70>; big-endian; }; + +Example (Exynos 4212): +ehci@1258 { +compatible = "samsung,exynos4210-ehci"; +reg = <0x1258 0x2>; +interrupts = <0 70 0>; +clocks = <&clock 304>, <&clock 305>; +clock-names = "usbhost", "otg"; +status = "disabled"; +#address-cells = <1>; +#size-cells = <0>; +port@0 { +reg = <0>; +phys = <&usb2phy 1>; +phy-names = "host"; +status = "disabled"; +}; +port@1 { +reg = <1>; +phys = <&usb2phy 2>; +phy-names = "hsic0"; +status = "disabled"; +}; +port@2 { +reg = <2>; +phys = <&usb2phy 3>; +phy-names = "hsic1"; +status = "disabled"; +}; +}; + diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index d1d8c47..7c35501 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -19,12 +19,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include "ehci.h" @@ -42,10 +42,10 @@ static const char hcd_name[] = "ehci-exynos"; static struct hc_driver __read_mostly exynos_ehci_hc_driver; +#define PHY_NUMBER 3 struct exynos_ehci_hcd { struct clk *clk; - struct usb_phy *phy; - struct usb_otg *otg; + struct phy *phy[PHY_NUMBER]; }; #define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv) @@ -69,13 +69,43 @@ static void exynos_setup_vbus_gpio(struct platform_device *pdev) dev_err(dev, "can't request ehci vbus gpio %d", gpio); } +static int exynos_phys_on(struct phy *p[]) +{ + int i; + int ret = 0; + + for (i = 0; ret == 0 && i < PHY_NUMBER; i++) + if (p[i]) + ret = phy_power_on(p[i]); + if (ret) + for (i--; i > 0; i--) + if (p[i]) + phy_power_off(p[i]); + + return ret; +} + +static int exynos_phys_off(struct phy *p[]) +{ + int i; + int ret = 0; + + for (i = 0; ret == 0 && i < PHY_NUMBER; i++) + if (p[i]) + ret = phy_power_off(p[i]); + + return ret; +} + static int exynos_ehci_probe(struct platform_device *pdev) { struct exynos_ehci_hcd *exynos_ehci; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct resource *res; - struct usb_phy *phy; + struct phy *phy; + struct device_node *child; + int phy_number; int irq; int err; @@ -102,14 +132,26 @@ static int exynos_ehci_probe(struct platform_device *pdev) "samsung,exynos5440-ehci")) goto skip_phy; - phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR(phy)) { - usb_put_hcd(hcd); - dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); - return -EPROBE_DEFER; - } else { - exynos_ehci->phy = phy; - exynos_ehci->otg = phy->otg; + for_each_available_child_of_node(pdev->dev.of_node, child) { + err = of_property_read_u32(child, "reg", &phy_number); + if (err) { + dev_err(&pdev->dev, "Failed to parse device tree\n"); + of_node_put(child); + return err; + } + if (phy_number >= PHY_NUMBER) { + dev_err(&pdev->dev, "Failed to parse
[PATCH v5 3/9] phy: Add new Exynos USB 2.0 PHY driver
Add a new driver for the Exynos USB 2.0 PHY. The new driver uses the generic PHY framework. The driver includes support for the Exynos 4x10 and 4x12 SoC families. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park --- .../devicetree/bindings/phy/samsung-phy.txt| 55 drivers/phy/Kconfig| 29 ++ drivers/phy/Makefile |3 + drivers/phy/phy-exynos4210-usb2.c | 257 drivers/phy/phy-exynos4212-usb2.c | 306 drivers/phy/phy-samsung-usb2.c | 226 +++ drivers/phy/phy-samsung-usb2.h | 67 + 7 files changed, 943 insertions(+) create mode 100644 drivers/phy/phy-exynos4210-usb2.c create mode 100644 drivers/phy/phy-exynos4212-usb2.c create mode 100644 drivers/phy/phy-samsung-usb2.c create mode 100644 drivers/phy/phy-samsung-usb2.h diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index c0fccaa..39d52cc 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -20,3 +20,58 @@ Required properties: - compatible : should be "samsung,exynos5250-dp-video-phy"; - reg : offset and length of the Display Port PHY register set; - #phy-cells : from the generic PHY bindings, must be 0; + +Samsung S5P/EXYNOS SoC series USB PHY +- + +Required properties: +- compatible : should be one of the listed compatibles: + - "samsung,exynos4210-usb2-phy" + - "samsung,exynos4212-usb2-phy" +- reg : a list of registers used by phy driver + - first and obligatory is the location of phy modules registers +- samsung,sysreg-phandle - handle to syscon used to control the system registers +- samsung,pmureg-phandle - handle to syscon used to control PMU registers +- #phy-cells : from the generic phy bindings, must be 1; +- clocks and clock-names: + - the "phy" clocks is required by the phy module + - next for each of the phys a clock has to be assigned, this clock + will be used to determine clocking frequency for the phys + (the labels are specified in the paragraph below) + +The first phandle argument in the PHY specifier identifies the PHY, its +meaning is compatible dependent. For the currently supported SoCs (Exynos 4210 +and Exynos 4212) it is as follows: + 0 - USB device ("device"), + 1 - USB host ("host"), + 2 - HSIC0 ("hsic0"), + 3 - HSIC1 ("hsic1"), + +Exynos 4210 and Exynos 4212 use mode switching and require that mode switch +register is supplied. + +Example: + +For Exynos 4412 (compatible with Exynos 4212): + +usbphy: phy@125b { + compatible = "samsung,exynos4212-usb2-phy"; + reg = <0x125b 0x100 0x10020704 0x0c 0x1001021c 0x4>; + clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>, + <&clock 2>; + clock-names = "phy", "device", "host", "hsic0", "hsic1"; + status = "okay"; + #phy-cells = <1>; + samsung,sysreg-phandle = <&sys_reg>; + samsung,pmureg-phandle = <&pmu_reg>; +}; + +Then the PHY can be used in other nodes such as: + +phy-consumer@1234 { + phys = <&usbphy 2>; + phy-names = "phy"; +}; + +Refer to DT bindings documentation of particular PHY consumer devices for more +information about required PHYs and the way of specification. diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index a344f3d..8e5cce1 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -51,4 +51,33 @@ config PHY_EXYNOS_DP_VIDEO help Support for Display Port PHY found on Samsung EXYNOS SoCs. +config PHY_SAMSUNG_USB2 + tristate "Samsung USB 2.0 PHY driver" + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the Samsung USB 2.0 PHY driver for Samsung + SoCs. This driver provides the interface for USB 2.0 PHY. Support for + particular SoCs has to be enabled in addition to this driver. Number + and type of supported phys depends on the SoC. + +config PHY_EXYNOS4210_USB2 + bool "Support for Exynos 4210" + depends on PHY_SAMSUNG_USB2 + depends on CPU_EXYNOS4210 + help + Enable USB PHY support for Exynos 4210. This option requires that + Samsung USB 2.0 PHY driver is enabled and means that support for this + particular SoC is compiled in the driver. In case of Exynos 4210 four + phys are available - device, host, HSCI0 and HSCI1. + +config PHY_EXYNOS4212_USB2 + bool "Support for Exynos 4212" + depends on PHY_SAMSUNG_USB2 + depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) + help + Enable USB PHY support for Exynos 4212. This option requires that + Samsung USB 2.0 PHY driver is enab
[PATCH v5 5/9] usb: s3c-hsotg: Use the new Exynos USB phy driver with the generic phy framework
Change the used phy driver to the new Exynos USB phy driver that uses the generic phy framework. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park --- .../devicetree/bindings/usb/samsung-hsotg.txt |4 drivers/usb/gadget/s3c-hsotg.c | 11 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/samsung-hsotg.txt b/Documentation/devicetree/bindings/usb/samsung-hsotg.txt index b83d428..75edb9d 100644 --- a/Documentation/devicetree/bindings/usb/samsung-hsotg.txt +++ b/Documentation/devicetree/bindings/usb/samsung-hsotg.txt @@ -24,6 +24,8 @@ Required properties: - first entry: must be "otg" - vusb_d-supply: phandle to voltage regulator of digital section, - vusb_a-supply: phandle to voltage regulator of analog section. +- phys: from general PHY binding: phandle to the PHY device +- phy-names: from general PHY binding: should be "usb2-phy" Example - @@ -36,5 +38,7 @@ Example clock-names = "otg"; vusb_d-supply = <&vusb_reg>; vusb_a-supply = <&vusbdac_reg>; + phys = <&usb2phy 0>; + phy-names = "usb2-phy"; }; diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 7aedaaf..a05c2f9 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -162,7 +163,7 @@ struct s3c_hsotg_ep { struct s3c_hsotg { struct device*dev; struct usb_gadget_driver *driver; - struct usb_phy *phy; + struct phy *phy; struct s3c_hsotg_plat*plat; spinlock_t lock; @@ -2910,7 +2911,7 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); if (hsotg->phy) - usb_phy_init(hsotg->phy); + phy_power_on(hsotg->phy); else if (hsotg->plat->phy_init) hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); } @@ -2927,7 +2928,7 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev); if (hsotg->phy) - usb_phy_shutdown(hsotg->phy); + phy_power_off(hsotg->phy); else if (hsotg->plat->phy_exit) hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); } @@ -3534,7 +3535,7 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) static int s3c_hsotg_probe(struct platform_device *pdev) { struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev); - struct usb_phy *phy; + struct phy *phy; struct device *dev = &pdev->dev; struct s3c_hsotg_ep *eps; struct s3c_hsotg *hsotg; @@ -3549,7 +3550,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) return -ENOMEM; } - phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + phy = devm_phy_get(&pdev->dev, "usb2-phy"); if (IS_ERR(phy)) { /* Fallback for pdata */ plat = dev_get_platdata(&pdev->dev); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 8/9] dts: Add usb2phy to Exynos 4
Add support to PHY of USB2 of the Exynos 4 SoC. Signed-off-by: Kamil Debski --- .../devicetree/bindings/arm/samsung/pmu.txt|2 ++ arch/arm/boot/dts/exynos4.dtsi | 31 arch/arm/boot/dts/exynos4210.dtsi | 17 +++ arch/arm/boot/dts/exynos4x12.dtsi | 17 +++ 4 files changed, 67 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt index 307e727..bfccab0 100644 --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt @@ -3,6 +3,8 @@ SAMSUNG Exynos SoC series PMU Registers Properties: - name : should be 'syscon'; - compatible : should contain two values. First value must be one from following list: + - "samsung,exynos4210-pmu" - for Exynos4210 SoC, + - "samsung,exynos4212-pmu" - for Exynos4212 SoC, - "samsung,exynos5250-pmu" - for Exynos5250 SoC, - "samsung,exynos5420-pmu" - for Exynos5420 SoC. second value must be always "syscon". diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index a73eeb5..031d07a 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -253,6 +253,17 @@ status = "disabled"; }; + usbotg@1248 { + compatible = "samsung,s3c6400-hsotg"; + reg = <0x1248 0x2>; + interrupts = <0 71 0>; + clocks = <&clock 305>; + clock-names = "otg"; + phys = <&usb2phy 0>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + ehci@1258 { compatible = "samsung,exynos4210-ehci"; reg = <0x1258 0x100>; @@ -260,6 +271,26 @@ clocks = <&clock 304>; clock-names = "usbhost"; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + phys = <&usb2phy 1>; + phy-names = "host"; + reg = <0>; + status = "disabled"; + }; + port@1 { + phys = <&usb2phy 2>; + phy-names = "hsic0"; + reg = <1>; + status = "disabled"; + }; + port@2 { + phys = <&usb2phy 3>; + phy-names = "hsic1"; + reg = <2>; + status = "disabled"; + }; }; ohci@1259 { diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index 057d682..f9d06bb 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -155,4 +155,21 @@ samsung,lcd-wb; }; }; + + pmu_reg: syscon@1002 { + compatible = "samsung,exynos4210-pmu", "syscon"; + reg = <0x1002 0x4000>; + }; + + usb2phy: phy@125B { + compatible = "samsung,exynos4210-usb2-phy"; + reg = <0x125B 0x100>; + clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>, + <&clock 2>; + clock-names = "phy", "device", "host", "hsic0", "hsic1"; + status = "disabled"; + #phy-cells = <1>; + samsung,sysreg-phandle = <&sys_reg>; + samsung,pmureg-phandle = <&pmu_reg>; + }; }; diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index ad531fe..712 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -176,4 +176,21 @@ }; }; }; + + pmu_reg: syscon@1002 { + compatible = "samsung,exynos4212-pmu", "syscon"; + reg = <0x1002 0x4000>; + }; + + usb2phy: phy@125B { + compatible = "samsung,exynos4212-usb2-phy"; + reg = <0x125B 0x100>; + clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>, + <&clock 2>; + clock-names = "phy", "device", "host", "hsic0", "hsic1"; + status = "disabled"; + #phy-cells = <1>; + samsung,sysreg-phandle = <&sys_reg>; + samsung,pmureg-phandle = <&pmu_reg>; + }; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 7/9] phy: Add Exynos 5250 support to the Exynos USB 2.0 PHY driver
Add support for Exynos 5250. This driver is to replace the old USB 2.0 PHY driver. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park --- .../devicetree/bindings/phy/samsung-phy.txt|1 + drivers/phy/Kconfig| 11 + drivers/phy/Makefile |1 + drivers/phy/phy-exynos5250-usb2.c | 356 drivers/phy/phy-samsung-usb2.c |6 + drivers/phy/phy-samsung-usb2.h |1 + 6 files changed, 376 insertions(+) create mode 100644 drivers/phy/phy-exynos5250-usb2.c diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index eb40460..afc47c2 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -29,6 +29,7 @@ Required properties: - "samsung,s5pv210-usb2-phy" - "samsung,exynos4210-usb2-phy" - "samsung,exynos4212-usb2-phy" + - "samsung,exynos5250-usb2-phy" - reg : a list of registers used by phy driver - first and obligatory is the location of phy modules registers - samsung,sysreg-phandle - handle to syscon used to control the system registers diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index b2c51ce..726410f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -90,4 +90,15 @@ config PHY_EXYNOS4212_USB2 Samsung USB 2.0 PHY driver is enabled and means that support for this particular SoC is compiled in the driver. In case of Exynos 4212 four phys are available - device, host, HSIC0 and HSIC1. + +config PHY_EXYNOS5250_USB2 + bool "Support for Exynos 5250" + depends on PHY_SAMSUNG_USB2 + depends on SOC_EXYNOS5250 + help + Enable USB PHY support for Exynos 5250. This option requires that + Samsung USB 2.0 PHY driver is enabled and means that support for this + particular SoC is compiled in the driver. In case of Exynos 5250 four + phys are available - device, host, HSIC0 and HSIC. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index fefc6c2..33c3ac1 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_PHY_SAMSUNG_USB2)+= phy-samsung-usb2.o obj-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o obj-$(CONFIG_PHY_EXYNOS4212_USB2) += phy-exynos4212-usb2.o +obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c new file mode 100644 index 000..b9b3b98 --- /dev/null +++ b/drivers/phy/phy-exynos5250-usb2.c @@ -0,0 +1,356 @@ +/* + * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Kamil Debski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "phy-samsung-usb2.h" + +/* Exynos USB PHY registers */ +#define EXYNOS_5250_REFCLKSEL_CRYSTAL 0x0 +#define EXYNOS_5250_REFCLKSEL_XO 0x1 +#define EXYNOS_5250_REFCLKSEL_CLKCORE 0x2 + +#define EXYNOS_5250_FSEL_9MHZ6 0x0 +#define EXYNOS_5250_FSEL_10MHZ 0x1 +#define EXYNOS_5250_FSEL_12MHZ 0x2 +#define EXYNOS_5250_FSEL_19MHZ20x3 +#define EXYNOS_5250_FSEL_20MHZ 0x4 +#define EXYNOS_5250_FSEL_24MHZ 0x5 +#define EXYNOS_5250_FSEL_50MHZ 0x7 + +/* Normal host */ +#define EXYNOS_5250_HOSTPHYCTRL0 0x0 + +#define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL BIT(31) +#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT 19 +#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_MASK\ + (0x3 << EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT) +#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT16 +#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK \ + (0x7 << EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT) +#define EXYNOS_5250_HOSTPHYCTRL0_TESTBURNINBIT(11) +#define EXYNOS_5250_HOSTPHYCTRL0_RETENABLE BIT(10) +#define EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N BIT(9) +#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_MASK(0x3 << 7) +#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_DUAL(0x0 << 7) +#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ID0 (0x1 << 7) +#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ANALOGTEST (0x2 << 7) +#define EXYNOS_5250_HOSTPHYCTRL0_SIDDQ BIT(6) +#define EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEPBIT(5) +#define EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND BIT(4) +#define EXYNOS_5250_HOSTPHYCTRL0_WORDINTERFACE BIT(3) +#define EXYNOS_5250_H
[PATCH v2 9/9] dts: Add usb2phy to Exynos 5250
Add support to PHY of USB2 of the Exynos 5250 SoC. Signed-off-by: Kamil Debski --- arch/arm/boot/dts/exynos5250.dtsi | 33 --- drivers/phy/phy-exynos5250-usb2.c | 64 + 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 2f264ad..922e0ed 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -163,6 +163,11 @@ interrupts = <0 47 0>; }; + sys_syscon: syscon@1004 { + compatible = "samsung,exynos5250-sys", "syscon"; + reg = <0x1005 0x5000>; + }; + pmu_syscon: syscon@1004 { compatible = "samsung,exynos5250-pmu", "syscon"; reg = <0x1004 0x5000>; @@ -505,6 +510,14 @@ clocks = <&clock 285>; clock-names = "usbhost"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + phys = <&usb2_phy 1>; + phy-names = "host"; + status = "ok"; + }; }; usb@1212 { @@ -516,19 +529,15 @@ clock-names = "usbhost"; }; - usb2_phy: usbphy@1213 { - compatible = "samsung,exynos5250-usb2phy"; + usb2_phy: phy@1213 { + compatible = "samsung,exynos5250-usb2-phy"; reg = <0x1213 0x100>; - clocks = <&clock 1>, <&clock 285>; - clock-names = "ext_xtal", "usbhost"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - usbphy-sys { - reg = <0x10040704 0x8>, - <0x10050230 0x4>; - }; + clocks = <&clock 285>, <&clock 1>, <&clock 1>, <&clock 1>, + <&clock 1>; + clock-names = "phy", "device", "host", "hsic0", "hsic1"; + #phy-cells = <1>; + samsung,sysreg-phandle = <&sys_syscon>; + samsung,pmureg-phandle = <&pmu_syscon>; }; amba { diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c index b9b3b98..337bf82 100644 --- a/drivers/phy/phy-exynos5250-usb2.c +++ b/drivers/phy/phy-exynos5250-usb2.c @@ -58,7 +58,13 @@ #define EXYNOS_5250_HOSTPHYCTRL2 0x20 #define EXYNOS_5250_HOSTPHYCTRLX_REFCLKSEL_MASK(0x3 << 23) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKSEL_DEFAULT (0x2 << 23) #define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_MASK(0x7f << 16) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_12 (0x24 << 16) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_15 (0x1c << 16) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_16 (0x1a << 16) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_19_2(0x15 << 16) +#define EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_20 (0x14 << 16) #define EXYNOS_5250_HOSTPHYCTRLX_SIDDQ BIT(6) #define EXYNOS_5250_HOSTPHYCTRLX_FORCESLEEPBIT(5) #define EXYNOS_5250_HOSTPHYCTRLX_FORCESUSPEND BIT(4) @@ -191,13 +197,14 @@ static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); } -static void exynos5250_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) +static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst) { struct samsung_usb2_phy_driver *drv = inst->drv; u32 ctrl0; u32 otg; u32 ehci; u32 ohci; + u32 hsic; switch (inst->cfg->id) { case EXYNOS5250_DEVICE: @@ -234,6 +241,8 @@ static void exynos5250_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) break; case EXYNOS5250_HOST: + case EXYNOS5250_HSIC0: + case EXYNOS5250_HSIC1: /* Host registers configuration */ ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); /* The clock */ @@ -279,6 +288,18 @@ static void exynos5250_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET); + /* HSIC phy configuration */ + hsic = (EXYNOS_5250_HOSTPHYCTRLX_REFCLKDIV_12 | + EXYNOS_5250_HOSTPHYCTRLX_REFCLKSEL_DEFAULT | + EXYNOS_5250_HOSTPHYCTRLX_PHYSWRST); + writel(hsic, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL1); + writel(hsic, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL2); + udelay(10); + hsic &= ~EXYNOS_5250_HOSTPHYCTRLX_PHYSWRST;
[PATCH RFC alternative ver 2] phy: Exynos 421x USB 2.0 PHY support
This the alternative version of the support for Exynos 421x USB 2.0 PHY in the Generic PHY framework. In this version the support for Exynos 4210 and 4212 was joined into one file. Signed-off-by: Kamil Debski --- Hi, This is the second alternative version. Please look at "[PATCH RFC alternative ver 1] phy: Exynos 421x USB 2.0 PHY support" for detailed description. Best wishes, Kamil Debski --- drivers/phy/phy-exynos4212-usb2.c | 452 + drivers/phy/phy-samsung-usb2.h|1 + 2 files changed, 453 insertions(+) create mode 100644 drivers/phy/phy-exynos4212-usb2.c diff --git a/drivers/phy/phy-exynos4212-usb2.c b/drivers/phy/phy-exynos4212-usb2.c new file mode 100644 index 000..8f7578a --- /dev/null +++ b/drivers/phy/phy-exynos4212-usb2.c @@ -0,0 +1,452 @@ +/* + * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4210 and 4212 support + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Kamil Debski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "phy-samsung-usb2.h" + +/* Exynos USB PHY registers */ + +/* PHY power control */ +#define EXYNOS_421x_UPHYPWR0x0 + +#define EXYNOS_421x_UPHYPWR_PHY0_SUSPEND BIT(0) +#define EXYNOS_421x_UPHYPWR_PHY0_PWR BIT(3) +#define EXYNOS_421x_UPHYPWR_PHY0_OTG_PWR BIT(4) +#define EXYNOS_421x_UPHYPWR_PHY0_SLEEP BIT(5) +#define EXYNOS_421x_UPHYPWR_PHY0 ( \ + EXYNOS_421x_UPHYPWR_PHY0_SUSPEND | \ + EXYNOS_421x_UPHYPWR_PHY0_PWR | \ + EXYNOS_421x_UPHYPWR_PHY0_OTG_PWR | \ + EXYNOS_421x_UPHYPWR_PHY0_SLEEP) + +#define EXYNOS_421x_UPHYPWR_PHY1_SUSPEND BIT(6) +#define EXYNOS_421x_UPHYPWR_PHY1_PWR BIT(7) +#define EXYNOS_421x_UPHYPWR_PHY1_SLEEP BIT(8) +#define EXYNOS_421x_UPHYPWR_PHY1 ( \ + EXYNOS_421x_UPHYPWR_PHY1_SUSPEND | \ + EXYNOS_421x_UPHYPWR_PHY1_PWR | \ + EXYNOS_421x_UPHYPWR_PHY1_SLEEP) + +#define EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND BIT(9) +#define EXYNOS_4210_UPHYPWR_HSCI0_SLEEPBIT(10) +#define EXYNOS_4210_UPHYPWR_HSCI0 ( \ + EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND | \ + EXYNOS_4210_UPHYPWR_HSCI0_SLEEP) + +#define EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND BIT(11) +#define EXYNOS_4210_UPHYPWR_HSCI1_SLEEPBIT(12) +#define EXYNOS_4210_UPHYPWR_HSCI1 ( \ + EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND | \ + EXYNOS_4210_UPHYPWR_HSCI1_SLEEP) + +#define EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND BIT(9) +#define EXYNOS_4212_UPHYPWR_HSCI0_PWR BIT(10) +#define EXYNOS_4212_UPHYPWR_HSCI0_SLEEPBIT(11) +#define EXYNOS_4212_UPHYPWR_HSCI0 ( \ + EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND | \ + EXYNOS_4212_UPHYPWR_HSCI0_PWR | \ + EXYNOS_4212_UPHYPWR_HSCI0_SLEEP) + +#define EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND BIT(12) +#define EXYNOS_4212_UPHYPWR_HSCI1_PWR BIT(13) +#define EXYNOS_4212_UPHYPWR_HSCI1_SLEEPBIT(14) +#define EXYNOS_4212_UPHYPWR_HSCI1 ( \ + EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND | \ + EXYNOS_4212_UPHYPWR_HSCI1_PWR | \ + EXYNOS_4212_UPHYPWR_HSCI1_SLEEP) + +/* PHY clock control */ +#define EXYNOS_421x_UPHYCLK0x4 + +#define EXYNOS_421x_UPHYCLK_PHY0_COMMON_ON BIT(4) +#define EXYNOS_421x_UPHYCLK_PHY1_COMMON_ON BIT(7) + +#define EXYNOS_4210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) + +#define EXYNOS_4210_UPHYCLK_PHY0_ID_PULLUP BIT(2) + +#define EXYNOS_4212_UPHYCLK_PHYFSEL_MASK (0x7 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_9MHZ6 (0x0 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_10MHZ (0x1 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_19MHZ2 (0x3 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_20MHZ (0x4 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0) + +#define EXYNOS_4212_UPHYCLK_PHY0_ID_PULLUP BIT(3) + +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_MASK (0x7f << 10) +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_12MHZ (0x24 << 10) +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_15MHZ (0x1c << 10) +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_16MHZ (0x1a << 10) +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_19MHZ2 (0x15 << 10) +#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_20MHZ (0x14 << 10) + +/* PHY reset control */ +#define EXYNOS_421x_UPHYRST0x8 + +#define EXYNOS_421x_URSTCON_PHY0 BIT(0) +#define EXYNOS_421x_URSTCON_OTG_HLINK BIT(1) +#define EXYNOS_421x_URSTCON_OTG_PHYLINKBIT(2) + +#define EXYNOS_4210_URSTCON_PHY1_ALL
[PATCH RFC alternative ver 1] phy: Exynos 421x USB 2.0 PHY support
This the alternative version of the support for Exynos 421x USB 2.0 PHY in the Generic PHY framework. In this version the support for Exynos 4210 and 4212 was joined into one file. Signed-off-by: Kamil Debski --- Hi, Me and Kishon were discussing for quite a long time the way how Exynos 4 should be handled. I have decided to post the original patches and try to make an alternative version with support for Exynos 4210 and 4212 joined in one file. I have prepared two versions. The first one has 506 lines (vs 563 when two files are used). When doing the second version I was a little more aggresive in removing code. This was done at a cost of adding if's deciding which SoC version the driver is dealing with in some internal functions. This resulted in a better number of removed lines - the second version has only 452 lines (vs 563 original and 506 version 1). Personally I like the original approach. One of my goals was to create a driver that would be clear and easy to understand. I see that this was done at a cost of having the code a little longer. The first alternative version mostly was done by removing duplicate defines of register values. The code clarity suffers a bit, but is still acceptable in my opinion. As to the second alternative version. It has the fewest lines, but I am not an enthusiast of using "if this is SoC" in functions. Anyway - please have a look at these two alternative versions in addition to looking at the original patch "phy: Add new Exynos USB PHY driver". Best wishes, Kamil Debski --- drivers/phy/phy-exynos4212-usb2.c | 506 + 1 file changed, 506 insertions(+) create mode 100644 drivers/phy/phy-exynos4212-usb2.c diff --git a/drivers/phy/phy-exynos4212-usb2.c b/drivers/phy/phy-exynos4212-usb2.c new file mode 100644 index 000..3fa22d0 --- /dev/null +++ b/drivers/phy/phy-exynos4212-usb2.c @@ -0,0 +1,506 @@ +/* + * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4210 and 4212 support + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Kamil Debski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "phy-samsung-usb2.h" + +/* Exynos USB PHY registers */ + +/* PHY power control */ +#define EXYNOS_421x_UPHYPWR0x0 + +#define EXYNOS_421x_UPHYPWR_PHY0_SUSPEND BIT(0) +#define EXYNOS_421x_UPHYPWR_PHY0_PWR BIT(3) +#define EXYNOS_421x_UPHYPWR_PHY0_OTG_PWR BIT(4) +#define EXYNOS_421x_UPHYPWR_PHY0_SLEEP BIT(5) +#define EXYNOS_421x_UPHYPWR_PHY0 ( \ + EXYNOS_421x_UPHYPWR_PHY0_SUSPEND | \ + EXYNOS_421x_UPHYPWR_PHY0_PWR | \ + EXYNOS_421x_UPHYPWR_PHY0_OTG_PWR | \ + EXYNOS_421x_UPHYPWR_PHY0_SLEEP) + +#define EXYNOS_421x_UPHYPWR_PHY1_SUSPEND BIT(6) +#define EXYNOS_421x_UPHYPWR_PHY1_PWR BIT(7) +#define EXYNOS_421x_UPHYPWR_PHY1_SLEEP BIT(8) +#define EXYNOS_421x_UPHYPWR_PHY1 ( \ + EXYNOS_421x_UPHYPWR_PHY1_SUSPEND | \ + EXYNOS_421x_UPHYPWR_PHY1_PWR | \ + EXYNOS_421x_UPHYPWR_PHY1_SLEEP) + +#define EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND BIT(9) +#define EXYNOS_4210_UPHYPWR_HSCI0_SLEEPBIT(10) +#define EXYNOS_4210_UPHYPWR_HSCI0 ( \ + EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND | \ + EXYNOS_4210_UPHYPWR_HSCI0_SLEEP) + +#define EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND BIT(11) +#define EXYNOS_4210_UPHYPWR_HSCI1_SLEEPBIT(12) +#define EXYNOS_4210_UPHYPWR_HSCI1 ( \ + EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND | \ + EXYNOS_4210_UPHYPWR_HSCI1_SLEEP) + +#define EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND BIT(9) +#define EXYNOS_4212_UPHYPWR_HSCI0_PWR BIT(10) +#define EXYNOS_4212_UPHYPWR_HSCI0_SLEEPBIT(11) +#define EXYNOS_4212_UPHYPWR_HSCI0 ( \ + EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND | \ + EXYNOS_4212_UPHYPWR_HSCI0_PWR | \ + EXYNOS_4212_UPHYPWR_HSCI0_SLEEP) + +#define EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND BIT(12) +#define EXYNOS_4212_UPHYPWR_HSCI1_PWR BIT(13) +#define EXYNOS_4212_UPHYPWR_HSCI1_SLEEPBIT(14) +#define EXYNOS_4212_UPHYPWR_HSCI1 ( \ + EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND | \ + EXYNOS_4212_UPHYPWR_HSCI1_PWR | \ + EXYNOS_4212_UPHYPWR_HSCI1_SLEEP) + +/* PHY clock control */ +#define EXYNOS_421x_UPHYCLK0x4 + +#define EXYNOS_421x_UPHYCLK_PHY0_COMMON_ON BIT(4) +#define EXYNOS_421x_UPHYCLK_PHY1_COMMON_ON BIT(7) + +#define EXYNOS_4210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) +#define EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) + +#define EXYNOS_4210_UPHYCLK_PHY0_ID_PULLUP BIT(2) + +#define EXYNOS_4212_UPHYCLK_PHYFSEL_MASK (0x7 << 0) +#define EXYNOS_4212_UPHYCLK_PHYFSEL_9MHZ6
[PATCH v5 6/9] phy: Add support for S5PV210 to the Exynos USB 2.0 PHY driver
From: Mateusz Krawczuk Add support for the Samsung's S5PV210 SoC to the Exynos USB 2.0 PHY driver. Signed-off-by: Mateusz Krawczuk [k.deb...@samsung.com: cleanup and commit description] [k.deb...@samsung.com: make changes accordingly to the mailing list comments] Signed-off-by: Kamil Debski --- .../devicetree/bindings/phy/samsung-phy.txt|1 + drivers/phy/Kconfig| 10 + drivers/phy/Makefile |1 + drivers/phy/phy-s5pv210-usb2.c | 199 drivers/phy/phy-samsung-usb2.c |6 + drivers/phy/phy-samsung-usb2.h |1 + 6 files changed, 218 insertions(+) create mode 100644 drivers/phy/phy-s5pv210-usb2.c diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 39d52cc..eb40460 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -26,6 +26,7 @@ Samsung S5P/EXYNOS SoC series USB PHY Required properties: - compatible : should be one of the listed compatibles: + - "samsung,s5pv210-usb2-phy" - "samsung,exynos4210-usb2-phy" - "samsung,exynos4212-usb2-phy" - reg : a list of registers used by phy driver diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8e5cce1..b2c51ce 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -61,6 +61,16 @@ config PHY_SAMSUNG_USB2 particular SoCs has to be enabled in addition to this driver. Number and type of supported phys depends on the SoC. +config PHY_S5PV210_USB2 + bool "Support for S5PV210" + depends on PHY_SAMSUNG_USB2 + depends on ARCH_S5PV210 + help + Enable USB PHY support for S5PV210. This option requires that Samsung + USB 2.0 PHY driver is enabled and means that support for this + particular SoC is compiled in the driver. In case of S5PV210 two phys + are available - device and host. + config PHY_EXYNOS4210_USB2 bool "Support for Exynos 4210" depends on PHY_SAMSUNG_USB2 diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 9f4befd..fefc6c2 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o obj-$(CONFIG_OMAP_USB2)+= phy-omap-usb2.o obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-samsung-usb2.o +obj-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o obj-$(CONFIG_PHY_EXYNOS4212_USB2) += phy-exynos4212-usb2.o diff --git a/drivers/phy/phy-s5pv210-usb2.c b/drivers/phy/phy-s5pv210-usb2.c new file mode 100644 index 000..58797a7 --- /dev/null +++ b/drivers/phy/phy-s5pv210-usb2.c @@ -0,0 +1,199 @@ +/* + * Samsung SoC USB 1.1/2.0 PHY driver - S5PV210 support + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Authors: Kamil Debski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include "phy-samsung-usb2.h" + +/* Exynos USB PHY registers */ + +/* PHY power control */ +#define S5PV210_UPHYPWR0x0 + +#define S5PV210_UPHYPWR_PHY0_SUSPEND BIT(0) +#define S5PV210_UPHYPWR_PHY0_PWR BIT(3) +#define S5PV210_UPHYPWR_PHY0_OTG_PWR BIT(4) +#define S5PV210_UPHYPWR_PHY0 ( \ + S5PV210_UPHYPWR_PHY0_SUSPEND | \ + S5PV210_UPHYPWR_PHY0_PWR | \ + S5PV210_UPHYPWR_PHY0_OTG_PWR) + +#define S5PV210_UPHYPWR_PHY1_SUSPEND BIT(6) +#define S5PV210_UPHYPWR_PHY1_PWR BIT(7) +#define S5PV210_UPHYPWR_PHY1 ( \ + S5PV210_UPHYPWR_PHY1_SUSPEND | \ + S5PV210_UPHYPWR_PHY1_PWR) + +/* PHY clock control */ +#define S5PV210_UPHYCLK0x4 + +#define S5PV210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) +#define S5PV210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) +#define S5PV210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) +#define S5PV210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) + +#define S5PV210_UPHYCLK_PHY0_ID_PULLUP BIT(2) +#define S5PV210_UPHYCLK_PHY0_COMMON_ON BIT(4) +#define S5PV210_UPHYCLK_PHY1_COMMON_ON BIT(7) + +/* PHY reset control */ +#define S5PV210_UPHYRST0x8 + +#define S5PV210_URSTCON_PHY0 BIT(0) +#define S5PV210_URSTCON_OTG_HLINK BIT(1) +#define S5PV210_URSTCON_OTG_PHYLINKBIT(2) +#define S5PV210_URSTCON_PHY1_ALL BIT(3) +#define S5PV210_URSTCON_HOST_LINK_ALL BIT(4) + +/* Isolation, configured in the power management unit */ +#define S5PV210_USB_ISOL_DEVICE_OFFSET 0x704 +#define S5PV210_USB_ISOL_DEVICEBIT(0) +#define S5PV210_USB_ISOL_HOST_OFFSET 0x708 +#define S5PV210_USB_ISOL_HOST
[PATCH v4 2/9] phy: core: Add devm_of_phy_get to phy-core
Adding devm_of_phy_get will allow to get phys by supplying a pointer to the struct device_node instead of struct device. Signed-off-by: Kamil Debski --- drivers/phy/phy-core.c | 31 +++ include/linux/phy/phy.h |2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index d6f8c34..0551cc3 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -450,6 +450,37 @@ struct phy *devm_phy_get(struct device *dev, const char *string) EXPORT_SYMBOL_GPL(devm_phy_get); /** + * devm_of_phy_get() - lookup and obtain a reference to a phy. + * @dev: device that requests this phy + * @np: node containing the phy + * @con_id: name of the phy from device's point of view + * + * Gets the phy using of_phy_get(), and associates a device with it using + * devres. On driver detach, release function is invoked on the devres data, + * then, devres data is freed. + */ +struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, + const char *con_id) +{ + struct phy **ptr, *phy; + + ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + phy = of_phy_get(np, con_id); + if (!IS_ERR(phy)) { + *ptr = phy; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return phy; +} +EXPORT_SYMBOL_GPL(devm_of_phy_get); + +/** * phy_create() - create a new phy * @dev: device that is creating the new phy * @ops: function pointers for performing phy operations diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index bcb6274..864914c 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -129,6 +129,8 @@ int phy_power_on(struct phy *phy); int phy_power_off(struct phy *phy); struct phy *phy_get(struct device *dev, const char *string); struct phy *devm_phy_get(struct device *dev, const char *string); +struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, + const char *con_id); void phy_put(struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); struct phy *of_phy_get(struct device_node *np, const char *con_id); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/9] phy: Add new Exynos USB 2.0 PHY driver
Hi, This is the fifth version of the patchset. It adds a new Exynos USB 2.0 PHY driver. The driver uses the Generic PHY Framework. I would like to thank everyone who contributed with comments and took the time to read through the patches in the previous versions of this patchset. We had a lengthy discussion with Kishon about how the driver should look like. This patchset contains the updated version of my original idea, where support for Exynos 4210 and 4212 is done in separate files. Kishon's idea is to join these two into a single file. I have prepared two alternative version which I will send soon after this patchset. Just like the fourth version this patch depends on: [PATCH V11 1/3] ARM: dts: Add pmu sysreg node to exynos5250 and exynos5420 dtsi files [1]. Best wishes, Kamil Debski [1] - http://www.spinics.net/lists/linux-samsung-soc/msg24528.html Changes from v4: 1) phy: core: Add an exported of_phy_get function - the new exported function of_phy_get was changed to take the phy's name as a parameter instead of the index 2) phy: core: Add devm_of_phy_get to phy-core - fixes made in the comments to devm_of_phy_get 3) phy: Add new Exynos USB PHY driver - move the documentation from a new to an existing file - samsung-phy.txt - fix typos and uppercase hex addresses - add more explanations to Kconfig (checkpatch still complains, but I find it hard to think what else could I add) - add selects MFD_SYSCON as the driver needs it (Thank you, Tobias!) - cleanup included headers in both *.c and .h files - use BIT(x) macro instead of (1 << x) - replaced HOST and DEV with PHY0 and PHY1 in phy-exynos4212-usb2.c, the registers are described as PHYx in the documentation hence the decision to leave the PHYx naming - fixed typo in exynos4210_rate_to_clk reg -> *reg - change hax_mode_switch and enabled type to bool 4) usb: ehci-s5p: Change to use phy provided by the generic phy framework - Put the issue of phy->otg in order - since the new phy driver does not provide this field. With the new driver the switch between host and device is done in power_on of the respective host and device phys. 5) usb: s3c-hsotg: Use the new Exynos USB phy driver with the generic phy framework - fixed the example in the documentation 6) phy: Add support for S5PV210 to the Exynos USB PHY driver - include files cleanup - use BIT(x) macro instead of (1 << x) 7) phy: Add Exynos 5250 support to the Exynos USB 2.0 PHY driver - include files cleanup - use BIT(x) macro instead of (1 << x) 8) dts: Add usb2phy to Exynos 4 - no changes 9) dts: Add usb2phy to Exynos 5250 - no changes Changes from v3: - using PMU and system registers indirectly via syscon - change labelling - change Kconfig name - fixed typos/stray whitespace - move of_phy_provider_register() to the end of probe - add a regular error return code to the rate_to_clk functions - cleanup code and remove unused code - change struct names to avoid collisions - add mechanism to support multiple phys by the ehci driver Changes from v2: - rebase all patches to the usb-next branch - fixes in the documentation file - remove wrong entries in the phy node (ranges, and #address- & #size-cells) - add clocks and clock-names as required properites - rephrase a few sentences - fixes in the ehci-exynos.c file - move phy_name variable next to phy in exynos_ehci_hcd - remove otg from exynos_ehci_hcd as it was no longer used - move devm_phy_get after the Exynos5440 skip_phy check - fixes in the s3c-hsotg.c file - cosmetic fixes (remove empty line that was wrongfully added) - fixes in the main driver - remove cpu_type in favour for a boolean flag matched with the compatible value - rename files, structures, variables and Kconfig entires - change from simple "uphy" to "usb2_phy" - fix multiline comments style - simplify #ifdefs in of_device_id - fix Kconfig description - change dev_info to dev_dbg where reasonable - cosmetic changes (remove wrongful blank lines) - remove unnecessary reference counting Changes from v1: - the changes include minor fixes of the hardware initialization of the PHY module - some other minor fixes were introduced -- Original cover letter: Hi, This patch adds a new drive for USB PHYs for Samsung SoCs. The driver is using the Generic PHY Framework created by Kishon Vijay Abrahan I. It can be found here https://lkml.org/lkml/2013/8/21/29. This patch adds support to Exynos4 family of SoCs. Support for Exynos3 and Exynos5 is planned to be added in the near future. I welcome your comments. -- [1] https://lkml.org/lkml/2013/8/21/29 Kamil Debski (8): phy: core: Add an exported of_phy_get function phy: core: Add devm_of_phy_get to phy-core phy: Add new Exynos USB PHY driver usb: ehci-s5p: Change to use phy provided by the generic phy framework usb: s3c-hsotg: Use the new Exynos USB phy driver with the
[PATCH v4 1/9] phy: core: Add an exported of_phy_get function
Previously the of_phy_get function took a struct device * and was declared static. It was impossible to call it from another driver and thus it was impossible to get phy defined for a given node. The old function was renamed to _of_phy_get and was left for internal use. of_phy_get function was added and it was exported. The function enables to get a phy for a given device tree node. Signed-off-by: Kamil Debski --- drivers/phy/phy-core.c | 45 - include/linux/phy/phy.h |1 + 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 03cf8fb..d6f8c34 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -240,8 +240,8 @@ out: EXPORT_SYMBOL_GPL(phy_power_off); /** - * of_phy_get() - lookup and obtain a reference to a phy by phandle - * @dev: device that requests this phy + * _of_phy_get() - lookup and obtain a reference to a phy by phandle + * @np: device_node for which to get the phy * @index: the index of the phy * * Returns the phy associated with the given phandle value, @@ -250,20 +250,17 @@ EXPORT_SYMBOL_GPL(phy_power_off); * not yet loaded. This function uses of_xlate call back function provided * while registering the phy_provider to find the phy instance. */ -static struct phy *of_phy_get(struct device *dev, int index) +static struct phy *_of_phy_get(struct device_node *np, int index) { int ret; struct phy_provider *phy_provider; struct phy *phy = NULL; struct of_phandle_args args; - ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells", + ret = of_parse_phandle_with_args(np, "phys", "#phy-cells", index, &args); - if (ret) { - dev_dbg(dev, "failed to get phy in %s node\n", - dev->of_node->full_name); + if (ret) return ERR_PTR(-ENODEV); - } mutex_lock(&phy_provider_mutex); phy_provider = of_phy_provider_lookup(args.np); @@ -283,6 +280,36 @@ err0: } /** + * of_phy_get() - lookup and obtain a reference to a phy using a device_node. + * @np: device_node for which to get the phy + * @con_id: name of the phy from device's point of view + * + * Returns the phy driver, after getting a refcount to it; or + * -ENODEV if there is no such phy. The caller is responsible for + * calling phy_put() to release that count. + */ +struct phy *of_phy_get(struct device_node *np, const char *con_id) +{ + struct phy *phy = NULL; + int index = 0; + + if (con_id) + index = of_property_match_string(np, "phy-names", con_id); + + phy = _of_phy_get(np, index); + if (IS_ERR(phy)) + return phy; + + if (!try_module_get(phy->ops->owner)) + return ERR_PTR(-EPROBE_DEFER); + + get_device(&phy->dev); + + return phy; +} +EXPORT_SYMBOL_GPL(of_phy_get); + +/** * phy_put() - release the PHY * @phy: the phy returned by phy_get() * @@ -370,7 +397,7 @@ struct phy *phy_get(struct device *dev, const char *string) if (dev->of_node) { index = of_property_match_string(dev->of_node, "phy-names", string); - phy = of_phy_get(dev, index); + phy = _of_phy_get(dev->of_node, index); if (IS_ERR(phy)) { dev_err(dev, "unable to find phy\n"); return phy; diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 6d72269..bcb6274 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -131,6 +131,7 @@ struct phy *phy_get(struct device *dev, const char *string); struct phy *devm_phy_get(struct device *dev, const char *string); void phy_put(struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); +struct phy *of_phy_get(struct device_node *np, const char *con_id); struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args *args); struct phy *phy_create(struct device *dev, const struct phy_ops *ops, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
poweroff during boot
Good morning I'm writing to you for a problem. I would like use live USB on a hardware encrypted drive with onboard hardware numpad. The system power off usb during boot, so i must reinsert keycode on drive and complete boot manually. Is it possible prevent usb poweroff during boot? Thankyou -- Stefano Butti Ticyweb Sagl Corso San Gottardo, 32 6830 Chiasso Tel. +41.91.682.11.27 Fax +41.91.682.11.28 http://www.ticyweb.ch -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: cdc-wdm: avoid hanging on zero length reads
commit 73e06865ead1 ("USB: cdc-wdm: support back-to-back USB_CDC_NOTIFY_RESPONSE_AVAILABLE notifications") implemented queued response handling. This added a new requirement: The read urb must be resubmitted every time we clear the WDM_READ flag if the response counter indicates that the device is waiting for a read. Fix by factoring out the code handling the WMD_READ clearing and possible urb submission, calling it everywhere we clear the flag. Without this fix, the driver ends up in a state where the read urb is inactive, but the response counter is positive after a zero length read. This prevents the read urb from ever being submitted again and the driver appears to be hanging. Fixes: 73e06865ead1 ("USB: cdc-wdm: support back-to-back USB_CDC_NOTIFY_RESPONSE_AVAILABLE notifications") Cc: Greg Suarez Signed-off-by: Bjørn Mork --- drivers/usb/class/cdc-wdm.c | 70 +++ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 0b23a8639311..590ff8b5aa20 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -432,6 +432,38 @@ outnl: return rv < 0 ? rv : count; } +/* + * clear WDM_READ flag and possibly submit the read urb if resp_count + * is non-zero. + * + * Called with desc->iuspin locked + */ +static int clear_wdm_read_flag(struct wdm_device *desc) +{ + int rv = 0; + + clear_bit(WDM_READ, &desc->flags); + + /* submit read urb only if the device is waiting for it */ + if (!--desc->resp_count) + goto out; + + set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); + rv = usb_submit_urb(desc->response, GFP_KERNEL); + spin_lock_irq(&desc->iuspin); + if (rv) { + dev_err(&desc->intf->dev, + "usb_submit_urb failed with result %d\n", rv); + + /* make sure the next notification trigger a submit */ + clear_bit(WDM_RESPONDING, &desc->flags); + desc->resp_count = 0; + } +out: + return rv; +} + static ssize_t wdm_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos) { @@ -503,8 +535,10 @@ retry: if (!desc->reslength) { /* zero length read */ dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); - clear_bit(WDM_READ, &desc->flags); + rv = clear_wdm_read_flag(desc); spin_unlock_irq(&desc->iuspin); + if (rv < 0) + goto err; goto retry; } cntr = desc->length; @@ -526,37 +560,9 @@ retry: desc->length -= cntr; /* in case we had outstanding data */ - if (!desc->length) { - clear_bit(WDM_READ, &desc->flags); - - if (--desc->resp_count) { - set_bit(WDM_RESPONDING, &desc->flags); - spin_unlock_irq(&desc->iuspin); - - rv = usb_submit_urb(desc->response, GFP_KERNEL); - if (rv) { - dev_err(&desc->intf->dev, - "%s: usb_submit_urb failed with result %d\n", - __func__, rv); - spin_lock_irq(&desc->iuspin); - clear_bit(WDM_RESPONDING, &desc->flags); - spin_unlock_irq(&desc->iuspin); - - if (rv == -ENOMEM) { - rv = schedule_work(&desc->rxwork); - if (rv) - dev_err(&desc->intf->dev, "Cannot schedule work\n"); - } else { - spin_lock_irq(&desc->iuspin); - desc->resp_count = 0; - spin_unlock_irq(&desc->iuspin); - } - } - } else - spin_unlock_irq(&desc->iuspin); - } else - spin_unlock_irq(&desc->iuspin); - + if (!desc->length) + clear_wdm_read_flag(desc); + spin_unlock_irq(&desc->iuspin); rv = cntr; err: -- 1.7.10.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 v4] kconfig/symbol.c: handle choice_values that depend on 'm' symbols
On 11/18/2013 07:08 PM, Yann E. MORIN wrote: > Dirk, All, Hi Yann, > Acked-by: "Yann E. MORIN" > > It will be in my tree soon. Thanks! I've been looking at gitorious.org:linux-kconfig/linux-kconfig.git into the yem/kconfig-for-next and kconfig-rc-fixes branch and haven't found it. Didn't you push your tree out or do you use another git tree for that? Sebastian -- 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:
Do you need business or personal loan? Reply back with details -- 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 v7 07/14] usb: phy-mxs: change description of usb device speed
> From: Peter Chen > Sent: 20 December 2013 07:52 > Change "high speed" to "HS" > Change "non-high speed" to "FS/LS" > > Implementation of notify_suspend and notify_resume will be different > according to mxs_phy_data->flags. > > Signed-off-by: Peter Chen > --- > drivers/usb/phy/phy-mxs-usb.c |8 > 1 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c > index 0ef930a..489096f 100644 > --- a/drivers/usb/phy/phy-mxs-usb.c > +++ b/drivers/usb/phy/phy-mxs-usb.c > @@ -166,8 +166,8 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) > static int mxs_phy_on_connect(struct usb_phy *phy, > enum usb_device_speed speed) > { > - dev_dbg(phy->dev, "%s speed device has connected\n", > - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); > + dev_dbg(phy->dev, "%s device has connected\n", > + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); Seems you are making these messages even more cryptic. With all the speeds that USB supports remembering what 'full' means is hard enough without having a cryptic acronym. David -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1] xhci: Switch Intel Lynx Point ports to EHCI on shutdown
> Also, which kernel are you experiencing this issue on? In 3.12, I > queued a separate patch to deal with spurious reboot issues on Lynx > Point: > > commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 > Author: Takashi Iwai > Date: Thu Sep 12 08:11:06 2013 +0200 > > xhci: Fix spurious wakeups after S5 on Haswell > > Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show > mysterious wakeups after shutdown occasionally. After discussing with > BIOS engineers, they explained that the new BIOS expects that the > wakeup sources are cleared and set to D3 for all wakeup devices when > the system is going to sleep or power off, but the current xhci driver > doesn't do this properly (partly intentionally). > > This patch introduces a new quirk, XHCI_SPURIOUS_WAKEUP, for > fixing the spurious wakeups at S5 by calling xhci_reset() in the xhci > shutdown ops as done in xhci_stop(), and setting the device to PCI D3 > at shutdown and remove ops. > > The PCI D3 call is based on the initial fix patch by Oliver Neukum. > > [Note: Sarah changed the quirk name from XHCI_HSW_SPURIOUS_WAKEUP to > XHCI_SPURIOUS_WAKEUP, since none of the other quirks have system names > in them. Sarah also fixed a collision with a quirk submitted around the > same time, by changing the xhci->quirks bit from 17 to 18.] > > This patch should be backported to kernels as old as 3.0, that > contain the commit 1c12443ab8eba71a658fae4572147e56d1f84f66 "xhci: Add > Lynx Point to list of Intel switchable hosts." > > Cc: Oliver Neukum > Signed-off-by: Takashi Iwai > Signed-off-by: Sarah Sharp > Cc: sta...@vger.kernel.org > > This patch is in 3.12, but a patch to narrow the quirk to only apply HP > systems > will hit 3.13 shortly: Sorry, I indeed tested not on the latest kernel version, Ubuntu 3.13-rc3 has this patch and it works for me. Denis -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] USB: phy: Fix double lock in OTG FSM
Mutex obtained at the beginning of the function should be released at the end to avoid double locking. Signed-off-by: Anton Tikhomirov --- drivers/usb/phy/phy-fsm-usb.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c index 6223872..65c3a72 100644 --- a/drivers/usb/phy/phy-fsm-usb.c +++ b/drivers/usb/phy/phy-fsm-usb.c @@ -357,7 +357,7 @@ int otg_statemachine(struct otg_fsm *fsm) default: break; } - mutex_lock(&fsm->lock); + mutex_unlock(&fsm->lock); VDBG("quit statemachine, changed = %d\n", state_changed); return state_changed; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] USB: core: remove CONFIG_USB_DEBUG usage
> From: Greg Kroah-Hartman > CONFIG_USB_DEBUG is going away, so remove the few places in the USB core > that relied on them. > > This means that we always now do the "debug" checks for every urb > submitted, which is a good idea, as who knows how many driver bugs we > have been ignoring when people forget to enable this option. Also, with > the overall speed of USB, doing these extra checks should not cause any > additional overhead. Well USB3 isn't that slow, and the new version coming along soon is even faster. Running gigabit ethernet on usb3 shows a significantly higher cpu cost than when using a normal ethernet adapter - and really the actual operations required are very similar. ... > /* Check that the pipe's type matches the endpoint's type */ > if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) It looks as though it ought to be possible to make that check: if (unlikely(xfertype != urb->pipe->valid_xfertype)) David -- 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/1] usb: gadget: f_fs: Add support for SuperSpeed Mode
On 11/26/2013 11:11 PM, Felipe Balbi wrote: > > any comments here ? nobody ? Manu, if nobody complains in another week, > please send this hunk as a formal patch. > I have just sent a Patch (v3). Thanks, Manu -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/1] usb: gadget: f_fs: Add support for SuperSpeed Mode
Allow userspace to pass SuperSpeed descriptors and handle them in the driver accordingly. This change doesn't modify existing desc_header and thereby keeps the ABI changes backward compatible i.e. existing userspace drivers compiled with old header (functionfs.h) would continue to work with the updated kernel. Signed-off-by: Manu Gautam --- drivers/usb/gadget/f_fs.c | 165 drivers/usb/gadget/u_fs.h | 8 +- include/uapi/linux/usb/functionfs.h | 5 ++ 3 files changed, 140 insertions(+), 38 deletions(-) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 306a2b5..65bc861 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -122,8 +122,8 @@ struct ffs_ep { struct usb_ep *ep;/* P: ffs->eps_lock */ struct usb_request *req; /* P: epfile->mutex */ - /* [0]: full speed, [1]: high speed */ - struct usb_endpoint_descriptor *descs[2]; + /* [0]: full speed, [1]: high speed, [2]: super speed */ + struct usb_endpoint_descriptor *descs[3]; u8 num; @@ -1184,9 +1184,12 @@ static void ffs_data_reset(struct ffs_data *ffs) ffs->stringtabs = NULL; ffs->raw_descs_length = 0; - ffs->raw_fs_descs_length = 0; + ffs->raw_fs_hs_descs_length = 0; + ffs->raw_ss_descs_offset = 0; + ffs->raw_ss_descs_length = 0; ffs->fs_descs_count = 0; ffs->hs_descs_count = 0; + ffs->ss_descs_count = 0; ffs->strings_count = 0; ffs->interfaces_count = 0; @@ -1329,7 +1332,20 @@ static int ffs_func_eps_enable(struct ffs_function *func) spin_lock_irqsave(&func->ffs->eps_lock, flags); do { struct usb_endpoint_descriptor *ds; - ds = ep->descs[ep->descs[1] ? 1 : 0]; + int desc_idx; + + if (ffs->gadget->speed == USB_SPEED_SUPER) + desc_idx = 2; + else if (ffs->gadget->speed == USB_SPEED_HIGH) + desc_idx = 1; + else + desc_idx = 0; + + ds = ep->descs[desc_idx]; + if (!ds) { + ret = -EINVAL; + break; + } ep->ep->driver_data = ep; ep->ep->desc = ds; @@ -1464,6 +1480,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, } break; + case USB_DT_SS_ENDPOINT_COMP: + pr_vdebug("EP SS companion descriptor\n"); + if (length != sizeof(struct usb_ss_ep_comp_descriptor)) + goto inv_length; + break; + case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_INTERFACE_POWER: case USB_DT_DEBUG: @@ -1574,8 +1596,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, static int __ffs_data_got_descs(struct ffs_data *ffs, char *const _data, size_t len) { - unsigned fs_count, hs_count; - int fs_len, ret = -EINVAL; + unsigned fs_count, hs_count, ss_count = 0; + int fs_len, hs_len, ss_len, ss_magic, ret = -EINVAL; char *data = _data; ENTER(); @@ -1586,9 +1608,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, fs_count = get_unaligned_le32(data + 8); hs_count = get_unaligned_le32(data + 12); - if (!fs_count && !hs_count) - goto einval; - data += 16; len -= 16; @@ -1607,22 +1626,59 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, } if (likely(hs_count)) { - ret = ffs_do_descs(hs_count, data, len, + hs_len = ffs_do_descs(hs_count, data, len, __ffs_data_do_entity, ffs); - if (unlikely(ret < 0)) + if (unlikely(hs_len < 0)) { + ret = hs_len; + goto error; + } + } else { + hs_len = 0; + } + + if ((len >= hs_len + 8)) { + /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */ + ss_magic = get_unaligned_le32(data + hs_len); + if (ss_magic != FUNCTIONFS_SS_DESC_MAGIC) + goto einval; + + ss_count = get_unaligned_le32(data + hs_len + 4); + data += hs_len + 8; + len -= hs_len + 8; + } else { + data += hs_len; + len -= hs_len; + } + + if (!fs_count && !hs_count && !ss_count) + goto einval; + + if (ss_count) { + ss_len = ffs_do_descs(ss_count, data, len, + __ffs_data_do_entity, ffs); + if (unlikely(ss_len < 0)) { + ret = ss_len; goto error; + }
[PATCH 1/2] usb: musb: fix prototype for musb_port_reset
musb_port_reset() takes a 2nd arguments. This didn't hit us yet because this function was never called externally prior to the musb_hub_control cleanup patch. Signed-off-by: Daniel Mack --- drivers/usb/musb/musb_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 909ba49..7bbf01b 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h @@ -125,7 +125,7 @@ static inline void musb_host_resume_root_hub(struct musb *musb) {} static inline void musb_host_poll_rh_status(struct musb *musb) {} static inline void musb_host_poke_root_hub(struct musb *musb) {} static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {} -static inline void musb_port_reset(struct musb *musb) {} +static inline void musb_port_reset(struct musb *musb, bool do_reset) {} static inline void musb_host_finish_resume(struct work_struct *work) {} #endif -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] usb: musb: fix musb pointer acqusition in musb_host_finish_resume
This is a fall-out from "usb: musb: finish suspend/reset work independently from musb_hub_control()" that I missed because the MUSB_POWER register does not have the MUSB_POWER_SUSPENDM bit set on AM335x platforms; hence the code path was not travelled in my tests. Signed-off-by: Daniel Mack --- drivers/usb/musb/musb_virthub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index ad417fd..966cf95 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -50,7 +50,7 @@ void musb_host_finish_resume(struct work_struct *work) unsigned long flags; u8 power; - musb = container_of(work, struct musb, deassert_reset_work.work); + musb = container_of(work, struct musb, finish_resume_work.work); spin_lock_irqsave(&musb->lock, flags); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/7] drivers: usb: Include appropriate header file in hcd.c
> From: Josh Triplett > On Thu, Dec 19, 2013 at 05:33:09PM -, David Laight wrote: > > OTOH just including extra headers isn't ideal - it can considerably > > slow down the compilation time. There are many subsystems that don't > > really separate their internal headers from their external ones. > > There's a benefit to doing so, though: it ensures that the prototypes in > the header stay in sync with the definition. I think you misunderstood what I was saying. The header with the function prototypes has to be included when the driver itself is built - there is a gcc warning for that as well. The 'problem' is that if I only have: void foo(struct foo *); then the C language (uselessly) scopes the declaration of 'struct foo' to the inside of the functions - making it almost impossible to call. All you need is an outer declaration: struct foo; void foo(struct foo *); what you don't need is the actual definition of 'struct foo'. Source files that need to look at the members of the structure should be directly including the header that defines the structure. Adding nested includes just makes it more likely that code will fail to directly include the headers that define the structures it uses. David -- 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] xhci: Allocate the td array and urb_priv together.
> From: David Cohen > On Wed, Dec 18, 2013 at 11:24:47AM -, David Laight wrote: > > This saves a kzalloc() call on every transfer and some memory > > indirections. > > > > The only possible downside is for isochronous tranfers with 64 td > > when the allocate is 8+4096 bytes (on 64bit systems) so requires > > an additional page. > > If you take this to embedded world there could be a bad side effect too. > The free memory isn't abundant and the fragmentation may make a bigger > kmalloc() to cost more than 2 smaller ones. The effect of this change is really to remove the first allocation and add 8 bytes (or maybe a pointer) to the start of the second one. So it is extremely unlikely to fail when the old code would work. It would, of course, be better to allocate a parallel 'software' ring containing the required extra information and completely remove the additional allocate/free on every USB request. David -- 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] xhci: Allocate the td array and urb_priv together.
> From: Steve Calfee > On Wed, Dec 18, 2013 at 3:24 AM, David Laight wrote: > > > > This saves a kzalloc() call on every transfer and some memory > > indirections. > > > > The only possible downside is for isochronous tranfers with 64 td > > when the allocate is 8+4096 bytes (on 64bit systems) so requires > > an additional page. ... > Are you sure this will not cause weird bugs on non-cache coherent > systems? You are smashing two memory allocations into one. This does > not insure that the memory in each allocation is cache line aligned > does it? Arm and Mips systems don't like having two i/o actions or cpu > and i/o activity on data sharing a cache line. These are both internal data structures and not visible to the hardware. David
Re: [PATCH] USB: chipidea: fix error path
On Thu, Dec 19, 2013 at 04:28:54PM +0800, Peter Chen wrote: > On Thu, Dec 19, 2013 at 09:35:44AM +0100, Sascha Hauer wrote: > > devm_usb_get_phy_by_phandle() returns a PTR_ERR on failure, so we have > > to check for IS_ERR before calling usb_phy_shutdown(), not for NULL. > > > > Signed-off-by: Sascha Hauer > > Cc: Peter Chen > > Cc: linux-usb@vger.kernel.org > > --- > > drivers/usb/chipidea/ci_hdrc_imx.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c > > b/drivers/usb/chipidea/ci_hdrc_imx.c > > index be822a2..1b7ffc9 100644 > > --- a/drivers/usb/chipidea/ci_hdrc_imx.c > > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c > > @@ -165,7 +165,7 @@ static int ci_hdrc_imx_probe(struct platform_device > > *pdev) > > disable_device: > > ci_hdrc_remove_device(data->ci_pdev); > > err_phy: > > - if (data->phy) > > + if (!IS_ERR(data->phy)) > > usb_phy_shutdown(data->phy); > > err_clk: > > clk_disable_unprepare(data->clk); > > @@ -179,7 +179,7 @@ static int ci_hdrc_imx_remove(struct platform_device > > *pdev) > > pm_runtime_disable(&pdev->dev); > > ci_hdrc_remove_device(data->ci_pdev); > > > > - if (data->phy) > > + if (!IS_ERR(data->phy)) > > usb_phy_shutdown(data->phy); > > > > clk_disable_unprepare(data->clk); > > -- > > 1.8.5.1 > > > > Sascha, thanks for your patch. > > We have already moved PHY operation from glue layer to core, this > patch may not be needed. Ok, right. I missed these. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- 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 v7 12/14] usb: phy-mxs: Add implementation of set_wakeup
When we need the PHY can be waken up by external signals, we can call this API. Besides, we call mxs_phy_disconnect_line at this API to close the connection between USB PHY and controller, after that, the line state from controller is SE0. Once the PHY is out of power, without calling mxs_phy_disconnect_line, there are unknown wakeups due to dp/dm floating at device mode. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 116 + 1 files changed, 116 insertions(+), 0 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 09ece2b..d4812fc 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -31,6 +31,9 @@ #define HW_USBPHY_CTRL_SET 0x34 #define HW_USBPHY_CTRL_CLR 0x38 +#define HW_USBPHY_DEBUG_SET0x54 +#define HW_USBPHY_DEBUG_CLR0x58 + #define HW_USBPHY_IP 0x90 #define HW_USBPHY_IP_SET 0x94 #define HW_USBPHY_IP_CLR 0x98 @@ -39,6 +42,9 @@ #define BM_USBPHY_CTRL_CLKGATE BIT(30) #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) #define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATEBIT(25) +#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23) +#define BM_USBPHY_CTRL_ENIDCHG_WKUPBIT(22) +#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21) #define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20) #define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19) #define BM_USBPHY_CTRL_ENAUTO_PWRON_PLLBIT(18) @@ -48,6 +54,25 @@ #define BM_USBPHY_IP_FIX (BIT(17) | BIT(18)) +#define BM_USBPHY_DEBUG_CLKGATEBIT(30) + +/* Anatop Registers */ +#define ANADIG_USB1_VBUS_DET_STAT 0x1c0 +#define ANADIG_USB2_VBUS_DET_STAT 0x220 + +#define ANADIG_USB1_LOOPBACK_SET 0x1e4 +#define ANADIG_USB1_LOOPBACK_CLR 0x1e8 +#define ANADIG_USB2_LOOPBACK_SET 0x244 +#define ANADIG_USB2_LOOPBACK_CLR 0x248 + +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALIDBIT(3) +#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALIDBIT(3) + +#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2) +#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5) +#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2) +#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5) + #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) /* Do disconnection between PHY and controller without vbus */ @@ -146,6 +171,79 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) return 0; } +/* Return true if the vbus is there */ +static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy) +{ + unsigned int vbus_value; + + if (mxs_phy->port_id == 0) + regmap_read(mxs_phy->regmap_anatop, + ANADIG_USB1_VBUS_DET_STAT, + &vbus_value); + else if (mxs_phy->port_id == 1) + regmap_read(mxs_phy->regmap_anatop, + ANADIG_USB2_VBUS_DET_STAT, + &vbus_value); + + if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID) + return true; + else + return false; +} + +static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) +{ + void __iomem *base = mxs_phy->phy.io_priv; + u32 reg; + + if (disconnect) + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE, + base + HW_USBPHY_DEBUG_CLR); + + if (mxs_phy->port_id == 0) { + reg = disconnect ? ANADIG_USB1_LOOPBACK_SET + : ANADIG_USB1_LOOPBACK_CLR; + regmap_write(mxs_phy->regmap_anatop, reg, + BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 | + BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN); + } else if (mxs_phy->port_id == 1) { + reg = disconnect ? ANADIG_USB2_LOOPBACK_SET + : ANADIG_USB2_LOOPBACK_CLR; + regmap_write(mxs_phy->regmap_anatop, reg, + BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 | + BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN); + } + + if (!disconnect) + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE, + base + HW_USBPHY_DEBUG_SET); + + /* Delay some time, and let Linestate be SE0 for controller */ + if (disconnect) + usleep_range(500, 1000); +} + +static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) +{ + bool vbus_is_on = false; + + /* If the SoCs don't need to disconnect line without vbus, quit */ + if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS)) + return; + + /* If the SoCs don't have anatop, quit */ + if (!mxs_phy->regmap_anatop) +
[PATCH v7 06/14] usb: phy-mxs: Add anatop regmap
It is needed by imx6 SoC series, but not for imx23 and imx28. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 23 +-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 0c6f3bc..0ef930a 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #define DRIVER_NAME "mxs_phy" @@ -58,6 +60,9 @@ */ #define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2) +/* The SoCs who have anatop module */ +#define MXS_PHY_HAS_ANATOP BIT(3) + struct mxs_phy_data { unsigned int flags; }; @@ -68,11 +73,13 @@ static const struct mxs_phy_data imx23_phy_data = { static const struct mxs_phy_data imx6q_phy_data = { .flags = MXS_PHY_SENDING_SOF_TOO_FAST | - MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, + MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | + MXS_PHY_HAS_ANATOP, }; static const struct mxs_phy_data imx6sl_phy_data = { - .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | + MXS_PHY_HAS_ANATOP, }; static const struct of_device_id mxs_phy_dt_ids[] = { @@ -87,6 +94,7 @@ struct mxs_phy { struct usb_phy phy; struct clk *clk; const struct mxs_phy_data *data; + struct regmap *regmap_anatop; }; static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) @@ -190,6 +198,7 @@ static int mxs_phy_probe(struct platform_device *pdev) int ret; const struct of_device_id *of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev); + struct device_node *np = pdev->dev.of_node; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); @@ -226,6 +235,16 @@ static int mxs_phy_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mxs_phy); + if (mxs_phy->data->flags & MXS_PHY_HAS_ANATOP) { + mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle + (np, "fsl,anatop"); + if (IS_ERR(mxs_phy->regmap_anatop)) { + dev_dbg(&pdev->dev, + "failed to find regmap for anatop\n"); + return PTR_ERR(mxs_phy->regmap_anatop); + } + } + ret = usb_add_phy_dev(&mxs_phy->phy); if (ret) return ret; -- 1.7.8 -- 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 v7 08/14] usb: phy-mxs: Enable IC fixes for related SoCs
Two PHY bugs are fixed by IC logic, but these bits are not enabled by default, so we enable them at driver. The two bugs are: MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST which are described at code. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 23 +-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 489096f..f28bdd8 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -31,6 +31,10 @@ #define HW_USBPHY_CTRL_SET 0x34 #define HW_USBPHY_CTRL_CLR 0x38 +#define HW_USBPHY_IP 0x90 +#define HW_USBPHY_IP_SET 0x94 +#define HW_USBPHY_IP_CLR 0x98 + #define BM_USBPHY_CTRL_SFTRST BIT(31) #define BM_USBPHY_CTRL_CLKGATE BIT(30) #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) @@ -42,6 +46,8 @@ #define BM_USBPHY_CTRL_ENUTMILEVEL2BIT(14) #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) +#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18)) + #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) /* Do disconnection between PHY and controller without vbus */ @@ -63,6 +69,14 @@ /* The SoCs who have anatop module */ #define MXS_PHY_HAS_ANATOP BIT(3) +/* + * IC has bug fixes logic, they include + * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST + * which are described at above flags, the RTL will handle it + * according to different versions. + */ +#define MXS_PHY_NEED_IP_FIXBIT(4) + struct mxs_phy_data { unsigned int flags; }; @@ -74,12 +88,14 @@ static const struct mxs_phy_data imx23_phy_data = { static const struct mxs_phy_data imx6q_phy_data = { .flags = MXS_PHY_SENDING_SOF_TOO_FAST | MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | - MXS_PHY_HAS_ANATOP, + MXS_PHY_HAS_ANATOP | + MXS_PHY_NEED_IP_FIX, }; static const struct mxs_phy_data imx6sl_phy_data = { .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | - MXS_PHY_HAS_ANATOP, + MXS_PHY_HAS_ANATOP | + MXS_PHY_NEED_IP_FIX, }; static const struct of_device_id mxs_phy_dt_ids[] = { @@ -123,6 +139,9 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) BM_USBPHY_CTRL_ENUTMILEVEL3, base + HW_USBPHY_CTRL_SET); + if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) + writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); + return 0; } -- 1.7.8 -- 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 v7 04/14] usb: doc: phy-mxs: update binding for adding anatop phandle
Add anatop phandle which is used to access anatop registers to control PHY's power and other USB operations. Signed-off-by: Peter Chen --- Documentation/devicetree/bindings/usb/mxs-phy.txt |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mxs-phy.txt b/Documentation/devicetree/bindings/usb/mxs-phy.txt index b43d4c9e..fc6659d 100644 --- a/Documentation/devicetree/bindings/usb/mxs-phy.txt +++ b/Documentation/devicetree/bindings/usb/mxs-phy.txt @@ -5,10 +5,12 @@ Required properties: for imx6dq and imx6dl, "fsl,imx6sl-usbphy" for imx6sl - reg: Should contain registers location and length - interrupts: Should contain phy interrupt +- fsl,anatop: phandle for anatop register, it is only for imx6 SoC series Example: usbphy1: usbphy@020c9000 { compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; reg = <0x020c9000 0x1000>; interrupts = <0 44 0x04>; + fsl,anatop = <&anatop>; }; -- 1.7.8 -- 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 v7 05/14] ARM: dts: imx6: add anatop phandle for usbphy
Add anatop phandle for usbphy Signed-off-by: Peter Chen --- arch/arm/boot/dts/imx6qdl.dtsi |2 ++ arch/arm/boot/dts/imx6sl.dtsi |2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 59154dc..4e74962 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -557,6 +557,7 @@ reg = <0x020c9000 0x1000>; interrupts = <0 44 0x04>; clocks = <&clks 182>; + fsl,anatop = <&anatop>; }; usbphy2: usbphy@020ca000 { @@ -564,6 +565,7 @@ reg = <0x020ca000 0x1000>; interrupts = <0 45 0x04>; clocks = <&clks 183>; + fsl,anatop = <&anatop>; }; snvs@020cc000 { diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 28558f1..30322b5 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -489,6 +489,7 @@ reg = <0x020c9000 0x1000>; interrupts = <0 44 0x04>; clocks = <&clks IMX6SL_CLK_USBPHY1>; + fsl,anatop = <&anatop>; }; usbphy2: usbphy@020ca000 { @@ -496,6 +497,7 @@ reg = <0x020ca000 0x1000>; interrupts = <0 45 0x04>; clocks = <&clks IMX6SL_CLK_USBPHY2>; + fsl,anatop = <&anatop>; }; snvs@020cc000 { -- 1.7.8 -- 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 v7 03/14] usb: phy-mxs: Add auto clock and power setting
The auto setting is used to open related power and clocks automatically after receiving wakeup signal. With this feature, the PHY's clock and power can be recovered correctly from low power mode, it is guaranteed by IC logic. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 20 +--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 6d49040..0c6f3bc 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -31,6 +31,11 @@ #define BM_USBPHY_CTRL_SFTRST BIT(31) #define BM_USBPHY_CTRL_CLKGATE BIT(30) +#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) +#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATEBIT(25) +#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20) +#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19) +#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLLBIT(18) #define BM_USBPHY_CTRL_ENUTMILEVEL3BIT(15) #define BM_USBPHY_CTRL_ENUTMILEVEL2BIT(14) #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) @@ -96,9 +101,18 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) /* Power up the PHY */ writel(0, base + HW_USBPHY_PWD); - /* enable FS/LS device */ - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | - BM_USBPHY_CTRL_ENUTMILEVEL3, + /* +* USB PHY Ctrl Setting +* - Auto clock/power on +* - Enable full/low speed support +*/ + writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS | + BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE | + BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD | + BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE | + BM_USBPHY_CTRL_ENAUTO_PWRON_PLL | + BM_USBPHY_CTRL_ENUTMILEVEL2 | + BM_USBPHY_CTRL_ENUTMILEVEL3, base + HW_USBPHY_CTRL_SET); return 0; -- 1.7.8 -- 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 v7 09/14] ARM: dts: imx: add mxs phy controller id
We need to use controller id to access different register regions for mxs phy. Signed-off-by: Peter Chen --- arch/arm/boot/dts/imx23.dtsi |1 + arch/arm/boot/dts/imx28.dtsi |2 ++ arch/arm/boot/dts/imx6qdl.dtsi |2 ++ arch/arm/boot/dts/imx6sl.dtsi |2 ++ 4 files changed, 7 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index c96ceae..a231f3d 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi @@ -23,6 +23,7 @@ serial1 = &auart1; spi0 = &ssp0; spi1 = &ssp1; + usbphy0 = &usbphy0; }; cpus { diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index cda19c8..671dda0 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -32,6 +32,8 @@ serial4 = &auart4; spi0 = &ssp1; spi1 = &ssp2; + usbphy0 = &usbphy0; + usbphy1 = &usbphy1; }; cpus { diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 4e74962..c23803d 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -33,6 +33,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; }; intc: interrupt-controller@00a01000 { diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 30322b5..a06d939 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -27,6 +27,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; }; cpus { -- 1.7.8 -- 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 v7 10/14] usb: phy-mxs: add controller id
It is used to access un-regulator registers according to different controllers. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index f28bdd8..09ece2b 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -111,6 +111,7 @@ struct mxs_phy { struct clk *clk; const struct mxs_phy_data *data; struct regmap *regmap_anatop; + int port_id; }; static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) @@ -237,6 +238,13 @@ static int mxs_phy_probe(struct platform_device *pdev) return -ENOMEM; } + ret = of_alias_get_id(np, "usbphy"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return ret; + } + mxs_phy->port_id = ret; + mxs_phy->phy.io_priv= base; mxs_phy->phy.dev= &pdev->dev; mxs_phy->phy.label = DRIVER_NAME; -- 1.7.8 -- 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 v7 07/14] usb: phy-mxs: change description of usb device speed
Change "high speed" to "HS" Change "non-high speed" to "FS/LS" Implementation of notify_suspend and notify_resume will be different according to mxs_phy_data->flags. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 0ef930a..489096f 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -166,8 +166,8 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) static int mxs_phy_on_connect(struct usb_phy *phy, enum usb_device_speed speed) { - dev_dbg(phy->dev, "%s speed device has connected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + dev_dbg(phy->dev, "%s device has connected\n", + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); if (speed == USB_SPEED_HIGH) writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, @@ -179,8 +179,8 @@ static int mxs_phy_on_connect(struct usb_phy *phy, static int mxs_phy_on_disconnect(struct usb_phy *phy, enum usb_device_speed speed) { - dev_dbg(phy->dev, "%s speed device has disconnected\n", - (speed == USB_SPEED_HIGH) ? "high" : "non-high"); + dev_dbg(phy->dev, "%s device has disconnected\n", + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); if (speed == USB_SPEED_HIGH) writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, -- 1.7.8 -- 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 v7 14/14] usb: phy-mxs: Add sync time after controller clear phcd
After clear portsc.phcd, PHY needs 200us stable time for switch 32K clock to AHB clock. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index d75670a..6c3dae2 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -156,6 +156,15 @@ static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy) return mxs_phy->data == &imx6sl_phy_data; } +/* + * PHY needs some 32K cycles to switch from 32K clock to + * bus (such as AHB/AXI, etc) clock. + */ +static void mxs_phy_clock_switch_delay(void) +{ + usleep_range(300, 400); +} + static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) { int ret; @@ -281,6 +290,7 @@ static int mxs_phy_init(struct usb_phy *phy) { struct mxs_phy *mxs_phy = to_mxs_phy(phy); + mxs_phy_clock_switch_delay(); clk_prepare_enable(mxs_phy->clk); return mxs_phy_hw_init(mxs_phy); } @@ -305,6 +315,7 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) x->io_priv + HW_USBPHY_CTRL_SET); clk_disable_unprepare(mxs_phy->clk); } else { + mxs_phy_clock_switch_delay(); clk_prepare_enable(mxs_phy->clk); writel(BM_USBPHY_CTRL_CLKGATE, x->io_priv + HW_USBPHY_CTRL_CLR); -- 1.7.8 -- 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 v7 00/14] Add power management support for mxs phy
Hi Felipe & Shawn, The serial adds power management support for MXS PHY, it includes: - Add one PHY API .set_wakeup, and related API implementation at mxs phy driver - misc changes and bug fixes for mxs phy to support low power mode and wakeup. It is based on Greg's usb-next, 3.13-rc1. Changes for v7: - Fixed indentation problem at binding doc [1/14] - s/ganranteed/guaranteed, and add explanation for "auto setting" [3/14] - add static before SIMPLE_DEV_PM_OPS [13/14] - add one patch to change usb device description [7/14] - Delete the .nofity_suspend and .notify_resume due to Felipe does not agree to add them as PHY API, will use other ways to implement them in future. Changes for v6: - Add description for IC bug fixes logic. [9/15] - Move is_imx6q_phy and is_imx6sl_phy from [9/15] to [14/15] - %s/mxs_phy_clock_switch/mxs_phy_clock_switch_delay to reflect the function meaning more precise [15/15] Changes for v5: Add Marc and Michael Grzeschik's commnets - typo error at [2/15] - sqhash patches which introducing mxs_phy_disconnect_line and fixed but at this function. [13/15] - Introducing flag MXS_PHY_NEED_IP_FIX who stands for the SoCs who have IC fixes. [2/15, 8/15] - Delete one patch for low speed connection problem at every rare situations due to the root cause has still not found. Peter Chen (14): usb: doc: phy-mxs: Add more compatible strings usb: phy-mxs: Add platform judgement code usb: phy-mxs: Add auto clock and power setting usb: doc: phy-mxs: update binding for adding anatop phandle ARM: dts: imx6: add anatop phandle for usbphy usb: phy-mxs: Add anatop regmap usb: phy-mxs: change description of usb device speed usb: phy-mxs: Enable IC fixes for related SoCs ARM: dts: imx: add mxs phy controller id usb: phy-mxs: add controller id usb: phy: Add set_wakeup API usb: phy-mxs: Add implementation of set_wakeup usb: phy-mxs: Add system suspend/resume API usb: phy-mxs: Add sync time after controller clear phcd Documentation/devicetree/bindings/usb/mxs-phy.txt |5 +- arch/arm/boot/dts/imx23.dtsi |1 + arch/arm/boot/dts/imx28.dtsi |2 + arch/arm/boot/dts/imx6qdl.dtsi|4 + arch/arm/boot/dts/imx6sl.dtsi |4 + drivers/usb/phy/phy-mxs-usb.c | 314 - include/linux/usb/phy.h | 16 + 7 files changed, 331 insertions(+), 15 deletions(-) -- 1.7.8 -- 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 v7 01/14] usb: doc: phy-mxs: Add more compatible strings
Add "fsl,imx6q-usbphy" for imx6dq and imx6dl, add "fsl,imx6sl-usbphy" for imx6sl. Signed-off-by: Peter Chen --- Documentation/devicetree/bindings/usb/mxs-phy.txt |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mxs-phy.txt b/Documentation/devicetree/bindings/usb/mxs-phy.txt index 5835b27..b43d4c9e 100644 --- a/Documentation/devicetree/bindings/usb/mxs-phy.txt +++ b/Documentation/devicetree/bindings/usb/mxs-phy.txt @@ -1,7 +1,8 @@ * Freescale MXS USB Phy Device Required properties: -- compatible: Should be "fsl,imx23-usbphy" +- compatible: "fsl,imx23-usbphy" for imx23 and imx28, "fsl,imx6q-usbphy" + for imx6dq and imx6dl, "fsl,imx6sl-usbphy" for imx6sl - reg: Should contain registers location and length - interrupts: Should contain phy interrupt -- 1.7.8 -- 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 v7 02/14] usb: phy-mxs: Add platform judgement code
The mxs-phy has several bugs and features at different versions, the driver code can get it through of_device_id.data. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 58 ++-- 1 files changed, 49 insertions(+), 9 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 545844b..6d49040 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -1,5 +1,5 @@ /* - * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012-2013 Freescale Semiconductor, Inc. * Copyright (C) 2012 Marek Vasut * on behalf of DENX Software Engineering GmbH * @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_NAME "mxs_phy" @@ -34,13 +35,55 @@ #define BM_USBPHY_CTRL_ENUTMILEVEL2BIT(14) #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) + +/* Do disconnection between PHY and controller without vbus */ +#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0) + +/* + * The PHY will be in messy if there is a wakeup after putting + * bus to suspend (set portsc.suspendM) but before setting PHY to low + * power mode (set portsc.phcd). + */ +#define MXS_PHY_ABNORMAL_IN_SUSPENDBIT(1) + +/* + * The SOF sends too fast after resuming, it will cause disconnection + * between host and high speed device. + */ +#define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2) + +struct mxs_phy_data { + unsigned int flags; +}; + +static const struct mxs_phy_data imx23_phy_data = { + .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST, +}; + +static const struct mxs_phy_data imx6q_phy_data = { + .flags = MXS_PHY_SENDING_SOF_TOO_FAST | + MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, +}; + +static const struct mxs_phy_data imx6sl_phy_data = { + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, +}; + +static const struct of_device_id mxs_phy_dt_ids[] = { + { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, + { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, + { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); + struct mxs_phy { struct usb_phy phy; struct clk *clk; + const struct mxs_phy_data *data; }; -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) - static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) { int ret; @@ -131,6 +174,8 @@ static int mxs_phy_probe(struct platform_device *pdev) struct clk *clk; struct mxs_phy *mxs_phy; int ret; + const struct of_device_id *of_id = + of_match_device(mxs_phy_dt_ids, &pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); @@ -163,6 +208,7 @@ static int mxs_phy_probe(struct platform_device *pdev) ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); mxs_phy->clk = clk; + mxs_phy->data = of_id->data; platform_set_drvdata(pdev, mxs_phy); @@ -182,12 +228,6 @@ static int mxs_phy_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id mxs_phy_dt_ids[] = { - { .compatible = "fsl,imx23-usbphy", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); - static struct platform_driver mxs_phy_driver = { .probe = mxs_phy_probe, .remove = mxs_phy_remove, -- 1.7.8 -- 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 v7 11/14] usb: phy: Add set_wakeup API
This API is used to set wakeup enable at PHY registers, in that case, the PHY can be waken up from suspend due to external events, like vbus change, dp/dm change and id change. Signed-off-by: Peter Chen --- include/linux/usb/phy.h | 16 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 6c0b1c5..c2c6f49 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -111,6 +111,13 @@ struct usb_phy { int (*set_suspend)(struct usb_phy *x, int suspend); + /* +* Set wakeup enable for PHY, in that case, the PHY can be +* waken up from suspend status due to external events, +* like vbus change, dp/dm change and id. +*/ + int (*set_wakeup)(struct usb_phy *x, bool enabled); + /* notify phy connect status change */ int (*notify_connect)(struct usb_phy *x, enum usb_device_speed speed); @@ -265,6 +272,15 @@ usb_phy_set_suspend(struct usb_phy *x, int suspend) } static inline int +usb_phy_set_wakeup(struct usb_phy *x, bool enabled) +{ + if (x && x->set_wakeup) + return x->set_wakeup(x, enabled); + else + return 0; +} + +static inline int usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) { if (x && x->notify_connect) -- 1.7.8 -- 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 v7 13/14] usb: phy-mxs: Add system suspend/resume API
We need this to keep PHY's power on or off during the system suspend mode. If we need to enable USB wakeup, then we must keep PHY's power being on during the system suspend mode. Otherwise, we need to keep PHY's power being off to save power. Signed-off-by: Peter Chen --- drivers/usb/phy/phy-mxs-usb.c | 59 + 1 files changed, 59 insertions(+), 0 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index d4812fc..d75670a 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -57,6 +57,10 @@ #define BM_USBPHY_DEBUG_CLKGATEBIT(30) /* Anatop Registers */ +#define ANADIG_ANA_MISC0 0x150 +#define ANADIG_ANA_MISC0_SET 0x154 +#define ANADIG_ANA_MISC0_CLR 0x158 + #define ANADIG_USB1_VBUS_DET_STAT 0x1c0 #define ANADIG_USB2_VBUS_DET_STAT 0x220 @@ -65,6 +69,9 @@ #define ANADIG_USB2_LOOPBACK_SET 0x244 #define ANADIG_USB2_LOOPBACK_CLR 0x248 +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12) +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11) + #define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALIDBIT(3) #define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALIDBIT(3) @@ -139,6 +146,16 @@ struct mxs_phy { int port_id; }; +static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy) +{ + return mxs_phy->data == &imx6q_phy_data; +} + +static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy) +{ + return mxs_phy->data == &imx6sl_phy_data; +} + static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) { int ret; @@ -244,6 +261,22 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) } +static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on) +{ + unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR; + + /* If the SoCs don't have anatop, quit */ + if (!mxs_phy->regmap_anatop) + return; + + if (is_imx6q_phy(mxs_phy)) + regmap_write(mxs_phy->regmap_anatop, reg, + BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG); + else if (is_imx6sl_phy(mxs_phy)) + regmap_write(mxs_phy->regmap_anatop, + reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL); +} + static int mxs_phy_init(struct usb_phy *phy) { struct mxs_phy *mxs_phy = to_mxs_phy(phy); @@ -388,6 +421,8 @@ static int mxs_phy_probe(struct platform_device *pdev) } } + device_set_wakeup_capable(&pdev->dev, true); + ret = usb_add_phy_dev(&mxs_phy->phy); if (ret) return ret; @@ -404,6 +439,29 @@ static int mxs_phy_remove(struct platform_device *pdev) return 0; } +static int mxs_phy_system_suspend(struct device *dev) +{ + struct mxs_phy *mxs_phy = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + mxs_phy_enable_ldo_in_suspend(mxs_phy, true); + + return 0; +} + +static int mxs_phy_system_resume(struct device *dev) +{ + struct mxs_phy *mxs_phy = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + mxs_phy_enable_ldo_in_suspend(mxs_phy, false); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, + mxs_phy_system_resume); + static struct platform_driver mxs_phy_driver = { .probe = mxs_phy_probe, .remove = mxs_phy_remove, @@ -411,6 +469,7 @@ static struct platform_driver mxs_phy_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, .of_match_table = mxs_phy_dt_ids, + .pm = &mxs_phy_pm, }, }; -- 1.7.8 -- 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