diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 02:48:26 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 02:48:26 +0300 |
commit | d3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396 (patch) | |
tree | 2072b4977f2e22f0b51bd7e48f131c48c14e896d /drivers/usb/gadget/udc | |
parent | 6181073dd6a7e5deafc60e7981bd765b6c93da8c (diff) | |
parent | 00988f70a0763f14c97c4c0df76fb9aa4959e953 (diff) | |
download | linux-d3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396.tar.xz |
Merge tag 'usb-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt updates from Greg KH:
"Here is the big set of USB and Thunderbolt driver changes for 6.1-rc1.
Nothing major in here, lots of little things with new devices
supported and updates for a few drivers. Highlights include:
- thunderbolt/USB4 devices supported a bit better than before, and
some new ids to enable new hardware devices
- USB gadget uvc updates for newer video formats and better v4l
integration (the v4l portions were acked by those maintainers)
- typec updates for tiny issues and more typec drivers for new chips.
- xhci tiny updates for minor issues
- big usb-serial ftdi_sio driver update to handle new devices better
- lots of tiny dwc3 fixes and updates for the IP block that is
showing up everywhere these days
- dts updates for new devices being supported
- other tiny janitorial and cleanups fixes for lots of different USB
drivers. Full details are in the shortlog.
All of these have been in linux-next for a while with no reported
issues"
* tag 'usb-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (169 commits)
usb: gadget: uvc: don't put item still in use
usb: gadget: uvc: Fix argument to sizeof() in uvc_register_video()
usb: host: ehci-exynos: switch to using gpiod API
Revert "usb: dwc3: Don't switch OTG -> peripheral if extcon is present"
Revert "USB: fixup for merge issue with "usb: dwc3: Don't switch OTG -> peripheral if extcon is present""
dt-bindings: usb: Convert FOTG210 to dt schema
usb: mtu3: fix failed runtime suspend in host only mode
USB: omap_udc: Fix spelling mistake: "tranceiver_ctrl" -> "transceiver_ctrl"
usb: typec: ucsi_ccg: Disable UCSI ALT support on Tegra
usb: typec: Replace custom implementation of device_match_fwnode()
usb: typec: ucsi: Don't warn on probe deferral
usb: add quirks for Lenovo OneLink+ Dock
MAINTAINERS: switch dwc3 to Thinh
usb: idmouse: fix an uninit-value in idmouse_open
USB: PHY: JZ4770: Switch to use dev_err_probe() helper
usb: phy: generic: Switch to use dev_err_probe() helper
usb: ulpi: use DEFINE_SHOW_ATTRIBUTE to simplify ulpi_regs
usb: cdns3: remove dead code
usb: cdc-wdm: Use skb_put_data() instead of skb_put/memcpy pair
usb: musb: sunxi: Switch to use dev_err_probe() helper
...
Diffstat (limited to 'drivers/usb/gadget/udc')
-rw-r--r-- | drivers/usb/gadget/udc/at91_udc.c | 10 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/net2272.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/omap_udc.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/renesas_usb3.c | 131 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/s3c2410_udc.c | 78 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/s3c2410_udc.h | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/tegra-xudc.c | 6 |
7 files changed, 154 insertions, 82 deletions
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 728987280373..a9a7b3fc60ec 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -994,7 +994,7 @@ static const struct usb_gadget_ops at91_udc_ops = { .udc_stop = at91_stop, /* - * VBUS-powered devices may also also want to support bigger + * VBUS-powered devices may also want to support bigger * power budgets after an appropriate SET_CONFIGURATION. */ /* .vbus_power = at91_vbus_power, */ @@ -1779,12 +1779,14 @@ static void at91udc_of_init(struct at91_udc *udc, struct device_node *np) if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0) board->vbus_polled = 1; - board->vbus_pin = gpiod_get_from_of_node(np, "atmel,vbus-gpio", 0, - GPIOD_IN, "udc_vbus"); + board->vbus_pin = fwnode_gpiod_get_index(of_fwnode_handle(np), + "atmel,vbus", 0, GPIOD_IN, + "udc_vbus"); if (IS_ERR(board->vbus_pin)) board->vbus_pin = NULL; - board->pullup_pin = gpiod_get_from_of_node(np, "atmel,pullup-gpio", 0, + board->pullup_pin = fwnode_gpiod_get_index(of_fwnode_handle(np), + "atmel,pullup", 0, GPIOD_ASIS, "udc_pullup"); if (IS_ERR(board->pullup_pin)) board->pullup_pin = NULL; diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index c97cd4bc817c..84605a4d0715 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -91,7 +91,7 @@ module_param(dma_mode, ushort, 0644); * mode 2 == ep-a 1k, ep-b 1k, ep-c 512db * mode 3 == ep-a 1k, ep-b disabled, ep-c 512db */ -static ushort fifo_mode = 0; +static ushort fifo_mode; module_param(fifo_mode, ushort, 0644); /* @@ -100,7 +100,7 @@ module_param(fifo_mode, ushort, 0644); * USB suspend requests will be ignored. This is acceptable for * self-powered devices. For bus powered devices set this to 1. */ -static ushort enable_suspend = 0; +static ushort enable_suspend; module_param(enable_suspend, ushort, 0644); static void assert_out_naking(struct net2272_ep *ep, const char *where) diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 61cabb9de6ae..bea346e362b2 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -2234,7 +2234,7 @@ static int proc_otg_show(struct seq_file *s) char *ctrl_name = "(UNKNOWN)"; tmp = omap_readl(OTG_REV); - ctrl_name = "tranceiver_ctrl"; + ctrl_name = "transceiver_ctrl"; trans = omap_readw(USB_TRANSCEIVER_CTRL); seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", tmp >> 4, tmp & 0xf, ctrl_name, trans); @@ -2558,7 +2558,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, /* set up driver data structures */ BUG_ON(strlen(name) >= sizeof ep->name); - strlcpy(ep->name, name, sizeof ep->name); + strscpy(ep->name, name, sizeof(ep->name)); INIT_LIST_HEAD(&ep->queue); INIT_LIST_HEAD(&ep->iso); ep->bEndpointAddress = addr; diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 648be3fd476a..615ba0a6fbee 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -17,6 +17,7 @@ #include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/sizes.h> #include <linux/slab.h> #include <linux/string.h> @@ -38,16 +39,16 @@ #define USB3_USB20_CON 0x204 #define USB3_USB30_CON 0x208 #define USB3_USB_STA 0x210 -#define USB3_DRD_CON 0x218 +#define USB3_DRD_CON(p) ((p)->is_rzv2m ? 0x400 : 0x218) #define USB3_USB_INT_STA_1 0x220 #define USB3_USB_INT_STA_2 0x224 #define USB3_USB_INT_ENA_1 0x228 #define USB3_USB_INT_ENA_2 0x22c #define USB3_STUP_DAT_0 0x230 #define USB3_STUP_DAT_1 0x234 -#define USB3_USB_OTG_STA 0x268 -#define USB3_USB_OTG_INT_STA 0x26c -#define USB3_USB_OTG_INT_ENA 0x270 +#define USB3_USB_OTG_STA(p) ((p)->is_rzv2m ? 0x410 : 0x268) +#define USB3_USB_OTG_INT_STA(p) ((p)->is_rzv2m ? 0x414 : 0x26c) +#define USB3_USB_OTG_INT_ENA(p) ((p)->is_rzv2m ? 0x418 : 0x270) #define USB3_P0_MOD 0x280 #define USB3_P0_CON 0x288 #define USB3_P0_STA 0x28c @@ -135,6 +136,8 @@ #define USB_STA_VBUS_STA BIT(0) /* DRD_CON */ +#define DRD_CON_PERI_RST BIT(31) /* rzv2m only */ +#define DRD_CON_HOST_RST BIT(30) /* rzv2m only */ #define DRD_CON_PERI_CON BIT(24) #define DRD_CON_VBOUT BIT(0) @@ -155,7 +158,7 @@ #define USB_INT_2_PIPE(n) BIT(n) /* USB_OTG_STA, USB_OTG_INT_STA and USB_OTG_INT_ENA */ -#define USB_OTG_IDMON BIT(4) +#define USB_OTG_IDMON(p) ((p)->is_rzv2m ? BIT(0) : BIT(4)) /* P0_MOD */ #define P0_MOD_DIR BIT(6) @@ -255,7 +258,7 @@ #define USB3_EP0_SS_MAX_PACKET_SIZE 512 #define USB3_EP0_HSFS_MAX_PACKET_SIZE 64 #define USB3_EP0_BUF_SIZE 8 -#define USB3_MAX_NUM_PIPES 6 /* This includes PIPE 0 */ +#define USB3_MAX_NUM_PIPES(p) ((p)->is_rzv2m ? 16 : 6) /* This includes PIPE 0 */ #define USB3_WAIT_US 3 #define USB3_DMA_NUM_SETTING_AREA 4 /* @@ -326,10 +329,13 @@ struct renesas_usb3_priv { int num_ramif; int ramsize_per_pipe; /* unit = bytes */ bool workaround_for_vbus; /* if true, don't check vbus signal */ + bool is_rzv2m; /* if true, RZ/V2M SoC */ }; struct renesas_usb3 { void __iomem *reg; + struct reset_control *drd_rstc; + struct reset_control *usbp_rstc; struct usb_gadget gadget; struct usb_gadget_driver *driver; @@ -363,6 +369,7 @@ struct renesas_usb3 { bool forced_b_device; bool start_to_connect; bool role_sw_by_connector; + bool is_rzv2m; }; #define gadget_to_renesas_usb3(_gadget) \ @@ -467,7 +474,7 @@ static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num) static bool usb3_is_host(struct renesas_usb3 *usb3) { - return !(usb3_read(usb3, USB3_DRD_CON) & DRD_CON_PERI_CON); + return !(usb3_read(usb3, USB3_DRD_CON(usb3)) & DRD_CON_PERI_CON); } static void usb3_init_axi_bridge(struct renesas_usb3 *usb3) @@ -674,10 +681,20 @@ static void renesas_usb3_role_work(struct work_struct *work) static void usb3_set_mode(struct renesas_usb3 *usb3, bool host) { + if (usb3->is_rzv2m) { + if (host) { + usb3_set_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); + usb3_clear_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); + } else { + usb3_set_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); + usb3_clear_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); + } + } + if (host) - usb3_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); + usb3_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); else - usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); + usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); } static void usb3_set_mode_by_role_sw(struct renesas_usb3 *usb3, bool host) @@ -693,9 +710,9 @@ static void usb3_set_mode_by_role_sw(struct renesas_usb3 *usb3, bool host) static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable) { if (enable) - usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON); + usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); else - usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON); + usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); } static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) @@ -716,7 +733,7 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) static bool usb3_is_a_device(struct renesas_usb3 *usb3) { - return !(usb3_read(usb3, USB3_USB_OTG_STA) & USB_OTG_IDMON); + return !(usb3_read(usb3, USB3_USB_OTG_STA(usb3)) & USB_OTG_IDMON(usb3)); } static void usb3_check_id(struct renesas_usb3 *usb3) @@ -739,8 +756,8 @@ static void renesas_usb3_init_controller(struct renesas_usb3 *usb3) usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL | USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP, USB3_USB_COM_CON); - usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_STA); - usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_ENA); + usb3_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_STA(usb3)); + usb3_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_ENA(usb3)); usb3_check_id(usb3); usb3_check_vbus(usb3); @@ -750,7 +767,7 @@ static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3) { usb3_disconnect(usb3); usb3_write(usb3, 0, USB3_P0_INT_ENA); - usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA); + usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA(usb3)); usb3_write(usb3, 0, USB3_USB_INT_ENA_1); usb3_write(usb3, 0, USB3_USB_INT_ENA_2); usb3_write(usb3, 0, USB3_AXI_INT_ENA); @@ -2005,9 +2022,15 @@ static void usb3_irq_idmon_change(struct renesas_usb3 *usb3) usb3_check_id(usb3); } -static void usb3_irq_otg_int(struct renesas_usb3 *usb3, u32 otg_int_sta) +static void usb3_irq_otg_int(struct renesas_usb3 *usb3) { - if (otg_int_sta & USB_OTG_IDMON) + u32 otg_int_sta = usb3_read(usb3, USB3_USB_OTG_INT_STA(usb3)); + + otg_int_sta &= usb3_read(usb3, USB3_USB_OTG_INT_ENA(usb3)); + if (otg_int_sta) + usb3_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA(usb3)); + + if (otg_int_sta & USB_OTG_IDMON(usb3)) usb3_irq_idmon_change(usb3); } @@ -2015,7 +2038,6 @@ static void usb3_irq_epc(struct renesas_usb3 *usb3) { u32 int_sta_1 = usb3_read(usb3, USB3_USB_INT_STA_1); u32 int_sta_2 = usb3_read(usb3, USB3_USB_INT_STA_2); - u32 otg_int_sta = usb3_read(usb3, USB3_USB_OTG_INT_STA); int_sta_1 &= usb3_read(usb3, USB3_USB_INT_ENA_1); if (int_sta_1) { @@ -2027,11 +2049,8 @@ static void usb3_irq_epc(struct renesas_usb3 *usb3) if (int_sta_2) usb3_irq_epc_int_2(usb3, int_sta_2); - otg_int_sta &= usb3_read(usb3, USB3_USB_OTG_INT_ENA); - if (otg_int_sta) { - usb3_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA); - usb3_irq_otg_int(usb3, otg_int_sta); - } + if (!usb3->is_rzv2m) + usb3_irq_otg_int(usb3); } static void usb3_irq_dma_int(struct renesas_usb3 *usb3, u32 dma_sta) @@ -2085,6 +2104,15 @@ static irqreturn_t renesas_usb3_irq(int irq, void *_usb3) return ret; } +static irqreturn_t renesas_usb3_otg_irq(int irq, void *_usb3) +{ + struct renesas_usb3 *usb3 = _usb3; + + usb3_irq_otg_int(usb3); + + return IRQ_HANDLED; +} + static void usb3_write_pn_mod(struct renesas_usb3_ep *usb3_ep, const struct usb_endpoint_descriptor *desc) { @@ -2571,6 +2599,8 @@ static int renesas_usb3_remove(struct platform_device *pdev) usb_role_switch_unregister(usb3->role_sw); usb_del_gadget_udc(&usb3->gadget); + reset_control_assert(usb3->usbp_rstc); + reset_control_assert(usb3->drd_rstc); renesas_usb3_dma_free_prd(usb3, &pdev->dev); __renesas_usb3_ep_free_request(usb3->ep0_req); @@ -2589,8 +2619,8 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, usb3->num_usb3_eps = priv->ramsize_per_ramif * priv->num_ramif * 2 / priv->ramsize_per_pipe + 1; - if (usb3->num_usb3_eps > USB3_MAX_NUM_PIPES) - usb3->num_usb3_eps = USB3_MAX_NUM_PIPES; + if (usb3->num_usb3_eps > USB3_MAX_NUM_PIPES(usb3)) + usb3->num_usb3_eps = USB3_MAX_NUM_PIPES(usb3); usb3->usb3_ep = devm_kcalloc(dev, usb3->num_usb3_eps, sizeof(*usb3_ep), @@ -2707,6 +2737,13 @@ static const struct renesas_usb3_priv renesas_usb3_priv_r8a77990 = { .workaround_for_vbus = true, }; +static const struct renesas_usb3_priv renesas_usb3_priv_rzv2m = { + .ramsize_per_ramif = SZ_16K, + .num_ramif = 1, + .ramsize_per_pipe = SZ_4K, + .is_rzv2m = true, +}; + static const struct of_device_id usb3_of_match[] = { { .compatible = "renesas,r8a774c0-usb3-peri", @@ -2718,6 +2755,9 @@ static const struct of_device_id usb3_of_match[] = { .compatible = "renesas,r8a77990-usb3-peri", .data = &renesas_usb3_priv_r8a77990, }, { + .compatible = "renesas,rzv2m-usb3-peri", + .data = &renesas_usb3_priv_rzv2m, + }, { .compatible = "renesas,rcar-gen3-usb3-peri", .data = &renesas_usb3_priv_gen3, }, @@ -2748,7 +2788,7 @@ static struct usb_role_switch_desc renesas_usb3_role_switch_desc = { static int renesas_usb3_probe(struct platform_device *pdev) { struct renesas_usb3 *usb3; - int irq, ret; + int irq, drd_irq, ret; const struct renesas_usb3_priv *priv; const struct soc_device_attribute *attr; @@ -2762,10 +2802,18 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (irq < 0) return irq; + if (priv->is_rzv2m) { + drd_irq = platform_get_irq_byname(pdev, "drd"); + if (drd_irq < 0) + return drd_irq; + } + usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); if (!usb3) return -ENOMEM; + usb3->is_rzv2m = priv->is_rzv2m; + usb3->reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(usb3->reg)) return PTR_ERR(usb3->reg); @@ -2787,6 +2835,14 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (ret < 0) return ret; + if (usb3->is_rzv2m) { + ret = devm_request_irq(&pdev->dev, drd_irq, + renesas_usb3_otg_irq, 0, + dev_name(&pdev->dev), usb3); + if (ret < 0) + return ret; + } + INIT_WORK(&usb3->extcon_work, renesas_usb3_extcon_work); usb3->extcon = devm_extcon_dev_allocate(&pdev->dev, renesas_usb3_cable); if (IS_ERR(usb3->extcon)) @@ -2817,10 +2873,27 @@ static int renesas_usb3_probe(struct platform_device *pdev) goto err_add_udc; } + usb3->drd_rstc = devm_reset_control_get_optional_shared(&pdev->dev, + "drd_reset"); + if (IS_ERR(usb3->drd_rstc)) { + ret = PTR_ERR(usb3->drd_rstc); + goto err_add_udc; + } + + usb3->usbp_rstc = devm_reset_control_get_optional_shared(&pdev->dev, + "aresetn_p"); + if (IS_ERR(usb3->usbp_rstc)) { + ret = PTR_ERR(usb3->usbp_rstc); + goto err_add_udc; + } + + reset_control_deassert(usb3->drd_rstc); + reset_control_deassert(usb3->usbp_rstc); + pm_runtime_enable(&pdev->dev); ret = usb_add_gadget_udc(&pdev->dev, &usb3->gadget); if (ret < 0) - goto err_add_udc; + goto err_reset; ret = device_create_file(&pdev->dev, &dev_attr_role); if (ret < 0) @@ -2858,6 +2931,10 @@ static int renesas_usb3_probe(struct platform_device *pdev) err_dev_create: usb_del_gadget_udc(&usb3->gadget); +err_reset: + reset_control_assert(usb3->usbp_rstc); + reset_control_assert(usb3->drd_rstc); + err_add_udc: renesas_usb3_dma_free_prd(usb3, &pdev->dev); diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index c6625aeb7bca..8c57b191e52b 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -23,7 +23,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/clk.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/prefetch.h> #include <linux/io.h> @@ -1419,8 +1419,7 @@ static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on) { dprintk(DEBUG_NORMAL, "%s()\n", __func__); - if (udc_info && (udc_info->udc_command || - gpio_is_valid(udc_info->pullup_pin))) { + if (udc_info && (udc_info->udc_command || udc->pullup_gpiod)) { if (is_on) s3c2410_udc_enable(udc); @@ -1467,9 +1466,7 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) dprintk(DEBUG_NORMAL, "%s()\n", __func__); - value = gpio_get_value(udc_info->vbus_pin) ? 1 : 0; - if (udc_info->vbus_pin_inverted) - value = !value; + value = gpiod_get_value(dev->vbus_gpiod); if (value != dev->vbus) s3c2410_udc_vbus_session(&dev->gadget, value); @@ -1504,14 +1501,15 @@ static const struct usb_gadget_ops s3c2410_ops = { .udc_stop = s3c2410_udc_stop, }; -static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) +static void s3c2410_udc_command(struct s3c2410_udc *udc, + enum s3c2410_udc_cmd_e cmd) { if (!udc_info) return; if (udc_info->udc_command) { udc_info->udc_command(cmd); - } else if (gpio_is_valid(udc_info->pullup_pin)) { + } else if (udc->pullup_gpiod) { int value; switch (cmd) { @@ -1524,9 +1522,8 @@ static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) default: return; } - value ^= udc_info->pullup_pin_inverted; - gpio_set_value(udc_info->pullup_pin, value); + gpiod_set_value(udc->pullup_gpiod, value); } } @@ -1551,7 +1548,7 @@ static void s3c2410_udc_disable(struct s3c2410_udc *dev) udc_write(0x1F, S3C2410_UDC_EP_INT_REG); /* Good bye, cruel world */ - s3c2410_udc_command(S3C2410_UDC_P_DISABLE); + s3c2410_udc_command(dev, S3C2410_UDC_P_DISABLE); /* Set speed to unknown */ dev->gadget.speed = USB_SPEED_UNKNOWN; @@ -1613,7 +1610,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG); /* time to say "hello, world" */ - s3c2410_udc_command(S3C2410_UDC_P_ENABLE); + s3c2410_udc_command(dev, S3C2410_UDC_P_ENABLE); } static int s3c2410_udc_start(struct usb_gadget *g, @@ -1802,14 +1799,15 @@ static int s3c2410_udc_probe(struct platform_device *pdev) dev_dbg(dev, "got irq %i\n", irq_usbd); - if (udc_info && udc_info->vbus_pin > 0) { - retval = gpio_request(udc_info->vbus_pin, "udc vbus"); - if (retval < 0) { - dev_err(dev, "cannot claim vbus pin\n"); - goto err_int; - } + udc->vbus_gpiod = gpiod_get_optional(dev, "vbus", GPIOD_IN); + if (IS_ERR(udc->vbus_gpiod)) { + retval = PTR_ERR(udc->vbus_gpiod); + goto err_int; + } + if (udc->vbus_gpiod) { + gpiod_set_consumer_name(udc->vbus_gpiod, "udc vbus"); - irq = gpio_to_irq(udc_info->vbus_pin); + irq = gpiod_to_irq(udc->vbus_gpiod); if (irq < 0) { dev_err(dev, "no irq for gpio vbus pin\n"); retval = irq; @@ -1833,16 +1831,12 @@ static int s3c2410_udc_probe(struct platform_device *pdev) udc->vbus = 1; } - if (udc_info && !udc_info->udc_command && - gpio_is_valid(udc_info->pullup_pin)) { - - retval = gpio_request_one(udc_info->pullup_pin, - udc_info->vbus_pin_inverted ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, - "udc pullup"); - if (retval) - goto err_vbus_irq; + udc->pullup_gpiod = gpiod_get_optional(dev, "pullup", GPIOD_OUT_LOW); + if (IS_ERR(udc->pullup_gpiod)) { + retval = PTR_ERR(udc->pullup_gpiod); + goto err_vbus_irq; } + gpiod_set_consumer_name(udc->pullup_gpiod, "udc pullup"); retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (retval) @@ -1856,15 +1850,10 @@ static int s3c2410_udc_probe(struct platform_device *pdev) return 0; err_add_udc: - if (udc_info && !udc_info->udc_command && - gpio_is_valid(udc_info->pullup_pin)) - gpio_free(udc_info->pullup_pin); err_vbus_irq: - if (udc_info && udc_info->vbus_pin > 0) - free_irq(gpio_to_irq(udc_info->vbus_pin), udc); + if (udc->vbus_gpiod) + free_irq(gpiod_to_irq(udc->vbus_gpiod), udc); err_gpio_claim: - if (udc_info && udc_info->vbus_pin > 0) - gpio_free(udc_info->vbus_pin); err_int: free_irq(irq_usbd, udc); err_udc_clk: @@ -1885,7 +1874,6 @@ err_usb_bus_clk: static int s3c2410_udc_remove(struct platform_device *pdev) { struct s3c2410_udc *udc = platform_get_drvdata(pdev); - unsigned int irq; dev_dbg(&pdev->dev, "%s()\n", __func__); @@ -1895,14 +1883,8 @@ static int s3c2410_udc_remove(struct platform_device *pdev) usb_del_gadget_udc(&udc->gadget); debugfs_remove(debugfs_lookup("registers", s3c2410_udc_debugfs_root)); - if (udc_info && !udc_info->udc_command && - gpio_is_valid(udc_info->pullup_pin)) - gpio_free(udc_info->pullup_pin); - - if (udc_info && udc_info->vbus_pin > 0) { - irq = gpio_to_irq(udc_info->vbus_pin); - free_irq(irq, udc); - } + if (udc->vbus_gpiod) + free_irq(gpiod_to_irq(udc->vbus_gpiod), udc); free_irq(irq_usbd, udc); @@ -1926,14 +1908,18 @@ static int s3c2410_udc_remove(struct platform_device *pdev) static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message) { - s3c2410_udc_command(S3C2410_UDC_P_DISABLE); + struct s3c2410_udc *udc = platform_get_drvdata(pdev); + + s3c2410_udc_command(udc, S3C2410_UDC_P_DISABLE); return 0; } static int s3c2410_udc_resume(struct platform_device *pdev) { - s3c2410_udc_command(S3C2410_UDC_P_ENABLE); + struct s3c2410_udc *udc = platform_get_drvdata(pdev); + + s3c2410_udc_command(udc, S3C2410_UDC_P_ENABLE); return 0; } diff --git a/drivers/usb/gadget/udc/s3c2410_udc.h b/drivers/usb/gadget/udc/s3c2410_udc.h index 135a5bff3c74..cdbf202e5ee8 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.h +++ b/drivers/usb/gadget/udc/s3c2410_udc.h @@ -83,6 +83,9 @@ struct s3c2410_udc { u32 port_status; int ep0state; + struct gpio_desc *vbus_gpiod; + struct gpio_desc *pullup_gpiod; + unsigned got_irq : 1; unsigned req_std : 1; diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 3c37effdfa64..76919d7570d2 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -2,7 +2,7 @@ /* * NVIDIA Tegra XUSB device mode controller * - * Copyright (c) 2013-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2013-2022, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2015, Google Inc. */ @@ -702,6 +702,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc) pm_runtime_get_sync(xudc->dev); + tegra_phy_xusb_utmi_pad_power_on(xudc->curr_utmi_phy); + err = phy_power_on(xudc->curr_utmi_phy); if (err < 0) dev_err(xudc->dev, "UTMI power on failed: %d\n", err); @@ -756,6 +758,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc) /* Make sure interrupt handler has completed before powergating. */ synchronize_irq(xudc->irq); + tegra_phy_xusb_utmi_pad_power_down(xudc->curr_utmi_phy); + err = phy_power_off(xudc->curr_utmi_phy); if (err < 0) dev_err(xudc->dev, "UTMI PHY power off failed: %d\n", err); |