diff options
Diffstat (limited to 'drivers/usb/gadget/udc/atmel_usba_udc.c')
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index a6426dd1cfef..2b893bceea45 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1056,16 +1056,19 @@ found_ep: switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_CONTROL: + ep->nr_banks = 1; break; case USB_ENDPOINT_XFER_ISOC: ep->fifo_size = 1024; - ep->nr_banks = 2; + if (ep->udc->ep_prealloc) + ep->nr_banks = 2; break; case USB_ENDPOINT_XFER_BULK: ep->fifo_size = 512; - ep->nr_banks = 1; + if (ep->udc->ep_prealloc) + ep->nr_banks = 1; break; case USB_ENDPOINT_XFER_INT: @@ -1075,7 +1078,8 @@ found_ep: else ep->fifo_size = roundup_pow_of_two(le16_to_cpu(desc->wMaxPacketSize)); - ep->nr_banks = 1; + if (ep->udc->ep_prealloc) + ep->nr_banks = 1; break; } @@ -1091,8 +1095,6 @@ found_ep: USBA_BF(EPT_SIZE, fls(ep->fifo_size - 1) - 3); ep->ept_cfg |= USBA_BF(BK_NUMBER, ep->nr_banks); - - ep->udc->configured_ep++; } return _ep; @@ -1786,7 +1788,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (status & USBA_END_OF_RESET) { struct usba_ep *ep0, *ep; - int i, n; + int i; usba_writel(udc, INT_CLR, USBA_END_OF_RESET|USBA_END_OF_RESUME @@ -1834,13 +1836,14 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) "ODD: EP0 configuration is invalid!\n"); /* Preallocate other endpoints */ - n = fifo_mode ? udc->num_ep : udc->configured_ep; - for (i = 1; i < n; i++) { + for (i = 1; i < udc->num_ep; i++) { ep = &udc->usba_ep[i]; - usba_ep_writel(ep, CFG, ep->ept_cfg); - if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) - dev_err(&udc->pdev->dev, - "ODD: EP%d configuration is invalid!\n", i); + if (ep->ep.claimed) { + usba_ep_writel(ep, CFG, ep->ept_cfg); + if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) + dev_err(&udc->pdev->dev, + "ODD: EP%d configuration is invalid!\n", i); + } } } @@ -2025,9 +2028,6 @@ static int atmel_usba_stop(struct usb_gadget *gadget) if (udc->vbus_pin) disable_irq(gpiod_to_irq(udc->vbus_pin)); - if (fifo_mode == 0) - udc->configured_ep = 1; - udc->suspended = false; usba_stop(udc); @@ -2090,33 +2090,51 @@ static const struct usba_udc_config udc_at91sam9rl_cfg = { .errata = &at91sam9rl_errata, .config = ep_config_sam9, .num_ep = ARRAY_SIZE(ep_config_sam9), + .ep_prealloc = true, }; static const struct usba_udc_config udc_at91sam9g45_cfg = { .errata = &at91sam9g45_errata, .config = ep_config_sam9, .num_ep = ARRAY_SIZE(ep_config_sam9), + .ep_prealloc = true, }; static const struct usba_udc_config udc_sama5d3_cfg = { .config = ep_config_sama5, .num_ep = ARRAY_SIZE(ep_config_sama5), + .ep_prealloc = true, +}; + +static const struct usba_udc_config udc_sam9x60_cfg = { + .num_ep = ARRAY_SIZE(ep_config_sam9), + .config = ep_config_sam9, + .ep_prealloc = false, }; static const struct of_device_id atmel_udc_dt_ids[] = { { .compatible = "atmel,at91sam9rl-udc", .data = &udc_at91sam9rl_cfg }, { .compatible = "atmel,at91sam9g45-udc", .data = &udc_at91sam9g45_cfg }, { .compatible = "atmel,sama5d3-udc", .data = &udc_sama5d3_cfg }, + { .compatible = "microchip,sam9x60-udc", .data = &udc_sam9x60_cfg }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids); +static const struct of_device_id atmel_pmc_dt_ids[] = { + { .compatible = "atmel,at91sam9g45-pmc" }, + { .compatible = "atmel,at91sam9rl-pmc" }, + { .compatible = "atmel,at91sam9x5-pmc" }, + { /* sentinel */ } +}; + static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, struct usba_udc *udc) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; + struct device_node *pp; int i, ret; struct usba_ep *eps, *ep; const struct usba_udc_config *udc_config; @@ -2126,14 +2144,19 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, return ERR_PTR(-EINVAL); udc_config = match->data; + udc->ep_prealloc = udc_config->ep_prealloc; udc->errata = udc_config->errata; - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc"); - if (IS_ERR(udc->pmc)) - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9rl-pmc"); - if (IS_ERR(udc->pmc)) - udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9x5-pmc"); - if (udc->errata && IS_ERR(udc->pmc)) - return ERR_CAST(udc->pmc); + if (udc->errata) { + pp = of_find_matching_node_and_match(NULL, atmel_pmc_dt_ids, + NULL); + if (!pp) + return ERR_PTR(-ENODEV); + + udc->pmc = syscon_node_to_regmap(pp); + of_node_put(pp); + if (IS_ERR(udc->pmc)) + return ERR_CAST(udc->pmc); + } udc->num_ep = 0; @@ -2142,7 +2165,6 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, if (fifo_mode == 0) { udc->num_ep = udc_config->num_ep; - udc->configured_ep = 1; } else { udc->num_ep = usba_config_fifo_table(udc); } |