From 687ef9817df7ed960d14575b9033dde3d04631fe Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 10:30:33 -0500 Subject: usb: dwc3: gadget: clear stall when disabling endpoint so it seems like DWC3 IP doesn't clear stalls automatically when we disable an endpoint, because of that, we _must_ make sure stalls are cleared before clearing the proper bit in DALEPENA register. Cc: # v3.4+ Reported-by: Johannes Stezenbach Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a740eac74d56..f0dc0ee85ded 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -608,6 +608,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) dwc3_remove_requests(dwc, dep); + /* make sure HW endpoint isn't stalled */ + if (dep->flags & DWC3_EP_STALL) + __dwc3_gadget_ep_set_halt(dep, 0); + reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); reg &= ~DWC3_DALEPENA_EP(dep->number); dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); -- cgit v1.2.3 From 3c9f94aca66aa8c83d531961ea8c7b8bace9433c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 15:08:29 -0500 Subject: usb: dwc3: core: refactor PHY initialization our probe() routine is too large and we can easily refactor PHY-related code out to another function to make it slightly less painful to read. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 120 ++++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index d001417e8e37..38976f3123d3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -486,70 +486,20 @@ static void dwc3_core_exit(struct dwc3 *dwc) phy_exit(dwc->usb3_generic_phy); } -#define DWC3_ALIGN_MASK (16 - 1) - -static int dwc3_probe(struct platform_device *pdev) +static int dwc3_core_get_phy(struct dwc3 *dwc) { - struct device *dev = &pdev->dev; - struct dwc3_platform_data *pdata = dev_get_platdata(dev); + struct device *dev = dwc->dev; struct device_node *node = dev->of_node; - struct resource *res; - struct dwc3 *dwc; - - int ret = -ENOMEM; - - void __iomem *regs; - void *mem; - - mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); - if (!mem) { - dev_err(dev, "not enough memory\n"); - return -ENOMEM; - } - dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); - dwc->mem = mem; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "missing IRQ\n"); - return -ENODEV; - } - dwc->xhci_resources[1].start = res->start; - dwc->xhci_resources[1].end = res->end; - dwc->xhci_resources[1].flags = res->flags; - dwc->xhci_resources[1].name = res->name; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing memory resource\n"); - return -ENODEV; - } + int ret; if (node) { - dwc->maximum_speed = of_usb_get_maximum_speed(node); - dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); - - dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); - dwc->dr_mode = of_usb_get_dr_mode(node); - } else if (pdata) { - dwc->maximum_speed = pdata->maximum_speed; - - dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); - - dwc->needs_fifo_resize = pdata->tx_fifo_resize; - dwc->dr_mode = pdata->dr_mode; } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } - /* default to superspeed if no maximum_speed passed */ - if (dwc->maximum_speed == USB_SPEED_UNKNOWN) - dwc->maximum_speed = USB_SPEED_SUPER; - if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); if (ret == -ENXIO || ret == -ENODEV) { @@ -600,6 +550,69 @@ static int dwc3_probe(struct platform_device *pdev) } } + return 0; +} + +#define DWC3_ALIGN_MASK (16 - 1) + +static int dwc3_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dwc3_platform_data *pdata = dev_get_platdata(dev); + struct device_node *node = dev->of_node; + struct resource *res; + struct dwc3 *dwc; + + int ret = -ENOMEM; + + void __iomem *regs; + void *mem; + + mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); + if (!mem) { + dev_err(dev, "not enough memory\n"); + return -ENOMEM; + } + dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); + dwc->mem = mem; + dwc->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "missing IRQ\n"); + return -ENODEV; + } + dwc->xhci_resources[1].start = res->start; + dwc->xhci_resources[1].end = res->end; + dwc->xhci_resources[1].flags = res->flags; + dwc->xhci_resources[1].name = res->name; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing memory resource\n"); + return -ENODEV; + } + + if (node) { + dwc->maximum_speed = of_usb_get_maximum_speed(node); + + dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); + dwc->dr_mode = of_usb_get_dr_mode(node); + } else if (pdata) { + dwc->maximum_speed = pdata->maximum_speed; + + dwc->needs_fifo_resize = pdata->tx_fifo_resize; + dwc->dr_mode = pdata->dr_mode; + } + + /* default to superspeed if no maximum_speed passed */ + if (dwc->maximum_speed == USB_SPEED_UNKNOWN) + dwc->maximum_speed = USB_SPEED_SUPER; + + ret = dwc3_core_get_phy(dwc); + if (ret) + return ret; + dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; @@ -621,7 +634,6 @@ static int dwc3_probe(struct platform_device *pdev) dwc->regs = regs; dwc->regs_size = resource_size(res); - dwc->dev = dev; dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; -- cgit v1.2.3 From 041832565e405d2e2ea218632b7bcafa87deaece Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 17 Apr 2014 11:24:27 -0500 Subject: usb: phy: mv-u3d: switch over to writel/readl by removing the _relaxed suffix, we can build this driver in other architectures. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-mv-u3d-usb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-mv-u3d-usb.c b/drivers/usb/phy/phy-mv-u3d-usb.c index d317903022bf..d342175eead7 100644 --- a/drivers/usb/phy/phy-mv-u3d-usb.c +++ b/drivers/usb/phy/phy-mv-u3d-usb.c @@ -39,8 +39,8 @@ static u32 mv_u3d_phy_read(void __iomem *base, u32 reg) addr = base; data = base + 0x4; - writel_relaxed(reg, addr); - return readl_relaxed(data); + writel(reg, addr); + return readl(data); } static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value) @@ -51,10 +51,10 @@ static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value) addr = base; data = base + 0x4; - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); + writel(reg, addr); + tmp = readl(data); tmp |= value; - writel_relaxed(tmp, data); + writel(tmp, data); } static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value) @@ -65,10 +65,10 @@ static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value) addr = base; data = base + 0x4; - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); + writel(reg, addr); + tmp = readl(data); tmp &= ~value; - writel_relaxed(tmp, data); + writel(tmp, data); } static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value) @@ -78,8 +78,8 @@ static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value) addr = base; data = base + 0x4; - writel_relaxed(reg, addr); - writel_relaxed(value, data); + writel(reg, addr); + writel(value, data); } static void mv_u3d_phy_shutdown(struct usb_phy *phy) -- cgit v1.2.3 From 5f94adfeed97a62f31a25d14effc6ac13c847333 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 15:13:45 -0500 Subject: usb: dwc3: core: refactor mode initialization to its own function Move mode (Host, Peripheral, OTG) initialization to its own function in order to decrease the size of our probe() routine. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 133 ++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 38976f3123d3..af8c8f6e67b3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -553,6 +553,69 @@ static int dwc3_core_get_phy(struct dwc3 *dwc) return 0; } +static int dwc3_core_init_mode(struct dwc3 *dwc) +{ + struct device *dev = dwc->dev; + int ret; + + switch (dwc->dr_mode) { + case USB_DR_MODE_PERIPHERAL: + dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); + ret = dwc3_gadget_init(dwc); + if (ret) { + dev_err(dev, "failed to initialize gadget\n"); + return ret; + } + break; + case USB_DR_MODE_HOST: + dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); + ret = dwc3_host_init(dwc); + if (ret) { + dev_err(dev, "failed to initialize host\n"); + return ret; + } + break; + case USB_DR_MODE_OTG: + dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); + ret = dwc3_host_init(dwc); + if (ret) { + dev_err(dev, "failed to initialize host\n"); + return ret; + } + + ret = dwc3_gadget_init(dwc); + if (ret) { + dev_err(dev, "failed to initialize gadget\n"); + return ret; + } + break; + default: + dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); + return -EINVAL; + } + + return 0; +} + +static void dwc3_core_exit_mode(struct dwc3 *dwc) +{ + switch (dwc->dr_mode) { + case USB_DR_MODE_PERIPHERAL: + dwc3_gadget_exit(dwc); + break; + case USB_DR_MODE_HOST: + dwc3_host_exit(dwc); + break; + case USB_DR_MODE_OTG: + dwc3_host_exit(dwc); + dwc3_gadget_exit(dwc); + break; + default: + /* do nothing */ + break; + } +} + #define DWC3_ALIGN_MASK (16 - 1) static int dwc3_probe(struct platform_device *pdev) @@ -682,41 +745,9 @@ static int dwc3_probe(struct platform_device *pdev) goto err_usb3phy_power; } - switch (dwc->dr_mode) { - case USB_DR_MODE_PERIPHERAL: - dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); - ret = dwc3_gadget_init(dwc); - if (ret) { - dev_err(dev, "failed to initialize gadget\n"); - goto err2; - } - break; - case USB_DR_MODE_HOST: - dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); - ret = dwc3_host_init(dwc); - if (ret) { - dev_err(dev, "failed to initialize host\n"); - goto err2; - } - break; - case USB_DR_MODE_OTG: - dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); - ret = dwc3_host_init(dwc); - if (ret) { - dev_err(dev, "failed to initialize host\n"); - goto err2; - } - - ret = dwc3_gadget_init(dwc); - if (ret) { - dev_err(dev, "failed to initialize gadget\n"); - goto err2; - } - break; - default: - dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); + ret = dwc3_core_init_mode(dwc); + if (ret) goto err2; - } ret = dwc3_debugfs_init(dwc); if (ret) { @@ -729,21 +760,7 @@ static int dwc3_probe(struct platform_device *pdev) return 0; err3: - switch (dwc->dr_mode) { - case USB_DR_MODE_PERIPHERAL: - dwc3_gadget_exit(dwc); - break; - case USB_DR_MODE_HOST: - dwc3_host_exit(dwc); - break; - case USB_DR_MODE_OTG: - dwc3_host_exit(dwc); - dwc3_gadget_exit(dwc); - break; - default: - /* do nothing */ - break; - } + dwc3_core_exit_mode(dwc); err2: dwc3_event_buffers_cleanup(dwc); @@ -778,23 +795,7 @@ static int dwc3_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); dwc3_debugfs_exit(dwc); - - switch (dwc->dr_mode) { - case USB_DR_MODE_PERIPHERAL: - dwc3_gadget_exit(dwc); - break; - case USB_DR_MODE_HOST: - dwc3_host_exit(dwc); - break; - case USB_DR_MODE_OTG: - dwc3_host_exit(dwc); - dwc3_gadget_exit(dwc); - break; - default: - /* do nothing */ - break; - } - + dwc3_core_exit_mode(dwc); dwc3_event_buffers_cleanup(dwc); dwc3_free_event_buffers(dwc); dwc3_core_exit(dwc); -- cgit v1.2.3 From 0700faaf736492bd203630d179b639a1f5bbb576 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 1 Apr 2014 13:19:32 -0500 Subject: usb: gadget: only GPL drivers in the gadget and phy framework We only support GPL drivers in the USB Gadget Framework, it sounds correct to make all exported symbols GPL too. Acked-by: Greg Kroah-Hartman Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 2 +- drivers/usb/gadget/f_fs.c | 6 ++--- drivers/usb/gadget/f_rndis.c | 2 +- drivers/usb/gadget/rndis.c | 28 ++++++++++---------- drivers/usb/gadget/storage_common.c | 52 ++++++++++++++++++------------------- drivers/usb/gadget/u_ether.c | 32 +++++++++++------------ drivers/usb/gadget/u_f.c | 2 +- drivers/usb/phy/phy-generic.c | 4 +-- 8 files changed, 64 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 7d1cc01796b6..dcead559a61e 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1005,7 +1005,7 @@ void unregister_gadget_item(struct config_item *item) unregister_gadget(gi); } -EXPORT_SYMBOL(unregister_gadget_item); +EXPORT_SYMBOL_GPL(unregister_gadget_item); static int __init gadget_cfs_init(void) { diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 2e164dca08e8..a01b3bd8fa00 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -190,7 +190,7 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data, /* Devices management *******************************************************/ DEFINE_MUTEX(ffs_lock); -EXPORT_SYMBOL(ffs_lock); +EXPORT_SYMBOL_GPL(ffs_lock); static struct ffs_dev *_ffs_find_dev(const char *name); static struct ffs_dev *_ffs_alloc_dev(void); @@ -2876,7 +2876,7 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name) return ret; } -EXPORT_SYMBOL(ffs_name_dev); +EXPORT_SYMBOL_GPL(ffs_name_dev); int ffs_single_dev(struct ffs_dev *dev) { @@ -2893,7 +2893,7 @@ int ffs_single_dev(struct ffs_dev *dev) ffs_dev_unlock(); return ret; } -EXPORT_SYMBOL(ffs_single_dev); +EXPORT_SYMBOL_GPL(ffs_single_dev); /* * ffs_lock must be taken by the caller of this function diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index c11761ce5113..139bc9c6f7e0 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -834,7 +834,7 @@ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net) opts->borrowed_net = opts->bound = true; opts->net = net; } -EXPORT_SYMBOL(rndis_borrow_net); +EXPORT_SYMBOL_GPL(rndis_borrow_net); static inline struct f_rndis_opts *to_f_rndis_opts(struct config_item *item) { diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index d822d822efb3..4c36694a0132 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -760,7 +760,7 @@ int rndis_signal_connect(int configNr) return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_CONNECT); } -EXPORT_SYMBOL(rndis_signal_connect); +EXPORT_SYMBOL_GPL(rndis_signal_connect); int rndis_signal_disconnect(int configNr) { @@ -769,7 +769,7 @@ int rndis_signal_disconnect(int configNr) return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_DISCONNECT); } -EXPORT_SYMBOL(rndis_signal_disconnect); +EXPORT_SYMBOL_GPL(rndis_signal_disconnect); void rndis_uninit(int configNr) { @@ -784,13 +784,13 @@ void rndis_uninit(int configNr) while ((buf = rndis_get_next_response(configNr, &length))) rndis_free_response(configNr, buf); } -EXPORT_SYMBOL(rndis_uninit); +EXPORT_SYMBOL_GPL(rndis_uninit); void rndis_set_host_mac(int configNr, const u8 *addr) { rndis_per_dev_params[configNr].host_mac = addr; } -EXPORT_SYMBOL(rndis_set_host_mac); +EXPORT_SYMBOL_GPL(rndis_set_host_mac); /* * Message Parser @@ -873,7 +873,7 @@ int rndis_msg_parser(u8 configNr, u8 *buf) return -ENOTSUPP; } -EXPORT_SYMBOL(rndis_msg_parser); +EXPORT_SYMBOL_GPL(rndis_msg_parser); int rndis_register(void (*resp_avail)(void *v), void *v) { @@ -895,7 +895,7 @@ int rndis_register(void (*resp_avail)(void *v), void *v) return -ENODEV; } -EXPORT_SYMBOL(rndis_register); +EXPORT_SYMBOL_GPL(rndis_register); void rndis_deregister(int configNr) { @@ -904,7 +904,7 @@ void rndis_deregister(int configNr) if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params[configNr].used = 0; } -EXPORT_SYMBOL(rndis_deregister); +EXPORT_SYMBOL_GPL(rndis_deregister); int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) { @@ -918,7 +918,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) return 0; } -EXPORT_SYMBOL(rndis_set_param_dev); +EXPORT_SYMBOL_GPL(rndis_set_param_dev); int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) { @@ -931,7 +931,7 @@ int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) return 0; } -EXPORT_SYMBOL(rndis_set_param_vendor); +EXPORT_SYMBOL_GPL(rndis_set_param_vendor); int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) { @@ -943,7 +943,7 @@ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) return 0; } -EXPORT_SYMBOL(rndis_set_param_medium); +EXPORT_SYMBOL_GPL(rndis_set_param_medium); void rndis_add_hdr(struct sk_buff *skb) { @@ -958,7 +958,7 @@ void rndis_add_hdr(struct sk_buff *skb) header->DataOffset = cpu_to_le32(36); header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); } -EXPORT_SYMBOL(rndis_add_hdr); +EXPORT_SYMBOL_GPL(rndis_add_hdr); void rndis_free_response(int configNr, u8 *buf) { @@ -975,7 +975,7 @@ void rndis_free_response(int configNr, u8 *buf) } } } -EXPORT_SYMBOL(rndis_free_response); +EXPORT_SYMBOL_GPL(rndis_free_response); u8 *rndis_get_next_response(int configNr, u32 *length) { @@ -997,7 +997,7 @@ u8 *rndis_get_next_response(int configNr, u32 *length) return NULL; } -EXPORT_SYMBOL(rndis_get_next_response); +EXPORT_SYMBOL_GPL(rndis_get_next_response); static rndis_resp_t *rndis_add_response(int configNr, u32 length) { @@ -1041,7 +1041,7 @@ int rndis_rm_hdr(struct gether *port, skb_queue_tail(list, skb); return 0; } -EXPORT_SYMBOL(rndis_rm_hdr); +EXPORT_SYMBOL_GPL(rndis_rm_hdr); #ifdef CONFIG_USB_GADGET_DEBUG_FILES diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index ec20a1f50c2d..ff205a7bc55c 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -43,7 +43,7 @@ struct usb_interface_descriptor fsg_intf_desc = { .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ .iInterface = FSG_STRING_INTERFACE, }; -EXPORT_SYMBOL(fsg_intf_desc); +EXPORT_SYMBOL_GPL(fsg_intf_desc); /* * Three full-speed endpoint descriptors: bulk-in, bulk-out, and @@ -58,7 +58,7 @@ struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, /* wMaxPacketSize set by autoconfiguration */ }; -EXPORT_SYMBOL(fsg_fs_bulk_in_desc); +EXPORT_SYMBOL_GPL(fsg_fs_bulk_in_desc); struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -68,7 +68,7 @@ struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, /* wMaxPacketSize set by autoconfiguration */ }; -EXPORT_SYMBOL(fsg_fs_bulk_out_desc); +EXPORT_SYMBOL_GPL(fsg_fs_bulk_out_desc); struct usb_descriptor_header *fsg_fs_function[] = { (struct usb_descriptor_header *) &fsg_intf_desc, @@ -76,7 +76,7 @@ struct usb_descriptor_header *fsg_fs_function[] = { (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, NULL, }; -EXPORT_SYMBOL(fsg_fs_function); +EXPORT_SYMBOL_GPL(fsg_fs_function); /* @@ -95,7 +95,7 @@ struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(512), }; -EXPORT_SYMBOL(fsg_hs_bulk_in_desc); +EXPORT_SYMBOL_GPL(fsg_hs_bulk_in_desc); struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -106,7 +106,7 @@ struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { .wMaxPacketSize = cpu_to_le16(512), .bInterval = 1, /* NAK every 1 uframe */ }; -EXPORT_SYMBOL(fsg_hs_bulk_out_desc); +EXPORT_SYMBOL_GPL(fsg_hs_bulk_out_desc); struct usb_descriptor_header *fsg_hs_function[] = { @@ -115,7 +115,7 @@ struct usb_descriptor_header *fsg_hs_function[] = { (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, NULL, }; -EXPORT_SYMBOL(fsg_hs_function); +EXPORT_SYMBOL_GPL(fsg_hs_function); struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -125,7 +125,7 @@ struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(1024), }; -EXPORT_SYMBOL(fsg_ss_bulk_in_desc); +EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_desc); struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { .bLength = sizeof(fsg_ss_bulk_in_comp_desc), @@ -133,7 +133,7 @@ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { /*.bMaxBurst = DYNAMIC, */ }; -EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc); +EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_comp_desc); struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -143,7 +143,7 @@ struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(1024), }; -EXPORT_SYMBOL(fsg_ss_bulk_out_desc); +EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_desc); struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { .bLength = sizeof(fsg_ss_bulk_in_comp_desc), @@ -151,7 +151,7 @@ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { /*.bMaxBurst = DYNAMIC, */ }; -EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc); +EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_comp_desc); struct usb_descriptor_header *fsg_ss_function[] = { (struct usb_descriptor_header *) &fsg_intf_desc, @@ -161,7 +161,7 @@ struct usb_descriptor_header *fsg_ss_function[] = { (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, NULL, }; -EXPORT_SYMBOL(fsg_ss_function); +EXPORT_SYMBOL_GPL(fsg_ss_function); /*-------------------------------------------------------------------------*/ @@ -179,7 +179,7 @@ void fsg_lun_close(struct fsg_lun *curlun) curlun->filp = NULL; } } -EXPORT_SYMBOL(fsg_lun_close); +EXPORT_SYMBOL_GPL(fsg_lun_close); int fsg_lun_open(struct fsg_lun *curlun, const char *filename) { @@ -278,7 +278,7 @@ out: fput(filp); return rc; } -EXPORT_SYMBOL(fsg_lun_open); +EXPORT_SYMBOL_GPL(fsg_lun_open); /*-------------------------------------------------------------------------*/ @@ -295,7 +295,7 @@ int fsg_lun_fsync_sub(struct fsg_lun *curlun) return 0; return vfs_fsync(filp, 1); } -EXPORT_SYMBOL(fsg_lun_fsync_sub); +EXPORT_SYMBOL_GPL(fsg_lun_fsync_sub); void store_cdrom_address(u8 *dest, int msf, u32 addr) { @@ -314,7 +314,7 @@ void store_cdrom_address(u8 *dest, int msf, u32 addr) put_unaligned_be32(addr, dest); } } -EXPORT_SYMBOL(store_cdrom_address); +EXPORT_SYMBOL_GPL(store_cdrom_address); /*-------------------------------------------------------------------------*/ @@ -325,13 +325,13 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf) ? curlun->ro : curlun->initially_ro); } -EXPORT_SYMBOL(fsg_show_ro); +EXPORT_SYMBOL_GPL(fsg_show_ro); ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) { return sprintf(buf, "%u\n", curlun->nofua); } -EXPORT_SYMBOL(fsg_show_nofua); +EXPORT_SYMBOL_GPL(fsg_show_nofua); ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, char *buf) @@ -357,19 +357,19 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, up_read(filesem); return rc; } -EXPORT_SYMBOL(fsg_show_file); +EXPORT_SYMBOL_GPL(fsg_show_file); ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) { return sprintf(buf, "%u\n", curlun->cdrom); } -EXPORT_SYMBOL(fsg_show_cdrom); +EXPORT_SYMBOL_GPL(fsg_show_cdrom); ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) { return sprintf(buf, "%u\n", curlun->removable); } -EXPORT_SYMBOL(fsg_show_removable); +EXPORT_SYMBOL_GPL(fsg_show_removable); /* * The caller must hold fsg->filesem for reading when calling this function. @@ -410,7 +410,7 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, return rc; } -EXPORT_SYMBOL(fsg_store_ro); +EXPORT_SYMBOL_GPL(fsg_store_ro); ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) { @@ -429,7 +429,7 @@ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) return count; } -EXPORT_SYMBOL(fsg_store_nofua); +EXPORT_SYMBOL_GPL(fsg_store_nofua); ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count) @@ -460,7 +460,7 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, up_write(filesem); return (rc < 0 ? rc : count); } -EXPORT_SYMBOL(fsg_store_file); +EXPORT_SYMBOL_GPL(fsg_store_file); ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count) @@ -483,7 +483,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, return ret; } -EXPORT_SYMBOL(fsg_store_cdrom); +EXPORT_SYMBOL_GPL(fsg_store_cdrom); ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, size_t count) @@ -499,6 +499,6 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, return count; } -EXPORT_SYMBOL(fsg_store_removable); +EXPORT_SYMBOL_GPL(fsg_store_removable); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 50d09c289137..216bbd1c871e 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -841,7 +841,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, return dev; } -EXPORT_SYMBOL(gether_setup_name); +EXPORT_SYMBOL_GPL(gether_setup_name); struct net_device *gether_setup_name_default(const char *netname) { @@ -879,7 +879,7 @@ struct net_device *gether_setup_name_default(const char *netname) return net; } -EXPORT_SYMBOL(gether_setup_name_default); +EXPORT_SYMBOL_GPL(gether_setup_name_default); int gether_register_netdev(struct net_device *net) { @@ -917,7 +917,7 @@ int gether_register_netdev(struct net_device *net) return status; } -EXPORT_SYMBOL(gether_register_netdev); +EXPORT_SYMBOL_GPL(gether_register_netdev); void gether_set_gadget(struct net_device *net, struct usb_gadget *g) { @@ -927,7 +927,7 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g) dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); } -EXPORT_SYMBOL(gether_set_gadget); +EXPORT_SYMBOL_GPL(gether_set_gadget); int gether_set_dev_addr(struct net_device *net, const char *dev_addr) { @@ -940,7 +940,7 @@ int gether_set_dev_addr(struct net_device *net, const char *dev_addr) memcpy(dev->dev_mac, new_addr, ETH_ALEN); return 0; } -EXPORT_SYMBOL(gether_set_dev_addr); +EXPORT_SYMBOL_GPL(gether_set_dev_addr); int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len) { @@ -949,7 +949,7 @@ int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len) dev = netdev_priv(net); return get_ether_addr_str(dev->dev_mac, dev_addr, len); } -EXPORT_SYMBOL(gether_get_dev_addr); +EXPORT_SYMBOL_GPL(gether_get_dev_addr); int gether_set_host_addr(struct net_device *net, const char *host_addr) { @@ -962,7 +962,7 @@ int gether_set_host_addr(struct net_device *net, const char *host_addr) memcpy(dev->host_mac, new_addr, ETH_ALEN); return 0; } -EXPORT_SYMBOL(gether_set_host_addr); +EXPORT_SYMBOL_GPL(gether_set_host_addr); int gether_get_host_addr(struct net_device *net, char *host_addr, int len) { @@ -971,7 +971,7 @@ int gether_get_host_addr(struct net_device *net, char *host_addr, int len) dev = netdev_priv(net); return get_ether_addr_str(dev->host_mac, host_addr, len); } -EXPORT_SYMBOL(gether_get_host_addr); +EXPORT_SYMBOL_GPL(gether_get_host_addr); int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) { @@ -985,7 +985,7 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) return strlen(host_addr); } -EXPORT_SYMBOL(gether_get_host_addr_cdc); +EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc); void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]) { @@ -994,7 +994,7 @@ void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]) dev = netdev_priv(net); memcpy(host_mac, dev->host_mac, ETH_ALEN); } -EXPORT_SYMBOL(gether_get_host_addr_u8); +EXPORT_SYMBOL_GPL(gether_get_host_addr_u8); void gether_set_qmult(struct net_device *net, unsigned qmult) { @@ -1003,7 +1003,7 @@ void gether_set_qmult(struct net_device *net, unsigned qmult) dev = netdev_priv(net); dev->qmult = qmult; } -EXPORT_SYMBOL(gether_set_qmult); +EXPORT_SYMBOL_GPL(gether_set_qmult); unsigned gether_get_qmult(struct net_device *net) { @@ -1012,7 +1012,7 @@ unsigned gether_get_qmult(struct net_device *net) dev = netdev_priv(net); return dev->qmult; } -EXPORT_SYMBOL(gether_get_qmult); +EXPORT_SYMBOL_GPL(gether_get_qmult); int gether_get_ifname(struct net_device *net, char *name, int len) { @@ -1021,7 +1021,7 @@ int gether_get_ifname(struct net_device *net, char *name, int len) rtnl_unlock(); return strlen(name); } -EXPORT_SYMBOL(gether_get_ifname); +EXPORT_SYMBOL_GPL(gether_get_ifname); /** * gether_cleanup - remove Ethernet-over-USB device @@ -1038,7 +1038,7 @@ void gether_cleanup(struct eth_dev *dev) flush_work(&dev->work); free_netdev(dev->net); } -EXPORT_SYMBOL(gether_cleanup); +EXPORT_SYMBOL_GPL(gether_cleanup); /** * gether_connect - notify network layer that USB link is active @@ -1119,7 +1119,7 @@ fail0: return ERR_PTR(result); return dev->net; } -EXPORT_SYMBOL(gether_connect); +EXPORT_SYMBOL_GPL(gether_connect); /** * gether_disconnect - notify network layer that USB link is inactive @@ -1197,7 +1197,7 @@ void gether_disconnect(struct gether *link) dev->port_usb = NULL; spin_unlock(&dev->lock); } -EXPORT_SYMBOL(gether_disconnect); +EXPORT_SYMBOL_GPL(gether_disconnect); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Brownell"); diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index 63b6642c162b..c6276f0268ae 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c @@ -29,4 +29,4 @@ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) } return req; } -EXPORT_SYMBOL(alloc_ep_req); +EXPORT_SYMBOL_GPL(alloc_ep_req); diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index bb394980532b..95e70bc384c2 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -54,14 +54,14 @@ void usb_nop_xceiv_register(void) return; } } -EXPORT_SYMBOL(usb_nop_xceiv_register); +EXPORT_SYMBOL_GPL(usb_nop_xceiv_register); void usb_nop_xceiv_unregister(void) { platform_device_unregister(pd); pd = NULL; } -EXPORT_SYMBOL(usb_nop_xceiv_unregister); +EXPORT_SYMBOL_GPL(usb_nop_xceiv_unregister); static int nop_set_suspend(struct usb_phy *x, int suspend) { -- cgit v1.2.3 From 4525beeb9aadbb9e1cb3e9e135f4371553f26a70 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 15:20:44 -0500 Subject: usb: phy: rename usb_nop_xceiv to usb_phy_generic no functional changes, just renaming the function in order to make it slightly clearer what it should be used for, also matching the driver name. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 6 ++--- drivers/usb/dwc3/dwc3-pci.c | 6 ++--- drivers/usb/musb/am35x.c | 4 ++-- drivers/usb/musb/blackfin.c | 4 ++-- drivers/usb/musb/da8xx.c | 4 ++-- drivers/usb/musb/davinci.c | 6 ++--- drivers/usb/musb/tusb6010.c | 6 ++--- drivers/usb/phy/phy-am335x.c | 2 +- drivers/usb/phy/phy-generic.c | 50 +++++++++++++++++++++--------------------- drivers/usb/phy/phy-generic.h | 6 ++--- drivers/usb/phy/phy-keystone.c | 2 +- 11 files changed, 48 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 28c8ad79f5e6..821cc59e6e1d 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -38,13 +38,13 @@ struct dwc3_exynos { static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) { - struct usb_phy_gen_xceiv_platform_data pdata; + struct usb_phy_generic_platform_data pdata; struct platform_device *pdev; int ret; memset(&pdata, 0x00, sizeof(pdata)); - pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO); + pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); if (!pdev) return -ENOMEM; @@ -56,7 +56,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) if (ret) goto err1; - pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO); + pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); if (!pdev) { ret = -ENOMEM; goto err1; diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index f393c183cc69..8b162f0e293c 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -40,13 +40,13 @@ struct dwc3_pci { static int dwc3_pci_register_phys(struct dwc3_pci *glue) { - struct usb_phy_gen_xceiv_platform_data pdata; + struct usb_phy_generic_platform_data pdata; struct platform_device *pdev; int ret; memset(&pdata, 0x00, sizeof(pdata)); - pdev = platform_device_alloc("usb_phy_gen_xceiv", 0); + pdev = platform_device_alloc("usb_phy_generic", 0); if (!pdev) return -ENOMEM; @@ -58,7 +58,7 @@ static int dwc3_pci_register_phys(struct dwc3_pci *glue) if (ret) goto err1; - pdev = platform_device_alloc("usb_phy_gen_xceiv", 1); + pdev = platform_device_alloc("usb_phy_generic", 1); if (!pdev) { ret = -ENOMEM; goto err1; diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index b3aa0184af9a..77ed66427969 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -360,7 +360,7 @@ static int am35x_musb_init(struct musb *musb) if (!rev) return -ENODEV; - usb_nop_xceiv_register(); + usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) return -EPROBE_DEFER; @@ -402,7 +402,7 @@ static int am35x_musb_exit(struct musb *musb) data->set_phy_power(0); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return 0; } diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 796677fa9a15..607f3ae04591 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -401,7 +401,7 @@ static int bfin_musb_init(struct musb *musb) } gpio_direction_output(musb->config->gpio_vrsel, 0); - usb_nop_xceiv_register(); + usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { gpio_free(musb->config->gpio_vrsel); @@ -426,7 +426,7 @@ static int bfin_musb_exit(struct musb *musb) gpio_free(musb->config->gpio_vrsel); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return 0; } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index e3486de71995..bcdce8e64670 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -418,7 +418,7 @@ static int da8xx_musb_init(struct musb *musb) if (!rev) goto fail; - usb_nop_xceiv_register(); + usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { ret = -EPROBE_DEFER; @@ -453,7 +453,7 @@ static int da8xx_musb_exit(struct musb *musb) phy_off(); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return 0; } diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index c259dac9d056..c0e07eddb079 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -381,7 +381,7 @@ static int davinci_musb_init(struct musb *musb) u32 revision; int ret = -ENODEV; - usb_nop_xceiv_register(); + usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { ret = -EPROBE_DEFER; @@ -439,7 +439,7 @@ static int davinci_musb_init(struct musb *musb) fail: usb_put_phy(musb->xceiv); unregister: - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return ret; } @@ -487,7 +487,7 @@ static int davinci_musb_exit(struct musb *musb) phy_off(); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return 0; } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 4e9fb1d08698..0c0f5ee1e3f1 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1065,7 +1065,7 @@ static int tusb_musb_init(struct musb *musb) void __iomem *sync = NULL; int ret; - usb_nop_xceiv_register(); + usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) return -EPROBE_DEFER; @@ -1117,7 +1117,7 @@ done: iounmap(sync); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); } return ret; } @@ -1133,7 +1133,7 @@ static int tusb_musb_exit(struct musb *musb) iounmap(musb->sync_va); usb_put_phy(musb->xceiv); - usb_nop_xceiv_unregister(); + usb_phy_generic_unregister(); return 0; } diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 12fc3468a01e..bb866e466051 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -13,7 +13,7 @@ #include "phy-generic.h" struct am335x_phy { - struct usb_phy_gen_xceiv usb_phy_gen; + struct usb_phy_generic usb_phy_gen; struct phy_control *phy_ctrl; int id; }; diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 95e70bc384c2..e76ca4ca3a8a 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -43,32 +43,32 @@ static struct platform_device *pd; -void usb_nop_xceiv_register(void) +void usb_phy_generic_register(void) { if (pd) return; - pd = platform_device_register_simple("usb_phy_gen_xceiv", -1, NULL, 0); + pd = platform_device_register_simple("usb_phy_generic", -1, NULL, 0); if (IS_ERR(pd)) { pr_err("Unable to register generic usb transceiver\n"); pd = NULL; return; } } -EXPORT_SYMBOL_GPL(usb_nop_xceiv_register); +EXPORT_SYMBOL_GPL(usb_phy_generic_register); -void usb_nop_xceiv_unregister(void) +void usb_phy_generic_unregister(void) { platform_device_unregister(pd); pd = NULL; } -EXPORT_SYMBOL_GPL(usb_nop_xceiv_unregister); +EXPORT_SYMBOL_GPL(usb_phy_generic_unregister); static int nop_set_suspend(struct usb_phy *x, int suspend) { return 0; } -static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) +static void nop_reset_set(struct usb_phy_generic *nop, int asserted) { int value; @@ -87,7 +87,7 @@ static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) int usb_gen_phy_init(struct usb_phy *phy) { - struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); + struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); if (!IS_ERR(nop->vcc)) { if (regulator_enable(nop->vcc)) @@ -106,7 +106,7 @@ EXPORT_SYMBOL_GPL(usb_gen_phy_init); void usb_gen_phy_shutdown(struct usb_phy *phy) { - struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); + struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); /* Assert RESET */ nop_reset_set(nop, 1); @@ -150,8 +150,8 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } -int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, - struct usb_phy_gen_xceiv_platform_data *pdata) +int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, + struct usb_phy_generic_platform_data *pdata) { enum usb_phy_type type = USB_PHY_TYPE_USB2; int err; @@ -245,10 +245,10 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, } EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); -static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) +static int usb_phy_generic_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct usb_phy_gen_xceiv *nop; + struct usb_phy_generic *nop; int err; nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); @@ -274,9 +274,9 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) return 0; } -static int usb_phy_gen_xceiv_remove(struct platform_device *pdev) +static int usb_phy_generic_remove(struct platform_device *pdev) { - struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev); + struct usb_phy_generic *nop = platform_get_drvdata(pdev); usb_remove_phy(&nop->phy); @@ -290,29 +290,29 @@ static const struct of_device_id nop_xceiv_dt_ids[] = { MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); -static struct platform_driver usb_phy_gen_xceiv_driver = { - .probe = usb_phy_gen_xceiv_probe, - .remove = usb_phy_gen_xceiv_remove, +static struct platform_driver usb_phy_generic_driver = { + .probe = usb_phy_generic_probe, + .remove = usb_phy_generic_remove, .driver = { - .name = "usb_phy_gen_xceiv", + .name = "usb_phy_generic", .owner = THIS_MODULE, .of_match_table = nop_xceiv_dt_ids, }, }; -static int __init usb_phy_gen_xceiv_init(void) +static int __init usb_phy_generic_init(void) { - return platform_driver_register(&usb_phy_gen_xceiv_driver); + return platform_driver_register(&usb_phy_generic_driver); } -subsys_initcall(usb_phy_gen_xceiv_init); +subsys_initcall(usb_phy_generic_init); -static void __exit usb_phy_gen_xceiv_exit(void) +static void __exit usb_phy_generic_exit(void) { - platform_driver_unregister(&usb_phy_gen_xceiv_driver); + platform_driver_unregister(&usb_phy_generic_driver); } -module_exit(usb_phy_gen_xceiv_exit); +module_exit(usb_phy_generic_exit); -MODULE_ALIAS("platform:usb_phy_gen_xceiv"); +MODULE_ALIAS("platform:usb_phy_generic"); MODULE_AUTHOR("Texas Instruments Inc"); MODULE_DESCRIPTION("NOP USB Transceiver driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index 38a81f307b82..f32450ada12d 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h @@ -3,7 +3,7 @@ #include -struct usb_phy_gen_xceiv { +struct usb_phy_generic { struct usb_phy phy; struct device *dev; struct clk *clk; @@ -15,7 +15,7 @@ struct usb_phy_gen_xceiv { int usb_gen_phy_init(struct usb_phy *phy); void usb_gen_phy_shutdown(struct usb_phy *phy); -int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, - struct usb_phy_gen_xceiv_platform_data *pdata); +int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, + struct usb_phy_generic_platform_data *pdata); #endif diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index d762003896c0..2404c442c302 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c @@ -35,7 +35,7 @@ #define PHY_REF_SSP_EN BIT(29) struct keystone_usbphy { - struct usb_phy_gen_xceiv usb_phy_gen; + struct usb_phy_generic usb_phy_gen; void __iomem *phy_ctrl; }; -- cgit v1.2.3 From d7078df6be6e9e5e3ac354859f5b8d60114391b4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 15:28:32 -0500 Subject: usb: phy: rename to now that all functions match the driver name, the only missing piece is to rename the header file itself. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 2 +- drivers/usb/dwc3/dwc3-pci.c | 2 +- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/blackfin.c | 2 +- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/tusb6010.c | 2 +- drivers/usb/phy/phy-am335x.c | 2 +- drivers/usb/phy/phy-generic.c | 2 +- drivers/usb/phy/phy-generic.h | 2 +- drivers/usb/phy/phy-keystone.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 821cc59e6e1d..ed22d722884e 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 8b162f0e293c..1ed95e0386eb 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -23,7 +23,7 @@ #include #include -#include +#include /* FIXME define these in */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 77ed66427969..044cd824c70d 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include "musb_core.h" diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 607f3ae04591..c9992a2eaaa8 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index bcdce8e64670..a0dabb05de76 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index c0e07eddb079..737035457858 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 3372ded5def7..18882924d9d5 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 0c0f5ee1e3f1..8d4a8194c8f2 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "musb_core.h" diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index bb866e466051..585e50cb1980 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index e76ca4ca3a8a..2c49cd8f6d25 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index f32450ada12d..d8feacc0b7fb 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h @@ -1,7 +1,7 @@ #ifndef _PHY_GENERIC_H_ #define _PHY_GENERIC_H_ -#include +#include struct usb_phy_generic { struct usb_phy phy; diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index 2404c442c302..f4d722de912b 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include -- cgit v1.2.3 From e741e637a85a802a93125dca1ecf324bc414101b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 16:05:17 -0500 Subject: usb: musb: move usb_phy_generic_{un,}register calls to probe()/remove() This patch is in preparation to supporting calling those functions multiple times. Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 4 ++-- drivers/usb/musb/blackfin.c | 6 +++--- drivers/usb/musb/da8xx.c | 4 ++-- drivers/usb/musb/davinci.c | 4 ++-- drivers/usb/musb/tusb6010.c | 5 ++--- 5 files changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 044cd824c70d..05459b56b2a8 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -360,7 +360,6 @@ static int am35x_musb_init(struct musb *musb) if (!rev) return -ENODEV; - usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) return -EPROBE_DEFER; @@ -402,7 +401,6 @@ static int am35x_musb_exit(struct musb *musb) data->set_phy_power(0); usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); return 0; } @@ -505,6 +503,7 @@ static int am35x_probe(struct platform_device *pdev) pdata->platform_ops = &am35x_ops; + usb_phy_generic_register(); platform_set_drvdata(pdev, glue); pinfo = am35x_dev_info; @@ -547,6 +546,7 @@ static int am35x_remove(struct platform_device *pdev) struct am35x_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); + usb_phy_generic_unregister(); clk_disable(glue->clk); clk_disable(glue->phy_clk); clk_put(glue->clk); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index c9992a2eaaa8..53acffe9a858 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -401,7 +401,6 @@ static int bfin_musb_init(struct musb *musb) } gpio_direction_output(musb->config->gpio_vrsel, 0); - usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { gpio_free(musb->config->gpio_vrsel); @@ -424,9 +423,8 @@ static int bfin_musb_init(struct musb *musb) static int bfin_musb_exit(struct musb *musb) { gpio_free(musb->config->gpio_vrsel); - usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); + return 0; } @@ -477,6 +475,7 @@ static int bfin_probe(struct platform_device *pdev) pdata->platform_ops = &bfin_ops; + usb_phy_generic_register(); platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -528,6 +527,7 @@ static int bfin_remove(struct platform_device *pdev) struct bfin_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); + usb_phy_generic_unregister(); kfree(glue); return 0; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index a0dabb05de76..024751f9b31d 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -418,7 +418,6 @@ static int da8xx_musb_init(struct musb *musb) if (!rev) goto fail; - usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { ret = -EPROBE_DEFER; @@ -453,7 +452,6 @@ static int da8xx_musb_exit(struct musb *musb) phy_off(); usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); return 0; } @@ -512,6 +510,7 @@ static int da8xx_probe(struct platform_device *pdev) pdata->platform_ops = &da8xx_ops; + usb_phy_generic_register(); platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -561,6 +560,7 @@ static int da8xx_remove(struct platform_device *pdev) struct da8xx_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); + usb_phy_generic_unregister(); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 737035457858..de8492b06e46 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -381,7 +381,6 @@ static int davinci_musb_init(struct musb *musb) u32 revision; int ret = -ENODEV; - usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { ret = -EPROBE_DEFER; @@ -487,7 +486,6 @@ static int davinci_musb_exit(struct musb *musb) phy_off(); usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); return 0; } @@ -545,6 +543,7 @@ static int davinci_probe(struct platform_device *pdev) pdata->platform_ops = &davinci_ops; + usb_phy_generic_register(); platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -603,6 +602,7 @@ static int davinci_remove(struct platform_device *pdev) struct davinci_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); + usb_phy_generic_unregister(); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 8d4a8194c8f2..e1da199c6f21 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1065,7 +1065,6 @@ static int tusb_musb_init(struct musb *musb) void __iomem *sync = NULL; int ret; - usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) return -EPROBE_DEFER; @@ -1117,7 +1116,6 @@ done: iounmap(sync); usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); } return ret; } @@ -1133,7 +1131,6 @@ static int tusb_musb_exit(struct musb *musb) iounmap(musb->sync_va); usb_put_phy(musb->xceiv); - usb_phy_generic_unregister(); return 0; } @@ -1176,6 +1173,7 @@ static int tusb_probe(struct platform_device *pdev) pdata->platform_ops = &tusb_ops; + usb_phy_generic_register(); platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -1224,6 +1222,7 @@ static int tusb_remove(struct platform_device *pdev) struct tusb6010_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); + usb_phy_generic_unregister(); kfree(glue); return 0; -- cgit v1.2.3 From 2f36ff6915c6c00df8b9962d9c6c7992befcf8ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Apr 2014 16:16:33 -0500 Subject: usb: phy: generic: allow multiples calls to usb_phy_generic_register() it's now very easy to return a platform_device pointer and have the caller pass it as argument when calling usb_phy_generic_unregister(). Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 12 +++++++++--- drivers/usb/musb/blackfin.c | 10 ++++++++-- drivers/usb/musb/da8xx.c | 14 +++++++++++--- drivers/usb/musb/tusb6010.c | 3 ++- drivers/usb/phy/phy-generic.c | 19 +++++-------------- 5 files changed, 35 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 05459b56b2a8..0a34dd859555 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -85,6 +85,7 @@ struct am35x_glue { struct device *dev; struct platform_device *musb; + struct platform_device *phy; struct clk *phy_clk; struct clk *clk; }; @@ -503,7 +504,9 @@ static int am35x_probe(struct platform_device *pdev) pdata->platform_ops = &am35x_ops; - usb_phy_generic_register(); + glue->phy = usb_phy_generic_register(); + if (IS_ERR(glue->phy)) + goto err7; platform_set_drvdata(pdev, glue); pinfo = am35x_dev_info; @@ -517,11 +520,14 @@ static int am35x_probe(struct platform_device *pdev) if (IS_ERR(musb)) { ret = PTR_ERR(musb); dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err7; + goto err8; } return 0; +err8: + usb_phy_generic_unregister(glue->phy); + err7: clk_disable(clk); @@ -546,7 +552,7 @@ static int am35x_remove(struct platform_device *pdev) struct am35x_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); - usb_phy_generic_unregister(); + usb_phy_generic_unregister(glue->phy); clk_disable(glue->clk); clk_disable(glue->phy_clk); clk_put(glue->clk); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 53acffe9a858..d40d5f0b5528 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -29,6 +29,7 @@ struct bfin_glue { struct device *dev; struct platform_device *musb; + struct platform_device *phy; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) @@ -475,7 +476,9 @@ static int bfin_probe(struct platform_device *pdev) pdata->platform_ops = &bfin_ops; - usb_phy_generic_register(); + glue->phy = usb_phy_generic_register(); + if (IS_ERR(glue->phy)) + goto err2; platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -513,6 +516,9 @@ static int bfin_probe(struct platform_device *pdev) return 0; err3: + usb_phy_generic_unregister(glue->phy); + +err2: platform_device_put(musb); err1: @@ -527,7 +533,7 @@ static int bfin_remove(struct platform_device *pdev) struct bfin_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); - usb_phy_generic_unregister(); + usb_phy_generic_unregister(glue->phy); kfree(glue); return 0; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 024751f9b31d..058775e647ad 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -85,6 +85,7 @@ struct da8xx_glue { struct device *dev; struct platform_device *musb; + struct platform_device *phy; struct clk *clk; }; @@ -510,7 +511,11 @@ static int da8xx_probe(struct platform_device *pdev) pdata->platform_ops = &da8xx_ops; - usb_phy_generic_register(); + glue->phy = usb_phy_generic_register(); + if (IS_ERR(glue->phy)) { + ret = PTR_ERR(glue->phy); + goto err5; + } platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -537,11 +542,14 @@ static int da8xx_probe(struct platform_device *pdev) if (IS_ERR(musb)) { ret = PTR_ERR(musb); dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err5; + goto err6; } return 0; +err6: + usb_phy_generic_unregister(glue->phy); + err5: clk_disable(clk); @@ -560,7 +568,7 @@ static int da8xx_remove(struct platform_device *pdev) struct da8xx_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); - usb_phy_generic_unregister(); + usb_phy_generic_unregister(glue->phy); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index e1da199c6f21..f38a8dbd6075 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -31,6 +31,7 @@ struct tusb6010_glue { struct device *dev; struct platform_device *musb; + struct platform_device *phy; }; static void tusb_musb_set_vbus(struct musb *musb, int is_on); @@ -1222,7 +1223,7 @@ static int tusb_remove(struct platform_device *pdev) struct tusb6010_glue *glue = platform_get_drvdata(pdev); platform_device_unregister(glue->musb); - usb_phy_generic_unregister(); + usb_phy_generic_unregister(glue->phy); kfree(glue); return 0; diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 2c49cd8f6d25..7594e5069ae5 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -41,25 +41,16 @@ #include "phy-generic.h" -static struct platform_device *pd; - -void usb_phy_generic_register(void) +struct platform_device *usb_phy_generic_register(void) { - if (pd) - return; - pd = platform_device_register_simple("usb_phy_generic", -1, NULL, 0); - if (IS_ERR(pd)) { - pr_err("Unable to register generic usb transceiver\n"); - pd = NULL; - return; - } + return platform_device_register_simple("usb_phy_generic", + PLATFORM_DEVID_AUTO, NULL, 0); } EXPORT_SYMBOL_GPL(usb_phy_generic_register); -void usb_phy_generic_unregister(void) +void usb_phy_generic_unregister(struct platform_device *pdev) { - platform_device_unregister(pd); - pd = NULL; + platform_device_unregister(pdev); } EXPORT_SYMBOL_GPL(usb_phy_generic_unregister); -- cgit v1.2.3 From 22876266de43ec24ae93f635490c40edabaf8278 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 27 Mar 2014 16:15:53 +0100 Subject: usb: gadget: gr_udc: improve platform_device variable name Rename struct platform_device pointers from ofdev to pdev for clarity, while at that, also use platform_set/get_drvdata() helpers. Suggested-by: Mark Rutland Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index f984ee75324d..ae5bebe98b2d 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -2065,9 +2065,9 @@ static int gr_udc_init(struct gr_udc *dev) return 0; } -static int gr_remove(struct platform_device *ofdev) +static int gr_remove(struct platform_device *pdev) { - struct gr_udc *dev = dev_get_drvdata(&ofdev->dev); + struct gr_udc *dev = platform_get_drvdata(pdev); if (dev->added) usb_del_gadget_udc(&dev->gadget); /* Shuts everything down */ @@ -2077,7 +2077,7 @@ static int gr_remove(struct platform_device *ofdev) gr_dfs_delete(dev); if (dev->desc_pool) dma_pool_destroy(dev->desc_pool); - dev_set_drvdata(&ofdev->dev, NULL); + platform_set_drvdata(pdev, NULL); gr_free_request(&dev->epi[0].ep, &dev->ep0reqi->req); gr_free_request(&dev->epo[0].ep, &dev->ep0reqo->req); @@ -2090,7 +2090,7 @@ static int gr_request_irq(struct gr_udc *dev, int irq) IRQF_SHARED, driver_name, dev); } -static int gr_probe(struct platform_device *ofdev) +static int gr_probe(struct platform_device *pdev) { struct gr_udc *dev; struct resource *res; @@ -2098,12 +2098,12 @@ static int gr_probe(struct platform_device *ofdev) int retval; u32 status; - dev = devm_kzalloc(&ofdev->dev, sizeof(*dev), GFP_KERNEL); + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - dev->dev = &ofdev->dev; + dev->dev = &pdev->dev; - res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(dev->dev, res); if (IS_ERR(regs)) return PTR_ERR(regs); @@ -2132,7 +2132,7 @@ static int gr_probe(struct platform_device *ofdev) spin_lock_init(&dev->lock); dev->regs = regs; - dev_set_drvdata(&ofdev->dev, dev); + platform_set_drvdata(pdev, dev); /* Determine number of endpoints and data interface mode */ status = gr_read32(&dev->regs->status); @@ -2204,7 +2204,7 @@ out: spin_unlock(&dev->lock); if (retval) - gr_remove(ofdev); + gr_remove(pdev); return retval; } -- cgit v1.2.3 From 196800da39a142e2952ad5e1cb58a84838956764 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 27 Mar 2014 16:15:55 +0100 Subject: usb: gadget: gr_udc: Use platform_get_irq instead of irq_of_parse_and_map Use platform_get_irq as no mapping needs to be done. No functional difference for SPARC which is the typical environment for the driver though. Suggested by Mark Rutland. Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index ae5bebe98b2d..7a992546335d 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -2108,20 +2108,22 @@ static int gr_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); - dev->irq = irq_of_parse_and_map(dev->dev->of_node, 0); - if (!dev->irq) { + dev->irq = platform_get_irq(pdev, 0); + if (dev->irq <= 0) { dev_err(dev->dev, "No irq found\n"); return -ENODEV; } /* Some core configurations has separate irqs for IN and OUT events */ - dev->irqi = irq_of_parse_and_map(dev->dev->of_node, 1); - if (dev->irqi) { - dev->irqo = irq_of_parse_and_map(dev->dev->of_node, 2); - if (!dev->irqo) { + dev->irqi = platform_get_irq(pdev, 1); + if (dev->irqi > 0) { + dev->irqo = platform_get_irq(pdev, 2); + if (dev->irqo <= 0) { dev_err(dev->dev, "Found irqi but not irqo\n"); return -ENODEV; } + } else { + dev->irqi = 0; } dev->gadget.name = driver_name; -- cgit v1.2.3 From 73e1c093e83a421d24d54a94cb87031e7c222cd1 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 27 Mar 2014 16:15:56 +0100 Subject: usb: gadget: gr_udc: Use of_property_read_u32_index to access arrays Use an appropriate accessor function for property arrays to make the code nicer and make the code correct if it would ever run on little endian architectures. Suggested by Mark Rutland. Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 7a992546335d..0f3a9531479a 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -2020,9 +2020,7 @@ static int gr_udc_init(struct gr_udc *dev) u32 dmactrl_val; int i; int ret = 0; - u32 *bufsizes; u32 bufsize; - int len; gr_set_address(dev, 0); @@ -2033,19 +2031,17 @@ static int gr_udc_init(struct gr_udc *dev) INIT_LIST_HEAD(&dev->ep_list); gr_set_ep0state(dev, GR_EP0_DISCONNECT); - bufsizes = (u32 *)of_get_property(np, "epobufsizes", &len); - len /= sizeof(u32); for (i = 0; i < dev->nepo; i++) { - bufsize = (bufsizes && i < len) ? bufsizes[i] : 1024; + if (of_property_read_u32_index(np, "epobufsizes", i, &bufsize)) + bufsize = 1024; ret = gr_ep_init(dev, i, 0, bufsize); if (ret) return ret; } - bufsizes = (u32 *)of_get_property(np, "epibufsizes", &len); - len /= sizeof(u32); for (i = 0; i < dev->nepi; i++) { - bufsize = (bufsizes && i < len) ? bufsizes[i] : 1024; + if (of_property_read_u32_index(np, "epibufsizes", i, &bufsize)) + bufsize = 1024; ret = gr_ep_init(dev, i, 1, bufsize); if (ret) return ret; -- cgit v1.2.3 From 5bddbd72c6c02498aba8b48527c86d1398dba3f4 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 27 Mar 2014 16:15:57 +0100 Subject: usb: gadget: gr_udc: Add ep.maxpacket_limit to debugfs information Add information on ep.maxpacket_limit for each endpoint in the debugfs information. Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 0f3a9531479a..253e608b57f9 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -143,6 +143,7 @@ static void gr_seq_ep_show(struct seq_file *seq, struct gr_ep *ep) seq_printf(seq, " wedged = %d\n", ep->wedged); seq_printf(seq, " callback = %d\n", ep->callback); seq_printf(seq, " maxpacket = %d\n", ep->ep.maxpacket); + seq_printf(seq, " maxpacket_limit = %d\n", ep->ep.maxpacket_limit); seq_printf(seq, " bytes_per_buffer = %d\n", ep->bytes_per_buffer); if (mode == 1 || mode == 3) seq_printf(seq, " nt = %d\n", -- cgit v1.2.3 From b38d27e5527c33a2a1f5bb3aee39b755e57dea86 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 27 Mar 2014 16:15:58 +0100 Subject: usb: gadget: gr_udc: Return error code when trying to set ep.maxpacket > ep.maxpacket_limit Make gr_ep_enable fail properly when a call requests a larger ep.maxpacket than ep.maxpacket_limit. Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 253e608b57f9..72458be7763a 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -1542,6 +1542,10 @@ static int gr_ep_enable(struct usb_ep *_ep, } else if (max == 0) { dev_err(dev->dev, "Max payload cannot be set to 0\n"); return -EINVAL; + } else if (max > ep->ep.maxpacket_limit) { + dev_err(dev->dev, "Requested max payload %d > limit %d\n", + max, ep->ep.maxpacket_limit); + return -EINVAL; } spin_lock(&ep->dev->lock); -- cgit v1.2.3 From 8652bcbfa09ca5ba24423c7c45c28b7d8771e0a8 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Tue, 1 Apr 2014 12:15:17 +0200 Subject: usb: gadget: gr_udc: Use GFP_ATOMIC when allocating under held spinlock As gr_ep_init must be called with dev->lock held, GFP_KERNEL must not be used. Reported-by: Dan Carpenter Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 72458be7763a..4966971d6978 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -1990,8 +1990,8 @@ static int gr_ep_init(struct gr_udc *dev, int num, int is_in, u32 maxplimit) INIT_LIST_HEAD(&ep->queue); if (num == 0) { - _req = gr_alloc_request(&ep->ep, GFP_KERNEL); - buf = devm_kzalloc(dev->dev, PAGE_SIZE, GFP_DMA | GFP_KERNEL); + _req = gr_alloc_request(&ep->ep, GFP_ATOMIC); + buf = devm_kzalloc(dev->dev, PAGE_SIZE, GFP_DMA | GFP_ATOMIC); if (!_req || !buf) { /* possible _req freed by gr_probe via gr_remove */ return -ENOMEM; -- cgit v1.2.3 From 1e42d20c88f2f56c0d81363d7b0f1d3762037f53 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 2 Apr 2014 13:58:27 +0200 Subject: usb: musb: add reset hook to platform ops Babble interrupts require us to reset the DSPS glue layer. In order to handle all other recovery tasks independently, add a new hook for platform-specific implementations of the actual reset. Signed-off-by: Daniel Mack Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 7083e82776ff..5514e4c82932 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -192,6 +192,7 @@ struct musb_platform_ops { int (*set_mode)(struct musb *musb, u8 mode); void (*try_idle)(struct musb *musb, unsigned long timeout); + void (*reset)(struct musb *musb); int (*vbus_status)(struct musb *musb); void (*set_vbus)(struct musb *musb, int on); @@ -552,6 +553,12 @@ static inline void musb_platform_try_idle(struct musb *musb, musb->ops->try_idle(musb, timeout); } +static inline void musb_platform_reset(struct musb *musb) +{ + if (musb->ops->reset) + musb->ops->reset(musb); +} + static inline int musb_platform_get_vbus_status(struct musb *musb) { if (!musb->ops->vbus_status) -- cgit v1.2.3 From ca88fc2ef0d790a1da37804219102336f7622b97 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 2 Apr 2014 13:58:28 +0200 Subject: usb: musb: add a work_struct to recover from babble errors Handle BABBLE interrupt error conditions from a work struct handler. This indirection is necessary as we can't be certain that the phy functions don't sleep. Platform layer implementation may pass a babble error down to the core in order to handle it. Signed-off-by: Daniel Mack Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 35 +++++++++++++++++++++++++++++++++++ drivers/usb/musb/musb_core.h | 1 + 2 files changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 07576907e2c6..61da471b7aed 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -848,6 +848,10 @@ b_host: } } + /* handle babble condition */ + if (int_usb & MUSB_INTR_BABBLE) + schedule_work(&musb->recover_work); + #if 0 /* REVISIT ... this would be for multiplexing periodic endpoints, or * supporting transfer phasing to prevent exceeding ISO bandwidth @@ -1746,6 +1750,34 @@ static void musb_irq_work(struct work_struct *data) } } +/* Recover from babble interrupt conditions */ +static void musb_recover_work(struct work_struct *data) +{ + struct musb *musb = container_of(data, struct musb, recover_work); + int status; + + musb_platform_reset(musb); + + usb_phy_vbus_off(musb->xceiv); + udelay(100); + + usb_phy_vbus_on(musb->xceiv); + udelay(100); + + /* + * When a babble condition occurs, the musb controller removes the + * session bit and the endpoint config is lost. + */ + if (musb->dyn_fifo) + status = ep_config_from_table(musb); + else + status = ep_config_from_hw(musb); + + /* start the session again */ + if (status == 0) + musb_start(musb); +} + /* -------------------------------------------------------------------------- * Init support */ @@ -1913,6 +1945,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* Init IRQ workqueue before request_irq */ INIT_WORK(&musb->irq_work, musb_irq_work); + INIT_WORK(&musb->recover_work, musb_recover_work); INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); @@ -2008,6 +2041,7 @@ fail4: fail3: cancel_work_sync(&musb->irq_work); + cancel_work_sync(&musb->recover_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); if (musb->dma_controller) @@ -2073,6 +2107,7 @@ static int musb_remove(struct platform_device *pdev) dma_controller_destroy(musb->dma_controller); cancel_work_sync(&musb->irq_work); + cancel_work_sync(&musb->recover_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); musb_free(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 5514e4c82932..47e88747e3a7 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -297,6 +297,7 @@ struct musb { irqreturn_t (*isr)(int, void *); struct work_struct irq_work; + struct work_struct recover_work; struct delayed_work deassert_reset_work; struct delayed_work finish_resume_work; u16 hwvers; -- cgit v1.2.3 From 1d57de306e1f3e73c607811a974f6662162e5df6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 2 Apr 2014 13:58:29 +0200 Subject: usb: musb: dsps: handle babble interrupts When the dsps isr sees a babble error, pass it down to the core for fixup. Also, provide a .reset hook so the core can call us back. A babble interrupt error occured when a USB mass storage device ("CHIPSBNK v3.3.9.1", 1e3d:2093) was disconnected from a AM33xx host. Signed-off-by: Daniel Mack Reported-by: Thomas Mellenthin Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 18882924d9d5..138d1dd86235 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -329,9 +329,21 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. * Also, DRVVBUS pulses for SRP (but not at 5V) ... */ - if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) + if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) { pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); + /* + * When a babble condition occurs, the musb controller removes + * the session and is no longer in host mode. Hence, all + * devices connected to its root hub get disconnected. + * + * Hand this error down to the musb core isr, so it can + * recover. + */ + musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT; + musb->int_tx = musb->int_rx = 0; + } + if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { int drvvbus = dsps_readl(reg_base, wrp->status); void __iomem *mregs = musb->mregs; @@ -523,6 +535,16 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) return 0; } +static void dsps_musb_reset(struct musb *musb) +{ + struct device *dev = musb->controller; + struct dsps_glue *glue = dev_get_drvdata(dev->parent); + const struct dsps_musb_wrapper *wrp = glue->wrp; + + dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); + udelay(100); +} + static struct musb_platform_ops dsps_ops = { .init = dsps_musb_init, .exit = dsps_musb_exit, @@ -532,6 +554,7 @@ static struct musb_platform_ops dsps_ops = { .try_idle = dsps_musb_try_idle, .set_mode = dsps_musb_set_mode, + .reset = dsps_musb_reset, }; static u64 musb_dmamask = DMA_BIT_MASK(32); -- cgit v1.2.3 From aea8928aba7d7ee2e6245d44ba7de4c04fc90559 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 8 Apr 2014 10:42:40 +0200 Subject: usb: dwc3: add glue layer dependencies Glue layers for the DWC3 driver only make sense on specific platforms. Add dependencies so that they are not built where they aren't needed. Cc: Greg Kroah-Hartman Cc: WingMan Kwok Signed-off-by: Jean Delvare Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index e2c730fc9a90..8eb996e4f058 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -44,7 +44,7 @@ comment "Platform Glue Driver Support" config USB_DWC3_OMAP tristate "Texas Instruments OMAP5 and similar Platforms" - depends on EXTCON + depends on EXTCON && (ARCH_OMAP2PLUS || COMPILE_TEST) default USB_DWC3 help Some platforms from Texas Instruments like OMAP5, DRA7xxx and @@ -54,6 +54,7 @@ config USB_DWC3_OMAP config USB_DWC3_EXYNOS tristate "Samsung Exynos Platform" + depends on ARCH_EXYNOS || COMPILE_TEST default USB_DWC3 help Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside, @@ -72,6 +73,7 @@ config USB_DWC3_PCI config USB_DWC3_KEYSTONE tristate "Texas Instruments Keystone2 Platforms" + depends on ARCH_KEYSTONE || COMPILE_TEST default USB_DWC3 help Support of USB2/3 functionality in TI Keystone2 platforms. -- cgit v1.2.3 From 9f58fa4c919e1a33e3844f6851735ec9f724bf52 Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Fri, 11 Apr 2014 18:05:13 +0800 Subject: usb: gadget: f_subset: replace PTR_RET with PTR_ERR_OR_ZERO PTR_RET is deprecated. Do not recommend its usage anymore. Use PTR_ERR_OR_ZERO instead. Signed-off-by: Duan Jiong Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_subset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index df4a0dcbc993..1ea8baf33333 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -276,7 +276,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } net = gether_connect(&geth->port); - return PTR_RET(net); + return PTR_ERR_OR_ZERO(net); } static void geth_disable(struct usb_function *f) -- cgit v1.2.3 From 5b7839836109a802b144a05cfbd4f57e6564d8e5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 17 Apr 2014 10:20:32 +0200 Subject: usb: musb: dsps: compile suspend/resume only with PM_SLEEP Depending on PM is not enough, because only PM_RUNTIME could be selected. Fixes: drivers/usb/musb/musb_dsps.c:703:12: warning: 'dsps_suspend' defined but not used [-Wunused-function] drivers/usb/musb/musb_dsps.c:721:12: warning: 'dsps_resume' defined but not used [-Wunused-function] Signed-off-by: Wolfram Sang Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 138d1dd86235..9d9acaaa1f18 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -774,7 +774,7 @@ static const struct of_device_id musb_dsps_of_match[] = { }; MODULE_DEVICE_TABLE(of, musb_dsps_of_match); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int dsps_suspend(struct device *dev) { struct dsps_glue *glue = dev_get_drvdata(dev); -- cgit v1.2.3 From bd8ce544ec35ff362489a7e3c059cf496c06c68e Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Mon, 21 Apr 2014 17:46:44 +0530 Subject: usb: dwc3: exynos: Make provision for vdd regulators Facilitate getting required 3.3V and 1.0V VDD supply for DWC3 controller on Exynos. With patches for regulators' nodes merged in 3.15: c8c253f ARM: dts: Add regulator entries to smdk5420 275dcd2 ARM: dts: add max77686 pmic node for smdk5250, certain perripherals will now need to ensure that, they request VDD regulators in their drivers, and enable them so as to make them working. Signed-off-by: Vivek Gautam Cc: Anton Tikhomirov Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 51 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index ed22d722884e..0ed85834bfec 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -27,6 +27,7 @@ #include #include #include +#include struct dwc3_exynos { struct platform_device *usb2_phy; @@ -34,6 +35,8 @@ struct dwc3_exynos { struct device *dev; struct clk *clk; + struct regulator *vdd33; + struct regulator *vdd10; }; static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) @@ -144,20 +147,46 @@ static int dwc3_exynos_probe(struct platform_device *pdev) clk_prepare_enable(exynos->clk); + exynos->vdd33 = devm_regulator_get(dev, "vdd33"); + if (IS_ERR(exynos->vdd33)) { + ret = PTR_ERR(exynos->vdd33); + goto err2; + } + ret = regulator_enable(exynos->vdd33); + if (ret) { + dev_err(dev, "Failed to enable VDD33 supply\n"); + goto err2; + } + + exynos->vdd10 = devm_regulator_get(dev, "vdd10"); + if (IS_ERR(exynos->vdd10)) { + ret = PTR_ERR(exynos->vdd10); + goto err3; + } + ret = regulator_enable(exynos->vdd10); + if (ret) { + dev_err(dev, "Failed to enable VDD10 supply\n"); + goto err3; + } + if (node) { ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { dev_err(dev, "failed to add dwc3 core\n"); - goto err2; + goto err4; } } else { dev_err(dev, "no device node, failed to add dwc3 core\n"); ret = -ENODEV; - goto err2; + goto err4; } return 0; +err4: + regulator_disable(exynos->vdd10); +err3: + regulator_disable(exynos->vdd33); err2: clk_disable_unprepare(clk); err1: @@ -174,6 +203,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev) clk_disable_unprepare(exynos->clk); + regulator_disable(exynos->vdd33); + regulator_disable(exynos->vdd10); + return 0; } @@ -192,12 +224,27 @@ static int dwc3_exynos_suspend(struct device *dev) clk_disable(exynos->clk); + regulator_disable(exynos->vdd33); + regulator_disable(exynos->vdd10); + return 0; } static int dwc3_exynos_resume(struct device *dev) { struct dwc3_exynos *exynos = dev_get_drvdata(dev); + int ret; + + ret = regulator_enable(exynos->vdd33); + if (ret) { + dev_err(dev, "Failed to enable VDD33 supply\n"); + return ret; + } + ret = regulator_enable(exynos->vdd10); + if (ret) { + dev_err(dev, "Failed to enable VDD10 supply\n"); + return ret; + } clk_enable(exynos->clk); -- cgit v1.2.3 From 40cc57c71b27998c558d4ea23556cad2baef8a56 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 25 Apr 2014 14:10:02 -0500 Subject: usb: dwc3: gadget: print both cmd string and number That way it's easy for humans looking at dmesg and humans(?) looking at Databooks. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f0dc0ee85ded..f5adf3fd8d89 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -336,9 +336,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, u32 timeout = 500; u32 reg; - dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n", + dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n", dep->name, - dwc3_gadget_ep_cmd_string(cmd), params->param0, + dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0, params->param1, params->param2); dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); -- cgit v1.2.3 From e57ebc1db6ef796124b69abca044a373b9110a47 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 22 Apr 2014 13:20:12 -0500 Subject: usb: dwc3: gadget: pretty print link states this makes it slightly easier to read link state change interrupt logs. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f5adf3fd8d89..9a8ae39f7fa8 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -302,6 +302,42 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd) } } +static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state) +{ + switch (link_state) { + case DWC3_LINK_STATE_U0: + return "U0"; + case DWC3_LINK_STATE_U1: + return "U1"; + case DWC3_LINK_STATE_U2: + return "U2"; + case DWC3_LINK_STATE_U3: + return "U3"; + case DWC3_LINK_STATE_SS_DIS: + return "SS.Disabled"; + case DWC3_LINK_STATE_RX_DET: + return "RX.Detect"; + case DWC3_LINK_STATE_SS_INACT: + return "SS.Inactive"; + case DWC3_LINK_STATE_POLL: + return "Polling"; + case DWC3_LINK_STATE_RECOV: + return "Recovery"; + case DWC3_LINK_STATE_HRESET: + return "Hot Reset"; + case DWC3_LINK_STATE_CMPLY: + return "Compliance"; + case DWC3_LINK_STATE_LPBK: + return "Loopback"; + case DWC3_LINK_STATE_RESET: + return "Reset"; + case DWC3_LINK_STATE_RESUME: + return "Resume"; + default: + return "UNKNOWN link state\n"; + } +} + int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) { u32 timeout = 500; @@ -2449,8 +2485,6 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, } } - dwc->link_state = next; - switch (next) { case DWC3_LINK_STATE_U1: if (dwc->speed == USB_SPEED_SUPER) @@ -2468,7 +2502,11 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, break; } - dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); + dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n", + dwc3_gadget_link_string(dwc->link_state), + dwc->link_state, dwc3_gadget_link_string(next), next); + + dwc->link_state = next; } static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, -- cgit v1.2.3 From 427c3df684ab97379b529188d505cc99c2a1429d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 25 Apr 2014 14:14:14 -0500 Subject: usb: dwc3: gadget: pretty print Generic CMDs this makes it slightly easier to read generic CMD logs. It also helps make sure we're sending proper parameters for each command. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9a8ae39f7fa8..e0b791050930 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -302,6 +302,32 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd) } } +static const char *dwc3_gadget_generic_cmd_string(u8 cmd) +{ + switch (cmd) { + case DWC3_DGCMD_SET_LMP: + return "Set LMP"; + case DWC3_DGCMD_SET_PERIODIC_PAR: + return "Set Periodic Parameters"; + case DWC3_DGCMD_XMIT_FUNCTION: + return "Transmit Function Wake Device Notification"; + case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: + return "Set Scratchpad Buffer Array Address Lo"; + case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: + return "Set Scratchpad Buffer Array Address Hi"; + case DWC3_DGCMD_SELECTED_FIFO_FLUSH: + return "Selected FIFO Flush"; + case DWC3_DGCMD_ALL_FIFO_FLUSH: + return "All FIFO Flush"; + case DWC3_DGCMD_SET_ENDPOINT_NRDY: + return "Set Endpoint NRDY"; + case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: + return "Run SoC Bus Loopback Test"; + default: + return "UNKNOWN"; + } +} + static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state) { switch (link_state) { @@ -343,6 +369,9 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) u32 timeout = 500; u32 reg; + dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n", + dwc3_gadget_generic_cmd_string(cmd), cmd, param); + dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); -- cgit v1.2.3 From 0d092fdb8c7a1b874d5c1b56f14d97b62df13186 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:04 +0300 Subject: usb: phy: msm: Make driver selectable on ARCH_QCOM Controller could be found on APQ and MSM platforms, make configuration description more generic. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 416e0c8cf6ff..0c668a3f5c37 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -171,11 +171,11 @@ config USB_ISP1301 module will be called phy-isp1301. config USB_MSM_OTG - tristate "OTG support for Qualcomm on-chip USB controller" - depends on (USB || USB_GADGET) && ARCH_MSM + tristate "Qualcomm on-chip USB OTG controller support" + depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM) select USB_PHY help - Enable this to support the USB OTG transceiver on MSM chips. It + Enable this to support the USB OTG transceiver on Qualcomm chips. It handles PHY initialization, clock management, and workarounds required after resetting the hardware and power management. This driver is required even for peripheral only or host only -- cgit v1.2.3 From 37cfdaf782590e277d9352626dba4496734e0375 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:06 +0300 Subject: usb: phy: msm: Move global regulators variables to driver state Eliminating global variables allows driver to handle multiple device instances. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 82 ++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 5b37b81f2ef6..878f67d29ed5 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -58,47 +58,43 @@ #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ -static struct regulator *hsusb_3p3; -static struct regulator *hsusb_1p8; -static struct regulator *hsusb_vddcx; - static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) { int ret = 0; if (init) { - hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); - if (IS_ERR(hsusb_vddcx)) { + motg->vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); + if (IS_ERR(motg->vddcx)) { dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); - return PTR_ERR(hsusb_vddcx); + return PTR_ERR(motg->vddcx); } - ret = regulator_set_voltage(hsusb_vddcx, + ret = regulator_set_voltage(motg->vddcx, USB_PHY_VDD_DIG_VOL_MIN, USB_PHY_VDD_DIG_VOL_MAX); if (ret) { dev_err(motg->phy.dev, "unable to set the voltage " "for hsusb vddcx\n"); - regulator_put(hsusb_vddcx); + regulator_put(motg->vddcx); return ret; } - ret = regulator_enable(hsusb_vddcx); + ret = regulator_enable(motg->vddcx); if (ret) { dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - regulator_put(hsusb_vddcx); + regulator_put(motg->vddcx); } } else { - ret = regulator_set_voltage(hsusb_vddcx, 0, + ret = regulator_set_voltage(motg->vddcx, 0, USB_PHY_VDD_DIG_VOL_MAX); if (ret) dev_err(motg->phy.dev, "unable to set the voltage " "for hsusb vddcx\n"); - ret = regulator_disable(hsusb_vddcx); + ret = regulator_disable(motg->vddcx); if (ret) dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - regulator_put(hsusb_vddcx); + regulator_put(motg->vddcx); } return ret; @@ -109,38 +105,38 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) int rc = 0; if (init) { - hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); - if (IS_ERR(hsusb_3p3)) { + motg->v3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); + if (IS_ERR(motg->v3p3)) { dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); - return PTR_ERR(hsusb_3p3); + return PTR_ERR(motg->v3p3); } - rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, + rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, USB_PHY_3P3_VOL_MAX); if (rc) { dev_err(motg->phy.dev, "unable to set voltage level " "for hsusb 3p3\n"); goto put_3p3; } - rc = regulator_enable(hsusb_3p3); + rc = regulator_enable(motg->v3p3); if (rc) { dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); goto put_3p3; } - hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); - if (IS_ERR(hsusb_1p8)) { + motg->v1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); + if (IS_ERR(motg->v1p8)) { dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); - rc = PTR_ERR(hsusb_1p8); + rc = PTR_ERR(motg->v1p8); goto disable_3p3; } - rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, + rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, USB_PHY_1P8_VOL_MAX); if (rc) { dev_err(motg->phy.dev, "unable to set voltage level " "for hsusb 1p8\n"); goto put_1p8; } - rc = regulator_enable(hsusb_1p8); + rc = regulator_enable(motg->v1p8); if (rc) { dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); goto put_1p8; @@ -149,54 +145,54 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) return 0; } - regulator_disable(hsusb_1p8); + regulator_disable(motg->v1p8); put_1p8: - regulator_put(hsusb_1p8); + regulator_put(motg->v1p8); disable_3p3: - regulator_disable(hsusb_3p3); + regulator_disable(motg->v3p3); put_3p3: - regulator_put(hsusb_3p3); + regulator_put(motg->v3p3); return rc; } -static int msm_hsusb_ldo_set_mode(int on) +static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) { int ret = 0; - if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { + if (!motg->v1p8 || IS_ERR(motg->v1p8)) { pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); return -ENODEV; } - if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { + if (!motg->v3p3 || IS_ERR(motg->v3p3)) { pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); return -ENODEV; } if (on) { - ret = regulator_set_optimum_mode(hsusb_1p8, + ret = regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_HPM_LOAD); if (ret < 0) { pr_err("%s: Unable to set HPM of the regulator " "HSUSB_1p8\n", __func__); return ret; } - ret = regulator_set_optimum_mode(hsusb_3p3, + ret = regulator_set_optimum_mode(motg->v3p3, USB_PHY_3P3_HPM_LOAD); if (ret < 0) { pr_err("%s: Unable to set HPM of the regulator " "HSUSB_3p3\n", __func__); - regulator_set_optimum_mode(hsusb_1p8, + regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_LPM_LOAD); return ret; } } else { - ret = regulator_set_optimum_mode(hsusb_1p8, + ret = regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_LPM_LOAD); if (ret < 0) pr_err("%s: Unable to set LPM of the regulator " "HSUSB_1p8\n", __func__); - ret = regulator_set_optimum_mode(hsusb_3p3, + ret = regulator_set_optimum_mode(motg->v3p3, USB_PHY_3P3_LPM_LOAD); if (ret < 0) pr_err("%s: Unable to set LPM of the regulator " @@ -417,7 +413,7 @@ static int msm_otg_reset(struct usb_phy *phy) #ifdef CONFIG_PM #define USB_PHY_SUSP_DIG_VOL 500000 -static int msm_hsusb_config_vddcx(int high) +static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) { int max_vol = USB_PHY_VDD_DIG_VOL_MAX; int min_vol; @@ -428,7 +424,7 @@ static int msm_hsusb_config_vddcx(int high) else min_vol = USB_PHY_SUSP_DIG_VOL; - ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); + ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); if (ret) { pr_err("%s: unable to set the voltage for regulator " "HSUSB_VDDCX\n", __func__); @@ -518,8 +514,8 @@ static int msm_otg_suspend(struct msm_otg *motg) if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(0); - msm_hsusb_config_vddcx(0); + msm_hsusb_ldo_set_mode(motg, 0); + msm_hsusb_config_vddcx(motg, 0); } if (device_may_wakeup(phy->dev)) @@ -555,8 +551,8 @@ static int msm_otg_resume(struct msm_otg *motg) if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && motg->pdata->otg_control == OTG_PMIC_CONTROL) { - msm_hsusb_ldo_set_mode(1); - msm_hsusb_config_vddcx(1); + msm_hsusb_ldo_set_mode(motg, 1); + msm_hsusb_config_vddcx(motg, 1); writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); } @@ -1521,7 +1517,7 @@ static int __init msm_otg_probe(struct platform_device *pdev) dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); goto vddcx_exit; } - ret = msm_hsusb_ldo_set_mode(1); + ret = msm_hsusb_ldo_set_mode(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg enable failed\n"); goto ldo_exit; -- cgit v1.2.3 From 06a6ec445bfa539285a7f6ae3e6e447a536d5a35 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:07 +0300 Subject: usb: phy: msm: Enable deferred driver probing Using platform_driver_probe() prevent driver from requesting probe deferral. Fix this. While at that, also switch to module_platform_driver() and remove __init annotation from probe(). Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 878f67d29ed5..b7d73f2f4bee 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1402,7 +1402,7 @@ static void msm_otg_debugfs_cleanup(void) debugfs_remove(msm_otg_dbg_root); } -static int __init msm_otg_probe(struct platform_device *pdev) +static int msm_otg_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; @@ -1736,6 +1736,7 @@ static const struct dev_pm_ops msm_otg_dev_pm_ops = { }; static struct platform_driver msm_otg_driver = { + .probe = msm_otg_probe, .remove = msm_otg_remove, .driver = { .name = DRIVER_NAME, @@ -1744,7 +1745,7 @@ static struct platform_driver msm_otg_driver = { }, }; -module_platform_driver_probe(msm_otg_driver, msm_otg_probe); +module_platform_driver(msm_otg_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MSM USB transceiver driver"); -- cgit v1.2.3 From 6b99c68ec1f979ef6ea956516a87afa9bb5551ca Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:08 +0300 Subject: usb: phy: msm: Migrate to Managed Device Resource allocation Move memory, regulators, clocks and irq allocation to devm_* variants. Properly check for valid clk handles. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 187 +++++++++++++++--------------------------- 1 file changed, 68 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index b7d73f2f4bee..67705fcc4b2a 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -63,27 +63,18 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) int ret = 0; if (init) { - motg->vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); - if (IS_ERR(motg->vddcx)) { - dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); - return PTR_ERR(motg->vddcx); - } - ret = regulator_set_voltage(motg->vddcx, USB_PHY_VDD_DIG_VOL_MIN, USB_PHY_VDD_DIG_VOL_MAX); if (ret) { dev_err(motg->phy.dev, "unable to set the voltage " "for hsusb vddcx\n"); - regulator_put(motg->vddcx); return ret; } ret = regulator_enable(motg->vddcx); - if (ret) { + if (ret) dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - regulator_put(motg->vddcx); - } } else { ret = regulator_set_voltage(motg->vddcx, 0, USB_PHY_VDD_DIG_VOL_MAX); @@ -93,8 +84,6 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) ret = regulator_disable(motg->vddcx); if (ret) dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - - regulator_put(motg->vddcx); } return ret; @@ -105,53 +94,38 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) int rc = 0; if (init) { - motg->v3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); - if (IS_ERR(motg->v3p3)) { - dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); - return PTR_ERR(motg->v3p3); - } - rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, USB_PHY_3P3_VOL_MAX); if (rc) { dev_err(motg->phy.dev, "unable to set voltage level " "for hsusb 3p3\n"); - goto put_3p3; + goto exit; } rc = regulator_enable(motg->v3p3); if (rc) { dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); - goto put_3p3; - } - motg->v1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); - if (IS_ERR(motg->v1p8)) { - dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); - rc = PTR_ERR(motg->v1p8); - goto disable_3p3; + goto exit; } rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, USB_PHY_1P8_VOL_MAX); if (rc) { dev_err(motg->phy.dev, "unable to set voltage level " "for hsusb 1p8\n"); - goto put_1p8; + goto disable_3p3; } rc = regulator_enable(motg->v1p8); if (rc) { dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); - goto put_1p8; + goto disable_3p3; } return 0; } regulator_disable(motg->v1p8); -put_1p8: - regulator_put(motg->v1p8); disable_3p3: regulator_disable(motg->v3p3); -put_3p3: - regulator_put(motg->v3p3); +exit: return rc; } @@ -506,7 +480,7 @@ static int msm_otg_suspend(struct msm_otg *motg) clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); - if (motg->core_clk) + if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); if (!IS_ERR(motg->pclk_src)) @@ -546,7 +520,7 @@ static int msm_otg_resume(struct msm_otg *motg) clk_prepare_enable(motg->pclk); clk_prepare_enable(motg->clk); - if (motg->core_clk) + if (!IS_ERR(motg->core_clk)) clk_prepare_enable(motg->core_clk); if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && @@ -1404,6 +1378,7 @@ static void msm_otg_debugfs_cleanup(void) static int msm_otg_probe(struct platform_device *pdev) { + struct regulator_bulk_data regs[3]; int ret = 0; struct resource *res; struct msm_otg *motg; @@ -1415,37 +1390,34 @@ static int msm_otg_probe(struct platform_device *pdev) return -ENODEV; } - motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); + motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); if (!motg) { dev_err(&pdev->dev, "unable to allocate msm_otg\n"); return -ENOMEM; } - motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), + GFP_KERNEL); if (!motg->phy.otg) { dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - ret = -ENOMEM; - goto free_motg; + return -ENOMEM; } motg->pdata = dev_get_platdata(&pdev->dev); phy = &motg->phy; phy->dev = &pdev->dev; - motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); + motg->phy_reset_clk = devm_clk_get(&pdev->dev, "usb_phy_clk"); if (IS_ERR(motg->phy_reset_clk)) { dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); - ret = PTR_ERR(motg->phy_reset_clk); - goto free_motg; + return PTR_ERR(motg->phy_reset_clk); } - motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); + motg->clk = devm_clk_get(&pdev->dev, "usb_hs_clk"); if (IS_ERR(motg->clk)) { dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); - ret = PTR_ERR(motg->clk); - goto put_phy_reset_clk; + return PTR_ERR(motg->clk); } - clk_set_rate(motg->clk, 60000000); /* * If USB Core is running its protocol engine based on CORE CLK, @@ -1454,22 +1426,18 @@ static int msm_otg_probe(struct platform_device *pdev) * CORE CLK. For such USB cores, vote for maximum clk frequency * on pclk source */ + motg->pclk_src = ERR_PTR(-ENOENT); if (motg->pdata->pclk_src_name) { - motg->pclk_src = clk_get(&pdev->dev, - motg->pdata->pclk_src_name); + motg->pclk_src = devm_clk_get(&pdev->dev, + motg->pdata->pclk_src_name); if (IS_ERR(motg->pclk_src)) - goto put_clk; - clk_set_rate(motg->pclk_src, INT_MAX); - clk_prepare_enable(motg->pclk_src); - } else - motg->pclk_src = ERR_PTR(-ENOENT); - + return PTR_ERR(motg->pclk_src); + } - motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); + motg->pclk = devm_clk_get(&pdev->dev, "usb_hs_pclk"); if (IS_ERR(motg->pclk)) { dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); - ret = PTR_ERR(motg->pclk); - goto put_pclk_src; + return PTR_ERR(motg->pclk); } /* @@ -1477,65 +1445,72 @@ static int msm_otg_probe(struct platform_device *pdev) * clock is introduced to remove the dependency on AXI * bus frequency. */ - motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); - if (IS_ERR(motg->core_clk)) - motg->core_clk = NULL; + motg->core_clk = devm_clk_get(&pdev->dev, "usb_hs_core_clk"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get platform resource mem\n"); - ret = -ENODEV; - goto put_core_clk; - } + motg->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (IS_ERR(motg->regs)) + return PTR_ERR(motg->regs); - motg->regs = ioremap(res->start, resource_size(res)); - if (!motg->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto put_core_clk; - } dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); motg->irq = platform_get_irq(pdev, 0); if (!motg->irq) { dev_err(&pdev->dev, "platform_get_irq failed\n"); - ret = -ENODEV; - goto free_regs; + return motg->irq; + } + + regs[0].supply = "HSUSB_VDDCX"; + regs[1].supply = "HSUSB_3p3"; + regs[2].supply = "HSUSB_1p8"; + + ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); + if (ret) + return ret; + + motg->vddcx = regs[0].consumer; + motg->v3p3 = regs[1].consumer; + motg->v1p8 = regs[2].consumer; + + clk_set_rate(motg->clk, 60000000); + if (!IS_ERR(motg->pclk_src)) { + clk_set_rate(motg->pclk_src, INT_MAX); + clk_prepare_enable(motg->pclk_src); } clk_prepare_enable(motg->clk); clk_prepare_enable(motg->pclk); + if (!IS_ERR(motg->core_clk)) + clk_prepare_enable(motg->core_clk); + ret = msm_hsusb_init_vddcx(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); - goto free_regs; + goto disable_clks; } ret = msm_hsusb_ldo_init(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); - goto vddcx_exit; + goto disable_vddcx; } ret = msm_hsusb_ldo_set_mode(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg enable failed\n"); - goto ldo_exit; + goto disable_ldo; } - if (motg->core_clk) - clk_prepare_enable(motg->core_clk); - writel(0, USB_USBINTR); writel(0, USB_OTGSC); INIT_WORK(&motg->sm_work, msm_otg_sm_work); INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); - ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, + ret = devm_request_irq(&pdev->dev, motg->irq, msm_otg_irq, IRQF_SHARED, "msm_otg", motg); if (ret) { dev_err(&pdev->dev, "request irq failed\n"); - goto disable_clks; + goto disable_ldo; } phy->init = msm_otg_reset; @@ -1550,7 +1525,7 @@ static int msm_otg_probe(struct platform_device *pdev) ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); - goto free_irq; + goto disable_ldo; } platform_set_drvdata(pdev, motg); @@ -1568,33 +1543,18 @@ static int msm_otg_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); return 0; -free_irq: - free_irq(motg->irq, motg); + +disable_ldo: + msm_hsusb_ldo_init(motg, 0); +disable_vddcx: + msm_hsusb_init_vddcx(motg, 0); disable_clks: clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); -ldo_exit: - msm_hsusb_ldo_init(motg, 0); -vddcx_exit: - msm_hsusb_init_vddcx(motg, 0); -free_regs: - iounmap(motg->regs); -put_core_clk: - if (motg->core_clk) - clk_put(motg->core_clk); - clk_put(motg->pclk); -put_pclk_src: - if (!IS_ERR(motg->pclk_src)) { + if (!IS_ERR(motg->core_clk)) + clk_disable_unprepare(motg->core_clk); + if (!IS_ERR(motg->pclk_src)) clk_disable_unprepare(motg->pclk_src); - clk_put(motg->pclk_src); - } -put_clk: - clk_put(motg->clk); -put_phy_reset_clk: - clk_put(motg->phy_reset_clk); -free_motg: - kfree(motg->phy.otg); - kfree(motg); return ret; } @@ -1617,7 +1577,7 @@ static int msm_otg_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); usb_remove_phy(phy); - free_irq(motg->irq, motg); + disable_irq(motg->irq); /* * Put PHY in low power mode. @@ -1637,26 +1597,15 @@ static int msm_otg_remove(struct platform_device *pdev) clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); - if (motg->core_clk) + if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) { + if (!IS_ERR(motg->pclk_src)) clk_disable_unprepare(motg->pclk_src); - clk_put(motg->pclk_src); - } + msm_hsusb_ldo_init(motg, 0); - iounmap(motg->regs); pm_runtime_set_suspended(&pdev->dev); - clk_put(motg->phy_reset_clk); - clk_put(motg->pclk); - clk_put(motg->clk); - if (motg->core_clk) - clk_put(motg->core_clk); - - kfree(motg->phy.otg); - kfree(motg); - return 0; } -- cgit v1.2.3 From f7ddad47421669452186678d51c09a3778ab552f Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:09 +0300 Subject: usb: phy: msm: Remove unnecessarily check for valid regulators. Whether regulators are available or not is checked at driver probe. If they are not available driver will refuse to load, so no need to check them again. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 67705fcc4b2a..d7b83600a7da 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -133,16 +133,6 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) { int ret = 0; - if (!motg->v1p8 || IS_ERR(motg->v1p8)) { - pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); - return -ENODEV; - } - - if (!motg->v3p3 || IS_ERR(motg->v3p3)) { - pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); - return -ENODEV; - } - if (on) { ret = regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_HPM_LOAD); -- cgit v1.2.3 From 3aca0fa95f61918d5b78b683c0fbcbf693579f81 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:10 +0300 Subject: usb: phy: msm: Fix checkpatch.pl warnings This fixes following: WARNING: quoted string split across lines WARNING: Prefer seq_puts to seq_printf Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index d7b83600a7da..874c51a85683 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -67,8 +67,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) USB_PHY_VDD_DIG_VOL_MIN, USB_PHY_VDD_DIG_VOL_MAX); if (ret) { - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); + dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); return ret; } @@ -79,8 +78,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) ret = regulator_set_voltage(motg->vddcx, 0, USB_PHY_VDD_DIG_VOL_MAX); if (ret) - dev_err(motg->phy.dev, "unable to set the voltage " - "for hsusb vddcx\n"); + dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); ret = regulator_disable(motg->vddcx); if (ret) dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); @@ -97,8 +95,7 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, USB_PHY_3P3_VOL_MAX); if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 3p3\n"); + dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); goto exit; } rc = regulator_enable(motg->v3p3); @@ -109,8 +106,7 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, USB_PHY_1P8_VOL_MAX); if (rc) { - dev_err(motg->phy.dev, "unable to set voltage level " - "for hsusb 1p8\n"); + dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); goto disable_3p3; } rc = regulator_enable(motg->v1p8); @@ -137,15 +133,13 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) ret = regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_HPM_LOAD); if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_1p8\n", __func__); + pr_err("Could not set HPM for v1p8\n"); return ret; } ret = regulator_set_optimum_mode(motg->v3p3, USB_PHY_3P3_HPM_LOAD); if (ret < 0) { - pr_err("%s: Unable to set HPM of the regulator " - "HSUSB_3p3\n", __func__); + pr_err("Could not set HPM for v3p3\n"); regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_LPM_LOAD); return ret; @@ -154,13 +148,11 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) ret = regulator_set_optimum_mode(motg->v1p8, USB_PHY_1P8_LPM_LOAD); if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_1p8\n", __func__); + pr_err("Could not set LPM for v1p8\n"); ret = regulator_set_optimum_mode(motg->v3p3, USB_PHY_3P3_LPM_LOAD); if (ret < 0) - pr_err("%s: Unable to set LPM of the regulator " - "HSUSB_3p3\n", __func__); + pr_err("Could not set LPM for v3p3\n"); } pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); @@ -390,8 +382,7 @@ static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); if (ret) { - pr_err("%s: unable to set the voltage for regulator " - "HSUSB_VDDCX\n", __func__); + pr_err("Cannot set vddcx voltage\n"); return ret; } @@ -546,8 +537,7 @@ static int msm_otg_resume(struct msm_otg *motg) * PHY. USB state can not be restored. Re-insertion * of USB cable is the only way to get USB working. */ - dev_err(phy->dev, "Unable to resume USB." - "Re-plugin the cable\n"); + dev_err(phy->dev, "Unable to resume USB. Re-plugin the cable\n"); msm_otg_reset(phy); } @@ -1242,13 +1232,13 @@ static int msm_otg_mode_show(struct seq_file *s, void *unused) switch (otg->phy->state) { case OTG_STATE_A_HOST: - seq_printf(s, "host\n"); + seq_puts(s, "host\n"); break; case OTG_STATE_B_PERIPHERAL: - seq_printf(s, "peripheral\n"); + seq_puts(s, "peripheral\n"); break; default: - seq_printf(s, "none\n"); + seq_puts(s, "none\n"); break; } @@ -1525,8 +1515,7 @@ static int msm_otg_probe(struct platform_device *pdev) motg->pdata->otg_control == OTG_USER_CONTROL) { ret = msm_otg_debugfs_init(motg); if (ret) - dev_dbg(&pdev->dev, "mode debugfs file is" - "not available\n"); + dev_dbg(&pdev->dev, "Can not create mode change file\n"); } pm_runtime_set_active(&pdev->dev); -- cgit v1.2.3 From 971232cf7c7a71ad3cbf433f592eee3ae1a578ac Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:11 +0300 Subject: usb: phy: msm: Replace custom enum usb_mode_type with enum usb_dr_mode Use enum usb_dr_mode and drop default usb_dr_mode from platform data. USB DT bindings states: dr_mode: "...In case this attribute isn't passed via DT, USB DRD controllers should default to OTG...", so remove redundand field. Signed-off-by: Ivan T. Ivanov Acked-by: David Brown Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 874c51a85683..7eb2abf3f874 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -348,10 +348,10 @@ static int msm_otg_reset(struct usb_phy *phy) if (pdata->otg_control == OTG_PHY_CONTROL) { val = readl(USB_OTGSC); - if (pdata->mode == USB_OTG) { + if (pdata->mode == USB_DR_MODE_OTG) { ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; val |= OTGSC_IDIE | OTGSC_BSVIE; - } else if (pdata->mode == USB_PERIPHERAL) { + } else if (pdata->mode == USB_DR_MODE_PERIPHERAL) { ulpi_val = ULPI_INT_SESS_VALID; val |= OTGSC_BSVIE; } @@ -637,7 +637,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) * Fail host registration if this board can support * only peripheral configuration. */ - if (motg->pdata->mode == USB_PERIPHERAL) { + if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) { dev_info(otg->phy->dev, "Host mode is not supported\n"); return -ENODEV; } @@ -666,7 +666,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) * Kick the state machine work, if peripheral is not supported * or peripheral is already registered with us. */ - if (motg->pdata->mode == USB_HOST || otg->gadget) { + if (motg->pdata->mode == USB_DR_MODE_HOST || otg->gadget) { pm_runtime_get_sync(otg->phy->dev); schedule_work(&motg->sm_work); } @@ -710,7 +710,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, * Fail peripheral registration if this board can support * only host configuration. */ - if (motg->pdata->mode == USB_HOST) { + if (motg->pdata->mode == USB_DR_MODE_HOST) { dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); return -ENODEV; } @@ -735,7 +735,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, * Kick the state machine work, if host is not supported * or host is already registered with us. */ - if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { + if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL || otg->host) { pm_runtime_get_sync(otg->phy->dev); schedule_work(&motg->sm_work); } @@ -1056,7 +1056,7 @@ static void msm_otg_init_sm(struct msm_otg *motg) u32 otgsc = readl(USB_OTGSC); switch (pdata->mode) { - case USB_OTG: + case USB_DR_MODE_OTG: if (pdata->otg_control == OTG_PHY_CONTROL) { if (otgsc & OTGSC_ID) set_bit(ID, &motg->inputs); @@ -1068,21 +1068,14 @@ static void msm_otg_init_sm(struct msm_otg *motg) else clear_bit(B_SESS_VLD, &motg->inputs); } else if (pdata->otg_control == OTG_USER_CONTROL) { - if (pdata->default_mode == USB_HOST) { - clear_bit(ID, &motg->inputs); - } else if (pdata->default_mode == USB_PERIPHERAL) { - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - } else { set_bit(ID, &motg->inputs); clear_bit(B_SESS_VLD, &motg->inputs); - } } break; - case USB_HOST: + case USB_DR_MODE_HOST: clear_bit(ID, &motg->inputs); break; - case USB_PERIPHERAL: + case USB_DR_MODE_PERIPHERAL: set_bit(ID, &motg->inputs); if (otgsc & OTGSC_BSV) set_bit(B_SESS_VLD, &motg->inputs); @@ -1258,7 +1251,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, char buf[16]; struct usb_otg *otg = motg->phy.otg; int status = count; - enum usb_mode_type req_mode; + enum usb_dr_mode req_mode; memset(buf, 0x00, sizeof(buf)); @@ -1268,18 +1261,18 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, } if (!strncmp(buf, "host", 4)) { - req_mode = USB_HOST; + req_mode = USB_DR_MODE_HOST; } else if (!strncmp(buf, "peripheral", 10)) { - req_mode = USB_PERIPHERAL; + req_mode = USB_DR_MODE_PERIPHERAL; } else if (!strncmp(buf, "none", 4)) { - req_mode = USB_NONE; + req_mode = USB_DR_MODE_UNKNOWN; } else { status = -EINVAL; goto out; } switch (req_mode) { - case USB_NONE: + case USB_DR_MODE_UNKNOWN: switch (otg->phy->state) { case OTG_STATE_A_HOST: case OTG_STATE_B_PERIPHERAL: @@ -1290,7 +1283,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, goto out; } break; - case USB_PERIPHERAL: + case USB_DR_MODE_PERIPHERAL: switch (otg->phy->state) { case OTG_STATE_B_IDLE: case OTG_STATE_A_HOST: @@ -1301,7 +1294,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, goto out; } break; - case USB_HOST: + case USB_DR_MODE_HOST: switch (otg->phy->state) { case OTG_STATE_B_IDLE: case OTG_STATE_B_PERIPHERAL: @@ -1511,7 +1504,7 @@ static int msm_otg_probe(struct platform_device *pdev) platform_set_drvdata(pdev, motg); device_init_wakeup(&pdev->dev, 1); - if (motg->pdata->mode == USB_OTG && + if (motg->pdata->mode == USB_DR_MODE_OTG && motg->pdata->otg_control == OTG_USER_CONTROL) { ret = msm_otg_debugfs_init(motg); if (ret) -- cgit v1.2.3 From ff0e4a68c931dc34e43c081d1b6a895a9aaf8a2b Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:12 +0300 Subject: usb: phy: msm: Remove unused pclk_src_name There are no references to 'pclk_src_name' in plaform code, so it is unused. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 7eb2abf3f874..c2361bfd2002 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -464,9 +464,6 @@ static int msm_otg_suspend(struct msm_otg *motg) if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) - clk_disable_unprepare(motg->pclk_src); - if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && motg->pdata->otg_control == OTG_PMIC_CONTROL) { msm_hsusb_ldo_set_mode(motg, 0); @@ -496,9 +493,6 @@ static int msm_otg_resume(struct msm_otg *motg) if (!atomic_read(&motg->in_lpm)) return 0; - if (!IS_ERR(motg->pclk_src)) - clk_prepare_enable(motg->pclk_src); - clk_prepare_enable(motg->pclk); clk_prepare_enable(motg->clk); if (!IS_ERR(motg->core_clk)) @@ -1396,17 +1390,8 @@ static int msm_otg_probe(struct platform_device *pdev) * If USB Core is running its protocol engine based on CORE CLK, * CORE CLK must be running at >55Mhz for correct HSUSB * operation and USB core cannot tolerate frequency changes on - * CORE CLK. For such USB cores, vote for maximum clk frequency - * on pclk source + * CORE CLK. */ - motg->pclk_src = ERR_PTR(-ENOENT); - if (motg->pdata->pclk_src_name) { - motg->pclk_src = devm_clk_get(&pdev->dev, - motg->pdata->pclk_src_name); - if (IS_ERR(motg->pclk_src)) - return PTR_ERR(motg->pclk_src); - } - motg->pclk = devm_clk_get(&pdev->dev, "usb_hs_pclk"); if (IS_ERR(motg->pclk)) { dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); @@ -1446,10 +1431,6 @@ static int msm_otg_probe(struct platform_device *pdev) motg->v1p8 = regs[2].consumer; clk_set_rate(motg->clk, 60000000); - if (!IS_ERR(motg->pclk_src)) { - clk_set_rate(motg->pclk_src, INT_MAX); - clk_prepare_enable(motg->pclk_src); - } clk_prepare_enable(motg->clk); clk_prepare_enable(motg->pclk); @@ -1525,8 +1506,6 @@ disable_clks: clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) - clk_disable_unprepare(motg->pclk_src); return ret; } @@ -1571,9 +1550,6 @@ static int msm_otg_remove(struct platform_device *pdev) clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); - if (!IS_ERR(motg->pclk_src)) - clk_disable_unprepare(motg->pclk_src); - msm_hsusb_ldo_init(motg, 0); pm_runtime_set_suspended(&pdev->dev); -- cgit v1.2.3 From f5ef2372f608df4bb54b4fc7c9e43fb8bbef4795 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:13 +0300 Subject: usb: phy: msm: Remove HSUSB prefix from regulator names Prefix did not bring any useful information. Currently none of the MSM platforms define these regulators, so it is safe to rename them. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c2361bfd2002..bd9e286ccd66 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1418,9 +1418,9 @@ static int msm_otg_probe(struct platform_device *pdev) return motg->irq; } - regs[0].supply = "HSUSB_VDDCX"; - regs[1].supply = "HSUSB_3p3"; - regs[2].supply = "HSUSB_1p8"; + regs[0].supply = "vddcx"; + regs[1].supply = "v3p3"; + regs[2].supply = "v1p8"; ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); if (ret) -- cgit v1.2.3 From f60c114a3ae528dfc6750baad58cf822d0b282a2 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:14 +0300 Subject: usb: phy: msm: Properly check result from platform_get_irq() Function return negative code on error. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index bd9e286ccd66..7e968aa143ce 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1413,7 +1413,7 @@ static int msm_otg_probe(struct platform_device *pdev) dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); motg->irq = platform_get_irq(pdev, 0); - if (!motg->irq) { + if (motg->irq < 0) { dev_err(&pdev->dev, "platform_get_irq failed\n"); return motg->irq; } -- cgit v1.2.3 From 8364f9af237f47fa128bd4e4f7b45beef890c994 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:15 +0300 Subject: usb: phy: msm: Add device tree support and binding information Allows controller to be specified via device tree. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 113 +++++++++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 7e968aa143ce..1bf2d4ee29d2 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -30,9 +30,12 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -217,16 +220,16 @@ static struct usb_phy_io_ops msm_otg_io_ops = { static void ulpi_init(struct msm_otg *motg) { struct msm_otg_platform_data *pdata = motg->pdata; - int *seq = pdata->phy_init_seq; + int *seq = pdata->phy_init_seq, idx; + u32 addr = ULPI_EXT_VENDOR_SPECIFIC; - if (!seq) - return; + for (idx = 0; idx < pdata->phy_init_sz; idx++) { + if (seq[idx] == -1) + continue; - while (seq[0] >= 0) { dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", - seq[0], seq[1]); - ulpi_write(&motg->phy, seq[0], seq[1]); - seq += 2; + seq[idx], addr + idx); + ulpi_write(&motg->phy, seq[idx], addr + idx); } } @@ -1343,26 +1346,96 @@ static void msm_otg_debugfs_cleanup(void) debugfs_remove(msm_otg_dbg_root); } +static struct of_device_id msm_otg_dt_match[] = { + { + .compatible = "qcom,usb-otg-ci", + .data = (void *) CI_45NM_INTEGRATED_PHY + }, + { + .compatible = "qcom,usb-otg-snps", + .data = (void *) SNPS_28NM_INTEGRATED_PHY + }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_otg_dt_match); + +static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata; + const struct of_device_id *id; + struct device_node *node = pdev->dev.of_node; + struct property *prop; + int len, ret, words; + u32 val; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + motg->pdata = pdata; + + id = of_match_device(msm_otg_dt_match, &pdev->dev); + pdata->phy_type = (int) id->data; + + pdata->mode = of_usb_get_dr_mode(node); + if (pdata->mode == USB_DR_MODE_UNKNOWN) + pdata->mode = USB_DR_MODE_OTG; + + pdata->otg_control = OTG_PHY_CONTROL; + if (!of_property_read_u32(node, "qcom,otg-control", &val)) + if (val == OTG_PMIC_CONTROL) + pdata->otg_control = val; + + prop = of_find_property(node, "qcom,phy-init-sequence", &len); + if (!prop || !len) + return 0; + + words = len / sizeof(u32); + + if (words >= ULPI_EXT_VENDOR_SPECIFIC) { + dev_warn(&pdev->dev, "Too big PHY init sequence %d\n", words); + return 0; + } + + pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); + if (!pdata->phy_init_seq) { + dev_warn(&pdev->dev, "No space for PHY init sequence\n"); + return 0; + } + + ret = of_property_read_u32_array(node, "qcom,phy-init-sequence", + pdata->phy_init_seq, words); + if (!ret) + pdata->phy_init_sz = words; + + return 0; +} + static int msm_otg_probe(struct platform_device *pdev) { struct regulator_bulk_data regs[3]; int ret = 0; + struct device_node *np = pdev->dev.of_node; + struct msm_otg_platform_data *pdata; struct resource *res; struct msm_otg *motg; struct usb_phy *phy; - dev_info(&pdev->dev, "msm_otg probe\n"); - if (!dev_get_platdata(&pdev->dev)) { - dev_err(&pdev->dev, "No platform data given. Bailing out\n"); - return -ENODEV; - } - motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); if (!motg) { dev_err(&pdev->dev, "unable to allocate msm_otg\n"); return -ENOMEM; } + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + if (!np) + return -ENXIO; + ret = msm_otg_read_dt(pdev, motg); + if (ret) + return ret; + } + motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!motg->phy.otg) { @@ -1370,17 +1443,17 @@ static int msm_otg_probe(struct platform_device *pdev) return -ENOMEM; } - motg->pdata = dev_get_platdata(&pdev->dev); phy = &motg->phy; phy->dev = &pdev->dev; - motg->phy_reset_clk = devm_clk_get(&pdev->dev, "usb_phy_clk"); + motg->phy_reset_clk = devm_clk_get(&pdev->dev, + np ? "phy" : "usb_phy_clk"); if (IS_ERR(motg->phy_reset_clk)) { dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); return PTR_ERR(motg->phy_reset_clk); } - motg->clk = devm_clk_get(&pdev->dev, "usb_hs_clk"); + motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); if (IS_ERR(motg->clk)) { dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); return PTR_ERR(motg->clk); @@ -1392,7 +1465,7 @@ static int msm_otg_probe(struct platform_device *pdev) * operation and USB core cannot tolerate frequency changes on * CORE CLK. */ - motg->pclk = devm_clk_get(&pdev->dev, "usb_hs_pclk"); + motg->pclk = devm_clk_get(&pdev->dev, np ? "iface" : "usb_hs_pclk"); if (IS_ERR(motg->pclk)) { dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); return PTR_ERR(motg->pclk); @@ -1403,7 +1476,8 @@ static int msm_otg_probe(struct platform_device *pdev) * clock is introduced to remove the dependency on AXI * bus frequency. */ - motg->core_clk = devm_clk_get(&pdev->dev, "usb_hs_core_clk"); + motg->core_clk = devm_clk_get(&pdev->dev, + np ? "alt_core" : "usb_hs_core_clk"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); motg->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); @@ -1486,7 +1560,7 @@ static int msm_otg_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); if (motg->pdata->mode == USB_DR_MODE_OTG && - motg->pdata->otg_control == OTG_USER_CONTROL) { + motg->pdata->otg_control == OTG_USER_CONTROL) { ret = msm_otg_debugfs_init(motg); if (ret) dev_dbg(&pdev->dev, "Can not create mode change file\n"); @@ -1639,6 +1713,7 @@ static struct platform_driver msm_otg_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, .pm = &msm_otg_dev_pm_ops, + .of_match_table = msm_otg_dt_match, }, }; -- cgit v1.2.3 From a27345434134080273e0597e1d9721ff9e6ca67f Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:16 +0300 Subject: usb: phy: msm: Use reset framework for LINK and PHY resets Using reset framework eliminate need of platform specific callbacks and enable reset lines to be specified in DT files. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 1bf2d4ee29d2..a6abb1b3a7f0 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -235,12 +236,15 @@ static void ulpi_init(struct msm_otg *motg) static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) { - int ret = 0; + int ret; - if (!motg->pdata->link_clk_reset) - return ret; + if (motg->pdata->link_clk_reset) + ret = motg->pdata->link_clk_reset(motg->clk, assert); + else if (assert) + ret = reset_control_assert(motg->link_rst); + else + ret = reset_control_deassert(motg->link_rst); - ret = motg->pdata->link_clk_reset(motg->clk, assert); if (ret) dev_err(motg->phy.dev, "usb link clk reset %s failed\n", assert ? "assert" : "deassert"); @@ -250,12 +254,13 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) static int msm_otg_phy_clk_reset(struct msm_otg *motg) { - int ret = 0; + int ret; - if (!motg->pdata->phy_clk_reset) - return ret; + if (motg->pdata->phy_clk_reset) + ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); + else + ret = reset_control_reset(motg->phy_rst); - ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); if (ret) dev_err(motg->phy.dev, "usb phy clk reset failed\n"); @@ -1377,6 +1382,14 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) id = of_match_device(msm_otg_dt_match, &pdev->dev); pdata->phy_type = (int) id->data; + motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); + if (IS_ERR(motg->link_rst)) + return PTR_ERR(motg->link_rst); + + motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); + if (IS_ERR(motg->phy_rst)) + return PTR_ERR(motg->phy_rst); + pdata->mode = of_usb_get_dr_mode(node); if (pdata->mode == USB_DR_MODE_UNKNOWN) pdata->mode = USB_DR_MODE_OTG; -- cgit v1.2.3 From cfa3ff5dfe6a11ac8bc4a080416984ab00b0980c Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:17 +0300 Subject: usb: phy: msm: Add support for secondary PHY control Allow support to use 2nd HSPHY with USB2 Core. Some platforms may have configuration to allow USB controller work with any of the two HSPHYs present. By default driver configures USB core to use primary HSPHY. Add support to allow user select 2nd HSPHY using DT parameter. Signed-off-by: Ivan T. Ivanov Cc: Manu Gautam Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index a6abb1b3a7f0..8d57045ac938 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -314,6 +314,9 @@ static int msm_otg_phy_reset(struct msm_otg *motg) if (!retries) return -ETIMEDOUT; + if (motg->phy_number) + writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); + dev_info(motg->phy.dev, "phy_reset: success\n"); return 0; } @@ -368,6 +371,9 @@ static int msm_otg_reset(struct usb_phy *phy) ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); } + if (motg->phy_number) + writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); + return 0; } @@ -404,6 +410,7 @@ static int msm_otg_suspend(struct msm_otg *motg) struct usb_phy *phy = &motg->phy; struct usb_bus *bus = phy->otg->host; struct msm_otg_platform_data *pdata = motg->pdata; + void __iomem *addr; int cnt = 0; if (atomic_read(&motg->in_lpm)) @@ -463,9 +470,13 @@ static int msm_otg_suspend(struct msm_otg *motg) */ writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); + addr = USB_PHY_CTRL; + if (motg->phy_number) + addr = USB_PHY_CTRL2; + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && motg->pdata->otg_control == OTG_PMIC_CONTROL) - writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); + writel(readl(addr) | PHY_RETEN, addr); clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); @@ -495,6 +506,7 @@ static int msm_otg_resume(struct msm_otg *motg) { struct usb_phy *phy = &motg->phy; struct usb_bus *bus = phy->otg->host; + void __iomem *addr; int cnt = 0; unsigned temp; @@ -508,9 +520,14 @@ static int msm_otg_resume(struct msm_otg *motg) if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && motg->pdata->otg_control == OTG_PMIC_CONTROL) { + + addr = USB_PHY_CTRL; + if (motg->phy_number) + addr = USB_PHY_CTRL2; + msm_hsusb_ldo_set_mode(motg, 1); msm_hsusb_config_vddcx(motg, 1); - writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); + writel(readl(addr) & ~PHY_RETEN, addr); } temp = readl(USB_USBCMD); @@ -1399,6 +1416,9 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) if (val == OTG_PMIC_CONTROL) pdata->otg_control = val; + if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) + motg->phy_number = val; + prop = of_find_property(node, "qcom,phy-init-sequence", &len); if (!prop || !len) return 0; -- cgit v1.2.3 From d69c6f5df376ea40df5886468b155f515fddfbb2 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:18 +0300 Subject: usb: phy: msm: Correct USB PHY Reset sequence for newer platform On few legacy platforms, USB PHY is having dedicated reset clk. It is used to reset USB PHY after putting USB PHY into low power mode and for calibration of USB PHY. Putting USB PHY into low power mode is causing ulpi read/write timeout as expected. USB PHY reset clk is not available on newer platform. For 28nm PHY, reset USB PHY after resetting USB LINK. Also reset USB PHY using USB_PHY_PON bit with USB_OTG_HS_PHY_CTRL register after programming USB PHY Override registers as suggested with hardware programming guidelines. Signed-off-by: Ivan T. Ivanov Signed-off-by: Tim Bird Cc: Mayank Rana Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 140 ++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 8d57045ac938..bb339963f8bb 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -48,6 +48,7 @@ #define DRIVER_NAME "msm_otg" #define ULPI_IO_TIMEOUT_USEC (10 * 1000) +#define LINK_RESET_TIMEOUT_USEC (250 * 1000) #define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ #define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ @@ -267,77 +268,35 @@ static int msm_otg_phy_clk_reset(struct msm_otg *motg) return ret; } -static int msm_otg_phy_reset(struct msm_otg *motg) +static int msm_link_reset(struct msm_otg *motg) { u32 val; int ret; - int retries; ret = msm_otg_link_clk_reset(motg, 1); - if (ret) - return ret; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - ret = msm_otg_link_clk_reset(motg, 0); if (ret) return ret; - val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_ULPI, USB_PORTSC); - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, - ULPI_CLR(ULPI_FUNC_CTRL)); - if (!ret) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; + /* wait for 1ms delay as suggested in HPG. */ + usleep_range(1000, 1200); - /* This reset calibrates the phy, if the above write succeeded */ - ret = msm_otg_phy_clk_reset(motg); + ret = msm_otg_link_clk_reset(motg, 0); if (ret) return ret; - for (retries = 3; retries > 0; retries--) { - ret = ulpi_read(&motg->phy, ULPI_DEBUG); - if (ret != -ETIMEDOUT) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - if (motg->phy_number) writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); - dev_info(motg->phy.dev, "phy_reset: success\n"); + val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; + writel(val | PORTSC_PTS_ULPI, USB_PORTSC); + return 0; } -#define LINK_RESET_TIMEOUT_USEC (250 * 1000) static int msm_otg_reset(struct usb_phy *phy) { struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - struct msm_otg_platform_data *pdata = motg->pdata; int cnt = 0; - int ret; - u32 val = 0; - u32 ulpi_val = 0; - - ret = msm_otg_phy_reset(motg); - if (ret) { - dev_err(phy->dev, "phy_reset failed\n"); - return ret; - } - - ulpi_init(motg); writel(USBCMD_RESET, USB_USBCMD); while (cnt < LINK_RESET_TIMEOUT_USEC) { @@ -351,11 +310,86 @@ static int msm_otg_reset(struct usb_phy *phy) /* select ULPI phy */ writel(0x80000000, USB_PORTSC); + writel(0x0, USB_AHBBURST); + writel(0x08, USB_AHBMODE); + + if (motg->phy_number) + writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); + return 0; +} + +static void msm_phy_reset(struct msm_otg *motg) +{ + void __iomem *addr; + + if (motg->pdata->phy_type != SNPS_28NM_INTEGRATED_PHY) { + msm_otg_phy_clk_reset(motg); + return; + } + + addr = USB_PHY_CTRL; + if (motg->phy_number) + addr = USB_PHY_CTRL2; + + /* Assert USB PHY_POR */ + writel(readl(addr) | PHY_POR_ASSERT, addr); + + /* + * wait for minimum 10 microseconds as suggested in HPG. + * Use a slightly larger value since the exact value didn't + * work 100% of the time. + */ + udelay(12); + + /* Deassert USB PHY_POR */ + writel(readl(addr) & ~PHY_POR_ASSERT, addr); +} + +static int msm_usb_reset(struct usb_phy *phy) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + int ret; + + if (!IS_ERR(motg->core_clk)) + clk_prepare_enable(motg->core_clk); + + ret = msm_link_reset(motg); + if (ret) { + dev_err(phy->dev, "phy_reset failed\n"); + return ret; + } + + ret = msm_otg_reset(&motg->phy); + if (ret) { + dev_err(phy->dev, "link reset failed\n"); + return ret; + } msleep(100); - writel(0x0, USB_AHBBURST); - writel(0x00, USB_AHBMODE); + /* Reset USB PHY after performing USB Link RESET */ + msm_phy_reset(motg); + + if (!IS_ERR(motg->core_clk)) + clk_disable_unprepare(motg->core_clk); + + return 0; +} + +static int msm_phy_init(struct usb_phy *phy) +{ + struct msm_otg *motg = container_of(phy, struct msm_otg, phy); + struct msm_otg_platform_data *pdata = motg->pdata; + u32 val, ulpi_val = 0; + + /* Program USB PHY Override registers. */ + ulpi_init(motg); + + /* + * It is recommended in HPG to reset USB PHY after programming + * USB PHY Override registers. + */ + msm_phy_reset(motg); if (pdata->otg_control == OTG_PHY_CONTROL) { val = readl(USB_OTGSC); @@ -1574,7 +1608,7 @@ static int msm_otg_probe(struct platform_device *pdev) goto disable_ldo; } - phy->init = msm_otg_reset; + phy->init = msm_phy_init; phy->set_power = msm_otg_set_power; phy->io_ops = &msm_otg_io_ops; @@ -1583,6 +1617,8 @@ static int msm_otg_probe(struct platform_device *pdev) phy->otg->set_host = msm_otg_set_host; phy->otg->set_peripheral = msm_otg_set_peripheral; + msm_usb_reset(phy); + ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); -- cgit v1.2.3 From 9f27984b9e098ce0a35b210ec0315c76108494e4 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Mon, 28 Apr 2014 16:34:19 +0300 Subject: usb: phy: msm: Fix PTS definitions for MSM USB controller Fix the value used for Parallel Transceiver Select (PTS) for the MSM USB controller. This is a standard chipidea PORTSC definition, where a PHY_TYPE of 10b (<<30) is ULPI and 11b (<<30) is SERIAL. Fix the definitions and use them correctly in the driver code. Signed-off-by: Tim Bird Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index bb339963f8bb..db8d96377620 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -287,8 +287,9 @@ static int msm_link_reset(struct msm_otg *motg) if (motg->phy_number) writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); + /* put transceiver in serial mode as part of reset */ val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_ULPI, USB_PORTSC); + writel(val | PORTSC_PTS_SERIAL, USB_PORTSC); return 0; } @@ -308,8 +309,9 @@ static int msm_otg_reset(struct usb_phy *phy) if (cnt >= LINK_RESET_TIMEOUT_USEC) return -ETIMEDOUT; - /* select ULPI phy */ - writel(0x80000000, USB_PORTSC); + /* select ULPI phy and clear other status/control bits in PORTSC */ + writel(PORTSC_PTS_ULPI, USB_PORTSC); + writel(0x0, USB_AHBBURST); writel(0x08, USB_AHBMODE); -- cgit v1.2.3 From 30bf8667cef5655ddfaedf043f13d03606844213 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Mon, 28 Apr 2014 16:34:20 +0300 Subject: usb: phy: msm: Select secondary PHY via TCSR Select the secondary PHY using the TCSR register, if phy-num=1 in the DTS (or phy_number is set in the platform data). The SOC has 2 PHYs which can be used with the OTG port, and this code allows configuring the correct one. Note: This resolves the problem I was seeing where I couldn't get the USB driver working at all on a dragonboard, from cold boot. This patch depends on patch 5/14 from Ivan's msm USB patch set. It does not use DT for the register address, as there's no evidence that this address changes between SoC versions. Signed-off-by: Tim Bird Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index db8d96377620..9437bcf8c367 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1489,6 +1489,7 @@ static int msm_otg_probe(struct platform_device *pdev) struct resource *res; struct msm_otg *motg; struct usb_phy *phy; + void __iomem *phy_select; motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); if (!motg) { @@ -1553,6 +1554,19 @@ static int msm_otg_probe(struct platform_device *pdev) if (IS_ERR(motg->regs)) return PTR_ERR(motg->regs); + /* + * NOTE: The PHYs can be multiplexed between the chipidea controller + * and the dwc3 controller, using a single bit. It is important that + * the dwc3 driver does not set this bit in an incompatible way. + */ + if (motg->phy_number) { + phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); + if (IS_ERR(phy_select)) + return PTR_ERR(phy_select); + /* Enable second PHY with the OTG port */ + writel_relaxed(0x1, phy_select); + } + dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); motg->irq = platform_get_irq(pdev, 0); -- cgit v1.2.3 From 349907c262ad5e698c24565658ae489fb69fee53 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:21 +0300 Subject: usb: phy: msm: Handle disconnect events Put the transceiver in non-driving mode. Otherwise host may not detect soft-disconnection. Signed-off-by: Ivan T. Ivanov Cc: Pavankumar Kondeti Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 9437bcf8c367..366527ecbdd1 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -235,6 +235,23 @@ static void ulpi_init(struct msm_otg *motg) } } +static int msm_phy_notify_disconnect(struct usb_phy *phy, + enum usb_device_speed speed) +{ + int val; + + /* + * Put the transceiver in non-driving mode. Otherwise host + * may not detect soft-disconnection. + */ + val = ulpi_read(phy, ULPI_FUNC_CTRL); + val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + ulpi_write(phy, val, ULPI_FUNC_CTRL); + + return 0; +} + static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) { int ret; @@ -1626,6 +1643,7 @@ static int msm_otg_probe(struct platform_device *pdev) phy->init = msm_phy_init; phy->set_power = msm_otg_set_power; + phy->notify_disconnect = msm_phy_notify_disconnect; phy->io_ops = &msm_otg_io_ops; -- cgit v1.2.3 From 01799b622217ffebdc95e8e0aedbd4cff6a35a50 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:22 +0300 Subject: usb: phy: msm: Vote for corner of VDD CX instead of voltage of VDD CX New platform uses RBCPR hardware feature, with that voting for absolute voltage of VDD CX is not required. Hence vote for corner of VDD CX which uses nominal corner voltage on VDD CX. Signed-off-by: Ivan T. Ivanov Cc: Mayank Rana Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 366527ecbdd1..8e7956eb8a77 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -62,6 +62,13 @@ #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ +#define USB_PHY_SUSP_DIG_VOL 500000 /* uV */ + +enum vdd_levels { + VDD_LEVEL_NONE = 0, + VDD_LEVEL_MIN, + VDD_LEVEL_MAX, +}; static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) { @@ -69,8 +76,8 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) if (init) { ret = regulator_set_voltage(motg->vddcx, - USB_PHY_VDD_DIG_VOL_MIN, - USB_PHY_VDD_DIG_VOL_MAX); + motg->vdd_levels[VDD_LEVEL_MIN], + motg->vdd_levels[VDD_LEVEL_MAX]); if (ret) { dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); return ret; @@ -81,7 +88,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); } else { ret = regulator_set_voltage(motg->vddcx, 0, - USB_PHY_VDD_DIG_VOL_MAX); + motg->vdd_levels[VDD_LEVEL_MAX]); if (ret) dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); ret = regulator_disable(motg->vddcx); @@ -435,17 +442,16 @@ static int msm_phy_init(struct usb_phy *phy) #ifdef CONFIG_PM -#define USB_PHY_SUSP_DIG_VOL 500000 static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) { - int max_vol = USB_PHY_VDD_DIG_VOL_MAX; + int max_vol = motg->vdd_levels[VDD_LEVEL_MAX]; int min_vol; int ret; if (high) - min_vol = USB_PHY_VDD_DIG_VOL_MIN; + min_vol = motg->vdd_levels[VDD_LEVEL_MIN]; else - min_vol = USB_PHY_SUSP_DIG_VOL; + min_vol = motg->vdd_levels[VDD_LEVEL_NONE]; ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); if (ret) { @@ -1441,7 +1447,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) struct device_node *node = pdev->dev.of_node; struct property *prop; int len, ret, words; - u32 val; + u32 val, tmp[3]; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -1472,6 +1478,19 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) motg->phy_number = val; + motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL; + motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN; + motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX; + + if (of_get_property(node, "qcom,vdd-levels", &len) && + len == sizeof(tmp)) { + of_property_read_u32_array(node, "qcom,vdd-levels", + tmp, len / sizeof(*tmp)); + motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE]; + motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN]; + motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; + } + prop = of_find_property(node, "qcom,phy-init-sequence", &len); if (!prop || !len) return 0; -- cgit v1.2.3 From e695abb3c8b1b758843a1db2a73c98b3d14c173a Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 28 Apr 2014 16:34:23 +0300 Subject: usb: phy: msm: Use usb_add_phy_dev() to register device There could be more than one USB2.0 PHY's on the platform. This will allow all of them to be registered successfully. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 8e7956eb8a77..9dc79180b934 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1663,6 +1663,7 @@ static int msm_otg_probe(struct platform_device *pdev) phy->init = msm_phy_init; phy->set_power = msm_otg_set_power; phy->notify_disconnect = msm_phy_notify_disconnect; + phy->type = USB_PHY_TYPE_USB2; phy->io_ops = &msm_otg_io_ops; @@ -1672,7 +1673,7 @@ static int msm_otg_probe(struct platform_device *pdev) msm_usb_reset(phy); - ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); + ret = usb_add_phy_dev(&motg->phy); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); goto disable_ldo; -- cgit v1.2.3 From b3025e6ada454848b6ae2d3bcd925738384517df Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 30 Apr 2014 11:33:04 -0500 Subject: usb: phy: msm: cast to enum msm_usb_phy_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this solves the following build warning found when running compile tests. drivers/usb/phy/phy-msm-usb.c: In function ‘msm_otg_read_dt’: drivers/usb/phy/phy-msm-usb.c:1459:20: warning: cast from pointer \ to integer of different size [-Wpointer-to-int-cast] pdata->phy_type = (int) id->data; ^ Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 9dc79180b934..591b406fd7f7 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1456,7 +1456,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) motg->pdata = pdata; id = of_match_device(msm_otg_dt_match, &pdev->dev); - pdata->phy_type = (int) id->data; + pdata->phy_type = (enum msm_usb_phy_type) id->data; motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); if (IS_ERR(motg->link_rst)) -- cgit v1.2.3 From 245974908c2ee8cd907856e6964f59fd8807e1e1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 30 Apr 2014 11:35:22 -0500 Subject: usb: phy: msm: switch over to writel() Remove that single instance of writel_relaxed() call which is only available on ARM architecture. This will let us build test this driver on all different architectures. Reviewed-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 591b406fd7f7..c522c4ff8084 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1600,7 +1600,7 @@ static int msm_otg_probe(struct platform_device *pdev) if (IS_ERR(phy_select)) return PTR_ERR(phy_select); /* Enable second PHY with the OTG port */ - writel_relaxed(0x1, phy_select); + writel(0x1, phy_select); } dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); -- cgit v1.2.3 From 1f7fc40876934d52278bb1ee0544191a4b4657f1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 30 Apr 2014 11:36:03 -0500 Subject: usb: phy: msm: enable build on other architectures By adding COMPILE_TEST to the list of dependencies we can build test this driver on all other architectures which is very valuable for maintainers applying patches and to find silly mistakes during development. Reviewed-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 0c668a3f5c37..fbbced80b68d 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -172,7 +172,7 @@ config USB_ISP1301 config USB_MSM_OTG tristate "Qualcomm on-chip USB OTG controller support" - depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM) + depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM || COMPILE_TEST) select USB_PHY help Enable this to support the USB OTG transceiver on Qualcomm chips. It -- cgit v1.2.3 From 6027f3173e797bf27fc5053aa74c9f40f85538d8 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 29 Apr 2014 13:26:28 +0800 Subject: usb: gadget: set gadget state as configured Set gadget device state as configurated after set configuration has finished. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 1 + drivers/usb/gadget/inode.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index fab906429b80..8060de6562cd 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -634,6 +634,7 @@ static int set_config(struct usb_composite_dev *cdev, if (!c) goto done; + usb_gadget_set_state(gadget, USB_STATE_CONFIGURED); cdev->config = c; /* Initialize all interfaces by setting them to altsetting zero. */ diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index b5be6f0308c2..09e21517377c 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1494,6 +1494,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) */ if (value == 0) { INFO (dev, "configuration #%d\n", dev->current_config); + usb_gadget_set_state(gadget, USB_STATE_CONFIGURED); if (dev->usermode_setup) { dev->setup_can_stall = 0; goto delegate; -- cgit v1.2.3 From b5fb8d0a40eb52039e8df6fadafa95ecdcdc3026 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 29 Apr 2014 13:26:29 +0800 Subject: usb: udc-core: set gadget state as not attached after unloading module Set gadget state as "not attached" after unloading gadget module, or its state will be unchanged after we unload gadget module. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 27768a7d986a..b0d98172bc07 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -428,6 +428,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) list_for_each_entry(udc, &udc_list, list) if (udc->driver == driver) { usb_gadget_remove_driver(udc); + usb_gadget_set_state(udc->gadget, + USB_STATE_NOTATTACHED); ret = 0; break; } -- cgit v1.2.3 From 411dd19c682dd9c1c29a722bde2d172ee72707de Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 2 May 2014 13:41:00 +0530 Subject: usb: musb: Kconfig: Select the DMA driver if DMA mode of MUSB is enabled AM335x MUSB supports both PIO and DMA mode. When DMA mode is selected users need to explicitly enable the DMA driver. To avoid the extra configuration select the DMA driver if DMA mode is set for AM335x MUSB. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 8b789792f6fa..6b2a4b8b82ca 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -141,6 +141,7 @@ config USB_TI_CPPI_DMA config USB_TI_CPPI41_DMA bool 'TI CPPI 4.1 (AM335x)' depends on ARCH_OMAP + select TI_CPPI41 config USB_TUSB_OMAP_DMA bool 'TUSB 6010' -- cgit v1.2.3 From 22a825079a75560e01fa3307229713ff29cc7aa2 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 4 May 2014 10:57:30 +0200 Subject: usb: musb: tusb: remove dead code musb_in_tusb() is always set to 0, because CONFIG_USB_TUSB6010 is never set (it should have been CONFIG_USB_MUSB_TUSB6010). But musb_in_tusb() is unused anyway, so remove a few lines of dead code. Signed-off-by: Paul Bolle Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h index 35c933a5d991..1864e24ac965 100644 --- a/drivers/usb/musb/tusb6010.h +++ b/drivers/usb/musb/tusb6010.h @@ -14,12 +14,6 @@ extern u8 tusb_get_revision(struct musb *musb); -#ifdef CONFIG_USB_TUSB6010 -#define musb_in_tusb() 1 -#else -#define musb_in_tusb() 0 -#endif - #ifdef CONFIG_USB_TUSB_OMAP_DMA #define tusb_dma_omap() 1 #else -- cgit v1.2.3 From 4d9f872ced245ef0c712f0f04adf446d37813c57 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 5 May 2014 07:39:34 +0800 Subject: usb: gadget: configfs: fix typo %s/atleast/at least Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index dcead559a61e..b5e965ec8b61 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -793,7 +793,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, ret = -EINVAL; if (list_empty(&gi->cdev.configs)) { - pr_err("Need atleast one configuration in %s.\n", + pr_err("Need at least one configuration in %s.\n", gi->composite.name); goto err_comp_cleanup; } @@ -804,7 +804,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, cfg = container_of(c, struct config_usb_cfg, c); if (list_empty(&cfg->func_list)) { - pr_err("Config %s/%d of %s needs atleast one function.\n", + pr_err("Config %s/%d of %s needs at least one function.\n", c->label, c->bConfigurationValue, gi->composite.name); goto err_comp_cleanup; -- cgit v1.2.3 From bcdbc084ebab447f6eb1add7b953f125b0c8174b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 6 May 2014 17:16:07 +0200 Subject: usb: gadget: atmel_usba: always test udc->driver Found using smatch: drivers/usb/gadget/atmel_usba_udc.c:1689 usba_udc_irq() error: we previously assumed 'udc->driver' could be null (see line 1636) Always test udc->driver before using its members. Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni Signed-off-by: Felipe Balbi --- drivers/usb/gadget/atmel_usba_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 9f65324f9ae0..76023ce449a3 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1686,7 +1686,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) reset_all_endpoints(udc); if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver->disconnect) { + && udc->driver && udc->driver->disconnect) { udc->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock(&udc->lock); udc->driver->disconnect(&udc->gadget); -- cgit v1.2.3 From d48d41f18a762c765df87d14b554485e52c393cd Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:41:16 +0900 Subject: usb: gadget: f_uac2: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index bc23040c7790..c024d27fcce2 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -974,8 +974,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); if (!prm->rbuf) { prm->max_psize = 0; - dev_err(&uac2->pdev.dev, - "%s:%d Error!\n", __func__, __LINE__); goto err; } @@ -984,8 +982,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); if (!prm->rbuf) { prm->max_psize = 0; - dev_err(&uac2->pdev.dev, - "%s:%d Error!\n", __func__, __LINE__); goto err; } @@ -1298,10 +1294,8 @@ static int audio_bind_config(struct usb_configuration *cfg) int res; agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); - if (agdev_g == NULL) { - printk(KERN_ERR "Unable to allocate audio gadget\n"); + if (agdev_g == NULL) return -ENOMEM; - } res = usb_string_ids_tab(cfg->cdev, strings_fn); if (res) -- cgit v1.2.3 From 0351c329f72a41ca712310587d3f7ca82fd8015f Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:42:21 +0900 Subject: usb: gadget: fotg210-udc: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fotg210-udc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fotg210-udc.c b/drivers/usb/gadget/fotg210-udc.c index 2d0305280e8c..e143d69f6017 100644 --- a/drivers/usb/gadget/fotg210-udc.c +++ b/drivers/usb/gadget/fotg210-udc.c @@ -1112,17 +1112,13 @@ static int fotg210_udc_probe(struct platform_device *pdev) /* initialize udc */ fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); - if (fotg210 == NULL) { - pr_err("kzalloc error\n"); + if (fotg210 == NULL) goto err_alloc; - } for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); - if (_ep[i] == NULL) { - pr_err("_ep kzalloc error\n"); + if (_ep[i] == NULL) goto err_alloc; - } fotg210->ep[i] = _ep[i]; } -- cgit v1.2.3 From 8a67ab7d1d2d267ffad3e22b5e4e4d46230e925a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:43:57 +0900 Subject: usb: gadget: fsl_udc_core: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 15960af0f67e..68843f081377 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2252,10 +2252,8 @@ static int __init struct_udc_setup(struct fsl_udc *udc, udc->phy_mode = pdata->phy_mode; udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); - if (!udc->eps) { - ERR("malloc fsl_ep failed\n"); + if (!udc->eps) return -1; - } /* initialized QHs, take care of alignment */ size = udc->max_ep * sizeof(struct ep_queue_head); @@ -2338,10 +2336,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev) u32 dccparams; udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); - if (udc_controller == NULL) { - ERR("malloc udc failed\n"); + if (udc_controller == NULL) return -ENOMEM; - } pdata = dev_get_platdata(&pdev->dev); udc_controller->pdata = pdata; -- cgit v1.2.3 From 8a24bb403974760b420777a76637b2e9f87ffa3f Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:44:59 +0900 Subject: usb: gadget: fusb300_udc: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fusb300_udc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 6423f1840ed9..3deb4e938071 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1400,17 +1400,13 @@ static int __init fusb300_probe(struct platform_device *pdev) /* initialize udc */ fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); - if (fusb300 == NULL) { - pr_err("kzalloc error\n"); + if (fusb300 == NULL) goto clean_up; - } for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); - if (_ep[i] == NULL) { - pr_err("_ep kzalloc error\n"); + if (_ep[i] == NULL) goto clean_up; - } fusb300->ep[i] = _ep[i]; } -- cgit v1.2.3 From c797f7fd5c64c8947900be03f0cd229879a708e6 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:46:23 +0900 Subject: usb: gadget: m66592-udc: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/m66592-udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 8cae01d88597..0d17174b86f8 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1594,7 +1594,6 @@ static int __init m66592_probe(struct platform_device *pdev) m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); if (m66592 == NULL) { ret = -ENOMEM; - pr_err("kzalloc error\n"); goto clean_up; } -- cgit v1.2.3 From f3772c2b4974241a0ee9d2a35b626fff7c2b7b8d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:48:13 +0900 Subject: usb: gadget: mv_u3d_core: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_u3d_core.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index d2ca59e7b477..16248711c152 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -297,10 +297,8 @@ static struct mv_u3d_trb *mv_u3d_build_trb_one(struct mv_u3d_req *req, u3d = req->ep->u3d; trb = kzalloc(sizeof(*trb), GFP_ATOMIC); - if (!trb) { - dev_err(u3d->dev, "%s, trb alloc fail\n", __func__); + if (!trb) return NULL; - } /* * Be careful that no _GFP_HIGHMEM is set, @@ -446,17 +444,12 @@ static int mv_u3d_req_to_trb(struct mv_u3d_req *req) trb_num++; trb = kcalloc(trb_num, sizeof(*trb), GFP_ATOMIC); - if (!trb) { - dev_err(u3d->dev, - "%s, trb alloc fail\n", __func__); + if (!trb) return -ENOMEM; - } trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); if (!trb_hw) { kfree(trb); - dev_err(u3d->dev, - "%s, trb_hw alloc fail\n", __func__); return -ENOMEM; } @@ -1811,7 +1804,6 @@ static int mv_u3d_probe(struct platform_device *dev) u3d = kzalloc(sizeof(*u3d), GFP_KERNEL); if (!u3d) { - dev_err(&dev->dev, "failed to allocate memory for u3d\n"); retval = -ENOMEM; goto err_alloc_private; } @@ -1905,7 +1897,6 @@ static int mv_u3d_probe(struct platform_device *dev) size = u3d->max_eps * sizeof(struct mv_u3d_ep) * 2; u3d->eps = kzalloc(size, GFP_KERNEL); if (!u3d->eps) { - dev_err(&dev->dev, "allocate ep memory failed\n"); retval = -ENOMEM; goto err_alloc_eps; } @@ -1913,7 +1904,6 @@ static int mv_u3d_probe(struct platform_device *dev) /* initialize ep0 status request structure */ u3d->status_req = kzalloc(sizeof(struct mv_u3d_req) + 8, GFP_KERNEL); if (!u3d->status_req) { - dev_err(&dev->dev, "allocate status_req memory failed\n"); retval = -ENOMEM; goto err_alloc_status_req; } -- cgit v1.2.3 From e5f06f909fd3a6901814da79e1ebb8a04887c889 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:49:10 +0900 Subject: usb: gadget: r8a66597-udc: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/r8a66597-udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index aff0a6718bc6..b698a490cc7d 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1904,7 +1904,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); if (r8a66597 == NULL) { ret = -ENOMEM; - dev_err(&pdev->dev, "kzalloc error\n"); goto clean_up; } -- cgit v1.2.3 From f06d186dbd294e9d436096747f34918b70b4f8f1 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 15:50:27 +0900 Subject: usb: gadget: tcm_usb_gadget: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/gadget/tcm_usb_gadget.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index f058c0368d61..49481e0a3382 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1383,10 +1383,8 @@ static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg) struct usbg_nacl *nacl; nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL); - if (!nacl) { - printk(KERN_ERR "Unable to allocate struct usbg_nacl\n"); + if (!nacl) return NULL; - } return &nacl->se_node_acl; } @@ -1561,10 +1559,8 @@ static struct se_portal_group *usbg_make_tpg( } tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); - if (!tpg) { - printk(KERN_ERR "Unable to allocate struct usbg_tpg"); + if (!tpg) return ERR_PTR(-ENOMEM); - } mutex_init(&tpg->tpg_mutex); atomic_set(&tpg->tpg_port_count, 0); tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); @@ -1613,10 +1609,8 @@ static struct se_wwn *usbg_make_tport( return ERR_PTR(-EINVAL); tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL); - if (!(tport)) { - printk(KERN_ERR "Unable to allocate struct usbg_tport"); + if (!(tport)) return ERR_PTR(-ENOMEM); - } tport->tport_wwpn = wwpn; snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name); return &tport->tport_wwn; @@ -1727,10 +1721,8 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name) ret = -ENOMEM; tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); - if (!tv_nexus) { - pr_err("Unable to allocate struct tcm_vhost_nexus\n"); + if (!tv_nexus) goto err_unlock; - } tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); if (IS_ERR(tv_nexus->tvn_se_sess)) goto err_free; -- cgit v1.2.3 From 966036fde60e6d96708815e0d495692ac352acf9 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Thu, 8 May 2014 00:26:52 +0400 Subject: usb: gadget: gr_udc: unconditionally use GFP_ATOMIC in gr_queue_ext() As far as gr_queue() is called with spinlock held, we have to pass GFP_ATOMIC regardless of gfp argument. Found by Linux Driver Verification project (linuxtesting.org). Acked-by: Andreas Larsson Signed-off-by: Alexey Khoroshilov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 4966971d6978..99a37ed03e27 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -1684,7 +1684,7 @@ static int gr_queue_ext(struct usb_ep *_ep, struct usb_request *_req, if (ep->is_in) gr_dbgprint_request("EXTERN", ep, req); - ret = gr_queue(ep, req, gfp_flags); + ret = gr_queue(ep, req, GFP_ATOMIC); spin_unlock(&ep->dev->lock); -- cgit v1.2.3 From 64890edb8536618ee856fbca699fe930fcef1573 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 8 May 2014 15:52:14 +0200 Subject: usb: gadget: s3c2410_udc: don't use pr_debug return value pr_debug() may be defined as "do { } while (0)" in some configurations, which means one cannot rely on the return value to be available. In the dprintk function in this driver, we can work around the resulting build error trivially by returning the length that this function already knows and ignoring the return value of pr_debug. Signed-off-by: Arnd Bergmann Cc: Ben Dooks Cc: Kukjin Kim Cc: linux-samsung-soc@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index dd9678f85c58..7987aa049fab 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -117,7 +117,8 @@ static int dprintk(int level, const char *fmt, ...) sizeof(printk_buf)-len, fmt, args); va_end(args); - return pr_debug("%s", printk_buf); + pr_debug("%s", printk_buf); + return len; } #else static int dprintk(int level, const char *fmt, ...) -- cgit v1.2.3 From 70c1ff4b3c865a36f00aa2498eab3eadd818e4ab Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 8 May 2014 15:52:15 +0200 Subject: usb: musb: tusb-dma can't be built-in if tusb is not A configuration with CONFIG_USB_MUSB_HDRC=y, CONFIG_USB_TUSB_OMAP_DMA=y and CONFIG_USB_MUSB_TUSB6010=m causes a link failure because of the dependency on the tusb_get_revision symbol: (.text+0x154ce8): undefined reference to `tusb_get_revision' This patch ensures that either MUSB_HDRC and MUSB_TUSB6010 are both modules or both built-in, which are the valid configurations. Signed-off-by: Arnd Bergmann Cc: linux-omap@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 6b2a4b8b82ca..e0fba7591dea 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -145,7 +145,7 @@ config USB_TI_CPPI41_DMA config USB_TUSB_OMAP_DMA bool 'TUSB 6010' - depends on USB_MUSB_TUSB6010 + depends on USB_MUSB_TUSB6010 = USB_MUSB_HDRC # both built-in or both modules depends on ARCH_OMAP help Enable DMA transfers on TUSB 6010 when OMAP DMA is available. -- cgit v1.2.3 From a8d191c8bb2f11a8f381e7cb98f978b7288c1401 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 8 May 2014 15:52:16 +0200 Subject: usb: musb: omap2plus bus glue needs USB host support The musb/omap2430.c bus glue driver calls usb_hcd_poll_rh_status, which is only available if CONFIG_USB is also set, i.e. we are building USB host mode and not just endpoint mode. Signed-off-by: Arnd Bergmann Cc: linux-omap@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index e0fba7591dea..06cc5d6ea681 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -76,7 +76,7 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" - depends on ARCH_OMAP2PLUS + depends on ARCH_OMAP2PLUS && USB select GENERIC_PHY config USB_MUSB_AM35X -- cgit v1.2.3 From c5ab571f81905568a59dce306df0181f33e00932 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 13 May 2014 21:46:52 +0200 Subject: usb: phy: msm: reset controller is mandatory now Commit a27345434134 "usb: phy: msm: Use reset framework for LINK and PHY resets" introduced a mandatory call to reset_control_get into the msm usb phy driver, which means we have to add a Kconfig dependency on the API to avoid this build error: phy/phy-msm-usb.c: In function 'msm_otg_read_dt': phy/phy-msm-usb.c:1461:2: error: implicit declaration of function 'devm_reset_control_get' [-Werror=implicit-function-declaration] motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); ^ Since the usb-ehci-msm driver currently selects the OTG driver, we could still get a broken dependency here. To solve that, this patch also removes the 'select', which turns out to be unnecessary. Reviewed-by: Ivan T. Ivanov Signed-off-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- drivers/usb/host/Kconfig | 1 - drivers/usb/phy/Kconfig | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3d9e54062d62..7a39ae86d5ce 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -170,7 +170,6 @@ config USB_EHCI_MSM tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" depends on ARCH_MSM select USB_EHCI_ROOT_HUB_TT - select USB_MSM_OTG ---help--- Enables support for the USB Host controller present on the Qualcomm chipsets. Root Hub has inbuilt TT. diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index fbbced80b68d..ec531a48d240 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -173,6 +173,7 @@ config USB_ISP1301 config USB_MSM_OTG tristate "Qualcomm on-chip USB OTG controller support" depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM || COMPILE_TEST) + depends on RESET_CONTROLLER select USB_PHY help Enable this to support the USB OTG transceiver on Qualcomm chips. It -- cgit v1.2.3 From 10f0577aa5cb03c81cf6ddc2ff7de1b6d6152d0b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 14 May 2014 16:54:47 +0300 Subject: usb: phy: msm: change devm_ioremap() to devm_ioremap_resource() There are several issues here: 1) platform_get_resource() can return NULL and that wasn't handled. 2) We should request the memory before we remap it, and devm_ioremap_resource() does that. 3) devm_ioremap() returns a NULL but we were checking for IS_ERR(). Fixes: 6b99c68ec1f9 ('usb: phy: msm: Migrate to Managed Device Resource allocation') Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c522c4ff8084..4f88174aede5 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1586,7 +1586,7 @@ static int msm_otg_probe(struct platform_device *pdev) np ? "alt_core" : "usb_hs_core_clk"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - motg->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + motg->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(motg->regs)) return PTR_ERR(motg->regs); -- cgit v1.2.3 From 74d484669784836c83f23f80ee21a44e9fbf4d59 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:21 +0200 Subject: usb: gadget: FunctionFS: share VLA macros with all usb gadget files Variable Length Array macros allow portable (compilable with both gcc and clang) way of allocating a number of structures using a single memory chunk. They can be useful for files other than f_fs.c, so move them to a header file. Signed-off-by: Andrzej Pietrasiewicz Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 27 +-------------------------- drivers/usb/gadget/u_f.h | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index a01b3bd8fa00..38641ea820a8 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -33,36 +33,11 @@ #include #include "u_fs.h" +#include "u_f.h" #include "configfs.h" #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ -/* Variable Length Array Macros **********************************************/ -#define vla_group(groupname) size_t groupname##__next = 0 -#define vla_group_size(groupname) groupname##__next - -#define vla_item(groupname, type, name, n) \ - size_t groupname##_##name##__offset = ({ \ - size_t align_mask = __alignof__(type) - 1; \ - size_t offset = (groupname##__next + align_mask) & ~align_mask;\ - size_t size = (n) * sizeof(type); \ - groupname##__next = offset + size; \ - offset; \ - }) - -#define vla_item_with_sz(groupname, type, name, n) \ - size_t groupname##_##name##__sz = (n) * sizeof(type); \ - size_t groupname##_##name##__offset = ({ \ - size_t align_mask = __alignof__(type) - 1; \ - size_t offset = (groupname##__next + align_mask) & ~align_mask;\ - size_t size = groupname##_##name##__sz; \ - groupname##__next = offset + size; \ - offset; \ - }) - -#define vla_ptr(ptr, groupname, name) \ - ((void *) ((char *)ptr + groupname##_##name##__offset)) - /* Reference counter handling */ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 71034c061fca..1d5f0eb68552 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -16,6 +16,32 @@ #ifndef __U_F_H__ #define __U_F_H__ +/* Variable Length Array Macros **********************************************/ +#define vla_group(groupname) size_t groupname##__next = 0 +#define vla_group_size(groupname) groupname##__next + +#define vla_item(groupname, type, name, n) \ + size_t groupname##_##name##__offset = ({ \ + size_t align_mask = __alignof__(type) - 1; \ + size_t offset = (groupname##__next + align_mask) & ~align_mask;\ + size_t size = (n) * sizeof(type); \ + groupname##__next = offset + size; \ + offset; \ + }) + +#define vla_item_with_sz(groupname, type, name, n) \ + size_t groupname##_##name##__sz = (n) * sizeof(type); \ + size_t groupname##_##name##__offset = ({ \ + size_t align_mask = __alignof__(type) - 1; \ + size_t offset = (groupname##__next + align_mask) & ~align_mask;\ + size_t size = groupname##_##name##__sz; \ + groupname##__next = offset + size; \ + offset; \ + }) + +#define vla_ptr(ptr, groupname, name) \ + ((void *) ((char *)ptr + groupname##_##name##__offset)) + struct usb_ep; struct usb_request; -- cgit v1.2.3 From 19824d5eeecedfb46639961da1b7a21ba3179930 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:22 +0200 Subject: usb: gadget: OS String support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a custom (non-USB IF) extension to the USB standard: http://msdn.microsoft.com/library/windows/hardware/gg463182 They grant permission to use the specification - there is "Microsoft OS Descriptor Specification License Agreement" under the link mentioned above, and its Section 2 "Grant of License", letter (b) reads: "Patent license. Microsoft hereby grants to You a nonexclusive, royalty-free, nontransferable, worldwide license under Microsoft’s patents embodied solely within the Specification and that are owned or licensable by Microsoft to make, use, import, offer to sell, sell and distribute directly or indirectly to Your Licensees Your Implementation. You may sublicense this patent license to Your Licensees under the same terms and conditions." The said extension is maintained by Microsoft for Microsoft. Yet it is fairly common for various devices to use it, and a popular proprietary operating system expects devices to provide "OS descriptors", so Linux-based USB gadgets whishing to be able to talk to a variety of operating systems should be able to provide the "OS descriptors". This patch adds optional support for gadgets whishing to expose the so called "OS String" under index 0xEE of language 0. The contents of the string is generated based on the qw_sign array and b_vendor_code. Interested gadgets need to set the cdev->use_os_string flag, fill cdev->qw_sign with appropriate values and fill cdev->b_vendor_code with a value of their choice. This patch does not however implement responding to any vendor-specific USB requests. Signed-off-by: Andrzej Pietrasiewicz Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 8060de6562cd..2f87b1697bf5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -21,6 +21,22 @@ #include #include +/** + * struct usb_os_string - represents OS String to be reported by a gadget + * @bLength: total length of the entire descritor, always 0x12 + * @bDescriptorType: USB_DT_STRING + * @qwSignature: the OS String proper + * @bMS_VendorCode: code used by the host for subsequent requests + * @bPad: not used, must be zero + */ +struct usb_os_string { + __u8 bLength; + __u8 bDescriptorType; + __u8 qwSignature[OS_STRING_QW_SIGN_LEN]; + __u8 bMS_VendorCode; + __u8 bPad; +} __packed; + /* * The code in this file is utility code, used to build a gadget driver * from one or more "function" drivers, one or more "configuration" @@ -961,6 +977,19 @@ static int get_string(struct usb_composite_dev *cdev, return s->bLength; } + if (cdev->use_os_string && language == 0 && id == OS_STRING_IDX) { + struct usb_os_string *b = buf; + b->bLength = sizeof(*b); + b->bDescriptorType = USB_DT_STRING; + compiletime_assert( + sizeof(b->qwSignature) == sizeof(cdev->qw_sign), + "qwSignature size must be equal to qw_sign"); + memcpy(&b->qwSignature, cdev->qw_sign, sizeof(b->qwSignature)); + b->bMS_VendorCode = cdev->b_vendor_code; + b->bPad = 0; + return sizeof(*b); + } + list_for_each_entry(uc, &cdev->gstrings, list) { struct usb_gadget_strings **sp; -- cgit v1.2.3 From 37a3a533429ef9b3cc9f15a656c19623f0e88df7 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:23 +0200 Subject: usb: gadget: OS Feature Descriptors support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a custom (non-USB IF) extension to the USB standard: http://msdn.microsoft.com/library/windows/hardware/gg463182 They grant permission to use the specification - there is "Microsoft OS Descriptor Specification License Agreement" under the link mentioned above, and its Section 2 "Grant of License", letter (b) reads: "Patent license. Microsoft hereby grants to You a nonexclusive, royalty-free, nontransferable, worldwide license under Microsoft’s patents embodied solely within the Specification and that are owned or licensable by Microsoft to make, use, import, offer to sell, sell and distribute directly or indirectly to Your Licensees Your Implementation. You may sublicense this patent license to Your Licensees under the same terms and conditions." The said extension is maintained by Microsoft for Microsoft. Yet it is fairly common for various devices to use it, and a popular proprietary operating system expects devices to provide "OS descriptors", so Linux-based USB gadgets whishing to be able to talk to a variety of operating systems should be able to provide the "OS descriptors". This patch adds optional support for gadgets whishing to expose the so called "OS Feature Descriptors", that is "Extended Compatibility ID" and "Extended Properties". Hosts which do request "OS descriptors" from gadgets do so during the enumeration phase and before the configuration is set with SET_CONFIGURATION. What is more, those hosts never ask for configurations at indices other than 0. Therefore, gadgets whishing to provide "OS descriptors" must designate one configuration to be used with this kind of hosts - this is what os_desc_config is added for in struct usb_composite_dev. There is an additional advantage to it: if a gadget provides "OS descriptors" and designates one configuration to be used with such non-USB-compliant hosts it can invoke "usb_add_config" in any order because the designated configuration will be reported to be at index 0 anyway. This patch also adds handling vendor-specific requests addressed at device or interface and related to handling "OS descriptors". Signed-off-by: Andrzej Pietrasiewicz Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 288 ++++++++++++++++++++++++++++++++++++++++- drivers/usb/gadget/u_os_desc.h | 90 +++++++++++++ 2 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/gadget/u_os_desc.h (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2f87b1697bf5..042c66b71df8 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -21,6 +21,8 @@ #include #include +#include "u_os_desc.h" + /** * struct usb_os_string - represents OS String to be reported by a gadget * @bLength: total length of the entire descritor, always 0x12 @@ -438,6 +440,7 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value) { struct usb_gadget *gadget = cdev->gadget; struct usb_configuration *c; + struct list_head *pos; u8 type = w_value >> 8; enum usb_device_speed speed = USB_SPEED_UNKNOWN; @@ -456,7 +459,20 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value) /* This is a lookup by config *INDEX* */ w_value &= 0xff; - list_for_each_entry(c, &cdev->configs, list) { + + pos = &cdev->configs; + c = cdev->os_desc_config; + if (c) + goto check_config; + + while ((pos = pos->next) != &cdev->configs) { + c = list_entry(pos, typeof(*c), list); + + /* skip OS Descriptors config which is handled separately */ + if (c == cdev->os_desc_config) + continue; + +check_config: /* ignore configs that won't work at this speed */ switch (speed) { case USB_SPEED_SUPER: @@ -1236,6 +1252,158 @@ static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) req->status, req->actual, req->length); } +static int count_ext_compat(struct usb_configuration *c) +{ + int i, res; + + res = 0; + for (i = 0; i < c->next_interface_id; ++i) { + struct usb_function *f; + int j; + + f = c->interface[i]; + for (j = 0; j < f->os_desc_n; ++j) { + struct usb_os_desc *d; + + if (i != f->os_desc_table[j].if_id) + continue; + d = f->os_desc_table[j].os_desc; + if (d && d->ext_compat_id) + ++res; + } + } + BUG_ON(res > 255); + return res; +} + +static void fill_ext_compat(struct usb_configuration *c, u8 *buf) +{ + int i, count; + + count = 16; + for (i = 0; i < c->next_interface_id; ++i) { + struct usb_function *f; + int j; + + f = c->interface[i]; + for (j = 0; j < f->os_desc_n; ++j) { + struct usb_os_desc *d; + + if (i != f->os_desc_table[j].if_id) + continue; + d = f->os_desc_table[j].os_desc; + if (d && d->ext_compat_id) { + *buf++ = i; + *buf++ = 0x01; + memcpy(buf, d->ext_compat_id, 16); + buf += 22; + } else { + ++buf; + *buf = 0x01; + buf += 23; + } + count += 24; + if (count >= 4096) + return; + } + } +} + +static int count_ext_prop(struct usb_configuration *c, int interface) +{ + struct usb_function *f; + int j, res; + + res = 0; + + f = c->interface[interface]; + for (j = 0; j < f->os_desc_n; ++j) { + struct usb_os_desc *d; + + if (interface != f->os_desc_table[j].if_id) + continue; + d = f->os_desc_table[j].os_desc; + if (d && d->ext_compat_id) + return d->ext_prop_count; + } + return res; +} + +static int len_ext_prop(struct usb_configuration *c, int interface) +{ + struct usb_function *f; + struct usb_os_desc *d; + int j, res; + + res = 10; /* header length */ + f = c->interface[interface]; + for (j = 0; j < f->os_desc_n; ++j) { + if (interface != f->os_desc_table[j].if_id) + continue; + d = f->os_desc_table[j].os_desc; + if (d) + return min(res + d->ext_prop_len, 4096); + } + return res; +} + +static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf) +{ + struct usb_function *f; + struct usb_os_desc *d; + struct usb_os_desc_ext_prop *ext_prop; + int j, count, n, ret; + u8 *start = buf; + + f = c->interface[interface]; + for (j = 0; j < f->os_desc_n; ++j) { + if (interface != f->os_desc_table[j].if_id) + continue; + d = f->os_desc_table[j].os_desc; + if (d) + list_for_each_entry(ext_prop, &d->ext_prop, entry) { + /* 4kB minus header length */ + n = buf - start; + if (n >= 4086) + return 0; + + count = ext_prop->data_len + + ext_prop->name_len + 14; + if (count > 4086 - n) + return -EINVAL; + usb_ext_prop_put_size(buf, count); + usb_ext_prop_put_type(buf, ext_prop->type); + ret = usb_ext_prop_put_name(buf, ext_prop->name, + ext_prop->name_len); + if (ret < 0) + return ret; + switch (ext_prop->type) { + case USB_EXT_PROP_UNICODE: + case USB_EXT_PROP_UNICODE_ENV: + case USB_EXT_PROP_UNICODE_LINK: + usb_ext_prop_put_unicode(buf, ret, + ext_prop->data, + ext_prop->data_len); + break; + case USB_EXT_PROP_BINARY: + usb_ext_prop_put_binary(buf, ret, + ext_prop->data, + ext_prop->data_len); + break; + case USB_EXT_PROP_LE32: + /* not implemented */ + case USB_EXT_PROP_BE32: + /* not implemented */ + default: + return -EINVAL; + } + buf += count; + } + } + + return 0; +} + /* * The setup() callback implements all the ep0 functionality that's * not handled lower down, in hardware or the hardware driver(like @@ -1445,6 +1613,91 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; default: unknown: + /* + * OS descriptors handling + */ + if (cdev->use_os_string && cdev->os_desc_config && + (ctrl->bRequest & USB_TYPE_VENDOR) && + ctrl->bRequest == cdev->b_vendor_code) { + struct usb_request *req; + struct usb_configuration *os_desc_cfg; + u8 *buf; + int interface; + int count = 0; + + req = cdev->os_desc_req; + req->complete = composite_setup_complete; + buf = req->buf; + os_desc_cfg = cdev->os_desc_config; + memset(buf, 0, w_length); + buf[5] = 0x01; + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + if (w_index != 0x4 || (w_value >> 8)) + break; + buf[6] = w_index; + if (w_length == 0x10) { + /* Number of ext compat interfaces */ + count = count_ext_compat(os_desc_cfg); + buf[8] = count; + count *= 24; /* 24 B/ext compat desc */ + count += 16; /* header */ + put_unaligned_le32(count, buf); + value = w_length; + } else { + /* "extended compatibility ID"s */ + count = count_ext_compat(os_desc_cfg); + buf[8] = count; + count *= 24; /* 24 B/ext compat desc */ + count += 16; /* header */ + put_unaligned_le32(count, buf); + buf += 16; + fill_ext_compat(os_desc_cfg, buf); + value = w_length; + } + break; + case USB_RECIP_INTERFACE: + if (w_index != 0x5 || (w_value >> 8)) + break; + interface = w_value & 0xFF; + buf[6] = w_index; + if (w_length == 0x0A) { + count = count_ext_prop(os_desc_cfg, + interface); + put_unaligned_le16(count, buf + 8); + count = len_ext_prop(os_desc_cfg, + interface); + put_unaligned_le32(count, buf); + + value = w_length; + } else { + count = count_ext_prop(os_desc_cfg, + interface); + put_unaligned_le16(count, buf + 8); + count = len_ext_prop(os_desc_cfg, + interface); + put_unaligned_le32(count, buf); + buf += 10; + value = fill_ext_prop(os_desc_cfg, + interface, buf); + if (value < 0) + return value; + + value = w_length; + } + break; + } + req->length = value; + req->zero = value < w_length; + value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + DBG(cdev, "ep_queue --> %d\n", value); + req->status = 0; + composite_setup_complete(gadget->ep0, req); + } + return value; + } + VDBG(cdev, "non-core control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, @@ -1668,6 +1921,29 @@ fail: return ret; } +int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, + struct usb_ep *ep0) +{ + int ret = 0; + + cdev->os_desc_req = usb_ep_alloc_request(ep0, GFP_KERNEL); + if (!cdev->os_desc_req) { + ret = PTR_ERR(cdev->os_desc_req); + goto end; + } + + /* OS feature descriptor length <= 4kB */ + cdev->os_desc_req->buf = kmalloc(4096, GFP_KERNEL); + if (!cdev->os_desc_req->buf) { + ret = PTR_ERR(cdev->os_desc_req->buf); + kfree(cdev->os_desc_req); + goto end; + } + cdev->os_desc_req->complete = composite_setup_complete; +end: + return ret; +} + void composite_dev_cleanup(struct usb_composite_dev *cdev) { struct usb_gadget_string_container *uc, *tmp; @@ -1676,6 +1952,10 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) list_del(&uc->list); kfree(uc); } + if (cdev->os_desc_req) { + kfree(cdev->os_desc_req->buf); + usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); + } if (cdev->req) { kfree(cdev->req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->req); @@ -1713,6 +1993,12 @@ static int composite_bind(struct usb_gadget *gadget, if (status < 0) goto fail; + if (cdev->use_os_string) { + status = composite_os_desc_req_prepare(cdev, gadget->ep0); + if (status) + goto fail; + } + update_unchanged_dev_desc(&cdev->desc, composite->dev); /* has userspace failed to provide a serial number? */ diff --git a/drivers/usb/gadget/u_os_desc.h b/drivers/usb/gadget/u_os_desc.h new file mode 100644 index 000000000000..ea5cf8c2da28 --- /dev/null +++ b/drivers/usb/gadget/u_os_desc.h @@ -0,0 +1,90 @@ +/* + * u_os_desc.h + * + * Utility definitions for "OS Descriptors" support + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Andrzej Pietrasiewicz + * + * 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. + */ + +#ifndef __U_OS_DESC_H__ +#define __U_OS_DESC_H__ + +#include +#include + +#define USB_EXT_PROP_DW_SIZE 0 +#define USB_EXT_PROP_DW_PROPERTY_DATA_TYPE 4 +#define USB_EXT_PROP_W_PROPERTY_NAME_LENGTH 8 +#define USB_EXT_PROP_B_PROPERTY_NAME 10 +#define USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH 10 +#define USB_EXT_PROP_B_PROPERTY_DATA 14 + +#define USB_EXT_PROP_RESERVED 0 +#define USB_EXT_PROP_UNICODE 1 +#define USB_EXT_PROP_UNICODE_ENV 2 +#define USB_EXT_PROP_BINARY 3 +#define USB_EXT_PROP_LE32 4 +#define USB_EXT_PROP_BE32 5 +#define USB_EXT_PROP_UNICODE_LINK 6 +#define USB_EXT_PROP_UNICODE_MULTI 7 + +static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) +{ + put_unaligned_le32(dw_size, &buf[USB_EXT_PROP_DW_SIZE]); +} + +static inline void usb_ext_prop_put_type(u8 *buf, int type) +{ + put_unaligned_le32(type, &buf[USB_EXT_PROP_DW_PROPERTY_DATA_TYPE]); +} + +static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) +{ + int result; + + put_unaligned_le16(pnl, &buf[USB_EXT_PROP_W_PROPERTY_NAME_LENGTH]); + result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, + (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_NAME], pnl - 2); + if (result < 0) + return result; + + put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl]); + + return pnl; +} + +static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, + int data_len) +{ + put_unaligned_le32(data_len, + &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); + memcpy(&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], data, data_len); +} + +static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, + int data_len) +{ + int result; + put_unaligned_le32(data_len, + &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); + + result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, + (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], + data_len - 2); + if (result < 0) + return result; + + put_unaligned_le16(0, + &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len]); + + return data_len; +} + +#endif /* __U_OS_DESC_H__ */ -- cgit v1.2.3 From de7a8d2d534fb3c35c29762b8a7d14e5b1937d6f Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:24 +0200 Subject: usb: gadget: f_rndis: OS descriptors support In order for usb functions to expose OS descriptors they need to be made aware of OS descriptors. This involves extending the "options" structure and setting up appropriate associations. Signed-off-by: Andrzej Pietrasiewicz Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 24 +++++++++++++++++++++--- drivers/usb/gadget/u_rndis.h | 3 +++ 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 139bc9c6f7e0..28d1891f11fa 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -682,6 +682,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); + if (cdev->use_os_string) { + f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), + GFP_KERNEL); + if (!f->os_desc_table) + return PTR_ERR(f->os_desc_table); + f->os_desc_n = 1; + f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; + } + /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, @@ -693,14 +702,16 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) gether_set_gadget(rndis_opts->net, cdev->gadget); status = gether_register_netdev(rndis_opts->net); if (status) - return status; + goto fail; rndis_opts->bound = true; } us = usb_gstrings_attach(cdev, rndis_strings, ARRAY_SIZE(rndis_string_defs)); - if (IS_ERR(us)) - return PTR_ERR(us); + if (IS_ERR(us)) { + status = PTR_ERR(us); + goto fail; + } rndis_control_intf.iInterface = us[0].id; rndis_data_intf.iInterface = us[1].id; rndis_iad_descriptor.iFunction = us[2].id; @@ -802,6 +813,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: + kfree(f->os_desc_table); + f->os_desc_n = 0; usb_free_all_descriptors(f); if (rndis->notify_req) { @@ -892,6 +905,8 @@ static struct usb_function_instance *rndis_alloc_inst(void) opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); + opts->rndis_os_desc.ext_compat_id = opts->rndis_ext_compat_id; + mutex_init(&opts->lock); opts->func_inst.free_func_inst = rndis_free_inst; opts->net = gether_setup_default(); @@ -900,6 +915,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) kfree(opts); return ERR_CAST(net); } + INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); @@ -925,6 +941,8 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_rndis *rndis = func_to_rndis(f); + kfree(f->os_desc_table); + f->os_desc_n = 0; usb_free_all_descriptors(f); kfree(rndis->notify_req->buf); diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h index 7291b15c9dce..e902aa42a297 100644 --- a/drivers/usb/gadget/u_rndis.h +++ b/drivers/usb/gadget/u_rndis.h @@ -26,6 +26,9 @@ struct f_rndis_opts { bool bound; bool borrowed_net; + struct usb_os_desc rndis_os_desc; + char rndis_ext_compat_id[16]; + /* * Read/write access to configfs attributes is handled by configfs. * -- cgit v1.2.3 From 87213d388e927aaa88b21d5ff7e1f75ca2288da1 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:25 +0200 Subject: usb: gadget: configfs: OS String support Add handling of OS String extension from the configfs interface. A directory "os_desc" is added at the top level of a gadget's directories hierarchy. In the "os_desc" directory there are three attributes: "use", "b_vendor_code" and "qw_sign". If "use" contains "0" the OS string is not reported to the host. "b_vendor_code" contains a one-byte value which is used for custom per-device and per-interface requests. "qw_sign" contains an identifier to be reported as the "OS String" proper. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 159 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index b5e965ec8b61..8b9e038ac22b 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "configfs.h" @@ -43,7 +44,8 @@ struct gadget_info { struct config_group functions_group; struct config_group configs_group; struct config_group strings_group; - struct config_group *default_groups[4]; + struct config_group os_desc_group; + struct config_group *default_groups[5]; struct mutex lock; struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1]; @@ -56,6 +58,9 @@ struct gadget_info { #endif struct usb_composite_driver composite; struct usb_composite_dev cdev; + bool use_os_desc; + char b_vendor_code; + char qw_sign[OS_STRING_QW_SIGN_LEN]; }; struct config_usb_cfg { @@ -79,6 +84,10 @@ struct gadget_strings { struct list_head list; }; +struct os_desc { + struct config_group group; +}; + struct gadget_config_name { struct usb_gadget_strings stringtab_dev; struct usb_string strings; @@ -736,6 +745,145 @@ static void gadget_strings_attr_release(struct config_item *item) USB_CONFIG_STRING_RW_OPS(gadget_strings); USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info); +static inline struct os_desc *to_os_desc(struct config_item *item) +{ + return container_of(to_config_group(item), struct os_desc, group); +} + +CONFIGFS_ATTR_STRUCT(os_desc); +CONFIGFS_ATTR_OPS(os_desc); + +static ssize_t os_desc_use_show(struct os_desc *os_desc, char *page) +{ + struct gadget_info *gi; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + + return sprintf(page, "%d", gi->use_os_desc); +} + +static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page, + size_t len) +{ + struct gadget_info *gi; + int ret; + bool use; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + + mutex_lock(&gi->lock); + ret = strtobool(page, &use); + if (!ret) { + gi->use_os_desc = use; + ret = len; + } + mutex_unlock(&gi->lock); + + return ret; +} + +static struct os_desc_attribute os_desc_use = + __CONFIGFS_ATTR(use, S_IRUGO | S_IWUSR, + os_desc_use_show, + os_desc_use_store); + +static ssize_t os_desc_b_vendor_code_show(struct os_desc *os_desc, char *page) +{ + struct gadget_info *gi; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + + return sprintf(page, "%d", gi->b_vendor_code); +} + +static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc, + const char *page, size_t len) +{ + struct gadget_info *gi; + int ret; + u8 b_vendor_code; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + + mutex_lock(&gi->lock); + ret = kstrtou8(page, 0, &b_vendor_code); + if (!ret) { + gi->b_vendor_code = b_vendor_code; + ret = len; + } + mutex_unlock(&gi->lock); + + return ret; +} + +static struct os_desc_attribute os_desc_b_vendor_code = + __CONFIGFS_ATTR(b_vendor_code, S_IRUGO | S_IWUSR, + os_desc_b_vendor_code_show, + os_desc_b_vendor_code_store); + +static ssize_t os_desc_qw_sign_show(struct os_desc *os_desc, char *page) +{ + struct gadget_info *gi; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + + memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN); + + return OS_STRING_QW_SIGN_LEN; +} + +static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page, + size_t len) +{ + struct gadget_info *gi; + int res, l; + + gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1); + if (page[l - 1] == '\n') + --l; + + mutex_lock(&gi->lock); + res = utf8s_to_utf16s(page, l, + UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign, + OS_STRING_QW_SIGN_LEN); + if (res > 0) + res = len; + mutex_unlock(&gi->lock); + + return res; +} + +static struct os_desc_attribute os_desc_qw_sign = + __CONFIGFS_ATTR(qw_sign, S_IRUGO | S_IWUSR, + os_desc_qw_sign_show, + os_desc_qw_sign_store); + +static struct configfs_attribute *os_desc_attrs[] = { + &os_desc_use.attr, + &os_desc_b_vendor_code.attr, + &os_desc_qw_sign.attr, + NULL, +}; + +static void os_desc_attr_release(struct config_item *item) +{ + struct os_desc *os_desc = to_os_desc(item); + kfree(os_desc); +} + +static struct configfs_item_operations os_desc_ops = { + .release = os_desc_attr_release, + .show_attribute = os_desc_attr_show, + .store_attribute = os_desc_attr_store, +}; + +static struct config_item_type os_desc_type = { + .ct_item_ops = &os_desc_ops, + .ct_attrs = os_desc_attrs, + .ct_owner = THIS_MODULE, +}; + static int configfs_do_nothing(struct usb_composite_dev *cdev) { WARN_ON(1); @@ -839,6 +987,12 @@ static int configfs_composite_bind(struct usb_gadget *gadget, gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id; } + if (gi->use_os_desc) { + cdev->use_os_string = true; + cdev->b_vendor_code = gi->b_vendor_code; + memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN); + } + /* Go through all configs, attach all functions */ list_for_each_entry(c, &gi->cdev.configs, list) { struct config_usb_cfg *cfg; @@ -929,6 +1083,7 @@ static struct config_group *gadgets_make( gi->group.default_groups[0] = &gi->functions_group; gi->group.default_groups[1] = &gi->configs_group; gi->group.default_groups[2] = &gi->strings_group; + gi->group.default_groups[3] = &gi->os_desc_group; config_group_init_type_name(&gi->functions_group, "functions", &functions_type); @@ -936,6 +1091,8 @@ static struct config_group *gadgets_make( &config_desc_type); config_group_init_type_name(&gi->strings_group, "strings", &gadget_strings_strings_type); + config_group_init_type_name(&gi->os_desc_group, "os_desc", + &os_desc_type); gi->composite.bind = configfs_do_nothing; gi->composite.unbind = configfs_do_nothing; -- cgit v1.2.3 From da4243145fb197622425d4c2feff5d6422f2391e Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:26 +0200 Subject: usb: gadget: configfs: OS Extended Compatibility descriptors support Add handling of OS Extended Compatibility descriptors from configfs interface. Hosts which expect the "OS Descriptors" ask only for configurations @ index 0, but linux-based USB devices can provide more than one configuration. This patch adds marking one of gadget's configurations the configuration to be reported at index 0, regardless of the actual sequence of usb_add_config invocations used for adding the configurations. The configuration is selected by creating a symbolic link pointing to it from the "os_desc" directory located at the top of a gadget's directory hierarchy. One kind of "OS Descriptors" are "Extended Compatibility Descriptors", which need to be specified per interface. This patch adds interface. directory in function's configfs directory to represent each interface defined by the function. Each interface's directory contains two attributes: "compatible_id" and "sub_compatible_id", which represent 8-byte strings to be reported to the host as the "Compatible ID" and "Sub Compatible ID". Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 190 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/configfs.h | 12 +++ 2 files changed, 202 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 8b9e038ac22b..fa6cb06cca09 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -6,6 +6,7 @@ #include #include #include "configfs.h" +#include "u_f.h" int check_user_usb_string(const char *name, struct usb_gadget_strings *stringtab_dev) @@ -872,10 +873,63 @@ static void os_desc_attr_release(struct config_item *item) kfree(os_desc); } +static int os_desc_link(struct config_item *os_desc_ci, + struct config_item *usb_cfg_ci) +{ + struct gadget_info *gi = container_of(to_config_group(os_desc_ci), + struct gadget_info, os_desc_group); + struct usb_composite_dev *cdev = &gi->cdev; + struct config_usb_cfg *c_target = + container_of(to_config_group(usb_cfg_ci), + struct config_usb_cfg, group); + struct usb_configuration *c; + int ret; + + mutex_lock(&gi->lock); + list_for_each_entry(c, &cdev->configs, list) { + if (c == &c_target->c) + break; + } + if (c != &c_target->c) { + ret = -EINVAL; + goto out; + } + + if (cdev->os_desc_config) { + ret = -EBUSY; + goto out; + } + + cdev->os_desc_config = &c_target->c; + ret = 0; + +out: + mutex_unlock(&gi->lock); + return ret; +} + +static int os_desc_unlink(struct config_item *os_desc_ci, + struct config_item *usb_cfg_ci) +{ + struct gadget_info *gi = container_of(to_config_group(os_desc_ci), + struct gadget_info, os_desc_group); + struct usb_composite_dev *cdev = &gi->cdev; + + mutex_lock(&gi->lock); + if (gi->udc_name) + unregister_gadget(gi); + cdev->os_desc_config = NULL; + WARN_ON(gi->udc_name); + mutex_unlock(&gi->lock); + return 0; +} + static struct configfs_item_operations os_desc_ops = { .release = os_desc_attr_release, .show_attribute = os_desc_attr_show, .store_attribute = os_desc_attr_store, + .allow_link = os_desc_link, + .drop_link = os_desc_unlink, }; static struct config_item_type os_desc_type = { @@ -884,6 +938,133 @@ static struct config_item_type os_desc_type = { .ct_owner = THIS_MODULE, }; +CONFIGFS_ATTR_STRUCT(usb_os_desc); +CONFIGFS_ATTR_OPS(usb_os_desc); + +static struct configfs_item_operations interf_item_ops = { + .show_attribute = usb_os_desc_attr_show, + .store_attribute = usb_os_desc_attr_store, +}; + +static ssize_t rndis_grp_compatible_id_show(struct usb_os_desc *desc, + char *page) +{ + memcpy(page, desc->ext_compat_id, 8); + return 8; +} + +static ssize_t rndis_grp_compatible_id_store(struct usb_os_desc *desc, + const char *page, size_t len) +{ + int l; + + l = min_t(int, 8, len); + if (page[l - 1] == '\n') + --l; + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + memcpy(desc->ext_compat_id, page, l); + desc->ext_compat_id[l] = '\0'; + + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + + return len; +} + +static struct usb_os_desc_attribute rndis_grp_attr_compatible_id = + __CONFIGFS_ATTR(compatible_id, S_IRUGO | S_IWUSR, + rndis_grp_compatible_id_show, + rndis_grp_compatible_id_store); + +static ssize_t rndis_grp_sub_compatible_id_show(struct usb_os_desc *desc, + char *page) +{ + memcpy(page, desc->ext_compat_id + 8, 8); + return 8; +} + +static ssize_t rndis_grp_sub_compatible_id_store(struct usb_os_desc *desc, + const char *page, size_t len) +{ + int l; + + l = min_t(int, 8, len); + if (page[l - 1] == '\n') + --l; + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + memcpy(desc->ext_compat_id + 8, page, l); + desc->ext_compat_id[l + 8] = '\0'; + + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + + return len; +} + +static struct usb_os_desc_attribute rndis_grp_attr_sub_compatible_id = + __CONFIGFS_ATTR(sub_compatible_id, S_IRUGO | S_IWUSR, + rndis_grp_sub_compatible_id_show, + rndis_grp_sub_compatible_id_store); + +static struct configfs_attribute *interf_grp_attrs[] = { + &rndis_grp_attr_compatible_id.attr, + &rndis_grp_attr_sub_compatible_id.attr, + NULL +}; + +int usb_os_desc_prepare_interf_dir(struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + struct module *owner) +{ + struct config_group **f_default_groups, *os_desc_group, + **interface_groups; + struct config_item_type *os_desc_type, *interface_type; + + vla_group(data_chunk); + vla_item(data_chunk, struct config_group *, f_default_groups, 2); + vla_item(data_chunk, struct config_group, os_desc_group, 1); + vla_item(data_chunk, struct config_group *, interface_groups, + n_interf + 1); + vla_item(data_chunk, struct config_item_type, os_desc_type, 1); + vla_item(data_chunk, struct config_item_type, interface_type, 1); + + char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); + if (!vlabuf) + return -ENOMEM; + + f_default_groups = vla_ptr(vlabuf, data_chunk, f_default_groups); + os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); + os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); + interface_groups = vla_ptr(vlabuf, data_chunk, interface_groups); + interface_type = vla_ptr(vlabuf, data_chunk, interface_type); + + parent->default_groups = f_default_groups; + os_desc_type->ct_owner = owner; + config_group_init_type_name(os_desc_group, "os_desc", os_desc_type); + f_default_groups[0] = os_desc_group; + + os_desc_group->default_groups = interface_groups; + interface_type->ct_item_ops = &interf_item_ops; + interface_type->ct_attrs = interf_grp_attrs; + interface_type->ct_owner = owner; + + while (n_interf--) { + struct usb_os_desc *d; + + d = desc[n_interf]; + config_group_init_type_name(&d->group, "", interface_type); + config_item_set_name(&d->group.cg_item, "interface.%d", + n_interf); + interface_groups[n_interf] = &d->group; + } + + return 0; +} +EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); + static int configfs_do_nothing(struct usb_composite_dev *cdev) { WARN_ON(1); @@ -893,6 +1074,9 @@ static int configfs_do_nothing(struct usb_composite_dev *cdev) int composite_dev_prepare(struct usb_composite_driver *composite, struct usb_composite_dev *dev); +int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, + struct usb_ep *ep0); + static void purge_configs_funcs(struct gadget_info *gi) { struct usb_configuration *c; @@ -1028,6 +1212,12 @@ static int configfs_composite_bind(struct usb_gadget *gadget, } usb_ep_autoconfig_reset(cdev->gadget); } + if (cdev->use_os_string) { + ret = composite_os_desc_req_prepare(cdev, gadget->ep0); + if (ret) + goto err_purge_funcs; + } + usb_ep_autoconfig_reset(cdev->gadget); return 0; diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index a7b564a913d1..a14ac792c698 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h @@ -1,6 +1,18 @@ #ifndef USB__GADGET__CONFIGFS__H #define USB__GADGET__CONFIGFS__H +#include + void unregister_gadget_item(struct config_item *item); +int usb_os_desc_prepare_interf_dir(struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + struct module *owner); + +static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) +{ + return container_of(to_config_group(item), struct usb_os_desc, group); +} + #endif /* USB__GADGET__CONFIGFS__H */ -- cgit v1.2.3 From a747b0958b5ead2d4ba46dc1f77d46e693a06efa Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:27 +0200 Subject: usb: gadget: f_rndis: OS Descriptors configfs support Added handling of OS Descriptors support for f_rndis. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 28d1891f11fa..f1bf5763eac4 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -27,6 +27,7 @@ #include "u_ether_configfs.h" #include "u_rndis.h" #include "rndis.h" +#include "configfs.h" /* * This function is an RNDIS Ethernet port -- a Microsoft protocol that's @@ -895,12 +896,15 @@ static void rndis_free_inst(struct usb_function_instance *f) else free_netdev(opts->net); } + + kfree(opts->rndis_os_desc.group.default_groups); /* single VLA chunk */ kfree(opts); } static struct usb_function_instance *rndis_alloc_inst(void) { struct f_rndis_opts *opts; + struct usb_os_desc *descs[1]; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) @@ -917,6 +921,9 @@ static struct usb_function_instance *rndis_alloc_inst(void) } INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); + descs[0] = &opts->rndis_os_desc; + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, + THIS_MODULE); config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); -- cgit v1.2.3 From 7419485f197c436d41535df78ddea1085042d271 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 8 May 2014 14:06:28 +0200 Subject: usb: gadget: configfs: OS Extended Properties descriptors support Add handling of OS Extended Properties descriptors from configfs interface. One kind of "OS Descriptors" are "Extended Properties" descriptors, which need to be specified per interface or per group of interfaces described by an IAD. This patch adds support for creating subdirectories in interface. directory located in the function's directory. Names of subdirectories created become names of properties. Each property contains two attributes: "type" and "data". The type can be a numeric value 1..7 while data is a blob interpreted depending on the type specified. The types are: 1 - unicode string 2 - unicode string with environment variables 3 - binary 4 - little-endian 32-bit 5 - big-endian 32-bit 6 - unicode string with a symbolic link 7 - multiple unicode strings Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 201 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index fa6cb06cca09..2ddcd635ca2a 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -7,6 +7,7 @@ #include #include "configfs.h" #include "u_f.h" +#include "u_os_desc.h" int check_user_usb_string(const char *name, struct usb_gadget_strings *stringtab_dev) @@ -941,6 +942,204 @@ static struct config_item_type os_desc_type = { CONFIGFS_ATTR_STRUCT(usb_os_desc); CONFIGFS_ATTR_OPS(usb_os_desc); + +static inline struct usb_os_desc_ext_prop +*to_usb_os_desc_ext_prop(struct config_item *item) +{ + return container_of(item, struct usb_os_desc_ext_prop, item); +} + +CONFIGFS_ATTR_STRUCT(usb_os_desc_ext_prop); +CONFIGFS_ATTR_OPS(usb_os_desc_ext_prop); + +static ssize_t ext_prop_type_show(struct usb_os_desc_ext_prop *ext_prop, + char *page) +{ + return sprintf(page, "%d", ext_prop->type); +} + +static ssize_t ext_prop_type_store(struct usb_os_desc_ext_prop *ext_prop, + const char *page, size_t len) +{ + struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); + u8 type; + int ret; + + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + ret = kstrtou8(page, 0, &type); + if (ret) + goto end; + if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) { + ret = -EINVAL; + goto end; + } + + if ((ext_prop->type == USB_EXT_PROP_BINARY || + ext_prop->type == USB_EXT_PROP_LE32 || + ext_prop->type == USB_EXT_PROP_BE32) && + (type == USB_EXT_PROP_UNICODE || + type == USB_EXT_PROP_UNICODE_ENV || + type == USB_EXT_PROP_UNICODE_LINK)) + ext_prop->data_len <<= 1; + else if ((ext_prop->type == USB_EXT_PROP_UNICODE || + ext_prop->type == USB_EXT_PROP_UNICODE_ENV || + ext_prop->type == USB_EXT_PROP_UNICODE_LINK) && + (type == USB_EXT_PROP_BINARY || + type == USB_EXT_PROP_LE32 || + type == USB_EXT_PROP_BE32)) + ext_prop->data_len >>= 1; + ext_prop->type = type; + ret = len; + +end: + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + return ret; +} + +static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop, + char *page) +{ + int len = ext_prop->data_len; + + if (ext_prop->type == USB_EXT_PROP_UNICODE || + ext_prop->type == USB_EXT_PROP_UNICODE_ENV || + ext_prop->type == USB_EXT_PROP_UNICODE_LINK) + len >>= 1; + memcpy(page, ext_prop->data, len); + + return len; +} + +static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, + const char *page, size_t len) +{ + struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); + char *new_data; + size_t ret_len = len; + + if (page[len - 1] == '\n' || page[len - 1] == '\0') + --len; + new_data = kzalloc(len, GFP_KERNEL); + if (!new_data) + return -ENOMEM; + + memcpy(new_data, page, len); + + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + kfree(ext_prop->data); + ext_prop->data = new_data; + desc->ext_prop_len -= ext_prop->data_len; + ext_prop->data_len = len; + desc->ext_prop_len += ext_prop->data_len; + if (ext_prop->type == USB_EXT_PROP_UNICODE || + ext_prop->type == USB_EXT_PROP_UNICODE_ENV || + ext_prop->type == USB_EXT_PROP_UNICODE_LINK) { + desc->ext_prop_len -= ext_prop->data_len; + ext_prop->data_len <<= 1; + ext_prop->data_len += 2; + desc->ext_prop_len += ext_prop->data_len; + } + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + return ret_len; +} + +static struct usb_os_desc_ext_prop_attribute ext_prop_type = + __CONFIGFS_ATTR(type, S_IRUGO | S_IWUSR, + ext_prop_type_show, ext_prop_type_store); + +static struct usb_os_desc_ext_prop_attribute ext_prop_data = + __CONFIGFS_ATTR(data, S_IRUGO | S_IWUSR, + ext_prop_data_show, ext_prop_data_store); + +static struct configfs_attribute *ext_prop_attrs[] = { + &ext_prop_type.attr, + &ext_prop_data.attr, + NULL, +}; + +static void usb_os_desc_ext_prop_release(struct config_item *item) +{ + struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); + + kfree(ext_prop); /* frees a whole chunk */ +} + +static struct configfs_item_operations ext_prop_ops = { + .release = usb_os_desc_ext_prop_release, + .show_attribute = usb_os_desc_ext_prop_attr_show, + .store_attribute = usb_os_desc_ext_prop_attr_store, +}; + +static struct config_item *ext_prop_make( + struct config_group *group, + const char *name) +{ + struct usb_os_desc_ext_prop *ext_prop; + struct config_item_type *ext_prop_type; + struct usb_os_desc *desc; + char *vlabuf; + + vla_group(data_chunk); + vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1); + vla_item(data_chunk, struct config_item_type, ext_prop_type, 1); + + vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); + if (!vlabuf) + return ERR_PTR(-ENOMEM); + + ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop); + ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type); + + desc = container_of(group, struct usb_os_desc, group); + ext_prop_type->ct_item_ops = &ext_prop_ops; + ext_prop_type->ct_attrs = ext_prop_attrs; + ext_prop_type->ct_owner = desc->owner; + + config_item_init_type_name(&ext_prop->item, name, ext_prop_type); + + ext_prop->name = kstrdup(name, GFP_KERNEL); + if (!ext_prop->name) { + kfree(vlabuf); + return ERR_PTR(-ENOMEM); + } + desc->ext_prop_len += 14; + ext_prop->name_len = 2 * strlen(ext_prop->name) + 2; + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + desc->ext_prop_len += ext_prop->name_len; + list_add_tail(&ext_prop->entry, &desc->ext_prop); + ++desc->ext_prop_count; + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + + return &ext_prop->item; +} + +static void ext_prop_drop(struct config_group *group, struct config_item *item) +{ + struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); + struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item); + + if (desc->opts_mutex) + mutex_lock(desc->opts_mutex); + list_del(&ext_prop->entry); + --desc->ext_prop_count; + kfree(ext_prop->name); + desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14); + if (desc->opts_mutex) + mutex_unlock(desc->opts_mutex); + config_item_put(item); +} + +static struct configfs_group_operations interf_grp_ops = { + .make_item = &ext_prop_make, + .drop_item = &ext_prop_drop, +}; + static struct configfs_item_operations interf_item_ops = { .show_attribute = usb_os_desc_attr_show, .store_attribute = usb_os_desc_attr_store, @@ -1048,6 +1247,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, os_desc_group->default_groups = interface_groups; interface_type->ct_item_ops = &interf_item_ops; + interface_type->ct_group_ops = &interf_grp_ops; interface_type->ct_attrs = interf_grp_attrs; interface_type->ct_owner = owner; @@ -1055,6 +1255,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, struct usb_os_desc *d; d = desc[n_interf]; + d->owner = owner; config_group_init_type_name(&d->group, "", interface_type); config_item_set_name(&d->group.cg_item, "interface.%d", n_interf); -- cgit v1.2.3 From b09e99ee7c2b7ee80cca128b93b07fb830e6ecad Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 15 May 2014 15:53:32 +0300 Subject: usb: dwc3: no need to initialize ret variable First usage of ret variable will re-write initial value. Thus, there is no need to initialize it. Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/dwc3-exynos.c | 12 +++++------- drivers/usb/dwc3/dwc3-omap.c | 2 +- drivers/usb/dwc3/dwc3-pci.c | 2 +- drivers/usb/dwc3/gadget.c | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index af8c8f6e67b3..3f59c1247825 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -626,7 +626,7 @@ static int dwc3_probe(struct platform_device *pdev) struct resource *res; struct dwc3 *dwc; - int ret = -ENOMEM; + int ret; void __iomem *regs; void *mem; diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 0ed85834bfec..f9fb8adb785b 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -110,12 +110,12 @@ static int dwc3_exynos_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; - int ret = -ENOMEM; + int ret; exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); if (!exynos) { dev_err(dev, "not enough memory\n"); - goto err1; + return -ENOMEM; } /* @@ -125,21 +125,20 @@ static int dwc3_exynos_probe(struct platform_device *pdev) */ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) - goto err1; + return ret; platform_set_drvdata(pdev, exynos); ret = dwc3_exynos_register_phys(exynos); if (ret) { dev_err(dev, "couldn't register PHYs\n"); - goto err1; + return ret; } clk = devm_clk_get(dev, "usbdrd30"); if (IS_ERR(clk)) { dev_err(dev, "couldn't get clock\n"); - ret = -EINVAL; - goto err1; + return -EINVAL; } exynos->dev = dev; @@ -189,7 +188,6 @@ err3: regulator_disable(exynos->vdd33); err2: clk_disable_unprepare(clk); -err1: return ret; } diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 1160ff41bed4..4af4c3567656 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -393,7 +393,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) struct extcon_dev *edev; struct regulator *vbus_reg = NULL; - int ret = -ENOMEM; + int ret; int irq; int utmi_mode = 0; diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 1ed95e0386eb..e76d1ca5531c 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -99,7 +99,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, struct resource res[2]; struct platform_device *dwc3; struct dwc3_pci *glue; - int ret = -ENOMEM; + int ret; struct device *dev = &pci->dev; glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e0b791050930..696b472274ef 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -584,7 +584,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, { struct dwc3 *dwc = dep->dwc; u32 reg; - int ret = -ENOMEM; + int ret; dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); -- cgit v1.2.3 From f1c7e7108109bfa12ad4544dce5cdcbf3c6f0a0a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 15 May 2014 15:53:33 +0300 Subject: usb: dwc3: convert to pcim_enable_device() This fixes a bug when dwc3_pci_register_phys() fails and leaves device enabled. Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index e76d1ca5531c..a60bab7dfa0a 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -110,7 +110,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, glue->dev = dev; - ret = pci_enable_device(pci); + ret = pcim_enable_device(pci); if (ret) { dev_err(dev, "failed to enable pci device\n"); return -ENODEV; @@ -127,8 +127,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); if (!dwc3) { dev_err(dev, "couldn't allocate dwc3 device\n"); - ret = -ENOMEM; - goto err1; + return -ENOMEM; } memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); @@ -145,7 +144,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); - goto err1; + return ret; } pci_set_drvdata(pci, glue); @@ -167,9 +166,6 @@ static int dwc3_pci_probe(struct pci_dev *pci, err3: platform_device_put(dwc3); -err1: - pci_disable_device(pci); - return ret; } @@ -180,7 +176,6 @@ static void dwc3_pci_remove(struct pci_dev *pci) platform_device_unregister(glue->dwc3); platform_device_unregister(glue->usb2_phy); platform_device_unregister(glue->usb3_phy); - pci_disable_device(pci); } static const struct pci_device_id dwc3_pci_id_table[] = { -- cgit v1.2.3 From 1ade5d7e179170e3cf4780ba578ebb8cc7aa15ef Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 15 May 2014 13:43:50 +0200 Subject: usb: gadget: f_uac2: don't queue new requests when shutting down In some circumstances when g_audio is being unloaded there happens an endless loop in udc driver. It has happend on a board with s3c-hsotg. If there are requests in endpoint's queue, they are completed in a loop. But completing them might cause appending new requests to the queue. This patch causes agdev_iso_complete() to return immediately if request's status is -ESHUTDOWN. If it does not return immediately, then although the current request is removed from the queue, a new one is appended to the queue, so the above mentioned loop cannot end. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index c024d27fcce2..6261db4a9910 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -196,7 +196,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) struct snd_uac2_chip *uac2 = prm->uac2; /* i/f shutting down */ - if (!prm->ep_enabled) + if (!prm->ep_enabled || req->status == -ESHUTDOWN) return; /* -- cgit v1.2.3 From 79cb5b533aa9dbb05123b3b7d170e686da558a35 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Wed, 14 May 2014 21:32:39 +0100 Subject: usb: phy: Add SMSC USB334x PHY ID adding new device id for SMSC USB334x devices. Signed-off-by: Liviu Dudau Signed-off-by: Ryan Harkin Signed-off-by: Mark Brown Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-ulpi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 17ea3f271bd8..4e3877c329f2 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c @@ -48,6 +48,7 @@ static struct ulpi_info ulpi_ids[] = { ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), + ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"), ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), }; -- cgit v1.2.3 From 16bf900f50ec7fd2f45dc3a297d7936075cdae55 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 23 Mar 2014 16:25:09 +0100 Subject: usb: gadget: uvc: Switch to monotonic clock for buffer timestamps The wall time clock isn't useful for applications as it can jump around due to time adjustement. Switch to the monotonic clock. Signed-off-by: Laurent Pinchart Reviewed-by: Hans Verkuil Acked-by: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_queue.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index 0bb5d50075de..9ac4ffe19014 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -20,6 +20,7 @@ #include #include +#include #include #include "uvc.h" @@ -379,14 +380,8 @@ static struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, else nextbuf = NULL; - /* - * FIXME: with videobuf2, the sequence number or timestamp fields - * are valid only for video capture devices and the UVC gadget usually - * is a video output device. Keeping these until the specs are clear on - * this aspect. - */ buf->buf.v4l2_buf.sequence = queue->sequence++; - do_gettimeofday(&buf->buf.v4l2_buf.timestamp); + v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); -- cgit v1.2.3 From f17388cc29090a94268256f1a17445e715bc5d94 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 23 Mar 2014 16:25:09 +0100 Subject: usb: gadget: uvc: Set the V4L2 buffer field to V4L2_FIELD_NONE The UVC gadget driver doesn't support interlaced video but left the buffer field uninitialized. Set it to V4L2_FIELD_NONE. Signed-off-by: Laurent Pinchart Reviewed-by: Hans Verkuil Acked-by: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_queue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index 9ac4ffe19014..305eb491c919 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -380,6 +380,7 @@ static struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, else nextbuf = NULL; + buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; buf->buf.v4l2_buf.sequence = queue->sequence++; v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); -- cgit v1.2.3 From c9e44b5354000386ef1324d200bf99b597756594 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 23 Mar 2014 16:19:50 +0100 Subject: usb: gadget: uvc: Set the vb2 queue timestamp flags The vb2 queue timestamp_flags field must be set by drivers, as enforced by a WARN_ON in vb2_queue_init. The UVC gadget driver failed to do so. This resulted in the following warning. [ 2.104371] g_webcam gadget: uvc_function_bind [ 2.105567] ------------[ cut here ]------------ [ 2.105567] ------------[ cut here ]------------ [ 2.106779] WARNING: CPU: 0 PID: 1 at drivers/media/v4l2-core/videobuf2-core.c:2207 vb2_queue_init+0xa3/0x113() Fix it. Reported-by: Fengguang Wu Signed-off-by: Laurent Pinchart Reviewed-by: Hans Verkuil Acked-by: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/gadget/uvc_queue.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index 305eb491c919..1c29bc954db9 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -137,6 +137,8 @@ static int uvc_queue_init(struct uvc_video_queue *queue, queue->queue.buf_struct_size = sizeof(struct uvc_buffer); queue->queue.ops = &uvc_queue_qops; queue->queue.mem_ops = &vb2_vmalloc_memops; + queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC + | V4L2_BUF_FLAG_TSTAMP_SRC_EOF; ret = vb2_queue_init(&queue->queue); if (ret) return ret; -- cgit v1.2.3 From 84237bfb0b112a18a7c5d4d35a0663c97bdd14c6 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 15 May 2014 14:28:45 +0200 Subject: usb: gadget: net2280: Fix NULL pointer dereference When DEBUG is enabled driver->driver.name is accessed, but driver can be NULL [ 174.411689] BUG: unable to handle kernel NULL pointer dereference at 0000000000000040 [ 174.429043] RIP: 0010:[] [] net2280_stop+0xa3/0x100 [net2280] [ 174.457910] Call Trace: [ 174.459503] [] usb_gadget_remove_driver+0x5a/0xb0 [udc_core] [ 174.462693] [] usb_del_gadget_udc+0xb4/0x110 [udc_core] [ 174.464316] [] net2280_remove+0x2f/0x1c0 [net2280] Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 43e5e2f9888f..300b3a71383b 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -1972,7 +1972,9 @@ static int net2280_stop(struct usb_gadget *_gadget, device_remove_file (&dev->pdev->dev, &dev_attr_function); device_remove_file (&dev->pdev->dev, &dev_attr_queues); - DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name); + DEBUG(dev, "unregistered driver '%s'\n", + driver ? driver->driver.name : ""); + return 0; } -- cgit v1.2.3 From 8c240dc17d900cc6453b48bdd513f4243a9ec97d Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Fri, 16 May 2014 18:19:54 +0400 Subject: usb: musb: tusb6010: Add tusb_revision to struct musb to store the revision. Add field to store tusb6010 revision value. Read the revision at the startup and store to the variable. Signed-off-by: Matwey V. Kornilov Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 1 + drivers/usb/musb/tusb6010.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 47e88747e3a7..d155a156f240 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -339,6 +339,7 @@ struct musb { dma_addr_t async; dma_addr_t sync; void __iomem *sync_va; + u8 tusb_revision; #endif /* passed down from chip/board specific irq handlers */ diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index f38a8dbd6075..8a746421a325 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1012,6 +1012,7 @@ static int tusb_musb_start(struct musb *musb) goto err; } + musb->tusb_revision = tusb_get_revision(musb); ret = tusb_print_revision(musb); if (ret < 2) { printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n", -- cgit v1.2.3 From 7751b6fb05869bcb318e74420148c06577adf894 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Fri, 16 May 2014 18:20:52 +0400 Subject: usb: musb: tusb6010: Use musb->tusb_revision instead of tusb_get_revision call. The value of the revision is stored in musb->tusb_revision, so don't re-read it every time. Exporting tusb_get_revision is not needed anymore, so the dependency loop between tusb6010 and tusb6010_omap is resolved. Signed-off-by: Matwey V. Kornilov Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.c | 19 ++++++++----------- drivers/usb/musb/tusb6010.h | 2 -- drivers/usb/musb/tusb6010_omap.c | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 8a746421a325..159ef4be1ef2 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -43,7 +43,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on); * Checks the revision. We need to use the DMA register as 3.0 does not * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. */ -u8 tusb_get_revision(struct musb *musb) +static u8 tusb_get_revision(struct musb *musb) { void __iomem *tbase = musb->ctrl_base; u32 die_id; @@ -59,14 +59,13 @@ u8 tusb_get_revision(struct musb *musb) return rev; } -EXPORT_SYMBOL_GPL(tusb_get_revision); -static int tusb_print_revision(struct musb *musb) +static void tusb_print_revision(struct musb *musb) { void __iomem *tbase = musb->ctrl_base; u8 rev; - rev = tusb_get_revision(musb); + rev = musb->tusb_revision; pr_info("tusb: %s%i.%i %s%i.%i %s%i.%i %s%i.%i %s%i %s%i.%i\n", "prcm", @@ -85,8 +84,6 @@ static int tusb_print_revision(struct musb *musb) TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase, TUSB_DIDR1_HI)), "rev", TUSB_REV_MAJOR(rev), TUSB_REV_MINOR(rev)); - - return tusb_get_revision(musb); } #define WBUS_QUIRK_MASK (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1 \ @@ -350,7 +347,7 @@ static void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) u32 reg; if ((wakeup_enables & TUSB_PRCM_WBUS) - && (tusb_get_revision(musb) == TUSB_REV_30)) + && (musb->tusb_revision == TUSB_REV_30)) tusb_wbus_quirk(musb, 1); tusb_set_clock_source(musb, 0); @@ -798,7 +795,7 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci) u32 reg; u32 i; - if (tusb_get_revision(musb) == TUSB_REV_30) + if (musb->tusb_revision == TUSB_REV_30) tusb_wbus_quirk(musb, 0); /* there are issues re-locking the PLL on wakeup ... */ @@ -1013,10 +1010,10 @@ static int tusb_musb_start(struct musb *musb) } musb->tusb_revision = tusb_get_revision(musb); - ret = tusb_print_revision(musb); - if (ret < 2) { + tusb_print_revision(musb); + if (musb->tusb_revision < 2) { printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n", - ret); + musb->tusb_revision); goto err; } diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h index 1864e24ac965..aec86c86ce32 100644 --- a/drivers/usb/musb/tusb6010.h +++ b/drivers/usb/musb/tusb6010.h @@ -12,8 +12,6 @@ #ifndef __TUSB6010_H__ #define __TUSB6010_H__ -extern u8 tusb_get_revision(struct musb *musb); - #ifdef CONFIG_USB_TUSB_OMAP_DMA #define tusb_dma_omap() 1 #else diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index e33b6b2c44c2..3ce152c0408e 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -677,7 +677,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba tusb_dma->controller.channel_program = tusb_omap_dma_program; tusb_dma->controller.channel_abort = tusb_omap_dma_abort; - if (tusb_get_revision(musb) >= TUSB_REV_30) + if (musb->tusb_revision >= TUSB_REV_30) tusb_dma->multichannel = 1; for (i = 0; i < MAX_DMAREQ; i++) { -- cgit v1.2.3