aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/omap-usb-tll.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/omap-usb-tll.c')
-rw-r--r--drivers/mfd/omap-usb-tll.c243
1 files changed, 134 insertions, 109 deletions
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index eb869153206d..0aef1a768880 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -54,10 +54,13 @@
54 54
55#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) 55#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
56#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 56#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
57#define OMAP_TLL_CHANNEL_CONF_DRVVBUS (1 << 16)
58#define OMAP_TLL_CHANNEL_CONF_CHRGVBUS (1 << 15)
57#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) 59#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
58#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) 60#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
59#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) 61#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
60#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) 62#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
63#define OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI (2 << 1)
61#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) 64#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
62#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) 65#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
63 66
@@ -92,21 +95,25 @@
92#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */ 95#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */
93#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */ 96#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */
94#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */ 97#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */
98#define OMAP_USBTLL_REV4 0x00000006 /* OMAP5 */
95 99
96#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) 100#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
97 101
102/* only PHY and UNUSED modes don't need TLL */
103#define omap_usb_mode_needs_tll(x) ((x) != OMAP_USBHS_PORT_MODE_UNUSED &&\
104 (x) != OMAP_EHCI_PORT_MODE_PHY)
105
98struct usbtll_omap { 106struct usbtll_omap {
99 struct clk *usbtll_p1_fck; 107 int nch; /* num. of channels */
100 struct clk *usbtll_p2_fck; 108 struct usbhs_omap_platform_data *pdata;
101 struct usbtll_omap_platform_data platdata; 109 struct clk **ch_clk;
102 /* secure the register updates */
103 spinlock_t lock;
104}; 110};
105 111
106/*-------------------------------------------------------------------------*/ 112/*-------------------------------------------------------------------------*/
107 113
108const char usbtll_driver_name[] = USBTLL_DRIVER_NAME; 114static const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
109struct platform_device *tll_pdev; 115static struct device *tll_dev;
116static DEFINE_SPINLOCK(tll_lock); /* serialize access to tll_dev */
110 117
111/*-------------------------------------------------------------------------*/ 118/*-------------------------------------------------------------------------*/
112 119
@@ -203,84 +210,84 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
203static int usbtll_omap_probe(struct platform_device *pdev) 210static int usbtll_omap_probe(struct platform_device *pdev)
204{ 211{
205 struct device *dev = &pdev->dev; 212 struct device *dev = &pdev->dev;
206 struct usbtll_omap_platform_data *pdata = dev->platform_data; 213 struct usbhs_omap_platform_data *pdata = dev->platform_data;
207 void __iomem *base; 214 void __iomem *base;
208 struct resource *res; 215 struct resource *res;
209 struct usbtll_omap *tll; 216 struct usbtll_omap *tll;
210 unsigned reg; 217 unsigned reg;
211 unsigned long flags;
212 int ret = 0; 218 int ret = 0;
213 int i, ver, count; 219 int i, ver;
220 bool needs_tll;
214 221
215 dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); 222 dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
216 223
217 tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL); 224 tll = devm_kzalloc(dev, sizeof(struct usbtll_omap), GFP_KERNEL);
218 if (!tll) { 225 if (!tll) {
219 dev_err(dev, "Memory allocation failed\n"); 226 dev_err(dev, "Memory allocation failed\n");
220 ret = -ENOMEM; 227 return -ENOMEM;
221 goto end;
222 } 228 }
223 229
224 spin_lock_init(&tll->lock); 230 if (!pdata) {
225 231 dev_err(dev, "Platform data missing\n");
226 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) 232 return -ENODEV;
227 tll->platdata.port_mode[i] = pdata->port_mode[i];
228
229 tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
230 if (IS_ERR(tll->usbtll_p1_fck)) {
231 ret = PTR_ERR(tll->usbtll_p1_fck);
232 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
233 goto err_tll;
234 } 233 }
235 234
236 tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); 235 tll->pdata = pdata;
237 if (IS_ERR(tll->usbtll_p2_fck)) {
238 ret = PTR_ERR(tll->usbtll_p2_fck);
239 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
240 goto err_usbtll_p1_fck;
241 }
242 236
243 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 237 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
244 if (!res) { 238 base = devm_request_and_ioremap(dev, res);
245 dev_err(dev, "usb tll get resource failed\n");
246 ret = -ENODEV;
247 goto err_usbtll_p2_fck;
248 }
249
250 base = ioremap(res->start, resource_size(res));
251 if (!base) { 239 if (!base) {
252 dev_err(dev, "TLL ioremap failed\n"); 240 ret = -EADDRNOTAVAIL;
253 ret = -ENOMEM; 241 dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
254 goto err_usbtll_p2_fck; 242 return ret;
255 } 243 }
256 244
257 platform_set_drvdata(pdev, tll); 245 platform_set_drvdata(pdev, tll);
258 pm_runtime_enable(dev); 246 pm_runtime_enable(dev);
259 pm_runtime_get_sync(dev); 247 pm_runtime_get_sync(dev);
260 248
261 spin_lock_irqsave(&tll->lock, flags);
262
263 ver = usbtll_read(base, OMAP_USBTLL_REVISION); 249 ver = usbtll_read(base, OMAP_USBTLL_REVISION);
264 switch (ver) { 250 switch (ver) {
265 case OMAP_USBTLL_REV1: 251 case OMAP_USBTLL_REV1:
266 case OMAP_USBTLL_REV2: 252 case OMAP_USBTLL_REV4:
267 count = OMAP_TLL_CHANNEL_COUNT; 253 tll->nch = OMAP_TLL_CHANNEL_COUNT;
268 break; 254 break;
255 case OMAP_USBTLL_REV2:
269 case OMAP_USBTLL_REV3: 256 case OMAP_USBTLL_REV3:
270 count = OMAP_REV2_TLL_CHANNEL_COUNT; 257 tll->nch = OMAP_REV2_TLL_CHANNEL_COUNT;
271 break; 258 break;
272 default: 259 default:
273 dev_err(dev, "TLL version failed\n"); 260 tll->nch = OMAP_TLL_CHANNEL_COUNT;
274 ret = -ENODEV; 261 dev_dbg(dev,
275 goto err_ioremap; 262 "USB TLL Rev : 0x%x not recognized, assuming %d channels\n",
263 ver, tll->nch);
264 break;
276 } 265 }
277 266
278 if (is_ehci_tll_mode(pdata->port_mode[0]) || 267 tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
279 is_ehci_tll_mode(pdata->port_mode[1]) || 268 GFP_KERNEL);
280 is_ehci_tll_mode(pdata->port_mode[2]) || 269 if (!tll->ch_clk) {
281 is_ohci_port(pdata->port_mode[0]) || 270 ret = -ENOMEM;
282 is_ohci_port(pdata->port_mode[1]) || 271 dev_err(dev, "Couldn't allocate memory for channel clocks\n");
283 is_ohci_port(pdata->port_mode[2])) { 272 goto err_clk_alloc;
273 }
274
275 for (i = 0; i < tll->nch; i++) {
276 char clkname[] = "usb_tll_hs_usb_chx_clk";
277
278 snprintf(clkname, sizeof(clkname),
279 "usb_tll_hs_usb_ch%d_clk", i);
280 tll->ch_clk[i] = clk_get(dev, clkname);
281
282 if (IS_ERR(tll->ch_clk[i]))
283 dev_dbg(dev, "can't get clock : %s\n", clkname);
284 }
285
286 needs_tll = false;
287 for (i = 0; i < tll->nch; i++)
288 needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]);
289
290 if (needs_tll) {
284 291
285 /* Program Common TLL register */ 292 /* Program Common TLL register */
286 reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); 293 reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
@@ -292,7 +299,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
292 usbtll_write(base, OMAP_TLL_SHARED_CONF, reg); 299 usbtll_write(base, OMAP_TLL_SHARED_CONF, reg);
293 300
294 /* Enable channels now */ 301 /* Enable channels now */
295 for (i = 0; i < count; i++) { 302 for (i = 0; i < tll->nch; i++) {
296 reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i)); 303 reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i));
297 304
298 if (is_ohci_port(pdata->port_mode[i])) { 305 if (is_ohci_port(pdata->port_mode[i])) {
@@ -308,6 +315,15 @@ static int usbtll_omap_probe(struct platform_device *pdev)
308 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE 315 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
309 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF 316 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
310 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); 317 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
318 } else if (pdata->port_mode[i] ==
319 OMAP_EHCI_PORT_MODE_HSIC) {
320 /*
321 * HSIC Mode requires UTMI port configurations
322 */
323 reg |= OMAP_TLL_CHANNEL_CONF_DRVVBUS
324 | OMAP_TLL_CHANNEL_CONF_CHRGVBUS
325 | OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI
326 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;
311 } else { 327 } else {
312 continue; 328 continue;
313 } 329 }
@@ -320,25 +336,18 @@ static int usbtll_omap_probe(struct platform_device *pdev)
320 } 336 }
321 } 337 }
322 338
323err_ioremap:
324 spin_unlock_irqrestore(&tll->lock, flags);
325 iounmap(base);
326 pm_runtime_put_sync(dev); 339 pm_runtime_put_sync(dev);
327 tll_pdev = pdev; 340 /* only after this can omap_tll_enable/disable work */
328 if (!ret) 341 spin_lock(&tll_lock);
329 goto end; 342 tll_dev = dev;
330 pm_runtime_disable(dev); 343 spin_unlock(&tll_lock);
331 344
332err_usbtll_p2_fck: 345 return 0;
333 clk_put(tll->usbtll_p2_fck);
334
335err_usbtll_p1_fck:
336 clk_put(tll->usbtll_p1_fck);
337 346
338err_tll: 347err_clk_alloc:
339 kfree(tll); 348 pm_runtime_put_sync(dev);
349 pm_runtime_disable(dev);
340 350
341end:
342 return ret; 351 return ret;
343} 352}
344 353
@@ -351,36 +360,42 @@ end:
351static int usbtll_omap_remove(struct platform_device *pdev) 360static int usbtll_omap_remove(struct platform_device *pdev)
352{ 361{
353 struct usbtll_omap *tll = platform_get_drvdata(pdev); 362 struct usbtll_omap *tll = platform_get_drvdata(pdev);
363 int i;
364
365 spin_lock(&tll_lock);
366 tll_dev = NULL;
367 spin_unlock(&tll_lock);
368
369 for (i = 0; i < tll->nch; i++)
370 if (!IS_ERR(tll->ch_clk[i]))
371 clk_put(tll->ch_clk[i]);
354 372
355 clk_put(tll->usbtll_p2_fck);
356 clk_put(tll->usbtll_p1_fck);
357 pm_runtime_disable(&pdev->dev); 373 pm_runtime_disable(&pdev->dev);
358 kfree(tll);
359 return 0; 374 return 0;
360} 375}
361 376
362static int usbtll_runtime_resume(struct device *dev) 377static int usbtll_runtime_resume(struct device *dev)
363{ 378{
364 struct usbtll_omap *tll = dev_get_drvdata(dev); 379 struct usbtll_omap *tll = dev_get_drvdata(dev);
365 struct usbtll_omap_platform_data *pdata = &tll->platdata; 380 struct usbhs_omap_platform_data *pdata = tll->pdata;
366 unsigned long flags; 381 int i;
367 382
368 dev_dbg(dev, "usbtll_runtime_resume\n"); 383 dev_dbg(dev, "usbtll_runtime_resume\n");
369 384
370 if (!pdata) { 385 for (i = 0; i < tll->nch; i++) {
371 dev_dbg(dev, "missing platform_data\n"); 386 if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
372 return -ENODEV; 387 int r;
373 }
374
375 spin_lock_irqsave(&tll->lock, flags);
376 388
377 if (is_ehci_tll_mode(pdata->port_mode[0])) 389 if (IS_ERR(tll->ch_clk[i]))
378 clk_enable(tll->usbtll_p1_fck); 390 continue;
379
380 if (is_ehci_tll_mode(pdata->port_mode[1]))
381 clk_enable(tll->usbtll_p2_fck);
382 391
383 spin_unlock_irqrestore(&tll->lock, flags); 392 r = clk_enable(tll->ch_clk[i]);
393 if (r) {
394 dev_err(dev,
395 "Error enabling ch %d clock: %d\n", i, r);
396 }
397 }
398 }
384 399
385 return 0; 400 return 0;
386} 401}
@@ -388,26 +403,18 @@ static int usbtll_runtime_resume(struct device *dev)
388static int usbtll_runtime_suspend(struct device *dev) 403static int usbtll_runtime_suspend(struct device *dev)
389{ 404{
390 struct usbtll_omap *tll = dev_get_drvdata(dev); 405 struct usbtll_omap *tll = dev_get_drvdata(dev);
391 struct usbtll_omap_platform_data *pdata = &tll->platdata; 406 struct usbhs_omap_platform_data *pdata = tll->pdata;
392 unsigned long flags; 407 int i;
393 408
394 dev_dbg(dev, "usbtll_runtime_suspend\n"); 409 dev_dbg(dev, "usbtll_runtime_suspend\n");
395 410
396 if (!pdata) { 411 for (i = 0; i < tll->nch; i++) {
397 dev_dbg(dev, "missing platform_data\n"); 412 if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
398 return -ENODEV; 413 if (!IS_ERR(tll->ch_clk[i]))
414 clk_disable(tll->ch_clk[i]);
415 }
399 } 416 }
400 417
401 spin_lock_irqsave(&tll->lock, flags);
402
403 if (is_ehci_tll_mode(pdata->port_mode[0]))
404 clk_disable(tll->usbtll_p1_fck);
405
406 if (is_ehci_tll_mode(pdata->port_mode[1]))
407 clk_disable(tll->usbtll_p2_fck);
408
409 spin_unlock_irqrestore(&tll->lock, flags);
410
411 return 0; 418 return 0;
412} 419}
413 420
@@ -429,21 +436,39 @@ static struct platform_driver usbtll_omap_driver = {
429 436
430int omap_tll_enable(void) 437int omap_tll_enable(void)
431{ 438{
432 if (!tll_pdev) { 439 int ret;
433 pr_err("missing omap usbhs tll platform_data\n"); 440
434 return -ENODEV; 441 spin_lock(&tll_lock);
442
443 if (!tll_dev) {
444 pr_err("%s: OMAP USB TLL not initialized\n", __func__);
445 ret = -ENODEV;
446 } else {
447 ret = pm_runtime_get_sync(tll_dev);
435 } 448 }
436 return pm_runtime_get_sync(&tll_pdev->dev); 449
450 spin_unlock(&tll_lock);
451
452 return ret;
437} 453}
438EXPORT_SYMBOL_GPL(omap_tll_enable); 454EXPORT_SYMBOL_GPL(omap_tll_enable);
439 455
440int omap_tll_disable(void) 456int omap_tll_disable(void)
441{ 457{
442 if (!tll_pdev) { 458 int ret;
443 pr_err("missing omap usbhs tll platform_data\n"); 459
444 return -ENODEV; 460 spin_lock(&tll_lock);
461
462 if (!tll_dev) {
463 pr_err("%s: OMAP USB TLL not initialized\n", __func__);
464 ret = -ENODEV;
465 } else {
466 ret = pm_runtime_put_sync(tll_dev);
445 } 467 }
446 return pm_runtime_put_sync(&tll_pdev->dev); 468
469 spin_unlock(&tll_lock);
470
471 return ret;
447} 472}
448EXPORT_SYMBOL_GPL(omap_tll_disable); 473EXPORT_SYMBOL_GPL(omap_tll_disable);
449 474