diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 25 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 3 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 25 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 2 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 3 |
5 files changed, 48 insertions, 10 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 371478704899..4cf77d3c3bd2 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -363,6 +363,7 @@ static void usbhsc_hotplug(struct usbhs_priv *priv) struct usbhs_mod *mod = usbhs_mod_get_current(priv); int id; int enable; + int cable; int ret; /* @@ -376,6 +377,16 @@ static void usbhsc_hotplug(struct usbhs_priv *priv) id = usbhs_platform_call(priv, get_id, pdev); if (enable && !mod) { + if (priv->edev) { + cable = extcon_get_cable_state(priv->edev, "USB-HOST"); + if ((cable > 0 && id != USBHS_HOST) || + (!cable && id != USBHS_GADGET)) { + dev_info(&pdev->dev, + "USB cable plugged in doesn't match the selected role!\n"); + return; + } + } + ret = usbhs_mod_change(priv, id); if (ret < 0) return; @@ -514,6 +525,12 @@ static int usbhs_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + if (of_property_read_bool(pdev->dev.of_node, "extcon")) { + priv->edev = extcon_get_edev_by_phandle(&pdev->dev, 0); + if (IS_ERR(priv->edev)) + return PTR_ERR(priv->edev); + } + /* * care platform info */ @@ -615,7 +632,7 @@ static int usbhs_probe(struct platform_device *pdev) */ ret = usbhs_platform_call(priv, hardware_init, pdev); if (ret < 0) { - dev_err(&pdev->dev, "platform prove failed.\n"); + dev_err(&pdev->dev, "platform init failed.\n"); goto probe_end_mod_exit; } @@ -632,16 +649,12 @@ static int usbhs_probe(struct platform_device *pdev) /* * manual call notify_hotplug for cold plug */ - ret = usbhsc_drvcllbck_notify_hotplug(pdev); - if (ret < 0) - goto probe_end_call_remove; + usbhsc_drvcllbck_notify_hotplug(pdev); dev_info(&pdev->dev, "probed\n"); return ret; -probe_end_call_remove: - usbhs_platform_call(priv, hardware_exit, pdev); probe_end_mod_exit: usbhs_mod_remove(priv); probe_end_fifo_exit: diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 0427cdd1a483..fc96e924edc4 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -17,6 +17,7 @@ #ifndef RENESAS_USB_DRIVER_H #define RENESAS_USB_DRIVER_H +#include <linux/extcon.h> #include <linux/platform_device.h> #include <linux/usb/renesas_usbhs.h> @@ -254,6 +255,8 @@ struct usbhs_priv { struct delayed_work notify_hotplug_work; struct platform_device *pdev; + struct extcon_dev *edev; + spinlock_t lock; u32 flags; diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index f46271ce1b15..d891bff39d66 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -1054,10 +1054,8 @@ static void usbhsf_dma_quit(struct usbhs_priv *priv, struct usbhs_fifo *fifo) fifo->rx_chan = NULL; } -static void usbhsf_dma_init(struct usbhs_priv *priv, - struct usbhs_fifo *fifo) +static void usbhsf_dma_init_pdev(struct usbhs_fifo *fifo) { - struct device *dev = usbhs_priv_to_dev(priv); dma_cap_mask_t mask; dma_cap_zero(mask); @@ -1069,6 +1067,27 @@ static void usbhsf_dma_init(struct usbhs_priv *priv, dma_cap_set(DMA_SLAVE, mask); fifo->rx_chan = dma_request_channel(mask, usbhsf_dma_filter, &fifo->rx_slave); +} + +static void usbhsf_dma_init_dt(struct device *dev, struct usbhs_fifo *fifo) +{ + fifo->tx_chan = dma_request_slave_channel_reason(dev, "tx"); + if (IS_ERR(fifo->tx_chan)) + fifo->tx_chan = NULL; + fifo->rx_chan = dma_request_slave_channel_reason(dev, "rx"); + if (IS_ERR(fifo->rx_chan)) + fifo->rx_chan = NULL; +} + +static void usbhsf_dma_init(struct usbhs_priv *priv, + struct usbhs_fifo *fifo) +{ + struct device *dev = usbhs_priv_to_dev(priv); + + if (dev->of_node) + usbhsf_dma_init_dt(dev, fifo); + else + usbhsf_dma_init_pdev(fifo); if (fifo->tx_chan || fifo->rx_chan) dev_dbg(dev, "enable DMAEngine (%s%s%s)\n", diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 8697e6efcabf..e0384af77e56 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -926,6 +926,8 @@ static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) else usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED); + gadget->is_selfpowered = (is_self != 0); + return 0; } diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index f0d323125871..96eead619282 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1234,7 +1234,8 @@ static int __usbhsh_hub_get_status(struct usbhsh_hpriv *hpriv, desc->bNbrPorts = roothub_id; desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; - desc->wHubCharacteristics = cpu_to_le16(0x0011); + desc->wHubCharacteristics = + cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM); desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); desc->u.hs.DeviceRemovable[1] = ~0; dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); |