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