mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
USB / PHY driver fixes for 4.6-rc5
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.) Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEABECAAYFAlcbSBAACgkQMUfUDdst+ykzfwCfUUN/z/tOkPladkx8xrnduKgR hNUAoMCdH1F6kit5D2wPJadVSUWNQNkI =85wa -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
68dc08b580
10 changed files with 78 additions and 35 deletions
|
@ -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-dp-phy";
|
compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd";
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
clocks = <&cru SCLK_EDP_24M>;
|
...
|
||||||
clock-names = "24m";
|
|
||||||
#phy-cells = <0>;
|
edp_phy: edp-phy {
|
||||||
|
compatible = "rockchip,rk3288-dp-phy";
|
||||||
|
clocks = <&cru SCLK_EDP_24M>;
|
||||||
|
clock-names = "24m";
|
||||||
|
#phy-cells = <0>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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";
|
grf: syscon@ff770000 {
|
||||||
rockchip,grf = <&grf>;
|
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
|
||||||
reg = <0xf780>;
|
#address-cells = <1>;
|
||||||
#phy-cells = <0>;
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
emmcphy: phy@f780 {
|
||||||
|
compatible = "rockchip,rk3399-emmc-phy";
|
||||||
|
reg = <0xf780 0x20>;
|
||||||
|
#phy-cells = <0>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 @@ 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)
|
||||||
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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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 &&
|
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);
|
||||||
|
|
Loading…
Reference in a new issue