0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/device.h>
0022 #include <linux/of_irq.h>
0023 #include <linux/of_address.h>
0024 #include <linux/of_platform.h>
0025
0026 static int uhci_grlib_init(struct usb_hcd *hcd)
0027 {
0028 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 if (!(uhci_readw(uhci, USBPORTSC1) & 0x80)) {
0040 uhci->big_endian_mmio = 1;
0041 uhci->big_endian_desc = 1;
0042 }
0043
0044 uhci->rh_numports = uhci_count_ports(hcd);
0045
0046
0047 uhci->reset_hc = uhci_generic_reset_hc;
0048 uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
0049
0050 uhci->configure_hc = NULL;
0051 uhci->resume_detect_interrupts_are_broken = NULL;
0052 uhci->global_suspend_mode_is_broken = NULL;
0053
0054
0055 check_and_reset_hc(uhci);
0056 return 0;
0057 }
0058
0059 static const struct hc_driver uhci_grlib_hc_driver = {
0060 .description = hcd_name,
0061 .product_desc = "GRLIB GRUSBHC UHCI Host Controller",
0062 .hcd_priv_size = sizeof(struct uhci_hcd),
0063
0064
0065 .irq = uhci_irq,
0066 .flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
0067
0068
0069 .reset = uhci_grlib_init,
0070 .start = uhci_start,
0071 #ifdef CONFIG_PM
0072 .pci_suspend = NULL,
0073 .pci_resume = NULL,
0074 .bus_suspend = uhci_rh_suspend,
0075 .bus_resume = uhci_rh_resume,
0076 #endif
0077 .stop = uhci_stop,
0078
0079 .urb_enqueue = uhci_urb_enqueue,
0080 .urb_dequeue = uhci_urb_dequeue,
0081
0082 .endpoint_disable = uhci_hcd_endpoint_disable,
0083 .get_frame_number = uhci_hcd_get_frame_number,
0084
0085 .hub_status_data = uhci_hub_status_data,
0086 .hub_control = uhci_hub_control,
0087 };
0088
0089
0090 static int uhci_hcd_grlib_probe(struct platform_device *op)
0091 {
0092 struct device_node *dn = op->dev.of_node;
0093 struct usb_hcd *hcd;
0094 struct uhci_hcd *uhci = NULL;
0095 struct resource res;
0096 int irq;
0097 int rv;
0098
0099 if (usb_disabled())
0100 return -ENODEV;
0101
0102 dev_dbg(&op->dev, "initializing GRUSBHC UHCI USB Controller\n");
0103
0104 rv = of_address_to_resource(dn, 0, &res);
0105 if (rv)
0106 return rv;
0107
0108
0109 op->dev.dma_mask = &op->dev.coherent_dma_mask;
0110 hcd = usb_create_hcd(&uhci_grlib_hc_driver, &op->dev,
0111 "GRUSBHC UHCI USB");
0112 if (!hcd)
0113 return -ENOMEM;
0114
0115 hcd->rsrc_start = res.start;
0116 hcd->rsrc_len = resource_size(&res);
0117
0118 irq = irq_of_parse_and_map(dn, 0);
0119 if (irq == NO_IRQ) {
0120 printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
0121 rv = -EBUSY;
0122 goto err_usb;
0123 }
0124
0125 hcd->regs = devm_ioremap_resource(&op->dev, &res);
0126 if (IS_ERR(hcd->regs)) {
0127 rv = PTR_ERR(hcd->regs);
0128 goto err_irq;
0129 }
0130
0131 uhci = hcd_to_uhci(hcd);
0132
0133 uhci->regs = hcd->regs;
0134
0135 rv = usb_add_hcd(hcd, irq, 0);
0136 if (rv)
0137 goto err_irq;
0138
0139 device_wakeup_enable(hcd->self.controller);
0140 return 0;
0141
0142 err_irq:
0143 irq_dispose_mapping(irq);
0144 err_usb:
0145 usb_put_hcd(hcd);
0146
0147 return rv;
0148 }
0149
0150 static int uhci_hcd_grlib_remove(struct platform_device *op)
0151 {
0152 struct usb_hcd *hcd = platform_get_drvdata(op);
0153
0154 dev_dbg(&op->dev, "stopping GRLIB GRUSBHC UHCI USB Controller\n");
0155
0156 usb_remove_hcd(hcd);
0157
0158 irq_dispose_mapping(hcd->irq);
0159 usb_put_hcd(hcd);
0160
0161 return 0;
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171 static void uhci_hcd_grlib_shutdown(struct platform_device *op)
0172 {
0173 struct usb_hcd *hcd = platform_get_drvdata(op);
0174
0175 uhci_hc_died(hcd_to_uhci(hcd));
0176 }
0177
0178 static const struct of_device_id uhci_hcd_grlib_of_match[] = {
0179 { .name = "GAISLER_UHCI", },
0180 { .name = "01_027", },
0181 {},
0182 };
0183 MODULE_DEVICE_TABLE(of, uhci_hcd_grlib_of_match);
0184
0185
0186 static struct platform_driver uhci_grlib_driver = {
0187 .probe = uhci_hcd_grlib_probe,
0188 .remove = uhci_hcd_grlib_remove,
0189 .shutdown = uhci_hcd_grlib_shutdown,
0190 .driver = {
0191 .name = "grlib-uhci",
0192 .of_match_table = uhci_hcd_grlib_of_match,
0193 },
0194 };