| .. | .. |
|---|
| 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 | }; |
|---|