1 /* 2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved. 3 * Author: Chao Xie <chao.xie@marvell.com> 4 * Neil Zhang <zhangwm@marvell.com> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/clk.h> 16 #include <linux/usb/otg.h> 17 #include <linux/platform_data/mv_usb.h> 18 19 #define CAPLENGTH_MASK (0xff) 20 21 struct ehci_hcd_mv { 22 struct usb_hcd *hcd; 23 24 /* Which mode does this ehci running OTG/Host ? */ 25 int mode; 26 27 void __iomem *phy_regs; 28 void __iomem *cap_regs; 29 void __iomem *op_regs; 30 31 struct usb_phy *otg; 32 33 struct mv_usb_platform_data *pdata; 34 35 /* clock source and total clock number */ 36 unsigned int clknum; 37 struct clk *clk[0]; 38 }; 39 40 static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) 41 { 42 unsigned int i; 43 44 for (i = 0; i < ehci_mv->clknum; i++) 45 clk_enable(ehci_mv->clk[i]); 46 } 47 48 static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) 49 { 50 unsigned int i; 51 52 for (i = 0; i < ehci_mv->clknum; i++) 53 clk_disable(ehci_mv->clk[i]); 54 } 55 56 static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) 57 { 58 int retval; 59 60 ehci_clock_enable(ehci_mv); 61 if (ehci_mv->pdata->phy_init) { 62 retval = ehci_mv->pdata->phy_init(ehci_mv->phy_regs); 63 if (retval) 64 return retval; 65 } 66 67 return 0; 68 } 69 70 static void mv_ehci_disable(struct ehci_hcd_mv *ehci_mv) 71 { 72 if (ehci_mv->pdata->phy_deinit) 73 ehci_mv->pdata->phy_deinit(ehci_mv->phy_regs); 74 ehci_clock_disable(ehci_mv); 75 } 76 77 static int mv_ehci_reset(struct usb_hcd *hcd) 78 { 79 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 80 struct device *dev = hcd->self.controller; 81 struct ehci_hcd_mv *ehci_mv = dev_get_drvdata(dev); 82 int retval; 83 84 if (ehci_mv == NULL) { 85 dev_err(dev, "Can not find private ehci data\n"); 86 return -ENODEV; 87 } 88 89 /* 90 * data structure init 91 */ 92 retval = ehci_init(hcd); 93 if (retval) { 94 dev_err(dev, "ehci_init failed %d\n", retval); 95 return retval; 96 } 97 98 hcd->has_tt = 1; 99 ehci->sbrn = 0x20; 100 101 retval = ehci_reset(ehci); 102 if (retval) { 103 dev_err(dev, "ehci_reset failed %d\n", retval); 104 return retval; 105 } 106 107 return 0; 108 } 109 110 static const struct hc_driver mv_ehci_hc_driver = { 111 .description = hcd_name, 112 .product_desc = "Marvell EHCI", 113 .hcd_priv_size = sizeof(struct ehci_hcd), 114 115 /* 116 * generic hardware linkage 117 */ 118 .irq = ehci_irq, 119 .flags = HCD_MEMORY | HCD_USB2, 120 121 /* 122 * basic lifecycle operations 123 */ 124 .reset = mv_ehci_reset, 125 .start = ehci_run, 126 .stop = ehci_stop, 127 .shutdown = ehci_shutdown, 128 129 /* 130 * managing i/o requests and associated device resources 131 */ 132 .urb_enqueue = ehci_urb_enqueue, 133 .urb_dequeue = ehci_urb_dequeue, 134 .endpoint_disable = ehci_endpoint_disable, 135 .endpoint_reset = ehci_endpoint_reset, 136 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 137 138 /* 139 * scheduling support 140 */ 141 .get_frame_number = ehci_get_frame, 142 143 /* 144 * root hub support 145 */ 146 .hub_status_data = ehci_hub_status_data, 147 .hub_control = ehci_hub_control, 148 .bus_suspend = ehci_bus_suspend, 149 .bus_resume = ehci_bus_resume, 150 }; 151 152 static int mv_ehci_probe(struct platform_device *pdev) 153 { 154 struct mv_usb_platform_data *pdata = pdev->dev.platform_data; 155 struct usb_hcd *hcd; 156 struct ehci_hcd *ehci; 157 struct ehci_hcd_mv *ehci_mv; 158 struct resource *r; 159 int clk_i, retval = -ENODEV; 160 u32 offset; 161 size_t size; 162 163 if (!pdata) { 164 dev_err(&pdev->dev, "missing platform_data\n"); 165 return -ENODEV; 166 } 167 168 if (usb_disabled()) 169 return -ENODEV; 170 171 hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); 172 if (!hcd) 173 return -ENOMEM; 174 175 size = sizeof(*ehci_mv) + sizeof(struct clk *) * pdata->clknum; 176 ehci_mv = kzalloc(size, GFP_KERNEL); 177 if (ehci_mv == NULL) { 178 dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); 179 retval = -ENOMEM; 180 goto err_put_hcd; 181 } 182 183 platform_set_drvdata(pdev, ehci_mv); 184 ehci_mv->pdata = pdata; 185 ehci_mv->hcd = hcd; 186 187 ehci_mv->clknum = pdata->clknum; 188 for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) { 189 ehci_mv->clk[clk_i] = 190 clk_get(&pdev->dev, pdata->clkname[clk_i]); 191 if (IS_ERR(ehci_mv->clk[clk_i])) { 192 dev_err(&pdev->dev, "error get clck \"%s\"\n", 193 pdata->clkname[clk_i]); 194 retval = PTR_ERR(ehci_mv->clk[clk_i]); 195 goto err_put_clk; 196 } 197 } 198 199 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); 200 if (r == NULL) { 201 dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); 202 retval = -ENODEV; 203 goto err_put_clk; 204 } 205 206 ehci_mv->phy_regs = ioremap(r->start, resource_size(r)); 207 if (ehci_mv->phy_regs == 0) { 208 dev_err(&pdev->dev, "failed to map phy I/O memory\n"); 209 retval = -EFAULT; 210 goto err_put_clk; 211 } 212 213 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); 214 if (!r) { 215 dev_err(&pdev->dev, "no I/O memory resource defined\n"); 216 retval = -ENODEV; 217 goto err_iounmap_phyreg; 218 } 219 220 ehci_mv->cap_regs = ioremap(r->start, resource_size(r)); 221 if (ehci_mv->cap_regs == NULL) { 222 dev_err(&pdev->dev, "failed to map I/O memory\n"); 223 retval = -EFAULT; 224 goto err_iounmap_phyreg; 225 } 226 227 retval = mv_ehci_enable(ehci_mv); 228 if (retval) { 229 dev_err(&pdev->dev, "init phy error %d\n", retval); 230 goto err_iounmap_capreg; 231 } 232 233 offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; 234 ehci_mv->op_regs = 235 (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); 236 237 hcd->rsrc_start = r->start; 238 hcd->rsrc_len = r->end - r->start + 1; 239 hcd->regs = ehci_mv->op_regs; 240 241 hcd->irq = platform_get_irq(pdev, 0); 242 if (!hcd->irq) { 243 dev_err(&pdev->dev, "Cannot get irq."); 244 retval = -ENODEV; 245 goto err_disable_clk; 246 } 247 248 ehci = hcd_to_ehci(hcd); 249 ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; 250 ehci->regs = (struct ehci_regs *) ehci_mv->op_regs; 251 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); 252 253 ehci_mv->mode = pdata->mode; 254 if (ehci_mv->mode == MV_USB_MODE_OTG) { 255 #ifdef CONFIG_USB_OTG_UTILS 256 ehci_mv->otg = usb_get_transceiver(); 257 if (!ehci_mv->otg) { 258 dev_err(&pdev->dev, 259 "unable to find transceiver\n"); 260 retval = -ENODEV; 261 goto err_disable_clk; 262 } 263 264 retval = otg_set_host(ehci_mv->otg->otg, &hcd->self); 265 if (retval < 0) { 266 dev_err(&pdev->dev, 267 "unable to register with transceiver\n"); 268 retval = -ENODEV; 269 goto err_put_transceiver; 270 } 271 /* otg will enable clock before use as host */ 272 mv_ehci_disable(ehci_mv); 273 #else 274 dev_info(&pdev->dev, "MV_USB_MODE_OTG " 275 "must have CONFIG_USB_OTG_UTILS enabled\n"); 276 goto err_disable_clk; 277 #endif 278 } else { 279 if (pdata->set_vbus) 280 pdata->set_vbus(1); 281 282 retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); 283 if (retval) { 284 dev_err(&pdev->dev, 285 "failed to add hcd with err %d\n", retval); 286 goto err_set_vbus; 287 } 288 } 289 290 if (pdata->private_init) 291 pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs); 292 293 dev_info(&pdev->dev, 294 "successful find EHCI device with regs 0x%p irq %d" 295 " working in %s mode\n", hcd->regs, hcd->irq, 296 ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); 297 298 return 0; 299 300 err_set_vbus: 301 if (pdata->set_vbus) 302 pdata->set_vbus(0); 303 #ifdef CONFIG_USB_OTG_UTILS 304 err_put_transceiver: 305 if (ehci_mv->otg) 306 usb_put_transceiver(ehci_mv->otg); 307 #endif 308 err_disable_clk: 309 mv_ehci_disable(ehci_mv); 310 err_iounmap_capreg: 311 iounmap(ehci_mv->cap_regs); 312 err_iounmap_phyreg: 313 iounmap(ehci_mv->phy_regs); 314 err_put_clk: 315 for (clk_i--; clk_i >= 0; clk_i--) 316 clk_put(ehci_mv->clk[clk_i]); 317 platform_set_drvdata(pdev, NULL); 318 kfree(ehci_mv); 319 err_put_hcd: 320 usb_put_hcd(hcd); 321 322 return retval; 323 } 324 325 static int mv_ehci_remove(struct platform_device *pdev) 326 { 327 struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); 328 struct usb_hcd *hcd = ehci_mv->hcd; 329 int clk_i; 330 331 if (hcd->rh_registered) 332 usb_remove_hcd(hcd); 333 334 if (ehci_mv->otg) { 335 otg_set_host(ehci_mv->otg->otg, NULL); 336 usb_put_transceiver(ehci_mv->otg); 337 } 338 339 if (ehci_mv->mode == MV_USB_MODE_HOST) { 340 if (ehci_mv->pdata->set_vbus) 341 ehci_mv->pdata->set_vbus(0); 342 343 mv_ehci_disable(ehci_mv); 344 } 345 346 iounmap(ehci_mv->cap_regs); 347 iounmap(ehci_mv->phy_regs); 348 349 for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) 350 clk_put(ehci_mv->clk[clk_i]); 351 352 platform_set_drvdata(pdev, NULL); 353 354 kfree(ehci_mv); 355 usb_put_hcd(hcd); 356 357 return 0; 358 } 359 360 MODULE_ALIAS("mv-ehci"); 361 362 static const struct platform_device_id ehci_id_table[] = { 363 {"pxa-u2oehci", PXA_U2OEHCI}, 364 {"pxa-sph", PXA_SPH}, 365 {"mmp3-hsic", MMP3_HSIC}, 366 {"mmp3-fsic", MMP3_FSIC}, 367 {}, 368 }; 369 370 static void mv_ehci_shutdown(struct platform_device *pdev) 371 { 372 struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); 373 struct usb_hcd *hcd = ehci_mv->hcd; 374 375 if (!hcd->rh_registered) 376 return; 377 378 if (hcd->driver->shutdown) 379 hcd->driver->shutdown(hcd); 380 } 381 382 static struct platform_driver ehci_mv_driver = { 383 .probe = mv_ehci_probe, 384 .remove = mv_ehci_remove, 385 .shutdown = mv_ehci_shutdown, 386 .driver = { 387 .name = "mv-ehci", 388 .bus = &platform_bus_type, 389 }, 390 .id_table = ehci_id_table, 391 }; 392