summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-27 14:07:31 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-27 14:07:31 -0700
commit752e69555d107853043cb9405250c9387b26e708 (patch)
tree5614a210da5793a05044e3683f78be7991837bee /drivers/usb
parentf2e0ae93cc81cb56ed32722da7b7246a24940f90 (diff)
parent0f2aa8caeaa043f6cbe6281eb72efba5ff860904 (diff)
Merge tag 'usb-for-v3.12-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.12 merge window (part 2) Here's a set of important fixes for v3.12 merge window which have been pending in the mailing list for quite some time. We have use-after-free fixes, signedness fixes, more of HAS_DMA dependencies, fixes for NULL pointer deferences, build fixes and some other fixes to the musb driver caused by recent patches. Patches are quite small and contain valuable fixes which will give us a much better -rc1 release. Please consider merging Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c1
-rw-r--r--drivers/usb/gadget/Kconfig5
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c10
-rw-r--r--drivers/usb/gadget/configfs.c4
-rw-r--r--drivers/usb/gadget/f_fs.c2
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/usb/musb/musb_cppi41.c4
-rw-r--r--drivers/usb/musb/musb_dsps.c61
-rw-r--r--drivers/usb/musb/musb_gadget.c15
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/musb/ux500_dma.c4
-rw-r--r--drivers/usb/phy/phy-am335x-control.c4
-rw-r--r--drivers/usb/phy/phy-fsl-usb.h2
-rw-r--r--drivers/usb/phy/phy-fsm-usb.c2
-rw-r--r--drivers/usb/phy/phy-omap-usb2.c7
15 files changed, 79 insertions, 48 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 577af1b237f2..474162e9d01d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -33,7 +33,6 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
-#include <linux/usb/otg.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/of.h>
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index bddd7ede5455..30e2dd8a1f2c 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -187,7 +187,7 @@ config USB_FSL_USB2
config USB_FUSB300
tristate "Faraday FUSB300 USB Peripheral Controller"
- depends on !PHYS_ADDR_T_64BIT
+ depends on !PHYS_ADDR_T_64BIT && HAS_DMA
help
Faraday usb device controller FUSB300 driver
@@ -244,6 +244,7 @@ config USB_PXA25X_SMALL
config USB_R8A66597
tristate "Renesas R8A66597 USB Peripheral Controller"
+ depends on HAS_DMA
help
R8A66597 is a discrete USB host and peripheral controller chip that
supports both full and high speed USB 2.0 data transfers.
@@ -385,7 +386,7 @@ config USB_NET2272
config USB_NET2272_DMA
boolean "Support external DMA controller"
- depends on USB_NET2272
+ depends on USB_NET2272 && HAS_DMA
help
The NET2272 part can optionally support an external DMA
controller, but your board has to have support in the
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 40d23384b716..2cb52e0438df 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1772,7 +1772,7 @@ out:
static int atmel_usba_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
{
- int ret = 0;
+ int ret;
struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget);
unsigned long flags;
@@ -1784,11 +1784,11 @@ static int atmel_usba_start(struct usb_gadget *gadget,
ret = clk_prepare_enable(udc->pclk);
if (ret)
- goto out;
+ return ret;
ret = clk_prepare_enable(udc->hclk);
if (ret) {
clk_disable_unprepare(udc->pclk);
- goto out;
+ return ret;
}
DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
@@ -1804,11 +1804,9 @@ static int atmel_usba_start(struct usb_gadget *gadget,
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
}
-
-out:
spin_unlock_irqrestore(&udc->lock, flags);
- return ret;
+ return 0;
}
static int atmel_usba_stop(struct usb_gadget *gadget,
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 80e7f75a56c7..8f0d6141e5e6 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -859,8 +859,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
list_del(&f->list);
ret = usb_add_function(c, f);
- if (ret)
+ if (ret) {
+ list_add(&f->list, &cfg->func_list);
goto err_purge_funcs;
+ }
}
usb_ep_autoconfig_reset(cdev->gadget);
}
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index f394f295d63d..1a66c5baa0d1 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1417,8 +1417,8 @@ static void functionfs_unbind(struct ffs_data *ffs)
usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
ffs->ep0req = NULL;
ffs->gadget = NULL;
- ffs_data_put(ffs);
clear_bit(FFS_FL_BOUND, &ffs->flags);
+ ffs_data_put(ffs);
}
}
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 570c005062ab..465ef8e2cc91 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1270,10 +1270,6 @@ dev_release (struct inode *inode, struct file *fd)
dev->buf = NULL;
put_dev (dev);
- /* other endpoints were all decoupled from this device */
- spin_lock_irq(&dev->lock);
- dev->state = STATE_DEV_DISABLED;
- spin_unlock_irq(&dev->lock);
return 0;
}
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index e64701d15401..ae959746f77f 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -150,8 +150,10 @@ static void cppi41_dma_callback(void *private_data)
remain_bytes,
direction,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (WARN_ON(!dma_desc))
+ if (WARN_ON(!dma_desc)) {
+ spin_unlock_irqrestore(&musb->lock, flags);
return;
+ }
dma_desc->callback = cppi41_dma_callback;
dma_desc->callback_param = channel;
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 4ffbaace7913..4047cbb91bac 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -44,6 +44,7 @@
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/usb/of.h>
#include "musb_core.h"
@@ -230,6 +231,8 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
glue->last_timer = jiffies;
return;
}
+ if (musb->port_mode == MUSB_PORT_MODE_HOST)
+ return;
if (time_after(glue->last_timer, timeout) &&
timer_pending(&glue->timer)) {
@@ -313,7 +316,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
jiffies + wrp->poll_seconds * HZ);
WARNING("VBUS error workaround (delay coming)\n");
} else if (drvvbus) {
- musb->is_active = 1;
MUSB_HST_MODE(musb);
musb->xceiv->otg->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
@@ -361,8 +363,8 @@ static int dsps_musb_init(struct musb *musb)
return -EINVAL;
reg_base = devm_ioremap_resource(dev, r);
- if (!musb->ctrl_base)
- return -EINVAL;
+ if (IS_ERR(reg_base))
+ return PTR_ERR(reg_base);
musb->ctrl_base = reg_base;
/* NOP driver needs change if supporting dual instance */
@@ -425,35 +427,51 @@ static int get_int_prop(struct device_node *dn, const char *s)
return val;
}
+static int get_musb_port_mode(struct device *dev)
+{
+ enum usb_dr_mode mode;
+
+ mode = of_usb_get_dr_mode(dev->of_node);
+ switch (mode) {
+ case USB_DR_MODE_HOST:
+ return MUSB_PORT_MODE_HOST;
+
+ case USB_DR_MODE_PERIPHERAL:
+ return MUSB_PORT_MODE_GADGET;
+
+ case USB_DR_MODE_UNKNOWN:
+ case USB_DR_MODE_OTG:
+ default:
+ return MUSB_PORT_MODE_DUAL_ROLE;
+ };
+}
+
static int dsps_create_musb_pdev(struct dsps_glue *glue,
struct platform_device *parent)
{
struct musb_hdrc_platform_data pdata;
struct resource resources[2];
+ struct resource *res;
struct device *dev = &parent->dev;
struct musb_hdrc_config *config;
struct platform_device *musb;
struct device_node *dn = parent->dev.of_node;
- struct device_node *child_node;
int ret;
- child_node = of_get_child_by_name(dn, "usb");
- if (!child_node)
- return -EINVAL;
-
memset(resources, 0, sizeof(resources));
- ret = of_address_to_resource(child_node, 0, &resources[0]);
- if (ret) {
+ res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc");
+ if (!res) {
dev_err(dev, "failed to get memory.\n");
- return ret;
+ return -EINVAL;
}
+ resources[0] = *res;
- ret = of_irq_to_resource(child_node, 0, &resources[1]);
- if (ret == 0) {
+ res = platform_get_resource_byname(parent, IORESOURCE_IRQ, "mc");
+ if (!res) {
dev_err(dev, "failed to get irq.\n");
- ret = -EINVAL;
- return ret;
+ return -EINVAL;
}
+ resources[1] = *res;
/* allocate the child platform device */
musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
@@ -465,7 +483,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
musb->dev.parent = dev;
musb->dev.dma_mask = &musb_dmamask;
musb->dev.coherent_dma_mask = musb_dmamask;
- musb->dev.of_node = of_node_get(child_node);
+ musb->dev.of_node = of_node_get(dn);
glue->musb = musb;
@@ -485,11 +503,12 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
pdata.config = config;
pdata.platform_ops = &dsps_ops;
- config->num_eps = get_int_prop(child_node, "num-eps");
- config->ram_bits = get_int_prop(child_node, "ram-bits");
- pdata.mode = get_int_prop(child_node, "port-mode");
- pdata.power = get_int_prop(child_node, "power");
- config->multipoint = of_property_read_bool(child_node, "multipoint");
+ config->num_eps = get_int_prop(dn, "mentor,num-eps");
+ config->ram_bits = get_int_prop(dn, "mentor,ram-bits");
+ pdata.mode = get_musb_port_mode(dev);
+ /* DT keeps this entry in mA, musb expects it as per USB spec */
+ pdata.power = get_int_prop(dn, "mentor,power") / 2;
+ config->multipoint = of_property_read_bool(dn, "mentor,multipoint");
ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
if (ret) {
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 4376f51f5ef1..9a08679d204d 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -76,13 +76,21 @@ static inline void map_dma_buffer(struct musb_request *request,
return;
if (request->request.dma == DMA_ADDR_INVALID) {
- request->request.dma = dma_map_single(
+ dma_addr_t dma_addr;
+ int ret;
+
+ dma_addr = dma_map_single(
musb->controller,
request->request.buf,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
+ ret = dma_mapping_error(musb->controller, dma_addr);
+ if (ret)
+ return;
+
+ request->request.dma = dma_addr;
request->map_state = MUSB_MAPPED;
} else {
dma_sync_single_for_device(musb->controller,
@@ -1804,6 +1812,8 @@ err:
void musb_gadget_cleanup(struct musb *musb)
{
+ if (musb->port_mode == MUSB_PORT_MODE_HOST)
+ return;
usb_del_gadget_udc(&musb->g);
}
@@ -1929,7 +1939,8 @@ static int musb_gadget_stop(struct usb_gadget *g,
stop_activity(musb, driver);
otg_set_peripheral(musb->xceiv->otg, NULL);
- dev_dbg(musb->controller, "unregistering driver %s\n", driver->function);
+ dev_dbg(musb->controller, "unregistering driver %s\n",
+ driver ? driver->function : "(removed)");
musb->is_active = 0;
musb->gadget_driver = NULL;
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index a9695f5a92fb..9a2b8c85f19a 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2628,6 +2628,8 @@ int musb_host_alloc(struct musb *musb)
void musb_host_cleanup(struct musb *musb)
{
+ if (musb->port_mode == MUSB_PORT_MODE_GADGET)
+ return;
usb_remove_hcd(musb->hcd);
musb->hcd = NULL;
}
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index e51dd9b88e71..3700e9713258 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -333,7 +333,9 @@ static int ux500_dma_controller_start(struct ux500_dma_controller *controller)
if (!ux500_channel->dma_chan)
ux500_channel->dma_chan =
dma_request_channel(mask,
- data->dma_filter,
+ data ?
+ data->dma_filter :
+ NULL,
param_array[ch_num]);
if (!ux500_channel->dma_chan) {
diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c
index 759754521426..22cf07d62e4c 100644
--- a/drivers/usb/phy/phy-am335x-control.c
+++ b/drivers/usb/phy/phy-am335x-control.c
@@ -42,8 +42,8 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
reg = AM335X_USB1_CTRL;
break;
default:
- __WARN();
- return;
+ WARN_ON(1);
+ return;
}
val = readl(usb_ctrl->phy_reg + reg);
diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h
index ca266280895d..e1859b8ef567 100644
--- a/drivers/usb/phy/phy-fsl-usb.h
+++ b/drivers/usb/phy/phy-fsl-usb.h
@@ -15,7 +15,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "otg_fsm.h"
+#include "phy-fsm-usb.h"
#include <linux/usb/otg.h>
#include <linux/ioctl.h>
diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c
index c520b3548e7c..7f4596606e18 100644
--- a/drivers/usb/phy/phy-fsm-usb.c
+++ b/drivers/usb/phy/phy-fsm-usb.c
@@ -29,7 +29,7 @@
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
-#include "phy-otg-fsm.h"
+#include "phy-fsm-usb.h"
/* Change USB protocol when there is a protocol change */
static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
index 844ab68f08d0..d266861d24f7 100644
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ b/drivers/usb/phy/phy-omap-usb2.c
@@ -98,8 +98,8 @@ static int omap_usb_set_peripheral(struct usb_otg *otg,
static int omap_usb2_suspend(struct usb_phy *x, int suspend)
{
- u32 ret;
struct omap_usb *phy = phy_to_omapusb(x);
+ int ret;
if (suspend && !phy->is_suspended) {
omap_control_usb_phy_power(phy->control_dev, 0);
@@ -108,8 +108,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
} else if (!suspend && phy->is_suspended) {
ret = pm_runtime_get_sync(phy->dev);
if (ret < 0) {
- dev_err(phy->dev, "get_sync failed with err %d\n",
- ret);
+ dev_err(phy->dev, "get_sync failed with err %d\n", ret);
return ret;
}
omap_control_usb_phy_power(phy->control_dev, 1);
@@ -209,9 +208,9 @@ static int omap_usb2_runtime_suspend(struct device *dev)
static int omap_usb2_runtime_resume(struct device *dev)
{
- u32 ret = 0;
struct platform_device *pdev = to_platform_device(dev);
struct omap_usb *phy = platform_get_drvdata(pdev);
+ int ret;
ret = clk_enable(phy->wkupclk);
if (ret < 0) {