From e1e499eef2200c2a7120c9ebf297d48b195cf887 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Oct 2009 05:15:25 +0000 Subject: usbnet: Use wwan%d interface name for mobile broadband devices Add support for usbnet based devices like CDC-Ether to indicate that they are actually mobile broadband devices. In that case use wwan%d as default interface name. Signed-off-by: Marcel Holtmann Signed-off-by: David S. Miller --- include/linux/usb/usbnet.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/usb') diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index f81473052059..86c31b753266 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -90,6 +90,7 @@ struct driver_info { #define FLAG_WLAN 0x0080 /* use "wlan%d" names */ #define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */ #define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */ +#define FLAG_WWAN 0x0400 /* use "wwan%d" names */ /* init device ... can sleep, or cause probe() failure */ -- cgit v1.2.3 From 37e8273cd30592d3a82bcb70cbb1bdc4eaeb6b71 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 4 Nov 2009 15:29:52 +0000 Subject: usbnet: Set link down initially for drivers that update link state Some usbnet drivers update link state while others do not due to hardware limitations. Add a flag to distinguish those that do, and set the link down initially for their devices. This is intended to fix this bug: http://bugs.debian.org/444043 Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 12 ++++++------ drivers/net/usb/cdc_ether.c | 2 +- drivers/net/usb/dm9601.c | 2 +- drivers/net/usb/usbnet.c | 4 +++- include/linux/usb/usbnet.h | 1 + 5 files changed, 12 insertions(+), 9 deletions(-) (limited to 'include/linux/usb') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6ce7f775bb74..1bef39a60a62 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1327,7 +1327,7 @@ static const struct driver_info ax8817x_info = { .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, .data = 0x00130103, }; @@ -1337,7 +1337,7 @@ static const struct driver_info dlink_dub_e100_info = { .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, .data = 0x009f9d9f, }; @@ -1347,7 +1347,7 @@ static const struct driver_info netgear_fa120_info = { .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, .data = 0x00130103, }; @@ -1357,7 +1357,7 @@ static const struct driver_info hawking_uf200_info = { .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, .data = 0x001f1d1f, }; @@ -1367,7 +1367,7 @@ static const struct driver_info ax88772_info = { .status = asix_status, .link_reset = ax88772_link_reset, .reset = ax88772_link_reset, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, .rx_fixup = asix_rx_fixup, .tx_fixup = asix_tx_fixup, }; @@ -1378,7 +1378,7 @@ static const struct driver_info ax88178_info = { .status = asix_status, .link_reset = ax88178_link_reset, .reset = ax88178_link_reset, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, .rx_fixup = asix_rx_fixup, .tx_fixup = asix_tx_fixup, }; diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 71d7ff3de99f..7ec24c9b2535 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -413,7 +413,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, // .check_connect = cdc_check_connect, .bind = cdc_bind, .unbind = usbnet_cdc_unbind, diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index a2b30a10064f..3d406f9b2f29 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -611,7 +611,7 @@ static int dm9601_link_reset(struct usbnet *dev) static const struct driver_info dm9601_info = { .description = "Davicom DM9601 USB Ethernet", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_LINK_INTR, .bind = dm9601_bind, .rx_fixup = dm9601_rx_fixup, .tx_fixup = dm9601_tx_fixup, diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 378da8c938fe..04f3f289e87c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1352,9 +1352,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // ok, it's ready to go. usb_set_intfdata (udev, dev); - // start as if the link is up netif_device_attach (net); + if (dev->driver_info->flags & FLAG_LINK_INTR) + netif_carrier_off(net); + return 0; out3: diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 86c31b753266..8c84881f8478 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -92,6 +92,7 @@ struct driver_info { #define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */ #define FLAG_WWAN 0x0400 /* use "wwan%d" names */ +#define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); -- cgit v1.2.3 From 69ee472f2706371ca639de49b06df91615c07d8d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Dec 2009 15:31:18 -0800 Subject: usbnet & cdc-ether: Autosuspend for online devices Using remote wakeup and delayed transmission to allow online device to go into usb autosuspend. Minimal alternate support for devices that don't support remote wakeup. Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 8 +++ drivers/net/usb/usbnet.c | 157 ++++++++++++++++++++++++++++++++++++-------- include/linux/usb/usbnet.h | 6 ++ 3 files changed, 142 insertions(+), 29 deletions(-) (limited to 'include/linux/usb') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 197912d9c04a..21e183a83b99 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -411,6 +411,12 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) return 0; } +static int cdc_manage_power(struct usbnet *dev, int on) +{ + dev->intf->needs_remote_wakeup = on; + return 0; +} + static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", .flags = FLAG_ETHER | FLAG_LINK_INTR, @@ -418,6 +424,7 @@ static const struct driver_info cdc_info = { .bind = cdc_bind, .unbind = usbnet_cdc_unbind, .status = cdc_status, + .manage_power = cdc_manage_power, }; static const struct driver_info mbm_info = { @@ -619,6 +626,7 @@ static struct usb_driver cdc_driver = { .suspend = usbnet_suspend, .resume = usbnet_resume, .reset_resume = usbnet_resume, + .supports_autosuspend = 1, }; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 511e7bdc4573..035fab04c0a0 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -353,7 +353,8 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) if (netif_running (dev->net) && netif_device_present (dev->net) && - !test_bit (EVENT_RX_HALT, &dev->flags)) { + !test_bit (EVENT_RX_HALT, &dev->flags) && + !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) { switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { case -EPIPE: usbnet_defer_kevent (dev, EVENT_RX_HALT); @@ -611,15 +612,39 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); /*-------------------------------------------------------------------------*/ // precondition: never called in_interrupt +static void usbnet_terminate_urbs(struct usbnet *dev) +{ + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); + DECLARE_WAITQUEUE(wait, current); + int temp; + + /* ensure there are no more active urbs */ + add_wait_queue(&unlink_wakeup, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + dev->wait = &unlink_wakeup; + temp = unlink_urbs(dev, &dev->txq) + + unlink_urbs(dev, &dev->rxq); + + /* maybe wait for deletions to finish. */ + while (!skb_queue_empty(&dev->rxq) + && !skb_queue_empty(&dev->txq) + && !skb_queue_empty(&dev->done)) { + schedule_timeout(UNLINK_TIMEOUT_MS); + set_current_state(TASK_UNINTERRUPTIBLE); + if (netif_msg_ifdown(dev)) + devdbg(dev, "waited for %d urb completions", + temp); + } + set_current_state(TASK_RUNNING); + dev->wait = NULL; + remove_wait_queue(&unlink_wakeup, &wait); +} int usbnet_stop (struct net_device *net) { struct usbnet *dev = netdev_priv(net); struct driver_info *info = dev->driver_info; - int temp; int retval; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); - DECLARE_WAITQUEUE (wait, current); netif_stop_queue (net); @@ -641,25 +666,8 @@ int usbnet_stop (struct net_device *net) info->description); } - if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) { - /* ensure there are no more active urbs */ - add_wait_queue(&unlink_wakeup, &wait); - dev->wait = &unlink_wakeup; - temp = unlink_urbs(dev, &dev->txq) + - unlink_urbs(dev, &dev->rxq); - - /* maybe wait for deletions to finish. */ - while (!skb_queue_empty(&dev->rxq) && - !skb_queue_empty(&dev->txq) && - !skb_queue_empty(&dev->done)) { - msleep(UNLINK_TIMEOUT_MS); - if (netif_msg_ifdown(dev)) - devdbg(dev, "waited for %d urb completions", - temp); - } - dev->wait = NULL; - remove_wait_queue(&unlink_wakeup, &wait); - } + if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) + usbnet_terminate_urbs(dev); usb_kill_urb(dev->interrupt); @@ -672,7 +680,10 @@ int usbnet_stop (struct net_device *net) dev->flags = 0; del_timer_sync (&dev->delay); tasklet_kill (&dev->bh); - usb_autopm_put_interface(dev->intf); + if (info->manage_power) + info->manage_power(dev, 0); + else + usb_autopm_put_interface(dev->intf); return 0; } @@ -753,6 +764,12 @@ int usbnet_open (struct net_device *net) // delay posting reads until we're fully open tasklet_schedule (&dev->bh); + if (info->manage_power) { + retval = info->manage_power(dev, 1); + if (retval < 0) + goto done; + usb_autopm_put_interface(dev->intf); + } return retval; done: usb_autopm_put_interface(dev->intf); @@ -881,11 +898,16 @@ kevent (struct work_struct *work) /* usb_clear_halt() needs a thread context */ if (test_bit (EVENT_TX_HALT, &dev->flags)) { unlink_urbs (dev, &dev->txq); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) + goto fail_pipe; status = usb_clear_halt (dev->udev, dev->out); + usb_autopm_put_interface(dev->intf); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_tx_err (dev)) +fail_pipe: deverr (dev, "can't clear tx halt, status %d", status); } else { @@ -896,11 +918,16 @@ kevent (struct work_struct *work) } if (test_bit (EVENT_RX_HALT, &dev->flags)) { unlink_urbs (dev, &dev->rxq); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) + goto fail_halt; status = usb_clear_halt (dev->udev, dev->in); + usb_autopm_put_interface(dev->intf); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_rx_err (dev)) +fail_halt: deverr (dev, "can't clear rx halt, status %d", status); } else { @@ -919,7 +946,12 @@ kevent (struct work_struct *work) clear_bit (EVENT_RX_MEMORY, &dev->flags); if (urb != NULL) { clear_bit (EVENT_RX_MEMORY, &dev->flags); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) + goto fail_lowmem; rx_submit (dev, urb, GFP_KERNEL); + usb_autopm_put_interface(dev->intf); +fail_lowmem: tasklet_schedule (&dev->bh); } } @@ -929,11 +961,18 @@ kevent (struct work_struct *work) int retval = 0; clear_bit (EVENT_LINK_RESET, &dev->flags); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) + goto skip_reset; if(info->link_reset && (retval = info->link_reset(dev)) < 0) { + usb_autopm_put_interface(dev->intf); +skip_reset: devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", retval, dev->udev->bus->bus_name, dev->udev->devpath, info->description); + } else { + usb_autopm_put_interface(dev->intf); } } @@ -971,6 +1010,7 @@ static void tx_complete (struct urb *urb) case -EPROTO: case -ETIME: case -EILSEQ: + usb_mark_last_busy(dev->udev); if (!timer_pending (&dev->delay)) { mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); @@ -987,6 +1027,7 @@ static void tx_complete (struct urb *urb) } } + usb_autopm_put_interface_async(dev->intf); urb->dev = NULL; entry->state = tx_done; defer_bh(dev, skb, &dev->txq); @@ -1057,14 +1098,34 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, } } - spin_lock_irqsave (&dev->txq.lock, flags); + spin_lock_irqsave(&dev->txq.lock, flags); + retval = usb_autopm_get_interface_async(dev->intf); + if (retval < 0) { + spin_unlock_irqrestore(&dev->txq.lock, flags); + goto drop; + } + +#ifdef CONFIG_PM + /* if this triggers the device is still a sleep */ + if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { + /* transmission will be done in resume */ + usb_anchor_urb(urb, &dev->deferred); + /* no use to process more packets */ + netif_stop_queue(net); + spin_unlock_irqrestore(&dev->txq.lock, flags); + devdbg(dev, "Delaying transmission for resumption"); + goto deferred; + } +#endif switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { case -EPIPE: netif_stop_queue (net); usbnet_defer_kevent (dev, EVENT_TX_HALT); + usb_autopm_put_interface_async(dev->intf); break; default: + usb_autopm_put_interface_async(dev->intf); if (netif_msg_tx_err (dev)) devdbg (dev, "tx: submit urb err %d", retval); break; @@ -1088,6 +1149,9 @@ drop: devdbg (dev, "> tx, len %d, type 0x%x", length, skb->protocol); } +#ifdef CONFIG_PM +deferred: +#endif return NETDEV_TX_OK; } EXPORT_SYMBOL_GPL(usbnet_start_xmit); @@ -1263,6 +1327,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK (&dev->kevent, kevent); + init_usb_anchor(&dev->deferred); dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); @@ -1382,13 +1447,23 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) struct usbnet *dev = usb_get_intfdata(intf); if (!dev->suspend_count++) { + spin_lock_irq(&dev->txq.lock); + /* don't autosuspend while transmitting */ + if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) { + spin_unlock_irq(&dev->txq.lock); + return -EBUSY; + } else { + set_bit(EVENT_DEV_ASLEEP, &dev->flags); + spin_unlock_irq(&dev->txq.lock); + } /* * accelerate emptying of the rx and queues, to avoid * having everything error out. */ netif_device_detach (dev->net); - (void) unlink_urbs (dev, &dev->rxq); - (void) unlink_urbs (dev, &dev->txq); + usbnet_terminate_urbs(dev); + usb_kill_urb(dev->interrupt); + /* * reattach so runtime management can use and * wake the device @@ -1402,10 +1477,34 @@ EXPORT_SYMBOL_GPL(usbnet_suspend); int usbnet_resume (struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); + struct sk_buff *skb; + struct urb *res; + int retval; + + if (!--dev->suspend_count) { + spin_lock_irq(&dev->txq.lock); + while ((res = usb_get_from_anchor(&dev->deferred))) { + + printk(KERN_INFO"%s has delayed data\n", __func__); + skb = (struct sk_buff *)res->context; + retval = usb_submit_urb(res, GFP_ATOMIC); + if (retval < 0) { + dev_kfree_skb_any(skb); + usb_free_urb(res); + usb_autopm_put_interface_async(dev->intf); + } else { + dev->net->trans_start = jiffies; + __skb_queue_tail(&dev->txq, skb); + } + } - if (!--dev->suspend_count) + smp_mb(); + clear_bit(EVENT_DEV_ASLEEP, &dev->flags); + spin_unlock_irq(&dev->txq.lock); + if (!(dev->txq.qlen >= TX_QLEN(dev))) + netif_start_queue(dev->net); tasklet_schedule (&dev->bh); - + } return 0; } EXPORT_SYMBOL_GPL(usbnet_resume); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 8c84881f8478..8ce61359bf73 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -55,6 +55,7 @@ struct usbnet { struct sk_buff_head done; struct sk_buff_head rxq_pause; struct urb *interrupt; + struct usb_anchor deferred; struct tasklet_struct bh; struct work_struct kevent; @@ -65,6 +66,8 @@ struct usbnet { # define EVENT_STS_SPLIT 3 # define EVENT_LINK_RESET 4 # define EVENT_RX_PAUSED 5 +# define EVENT_DEV_WAKING 6 +# define EVENT_DEV_ASLEEP 7 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) @@ -109,6 +112,9 @@ struct driver_info { /* see if peer is connected ... can sleep */ int (*check_connect)(struct usbnet *); + /* (dis)activate runtime power management */ + int (*manage_power)(struct usbnet *, int); + /* for status polling */ void (*status)(struct usbnet *, struct urb *); -- cgit v1.2.3 From 6070d81eb5f2d4943223c96e7609a53cdc984364 Mon Sep 17 00:00:00 2001 From: Adam Buchbinder Date: Fri, 4 Dec 2009 15:47:01 -0500 Subject: tree-wide: fix misspelling of "definition" in comments "Definition" is misspelled "defintion" in several comments; this patch fixes them. No code changes. Signed-off-by: Adam Buchbinder Signed-off-by: Jiri Kosina --- arch/arm/mach-bcmring/include/csp/reg.h | 2 +- arch/arm/mach-bcmring/include/mach/csp/mm_addr.h | 2 +- arch/arm/mach-u300/include/mach/u300-regs.h | 2 +- arch/sh/include/mach-common/mach/titan.h | 2 +- arch/x86/include/asm/sigcontext.h | 4 ++-- drivers/block/cciss_cmd.h | 2 +- drivers/gpu/drm/radeon/atombios.h | 16 ++++++++-------- drivers/media/video/cx18/cx18-av-core.h | 2 +- drivers/media/video/cx18/cx18-mailbox.h | 2 +- drivers/net/wireless/ath/ath5k/base.h | 2 +- drivers/s390/net/qeth_core_mpc.h | 2 +- drivers/scsi/advansys.c | 2 +- drivers/scsi/aic94xx/aic94xx_reg_def.h | 2 +- drivers/scsi/bfa/include/protocol/ct.h | 4 ++-- drivers/scsi/dmx3191d.c | 2 +- drivers/scsi/wd7000.c | 2 +- drivers/staging/otus/80211core/pub_zfi.h | 2 +- drivers/staging/otus/zdcompat.h | 2 +- drivers/staging/rtl8192su/r8192S_phyreg.h | 2 +- fs/cifs/cifspdu.h | 2 +- fs/compat_ioctl.c | 2 +- include/linux/cciss_ioctl.h | 2 +- include/linux/in6.h | 2 +- include/linux/usb/wusb.h | 2 +- 24 files changed, 33 insertions(+), 33 deletions(-) (limited to 'include/linux/usb') diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h index e5f60bf5a1f3..56654d23c3d7 100644 --- a/arch/arm/mach-bcmring/include/csp/reg.h +++ b/arch/arm/mach-bcmring/include/csp/reg.h @@ -16,7 +16,7 @@ /** * @file reg.h * -* @brief Generic register defintions used in CSP +* @brief Generic register definitions used in CSP */ /****************************************************************************/ diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h index 86bb58d4f58c..ad58cf873377 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h +++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h @@ -16,7 +16,7 @@ /** * @file mm_addr.h * -* @brief Memory Map address defintions +* @brief Memory Map address definitions * * @note * None diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h index 88333dfb19fc..56721a0cd2af 100644 --- a/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/arch/arm/mach-u300/include/mach/u300-regs.h @@ -6,7 +6,7 @@ * Copyright (C) 2006-2009 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 * Basic register address definitions in physical memory and - * some block defintions for core devices like the timer. + * some block definitions for core devices like the timer. * Author: Linus Walleij */ diff --git a/arch/sh/include/mach-common/mach/titan.h b/arch/sh/include/mach-common/mach/titan.h index 03f3583c8918..4a674d27cbb8 100644 --- a/arch/sh/include/mach-common/mach/titan.h +++ b/arch/sh/include/mach-common/mach/titan.h @@ -1,5 +1,5 @@ /* - * Platform defintions for Titan + * Platform definitions for Titan */ #ifndef _ASM_SH_TITAN_H #define _ASM_SH_TITAN_H diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h index 72e5a4491661..04459d25e66e 100644 --- a/arch/x86/include/asm/sigcontext.h +++ b/arch/x86/include/asm/sigcontext.h @@ -124,7 +124,7 @@ struct sigcontext { * fpstate is really (struct _fpstate *) or (struct _xstate *) * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end - * of extended memory layout. See comments at the defintion of + * of extended memory layout. See comments at the definition of * (struct _fpx_sw_bytes) */ void __user *fpstate; /* zero when no FPU/extended context */ @@ -219,7 +219,7 @@ struct sigcontext { * fpstate is really (struct _fpstate *) or (struct _xstate *) * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end - * of extended memory layout. See comments at the defintion of + * of extended memory layout. See comments at the definition of * (struct _fpx_sw_bytes) */ void __user *fpstate; /* zero when no FPU/extended context */ diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index dbaed1ea0da3..8098fccdbec4 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -5,7 +5,7 @@ //########################################################################### #define CISS_VERSION "1.00" -//general boundary defintions +//general boundary definitions #define SENSEINFOBYTES 32//note that this value may vary between host implementations #define MAXSGENTRIES 31 #define MAXREPLYQS 256 diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 5d402086bc47..811178907413 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1141,7 +1141,7 @@ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS { /* ucTableFormatRevision=1,ucTableContentRevision=2 */ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx defintions below */ + UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx definitions below */ UCHAR ucAction; /* 0: turn off encoder */ /* 1: setup and turn on encoder */ UCHAR ucTruncate; /* bit0=0: Disable truncate */ @@ -1424,7 +1424,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO { /* Structures used in FirmwareInfoTable */ /****************************************************************************/ -/* usBIOSCapability Defintion: */ +/* usBIOSCapability Definition: */ /* Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */ /* Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */ /* Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */ @@ -2386,7 +2386,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { } ATOM_ANALOG_TV_INFO_V1_2; /**************************************************************************/ -/* VRAM usage and their defintions */ +/* VRAM usage and their definitions */ /* One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */ /* Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */ @@ -3046,7 +3046,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S0_CRT1_MONOb0 0x01 #define ATOM_S0_CRT1_COLORb0 0x02 #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) @@ -3131,7 +3131,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF #define ATOM_S2_CRT1_DPMS_STATEb2 0x01 @@ -3190,7 +3190,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S3_CRT1_ACTIVEb0 0x01 #define ATOM_S3_LCD1_ACTIVEb0 0x02 #define ATOM_S3_TV1_ACTIVEb0 0x04 @@ -3230,7 +3230,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L #define ATOM_S4_LCD1_REFRESH_SHIFT 8 -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 @@ -3310,7 +3310,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L -/* Byte aligned defintion for BIOS usage */ +/* Byte aligned definition for BIOS usage */ #define ATOM_S6_DEVICE_CHANGEb0 0x01 #define ATOM_S6_SCALER_CHANGEb0 0x02 #define ATOM_S6_LID_CHANGEb0 0x04 diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 9b84a0c58e0e..cafb7e99b9a0 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -294,7 +294,7 @@ struct cx18_av_state { #define CXADEC_QAM_CONST_DEC 0x924 #define CXADEC_QAM_ROTATOR_FREQ 0x948 -/* Bit defintions / settings used in Mako Audio */ +/* Bit definitions / settings used in Mako Audio */ #define CXADEC_PREF_MODE_MONO_LANGA 0 #define CXADEC_PREF_MODE_MONO_LANGB 1 #define CXADEC_PREF_MODE_MONO_LANGC 2 diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index e23aaac5b280..522ad534034c 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h @@ -41,7 +41,7 @@ struct cx18; /* * This structure is used by CPU to provide completed buffers information * Its structure is dictrated by the layout of the SCB, required by the - * firmware, but its defintion needs to be here, instead of in cx18-scb.h, + * firmware, but its definition needs to be here, instead of in cx18-scb.h, * for mailbox work order scheduling */ struct cx18_mdl_ack { diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index c79a65044b67..4da029410467 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -36,7 +36,7 @@ */ /* - * Defintions for the Atheros Wireless LAN controller driver. + * Definitions for the Atheros Wireless LAN controller driver. */ #ifndef _DEV_ATH_ATHVAR_H #define _DEV_ATH_ATHVAR_H diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index eecb2ee62e85..de7bccef49f0 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -507,7 +507,7 @@ extern unsigned char ULP_ENABLE[]; (PDU_ENCAPSULATION(buffer) + 0x17) #define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \ (PDU_ENCAPSULATION(buffer) + 0x2b) -/* Layer 2 defintions */ +/* Layer 2 definitions */ #define QETH_PROT_LAYER2 0x08 #define QETH_PROT_TCPIP 0x03 #define QETH_PROT_OSN2 0x0a diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index b756041f0b26..22626abdb630 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7969,7 +7969,7 @@ static int advansys_reset(struct scsi_cmnd *scp) ASC_DBG(1, "before AscInitAsc1000Driver()\n"); status = AscInitAsc1000Driver(asc_dvc); - /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ + /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */ if (asc_dvc->err_code) { scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " "0x%x\n", asc_dvc->err_code); diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index a43e8cdf4ee4..28aaf349c111 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h @@ -1,5 +1,5 @@ /* - * Aic94xx SAS/SATA driver hardware registers defintions. + * Aic94xx SAS/SATA driver hardware registers definitions. * * Copyright (C) 2004 Adaptec, Inc. All rights reserved. * Copyright (C) 2004 David Chaw diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h index c59d6630b070..79d16a9ab281 100644 --- a/drivers/scsi/bfa/include/protocol/ct.h +++ b/drivers/scsi/bfa/include/protocol/ct.h @@ -82,7 +82,7 @@ enum { }; /* - * defintions for CT reason code + * definitions for CT reason code */ enum { CT_RSN_INV_CMD = 0x01, @@ -129,7 +129,7 @@ enum { }; /* - * defintions for the explanation code for all servers + * definitions for the explanation code for all servers */ enum { CT_EXP_AUTH_EXCEPTION = 0xF1, diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index fa738ec8692a..207352cc70cc 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -31,7 +31,7 @@ #include /* - * Defintions for the generic 5380 driver. + * Definitions for the generic 5380 driver. */ #define AUTOSENSE diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 093610bcfcce..2f6e9d8eaf71 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -161,7 +161,7 @@ * * 2003/02/12 - Christoph Hellwig * - * Cleaned up host template defintion + * Cleaned up host template definition * Removed now obsolete wd7000.h */ diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h index a35bd5d41d2c..60b7d1c56dee 100644 --- a/drivers/staging/otus/80211core/pub_zfi.h +++ b/drivers/staging/otus/80211core/pub_zfi.h @@ -20,7 +20,7 @@ #include "../oal_dt.h" /***** Section 1 : Tunable Parameters *****/ -/* The defintions in this section are tunabel parameters */ +/* The definitions in this section are tunabel parameters */ /* Maximum number of BSS that could be scaned */ #define ZM_MAX_BSS 128 diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h index 84ac43356b77..cdcaef54afcd 100644 --- a/drivers/staging/otus/zdcompat.h +++ b/drivers/staging/otus/zdcompat.h @@ -17,7 +17,7 @@ /* Module Name : zdcompat.h */ /* */ /* Abstract */ -/* This module contains function defintion for compatibility. */ +/* This module contains function definition for compatibility. */ /* */ /* NOTES */ /* Platform dependent. */ diff --git a/drivers/staging/rtl8192su/r8192S_phyreg.h b/drivers/staging/rtl8192su/r8192S_phyreg.h index 96c7cfa92542..acf644f430aa 100644 --- a/drivers/staging/rtl8192su/r8192S_phyreg.h +++ b/drivers/staging/rtl8192su/r8192S_phyreg.h @@ -38,7 +38,7 @@ // 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 // 3. RF register 0x00-2E // 4. Bit Mask for BB/RF register -// 5. Other defintion for BB/RF R/W +// 5. Other definition for BB/RF R/W // diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 2d07f890a842..3877737f96a6 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1227,7 +1227,7 @@ typedef struct smb_com_setattr_rsp { /* empty wct response to setattr */ /*******************************************************/ -/* NT Transact structure defintions follow */ +/* NT Transact structure definitions follow */ /* Currently only ioctl, acl (get security descriptor) */ /* and notify are implemented */ /*******************************************************/ diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index f91fd51b32e3..5fc8e52ee306 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -2655,7 +2655,7 @@ COMPATIBLE_IOCTL(TIOCSLTC) #endif #ifdef TIOCSTART /* - * For these two we have defintions in ioctls.h and/or termios.h on + * For these two we have definitions in ioctls.h and/or termios.h on * some architectures but no actual implemention. Some applications * like bash call them if they are defined in the headers, so we provide * entries here to avoid syslog message spew. diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h index cb57c30081a8..eb130b4d8e72 100644 --- a/include/linux/cciss_ioctl.h +++ b/include/linux/cciss_ioctl.h @@ -39,7 +39,7 @@ typedef __u32 DriverVer_type; #ifndef CCISS_CMD_H // This defines are duplicated in cciss_cmd.h in the driver directory -//general boundary defintions +//general boundary definitions #define SENSEINFOBYTES 32//note that this value may vary between host implementations //Command Status value diff --git a/include/linux/in6.h b/include/linux/in6.h index 718bf21c5754..010290dd79bb 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -113,7 +113,7 @@ struct in6_flowlabel_req #define IPV6_FLOWINFO_FLOWLABEL 0x000fffff #define IPV6_FLOWINFO_PRIORITY 0x0ff00000 -/* These defintions are obsolete */ +/* These definitions are obsolete */ #define IPV6_PRIORITY_UNCHARACTERIZED 0x0000 #define IPV6_PRIORITY_FILLER 0x0100 #define IPV6_PRIORITY_UNATTENDED 0x0200 diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h index 429c631d2aad..63ebdcc5dda6 100644 --- a/include/linux/usb/wusb.h +++ b/include/linux/usb/wusb.h @@ -74,7 +74,7 @@ enum { * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of * data. In order to avoid confusion and enforce types, we wrap it. * - * Make it packed, as we use it in some hw defintions. + * Make it packed, as we use it in some hw definitions. */ struct wusb_ckhdid { u8 data[16]; -- cgit v1.2.3 From 5242658d1b97771d658991cf29be32bcf81d5859 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 21 Oct 2009 00:03:38 +0200 Subject: USB gadget: Handle endpoint requests at the function level Control requests targeted at an endpoint (that is sent to EP0 but specifying the target endpoint address in wIndex) are dispatched to the current configuration's setup callback, requiring all gadget drivers to dispatch the requests to the correct function driver. To avoid this, record which endpoints are used by each function in the composite driver SET CONFIGURATION handler and dispatch requests targeted at endpoints to the correct function. Signed-off-by: Laurent Pinchart Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 54 +++++++++++++++++++++++++++++++++++------- include/linux/usb/composite.h | 1 + 2 files changed, 47 insertions(+), 8 deletions(-) (limited to 'include/linux/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d05397ec8a18..8498f1a114d5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -373,6 +373,8 @@ static void reset_config(struct usb_composite_dev *cdev) list_for_each_entry(f, &cdev->config->functions, list) { if (f->disable) f->disable(f); + + bitmap_zero(f->endpoints, 32); } cdev->config = NULL; } @@ -418,10 +420,35 @@ static int set_config(struct usb_composite_dev *cdev, /* Initialize all interfaces by setting them to altsetting zero. */ for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) { struct usb_function *f = c->interface[tmp]; + struct usb_descriptor_header **descriptors; if (!f) break; + /* + * Record which endpoints are used by the function. This is used + * to dispatch control requests targeted at that endpoint to the + * function's setup callback instead of the current + * configuration's setup callback. + */ + if (gadget->speed == USB_SPEED_HIGH) + descriptors = f->hs_descriptors; + else + descriptors = f->descriptors; + + for (; *descriptors; ++descriptors) { + struct usb_endpoint_descriptor *ep; + int addr; + + if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT) + continue; + + ep = (struct usb_endpoint_descriptor *)*descriptors; + addr = ((ep->bEndpointAddress & 0x80) >> 3) + | (ep->bEndpointAddress & 0x0f); + set_bit(addr, f->endpoints); + } + result = f->set_alt(f, tmp, 0); if (result < 0) { DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", @@ -688,6 +715,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); struct usb_function *f = NULL; + u8 endp; /* partial re-init of the response message; the function or the * gadget might need to intercept e.g. a control-OUT completion @@ -800,23 +828,33 @@ unknown: ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); - /* functions always handle their interfaces ... punt other - * recipients (endpoint, other, WUSB, ...) to the current + /* functions always handle their interfaces and endpoints... + * punt other recipients (other, WUSB, ...) to the current * configuration code. * * REVISIT it could make sense to let the composite device * take such requests too, if that's ever needed: to work * in config 0, etc. */ - if ((ctrl->bRequestType & USB_RECIP_MASK) - == USB_RECIP_INTERFACE) { + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_INTERFACE: f = cdev->config->interface[intf]; - if (f && f->setup) - value = f->setup(f, ctrl); - else + break; + + case USB_RECIP_ENDPOINT: + endp = ((w_index & 0x80) >> 3) | (w_index & 0x0f); + list_for_each_entry(f, &cdev->config->functions, list) { + if (test_bit(endp, f->endpoints)) + break; + } + if (&f->list == &cdev->config->functions) f = NULL; + break; } - if (value < 0 && !f) { + + if (f && f->setup) + value = f->setup(f, ctrl); + else { struct usb_configuration *c; c = cdev->config; diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 4f6bb3d2160e..738ea1a691cb 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -127,6 +127,7 @@ struct usb_function { /* private: */ /* internals */ struct list_head list; + DECLARE_BITMAP(endpoints, 32); }; int usb_add_function(struct usb_configuration *, struct usb_function *); -- cgit v1.2.3 From 91c8a5a9985d5bf9c55f6f82f183f57b050b2a3a Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 15 Oct 2009 17:09:34 +0300 Subject: USB OTG: add support for ulpi connected external transceivers This adds support for OTG transceivers directly connected to the ULPI interface. In particular, the following details are added - a struct for low level io functions (read/write) - a priv field to be used as 'viewport' by low level access functions - an (*init) and (*shutdown) callbacks, along with static inline helpers - a (*set_vbus) callback to switch the port power on and off - a flags field for per-transceiver settings - some defines for the flags bitmask to configure platform specific details Signed-off-by: Daniel Mack Cc: Heikki Krogerus Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/otg.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'include/linux/usb') diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 2443c0e7a80c..52bb917641f0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -33,6 +33,23 @@ enum usb_otg_state { OTG_STATE_A_VBUS_ERR, }; +#define USB_OTG_PULLUP_ID (1 << 0) +#define USB_OTG_PULLDOWN_DP (1 << 1) +#define USB_OTG_PULLDOWN_DM (1 << 2) +#define USB_OTG_EXT_VBUS_INDICATOR (1 << 3) +#define USB_OTG_DRV_VBUS (1 << 4) +#define USB_OTG_DRV_VBUS_EXT (1 << 5) + +struct otg_transceiver; + +/* for transceivers connected thru an ULPI interface, the user must + * provide access ops + */ +struct otg_io_access_ops { + int (*read)(struct otg_transceiver *otg, u32 reg); + int (*write)(struct otg_transceiver *otg, u32 val, u32 reg); +}; + /* * the otg driver needs to interact with both device side and host side * usb controllers. it decides which controller is active at a given @@ -42,6 +59,7 @@ enum usb_otg_state { struct otg_transceiver { struct device *dev; const char *label; + unsigned int flags; u8 default_a; enum usb_otg_state state; @@ -49,10 +67,17 @@ struct otg_transceiver { struct usb_bus *host; struct usb_gadget *gadget; + struct otg_io_access_ops *io_ops; + void __iomem *io_priv; + /* to pass extra port status to the root hub */ u16 port_status; u16 port_change; + /* initialize/shutdown the OTG controller */ + int (*init)(struct otg_transceiver *otg); + void (*shutdown)(struct otg_transceiver *otg); + /* bind/unbind the host controller */ int (*set_host)(struct otg_transceiver *otg, struct usb_bus *host); @@ -65,6 +90,10 @@ struct otg_transceiver { int (*set_power)(struct otg_transceiver *otg, unsigned mA); + /* effective for A-peripheral, ignored for B devices */ + int (*set_vbus)(struct otg_transceiver *otg, + bool enabled); + /* for non-OTG B devices: set transceiver into suspend mode */ int (*set_suspend)(struct otg_transceiver *otg, int suspend); @@ -85,6 +114,38 @@ extern int otg_set_transceiver(struct otg_transceiver *); extern void usb_nop_xceiv_register(void); extern void usb_nop_xceiv_unregister(void); +/* helpers for direct access thru low-level io interface */ +static inline int otg_io_read(struct otg_transceiver *otg, u32 reg) +{ + if (otg->io_ops && otg->io_ops->read) + return otg->io_ops->read(otg, reg); + + return -EINVAL; +} + +static inline int otg_io_write(struct otg_transceiver *otg, u32 reg, u32 val) +{ + if (otg->io_ops && otg->io_ops->write) + return otg->io_ops->write(otg, reg, val); + + return -EINVAL; +} + +static inline int +otg_init(struct otg_transceiver *otg) +{ + if (otg->init) + return otg->init(otg); + + return 0; +} + +static inline void +otg_shutdown(struct otg_transceiver *otg) +{ + if (otg->shutdown) + otg->shutdown(otg); +} /* for usb host and peripheral controller drivers */ extern struct otg_transceiver *otg_get_transceiver(void); @@ -97,6 +158,12 @@ otg_start_hnp(struct otg_transceiver *otg) return otg->start_hnp(otg); } +/* Context: can sleep */ +static inline int +otg_set_vbus(struct otg_transceiver *otg, bool enabled) +{ + return otg->set_vbus(otg, enabled); +} /* for HCDs */ static inline int @@ -105,7 +172,6 @@ otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) return otg->set_host(otg, host); } - /* for usb peripheral controller drivers */ /* Context: can sleep */ -- cgit v1.2.3 From 2d57a95f09cf71c4c642e5be15f8b700d17ee90c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 15 Oct 2009 17:09:35 +0300 Subject: USB OTG: Add generic driver for ULPI OTG transceiver This adds a minimal generic driver for ULPI connected transceivers, using the OTG framework functions recently introduced. The driver got a table to match the ULPI chips, which currently only has one entry for NXP's ISP 1504 transceiver. Signed-off-by: Daniel Mack Cc: Heikki Krogerus Cc: David Brownell Cc: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 + drivers/usb/otg/Kconfig | 9 ++++ drivers/usb/otg/Makefile | 1 + drivers/usb/otg/ulpi.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/ulpi.h | 7 +++ 5 files changed, 155 insertions(+) create mode 100644 drivers/usb/otg/ulpi.c create mode 100644 include/linux/usb/ulpi.h (limited to 'include/linux/usb') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index be3c9b80bc9f..473aa1a20de9 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -44,3 +44,5 @@ obj-y += early/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ + +obj-$(CONFIG_USB_ULPI) += otg/ diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index aa884d072f0b..de56b3d743d7 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -41,6 +41,15 @@ config ISP1301_OMAP This driver can also be built as a module. If so, the module will be called isp1301_omap. +config USB_ULPI + bool "Generic ULPI Transceiver Driver" + depends on ARM + help + Enable this to support ULPI connected USB OTG transceivers which + are likely found on embedded boards. + + The only chip currently supported is NXP's ISP1504 + config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index 208167856529..aeb49a8ec412 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o +obj-$(CONFIG_USB_ULPI) += ulpi.o ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c new file mode 100644 index 000000000000..896527456b7e --- /dev/null +++ b/drivers/usb/otg/ulpi.c @@ -0,0 +1,136 @@ +/* + * Generic ULPI USB transceiver support + * + * Copyright (C) 2009 Daniel Mack + * + * Based on sources from + * + * Sascha Hauer + * Freescale Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +/* ULPI register addresses */ +#define ULPI_VID_LOW 0x00 /* Vendor ID low */ +#define ULPI_VID_HIGH 0x01 /* Vendor ID high */ +#define ULPI_PID_LOW 0x02 /* Product ID low */ +#define ULPI_PID_HIGH 0x03 /* Product ID high */ +#define ULPI_ITFCTL 0x07 /* Interface Control */ +#define ULPI_OTGCTL 0x0A /* OTG Control */ + +/* add to above register address to access Set/Clear functions */ +#define ULPI_REG_SET 0x01 +#define ULPI_REG_CLEAR 0x02 + +/* ULPI OTG Control Register bits */ +#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */ +#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */ +#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */ +#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */ +#define CHRG_VBUS (1 << 4) /* Charge Vbus */ +#define DRV_VBUS (1 << 5) /* Drive Vbus */ +#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */ +#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */ + +#define ULPI_ID(vendor, product) (((vendor) << 16) | (product)) + +#define TR_FLAG(flags, a, b) (((flags) & a) ? b : 0) + +/* ULPI hardcoded IDs, used for probing */ +static unsigned int ulpi_ids[] = { + ULPI_ID(0x04cc, 0x1504), /* NXP ISP1504 */ +}; + +static int ulpi_set_flags(struct otg_transceiver *otg) +{ + unsigned int flags = 0; + + if (otg->flags & USB_OTG_PULLUP_ID) + flags |= ID_PULL_UP; + + if (otg->flags & USB_OTG_PULLDOWN_DM) + flags |= DM_PULL_DOWN; + + if (otg->flags & USB_OTG_PULLDOWN_DP) + flags |= DP_PULL_DOWN; + + if (otg->flags & USB_OTG_EXT_VBUS_INDICATOR) + flags |= USE_EXT_VBUS_IND; + + return otg_io_write(otg, flags, ULPI_OTGCTL + ULPI_REG_SET); +} + +static int ulpi_init(struct otg_transceiver *otg) +{ + int i, vid, pid; + + vid = (otg_io_read(otg, ULPI_VID_HIGH) << 8) | + otg_io_read(otg, ULPI_VID_LOW); + pid = (otg_io_read(otg, ULPI_PID_HIGH) << 8) | + otg_io_read(otg, ULPI_PID_LOW); + + pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); + + for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) + if (ulpi_ids[i] == ULPI_ID(vid, pid)) + return ulpi_set_flags(otg); + + pr_err("ULPI ID does not match any known transceiver.\n"); + return -ENODEV; +} + +static int ulpi_set_vbus(struct otg_transceiver *otg, bool on) +{ + unsigned int flags = otg_io_read(otg, ULPI_OTGCTL); + + flags &= ~(DRV_VBUS | DRV_VBUS_EXT); + + if (on) { + if (otg->flags & USB_OTG_DRV_VBUS) + flags |= DRV_VBUS; + + if (otg->flags & USB_OTG_DRV_VBUS_EXT) + flags |= DRV_VBUS_EXT; + } + + return otg_io_write(otg, flags, ULPI_OTGCTL + ULPI_REG_SET); +} + +struct otg_transceiver * +otg_ulpi_create(struct otg_io_access_ops *ops, + unsigned int flags) +{ + struct otg_transceiver *otg; + + otg = kzalloc(sizeof(*otg), GFP_KERNEL); + if (!otg) + return NULL; + + otg->label = "ULPI"; + otg->flags = flags; + otg->io_ops = ops; + otg->init = ulpi_init; + otg->set_vbus = ulpi_set_vbus; + + return otg; +} +EXPORT_SYMBOL_GPL(otg_ulpi_create); + diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h new file mode 100644 index 000000000000..20675c6ebc4d --- /dev/null +++ b/include/linux/usb/ulpi.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_USB_ULPI_H +#define __LINUX_USB_ULPI_H + +struct otg_transceiver *otg_ulpi_create(struct otg_io_access_ops *ops, + unsigned int flags); + +#endif /* __LINUX_USB_ULPI_H */ -- cgit v1.2.3 From 82fc5943430e3cbf15033ed4186a73f90906345d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Oct 2009 16:06:46 +0100 Subject: usb_serial: Kill port mutex The tty port has a port mutex used for all the port related locking so we don't need the one in the USB serial layer any more. Signed-off-by: Alan Cox Cc: Alan Stern Cc: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 4 ++-- drivers/usb/serial/usb-serial.c | 1 - include/linux/usb/serial.h | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'include/linux/usb') diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 80f59b6350cb..c03fdc0242dd 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -501,12 +501,12 @@ static int opticon_resume(struct usb_interface *intf) struct usb_serial_port *port = serial->port[0]; int result; - mutex_lock(&port->mutex); + mutex_lock(&port->port.mutex); if (port->port.count) result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); else result = 0; - mutex_unlock(&port->mutex); + mutex_unlock(&port->port.mutex); return result; } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 829a46684e1d..4543f359be75 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -897,7 +897,6 @@ int usb_serial_probe(struct usb_interface *interface, spin_lock_init(&port->lock); /* Keep this for private driver use for the moment but should probably go away */ - mutex_init(&port->mutex); INIT_WORK(&port->work, usb_serial_port_work); serial->port[i] = port; port->dev.parent = &interface->dev; diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index ce911ebf91e8..acf6e457c04b 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -39,8 +39,6 @@ enum port_dev_state { * @serial: pointer back to the struct usb_serial owner of this port. * @port: pointer to the corresponding tty_port for this port. * @lock: spinlock to grab when updating portions of this structure. - * @mutex: mutex used to synchronize serial_open() and serial_close() - * access for this port. * @number: the number of the port (the minor number). * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. @@ -77,7 +75,6 @@ struct usb_serial_port { struct usb_serial *serial; struct tty_port port; spinlock_t lock; - struct mutex mutex; unsigned char number; unsigned char *interrupt_in_buffer; -- cgit v1.2.3 From 119eecc831a42bd090543568932e440c6831f1bb Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Wed, 23 Dec 2009 09:10:48 +0100 Subject: Fix usb_serial_probe() problem introduced by the recent kfifo changes The USB serial code was a new user of the kfifo API, and it was missed when porting things to the new kfifo API. Please make the write_fifo in place. Here is my patch to fix the regression and full ported version. Signed-off-by: Stefani Seibold Reported-and-tested-by: Rafael J. Wysocki Cc: Greg KH Cc: Andrew Morton Cc: Alan Stern Signed-off-by: Linus Torvalds --- drivers/usb/serial/generic.c | 12 ++++++------ drivers/usb/serial/usb-serial.c | 5 ++--- include/linux/usb/serial.h | 3 ++- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'include/linux/usb') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index b0f1183755c9..f1ea3a33b6e6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) if (port->write_urb_busy) start_io = false; else { - start_io = (kfifo_len(port->write_fifo) != 0); + start_io = (kfifo_len(&port->write_fifo) != 0); port->write_urb_busy = start_io; } spin_unlock_irqrestore(&port->lock, flags); @@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) return 0; data = port->write_urb->transfer_buffer; - count = kfifo_out_locked(port->write_fifo, data, port->bulk_out_size, &port->lock); + count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock); usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ @@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, return usb_serial_multi_urb_write(tty, port, buf, count); - count = kfifo_in_locked(port->write_fifo, buf, count, &port->lock); + count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); result = usb_serial_generic_write_start(port); if (result >= 0) @@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) (serial->type->max_in_flight_urbs - port->urbs_in_flight); } else if (serial->num_bulk_out) - room = port->write_fifo->size - kfifo_len(port->write_fifo); + room = kfifo_avail(&port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); @@ -391,7 +391,7 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) chars = port->tx_bytes_flight; spin_unlock_irqrestore(&port->lock, flags); } else if (serial->num_bulk_out) - chars = kfifo_len(port->write_fifo); + chars = kfifo_len(&port->write_fifo); dbg("%s - returns %d", __func__, chars); return chars; @@ -507,7 +507,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) if (status) { dbg("%s - nonzero multi-urb write bulk status " "received: %d", __func__, status); - kfifo_reset(port->write_fifo); + kfifo_reset_out(&port->write_fifo); } else usb_serial_generic_write_start(port); } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 636a4f23445e..33c85f7084f8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -595,8 +595,7 @@ static void port_release(struct device *dev) usb_free_urb(port->write_urb); usb_free_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_out_urb); - if (!IS_ERR(port->write_fifo) && port->write_fifo) - kfifo_free(port->write_fifo); + kfifo_free(&port->write_fifo); kfree(port->bulk_in_buffer); kfree(port->bulk_out_buffer); kfree(port->interrupt_in_buffer); @@ -939,7 +938,7 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) goto probe_error; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); port->bulk_out_size = buffer_size; diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index acf6e457c04b..1819396ed501 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -16,6 +16,7 @@ #include #include #include +#include #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 254 /* loads of devices :) */ @@ -94,7 +95,7 @@ struct usb_serial_port { unsigned char *bulk_out_buffer; int bulk_out_size; struct urb *write_urb; - struct kfifo *write_fifo; + struct kfifo write_fifo; int write_urb_busy; __u8 bulk_out_endpointAddress; -- cgit v1.2.3