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