@@ -296,6 +296,8 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep)
296296 */
297297void cdns3_hw_reset_eps_config (struct cdns3_device * priv_dev )
298298{
299+ int i ;
300+
299301 writel (USB_CONF_CFGRST , & priv_dev -> regs -> usb_conf );
300302
301303 cdns3_allow_enable_l1 (priv_dev , 0 );
@@ -304,6 +306,10 @@ void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev)
304306 priv_dev -> out_mem_is_allocated = 0 ;
305307 priv_dev -> wait_for_setup = 0 ;
306308 priv_dev -> using_streams = 0 ;
309+
310+ for (i = 0 ; i < CDNS3_ENDPOINTS_MAX_COUNT ; i ++ )
311+ if (priv_dev -> eps [i ])
312+ priv_dev -> eps [i ]-> flags &= ~EP_CONFIGURED ;
307313}
308314
309315/**
@@ -506,7 +512,6 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
506512
507513 while (!list_empty (& priv_ep -> wa2_descmiss_req_list )) {
508514 int chunk_end ;
509- int length ;
510515
511516 descmiss_priv_req =
512517 cdns3_next_priv_request (& priv_ep -> wa2_descmiss_req_list );
@@ -517,7 +522,6 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
517522 break ;
518523
519524 chunk_end = descmiss_priv_req -> flags & REQUEST_INTERNAL_CH ;
520- length = request -> actual + descmiss_req -> actual ;
521525 request -> status = descmiss_req -> status ;
522526 __cdns3_descmiss_copy_data (request , descmiss_req );
523527 list_del_init (& descmiss_priv_req -> list );
@@ -1746,11 +1750,8 @@ static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep)
17461750
17471751static void cdns3_disconnect_gadget (struct cdns3_device * priv_dev )
17481752{
1749- if (priv_dev -> gadget_driver && priv_dev -> gadget_driver -> disconnect ) {
1750- spin_unlock (& priv_dev -> lock );
1753+ if (priv_dev -> gadget_driver && priv_dev -> gadget_driver -> disconnect )
17511754 priv_dev -> gadget_driver -> disconnect (& priv_dev -> gadget );
1752- spin_lock (& priv_dev -> lock );
1753- }
17541755}
17551756
17561757/**
@@ -1761,6 +1762,7 @@ static void cdns3_disconnect_gadget(struct cdns3_device *priv_dev)
17611762 */
17621763static void cdns3_check_usb_interrupt_proceed (struct cdns3_device * priv_dev ,
17631764 u32 usb_ists )
1765+ __must_hold (& priv_dev - > lock )
17641766{
17651767 int speed = 0 ;
17661768
@@ -1785,7 +1787,9 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
17851787
17861788 /* Disconnection detected */
17871789 if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI )) {
1790+ spin_unlock (& priv_dev -> lock );
17881791 cdns3_disconnect_gadget (priv_dev );
1792+ spin_lock (& priv_dev -> lock );
17891793 priv_dev -> gadget .speed = USB_SPEED_UNKNOWN ;
17901794 usb_gadget_set_state (& priv_dev -> gadget , USB_STATE_NOTATTACHED );
17911795 cdns3_hw_reset_eps_config (priv_dev );
@@ -1979,27 +1983,6 @@ static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev,
19791983 return 0 ;
19801984}
19811985
1982- static void cdns3_stream_ep_reconfig (struct cdns3_device * priv_dev ,
1983- struct cdns3_endpoint * priv_ep )
1984- {
1985- if (!priv_ep -> use_streams || priv_dev -> gadget .speed < USB_SPEED_SUPER )
1986- return ;
1987-
1988- if (priv_dev -> dev_ver >= DEV_VER_V3 ) {
1989- u32 mask = BIT (priv_ep -> num + (priv_ep -> dir ? 16 : 0 ));
1990-
1991- /*
1992- * Stream capable endpoints are handled by using ep_tdl
1993- * register. Other endpoints use TDL from TRB feature.
1994- */
1995- cdns3_clear_register_bit (& priv_dev -> regs -> tdl_from_trb , mask );
1996- }
1997-
1998- /* Enable Stream Bit TDL chk and SID chk */
1999- cdns3_set_register_bit (& priv_dev -> regs -> ep_cfg , EP_CFG_STREAM_EN |
2000- EP_CFG_TDL_CHK | EP_CFG_SID_CHK );
2001- }
2002-
20031986static void cdns3_configure_dmult (struct cdns3_device * priv_dev ,
20041987 struct cdns3_endpoint * priv_ep )
20051988{
@@ -2037,8 +2020,9 @@ static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
20372020/**
20382021 * cdns3_ep_config Configure hardware endpoint
20392022 * @priv_ep: extended endpoint object
2023+ * @enable: set EP_CFG_ENABLE bit in ep_cfg register.
20402024 */
2041- void cdns3_ep_config (struct cdns3_endpoint * priv_ep )
2025+ int cdns3_ep_config (struct cdns3_endpoint * priv_ep , bool enable )
20422026{
20432027 bool is_iso_ep = (priv_ep -> type == USB_ENDPOINT_XFER_ISOC );
20442028 struct cdns3_device * priv_dev = priv_ep -> cdns3_dev ;
@@ -2099,7 +2083,7 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
20992083 break ;
21002084 default :
21012085 /* all other speed are not supported */
2102- return ;
2086+ return - EINVAL ;
21032087 }
21042088
21052089 if (max_packet_size == 1024 )
@@ -2109,11 +2093,33 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
21092093 else
21102094 priv_ep -> trb_burst_size = 16 ;
21112095
2112- ret = cdns3_ep_onchip_buffer_reserve (priv_dev , buffering + 1 ,
2113- !!priv_ep -> dir );
2114- if (ret ) {
2115- dev_err (priv_dev -> dev , "onchip mem is full, ep is invalid\n" );
2116- return ;
2096+ /* onchip buffer is only allocated before configuration */
2097+ if (!priv_dev -> hw_configured_flag ) {
2098+ ret = cdns3_ep_onchip_buffer_reserve (priv_dev , buffering + 1 ,
2099+ !!priv_ep -> dir );
2100+ if (ret ) {
2101+ dev_err (priv_dev -> dev , "onchip mem is full, ep is invalid\n" );
2102+ return ret ;
2103+ }
2104+ }
2105+
2106+ if (enable )
2107+ ep_cfg |= EP_CFG_ENABLE ;
2108+
2109+ if (priv_ep -> use_streams && priv_dev -> gadget .speed >= USB_SPEED_SUPER ) {
2110+ if (priv_dev -> dev_ver >= DEV_VER_V3 ) {
2111+ u32 mask = BIT (priv_ep -> num + (priv_ep -> dir ? 16 : 0 ));
2112+
2113+ /*
2114+ * Stream capable endpoints are handled by using ep_tdl
2115+ * register. Other endpoints use TDL from TRB feature.
2116+ */
2117+ cdns3_clear_register_bit (& priv_dev -> regs -> tdl_from_trb ,
2118+ mask );
2119+ }
2120+
2121+ /* Enable Stream Bit TDL chk and SID chk */
2122+ ep_cfg |= EP_CFG_STREAM_EN | EP_CFG_TDL_CHK | EP_CFG_SID_CHK ;
21172123 }
21182124
21192125 ep_cfg |= EP_CFG_MAXPKTSIZE (max_packet_size ) |
@@ -2123,9 +2129,12 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
21232129
21242130 cdns3_select_ep (priv_dev , bEndpointAddress );
21252131 writel (ep_cfg , & priv_dev -> regs -> ep_cfg );
2132+ priv_ep -> flags |= EP_CONFIGURED ;
21262133
21272134 dev_dbg (priv_dev -> dev , "Configure %s: with val %08x\n" ,
21282135 priv_ep -> name , ep_cfg );
2136+
2137+ return 0 ;
21292138}
21302139
21312140/* Find correct direction for HW endpoint according to description */
@@ -2266,7 +2275,7 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
22662275 u32 bEndpointAddress ;
22672276 unsigned long flags ;
22682277 int enable = 1 ;
2269- int ret ;
2278+ int ret = 0 ;
22702279 int val ;
22712280
22722281 priv_ep = ep_to_cdns3_ep (ep );
@@ -2305,6 +2314,17 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23052314 bEndpointAddress = priv_ep -> num | priv_ep -> dir ;
23062315 cdns3_select_ep (priv_dev , bEndpointAddress );
23072316
2317+ /*
2318+ * For some versions of controller at some point during ISO OUT traffic
2319+ * DMA reads Transfer Ring for the EP which has never got doorbell.
2320+ * This issue was detected only on simulation, but to avoid this issue
2321+ * driver add protection against it. To fix it driver enable ISO OUT
2322+ * endpoint before setting DRBL. This special treatment of ISO OUT
2323+ * endpoints are recommended by controller specification.
2324+ */
2325+ if (priv_ep -> type == USB_ENDPOINT_XFER_ISOC && !priv_ep -> dir )
2326+ enable = 0 ;
2327+
23082328 if (usb_ss_max_streams (comp_desc ) && usb_endpoint_xfer_bulk (desc )) {
23092329 /*
23102330 * Enable stream support (SS mode) related interrupts
@@ -2315,13 +2335,17 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23152335 EP_STS_EN_SIDERREN | EP_STS_EN_MD_EXITEN |
23162336 EP_STS_EN_STREAMREN ;
23172337 priv_ep -> use_streams = true;
2318- cdns3_stream_ep_reconfig ( priv_dev , priv_ep );
2338+ ret = cdns3_ep_config ( priv_ep , enable );
23192339 priv_dev -> using_streams |= true;
23202340 }
2341+ } else {
2342+ ret = cdns3_ep_config (priv_ep , enable );
23212343 }
23222344
2323- ret = cdns3_allocate_trb_pool (priv_ep );
2345+ if (ret )
2346+ goto exit ;
23242347
2348+ ret = cdns3_allocate_trb_pool (priv_ep );
23252349 if (ret )
23262350 goto exit ;
23272351
@@ -2351,20 +2375,6 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23512375
23522376 writel (reg , & priv_dev -> regs -> ep_sts_en );
23532377
2354- /*
2355- * For some versions of controller at some point during ISO OUT traffic
2356- * DMA reads Transfer Ring for the EP which has never got doorbell.
2357- * This issue was detected only on simulation, but to avoid this issue
2358- * driver add protection against it. To fix it driver enable ISO OUT
2359- * endpoint before setting DRBL. This special treatment of ISO OUT
2360- * endpoints are recommended by controller specification.
2361- */
2362- if (priv_ep -> type == USB_ENDPOINT_XFER_ISOC && !priv_ep -> dir )
2363- enable = 0 ;
2364-
2365- if (enable )
2366- cdns3_set_register_bit (& priv_dev -> regs -> ep_cfg , EP_CFG_ENABLE );
2367-
23682378 ep -> desc = desc ;
23692379 priv_ep -> flags &= ~(EP_PENDING_REQUEST | EP_STALLED | EP_STALL_PENDING |
23702380 EP_QUIRK_ISO_OUT_EN | EP_QUIRK_EXTRA_BUF_EN );
@@ -3265,10 +3275,13 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
32653275}
32663276
32673277static int cdns3_gadget_suspend (struct cdns3 * cdns , bool do_wakeup )
3278+ __must_hold (& cdns - > lock )
32683279{
32693280 struct cdns3_device * priv_dev = cdns -> gadget_dev ;
32703281
3282+ spin_unlock (& cdns -> lock );
32713283 cdns3_disconnect_gadget (priv_dev );
3284+ spin_lock (& cdns -> lock );
32723285
32733286 priv_dev -> gadget .speed = USB_SPEED_UNKNOWN ;
32743287 usb_gadget_set_state (& priv_dev -> gadget , USB_STATE_NOTATTACHED );
0 commit comments