X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fusb%2Fdwc3%2Fcore.c;h=87b9c87edf6a0348d84b90d839160babfa896e11;hb=022ceacaf8a6a67f86f0a5ed8f6ce6b2f6ab73a4;hp=78322b736b4920f13bbbdab89ac0c8a7e24738a1;hpb=71744d0d06fd078207c527f362fcc66c93228d36;p=oweals%2Fu-boot.git diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 78322b736b..87b9c87edf 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -28,9 +29,10 @@ #include "linux-compat.h" +static LIST_HEAD(dwc3_list); /* -------------------------------------------------------------------------- */ -void dwc3_set_mode(struct dwc3 *dwc, u32 mode) +static void dwc3_set_mode(struct dwc3 *dwc, u32 mode) { u32 reg; @@ -120,6 +122,8 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, if (!evt->buf) return ERR_PTR(-ENOMEM); + dwc3_flush_cache((uintptr_t)evt->buf, evt->length); + return evt; } @@ -155,8 +159,8 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) num = DWC3_NUM_INT(dwc->hwparams.hwparams1); dwc->num_event_buffers = num; - dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num, - GFP_KERNEL); + dwc->ev_buffs = memalign(CONFIG_SYS_CACHELINE_SIZE, + sizeof(*dwc->ev_buffs) * num); if (!dwc->ev_buffs) return -ENOMEM; @@ -279,7 +283,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc) return 0; err1: - dma_unmap_single((void *)dwc->scratch_addr, dwc->nr_scratch * + dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL); err0: @@ -294,7 +298,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc) if (!dwc->nr_scratch) return; - dma_unmap_single((void *)dwc->scratch_addr, dwc->nr_scratch * + dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL); kfree(dwc->scratchbuf); } @@ -597,20 +601,27 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) #define DWC3_ALIGN_MASK (16 - 1) -static int dwc3_probe(struct platform_device *pdev) +/** + * dwc3_uboot_init - dwc3 core uboot initialization code + * @dwc3_dev: struct dwc3_device containing initialization data + * + * Entry point for dwc3 driver (equivalent to dwc3_probe in linux + * kernel driver). Pointer to dwc3_device should be passed containing + * base address and other initialization data. Returns '0' on success and + * a negative value on failure. + * + * Generally called from board_usb_init() implemented in board file. + */ +int dwc3_uboot_init(struct dwc3_device *dwc3_dev) { - struct device *dev = &pdev->dev; - struct dwc3_platform_data *pdata = dev_get_platdata(dev); - struct device_node *node = dev->of_node; - struct resource *res; struct dwc3 *dwc; + struct device *dev = NULL; u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; int ret; - void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); @@ -619,48 +630,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; - dwc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "missing IRQ\n"); - return -ENODEV; - } - dwc->xhci_resources[1].start = res->start; - dwc->xhci_resources[1].end = res->end; - dwc->xhci_resources[1].flags = res->flags; - dwc->xhci_resources[1].name = res->name; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing memory resource\n"); - return -ENODEV; - } - - dwc->xhci_resources[0].start = res->start; - dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + - DWC3_XHCI_REGS_END; - dwc->xhci_resources[0].flags = res->flags; - dwc->xhci_resources[0].name = res->name; - - res->start += DWC3_GLOBALS_REGS_START; - - /* - * Request memory region but exclude xHCI regs, - * since it will be requested by the xhci-plat driver. - */ - regs = devm_ioremap_resource(dev, res); - if (IS_ERR(regs)) - return PTR_ERR(regs); - - dwc->regs = regs; - dwc->regs_size = resource_size(res); - /* - * restore res->start back to its original value so that, - * in case the probe is deferred, we don't end up getting error in - * request the memory region the next time probe is called. - */ - res->start -= DWC3_GLOBALS_REGS_START; + dwc->regs = (void *)(uintptr_t)(dwc3_dev->base + + DWC3_GLOBALS_REGS_START); /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; @@ -674,73 +646,31 @@ static int dwc3_probe(struct platform_device *pdev) */ hird_threshold = 12; - if (node) { - dwc->maximum_speed = of_usb_get_maximum_speed(node); - dwc->has_lpm_erratum = of_property_read_bool(node, - "snps,has-lpm-erratum"); - of_property_read_u8(node, "snps,lpm-nyet-threshold", - &lpm_nyet_threshold); - dwc->is_utmi_l1_suspend = of_property_read_bool(node, - "snps,is-utmi-l1-suspend"); - of_property_read_u8(node, "snps,hird-threshold", - &hird_threshold); - - dwc->needs_fifo_resize = of_property_read_bool(node, - "tx-fifo-resize"); - dwc->dr_mode = of_usb_get_dr_mode(node); - - dwc->disable_scramble_quirk = of_property_read_bool(node, - "snps,disable_scramble_quirk"); - dwc->u2exit_lfps_quirk = of_property_read_bool(node, - "snps,u2exit_lfps_quirk"); - dwc->u2ss_inp3_quirk = of_property_read_bool(node, - "snps,u2ss_inp3_quirk"); - dwc->req_p1p2p3_quirk = of_property_read_bool(node, - "snps,req_p1p2p3_quirk"); - dwc->del_p1p2p3_quirk = of_property_read_bool(node, - "snps,del_p1p2p3_quirk"); - dwc->del_phy_power_chg_quirk = of_property_read_bool(node, - "snps,del_phy_power_chg_quirk"); - dwc->lfps_filter_quirk = of_property_read_bool(node, - "snps,lfps_filter_quirk"); - dwc->rx_detect_poll_quirk = of_property_read_bool(node, - "snps,rx_detect_poll_quirk"); - dwc->dis_u3_susphy_quirk = of_property_read_bool(node, - "snps,dis_u3_susphy_quirk"); - dwc->dis_u2_susphy_quirk = of_property_read_bool(node, - "snps,dis_u2_susphy_quirk"); - - dwc->tx_de_emphasis_quirk = of_property_read_bool(node, - "snps,tx_de_emphasis_quirk"); - of_property_read_u8(node, "snps,tx_de_emphasis", - &tx_de_emphasis); - } else if (pdata) { - dwc->maximum_speed = pdata->maximum_speed; - dwc->has_lpm_erratum = pdata->has_lpm_erratum; - if (pdata->lpm_nyet_threshold) - lpm_nyet_threshold = pdata->lpm_nyet_threshold; - dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend; - if (pdata->hird_threshold) - hird_threshold = pdata->hird_threshold; - - dwc->needs_fifo_resize = pdata->tx_fifo_resize; - dwc->dr_mode = pdata->dr_mode; - - dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; - dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; - dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; - dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; - dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; - dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; - dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; - dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; - dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; - dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; - - dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; - if (pdata->tx_de_emphasis) - tx_de_emphasis = pdata->tx_de_emphasis; - } + dwc->maximum_speed = dwc3_dev->maximum_speed; + dwc->has_lpm_erratum = dwc3_dev->has_lpm_erratum; + if (dwc3_dev->lpm_nyet_threshold) + lpm_nyet_threshold = dwc3_dev->lpm_nyet_threshold; + dwc->is_utmi_l1_suspend = dwc3_dev->is_utmi_l1_suspend; + if (dwc3_dev->hird_threshold) + hird_threshold = dwc3_dev->hird_threshold; + + dwc->needs_fifo_resize = dwc3_dev->tx_fifo_resize; + dwc->dr_mode = dwc3_dev->dr_mode; + + dwc->disable_scramble_quirk = dwc3_dev->disable_scramble_quirk; + dwc->u2exit_lfps_quirk = dwc3_dev->u2exit_lfps_quirk; + dwc->u2ss_inp3_quirk = dwc3_dev->u2ss_inp3_quirk; + dwc->req_p1p2p3_quirk = dwc3_dev->req_p1p2p3_quirk; + dwc->del_p1p2p3_quirk = dwc3_dev->del_p1p2p3_quirk; + dwc->del_phy_power_chg_quirk = dwc3_dev->del_phy_power_chg_quirk; + dwc->lfps_filter_quirk = dwc3_dev->lfps_filter_quirk; + dwc->rx_detect_poll_quirk = dwc3_dev->rx_detect_poll_quirk; + dwc->dis_u3_susphy_quirk = dwc3_dev->dis_u3_susphy_quirk; + dwc->dis_u2_susphy_quirk = dwc3_dev->dis_u2_susphy_quirk; + + dwc->tx_de_emphasis_quirk = dwc3_dev->tx_de_emphasis_quirk; + if (dwc3_dev->tx_de_emphasis) + tx_de_emphasis = dwc3_dev->tx_de_emphasis; /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) @@ -752,14 +682,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); - spin_lock_init(&dwc->lock); - platform_set_drvdata(pdev, dwc); - - if (!dev->dma_mask) { - dev->dma_mask = dev->parent->dma_mask; - dev->dma_parms = dev->parent->dma_parms; - dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); - } + dwc->index = dwc3_dev->index; dwc3_cache_hwparams(dwc); @@ -793,6 +716,8 @@ static int dwc3_probe(struct platform_device *pdev) if (ret) goto err2; + list_add_tail(&dwc->list, &dwc3_list); + return 0; err2: @@ -807,55 +732,56 @@ err0: return ret; } -static int dwc3_remove(struct platform_device *pdev) +/** + * dwc3_uboot_exit - dwc3 core uboot cleanup code + * @index: index of this controller + * + * Performs cleanup of memory allocated in dwc3_uboot_init and other misc + * cleanups (equivalent to dwc3_remove in linux). index of _this_ controller + * should be passed and should match with the index passed in + * dwc3_device during init. + * + * Generally called from board file. + */ +void dwc3_uboot_exit(int index) { - struct dwc3 *dwc = platform_get_drvdata(pdev); + struct dwc3 *dwc; + + list_for_each_entry(dwc, &dwc3_list, list) { + if (dwc->index != index) + continue; + + dwc3_core_exit_mode(dwc); + dwc3_event_buffers_cleanup(dwc); + dwc3_free_event_buffers(dwc); + dwc3_core_exit(dwc); + list_del(&dwc->list); + kfree(dwc->mem); + break; + } +} - dwc3_core_exit_mode(dwc); - dwc3_event_buffers_cleanup(dwc); - dwc3_free_event_buffers(dwc); +/** + * dwc3_uboot_handle_interrupt - handle dwc3 core interrupt + * @index: index of this controller + * + * Invokes dwc3 gadget interrupts. + * + * Generally called from board file. + */ +void dwc3_uboot_handle_interrupt(int index) +{ + struct dwc3 *dwc = NULL; - dwc3_core_exit(dwc); + list_for_each_entry(dwc, &dwc3_list, list) { + if (dwc->index != index) + continue; - return 0; + dwc3_gadget_uboot_handle_interrupt(dwc); + break; + } } -#ifdef CONFIG_OF -static const struct of_device_id of_dwc3_match[] = { - { - .compatible = "snps,dwc3" - }, - { - .compatible = "synopsys,dwc3" - }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_dwc3_match); -#endif - -#ifdef CONFIG_ACPI - -#define ACPI_ID_INTEL_BSW "808622B7" - -static const struct acpi_device_id dwc3_acpi_match[] = { - { ACPI_ID_INTEL_BSW, 0 }, - { }, -}; -MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match); -#endif - -static struct platform_driver dwc3_driver = { - .probe = dwc3_probe, - .remove = dwc3_remove, - .driver = { - .name = "dwc3", - .of_match_table = of_match_ptr(of_dwc3_match), - .acpi_match_table = ACPI_PTR(dwc3_acpi_match), - }, -}; - -module_platform_driver(dwc3_driver); - MODULE_ALIAS("platform:dwc3"); MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("GPL v2");