0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/platform_device.h>
0025 #include <linux/mfd/core.h>
0026 #include <linux/mfd/tmio.h>
0027 #include <linux/dma-mapping.h>
0028
0029
0030
0031
0032
0033
0034 #define CCR_REVID 0x08
0035 #define CCR_BASE 0x10
0036 #define CCR_ILME 0x40
0037 #define CCR_PM 0x4c
0038 #define CCR_INTC 0x50
0039 #define CCR_LMW1L 0x54
0040 #define CCR_LMW1H 0x56
0041 #define CCR_LMW1BL 0x58
0042 #define CCR_LMW1BH 0x5A
0043 #define CCR_LMW2L 0x5C
0044 #define CCR_LMW2H 0x5E
0045 #define CCR_LMW2BL 0x60
0046 #define CCR_LMW2BH 0x62
0047 #define CCR_MISC 0xFC
0048
0049 #define CCR_PM_GKEN 0x0001
0050 #define CCR_PM_CKRNEN 0x0002
0051 #define CCR_PM_USBPW1 0x0004
0052 #define CCR_PM_USBPW2 0x0008
0053 #define CCR_PM_USBPW3 0x0010
0054 #define CCR_PM_PMEE 0x0100
0055 #define CCR_PM_PMES 0x8000
0056
0057
0058
0059 struct tmio_hcd {
0060 void __iomem *ccr;
0061 spinlock_t lock;
0062 };
0063
0064 #define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1))
0065
0066
0067
0068 static void tmio_write_pm(struct platform_device *dev)
0069 {
0070 struct usb_hcd *hcd = platform_get_drvdata(dev);
0071 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0072 u16 pm;
0073 unsigned long flags;
0074
0075 spin_lock_irqsave(&tmio->lock, flags);
0076
0077 pm = CCR_PM_GKEN | CCR_PM_CKRNEN |
0078 CCR_PM_PMEE | CCR_PM_PMES;
0079
0080 tmio_iowrite16(pm, tmio->ccr + CCR_PM);
0081 spin_unlock_irqrestore(&tmio->lock, flags);
0082 }
0083
0084 static void tmio_stop_hc(struct platform_device *dev)
0085 {
0086 struct usb_hcd *hcd = platform_get_drvdata(dev);
0087 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
0088 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0089 u16 pm;
0090
0091 pm = CCR_PM_GKEN | CCR_PM_CKRNEN;
0092 switch (ohci->num_ports) {
0093 default:
0094 dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports);
0095 fallthrough;
0096 case 3:
0097 pm |= CCR_PM_USBPW3;
0098 fallthrough;
0099 case 2:
0100 pm |= CCR_PM_USBPW2;
0101 fallthrough;
0102 case 1:
0103 pm |= CCR_PM_USBPW1;
0104 }
0105 tmio_iowrite8(0, tmio->ccr + CCR_INTC);
0106 tmio_iowrite8(0, tmio->ccr + CCR_ILME);
0107 tmio_iowrite16(0, tmio->ccr + CCR_BASE);
0108 tmio_iowrite16(0, tmio->ccr + CCR_BASE + 2);
0109 tmio_iowrite16(pm, tmio->ccr + CCR_PM);
0110 }
0111
0112 static void tmio_start_hc(struct platform_device *dev)
0113 {
0114 struct usb_hcd *hcd = platform_get_drvdata(dev);
0115 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0116 unsigned long base = hcd->rsrc_start;
0117
0118 tmio_write_pm(dev);
0119 tmio_iowrite16(base, tmio->ccr + CCR_BASE);
0120 tmio_iowrite16(base >> 16, tmio->ccr + CCR_BASE + 2);
0121 tmio_iowrite8(1, tmio->ccr + CCR_ILME);
0122 tmio_iowrite8(2, tmio->ccr + CCR_INTC);
0123
0124 dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n",
0125 tmio_ioread8(tmio->ccr + CCR_REVID),
0126 (u64) hcd->rsrc_start, hcd->irq);
0127 }
0128
0129 static int ohci_tmio_start(struct usb_hcd *hcd)
0130 {
0131 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
0132 int ret;
0133
0134 if ((ret = ohci_init(ohci)) < 0)
0135 return ret;
0136
0137 if ((ret = ohci_run(ohci)) < 0) {
0138 dev_err(hcd->self.controller, "can't start %s\n",
0139 hcd->self.bus_name);
0140 ohci_stop(hcd);
0141 return ret;
0142 }
0143
0144 return 0;
0145 }
0146
0147 static const struct hc_driver ohci_tmio_hc_driver = {
0148 .description = hcd_name,
0149 .product_desc = "TMIO OHCI USB Host Controller",
0150 .hcd_priv_size = sizeof(struct ohci_hcd) + sizeof (struct tmio_hcd),
0151
0152
0153 .irq = ohci_irq,
0154 .flags = HCD_USB11 | HCD_MEMORY,
0155
0156
0157 .start = ohci_tmio_start,
0158 .stop = ohci_stop,
0159 .shutdown = ohci_shutdown,
0160
0161
0162 .urb_enqueue = ohci_urb_enqueue,
0163 .urb_dequeue = ohci_urb_dequeue,
0164 .endpoint_disable = ohci_endpoint_disable,
0165
0166
0167 .get_frame_number = ohci_get_frame,
0168
0169
0170 .hub_status_data = ohci_hub_status_data,
0171 .hub_control = ohci_hub_control,
0172 #ifdef CONFIG_PM
0173 .bus_suspend = ohci_bus_suspend,
0174 .bus_resume = ohci_bus_resume,
0175 #endif
0176 .start_port_reset = ohci_start_port_reset,
0177 };
0178
0179
0180 static struct platform_driver ohci_hcd_tmio_driver;
0181
0182 static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
0183 {
0184 const struct mfd_cell *cell = mfd_get_cell(dev);
0185 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
0186 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
0187 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
0188 int irq = platform_get_irq(dev, 0);
0189 struct tmio_hcd *tmio;
0190 struct ohci_hcd *ohci;
0191 struct usb_hcd *hcd;
0192 int ret;
0193
0194 if (usb_disabled())
0195 return -ENODEV;
0196
0197 if (!cell || !regs || !config || !sram)
0198 return -EINVAL;
0199
0200 if (irq < 0)
0201 return irq;
0202
0203 hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev_name(&dev->dev));
0204 if (!hcd) {
0205 ret = -ENOMEM;
0206 goto err_usb_create_hcd;
0207 }
0208
0209 hcd->rsrc_start = regs->start;
0210 hcd->rsrc_len = resource_size(regs);
0211
0212 tmio = hcd_to_tmio(hcd);
0213
0214 spin_lock_init(&tmio->lock);
0215
0216 tmio->ccr = ioremap(config->start, resource_size(config));
0217 if (!tmio->ccr) {
0218 ret = -ENOMEM;
0219 goto err_ioremap_ccr;
0220 }
0221
0222 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
0223 if (!hcd->regs) {
0224 ret = -ENOMEM;
0225 goto err_ioremap_regs;
0226 }
0227
0228 if (cell->enable) {
0229 ret = cell->enable(dev);
0230 if (ret)
0231 goto err_enable;
0232 }
0233
0234 tmio_start_hc(dev);
0235 ohci = hcd_to_ohci(hcd);
0236 ohci_hcd_init(ohci);
0237
0238 ret = usb_hcd_setup_local_mem(hcd, sram->start, sram->start,
0239 resource_size(sram));
0240 if (ret < 0)
0241 goto err_enable;
0242
0243 ret = usb_add_hcd(hcd, irq, 0);
0244 if (ret)
0245 goto err_add_hcd;
0246
0247 device_wakeup_enable(hcd->self.controller);
0248 if (ret == 0)
0249 return ret;
0250
0251 usb_remove_hcd(hcd);
0252
0253 err_add_hcd:
0254 tmio_stop_hc(dev);
0255 if (cell->disable)
0256 cell->disable(dev);
0257 err_enable:
0258 iounmap(hcd->regs);
0259 err_ioremap_regs:
0260 iounmap(tmio->ccr);
0261 err_ioremap_ccr:
0262 usb_put_hcd(hcd);
0263 err_usb_create_hcd:
0264
0265 return ret;
0266 }
0267
0268 static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
0269 {
0270 struct usb_hcd *hcd = platform_get_drvdata(dev);
0271 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0272 const struct mfd_cell *cell = mfd_get_cell(dev);
0273
0274 usb_remove_hcd(hcd);
0275 tmio_stop_hc(dev);
0276 if (cell->disable)
0277 cell->disable(dev);
0278 iounmap(hcd->regs);
0279 iounmap(tmio->ccr);
0280 usb_put_hcd(hcd);
0281
0282 return 0;
0283 }
0284
0285 #ifdef CONFIG_PM
0286 static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
0287 {
0288 const struct mfd_cell *cell = mfd_get_cell(dev);
0289 struct usb_hcd *hcd = platform_get_drvdata(dev);
0290 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
0291 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0292 unsigned long flags;
0293 u8 misc;
0294 int ret;
0295
0296 if (time_before(jiffies, ohci->next_statechange))
0297 msleep(5);
0298 ohci->next_statechange = jiffies;
0299
0300 spin_lock_irqsave(&tmio->lock, flags);
0301
0302 misc = tmio_ioread8(tmio->ccr + CCR_MISC);
0303 misc |= 1 << 3;
0304 tmio_iowrite8(misc, tmio->ccr + CCR_MISC);
0305
0306 spin_unlock_irqrestore(&tmio->lock, flags);
0307
0308 if (cell->suspend) {
0309 ret = cell->suspend(dev);
0310 if (ret)
0311 return ret;
0312 }
0313 return 0;
0314 }
0315
0316 static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
0317 {
0318 const struct mfd_cell *cell = mfd_get_cell(dev);
0319 struct usb_hcd *hcd = platform_get_drvdata(dev);
0320 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
0321 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
0322 unsigned long flags;
0323 u8 misc;
0324 int ret;
0325
0326 if (time_before(jiffies, ohci->next_statechange))
0327 msleep(5);
0328 ohci->next_statechange = jiffies;
0329
0330 if (cell->resume) {
0331 ret = cell->resume(dev);
0332 if (ret)
0333 return ret;
0334 }
0335
0336 tmio_start_hc(dev);
0337
0338 spin_lock_irqsave(&tmio->lock, flags);
0339
0340 misc = tmio_ioread8(tmio->ccr + CCR_MISC);
0341 misc &= ~(1 << 3);
0342 tmio_iowrite8(misc, tmio->ccr + CCR_MISC);
0343
0344 spin_unlock_irqrestore(&tmio->lock, flags);
0345
0346 ohci_resume(hcd, false);
0347
0348 return 0;
0349 }
0350 #else
0351 #define ohci_hcd_tmio_drv_suspend NULL
0352 #define ohci_hcd_tmio_drv_resume NULL
0353 #endif
0354
0355 static struct platform_driver ohci_hcd_tmio_driver = {
0356 .probe = ohci_hcd_tmio_drv_probe,
0357 .remove = ohci_hcd_tmio_drv_remove,
0358 .shutdown = usb_hcd_platform_shutdown,
0359 .suspend = ohci_hcd_tmio_drv_suspend,
0360 .resume = ohci_hcd_tmio_drv_resume,
0361 .driver = {
0362 .name = "tmio-ohci",
0363 },
0364 };