.. | .. |
---|
12 | 12 | #include <linux/spinlock.h> |
---|
13 | 13 | #include <linux/platform_device.h> |
---|
14 | 14 | #include <linux/interrupt.h> |
---|
| 15 | +#include <linux/iopoll.h> |
---|
15 | 16 | #include <linux/ioport.h> |
---|
16 | 17 | #include <linux/io.h> |
---|
17 | 18 | #include <linux/list.h> |
---|
.. | .. |
---|
29 | 30 | #include "bdc_dbg.h" |
---|
30 | 31 | |
---|
31 | 32 | /* Poll till controller status is not OIP */ |
---|
32 | | -static int poll_oip(struct bdc *bdc, int usec) |
---|
| 33 | +static int poll_oip(struct bdc *bdc, u32 usec) |
---|
33 | 34 | { |
---|
34 | 35 | u32 status; |
---|
35 | | - /* Poll till STS!= OIP */ |
---|
36 | | - while (usec) { |
---|
37 | | - status = bdc_readl(bdc->regs, BDC_BDCSC); |
---|
38 | | - if (BDC_CSTS(status) != BDC_OIP) { |
---|
39 | | - dev_dbg(bdc->dev, |
---|
40 | | - "poll_oip complete status=%d", |
---|
41 | | - BDC_CSTS(status)); |
---|
42 | | - return 0; |
---|
43 | | - } |
---|
44 | | - udelay(10); |
---|
45 | | - usec -= 10; |
---|
46 | | - } |
---|
47 | | - dev_err(bdc->dev, "Err: operation timedout BDCSC: 0x%08x\n", status); |
---|
| 36 | + int ret; |
---|
48 | 37 | |
---|
49 | | - return -ETIMEDOUT; |
---|
| 38 | + ret = readl_poll_timeout(bdc->regs + BDC_BDCSC, status, |
---|
| 39 | + (BDC_CSTS(status) != BDC_OIP), 10, usec); |
---|
| 40 | + if (ret) |
---|
| 41 | + dev_err(bdc->dev, "operation timedout BDCSC: 0x%08x\n", status); |
---|
| 42 | + else |
---|
| 43 | + dev_dbg(bdc->dev, "%s complete status=%d", __func__, BDC_CSTS(status)); |
---|
| 44 | + |
---|
| 45 | + return ret; |
---|
50 | 46 | } |
---|
51 | 47 | |
---|
52 | 48 | /* Stop the BDC controller */ |
---|
.. | .. |
---|
172 | 168 | /* Refer to BDC spec, Table 4 for description of SPB */ |
---|
173 | 169 | sp_buff_size = 1 << (sp_buff_size + 5); |
---|
174 | 170 | dev_dbg(bdc->dev, "Allocating %d bytes for scratchpad\n", sp_buff_size); |
---|
175 | | - bdc->scratchpad.buff = dma_zalloc_coherent(bdc->dev, sp_buff_size, |
---|
176 | | - &bdc->scratchpad.sp_dma, GFP_KERNEL); |
---|
| 171 | + bdc->scratchpad.buff = dma_alloc_coherent(bdc->dev, sp_buff_size, |
---|
| 172 | + &bdc->scratchpad.sp_dma, |
---|
| 173 | + GFP_KERNEL); |
---|
177 | 174 | |
---|
178 | 175 | if (!bdc->scratchpad.buff) |
---|
179 | 176 | goto fail; |
---|
.. | .. |
---|
202 | 199 | bdc_writel(bdc->regs, BDC_SRRINT(0), BDC_SRR_RWS | BDC_SRR_RST); |
---|
203 | 200 | bdc->srr.dqp_index = 0; |
---|
204 | 201 | /* allocate the status report descriptors */ |
---|
205 | | - bdc->srr.sr_bds = dma_zalloc_coherent( |
---|
206 | | - bdc->dev, |
---|
207 | | - NUM_SR_ENTRIES * sizeof(struct bdc_bd), |
---|
208 | | - &bdc->srr.dma_addr, |
---|
209 | | - GFP_KERNEL); |
---|
| 202 | + bdc->srr.sr_bds = dma_alloc_coherent(bdc->dev, |
---|
| 203 | + NUM_SR_ENTRIES * sizeof(struct bdc_bd), |
---|
| 204 | + &bdc->srr.dma_addr, GFP_KERNEL); |
---|
210 | 205 | if (!bdc->srr.sr_bds) |
---|
211 | 206 | return -ENOMEM; |
---|
212 | 207 | |
---|
.. | .. |
---|
293 | 288 | /* Initialize SRR to 0 */ |
---|
294 | 289 | memset(bdc->srr.sr_bds, 0, |
---|
295 | 290 | NUM_SR_ENTRIES * sizeof(struct bdc_bd)); |
---|
296 | | - /* clear ep flags to avoid post disconnect stops/deconfigs */ |
---|
297 | | - for (i = 1; i < bdc->num_eps; ++i) |
---|
298 | | - bdc->bdc_ep_array[i]->flags = 0; |
---|
| 291 | + /* |
---|
| 292 | + * clear ep flags to avoid post disconnect stops/deconfigs but |
---|
| 293 | + * not during S2 exit |
---|
| 294 | + */ |
---|
| 295 | + if (!bdc->gadget.speed) |
---|
| 296 | + for (i = 1; i < bdc->num_eps; ++i) |
---|
| 297 | + bdc->bdc_ep_array[i]->flags = 0; |
---|
299 | 298 | } else { |
---|
300 | 299 | /* One time initiaization only */ |
---|
301 | 300 | /* Enable status report function pointers */ |
---|
.. | .. |
---|
485 | 484 | static int bdc_probe(struct platform_device *pdev) |
---|
486 | 485 | { |
---|
487 | 486 | struct bdc *bdc; |
---|
488 | | - struct resource *res; |
---|
489 | | - int ret = -ENOMEM; |
---|
| 487 | + int ret; |
---|
490 | 488 | int irq; |
---|
491 | 489 | u32 temp; |
---|
492 | 490 | struct device *dev = &pdev->dev; |
---|
493 | | - struct clk *clk; |
---|
494 | 491 | int phy_num; |
---|
495 | 492 | |
---|
496 | 493 | dev_dbg(dev, "%s()\n", __func__); |
---|
497 | | - |
---|
498 | | - clk = devm_clk_get(dev, "sw_usbd"); |
---|
499 | | - if (IS_ERR(clk)) { |
---|
500 | | - dev_info(dev, "Clock not found in Device Tree\n"); |
---|
501 | | - clk = NULL; |
---|
502 | | - } |
---|
503 | | - |
---|
504 | | - ret = clk_prepare_enable(clk); |
---|
505 | | - if (ret) { |
---|
506 | | - dev_err(dev, "could not enable clock\n"); |
---|
507 | | - return ret; |
---|
508 | | - } |
---|
509 | 494 | |
---|
510 | 495 | bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); |
---|
511 | 496 | if (!bdc) |
---|
512 | 497 | return -ENOMEM; |
---|
513 | 498 | |
---|
514 | | - bdc->clk = clk; |
---|
| 499 | + bdc->regs = devm_platform_ioremap_resource(pdev, 0); |
---|
| 500 | + if (IS_ERR(bdc->regs)) |
---|
| 501 | + return PTR_ERR(bdc->regs); |
---|
515 | 502 | |
---|
516 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
517 | | - bdc->regs = devm_ioremap_resource(dev, res); |
---|
518 | | - if (IS_ERR(bdc->regs)) { |
---|
519 | | - dev_err(dev, "ioremap error\n"); |
---|
520 | | - return -ENOMEM; |
---|
521 | | - } |
---|
522 | 503 | irq = platform_get_irq(pdev, 0); |
---|
523 | | - if (irq < 0) { |
---|
524 | | - dev_err(dev, "platform_get_irq failed:%d\n", irq); |
---|
| 504 | + if (irq < 0) |
---|
525 | 505 | return irq; |
---|
526 | | - } |
---|
527 | 506 | spin_lock_init(&bdc->lock); |
---|
528 | 507 | platform_set_drvdata(pdev, bdc); |
---|
529 | 508 | bdc->irq = irq; |
---|
.. | .. |
---|
553 | 532 | } |
---|
554 | 533 | } |
---|
555 | 534 | |
---|
| 535 | + bdc->clk = devm_clk_get_optional(dev, "sw_usbd"); |
---|
| 536 | + if (IS_ERR(bdc->clk)) |
---|
| 537 | + return PTR_ERR(bdc->clk); |
---|
| 538 | + |
---|
| 539 | + ret = clk_prepare_enable(bdc->clk); |
---|
| 540 | + if (ret) { |
---|
| 541 | + dev_err(dev, "could not enable clock\n"); |
---|
| 542 | + return ret; |
---|
| 543 | + } |
---|
| 544 | + |
---|
556 | 545 | ret = bdc_phy_init(bdc); |
---|
557 | 546 | if (ret) { |
---|
558 | 547 | dev_err(bdc->dev, "BDC phy init failure:%d\n", ret); |
---|
559 | | - return ret; |
---|
| 548 | + goto disable_clk; |
---|
560 | 549 | } |
---|
561 | 550 | |
---|
562 | 551 | temp = bdc_readl(bdc->regs, BDC_BDCCAP1); |
---|
.. | .. |
---|
589 | 578 | bdc_hw_exit(bdc); |
---|
590 | 579 | phycleanup: |
---|
591 | 580 | bdc_phy_exit(bdc); |
---|
| 581 | +disable_clk: |
---|
| 582 | + clk_disable_unprepare(bdc->clk); |
---|
592 | 583 | return ret; |
---|
593 | 584 | } |
---|
594 | 585 | |
---|
.. | .. |
---|
644 | 635 | bdc_resume); |
---|
645 | 636 | |
---|
646 | 637 | static const struct of_device_id bdc_of_match[] = { |
---|
647 | | - { .compatible = "brcm,bdc-v0.16" }, |
---|
| 638 | + { .compatible = "brcm,bdc-udc-v2" }, |
---|
648 | 639 | { .compatible = "brcm,bdc" }, |
---|
649 | 640 | { /* sentinel */ } |
---|
650 | 641 | }; |
---|