Эх сурвалжийг харах

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
Linus Torvalds 9 жил өмнө
parent
commit
68dc08b580

+ 11 - 7
Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt

@@ -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 {
-	compatible = "rockchip,rk3288-dp-phy";
-	rockchip,grf = <&grf>;
-	clocks = <&cru SCLK_EDP_24M>;
-	clock-names = "24m";
-	#phy-cells = <0>;
+grf: syscon@ff770000 {
+	compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd";
+
+...
+
+	edp_phy: edp-phy {
+		compatible = "rockchip,rk3288-dp-phy";
+		clocks = <&cru SCLK_EDP_24M>;
+		clock-names = "24m";
+		#phy-cells = <0>;
+	};
 };
 };

+ 14 - 8
Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt

@@ -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 {
-	compatible = "rockchip,rk3399-emmc-phy";
-	rockchip,grf = <&grf>;
-	reg = <0xf780>;
-	#phy-cells = <0>;
+
+grf: syscon@ff770000 {
+	compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+...
+
+	emmcphy: phy@f780 {
+		compatible = "rockchip,rk3399-emmc-phy";
+		reg = <0xf780 0x20>;
+		#phy-cells = <0>;
+	};
 };
 };

+ 5 - 2
drivers/phy/phy-rockchip-dp.c

@@ -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)
 		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);
 	}
 	}
 
 

+ 4 - 1
drivers/phy/phy-rockchip-emmc.c

@@ -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);

+ 22 - 1
drivers/usb/dwc3/core.c

@@ -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)
 
 
 	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)
 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;
 }
 }
 
 

+ 8 - 5
drivers/usb/dwc3/debugfs.c

@@ -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)
 				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)
 				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 @@ err0:
 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);
 }
 }

+ 4 - 8
drivers/usb/dwc3/dwc3-omap.c

@@ -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)
 
 
 	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;

+ 6 - 0
drivers/usb/dwc3/gadget.c

@@ -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)
 	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);
 
 

+ 2 - 0
drivers/usb/gadget/composite.c

@@ -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);

+ 2 - 3
drivers/usb/gadget/function/f_fs.c

@@ -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)
 
 
 	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 &&
-	    !(io_data->kiocb->ki_flags & IOCB_EVENTFD))
+	if (io_data->ffs->ffs_eventfd && !kiocb_has_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);