1da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak/* 2da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * EHCI HCD (Host Controller Driver) for USB. 3da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * 4da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus 5da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * Tested on AMCC PPC 440EPx 6da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * 7da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * Valentine Barshak <vbarshak@ru.mvista.com> 8da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * 9da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * Based on "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de> 10da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com> 11da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * 12da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * This file is licenced under the GPL. 13da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 14da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 15da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#include <linux/signal.h> 16da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 17da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#include <linux/of.h> 18da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#include <linux/of_platform.h> 19da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 20da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak/* called during probe() after chip reset completes */ 21da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakstatic int ehci_ppc_of_setup(struct usb_hcd *hcd) 22da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak{ 23da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak struct ehci_hcd *ehci = hcd_to_ehci(hcd); 24da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak int retval; 25da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 26da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak retval = ehci_halt(ehci); 27da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (retval) 28da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return retval; 29da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 30da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak retval = ehci_init(hcd); 31da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (retval) 32da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return retval; 33da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 34da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->sbrn = 0x20; 35da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return ehci_reset(ehci); 36da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak} 37da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 38da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 39da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakstatic const struct hc_driver ehci_ppc_of_hc_driver = { 40da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .description = hcd_name, 41da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .product_desc = "OF EHCI", 42da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .hcd_priv_size = sizeof(struct ehci_hcd), 43da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 44da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* 45da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * generic hardware linkage 46da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 47da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .irq = ehci_irq, 48da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .flags = HCD_MEMORY | HCD_USB2, 49da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 50da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* 51da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * basic lifecycle operations 52da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 53da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .reset = ehci_ppc_of_setup, 54da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .start = ehci_run, 55da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .stop = ehci_stop, 56da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .shutdown = ehci_shutdown, 57da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 58da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* 59da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * managing i/o requests and associated device resources 60da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 61da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .urb_enqueue = ehci_urb_enqueue, 62da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .urb_dequeue = ehci_urb_dequeue, 63da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .endpoint_disable = ehci_endpoint_disable, 64b18ffd49e86102a9ed0a1cc83fdafe3891e844e5Alan Stern .endpoint_reset = ehci_endpoint_reset, 65da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 66da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* 67da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * scheduling support 68da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 69da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .get_frame_number = ehci_get_frame, 70da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 71da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* 72da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * root hub support 73da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 74da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .hub_status_data = ehci_hub_status_data, 75da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .hub_control = ehci_hub_control, 76da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#ifdef CONFIG_PM 77da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .bus_suspend = ehci_bus_suspend, 78da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .bus_resume = ehci_bus_resume, 79da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#endif 80a8e5177583e975fc1f7c621c93956f494df9b979Alan Stern .relinquish_port = ehci_relinquish_port, 813a31155cfff0935e4b178f3dca733d2d60d2eb8dAlan Stern .port_handed_over = ehci_port_handed_over, 82914b701280a76f96890ad63eb0fa99bf204b961cAlan Stern 83914b701280a76f96890ad63eb0fa99bf204b961cAlan Stern .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 84da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak}; 85da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 86da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 87da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak/* 88da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * 440EPx Errata USBH_3 89da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak * Fix: Enable Break Memory Transfer (BMT) in INSNREG3 90da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak */ 91da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0) 92da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakstatic int __devinit 93da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakppc44x_enable_bmt(struct device_node *dn) 94da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak{ 95da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak __iomem u32 *insreg_virt; 96da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 97da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak insreg_virt = of_iomap(dn, 1); 98da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (!insreg_virt) 99da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return -EINVAL; 100da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 101da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak out_be32(insreg_virt + 3, PPC440EPX_EHCI0_INSREG_BMT); 102da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 103da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak iounmap(insreg_virt); 104da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return 0; 105da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak} 106da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 107da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 108d35fb6417655ebf6de93e2135dc386c3c470f545Grant Likelystatic int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op) 109da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak{ 11061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *dn = op->dev.of_node; 111da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak struct usb_hcd *hcd; 112796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug struct ehci_hcd *ehci = NULL; 113da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak struct resource res; 114da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak int irq; 115da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak int rv; 116da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 117796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug struct device_node *np; 118796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug 119da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (usb_disabled()) 120da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return -ENODEV; 121da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 122da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); 123da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 124da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = of_address_to_resource(dn, 0, &res); 125da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (rv) 126da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return rv; 127da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 128da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak hcd = usb_create_hcd(&ehci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); 129da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (!hcd) 130da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return -ENOMEM; 131da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 132da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak hcd->rsrc_start = res.start; 13328f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches hcd->rsrc_len = resource_size(&res); 134da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 135da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 136f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); 137da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = -EBUSY; 138da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak goto err_rmr; 139da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak } 140da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 141da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak irq = irq_of_parse_and_map(dn, 0); 142da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (irq == NO_IRQ) { 143f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); 144da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = -EBUSY; 145da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak goto err_irq; 146da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak } 147da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 148da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 149da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (!hcd->regs) { 150f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches printk(KERN_ERR "%s: ioremap failed\n", __FILE__); 151da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = -ENOMEM; 152da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak goto err_ioremap; 153da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak } 154da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 155da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci = hcd_to_ehci(hcd); 156796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx"); 157796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (np != NULL) { 158796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug /* claim we really affected by usb23 erratum */ 159796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (!of_address_to_resource(np, 0, &res)) 160796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug ehci->ohci_hcctrl_reg = ioremap(res.start + 161796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN); 162796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug else 163f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches pr_debug("%s: no ohci offset in fdt\n", __FILE__); 164796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (!ehci->ohci_hcctrl_reg) { 165f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__); 166796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug } else { 167796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug ehci->has_amcc_usb23 = 1; 168796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug } 169796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug } 170da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 171da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (of_get_property(dn, "big-endian", NULL)) { 172da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->big_endian_mmio = 1; 173da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->big_endian_desc = 1; 174da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak } 175da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (of_get_property(dn, "big-endian-regs", NULL)) 176da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->big_endian_mmio = 1; 177da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (of_get_property(dn, "big-endian-desc", NULL)) 178da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->big_endian_desc = 1; 179da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 180da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->caps = hcd->regs; 181da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->regs = hcd->regs + 182c430131a02d677aa708f56342c1565edfdacb3c0Jan Andersson HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); 183da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 184da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak /* cache this readonly data; minimize chip reads */ 185da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); 186da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 187da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (of_device_is_compatible(dn, "ibm,usb-ehci-440epx")) { 188da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = ppc44x_enable_bmt(dn); 189da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak ehci_dbg(ehci, "Break Memory Transfer (BMT) is %senabled!\n", 190da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv ? "NOT ": ""); 191da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak } 192da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 193da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak rv = usb_add_hcd(hcd, irq, 0); 19408a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter if (rv) 19508a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter goto err_ehci; 19608a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter 19708a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter return 0; 198da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 19908a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpentererr_ehci: 20008a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter if (ehci->has_amcc_usb23) 20108a3b3b1c2e622e378d9086aee9e2e42ce37591dDan Carpenter iounmap(ehci->ohci_hcctrl_reg); 202da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak iounmap(hcd->regs); 203da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakerr_ioremap: 204da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak irq_dispose_mapping(irq); 205da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakerr_irq: 206da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 207da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshakerr_rmr: 208da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak usb_put_hcd(hcd); 209da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 210da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return rv; 211da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak} 212da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 213da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 2142dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int ehci_hcd_ppc_of_remove(struct platform_device *op) 215da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak{ 216da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak struct usb_hcd *hcd = dev_get_drvdata(&op->dev); 217796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug struct ehci_hcd *ehci = hcd_to_ehci(hcd); 218796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug 219796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug struct device_node *np; 220796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug struct resource res; 221796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug 222da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak dev_set_drvdata(&op->dev, NULL); 223da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 224da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); 225da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 226da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak usb_remove_hcd(hcd); 227da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 228da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak iounmap(hcd->regs); 229da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak irq_dispose_mapping(hcd->irq); 230da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 231da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 232796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug /* use request_mem_region to test if the ohci driver is loaded. if so 233796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug * ensure the ohci core is operational. 234796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug */ 235796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (ehci->has_amcc_usb23) { 236796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx"); 237796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (np != NULL) { 238796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (!of_address_to_resource(np, 0, &res)) 239796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug if (!request_mem_region(res.start, 240796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug 0x4, hcd_name)) 241796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug set_ohci_hcfs(ehci, 1); 242796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug else 243796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug release_mem_region(res.start, 0x4); 244796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug else 245f45ba776da4fe6c9a9eddd42b0fd5d1f15c260f3Joe Perches pr_debug("%s: no ohci offset in fdt\n", __FILE__); 246796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug of_node_put(np); 247796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug } 248796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug 249796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug iounmap(ehci->ohci_hcctrl_reg); 250796bcae7361c28cf825780f6f1aac9dd3411394eVitaly Bordug } 251da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak usb_put_hcd(hcd); 252da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 253da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak return 0; 254da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak} 255da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 256da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 257d35fb6417655ebf6de93e2135dc386c3c470f545Grant Likelystatic void ehci_hcd_ppc_of_shutdown(struct platform_device *op) 258da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak{ 259da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak struct usb_hcd *hcd = dev_get_drvdata(&op->dev); 260da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 261da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak if (hcd->driver->shutdown) 262da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak hcd->driver->shutdown(hcd); 263da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak} 264da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 265da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 266c4386ad07c318ae6188190e63b517ecc5ee3c883Németh Mártonstatic const struct of_device_id ehci_hcd_ppc_of_match[] = { 267da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak { 268da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .compatible = "usb-ehci", 269da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak }, 270da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak {}, 271da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak}; 272da0e8fb00b862aa10265f0c64930b432cd44420bValentine BarshakMODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); 273da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 274da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak 275d35fb6417655ebf6de93e2135dc386c3c470f545Grant Likelystatic struct platform_driver ehci_hcd_ppc_of_driver = { 276da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .probe = ehci_hcd_ppc_of_probe, 277da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .remove = ehci_hcd_ppc_of_remove, 278da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak .shutdown = ehci_hcd_ppc_of_shutdown, 2794018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 2804018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = "ppc-of-ehci", 2814018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 2824018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = ehci_hcd_ppc_of_match, 283da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak }, 284da0e8fb00b862aa10265f0c64930b432cd44420bValentine Barshak}; 285