Commit d8916353 authored by Wolfram Sang's avatar Wolfram Sang
Browse files

Merge tag 'i2c-host-7.1-part2' of...

Merge tag 'i2c-host-7.1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-mergewindow

i2c-host for v7.1, part 2

- cx92755: convert I2C bindings to DT schema
- mediatek: add optional bus power management during transfers
- pxa: handle early bus busy condition
parents c1f49dea faed986d
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/cnxt,cx92755-i2c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Conexant Digicolor I2C controller

allOf:
  - $ref: /schemas/i2c/i2c-controller.yaml#

maintainers:
  - Baruch Siach <baruch@tkos.co.il>

properties:
  compatible:
    const: cnxt,cx92755-i2c

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1

  clocks:
    maxItems: 1

  clock-frequency:
    default: 100000

required:
  - compatible
  - reg
  - interrupts
  - clocks

unevaluatedProperties: false

examples:
  - |
    i2c@f0000120 {
      compatible = "cnxt,cx92755-i2c";
      reg = <0xf0000120 0x10>;
      interrupts = <28>;
      clocks = <&main_clk>;
      clock-frequency = <100000>;
      #address-cells = <1>;
      #size-cells = <0>;
    };
+0 −25
Original line number Diff line number Diff line
Conexant Digicolor I2C controller

Required properties:
 - compatible: must be "cnxt,cx92755-i2c"
 - reg: physical address and length of the device registers
 - interrupts: a single interrupt specifier
 - clocks: clock for the device
 - #address-cells: should be <1>
 - #size-cells: should be <0>

Optional properties:
- clock-frequency: the desired I2C bus clock frequency in Hz; in
  absence of this property the default value is used (100 kHz).

Example:

	i2c: i2c@f0000120 {
		compatible = "cnxt,cx92755-i2c";
		reg = <0xf0000120 0x10>;
		interrupts = <28>;
		clocks = <&main_clk>;
		clock-frequency = <100000>;
		#address-cells = <1>;
		#size-cells = <0>;
	};
+12 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/slab.h>
@@ -1244,9 +1245,15 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
	bool write_then_read_en = false;
	struct mtk_i2c *i2c = i2c_get_adapdata(adap);

	ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
	if (i2c->adap.bus_regulator) {
		ret = regulator_enable(i2c->adap.bus_regulator);
		if (ret)
			return ret;
	}

	ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
	if (ret)
		goto err_regulator;

	i2c->auto_restart = i2c->dev_comp->auto_restart;

@@ -1301,6 +1308,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,

err_exit:
	clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks);
err_regulator:
	if (i2c->adap.bus_regulator)
		regulator_disable(i2c->adap.bus_regulator);

	return ret;
}

+12 −6
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#define ISR_GCAD	(1 << 8)	   /* general call address detected */
#define ISR_SAD		(1 << 9)	   /* slave address detected */
#define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */
#define ISR_A3700_EBB	(1 << 11)	   /* early bus busy for armada 3700 */

#define ILCR_SLV_SHIFT		0
#define ILCR_SLV_MASK		(0x1FF << ILCR_SLV_SHIFT)
@@ -263,6 +264,7 @@ struct pxa_i2c {
	bool			highmode_enter;
	u32			fm_mask;
	u32			hs_mask;
	u32			busy_mask;

	struct i2c_bus_recovery_info recovery;
	struct pinctrl		*pinctrl;
@@ -430,7 +432,7 @@ static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)

	while (1) {
		isr = readl(_ISR(i2c));
		if (!(isr & (ISR_IBB | ISR_UB)))
		if (!(isr & i2c->busy_mask))
			return 0;

		if (isr & ISR_SAD)
@@ -467,7 +469,7 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
		 * quick check of the i2c lines themselves to ensure they've
		 * gone high...
		 */
		if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 &&
		if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 &&
		    readl(_IBMR(i2c)) == (IBMR_SCLS | IBMR_SDAS)) {
			if (i2c_debug > 0)
				dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
@@ -488,7 +490,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
	if (i2c_debug)
		dev_dbg(&i2c->adap.dev, "setting to bus master\n");

	if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
	if ((readl(_ISR(i2c)) & i2c->busy_mask) != 0) {
		dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
		if (!i2c_pxa_wait_master(i2c)) {
			dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
@@ -514,7 +516,7 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
			dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
				__func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));

		if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
		if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 ||
		    (readl(_ISR(i2c)) & ISR_SAD) != 0 ||
		    (readl(_ICR(i2c)) & ICR_SCLE) == 0) {
			if (i2c_debug > 1)
@@ -1177,7 +1179,7 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
	/*
	 * Wait for the bus to become free.
	 */
	while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB))
	while (timeout-- && readl(_ISR(i2c)) & i2c->busy_mask)
		udelay(1000);

	if (timeout < 0) {
@@ -1322,7 +1324,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
	 * handing control of the bus back to avoid the bus changing state.
	 */
	isr = readl(_ISR(i2c));
	if (isr & (ISR_UB | ISR_IBB)) {
	if (isr & i2c->busy_mask) {
		dev_dbg(&i2c->adap.dev,
			"recovery: resetting controller, ISR=0x%08x\n", isr);
		i2c_pxa_do_reset(i2c);
@@ -1479,6 +1481,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
	i2c->fm_mask = pxa_reg_layout[i2c_type].fm;
	i2c->hs_mask = pxa_reg_layout[i2c_type].hs;

	i2c->busy_mask = ISR_UB | ISR_IBB;
	if (i2c_type == REGS_A3700)
		i2c->busy_mask |= ISR_A3700_EBB;

	if (i2c_type != REGS_CE4100)
		i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;