Skip to content

Commit f5c8a6c

Browse files
Fabrice Gasniergregkh
authored andcommitted
usb: dwc2: add otg_rev and otg_caps information for gadget driver
Currently the dwc2 doesn't fill in the 'otg_caps' of usb_gadget structure. When registering a gadget device (e.g. via configfs), the usb_otg_descriptor_init() checks the 'otg_caps' and 'otg_rev'. It defaults to HNP and SRP bmAttributes if unspecified. There may be a mismatch with what's being set in dwc2 params structure. This result in the descriptors to be miss-configured in this case. So replace 'otg_cap' bit field by 'otg_caps' structure, so hnp, srp and otg_rev' can be configured directly in the params. It's then provided to the gadget struct. These parameters can be tuned for each platform. In case it's not set, it will default to current behavior. Also add option to setup these from the device tree by calling of_usb_update_otg_caps(). This provides support for standard properties such as "otg-rev", "hnp-disable" and "srp-disable" (see usb-drd.yaml). Signed-off-by: Fabrice Gasnier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 924e2b4 commit f5c8a6c

File tree

5 files changed

+57
-52
lines changed

5 files changed

+57
-52
lines changed

drivers/usb/dwc2/core.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,14 @@ enum dwc2_ep0_state {
238238
/**
239239
* struct dwc2_core_params - Parameters for configuring the core
240240
*
241-
* @otg_cap: Specifies the OTG capabilities.
242-
* 0 - HNP and SRP capable
243-
* 1 - SRP Only capable
244-
* 2 - No HNP/SRP capable (always available)
245-
* Defaults to best available option (0, 1, then 2)
241+
* @otg_caps: Specifies the OTG capabilities. OTG caps from the platform parameters,
242+
* used to setup the:
243+
* - HNP and SRP capable
244+
* - SRP Only capable
245+
* - No HNP/SRP capable (always available)
246+
* Defaults to best available option
247+
* - OTG revision number the device is compliant with, in binary-coded
248+
* decimal (i.e. 2.0 is 0200H). (see struct usb_otg_caps)
246249
* @host_dma: Specifies whether to use slave or DMA mode for accessing
247250
* the data FIFOs. The driver will automatically detect the
248251
* value for this parameter if none is specified.
@@ -453,11 +456,7 @@ enum dwc2_ep0_state {
453456
* default described above.
454457
*/
455458
struct dwc2_core_params {
456-
u8 otg_cap;
457-
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
458-
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
459-
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
460-
459+
struct usb_otg_caps otg_caps;
461460
u8 phy_type;
462461
#define DWC2_PHY_TYPE_PARAM_FS 0
463462
#define DWC2_PHY_TYPE_PARAM_UTMI 1

drivers/usb/dwc2/debugfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,9 @@ static int params_show(struct seq_file *seq, void *v)
670670
struct dwc2_core_params *p = &hsotg->params;
671671
int i;
672672

673-
print_param(seq, p, otg_cap);
673+
print_param(seq, p, otg_caps.hnp_support);
674+
print_param(seq, p, otg_caps.srp_support);
675+
print_param(seq, p, otg_caps.otg_rev);
674676
print_param(seq, p, dma_desc_enable);
675677
print_param(seq, p, dma_desc_fs_enable);
676678
print_param(seq, p, speed);

drivers/usb/dwc2/gadget.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4966,6 +4966,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
49664966
hsotg->gadget.max_speed = USB_SPEED_HIGH;
49674967
hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;
49684968
hsotg->gadget.name = dev_name(dev);
4969+
hsotg->gadget.otg_caps = &hsotg->params.otg_caps;
49694970
hsotg->remote_wakeup_allowed = 0;
49704971

49714972
if (hsotg->params.lpm)

drivers/usb/dwc2/hcd.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,15 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
138138

139139
switch (hsotg->hw_params.op_mode) {
140140
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
141-
if (hsotg->params.otg_cap ==
142-
DWC2_CAP_PARAM_HNP_SRP_CAPABLE)
141+
if (hsotg->params.otg_caps.hnp_support &&
142+
hsotg->params.otg_caps.srp_support)
143143
usbcfg |= GUSBCFG_HNPCAP;
144-
if (hsotg->params.otg_cap !=
145-
DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE)
146-
usbcfg |= GUSBCFG_SRPCAP;
147-
break;
144+
fallthrough;
148145

149146
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
150147
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
151148
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
152-
if (hsotg->params.otg_cap !=
153-
DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE)
149+
if (hsotg->params.otg_caps.srp_support)
154150
usbcfg |= GUSBCFG_SRPCAP;
155151
break;
156152

drivers/usb/dwc2/params.c

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/kernel.h>
3737
#include <linux/module.h>
3838
#include <linux/of_device.h>
39+
#include <linux/usb/of.h>
3940

4041
#include "core.h"
4142

@@ -53,7 +54,8 @@ static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
5354
{
5455
struct dwc2_core_params *p = &hsotg->params;
5556

56-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
57+
p->otg_caps.hnp_support = false;
58+
p->otg_caps.srp_support = false;
5759
p->speed = DWC2_SPEED_PARAM_HIGH;
5860
p->host_rx_fifo_size = 512;
5961
p->host_nperio_tx_fifo_size = 512;
@@ -84,7 +86,8 @@ static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg)
8486
{
8587
struct dwc2_core_params *p = &hsotg->params;
8688

87-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
89+
p->otg_caps.hnp_support = false;
90+
p->otg_caps.srp_support = false;
8891
p->host_rx_fifo_size = 525;
8992
p->host_nperio_tx_fifo_size = 128;
9093
p->host_perio_tx_fifo_size = 256;
@@ -97,7 +100,8 @@ static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
97100
{
98101
struct dwc2_core_params *p = &hsotg->params;
99102

100-
p->otg_cap = 2;
103+
p->otg_caps.hnp_support = false;
104+
p->otg_caps.srp_support = false;
101105
p->host_rx_fifo_size = 288;
102106
p->host_nperio_tx_fifo_size = 128;
103107
p->host_perio_tx_fifo_size = 96;
@@ -111,7 +115,8 @@ static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
111115
{
112116
struct dwc2_core_params *p = &hsotg->params;
113117

114-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
118+
p->otg_caps.hnp_support = false;
119+
p->otg_caps.srp_support = false;
115120
p->speed = DWC2_SPEED_PARAM_HIGH;
116121
p->host_rx_fifo_size = 512;
117122
p->host_nperio_tx_fifo_size = 500;
@@ -144,7 +149,8 @@ static void dwc2_set_stm32f4x9_fsotg_params(struct dwc2_hsotg *hsotg)
144149
{
145150
struct dwc2_core_params *p = &hsotg->params;
146151

147-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
152+
p->otg_caps.hnp_support = false;
153+
p->otg_caps.srp_support = false;
148154
p->speed = DWC2_SPEED_PARAM_FULL;
149155
p->host_rx_fifo_size = 128;
150156
p->host_nperio_tx_fifo_size = 96;
@@ -168,7 +174,8 @@ static void dwc2_set_stm32mp15_fsotg_params(struct dwc2_hsotg *hsotg)
168174
{
169175
struct dwc2_core_params *p = &hsotg->params;
170176

171-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
177+
p->otg_caps.hnp_support = false;
178+
p->otg_caps.srp_support = false;
172179
p->speed = DWC2_SPEED_PARAM_FULL;
173180
p->host_rx_fifo_size = 128;
174181
p->host_nperio_tx_fifo_size = 96;
@@ -188,7 +195,8 @@ static void dwc2_set_stm32mp15_hsotg_params(struct dwc2_hsotg *hsotg)
188195
{
189196
struct dwc2_core_params *p = &hsotg->params;
190197

191-
p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
198+
p->otg_caps.hnp_support = false;
199+
p->otg_caps.srp_support = false;
192200
p->activate_stm_id_vb_detection = !device_property_read_bool(hsotg->dev, "usb-role-switch");
193201
p->host_rx_fifo_size = 440;
194202
p->host_nperio_tx_fifo_size = 256;
@@ -241,23 +249,22 @@ MODULE_DEVICE_TABLE(acpi, dwc2_acpi_match);
241249

242250
static void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg)
243251
{
244-
u8 val;
245-
246252
switch (hsotg->hw_params.op_mode) {
247253
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
248-
val = DWC2_CAP_PARAM_HNP_SRP_CAPABLE;
254+
hsotg->params.otg_caps.hnp_support = true;
255+
hsotg->params.otg_caps.srp_support = true;
249256
break;
250257
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
251258
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
252259
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
253-
val = DWC2_CAP_PARAM_SRP_ONLY_CAPABLE;
260+
hsotg->params.otg_caps.hnp_support = false;
261+
hsotg->params.otg_caps.srp_support = true;
254262
break;
255263
default:
256-
val = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
264+
hsotg->params.otg_caps.hnp_support = false;
265+
hsotg->params.otg_caps.srp_support = false;
257266
break;
258267
}
259-
260-
hsotg->params.otg_cap = val;
261268
}
262269

263270
static void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg)
@@ -463,6 +470,8 @@ static void dwc2_get_device_properties(struct dwc2_hsotg *hsotg)
463470
&p->g_tx_fifo_size[1],
464471
num);
465472
}
473+
474+
of_usb_update_otg_caps(hsotg->dev->of_node, &p->otg_caps);
466475
}
467476

468477
if (of_find_property(hsotg->dev->of_node, "disable-over-current", NULL))
@@ -473,29 +482,27 @@ static void dwc2_check_param_otg_cap(struct dwc2_hsotg *hsotg)
473482
{
474483
int valid = 1;
475484

476-
switch (hsotg->params.otg_cap) {
477-
case DWC2_CAP_PARAM_HNP_SRP_CAPABLE:
485+
if (hsotg->params.otg_caps.hnp_support && hsotg->params.otg_caps.srp_support) {
486+
/* check HNP && SRP capable */
478487
if (hsotg->hw_params.op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE)
479488
valid = 0;
480-
break;
481-
case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE:
482-
switch (hsotg->hw_params.op_mode) {
483-
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
484-
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
485-
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
486-
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
487-
break;
488-
default:
489-
valid = 0;
490-
break;
489+
} else if (!hsotg->params.otg_caps.hnp_support) {
490+
/* check SRP only capable */
491+
if (hsotg->params.otg_caps.srp_support) {
492+
switch (hsotg->hw_params.op_mode) {
493+
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
494+
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
495+
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
496+
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
497+
break;
498+
default:
499+
valid = 0;
500+
break;
501+
}
491502
}
492-
break;
493-
case DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE:
494-
/* always valid */
495-
break;
496-
default:
503+
/* else: NO HNP && NO SRP capable: always valid */
504+
} else {
497505
valid = 0;
498-
break;
499506
}
500507

501508
if (!valid)

0 commit comments

Comments
 (0)