| .. | .. |
|---|
| 165 | 165 | struct brcmstb_i2c_dev { |
|---|
| 166 | 166 | struct device *device; |
|---|
| 167 | 167 | void __iomem *base; |
|---|
| 168 | | - void __iomem *irq_base; |
|---|
| 169 | 168 | int irq; |
|---|
| 170 | 169 | struct bsc_regs *bsc_regmap; |
|---|
| 171 | 170 | struct i2c_adapter adapter; |
|---|
| 172 | 171 | struct completion done; |
|---|
| 173 | | - bool is_suspended; |
|---|
| 174 | 172 | u32 clk_freq_hz; |
|---|
| 175 | 173 | int data_regsz; |
|---|
| 176 | 174 | }; |
|---|
| .. | .. |
|---|
| 467 | 465 | int xfersz = brcmstb_i2c_get_xfersz(dev); |
|---|
| 468 | 466 | u32 cond, cond_per_msg; |
|---|
| 469 | 467 | |
|---|
| 470 | | - if (dev->is_suspended) |
|---|
| 471 | | - return -EBUSY; |
|---|
| 472 | | - |
|---|
| 473 | 468 | /* Loop through all messages */ |
|---|
| 474 | 469 | for (i = 0; i < num; i++) { |
|---|
| 475 | 470 | pmsg = &msgs[i]; |
|---|
| .. | .. |
|---|
| 585 | 580 | brcmstb_i2c_set_bus_speed(dev); |
|---|
| 586 | 581 | } |
|---|
| 587 | 582 | |
|---|
| 583 | +#define AUTOI2C_CTRL0 0x26c |
|---|
| 584 | +#define AUTOI2C_CTRL0_RELEASE_BSC BIT(1) |
|---|
| 585 | + |
|---|
| 586 | +static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev) |
|---|
| 587 | +{ |
|---|
| 588 | + struct platform_device *pdev = to_platform_device(dev->device); |
|---|
| 589 | + struct resource *iomem; |
|---|
| 590 | + void __iomem *autoi2c; |
|---|
| 591 | + |
|---|
| 592 | + /* Map hardware registers */ |
|---|
| 593 | + iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c"); |
|---|
| 594 | + autoi2c = devm_ioremap_resource(&pdev->dev, iomem); |
|---|
| 595 | + if (IS_ERR(autoi2c)) |
|---|
| 596 | + return PTR_ERR(autoi2c); |
|---|
| 597 | + |
|---|
| 598 | + writel(AUTOI2C_CTRL0_RELEASE_BSC, autoi2c + AUTOI2C_CTRL0); |
|---|
| 599 | + devm_iounmap(&pdev->dev, autoi2c); |
|---|
| 600 | + |
|---|
| 601 | + /* We need to reset the controller after the release */ |
|---|
| 602 | + dev->bsc_regmap->iic_enable = 0; |
|---|
| 603 | + bsc_writel(dev, dev->bsc_regmap->iic_enable, iic_enable); |
|---|
| 604 | + |
|---|
| 605 | + return 0; |
|---|
| 606 | +} |
|---|
| 607 | + |
|---|
| 588 | 608 | static int brcmstb_i2c_probe(struct platform_device *pdev) |
|---|
| 589 | 609 | { |
|---|
| 590 | 610 | int rc = 0; |
|---|
| .. | .. |
|---|
| 614 | 634 | goto probe_errorout; |
|---|
| 615 | 635 | } |
|---|
| 616 | 636 | |
|---|
| 637 | + if (of_device_is_compatible(dev->device->of_node, |
|---|
| 638 | + "brcm,bcm2711-hdmi-i2c")) { |
|---|
| 639 | + rc = bcm2711_release_bsc(dev); |
|---|
| 640 | + if (rc) |
|---|
| 641 | + goto probe_errorout; |
|---|
| 642 | + } |
|---|
| 643 | + |
|---|
| 617 | 644 | rc = of_property_read_string(dev->device->of_node, "interrupt-names", |
|---|
| 618 | 645 | &int_name); |
|---|
| 619 | 646 | if (rc < 0) |
|---|
| 620 | 647 | int_name = NULL; |
|---|
| 621 | 648 | |
|---|
| 622 | 649 | /* Get the interrupt number */ |
|---|
| 623 | | - dev->irq = platform_get_irq(pdev, 0); |
|---|
| 650 | + dev->irq = platform_get_irq_optional(pdev, 0); |
|---|
| 624 | 651 | |
|---|
| 625 | 652 | /* disable the bsc interrupt line */ |
|---|
| 626 | 653 | brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE); |
|---|
| 627 | 654 | |
|---|
| 628 | 655 | /* register the ISR handler */ |
|---|
| 629 | | - rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr, |
|---|
| 630 | | - IRQF_SHARED, |
|---|
| 631 | | - int_name ? int_name : pdev->name, |
|---|
| 632 | | - dev); |
|---|
| 656 | + if (dev->irq >= 0) { |
|---|
| 657 | + rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr, |
|---|
| 658 | + IRQF_SHARED, |
|---|
| 659 | + int_name ? int_name : pdev->name, |
|---|
| 660 | + dev); |
|---|
| 633 | 661 | |
|---|
| 634 | | - if (rc) { |
|---|
| 635 | | - dev_dbg(dev->device, "falling back to polling mode"); |
|---|
| 636 | | - dev->irq = -1; |
|---|
| 662 | + if (rc) { |
|---|
| 663 | + dev_dbg(dev->device, "falling back to polling mode"); |
|---|
| 664 | + dev->irq = -1; |
|---|
| 665 | + } |
|---|
| 637 | 666 | } |
|---|
| 638 | 667 | |
|---|
| 639 | 668 | if (of_property_read_u32(dev->device->of_node, |
|---|
| .. | .. |
|---|
| 689 | 718 | { |
|---|
| 690 | 719 | struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
|---|
| 691 | 720 | |
|---|
| 692 | | - i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER); |
|---|
| 693 | | - i2c_dev->is_suspended = true; |
|---|
| 694 | | - i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER); |
|---|
| 695 | | - |
|---|
| 721 | + i2c_mark_adapter_suspended(&i2c_dev->adapter); |
|---|
| 696 | 722 | return 0; |
|---|
| 697 | 723 | } |
|---|
| 698 | 724 | |
|---|
| .. | .. |
|---|
| 700 | 726 | { |
|---|
| 701 | 727 | struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
|---|
| 702 | 728 | |
|---|
| 703 | | - i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER); |
|---|
| 704 | 729 | brcmstb_i2c_set_bsc_reg_defaults(i2c_dev); |
|---|
| 705 | | - i2c_dev->is_suspended = false; |
|---|
| 706 | | - i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER); |
|---|
| 730 | + i2c_mark_adapter_resumed(&i2c_dev->adapter); |
|---|
| 707 | 731 | |
|---|
| 708 | 732 | return 0; |
|---|
| 709 | 733 | } |
|---|
| .. | .. |
|---|
| 715 | 739 | static const struct of_device_id brcmstb_i2c_of_match[] = { |
|---|
| 716 | 740 | {.compatible = "brcm,brcmstb-i2c"}, |
|---|
| 717 | 741 | {.compatible = "brcm,brcmper-i2c"}, |
|---|
| 742 | + {.compatible = "brcm,bcm2711-hdmi-i2c"}, |
|---|
| 718 | 743 | {}, |
|---|
| 719 | 744 | }; |
|---|
| 720 | 745 | MODULE_DEVICE_TABLE(of, brcmstb_i2c_of_match); |
|---|