^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic UHCI HCD (Host Controller Driver) for Platform Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011 Tony Prisk <linux@prisktech.co.nz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This file is based on uhci-grlib.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static int uhci_platform_init(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct uhci_hcd *uhci = hcd_to_uhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Probe number of ports if not already provided by DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (!uhci->rh_numports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) uhci->rh_numports = uhci_count_ports(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Set up pointers to to generic functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) uhci->reset_hc = uhci_generic_reset_hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* No special actions need to be taken for the functions below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) uhci->configure_hc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) uhci->resume_detect_interrupts_are_broken = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) uhci->global_suspend_mode_is_broken = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Reset if the controller isn't already safely quiescent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) check_and_reset_hc(uhci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static const struct hc_driver uhci_platform_hc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .description = hcd_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .product_desc = "Generic UHCI Host Controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .hcd_priv_size = sizeof(struct uhci_hcd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Generic hardware linkage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .irq = uhci_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Basic lifecycle operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .reset = uhci_platform_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .start = uhci_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .pci_suspend = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .pci_resume = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .bus_suspend = uhci_rh_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .bus_resume = uhci_rh_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .stop = uhci_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .urb_enqueue = uhci_urb_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .urb_dequeue = uhci_urb_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .endpoint_disable = uhci_hcd_endpoint_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .get_frame_number = uhci_hcd_get_frame_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .hub_status_data = uhci_hub_status_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .hub_control = uhci_hub_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int uhci_hcd_platform_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct uhci_hcd *uhci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (usb_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Right now device-tree probed devices don't get dma_mask set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Since shared usb code relies on it, set it here for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Once we have dma capability bindings this can go away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) pdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) uhci = hcd_to_uhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) hcd->regs = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (IS_ERR(hcd->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret = PTR_ERR(hcd->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) goto err_rmr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hcd->rsrc_start = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) hcd->rsrc_len = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) uhci->regs = hcd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Grab some things from the device-tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u32 num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (of_property_read_u32(np, "#ports", &num_ports) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) uhci->rh_numports = num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dev_info(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) "Detected %d ports from device-tree\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) num_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) uhci->is_aspeed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_info(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) "Enabled Aspeed implementation workarounds\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Get and enable clock if any specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) uhci->clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (IS_ERR(uhci->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = PTR_ERR(uhci->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto err_rmr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = clk_prepare_enable(uhci->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) goto err_rmr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) device_wakeup_enable(hcd->self.controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) clk_disable_unprepare(uhci->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) err_rmr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int uhci_hcd_platform_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct usb_hcd *hcd = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct uhci_hcd *uhci = hcd_to_uhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) clk_disable_unprepare(uhci->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) usb_remove_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Make sure the controller is quiescent and that we're not using it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * any more. This is mainly for the benefit of programs which, like kexec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * expect the hardware to be idle: not doing DMA or generating IRQs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * This routine may be called in a damaged or failing kernel. Hence we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * do not acquire the spinlock before shutting down the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void uhci_hcd_platform_shutdown(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct usb_hcd *hcd = platform_get_drvdata(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) uhci_hc_died(hcd_to_uhci(hcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct of_device_id platform_uhci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { .compatible = "generic-uhci", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { .compatible = "platform-uhci", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) MODULE_DEVICE_TABLE(of, platform_uhci_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct platform_driver uhci_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .probe = uhci_hcd_platform_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .remove = uhci_hcd_platform_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .shutdown = uhci_hcd_platform_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .name = "platform-uhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .of_match_table = platform_uhci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };