Commit 68dc08b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-4.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB / PHY driver fixes from Greg KH:
 "Here are two small sets of patches, both from subsystem trees, USB
  gadget and PHY drivers.

  Full details are in the shortlog, and they have all been in linux-next
  for a while (before I merged them to the USB tree)"

* tag 'usb-4.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: gadget: f_fs: Fix use-after-free
  usb: dwc3: gadget: Fix suspend/resume during device mode
  usb: dwc3: fix memory leak of dwc->regset
  usb: dwc3: core: fix PHY handling during suspend
  usb: dwc3: omap: fix up error path on probe()
  usb: gadget: composite: Clear reserved fields of SSP Dev Cap
  phy: rockchip-emmc: adapt binding to specifiy register offset and length
  phy: rockchip-emmc: should be a child device of the GRF
  phy: rockchip-dp: should be a child device of the GRF
parents 8e3ae37a d40d3347
...@@ -8,15 +8,19 @@ Required properties: ...@@ -8,15 +8,19 @@ Required properties:
of memory mapped region. of memory mapped region.
- clock-names: from common clock binding: - clock-names: from common clock binding:
Required elements: "24m" Required elements: "24m"
- rockchip,grf: phandle to the syscon managing the "general register files"
- #phy-cells : from the generic PHY bindings, must be 0; - #phy-cells : from the generic PHY bindings, must be 0;
Example: Example:
edp_phy: edp-phy { grf: syscon@ff770000 {
compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd";
...
edp_phy: edp-phy {
compatible = "rockchip,rk3288-dp-phy"; compatible = "rockchip,rk3288-dp-phy";
rockchip,grf = <&grf>;
clocks = <&cru SCLK_EDP_24M>; clocks = <&cru SCLK_EDP_24M>;
clock-names = "24m"; clock-names = "24m";
#phy-cells = <0>; #phy-cells = <0>;
};
}; };
...@@ -3,17 +3,23 @@ Rockchip EMMC PHY ...@@ -3,17 +3,23 @@ Rockchip EMMC PHY
Required properties: Required properties:
- compatible: rockchip,rk3399-emmc-phy - compatible: rockchip,rk3399-emmc-phy
- rockchip,grf : phandle to the syscon managing the "general
register files"
- #phy-cells: must be 0 - #phy-cells: must be 0
- reg: PHY configure reg address offset in "general - reg: PHY register address offset and length in "general
register files" register files"
Example: Example:
emmcphy: phy {
grf: syscon@ff770000 {
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
...
emmcphy: phy@f780 {
compatible = "rockchip,rk3399-emmc-phy"; compatible = "rockchip,rk3399-emmc-phy";
rockchip,grf = <&grf>; reg = <0xf780 0x20>;
reg = <0xf780>;
#phy-cells = <0>; #phy-cells = <0>;
};
}; };
...@@ -86,6 +86,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) ...@@ -86,6 +86,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev)
if (!np) if (!np)
return -ENODEV; return -ENODEV;
if (!dev->parent || !dev->parent->of_node)
return -ENODEV;
dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
if (IS_ERR(dp)) if (IS_ERR(dp))
return -ENOMEM; return -ENOMEM;
...@@ -104,9 +107,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) ...@@ -104,9 +107,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev)
return ret; return ret;
} }
dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); dp->grf = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(dp->grf)) { if (IS_ERR(dp->grf)) {
dev_err(dev, "rk3288-dp needs rockchip,grf property\n"); dev_err(dev, "rk3288-dp needs the General Register Files syscon\n");
return PTR_ERR(dp->grf); return PTR_ERR(dp->grf);
} }
......
...@@ -176,7 +176,10 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) ...@@ -176,7 +176,10 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev)
struct regmap *grf; struct regmap *grf;
unsigned int reg_offset; unsigned int reg_offset;
grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); if (!dev->parent || !dev->parent->of_node)
return -ENODEV;
grf = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(grf)) { if (IS_ERR(grf)) {
dev_err(dev, "Missing rockchip,grf property\n"); dev_err(dev, "Missing rockchip,grf property\n");
return PTR_ERR(grf); return PTR_ERR(grf);
......
...@@ -1150,6 +1150,11 @@ static int dwc3_suspend(struct device *dev) ...@@ -1150,6 +1150,11 @@ static int dwc3_suspend(struct device *dev)
phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy); phy_exit(dwc->usb3_generic_phy);
usb_phy_set_suspend(dwc->usb2_phy, 1);
usb_phy_set_suspend(dwc->usb3_phy, 1);
WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0);
WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0);
pinctrl_pm_select_sleep_state(dev); pinctrl_pm_select_sleep_state(dev);
return 0; return 0;
...@@ -1163,11 +1168,21 @@ static int dwc3_resume(struct device *dev) ...@@ -1163,11 +1168,21 @@ static int dwc3_resume(struct device *dev)
pinctrl_pm_select_default_state(dev); pinctrl_pm_select_default_state(dev);
usb_phy_set_suspend(dwc->usb2_phy, 0);
usb_phy_set_suspend(dwc->usb3_phy, 0);
ret = phy_power_on(dwc->usb2_generic_phy);
if (ret < 0)
return ret;
ret = phy_power_on(dwc->usb3_generic_phy);
if (ret < 0)
goto err_usb2phy_power;
usb_phy_init(dwc->usb3_phy); usb_phy_init(dwc->usb3_phy);
usb_phy_init(dwc->usb2_phy); usb_phy_init(dwc->usb2_phy);
ret = phy_init(dwc->usb2_generic_phy); ret = phy_init(dwc->usb2_generic_phy);
if (ret < 0) if (ret < 0)
return ret; goto err_usb3phy_power;
ret = phy_init(dwc->usb3_generic_phy); ret = phy_init(dwc->usb3_generic_phy);
if (ret < 0) if (ret < 0)
...@@ -1200,6 +1215,12 @@ static int dwc3_resume(struct device *dev) ...@@ -1200,6 +1215,12 @@ static int dwc3_resume(struct device *dev)
err_usb2phy_init: err_usb2phy_init:
phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb2_generic_phy);
err_usb3phy_power:
phy_power_off(dwc->usb3_generic_phy);
err_usb2phy_power:
phy_power_off(dwc->usb2_generic_phy);
return ret; return ret;
} }
......
...@@ -645,7 +645,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc) ...@@ -645,7 +645,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
if (!file) { if (!file) {
ret = -ENOMEM; ret = -ENOMEM;
goto err1; goto err2;
} }
if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
...@@ -653,7 +653,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc) ...@@ -653,7 +653,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
dwc, &dwc3_mode_fops); dwc, &dwc3_mode_fops);
if (!file) { if (!file) {
ret = -ENOMEM; ret = -ENOMEM;
goto err1; goto err2;
} }
} }
...@@ -663,19 +663,22 @@ int dwc3_debugfs_init(struct dwc3 *dwc) ...@@ -663,19 +663,22 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
dwc, &dwc3_testmode_fops); dwc, &dwc3_testmode_fops);
if (!file) { if (!file) {
ret = -ENOMEM; ret = -ENOMEM;
goto err1; goto err2;
} }
file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
dwc, &dwc3_link_state_fops); dwc, &dwc3_link_state_fops);
if (!file) { if (!file) {
ret = -ENOMEM; ret = -ENOMEM;
goto err1; goto err2;
} }
} }
return 0; return 0;
err2:
kfree(dwc->regset);
err1: err1:
debugfs_remove_recursive(root); debugfs_remove_recursive(root);
...@@ -686,5 +689,5 @@ int dwc3_debugfs_init(struct dwc3 *dwc) ...@@ -686,5 +689,5 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
void dwc3_debugfs_exit(struct dwc3 *dwc) void dwc3_debugfs_exit(struct dwc3 *dwc)
{ {
debugfs_remove_recursive(dwc->root); debugfs_remove_recursive(dwc->root);
dwc->root = NULL; kfree(dwc->regset);
} }
...@@ -496,7 +496,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) ...@@ -496,7 +496,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "get_sync failed with err %d\n", ret); dev_err(dev, "get_sync failed with err %d\n", ret);
goto err0; goto err1;
} }
dwc3_omap_map_offset(omap); dwc3_omap_map_offset(omap);
...@@ -516,28 +516,24 @@ static int dwc3_omap_probe(struct platform_device *pdev) ...@@ -516,28 +516,24 @@ static int dwc3_omap_probe(struct platform_device *pdev)
ret = dwc3_omap_extcon_register(omap); ret = dwc3_omap_extcon_register(omap);
if (ret < 0) if (ret < 0)
goto err2; goto err1;
ret = of_platform_populate(node, NULL, NULL, dev); ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to create dwc3 core\n"); dev_err(&pdev->dev, "failed to create dwc3 core\n");
goto err3; goto err2;
} }
dwc3_omap_enable_irqs(omap); dwc3_omap_enable_irqs(omap);
return 0; return 0;
err3: err2:
extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb);
extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb);
err2:
dwc3_omap_disable_irqs(omap);
err1: err1:
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
err0:
pm_runtime_disable(dev); pm_runtime_disable(dev);
return ret; return ret;
......
...@@ -2936,6 +2936,9 @@ void dwc3_gadget_exit(struct dwc3 *dwc) ...@@ -2936,6 +2936,9 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
int dwc3_gadget_suspend(struct dwc3 *dwc) int dwc3_gadget_suspend(struct dwc3 *dwc)
{ {
if (!dwc->gadget_driver)
return 0;
if (dwc->pullups_connected) { if (dwc->pullups_connected) {
dwc3_gadget_disable_irq(dwc); dwc3_gadget_disable_irq(dwc);
dwc3_gadget_run_stop(dwc, true, true); dwc3_gadget_run_stop(dwc, true, true);
...@@ -2954,6 +2957,9 @@ int dwc3_gadget_resume(struct dwc3 *dwc) ...@@ -2954,6 +2957,9 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
struct dwc3_ep *dep; struct dwc3_ep *dep;
int ret; int ret;
if (!dwc->gadget_driver)
return 0;
/* Start with SuperSpeed Default */ /* Start with SuperSpeed Default */
dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
......
...@@ -651,6 +651,8 @@ static int bos_desc(struct usb_composite_dev *cdev) ...@@ -651,6 +651,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1);
ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE;
ssp_cap->bReserved = 0;
ssp_cap->wReserved = 0;
/* SSAC = 1 (2 attributes) */ /* SSAC = 1 (2 attributes) */
ssp_cap->bmAttributes = cpu_to_le32(1); ssp_cap->bmAttributes = cpu_to_le32(1);
......
...@@ -646,6 +646,7 @@ static void ffs_user_copy_worker(struct work_struct *work) ...@@ -646,6 +646,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
work); work);
int ret = io_data->req->status ? io_data->req->status : int ret = io_data->req->status ? io_data->req->status :
io_data->req->actual; io_data->req->actual;
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
if (io_data->read && ret > 0) { if (io_data->read && ret > 0) {
use_mm(io_data->mm); use_mm(io_data->mm);
...@@ -657,13 +658,11 @@ static void ffs_user_copy_worker(struct work_struct *work) ...@@ -657,13 +658,11 @@ static void ffs_user_copy_worker(struct work_struct *work)
io_data->kiocb->ki_complete(io_data->kiocb, ret, ret); io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
if (io_data->ffs->ffs_eventfd && if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
!(io_data->kiocb->ki_flags & IOCB_EVENTFD))
eventfd_signal(io_data->ffs->ffs_eventfd, 1); eventfd_signal(io_data->ffs->ffs_eventfd, 1);
usb_ep_free_request(io_data->ep, io_data->req); usb_ep_free_request(io_data->ep, io_data->req);
io_data->kiocb->private = NULL;
if (io_data->read) if (io_data->read)
kfree(io_data->to_free); kfree(io_data->to_free);
kfree(io_data->buf); kfree(io_data->buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment