mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
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 <[email protected]> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJSHQe5AAoJEIaOsuA1yqREgaUP/3wnPuYiP5lvNb60B/YcKlbV 0Qyw/6yEz2+H0cbUsGWxqNTqX6bj72vPuNyAM4EGCs26ZJG8Jz6fFpJ7xIQCsGaY 7iGo/RiGvCNQj15r/QBjM0mMIQSG8QwU/sFl45Ai/0g3sbUdKBdHVm4lRMV1Q9EG +vSUvmkuidXZ2PuF2k2goVofeQ7NOPJSxvP91Vt3DQK2CIICol8J+IXgMkJUGTOW xR7L5lRIMTj7F0PWY63x8HrEQdGqlXjvcq+/FQOd++ErUkDMcQ6q/G1vZeHqu9aD kSMDoJOrjYM2qwW29JH9rR7y4F1ac+XYQj3MoNd95GRWMWWx1mXqIGYbTc8gel/S 1h0Vu2qVsFsWZTNRESY8wWSKb8ogoubMQX+PNpwZZnrqJBEk7/WpnX42gF209tLc xYnExU4ZIAES2j5QZ4eJbFAo5RiqWQ4EVVTscWTVZ1zFf06u6Bqa+Nk6GB+qS91U QOKonQi9SZRx4sMjt7H6kYbsNBIslplSZCqFcory6XTbtpDhoTlyx9e11rnWV8wC vSQPpc2fyVlPNaJE7UQhC2U2MHiXCsT9KGYr5CD5JKMaNmcBSSMVDGvUZQbuu5wA KutERTnU+x+KHwtnoA7QfcT97SR8cothVRa1+CrvzkPd8hQJGvai29RumLPjM3da DWqj5VmDljtX9e4kdDiq =QceB -----END PGP SIGNATURE----- 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 <[email protected]>
This commit is contained in:
commit
752e69555d
21 changed files with 329 additions and 126 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue