Merge branch 'i2c/for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Oct 2016 21:12:21 +0000 (14:12 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Oct 2016 21:12:21 +0000 (14:12 -0700)
Pull i2c updates from Wolfram Sang:
 "Here is the 4.9 pull request from I2C including:

   - centralized error messages when registering to the core
   - improved lockdep annotations to prevent false positives
   - DT support for muxes, gates, and arbitrators
   - bus speeds can now be obtained from ACPI
   - i2c-octeon got refactored and now supports ThunderX SoCs, too
   - i2c-tegra and i2c-designware got a bigger bunch of updates
   - a couple of standard driver fixes and improvements"

* 'i2c/for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (71 commits)
  i2c: axxia: disable clks in case of failure in probe
  i2c: octeon: thunderx: Limit register access retries
  i2c: uniphier-f: fix misdetection of incomplete STOP condition
  gpio: pca953x: variable 'id' was used twice
  i2c: i801: Add support for Kaby Lake PCH-H
  gpio: pca953x: fix an incorrect lockdep warning
  i2c: add a warning to i2c_adapter_depth()
  lockdep: make MAX_LOCKDEP_SUBCLASSES unconditionally visible
  i2c: export i2c_adapter_depth()
  i2c: rk3x: Fix variable 'min_total_ns' unused warning
  i2c: rk3x: Fix sparse warning
  i2c / ACPI: Do not touch an I2C device if it belongs to another adapter
  i2c: octeon: Fix high-level controller status check
  i2c: octeon: Avoid sending STOP during recovery
  i2c: octeon: Fix set SCL recovery function
  i2c: rcar: add support for r8a7796 (R-Car M3-W)
  i2c: imx: make bus recovery through pinctrl optional
  i2c: meson: add gxbb compatible string
  i2c: uniphier-f: set the adapter to master mode when probing
  i2c: uniphier-f: avoid WARN_ON() of clk_disable() in failure path
  ...

83 files changed:
Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt
Documentation/devicetree/bindings/i2c/i2c-arb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-gate.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-meson.txt
Documentation/devicetree/bindings/i2c/i2c-mux.txt
Documentation/devicetree/bindings/i2c/i2c-rcar.txt
Documentation/devicetree/bindings/i2c/nxp,pca9541.txt [new file with mode: 0644]
MAINTAINERS
drivers/gpio/gpio-pca953x.c
drivers/gpu/drm/drm_dp_helper.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-at91.c
drivers/i2c/busses/i2c-axxia.c
drivers/i2c/busses/i2c-bcm-iproc.c
drivers/i2c/busses/i2c-bcm-kona.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-brcmstb.c
drivers/i2c/busses/i2c-cadence.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-cros-ec-tunnel.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-diolan-u2c.c
drivers/i2c/busses/i2c-dln2.c
drivers/i2c/busses/i2c-efm32.c
drivers/i2c/busses/i2c-exynos5.c
drivers/i2c/busses/i2c-hix5hd2.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-img-scb.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-isch.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-jz4780.c
drivers/i2c/busses/i2c-lpc2k.c
drivers/i2c/busses/i2c-meson.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mt65xx.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-octeon-core.c [new file with mode: 0644]
drivers/i2c/busses/i2c-octeon-core.h [new file with mode: 0644]
drivers/i2c/busses/i2c-octeon-platdrv.c [new file with mode: 0644]
drivers/i2c/busses/i2c-octeon.c [deleted file]
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-puv3.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-riic.c
drivers/i2c/busses/i2c-rk3x.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-sh7760.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-sirf.c
drivers/i2c/busses/i2c-st.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-thunderx-pcidrv.c [new file with mode: 0644]
drivers/i2c/busses/i2c-uniphier-f.c
drivers/i2c/busses/i2c-uniphier.c
drivers/i2c/busses/i2c-wmt.c
drivers/i2c/busses/i2c-xgene-slimpro.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/busses/i2c-xlp9xx.c
drivers/i2c/busses/i2c-xlr.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-mux.c
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/misc/eeprom/at24.c
include/linux/i2c-mux.h
include/linux/i2c.h
include/linux/lockdep.h

index 71191ff0e7814c958502fbc7ee79c6d0f71c9b02..248a155414c2185d89deaba032ede2051cf7249a 100644 (file)
@@ -44,8 +44,7 @@ Required properties:
 - our-claim-gpio: The GPIO that we use to claim the bus.
 - their-claim-gpios: The GPIOs that the other sides use to claim the bus.
   Note that some implementations may only support a single other master.
-- Standard I2C mux properties. See i2c-mux.txt in this directory.
-- Single I2C child bus node at reg 0. See i2c-mux.txt in this directory.
+- I2C arbitration bus node. See i2c-arb.txt in this directory.
 
 Optional properties:
 - slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us.
@@ -63,8 +62,6 @@ Example:
 
        i2c-arbitrator {
                compatible = "i2c-arb-gpio-challenge";
-               #address-cells = <1>;
-               #size-cells = <0>;
 
                i2c-parent = <&{/i2c@12CA0000}>;
 
@@ -74,8 +71,7 @@ Example:
                wait-retry-us = <3000>;
                wait-free-us = <50000>;
 
-               i2c@0 {
-                       reg = <0>;
+               i2c-arb {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
diff --git a/Documentation/devicetree/bindings/i2c/i2c-arb.txt b/Documentation/devicetree/bindings/i2c/i2c-arb.txt
new file mode 100644 (file)
index 0000000..59abf92
--- /dev/null
@@ -0,0 +1,35 @@
+Common i2c arbitration bus properties.
+
+- i2c-arb child node
+
+Required properties for the i2c-arb child node:
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties for i2c-arb child node:
+- Child nodes conforming to i2c bus binding
+
+
+Example :
+
+       /*
+          An NXP pca9541 I2C bus master selector at address 0x74
+          with a NXP pca8574 GPIO expander attached.
+        */
+
+       arb@74 {
+               compatible = "nxp,pca9541";
+               reg = <0x74>;
+
+               i2c-arb {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       gpio@38 {
+                               compatible = "nxp,pca8574";
+                               reg = <0x38>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                       };
+               };
+       };
diff --git a/Documentation/devicetree/bindings/i2c/i2c-gate.txt b/Documentation/devicetree/bindings/i2c/i2c-gate.txt
new file mode 100644 (file)
index 0000000..1846d23
--- /dev/null
@@ -0,0 +1,41 @@
+An i2c gate is useful to e.g. reduce the digital noise for RF tuners connected
+to the i2c bus. Gates are similar to arbitrators in that you need to perform
+some kind of operation to access the i2c bus past the arbitrator/gate, but
+there are no competing masters to consider for gates and therefore there is
+no arbitration happening for gates.
+
+Common i2c gate properties.
+
+- i2c-gate child node
+
+Required properties for the i2c-gate child node:
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties for i2c-gate child node:
+- Child nodes conforming to i2c bus binding
+
+
+Example :
+
+       /*
+          An Invensense mpu9150 at address 0x68 featuring an on-chip Asahi
+          Kasei ak8975 compass behind a gate.
+        */
+
+       mpu9150@68 {
+               compatible = "invensense,mpu9150";
+               reg = <0x68>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <18 1>;
+
+               i2c-gate {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       ax8975@c {
+                               compatible = "ak,ak8975";
+                               reg = <0x0c>;
+                       };
+               };
+       };
index 682f9a6f766e8d74232bf5e1c4a85cf2db7f1a6c..386357d1aab05de652675bf6ed19c0dc22b50709 100644 (file)
@@ -1,7 +1,7 @@
 Amlogic Meson I2C controller
 
 Required properties:
- - compatible: must be "amlogic,meson6-i2c"
+ - compatible: must be "amlogic,meson6-i2c" or "amlogic,meson-gxbb-i2c"
  - reg: physical address and length of the device registers
  - interrupts: a single interrupt specifier
  - clocks: clock for the device
index af84cce5cd7bcd73c8b062e0e26b9d9494339864..212e6779dc5c0caf34944f1facac0ef971d16ffd 100644 (file)
@@ -2,19 +2,32 @@ Common i2c bus multiplexer/switch properties.
 
 An i2c bus multiplexer/switch will have several child busses that are
 numbered uniquely in a device dependent manner.  The nodes for an i2c bus
-multiplexer/switch will have one child node for each child
-bus.
+multiplexer/switch will have one child node for each child bus.
 
-Required properties:
+Optional properties:
+- #address-cells = <1>;
+   This property is required is the i2c-mux child node does not exist.
+
+- #size-cells = <0>;
+   This property is required is the i2c-mux child node does not exist.
+
+- i2c-mux
+   For i2c multiplexers/switches that have child nodes that are a mixture
+   of both i2c child busses and other child nodes, the 'i2c-mux' subnode
+   can be used for populating the i2c child busses.  If an 'i2c-mux'
+   subnode is present, only subnodes of this will be considered as i2c
+   child busses.
+
+Required properties for the i2c-mux child node:
 - #address-cells = <1>;
 - #size-cells = <0>;
 
-Required properties for child nodes:
+Required properties for i2c child bus nodes:
 - #address-cells = <1>;
 - #size-cells = <0>;
 - reg : The sub-bus number.
 
-Optional properties for child nodes:
+Optional properties for i2c child bus nodes:
 - Other properties specific to the multiplexer/switch hardware.
 - Child nodes conforming to i2c bus binding
 
index 5f0cb502b1db8908d6891c2204df45cf938b15d3..239632a0d709e7ad176914df526902f332d082ce 100644 (file)
@@ -11,6 +11,7 @@ Required properties:
        "renesas,i2c-r8a7793"
        "renesas,i2c-r8a7794"
        "renesas,i2c-r8a7795"
+       "renesas,i2c-r8a7796"
 - reg: physical base address of the controller and length of memory mapped
   region.
 - interrupts: interrupt specifier.
diff --git a/Documentation/devicetree/bindings/i2c/nxp,pca9541.txt b/Documentation/devicetree/bindings/i2c/nxp,pca9541.txt
new file mode 100644 (file)
index 0000000..0fbbc69
--- /dev/null
@@ -0,0 +1,29 @@
+* NXP PCA9541 I2C bus master selector
+
+Required Properties:
+
+  - compatible: Must be "nxp,pca9541"
+
+  - reg: The I2C address of the device.
+
+  The following required properties are defined externally:
+
+  - I2C arbitration bus node. See i2c-arb.txt in this directory.
+
+
+Example:
+
+       i2c-arbitrator@74 {
+               compatible = "nxp,pca9541";
+               reg = <0x74>;
+
+               i2c-arb {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       eeprom@54 {
+                               compatible = "at,24c08";
+                               reg = <0x54>;
+                       };
+               };
+       };
index 33d77794a1f2289c64418bbed0ab2ba8bd49ac0d..255655880881cd22df8f0c5ff53f76e72691d1f2 100644 (file)
@@ -2908,6 +2908,14 @@ S:       Maintained
 F:     drivers/iio/light/cm*
 F:     Documentation/devicetree/bindings/i2c/trivial-devices.txt
 
+CAVIUM I2C DRIVER
+M:     Jan Glauber <jglauber@cavium.com>
+M:     David Daney <david.daney@cavium.com>
+W:     http://www.cavium.com
+S:     Supported
+F:     drivers/i2c/busses/i2c-octeon*
+F:     drivers/i2c/busses/i2c-thunderx*
+
 CAVIUM LIQUIDIO NETWORK DRIVER
 M:     Derek Chickles <derek.chickles@caviumnetworks.com>
 M:     Satanand Burla <satananda.burla@caviumnetworks.com>
@@ -5788,6 +5796,8 @@ S:        Maintained
 F:     Documentation/i2c/i2c-topology
 F:     Documentation/i2c/muxes/
 F:     Documentation/devicetree/bindings/i2c/i2c-mux*
+F:     Documentation/devicetree/bindings/i2c/i2c-arb*
+F:     Documentation/devicetree/bindings/i2c/i2c-gate*
 F:     drivers/i2c/i2c-mux.c
 F:     drivers/i2c/muxes/
 F:     include/linux/i2c-mux.h
index 5d059866d17acf4eb397f85adef7481fdde4cdcc..45c8817d068c60649ee9e5648dbf9451f3bf5667 100644 (file)
@@ -732,7 +732,7 @@ out:
 static const struct of_device_id pca953x_dt_ids[];
 
 static int pca953x_probe(struct i2c_client *client,
-                                  const struct i2c_device_id *id)
+                                  const struct i2c_device_id *i2c_id)
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
@@ -773,27 +773,29 @@ static int pca953x_probe(struct i2c_client *client,
        }
        chip->regulator = reg;
 
-       if (id) {
-               chip->driver_data = id->driver_data;
+       if (i2c_id) {
+               chip->driver_data = i2c_id->driver_data;
        } else {
-               const struct acpi_device_id *id;
+               const struct acpi_device_id *acpi_id;
                const struct of_device_id *match;
 
                match = of_match_device(pca953x_dt_ids, &client->dev);
                if (match) {
                        chip->driver_data = (int)(uintptr_t)match->data;
                } else {
-                       id = acpi_match_device(pca953x_acpi_ids, &client->dev);
-                       if (!id) {
+                       acpi_id = acpi_match_device(pca953x_acpi_ids, &client->dev);
+                       if (!acpi_id) {
                                ret = -ENODEV;
                                goto err_exit;
                        }
 
-                       chip->driver_data = id->driver_data;
+                       chip->driver_data = acpi_id->driver_data;
                }
        }
 
        mutex_init(&chip->i2c_lock);
+       lockdep_set_subclass(&chip->i2c_lock,
+                            i2c_adapter_depth(client->adapter));
 
        /* initialize cached registers from their original values.
         * we can't share this chip with another i2c master.
index eae5ef963cb790d261a5093aa8b8d72671b25e86..2bd064493ae7ce09cf39a47f8ce7e2786bc2567a 100644 (file)
@@ -790,6 +790,12 @@ static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags)
        mutex_unlock(&i2c_to_aux(i2c)->hw_mutex);
 }
 
+static const struct i2c_lock_operations drm_dp_i2c_lock_ops = {
+       .lock_bus = lock_bus,
+       .trylock_bus = trylock_bus,
+       .unlock_bus = unlock_bus,
+};
+
 /**
  * drm_dp_aux_init() - minimally initialise an aux channel
  * @aux: DisplayPort AUX channel
@@ -807,9 +813,7 @@ void drm_dp_aux_init(struct drm_dp_aux *aux)
        aux->ddc.algo_data = aux;
        aux->ddc.retries = 3;
 
-       aux->ddc.lock_bus = lock_bus;
-       aux->ddc.trylock_bus = trylock_bus;
-       aux->ddc.unlock_bus = unlock_bus;
+       aux->ddc.lock_ops = &drm_dp_i2c_lock_ops;
 }
 EXPORT_SYMBOL(drm_dp_aux_init);
 
index 5c3993b261298ef3c9571e76307fe912548b9538..6d94e2ec5b4f7183734fbd1159db5d7013fa6f74 100644 (file)
@@ -836,7 +836,7 @@ config I2C_SH7760
 config I2C_SH_MOBILE
        tristate "SuperH Mobile I2C Controller"
        depends on HAS_DMA
-       depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
+       depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the Renesas SH-Mobile processor.
@@ -956,6 +956,17 @@ config I2C_OCTEON
          This driver can also be built as a module.  If so, the module
          will be called i2c-octeon.
 
+config I2C_THUNDERX
+       tristate "Cavium ThunderX I2C bus support"
+       depends on 64BIT && PCI && (ARM64 || COMPILE_TEST)
+       select I2C_SMBUS
+       help
+         Say yes if you want to support the I2C serial bus on Cavium
+         ThunderX SOC.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-thunderx.
+
 config I2C_XILINX
        tristate "Xilinx I2C Controller"
        depends on HAS_IOMEM
index 37f2819b4560b0e0947b74c214f5c5a0952bc0ae..29764cc20a440752841272ddfed3993048ecd105 100644 (file)
@@ -91,7 +91,10 @@ obj-$(CONFIG_I2C_UNIPHIER)   += i2c-uniphier.o
 obj-$(CONFIG_I2C_UNIPHIER_F)   += i2c-uniphier-f.o
 obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_WMT)          += i2c-wmt.o
+i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o
 obj-$(CONFIG_I2C_OCTEON)       += i2c-octeon.o
+i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o
+obj-$(CONFIG_I2C_THUNDERX)     += i2c-thunderx.o
 obj-$(CONFIG_I2C_XILINX)       += i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)          += i2c-xlr.o
 obj-$(CONFIG_I2C_XLP9XX)       += i2c-xlp9xx.o
index 6c7113d990f882a758435eb78fc172510a6faed6..274908cd1fdeabc4a76f8c9e58e7b3a52cc20401 100644 (file)
@@ -378,11 +378,8 @@ static int amd756_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                 amd756_ioport);
 
        error = i2c_add_adapter(&amd756_smbus);
-       if (error) {
-               dev_err(&pdev->dev,
-                       "Adapter registration failed, module not inserted\n");
+       if (error)
                goto out_err;
-       }
 
        return 0;
 
index 1bb97f658b47a1fa4c5b15e85779fa5160c6c3e6..0b86c6173e073806a4d0021a6f98cacfa082566a 100644 (file)
@@ -1122,8 +1122,6 @@ static int at91_twi_probe(struct platform_device *pdev)
 
        rc = i2c_add_numbered_adapter(&dev->adapter);
        if (rc) {
-               dev_err(dev->dev, "Adapter %s registration failed\n",
-                       dev->adapter.name);
                clk_disable_unprepare(dev->clk);
 
                pm_runtime_disable(dev->dev);
index c335cc7852f94ef0b08525901c03eb8b38ec76ae..4351a9343058920e76bf9aa39eabceedf7a0a570 100644 (file)
@@ -545,7 +545,11 @@ static int axxia_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
-       clk_prepare_enable(idev->i2c_clk);
+       ret = clk_prepare_enable(idev->i2c_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to enable clock\n");
+               return ret;
+       }
 
        i2c_set_adapdata(&idev->adapter, idev);
        strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
@@ -560,7 +564,7 @@ static int axxia_i2c_probe(struct platform_device *pdev)
 
        ret = i2c_add_adapter(&idev->adapter);
        if (ret) {
-               dev_err(&pdev->dev, "failed to add adapter\n");
+               clk_disable_unprepare(idev->i2c_clk);
                return ret;
        }
 
index 95f7cac76f89bfeac68ad22521d8c38c2df348c8..326b3db02c48b2cfce1591243e5db8e9b57855ba 100644 (file)
@@ -488,13 +488,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
 
-       ret = i2c_add_adapter(adap);
-       if (ret) {
-               dev_err(iproc_i2c->device, "failed to add adapter\n");
-               return ret;
-       }
-
-       return 0;
+       return i2c_add_adapter(adap);
 }
 
 static int bcm_iproc_i2c_remove(struct platform_device *pdev)
index 258cb9a40ab3491b7c872432e07a2a1a435da78b..4e489a9d16fb36b3720a46573fc8196897889db9 100644 (file)
@@ -858,10 +858,8 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
        adap->dev.of_node = pdev->dev.of_node;
 
        rc = i2c_add_adapter(adap);
-       if (rc) {
-               dev_err(dev->device, "failed to add adapter\n");
+       if (rc)
                return rc;
-       }
 
        dev_info(dev->device, "device registered successfully\n");
 
index 025686d4164058498216862d37af9ad114fe4fa2..29d00c4f7824c2b3a9deaa41749567a07eb2c123 100644 (file)
@@ -685,10 +685,8 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
        write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
 
        rc = i2c_add_numbered_adapter(p_adap);
-       if (rc < 0) {
-               dev_err(&pdev->dev, "Can't add i2c adapter!\n");
+       if (rc < 0)
                goto out_error;
-       }
 
        platform_set_drvdata(pdev, iface);
 
index 385b57bfcb386ce8754892741584fd30a10b3b47..0652281662a8b35b974d084c5d0636f8ac75e450 100644 (file)
@@ -648,10 +648,8 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
        rc = i2c_add_adapter(adap);
-       if (rc) {
-               dev_err(dev->device, "failed to add adapter\n");
+       if (rc)
                goto probe_errorout;
-       }
 
        dev_info(dev->device, "%s@%dhz registered in %s mode\n",
                 int_name ? int_name : " ", dev->clk_freq_hz,
index 3c16a2f7c673cb808b4113a65d41493bd167ca89..686971263bef19a2fcc159432a6e6e46b1e16771 100644 (file)
@@ -963,10 +963,8 @@ static int cdns_i2c_probe(struct platform_device *pdev)
        }
 
        ret = i2c_add_adapter(&id->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
+       if (ret < 0)
                goto err_clk_dis;
-       }
 
        /*
         * Cadence I2C controller has a bug wherein it generates
index ee57c1e865e271228a38484d03c1c02c979fa7a9..d89bde2c5da256ecff87c4bd6ba1fc6fc3a2f4b0 100644 (file)
@@ -665,10 +665,8 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
        cpm->adap.nr = (data && len == 4) ? be32_to_cpup(data) : -1;
        result = i2c_add_numbered_adapter(&cpm->adap);
 
-       if (result < 0) {
-               dev_err(&ofdev->dev, "Unable to register with I2C\n");
+       if (result < 0)
                goto out_shut;
-       }
 
        dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
                cpm->adap.name);
index 2d5ff86398d0911cd0c3a261fb689cf2c9e04609..9b36a7b3befda300bd9a6371f91a7253d173c501 100644 (file)
@@ -281,10 +281,8 @@ static int ec_i2c_probe(struct platform_device *pdev)
        bus->adap.retries = I2C_MAX_RETRIES;
 
        err = i2c_add_adapter(&bus->adap);
-       if (err) {
-               dev_err(dev, "cannot register i2c adapter\n");
+       if (err)
                return err;
-       }
        platform_set_drvdata(pdev, bus);
 
        return err;
index a8bdcb5292f5b30a925c40f28c8d193395b443c6..9e7ef5cf5d495d6de7fa8fad20449c4fa91aa5f8 100644 (file)
@@ -846,10 +846,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 
        adap->nr = pdev->id;
        r = i2c_add_numbered_adapter(adap);
-       if (r) {
-               dev_err(&pdev->dev, "failure adding adapter\n");
+       if (r)
                goto err_unuse_clocks;
-       }
 
        return 0;
 
index fcd973d5131e8f767cbe2af45cfac7bad74aed24..1fe93c43215cf9e5d26385727e7c4f35a7e2fe89 100644 (file)
@@ -42,6 +42,8 @@
 #define DW_IC_SS_SCL_LCNT      0x18
 #define DW_IC_FS_SCL_HCNT      0x1c
 #define DW_IC_FS_SCL_LCNT      0x20
+#define DW_IC_HS_SCL_HCNT      0x24
+#define DW_IC_HS_SCL_LCNT      0x28
 #define DW_IC_INTR_STAT                0x2c
 #define DW_IC_INTR_MASK                0x30
 #define DW_IC_RAW_INTR_STAT    0x34
                                         DW_IC_INTR_TX_ABRT | \
                                         DW_IC_INTR_STOP_DET)
 
-#define DW_IC_STATUS_ACTIVITY  0x1
+#define DW_IC_STATUS_ACTIVITY          0x1
+#define DW_IC_STATUS_TFE               BIT(2)
+#define DW_IC_STATUS_MST_ACTIVITY      BIT(5)
 
 #define DW_IC_ERR_TX_ABRT      0x1
 
 #define DW_IC_TAR_10BITADDR_MASTER BIT(12)
 
+#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH     (BIT(2) | BIT(3))
+#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK     GENMASK(3, 2)
+
 /*
  * status codes
  */
@@ -251,11 +258,16 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
 }
 
 static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable)
+{
+       dw_writel(dev, enable, DW_IC_ENABLE);
+}
+
+static void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
 {
        int timeout = 100;
 
        do {
-               dw_writel(dev, enable, DW_IC_ENABLE);
+               __i2c_dw_enable(dev, enable);
                if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == enable)
                        return;
 
@@ -282,6 +294,28 @@ static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
        return dev->get_clk_rate_khz(dev);
 }
 
+static int i2c_dw_acquire_lock(struct dw_i2c_dev *dev)
+{
+       int ret;
+
+       if (!dev->acquire_lock)
+               return 0;
+
+       ret = dev->acquire_lock(dev);
+       if (!ret)
+               return 0;
+
+       dev_err(dev->dev, "couldn't acquire bus ownership\n");
+
+       return ret;
+}
+
+static void i2c_dw_release_lock(struct dw_i2c_dev *dev)
+{
+       if (dev->release_lock)
+               dev->release_lock(dev);
+}
+
 /**
  * i2c_dw_init() - initialize the designware i2c master hardware
  * @dev: device private data
@@ -293,17 +327,13 @@ static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
 int i2c_dw_init(struct dw_i2c_dev *dev)
 {
        u32 hcnt, lcnt;
-       u32 reg;
+       u32 reg, comp_param1;
        u32 sda_falling_time, scl_falling_time;
        int ret;
 
-       if (dev->acquire_lock) {
-               ret = dev->acquire_lock(dev);
-               if (ret) {
-                       dev_err(dev->dev, "couldn't acquire bus ownership\n");
-                       return ret;
-               }
-       }
+       ret = i2c_dw_acquire_lock(dev);
+       if (ret)
+               return ret;
 
        reg = dw_readl(dev, DW_IC_COMP_TYPE);
        if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
@@ -315,13 +345,14 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
        } else if (reg != DW_IC_COMP_TYPE_VALUE) {
                dev_err(dev->dev, "Unknown Synopsys component type: "
                        "0x%08x\n", reg);
-               if (dev->release_lock)
-                       dev->release_lock(dev);
+               i2c_dw_release_lock(dev);
                return -ENODEV;
        }
 
+       comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
+
        /* Disable the adapter */
-       __i2c_dw_enable(dev, false);
+       __i2c_dw_enable_and_wait(dev, false);
 
        /* set standard and fast speed deviders for high/low periods */
 
@@ -347,8 +378,11 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
        dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
        dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
 
-       /* Set SCL timing parameters for fast-mode */
-       if (dev->fs_hcnt && dev->fs_lcnt) {
+       /* Set SCL timing parameters for fast-mode or fast-mode plus */
+       if ((dev->clk_freq == 1000000) && dev->fp_hcnt && dev->fp_lcnt) {
+               hcnt = dev->fp_hcnt;
+               lcnt = dev->fp_lcnt;
+       } else if (dev->fs_hcnt && dev->fs_lcnt) {
                hcnt = dev->fs_hcnt;
                lcnt = dev->fs_lcnt;
        } else {
@@ -366,6 +400,23 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
        dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
        dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
 
+       if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) ==
+               DW_IC_CON_SPEED_HIGH) {
+               if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
+                       != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) {
+                       dev_err(dev->dev, "High Speed not supported!\n");
+                       dev->master_cfg &= ~DW_IC_CON_SPEED_MASK;
+                       dev->master_cfg |= DW_IC_CON_SPEED_FAST;
+               } else if (dev->hs_hcnt && dev->hs_lcnt) {
+                       hcnt = dev->hs_hcnt;
+                       lcnt = dev->hs_lcnt;
+                       dw_writel(dev, hcnt, DW_IC_HS_SCL_HCNT);
+                       dw_writel(dev, lcnt, DW_IC_HS_SCL_LCNT);
+                       dev_dbg(dev->dev, "HighSpeed-mode HCNT:LCNT = %d:%d\n",
+                               hcnt, lcnt);
+               }
+       }
+
        /* Configure SDA Hold Time if required */
        reg = dw_readl(dev, DW_IC_COMP_VERSION);
        if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
@@ -387,8 +438,8 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
        /* configure the i2c master */
        dw_writel(dev, dev->master_cfg , DW_IC_CON);
 
-       if (dev->release_lock)
-               dev->release_lock(dev);
+       i2c_dw_release_lock(dev);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(i2c_dw_init);
@@ -415,27 +466,45 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev)
 static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
 {
        struct i2c_msg *msgs = dev->msgs;
-       u32 ic_con, ic_tar = 0;
+       u32 ic_tar = 0;
+       bool enabled;
 
-       /* Disable the adapter */
-       __i2c_dw_enable(dev, false);
+       enabled = dw_readl(dev, DW_IC_ENABLE_STATUS) & 1;
+
+       if (enabled) {
+               u32 ic_status;
+
+               /*
+                * Only disable adapter if ic_tar and ic_con can't be
+                * dynamically updated
+                */
+               ic_status = dw_readl(dev, DW_IC_STATUS);
+               if (!dev->dynamic_tar_update_enabled ||
+                   (ic_status & DW_IC_STATUS_MST_ACTIVITY) ||
+                   !(ic_status & DW_IC_STATUS_TFE)) {
+                       __i2c_dw_enable_and_wait(dev, false);
+                       enabled = false;
+               }
+       }
 
        /* if the slave address is ten bit address, enable 10BITADDR */
-       ic_con = dw_readl(dev, DW_IC_CON);
-       if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) {
-               ic_con |= DW_IC_CON_10BITADDR_MASTER;
+       if (dev->dynamic_tar_update_enabled) {
                /*
                 * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing
-                * mode has to be enabled via bit 12 of IC_TAR register.
-                * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be
-                * detected from registers.
+                * mode has to be enabled via bit 12 of IC_TAR register,
+                * otherwise bit 4 of IC_CON is used.
                 */
-               ic_tar = DW_IC_TAR_10BITADDR_MASTER;
+               if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
+                       ic_tar = DW_IC_TAR_10BITADDR_MASTER;
        } else {
-               ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
-       }
+               u32 ic_con = dw_readl(dev, DW_IC_CON);
 
-       dw_writel(dev, ic_con, DW_IC_CON);
+               if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
+                       ic_con |= DW_IC_CON_10BITADDR_MASTER;
+               else
+                       ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
+               dw_writel(dev, ic_con, DW_IC_CON);
+       }
 
        /*
         * Set the slave (target) address and enable 10-bit addressing mode
@@ -446,8 +515,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
        /* enforce disabled interrupts (due to HW issues) */
        i2c_dw_disable_int(dev);
 
-       /* Enable the adapter */
-       __i2c_dw_enable(dev, true);
+       if (!enabled)
+               __i2c_dw_enable(dev, true);
 
        /* Clear and enable interrupts */
        dw_readl(dev, DW_IC_CLR_INTR);
@@ -628,7 +697,8 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
 }
 
 /*
- * Prepare controller for a transaction and call i2c_dw_xfer_msg
+ * Prepare controller for a transaction and start transfer by calling
+ * i2c_dw_xfer_init()
  */
 static int
 i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
@@ -651,13 +721,9 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        dev->abort_source = 0;
        dev->rx_outstanding = 0;
 
-       if (dev->acquire_lock) {
-               ret = dev->acquire_lock(dev);
-               if (ret) {
-                       dev_err(dev->dev, "couldn't acquire bus ownership\n");
-                       goto done_nolock;
-               }
-       }
+       ret = i2c_dw_acquire_lock(dev);
+       if (ret)
+               goto done_nolock;
 
        ret = i2c_dw_wait_bus_not_busy(dev);
        if (ret < 0)
@@ -675,16 +741,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
                goto done;
        }
 
-       /*
-        * We must disable the adapter before returning and signaling the end
-        * of the current transfer. Otherwise the hardware might continue
-        * generating interrupts which in turn causes a race condition with
-        * the following transfer.  Needs some more investigation if the
-        * additional interrupts are a hardware bug or this driver doesn't
-        * handle them correctly yet.
-        */
-       __i2c_dw_enable(dev, false);
-
        if (dev->msg_err) {
                ret = dev->msg_err;
                goto done;
@@ -704,8 +760,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        ret = -EIO;
 
 done:
-       if (dev->release_lock)
-               dev->release_lock(dev);
+       i2c_dw_release_lock(dev);
 
 done_nolock:
        pm_runtime_mark_last_busy(dev->dev);
@@ -822,9 +877,19 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
         */
 
 tx_aborted:
-       if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
+       if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET))
+                       || dev->msg_err) {
+               /*
+                * We must disable interruts before returning and signaling
+                * the end of the current transfer. Otherwise the hardware
+                * might continue generating interrupts for non-existent
+                * transfers.
+                */
+               i2c_dw_disable_int(dev);
+               dw_readl(dev, DW_IC_CLR_INTR);
+
                complete(&dev->cmd_complete);
-       else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+       else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
                /* workaround to trigger pending interrupt */
                stat = dw_readl(dev, DW_IC_INTR_MASK);
                i2c_dw_disable_int(dev);
@@ -837,7 +902,7 @@ tx_aborted:
 void i2c_dw_disable(struct dw_i2c_dev *dev)
 {
        /* Disable controller */
-       __i2c_dw_enable(dev, false);
+       __i2c_dw_enable_and_wait(dev, false);
 
        /* Disable all interupts */
        dw_writel(dev, 0, DW_IC_INTR_MASK);
@@ -861,6 +926,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
 {
        struct i2c_adapter *adap = &dev->adapter;
        int r;
+       u32 reg;
 
        init_completion(&dev->cmd_complete);
 
@@ -868,6 +934,26 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
        if (r)
                return r;
 
+       r = i2c_dw_acquire_lock(dev);
+       if (r)
+               return r;
+
+       /*
+        * Test if dynamic TAR update is enabled in this controller by writing
+        * to IC_10BITADDR_MASTER field in IC_CON: when it is enabled this
+        * field is read-only so it should not succeed
+        */
+       reg = dw_readl(dev, DW_IC_CON);
+       dw_writel(dev, reg ^ DW_IC_CON_10BITADDR_MASTER, DW_IC_CON);
+
+       if ((dw_readl(dev, DW_IC_CON) & DW_IC_CON_10BITADDR_MASTER) ==
+           (reg & DW_IC_CON_10BITADDR_MASTER)) {
+               dev->dynamic_tar_update_enabled = true;
+               dev_dbg(dev->dev, "Dynamic TAR update enabled");
+       }
+
+       i2c_dw_release_lock(dev);
+
        snprintf(adap->name, sizeof(adap->name),
                 "Synopsys DesignWare I2C adapter");
        adap->retries = 3;
index 38493a7142ad4ae7b5f765cfabf3a6fec7fd2264..0d44d2ae7d4c2ea9d091f446bccc76efa98f926d 100644 (file)
@@ -26,6 +26,7 @@
 #define DW_IC_CON_MASTER               0x1
 #define DW_IC_CON_SPEED_STD            0x2
 #define DW_IC_CON_SPEED_FAST           0x4
+#define DW_IC_CON_SPEED_HIGH           0x6
 #define DW_IC_CON_SPEED_MASK           0x6
 #define DW_IC_CON_10BITADDR_MASTER     0x10
 #define DW_IC_CON_RESTART_EN           0x20
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_outstanding: current master-rx elements in tx fifo
+ * @clk_freq: bus clock frequency
  * @ss_hcnt: standard speed HCNT value
  * @ss_lcnt: standard speed LCNT value
  * @fs_hcnt: fast speed HCNT value
  * @fs_lcnt: fast speed LCNT value
+ * @fp_hcnt: fast plus HCNT value
+ * @fp_lcnt: fast plus LCNT value
+ * @hs_hcnt: high speed HCNT value
+ * @hs_lcnt: high speed LCNT value
  * @acquire_lock: function to acquire a hardware lock on the bus
  * @release_lock: function to release a hardware lock on the bus
  * @pm_runtime_disabled: true if pm runtime is disabled
@@ -96,6 +102,7 @@ struct dw_i2c_dev {
        unsigned int            tx_fifo_depth;
        unsigned int            rx_fifo_depth;
        int                     rx_outstanding;
+       u32                     clk_freq;
        u32                     sda_hold_time;
        u32                     sda_falling_time;
        u32                     scl_falling_time;
@@ -103,9 +110,14 @@ struct dw_i2c_dev {
        u16                     ss_lcnt;
        u16                     fs_hcnt;
        u16                     fs_lcnt;
+       u16                     fp_hcnt;
+       u16                     fp_lcnt;
+       u16                     hs_hcnt;
+       u16                     hs_lcnt;
        int                     (*acquire_lock)(struct dw_i2c_dev *dev);
        void                    (*release_lock)(struct dw_i2c_dev *dev);
        bool                    pm_runtime_disabled;
+       bool                    dynamic_tar_update_enabled;
 };
 
 #define ACCESS_SWAP            0x00000001
index d656657b805c20dafdfc28925c09179705789eae..0b42a12171f3a146ddc61ac6e2ed6d9d9cacf12e 100644 (file)
@@ -107,6 +107,8 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL);
        dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
                           &dev->sda_hold_time);
+       dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, NULL);
+       dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, NULL);
 
        id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
        if (id && id->driver_data)
@@ -155,7 +157,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        struct i2c_adapter *adap;
        struct resource *mem;
        int irq, r;
-       u32 clk_freq, ht = 0;
+       u32 acpi_speed, ht = 0;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
@@ -175,10 +177,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);
 
        /* fast mode by default because of legacy reasons */
-       clk_freq = 400000;
+       dev->clk_freq = 400000;
 
        if (pdata) {
-               clk_freq = pdata->i2c_scl_freq;
+               dev->clk_freq = pdata->i2c_scl_freq;
        } else {
                device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
                                         &ht);
@@ -187,17 +189,24 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
                device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
                                         &dev->scl_falling_time);
                device_property_read_u32(&pdev->dev, "clock-frequency",
-                                        &clk_freq);
+                                        &dev->clk_freq);
        }
 
+       acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
+       if (acpi_speed)
+               dev->clk_freq = acpi_speed;
+
        if (has_acpi_companion(&pdev->dev))
                dw_i2c_acpi_configure(pdev);
 
        /*
-        * Only standard mode at 100kHz and fast mode at 400kHz are supported.
+        * Only standard mode at 100kHz, fast mode at 400kHz,
+        * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
         */
-       if (clk_freq != 100000 && clk_freq != 400000) {
-               dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
+       if (dev->clk_freq != 100000 && dev->clk_freq != 400000
+           && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
+               dev_err(&pdev->dev,
+                       "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
                return -EINVAL;
        }
 
@@ -212,12 +221,20 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
                I2C_FUNC_SMBUS_BYTE_DATA |
                I2C_FUNC_SMBUS_WORD_DATA |
                I2C_FUNC_SMBUS_I2C_BLOCK;
-       if (clk_freq == 100000)
-               dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-                       DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_STD;
-       else
-               dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-                       DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
+
+       dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
+                         DW_IC_CON_RESTART_EN;
+
+       switch (dev->clk_freq) {
+       case 100000:
+               dev->master_cfg |= DW_IC_CON_SPEED_STD;
+               break;
+       case 3400000:
+               dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
+               break;
+       default:
+               dev->master_cfg |= DW_IC_CON_SPEED_FAST;
+       }
 
        dev->clk = devm_clk_get(&pdev->dev, NULL);
        if (!i2c_dw_plat_prepare_clk(dev, true)) {
index b19a310bf9b3e822121cfcf48c1a01856fcabe67..f718ee4e3332fe3ced0cf3abff9c59b21f56b99b 100644 (file)
@@ -487,10 +487,8 @@ static int diolan_u2c_probe(struct usb_interface *interface,
 
        /* and finally attach to i2c layer */
        ret = i2c_add_adapter(&dev->adapter);
-       if (ret < 0) {
-               dev_err(&interface->dev, "failed to add I2C adapter\n");
+       if (ret < 0)
                goto error_free;
-       }
 
        dev_dbg(&interface->dev, "connected " DRIVER_NAME "\n");
 
index f2eb4f76591fbe5006c03eb3e61972d9d7f2d0e4..8acda2aa15583c327221d4f9a30f74566123aaee 100644 (file)
@@ -228,10 +228,8 @@ static int dln2_i2c_probe(struct platform_device *pdev)
 
        /* and finally attach to i2c layer */
        ret = i2c_add_adapter(&dln2->adapter);
-       if (ret < 0) {
-               dev_err(dev, "failed to add I2C adapter: %d\n", ret);
+       if (ret < 0)
                goto out_disable;
-       }
 
        return 0;
 
index e253598d764c0d1429e18982a3f8f4a2d32b77a4..aa336ba89aa3fe93ca07b224b851881ff98c9d92 100644 (file)
@@ -438,7 +438,6 @@ static int efm32_i2c_probe(struct platform_device *pdev)
 
        ret = i2c_add_adapter(&ddata->adapter);
        if (ret) {
-               dev_err(&pdev->dev, "failed to add i2c adapter (%d)\n", ret);
                free_irq(ddata->irq, ddata);
 
 err_disable_clk:
index c0e3ada028763d3e615c98f0998db8b169eb12be..bea607149972d4c3e7f412ff0cd28a1d0df9c6e7 100644 (file)
@@ -796,10 +796,8 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
        exynos5_i2c_reset(i2c);
 
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+       if (ret < 0)
                goto err_clk;
-       }
 
        platform_set_drvdata(pdev, i2c);
 
index 7c6966434ee7b9a2707da849e56128af41c0baf5..ae7f3180f7e88747aab4a92282a1b6b685ced405 100644 (file)
@@ -478,10 +478,8 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
        pm_runtime_enable(priv->dev);
 
        ret = i2c_add_adapter(&priv->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+       if (ret < 0)
                goto err_runtime;
-       }
 
        return ret;
 
index 26298af73232e417a40788206b0fef5fa5a37cd1..08847e8b899872e2bc1bffd1d0936f63ee4f38d7 100644 (file)
@@ -64,6 +64,7 @@
  * Broxton (SOC)               0x5ad4  32      hard    yes     yes     yes
  * Lewisburg (PCH)             0xa1a3  32      hard    yes     yes     yes
  * Lewisburg Supersku (PCH)    0xa223  32      hard    yes     yes     yes
+ * Kaby Lake PCH-H (PCH)       0xa2a3  32      hard    yes     yes     yes
  *
  * Features supported by this driver:
  * Software PEC                                no
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS       0xa123
 #define PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS            0xa1a3
 #define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS       0xa223
+#define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS       0xa2a3
 
 struct i801_mux_config {
        char *gpio_chip;
@@ -1006,6 +1008,7 @@ static const struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) },
        { 0, }
 };
 
@@ -1482,6 +1485,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
        case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS:
        case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS:
        case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
+       case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS:
                priv->features |= FEATURE_I2C_BLOCK_READ;
                priv->features |= FEATURE_IRQ;
                priv->features |= FEATURE_SMBUS_PEC;
@@ -1615,7 +1619,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
                "SMBus I801 adapter at %04lx", priv->smba);
        err = i2c_add_adapter(&priv->adapter);
        if (err) {
-               dev_err(&dev->dev, "Failed to add SMBus adapter\n");
                i801_acpi_remove(priv);
                return err;
        }
index cdaa7be2cd1b940647df6d98b11edd8a2f7c67ef..412b91d255ad1d7e62ef6bb7d6b2518172c4d0e9 100644 (file)
@@ -751,10 +751,8 @@ static int iic_probe(struct platform_device *ofdev)
        adap->timeout = HZ;
 
        ret = i2c_add_adapter(adap);
-       if (ret  < 0) {
-               dev_err(&ofdev->dev, "failed to register i2c adapter\n");
+       if (ret  < 0)
                goto error_cleanup;
-       }
 
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
index ea20425b6972179c037abb239ecde0b4b4f1994f..db8e8b40569d98aa2a4f107eddf574f0e5a31cd2 100644 (file)
@@ -1394,10 +1394,8 @@ static int img_i2c_probe(struct platform_device *pdev)
                goto disable_clk;
 
        ret = i2c_add_numbered_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add adapter\n");
+       if (ret < 0)
                goto disable_clk;
-       }
 
        return 0;
 
index 1844bc9f7cd5a229d3c9f169c5d3ef78429c60c1..592a8f26a708db4cb331da5906c492f7af06a6a8 100644 (file)
@@ -984,11 +984,24 @@ static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
        pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_default);
 }
 
-static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
+/*
+ * We switch SCL and SDA to their GPIO function and do some bitbanging
+ * for bus recovery. These alternative pinmux settings can be
+ * described in the device tree by a separate pinctrl state "gpio". If
+ * this is missing this is not a big problem, the only implication is
+ * that we can't do bus recovery.
+ */
+static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
                struct platform_device *pdev)
 {
        struct i2c_bus_recovery_info *rinfo = &i2c_imx->rinfo;
 
+       i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (!i2c_imx->pinctrl || IS_ERR(i2c_imx->pinctrl)) {
+               dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n");
+               return PTR_ERR(i2c_imx->pinctrl);
+       }
+
        i2c_imx->pinctrl_pins_default = pinctrl_lookup_state(i2c_imx->pinctrl,
                        PINCTRL_STATE_DEFAULT);
        i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
@@ -1001,7 +1014,7 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
            IS_ERR(i2c_imx->pinctrl_pins_default) ||
            IS_ERR(i2c_imx->pinctrl_pins_gpio)) {
                dev_dbg(&pdev->dev, "recovery information incomplete\n");
-               return;
+               return 0;
        }
 
        dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
@@ -1011,6 +1024,8 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
        rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
        rinfo->recover_bus = i2c_generic_gpio_recovery;
        i2c_imx->adapter.bus_recovery_info = rinfo;
+
+       return 0;
 }
 
 static u32 i2c_imx_func(struct i2c_adapter *adapter)
@@ -1081,12 +1096,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
                return ret;
        }
 
-       i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
-       if (IS_ERR(i2c_imx->pinctrl)) {
-               ret = PTR_ERR(i2c_imx->pinctrl);
-               goto clk_disable;
-       }
-
        /* Request IRQ */
        ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
                                pdev->name, i2c_imx);
@@ -1125,14 +1134,16 @@ static int i2c_imx_probe(struct platform_device *pdev)
                        i2c_imx, IMX_I2C_I2CR);
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
 
-       i2c_imx_init_recovery_info(i2c_imx, pdev);
+       /* Init optional bus recovery function */
+       ret = i2c_imx_init_recovery_info(i2c_imx, pdev);
+       /* Give it another chance if pinctrl used is not ready yet */
+       if (ret == -EPROBE_DEFER)
+               goto rpm_disable;
 
        /* Add I2C adapter */
        ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "registration failed\n");
+       if (ret < 0)
                goto rpm_disable;
-       }
 
        pm_runtime_mark_last_busy(&pdev->dev);
        pm_runtime_put_autosuspend(&pdev->dev);
index c2f25f19d76f9bb4bd5832a4a6c8b72b80391dbb..0cf1379f4e8091b8627ed5bdf5c3dfe03a536630 100644 (file)
@@ -288,10 +288,8 @@ static int smbus_sch_probe(struct platform_device *dev)
                "SMBus SCH adapter at %04x", sch_smba);
 
        retval = i2c_add_adapter(&sch_adapter);
-       if (retval) {
-               dev_err(&dev->dev, "Couldn't register adapter!\n");
+       if (retval)
                sch_smba = 0;
-       }
 
        return retval;
 }
index 1c8707710098405ce485cf310d519bee20ff6966..f573448d2132161d4839a17d11afb1c1f4104188 100644 (file)
@@ -922,10 +922,8 @@ ismt_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                return err;
 
        err = i2c_add_adapter(&priv->adapter);
-       if (err) {
-               dev_err(&pdev->dev, "Failed to add SMBus iSMT adapter\n");
+       if (err)
                return -ENODEV;
-       }
        return 0;
 }
 
index cd9872594fe2a057b5c0b646c1b38ca56cc54814..b8ea62105f42c99205c1a241176ebb7210a55c08 100644 (file)
@@ -798,10 +798,8 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
                goto err;
 
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to add bus\n");
+       if (ret < 0)
                goto err;
-       }
 
        return 0;
 
index 586a15205e61ded5757ef01e107d96a0a2915e01..9b1fef455a895d6174dd9f4b4775f75f5461ebe8 100644 (file)
@@ -432,10 +432,8 @@ static int i2c_lpc2k_probe(struct platform_device *pdev)
        i2c->adap.dev.of_node = pdev->dev.of_node;
 
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add adapter!\n");
+       if (ret < 0)
                goto fail_clk;
-       }
 
        dev_info(&pdev->dev, "LPC2K I2C adapter\n");
 
index 76e28980904f0b166971ffa09688f4302f067c5b..2aa61bbbd307b9aead3730e137bbf5b95e29a366 100644 (file)
@@ -453,7 +453,6 @@ static int meson_i2c_probe(struct platform_device *pdev)
 
        ret = i2c_add_adapter(&i2c->adap);
        if (ret < 0) {
-               dev_err(&pdev->dev, "can't register adapter\n");
                clk_unprepare(i2c->clk);
                return ret;
        }
@@ -473,6 +472,7 @@ static int meson_i2c_remove(struct platform_device *pdev)
 
 static const struct of_device_id meson_i2c_match[] = {
        { .compatible = "amlogic,meson6-i2c" },
+       { .compatible = "amlogic,meson-gxbb-i2c" },
        { },
 };
 MODULE_DEVICE_TABLE(of, meson_i2c_match);
index 48ecffecc0eda3fb42e63ff19a6e93d2f49ed918..565a49a0c564105e3cadf56bf3944e1b76ab505f 100644 (file)
@@ -737,10 +737,8 @@ static int fsl_i2c_probe(struct platform_device *op)
        i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
 
        result = i2c_add_adapter(&i2c->adap);
-       if (result < 0) {
-               dev_err(i2c->dev, "failed to add adapter\n");
+       if (result < 0)
                goto fail_add;
-       }
 
        return result;
 
index d9373e60be8ae307336041581f3b8e10fcb0a0b3..4a7d9bc2142ba31db7579ed140cfbe6ed5224c02 100644 (file)
@@ -786,10 +786,8 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 
        i2c_set_adapdata(&i2c->adap, i2c);
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add i2c bus to i2c core\n");
+       if (ret)
                return ret;
-       }
 
        platform_set_drvdata(pdev, i2c);
 
index 033846cdf266227a767b24546c8eda54444f2d3c..5738556b6aac20cb45f7c3060aa634de379f5b8e 100644 (file)
@@ -868,7 +868,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(adap, i2c);
        err = i2c_add_numbered_adapter(adap);
        if (err) {
-               dev_err(dev, "Failed to add adapter (%d)\n", err);
                writel(MXS_I2C_CTRL0_SFTRST,
                                i2c->regs + MXS_I2C_CTRL0_SET);
                return err;
index 42fcc9458432f8abc2f25ededee424124551a784..374b35e7e450ce55ea97f7438864100c90f68b66 100644 (file)
@@ -366,7 +366,6 @@ static int nforce2_probe_smb(struct pci_dev *dev, int bar, int alt_reg,
 
        error = i2c_add_adapter(&smbus->adapter);
        if (error) {
-               dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
                release_region(smbus->base, smbus->size);
                return error;
        }
index bcd17e8cbcb4b3cc8bb5b6aee7d4d6e2873df8b6..da6609d628487b161a531d37145e681c13500965 100644 (file)
@@ -1046,10 +1046,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
                 adap->name, dev->virtbase);
 
        ret = i2c_add_adapter(adap);
-       if (ret) {
-               dev_err(&adev->dev, "failed to add adapter\n");
+       if (ret)
                goto err_no_adap;
-       }
 
        pm_runtime_put(&adev->dev);
 
index ac88a524143e07406bc2e4837a80a8ac17a4bd91..34f1889a407368e7bb14ecbfba3e86d28730c21d 100644 (file)
@@ -494,10 +494,8 @@ static int ocores_i2c_probe(struct platform_device *pdev)
 
        /* add i2c adapter to i2c tree */
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add adapter\n");
+       if (ret)
                goto err_clk;
-       }
 
        /* add in known devices to the bus */
        if (pdata) {
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
new file mode 100644 (file)
index 0000000..419b54b
--- /dev/null
@@ -0,0 +1,827 @@
+/*
+ * (C) Copyright 2009-2010
+ * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
+ *
+ * Portions Copyright (C) 2010 - 2016 Cavium, Inc.
+ *
+ * This file contains the shared part of the driver for the i2c adapter in
+ * Cavium Networks' OCTEON processors and ThunderX SOCs.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "i2c-octeon-core.h"
+
+/* interrupt service routine */
+irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
+{
+       struct octeon_i2c *i2c = dev_id;
+
+       i2c->int_disable(i2c);
+       wake_up(&i2c->queue);
+
+       return IRQ_HANDLED;
+}
+
+static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c)
+{
+       return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG);
+}
+
+static bool octeon_i2c_test_ready(struct octeon_i2c *i2c, bool *first)
+{
+       if (octeon_i2c_test_iflg(i2c))
+               return true;
+
+       if (*first) {
+               *first = false;
+               return false;
+       }
+
+       /*
+        * IRQ has signaled an event but IFLG hasn't changed.
+        * Sleep and retry once.
+        */
+       usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
+       return octeon_i2c_test_iflg(i2c);
+}
+
+/**
+ * octeon_i2c_wait - wait for the IFLG to be set
+ * @i2c: The struct octeon_i2c
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_wait(struct octeon_i2c *i2c)
+{
+       long time_left;
+       bool first = true;
+
+       /*
+        * Some chip revisions don't assert the irq in the interrupt
+        * controller. So we must poll for the IFLG change.
+        */
+       if (i2c->broken_irq_mode) {
+               u64 end = get_jiffies_64() + i2c->adap.timeout;
+
+               while (!octeon_i2c_test_iflg(i2c) &&
+                      time_before64(get_jiffies_64(), end))
+                       usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
+
+               return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT;
+       }
+
+       i2c->int_enable(i2c);
+       time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_ready(i2c, &first),
+                                      i2c->adap.timeout);
+       i2c->int_disable(i2c);
+
+       if (i2c->broken_irq_check && !time_left &&
+           octeon_i2c_test_iflg(i2c)) {
+               dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
+               i2c->broken_irq_mode = true;
+               return 0;
+       }
+
+       if (!time_left)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
+{
+       return (__raw_readq(i2c->twsi_base + SW_TWSI(i2c)) & SW_TWSI_V) == 0;
+}
+
+static bool octeon_i2c_hlc_test_ready(struct octeon_i2c *i2c, bool *first)
+{
+       /* check if valid bit is cleared */
+       if (octeon_i2c_hlc_test_valid(i2c))
+               return true;
+
+       if (*first) {
+               *first = false;
+               return false;
+       }
+
+       /*
+        * IRQ has signaled an event but valid bit isn't cleared.
+        * Sleep and retry once.
+        */
+       usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
+       return octeon_i2c_hlc_test_valid(i2c);
+}
+
+static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
+{
+       /* clear ST/TS events, listen for neither */
+       octeon_i2c_write_int(i2c, TWSI_INT_ST_INT | TWSI_INT_TS_INT);
+}
+
+/*
+ * Cleanup low-level state & enable high-level controller.
+ */
+static void octeon_i2c_hlc_enable(struct octeon_i2c *i2c)
+{
+       int try = 0;
+       u64 val;
+
+       if (i2c->hlc_enabled)
+               return;
+       i2c->hlc_enabled = true;
+
+       while (1) {
+               val = octeon_i2c_ctl_read(i2c);
+               if (!(val & (TWSI_CTL_STA | TWSI_CTL_STP)))
+                       break;
+
+               /* clear IFLG event */
+               if (val & TWSI_CTL_IFLG)
+                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+
+               if (try++ > 100) {
+                       pr_err("%s: giving up\n", __func__);
+                       break;
+               }
+
+               /* spin until any start/stop has finished */
+               udelay(10);
+       }
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_CE | TWSI_CTL_AAK | TWSI_CTL_ENAB);
+}
+
+static void octeon_i2c_hlc_disable(struct octeon_i2c *i2c)
+{
+       if (!i2c->hlc_enabled)
+               return;
+
+       i2c->hlc_enabled = false;
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+}
+
+/**
+ * octeon_i2c_hlc_wait - wait for an HLC operation to complete
+ * @i2c: The struct octeon_i2c
+ *
+ * Returns 0 on success, otherwise -ETIMEDOUT.
+ */
+static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
+{
+       bool first = true;
+       int time_left;
+
+       /*
+        * Some cn38xx boards don't assert the irq in the interrupt
+        * controller. So we must poll for the valid bit change.
+        */
+       if (i2c->broken_irq_mode) {
+               u64 end = get_jiffies_64() + i2c->adap.timeout;
+
+               while (!octeon_i2c_hlc_test_valid(i2c) &&
+                      time_before64(get_jiffies_64(), end))
+                       usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
+
+               return octeon_i2c_hlc_test_valid(i2c) ? 0 : -ETIMEDOUT;
+       }
+
+       i2c->hlc_int_enable(i2c);
+       time_left = wait_event_timeout(i2c->queue,
+                                      octeon_i2c_hlc_test_ready(i2c, &first),
+                                      i2c->adap.timeout);
+       i2c->hlc_int_disable(i2c);
+       if (!time_left)
+               octeon_i2c_hlc_int_clear(i2c);
+
+       if (i2c->broken_irq_check && !time_left &&
+           octeon_i2c_hlc_test_valid(i2c)) {
+               dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
+               i2c->broken_irq_mode = true;
+               return 0;
+       }
+
+       if (!time_left)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
+{
+       u8 stat;
+
+       /*
+        * This is ugly... in HLC mode the status is not in the status register
+        * but in the lower 8 bits of SW_TWSI.
+        */
+       if (i2c->hlc_enabled)
+               stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       else
+               stat = octeon_i2c_stat_read(i2c);
+
+       switch (stat) {
+       /* Everything is fine */
+       case STAT_IDLE:
+       case STAT_AD2W_ACK:
+       case STAT_RXADDR_ACK:
+       case STAT_TXADDR_ACK:
+       case STAT_TXDATA_ACK:
+               return 0;
+
+       /* ACK allowed on pre-terminal bytes only */
+       case STAT_RXDATA_ACK:
+               if (!final_read)
+                       return 0;
+               return -EIO;
+
+       /* NAK allowed on terminal byte only */
+       case STAT_RXDATA_NAK:
+               if (final_read)
+                       return 0;
+               return -EIO;
+
+       /* Arbitration lost */
+       case STAT_LOST_ARB_38:
+       case STAT_LOST_ARB_68:
+       case STAT_LOST_ARB_78:
+       case STAT_LOST_ARB_B0:
+               return -EAGAIN;
+
+       /* Being addressed as slave, should back off & listen */
+       case STAT_SLAVE_60:
+       case STAT_SLAVE_70:
+       case STAT_GENDATA_ACK:
+       case STAT_GENDATA_NAK:
+               return -EOPNOTSUPP;
+
+       /* Core busy as slave */
+       case STAT_SLAVE_80:
+       case STAT_SLAVE_88:
+       case STAT_SLAVE_A0:
+       case STAT_SLAVE_A8:
+       case STAT_SLAVE_LOST:
+       case STAT_SLAVE_NAK:
+       case STAT_SLAVE_ACK:
+               return -EOPNOTSUPP;
+
+       case STAT_TXDATA_NAK:
+               return -EIO;
+       case STAT_TXADDR_NAK:
+       case STAT_RXADDR_NAK:
+       case STAT_AD2W_NAK:
+               return -ENXIO;
+       default:
+               dev_err(i2c->dev, "unhandled state: %d\n", stat);
+               return -EIO;
+       }
+}
+
+static int octeon_i2c_recovery(struct octeon_i2c *i2c)
+{
+       int ret;
+
+       ret = i2c_recover_bus(&i2c->adap);
+       if (ret)
+               /* recover failed, try hardware re-init */
+               ret = octeon_i2c_init_lowlevel(i2c);
+       return ret;
+}
+
+/**
+ * octeon_i2c_start - send START to the bus
+ * @i2c: The struct octeon_i2c
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_start(struct octeon_i2c *i2c)
+{
+       int ret;
+       u8 stat;
+
+       octeon_i2c_hlc_disable(i2c);
+
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STA);
+       ret = octeon_i2c_wait(i2c);
+       if (ret)
+               goto error;
+
+       stat = octeon_i2c_stat_read(i2c);
+       if (stat == STAT_START || stat == STAT_REP_START)
+               /* START successful, bail out */
+               return 0;
+
+error:
+       /* START failed, try to recover */
+       ret = octeon_i2c_recovery(i2c);
+       return (ret) ? ret : -EAGAIN;
+}
+
+/* send STOP to the bus */
+static void octeon_i2c_stop(struct octeon_i2c *i2c)
+{
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STP);
+}
+
+/**
+ * octeon_i2c_read - receive data from the bus via low-level controller
+ * @i2c: The struct octeon_i2c
+ * @target: Target address
+ * @data: Pointer to the location to store the data
+ * @rlength: Length of the data
+ * @recv_len: flag for length byte
+ *
+ * The address is sent over the bus, then the data is read.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
+                          u8 *data, u16 *rlength, bool recv_len)
+{
+       int i, result, length = *rlength;
+       bool final_read = false;
+
+       octeon_i2c_data_write(i2c, (target << 1) | 1);
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+
+       result = octeon_i2c_wait(i2c);
+       if (result)
+               return result;
+
+       /* address OK ? */
+       result = octeon_i2c_check_status(i2c, false);
+       if (result)
+               return result;
+
+       for (i = 0; i < length; i++) {
+               /*
+                * For the last byte to receive TWSI_CTL_AAK must not be set.
+                *
+                * A special case is I2C_M_RECV_LEN where we don't know the
+                * additional length yet. If recv_len is set we assume we're
+                * not reading the final byte and therefore need to set
+                * TWSI_CTL_AAK.
+                */
+               if ((i + 1 == length) && !(recv_len && i == 0))
+                       final_read = true;
+
+               /* clear iflg to allow next event */
+               if (final_read)
+                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+               else
+                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_AAK);
+
+               result = octeon_i2c_wait(i2c);
+               if (result)
+                       return result;
+
+               data[i] = octeon_i2c_data_read(i2c, &result);
+               if (result)
+                       return result;
+               if (recv_len && i == 0) {
+                       if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
+                               return -EPROTO;
+                       length += data[i];
+               }
+
+               result = octeon_i2c_check_status(i2c, final_read);
+               if (result)
+                       return result;
+       }
+       *rlength = length;
+       return 0;
+}
+
+/**
+ * octeon_i2c_write - send data to the bus via low-level controller
+ * @i2c: The struct octeon_i2c
+ * @target: Target address
+ * @data: Pointer to the data to be sent
+ * @length: Length of the data
+ *
+ * The address is sent over the bus, then the data.
+ *
+ * Returns 0 on success, otherwise a negative errno.
+ */
+static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
+                           const u8 *data, int length)
+{
+       int i, result;
+
+       octeon_i2c_data_write(i2c, target << 1);
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+
+       result = octeon_i2c_wait(i2c);
+       if (result)
+               return result;
+
+       for (i = 0; i < length; i++) {
+               result = octeon_i2c_check_status(i2c, false);
+               if (result)
+                       return result;
+
+               octeon_i2c_data_write(i2c, data[i]);
+               octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+
+               result = octeon_i2c_wait(i2c);
+               if (result)
+                       return result;
+       }
+
+       return 0;
+}
+
+/* high-level-controller pure read of up to 8 bytes */
+static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
+{
+       int i, j, ret = 0;
+       u64 cmd;
+
+       octeon_i2c_hlc_enable(i2c);
+       octeon_i2c_hlc_int_clear(i2c);
+
+       cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
+       /* SIZE */
+       cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
+       /* A */
+       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
+
+       if (msgs[0].flags & I2C_M_TEN)
+               cmd |= SW_TWSI_OP_10;
+       else
+               cmd |= SW_TWSI_OP_7;
+
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       ret = octeon_i2c_hlc_wait(i2c);
+       if (ret)
+               goto err;
+
+       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       if ((cmd & SW_TWSI_R) == 0)
+               return octeon_i2c_check_status(i2c, false);
+
+       for (i = 0, j = msgs[0].len - 1; i  < msgs[0].len && i < 4; i++, j--)
+               msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
+
+       if (msgs[0].len > 4) {
+               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+               for (i = 0; i  < msgs[0].len - 4 && i < 4; i++, j--)
+                       msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
+       }
+
+err:
+       return ret;
+}
+
+/* high-level-controller pure write of up to 8 bytes */
+static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
+{
+       int i, j, ret = 0;
+       u64 cmd;
+
+       octeon_i2c_hlc_enable(i2c);
+       octeon_i2c_hlc_int_clear(i2c);
+
+       cmd = SW_TWSI_V | SW_TWSI_SOVR;
+       /* SIZE */
+       cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
+       /* A */
+       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
+
+       if (msgs[0].flags & I2C_M_TEN)
+               cmd |= SW_TWSI_OP_10;
+       else
+               cmd |= SW_TWSI_OP_7;
+
+       for (i = 0, j = msgs[0].len - 1; i  < msgs[0].len && i < 4; i++, j--)
+               cmd |= (u64)msgs[0].buf[j] << (8 * i);
+
+       if (msgs[0].len > 4) {
+               u64 ext = 0;
+
+               for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
+                       ext |= (u64)msgs[0].buf[j] << (8 * i);
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+       }
+
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       ret = octeon_i2c_hlc_wait(i2c);
+       if (ret)
+               goto err;
+
+       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       if ((cmd & SW_TWSI_R) == 0)
+               return octeon_i2c_check_status(i2c, false);
+
+err:
+       return ret;
+}
+
+/* high-level-controller composite write+read, msg0=addr, msg1=data */
+static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
+{
+       int i, j, ret = 0;
+       u64 cmd;
+
+       octeon_i2c_hlc_enable(i2c);
+
+       cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
+       /* SIZE */
+       cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
+       /* A */
+       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
+
+       if (msgs[0].flags & I2C_M_TEN)
+               cmd |= SW_TWSI_OP_10_IA;
+       else
+               cmd |= SW_TWSI_OP_7_IA;
+
+       if (msgs[0].len == 2) {
+               u64 ext = 0;
+
+               cmd |= SW_TWSI_EIA;
+               ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
+               cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+       } else {
+               cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
+       }
+
+       octeon_i2c_hlc_int_clear(i2c);
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+
+       ret = octeon_i2c_hlc_wait(i2c);
+       if (ret)
+               goto err;
+
+       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       if ((cmd & SW_TWSI_R) == 0)
+               return octeon_i2c_check_status(i2c, false);
+
+       for (i = 0, j = msgs[1].len - 1; i  < msgs[1].len && i < 4; i++, j--)
+               msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
+
+       if (msgs[1].len > 4) {
+               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+               for (i = 0; i  < msgs[1].len - 4 && i < 4; i++, j--)
+                       msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
+       }
+
+err:
+       return ret;
+}
+
+/* high-level-controller composite write+write, m[0]len<=2, m[1]len<=8 */
+static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
+{
+       bool set_ext = false;
+       int i, j, ret = 0;
+       u64 cmd, ext = 0;
+
+       octeon_i2c_hlc_enable(i2c);
+
+       cmd = SW_TWSI_V | SW_TWSI_SOVR;
+       /* SIZE */
+       cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
+       /* A */
+       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
+
+       if (msgs[0].flags & I2C_M_TEN)
+               cmd |= SW_TWSI_OP_10_IA;
+       else
+               cmd |= SW_TWSI_OP_7_IA;
+
+       if (msgs[0].len == 2) {
+               cmd |= SW_TWSI_EIA;
+               ext |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
+               set_ext = true;
+               cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
+       } else {
+               cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
+       }
+
+       for (i = 0, j = msgs[1].len - 1; i  < msgs[1].len && i < 4; i++, j--)
+               cmd |= (u64)msgs[1].buf[j] << (8 * i);
+
+       if (msgs[1].len > 4) {
+               for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--)
+                       ext |= (u64)msgs[1].buf[j] << (8 * i);
+               set_ext = true;
+       }
+       if (set_ext)
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+
+       octeon_i2c_hlc_int_clear(i2c);
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+
+       ret = octeon_i2c_hlc_wait(i2c);
+       if (ret)
+               goto err;
+
+       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       if ((cmd & SW_TWSI_R) == 0)
+               return octeon_i2c_check_status(i2c, false);
+
+err:
+       return ret;
+}
+
+/**
+ * octeon_i2c_xfer - The driver's master_xfer function
+ * @adap: Pointer to the i2c_adapter structure
+ * @msgs: Pointer to the messages to be processed
+ * @num: Length of the MSGS array
+ *
+ * Returns the number of messages processed, or a negative errno on failure.
+ */
+int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+       int i, ret = 0;
+
+       if (num == 1) {
+               if (msgs[0].len > 0 && msgs[0].len <= 8) {
+                       if (msgs[0].flags & I2C_M_RD)
+                               ret = octeon_i2c_hlc_read(i2c, msgs);
+                       else
+                               ret = octeon_i2c_hlc_write(i2c, msgs);
+                       goto out;
+               }
+       } else if (num == 2) {
+               if ((msgs[0].flags & I2C_M_RD) == 0 &&
+                   (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
+                   msgs[0].len > 0 && msgs[0].len <= 2 &&
+                   msgs[1].len > 0 && msgs[1].len <= 8 &&
+                   msgs[0].addr == msgs[1].addr) {
+                       if (msgs[1].flags & I2C_M_RD)
+                               ret = octeon_i2c_hlc_comp_read(i2c, msgs);
+                       else
+                               ret = octeon_i2c_hlc_comp_write(i2c, msgs);
+                       goto out;
+               }
+       }
+
+       for (i = 0; ret == 0 && i < num; i++) {
+               struct i2c_msg *pmsg = &msgs[i];
+
+               /* zero-length messages are not supported */
+               if (!pmsg->len) {
+                       ret = -EOPNOTSUPP;
+                       break;
+               }
+
+               ret = octeon_i2c_start(i2c);
+               if (ret)
+                       return ret;
+
+               if (pmsg->flags & I2C_M_RD)
+                       ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf,
+                                             &pmsg->len, pmsg->flags & I2C_M_RECV_LEN);
+               else
+                       ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf,
+                                              pmsg->len);
+       }
+       octeon_i2c_stop(i2c);
+out:
+       return (ret != 0) ? ret : num;
+}
+
+/* calculate and set clock divisors */
+void octeon_i2c_set_clock(struct octeon_i2c *i2c)
+{
+       int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
+       int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
+
+       for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
+               /*
+                * An mdiv value of less than 2 seems to not work well
+                * with ds1337 RTCs, so we constrain it to larger values.
+                */
+               for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
+                       /*
+                        * For given ndiv and mdiv values check the
+                        * two closest thp values.
+                        */
+                       tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
+                       tclk *= (1 << ndiv_idx);
+                       thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
+
+                       for (inc = 0; inc <= 1; inc++) {
+                               thp_idx = thp_base + inc;
+                               if (thp_idx < 5 || thp_idx > 0xff)
+                                       continue;
+
+                               foscl = i2c->sys_freq / (2 * (thp_idx + 1));
+                               foscl = foscl / (1 << ndiv_idx);
+                               foscl = foscl / (mdiv_idx + 1) / 10;
+                               diff = abs(foscl - i2c->twsi_freq);
+                               if (diff < delta_hz) {
+                                       delta_hz = diff;
+                                       thp = thp_idx;
+                                       mdiv = mdiv_idx;
+                                       ndiv = ndiv_idx;
+                               }
+                       }
+               }
+       }
+       octeon_i2c_reg_write(i2c, SW_TWSI_OP_TWSI_CLK, thp);
+       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
+}
+
+int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
+{
+       u8 status = 0;
+       int tries;
+
+       /* reset controller */
+       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
+
+       for (tries = 10; tries && status != STAT_IDLE; tries--) {
+               udelay(1);
+               status = octeon_i2c_stat_read(i2c);
+               if (status == STAT_IDLE)
+                       break;
+       }
+
+       if (status != STAT_IDLE) {
+               dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n",
+                       __func__, status);
+               return -EIO;
+       }
+
+       /* toggle twice to force both teardowns */
+       octeon_i2c_hlc_enable(i2c);
+       octeon_i2c_hlc_disable(i2c);
+       return 0;
+}
+
+static int octeon_i2c_get_scl(struct i2c_adapter *adap)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+       u64 state;
+
+       state = octeon_i2c_read_int(i2c);
+       return state & TWSI_INT_SCL;
+}
+
+static void octeon_i2c_set_scl(struct i2c_adapter *adap, int val)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+
+       octeon_i2c_write_int(i2c, val ? 0 : TWSI_INT_SCL_OVR);
+}
+
+static int octeon_i2c_get_sda(struct i2c_adapter *adap)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+       u64 state;
+
+       state = octeon_i2c_read_int(i2c);
+       return state & TWSI_INT_SDA;
+}
+
+static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+
+       octeon_i2c_hlc_disable(i2c);
+
+       /*
+        * Bring control register to a good state regardless
+        * of HLC state.
+        */
+       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
+
+       octeon_i2c_write_int(i2c, 0);
+}
+
+static void octeon_i2c_unprepare_recovery(struct i2c_adapter *adap)
+{
+       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
+
+       /*
+        * Generate STOP to finish the unfinished transaction.
+        * Can't generate STOP via the TWSI CTL register
+        * since it could bring the TWSI controller into an inoperable state.
+        */
+       octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR | TWSI_INT_SCL_OVR);
+       udelay(5);
+       octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR);
+       udelay(5);
+       octeon_i2c_write_int(i2c, 0);
+}
+
+struct i2c_bus_recovery_info octeon_i2c_recovery_info = {
+       .recover_bus = i2c_generic_scl_recovery,
+       .get_scl = octeon_i2c_get_scl,
+       .set_scl = octeon_i2c_set_scl,
+       .get_sda = octeon_i2c_get_sda,
+       .prepare_recovery = octeon_i2c_prepare_recovery,
+       .unprepare_recovery = octeon_i2c_unprepare_recovery,
+};
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
new file mode 100644 (file)
index 0000000..1db7c83
--- /dev/null
@@ -0,0 +1,216 @@
+#include <linux/atomic.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-smbus.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+/* Controller command patterns */
+#define SW_TWSI_V              BIT_ULL(63)     /* Valid bit */
+#define SW_TWSI_EIA            BIT_ULL(61)     /* Extended internal address */
+#define SW_TWSI_R              BIT_ULL(56)     /* Result or read bit */
+#define SW_TWSI_SOVR           BIT_ULL(55)     /* Size override */
+#define SW_TWSI_SIZE_SHIFT     52
+#define SW_TWSI_ADDR_SHIFT     40
+#define SW_TWSI_IA_SHIFT       32              /* Internal address */
+
+/* Controller opcode word (bits 60:57) */
+#define SW_TWSI_OP_SHIFT       57
+#define SW_TWSI_OP_7           (0ULL << SW_TWSI_OP_SHIFT)
+#define SW_TWSI_OP_7_IA                (1ULL << SW_TWSI_OP_SHIFT)
+#define SW_TWSI_OP_10          (2ULL << SW_TWSI_OP_SHIFT)
+#define SW_TWSI_OP_10_IA       (3ULL << SW_TWSI_OP_SHIFT)
+#define SW_TWSI_OP_TWSI_CLK    (4ULL << SW_TWSI_OP_SHIFT)
+#define SW_TWSI_OP_EOP         (6ULL << SW_TWSI_OP_SHIFT) /* Extended opcode */
+
+/* Controller extended opcode word (bits 34:32) */
+#define SW_TWSI_EOP_SHIFT      32
+#define SW_TWSI_EOP_TWSI_DATA  (SW_TWSI_OP_EOP | 1ULL << SW_TWSI_EOP_SHIFT)
+#define SW_TWSI_EOP_TWSI_CTL   (SW_TWSI_OP_EOP | 2ULL << SW_TWSI_EOP_SHIFT)
+#define SW_TWSI_EOP_TWSI_CLKCTL        (SW_TWSI_OP_EOP | 3ULL << SW_TWSI_EOP_SHIFT)
+#define SW_TWSI_EOP_TWSI_STAT  (SW_TWSI_OP_EOP | 3ULL << SW_TWSI_EOP_SHIFT)
+#define SW_TWSI_EOP_TWSI_RST   (SW_TWSI_OP_EOP | 7ULL << SW_TWSI_EOP_SHIFT)
+
+/* Controller command and status bits */
+#define TWSI_CTL_CE            0x80    /* High level controller enable */
+#define TWSI_CTL_ENAB          0x40    /* Bus enable */
+#define TWSI_CTL_STA           0x20    /* Master-mode start, HW clears when done */
+#define TWSI_CTL_STP           0x10    /* Master-mode stop, HW clears when done */
+#define TWSI_CTL_IFLG          0x08    /* HW event, SW writes 0 to ACK */
+#define TWSI_CTL_AAK           0x04    /* Assert ACK */
+
+/* Status values */
+#define STAT_ERROR             0x00
+#define STAT_START             0x08
+#define STAT_REP_START         0x10
+#define STAT_TXADDR_ACK                0x18
+#define STAT_TXADDR_NAK                0x20
+#define STAT_TXDATA_ACK                0x28
+#define STAT_TXDATA_NAK                0x30
+#define STAT_LOST_ARB_38       0x38
+#define STAT_RXADDR_ACK                0x40
+#define STAT_RXADDR_NAK                0x48
+#define STAT_RXDATA_ACK                0x50
+#define STAT_RXDATA_NAK                0x58
+#define STAT_SLAVE_60          0x60
+#define STAT_LOST_ARB_68       0x68
+#define STAT_SLAVE_70          0x70
+#define STAT_LOST_ARB_78       0x78
+#define STAT_SLAVE_80          0x80
+#define STAT_SLAVE_88          0x88
+#define STAT_GENDATA_ACK       0x90
+#define STAT_GENDATA_NAK       0x98
+#define STAT_SLAVE_A0          0xA0
+#define STAT_SLAVE_A8          0xA8
+#define STAT_LOST_ARB_B0       0xB0
+#define STAT_SLAVE_LOST                0xB8
+#define STAT_SLAVE_NAK         0xC0
+#define STAT_SLAVE_ACK         0xC8
+#define STAT_AD2W_ACK          0xD0
+#define STAT_AD2W_NAK          0xD8
+#define STAT_IDLE              0xF8
+
+/* TWSI_INT values */
+#define TWSI_INT_ST_INT                BIT_ULL(0)
+#define TWSI_INT_TS_INT                BIT_ULL(1)
+#define TWSI_INT_CORE_INT      BIT_ULL(2)
+#define TWSI_INT_ST_EN         BIT_ULL(4)
+#define TWSI_INT_TS_EN         BIT_ULL(5)
+#define TWSI_INT_CORE_EN       BIT_ULL(6)
+#define TWSI_INT_SDA_OVR       BIT_ULL(8)
+#define TWSI_INT_SCL_OVR       BIT_ULL(9)
+#define TWSI_INT_SDA           BIT_ULL(10)
+#define TWSI_INT_SCL           BIT_ULL(11)
+
+#define I2C_OCTEON_EVENT_WAIT 80 /* microseconds */
+
+/* Register offsets */
+struct octeon_i2c_reg_offset {
+       unsigned int sw_twsi;
+       unsigned int twsi_int;
+       unsigned int sw_twsi_ext;
+};
+
+#define SW_TWSI(x)     (x->roff.sw_twsi)
+#define TWSI_INT(x)    (x->roff.twsi_int)
+#define SW_TWSI_EXT(x) (x->roff.sw_twsi_ext)
+
+struct octeon_i2c {
+       wait_queue_head_t queue;
+       struct i2c_adapter adap;
+       struct octeon_i2c_reg_offset roff;
+       struct clk *clk;
+       int irq;
+       int hlc_irq;            /* For cn7890 only */
+       u32 twsi_freq;
+       int sys_freq;
+       void __iomem *twsi_base;
+       struct device *dev;
+       bool hlc_enabled;
+       bool broken_irq_mode;
+       bool broken_irq_check;
+       void (*int_enable)(struct octeon_i2c *);
+       void (*int_disable)(struct octeon_i2c *);
+       void (*hlc_int_enable)(struct octeon_i2c *);
+       void (*hlc_int_disable)(struct octeon_i2c *);
+       atomic_t int_enable_cnt;
+       atomic_t hlc_int_enable_cnt;
+#if IS_ENABLED(CONFIG_I2C_THUNDERX)
+       struct msix_entry i2c_msix;
+#endif
+       struct i2c_smbus_alert_setup alert_data;
+       struct i2c_client *ara;
+};
+
+static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
+{
+       __raw_writeq(val, addr);
+       __raw_readq(addr);      /* wait for write to land */
+}
+
+/**
+ * octeon_i2c_reg_write - write an I2C core register
+ * @i2c: The struct octeon_i2c
+ * @eop_reg: Register selector
+ * @data: Value to be written
+ *
+ * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ */
+static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
+{
+       u64 tmp;
+
+       __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
+
+       readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp, tmp & SW_TWSI_V,
+                          I2C_OCTEON_EVENT_WAIT, i2c->adap.timeout);
+}
+
+#define octeon_i2c_ctl_write(i2c, val)                                 \
+       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, val)
+#define octeon_i2c_data_write(i2c, val)                                        \
+       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, val)
+
+/**
+ * octeon_i2c_reg_read - read lower bits of an I2C core register
+ * @i2c: The struct octeon_i2c
+ * @eop_reg: Register selector
+ *
+ * Returns the data.
+ *
+ * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ */
+static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
+                                     int *error)
+{
+       u64 tmp;
+       int ret;
+
+       __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+
+       ret = readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp,
+                                tmp & SW_TWSI_V, I2C_OCTEON_EVENT_WAIT,
+                                i2c->adap.timeout);
+       if (error)
+               *error = ret;
+       return tmp & 0xFF;
+}
+
+#define octeon_i2c_ctl_read(i2c)                                       \
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
+#define octeon_i2c_data_read(i2c, error)                               \
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
+#define octeon_i2c_stat_read(i2c)                                      \
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
+
+/**
+ * octeon_i2c_read_int - read the TWSI_INT register
+ * @i2c: The struct octeon_i2c
+ *
+ * Returns the value of the register.
+ */
+static inline u64 octeon_i2c_read_int(struct octeon_i2c *i2c)
+{
+       return __raw_readq(i2c->twsi_base + TWSI_INT(i2c));
+}
+
+/**
+ * octeon_i2c_write_int - write the TWSI_INT register
+ * @i2c: The struct octeon_i2c
+ * @data: Value to be written
+ */
+static inline void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
+{
+       octeon_i2c_writeq_flush(data, i2c->twsi_base + TWSI_INT(i2c));
+}
+
+/* Prototypes */
+irqreturn_t octeon_i2c_isr(int irq, void *dev_id);
+int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
+int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c);
+void octeon_i2c_set_clock(struct octeon_i2c *i2c);
+extern struct i2c_bus_recovery_info octeon_i2c_recovery_info;
diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
new file mode 100644 (file)
index 0000000..917524c
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * (C) Copyright 2009-2010
+ * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
+ *
+ * Portions Copyright (C) 2010 - 2016 Cavium, Inc.
+ *
+ * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/atomic.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/octeon/octeon.h>
+#include "i2c-octeon-core.h"
+
+#define DRV_NAME "i2c-octeon"
+
+/**
+ * octeon_i2c_int_enable - enable the CORE interrupt
+ * @i2c: The struct octeon_i2c
+ *
+ * The interrupt will be asserted when there is non-STAT_IDLE state in
+ * the SW_TWSI_EOP_TWSI_STAT register.
+ */
+static void octeon_i2c_int_enable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_write_int(i2c, TWSI_INT_CORE_EN);
+}
+
+/* disable the CORE interrupt */
+static void octeon_i2c_int_disable(struct octeon_i2c *i2c)
+{
+       /* clear TS/ST/IFLG events */
+       octeon_i2c_write_int(i2c, 0);
+}
+
+/**
+ * octeon_i2c_int_enable78 - enable the CORE interrupt
+ * @i2c: The struct octeon_i2c
+ *
+ * The interrupt will be asserted when there is non-STAT_IDLE state in the
+ * SW_TWSI_EOP_TWSI_STAT register.
+ */
+static void octeon_i2c_int_enable78(struct octeon_i2c *i2c)
+{
+       atomic_inc_return(&i2c->int_enable_cnt);
+       enable_irq(i2c->irq);
+}
+
+static void __octeon_i2c_irq_disable(atomic_t *cnt, int irq)
+{
+       int count;
+
+       /*
+        * The interrupt can be disabled in two places, but we only
+        * want to make the disable_irq_nosync() call once, so keep
+        * track with the atomic variable.
+        */
+       count = atomic_dec_if_positive(cnt);
+       if (count >= 0)
+               disable_irq_nosync(irq);
+}
+
+/* disable the CORE interrupt */
+static void octeon_i2c_int_disable78(struct octeon_i2c *i2c)
+{
+       __octeon_i2c_irq_disable(&i2c->int_enable_cnt, i2c->irq);
+}
+
+/**
+ * octeon_i2c_hlc_int_enable78 - enable the ST interrupt
+ * @i2c: The struct octeon_i2c
+ *
+ * The interrupt will be asserted when there is non-STAT_IDLE state in
+ * the SW_TWSI_EOP_TWSI_STAT register.
+ */
+static void octeon_i2c_hlc_int_enable78(struct octeon_i2c *i2c)
+{
+       atomic_inc_return(&i2c->hlc_int_enable_cnt);
+       enable_irq(i2c->hlc_irq);
+}
+
+/* disable the ST interrupt */
+static void octeon_i2c_hlc_int_disable78(struct octeon_i2c *i2c)
+{
+       __octeon_i2c_irq_disable(&i2c->hlc_int_enable_cnt, i2c->hlc_irq);
+}
+
+/* HLC interrupt service routine */
+static irqreturn_t octeon_i2c_hlc_isr78(int irq, void *dev_id)
+{
+       struct octeon_i2c *i2c = dev_id;
+
+       i2c->hlc_int_disable(i2c);
+       wake_up(&i2c->queue);
+
+       return IRQ_HANDLED;
+}
+
+static void octeon_i2c_hlc_int_enable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_write_int(i2c, TWSI_INT_ST_EN);
+}
+
+static u32 octeon_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
+              I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_SMBUS_BLOCK_PROC_CALL;
+}
+
+static const struct i2c_algorithm octeon_i2c_algo = {
+       .master_xfer = octeon_i2c_xfer,
+       .functionality = octeon_i2c_functionality,
+};
+
+static struct i2c_adapter octeon_i2c_ops = {
+       .owner = THIS_MODULE,
+       .name = "OCTEON adapter",
+       .algo = &octeon_i2c_algo,
+};
+
+static int octeon_i2c_probe(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       int irq, result = 0, hlc_irq = 0;
+       struct resource *res_mem;
+       struct octeon_i2c *i2c;
+       bool cn78xx_style;
+
+       cn78xx_style = of_device_is_compatible(node, "cavium,octeon-7890-twsi");
+       if (cn78xx_style) {
+               hlc_irq = platform_get_irq(pdev, 0);
+               if (hlc_irq < 0)
+                       return hlc_irq;
+
+               irq = platform_get_irq(pdev, 2);
+               if (irq < 0)
+                       return irq;
+       } else {
+               /* All adaptors have an irq.  */
+               irq = platform_get_irq(pdev, 0);
+               if (irq < 0)
+                       return irq;
+       }
+
+       i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+       if (!i2c) {
+               result = -ENOMEM;
+               goto out;
+       }
+       i2c->dev = &pdev->dev;
+
+       i2c->roff.sw_twsi = 0x00;
+       i2c->roff.twsi_int = 0x10;
+       i2c->roff.sw_twsi_ext = 0x18;
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       i2c->twsi_base = devm_ioremap_resource(&pdev->dev, res_mem);
+       if (IS_ERR(i2c->twsi_base)) {
+               result = PTR_ERR(i2c->twsi_base);
+               goto out;
+       }
+
+       /*
+        * "clock-rate" is a legacy binding, the official binding is
+        * "clock-frequency".  Try the official one first and then
+        * fall back if it doesn't exist.
+        */
+       if (of_property_read_u32(node, "clock-frequency", &i2c->twsi_freq) &&
+           of_property_read_u32(node, "clock-rate", &i2c->twsi_freq)) {
+               dev_err(i2c->dev,
+                       "no I2C 'clock-rate' or 'clock-frequency' property\n");
+               result = -ENXIO;
+               goto out;
+       }
+
+       i2c->sys_freq = octeon_get_io_clock_rate();
+
+       init_waitqueue_head(&i2c->queue);
+
+       i2c->irq = irq;
+
+       if (cn78xx_style) {
+               i2c->hlc_irq = hlc_irq;
+
+               i2c->int_enable = octeon_i2c_int_enable78;
+               i2c->int_disable = octeon_i2c_int_disable78;
+               i2c->hlc_int_enable = octeon_i2c_hlc_int_enable78;
+               i2c->hlc_int_disable = octeon_i2c_hlc_int_disable78;
+
+               irq_set_status_flags(i2c->irq, IRQ_NOAUTOEN);
+               irq_set_status_flags(i2c->hlc_irq, IRQ_NOAUTOEN);
+
+               result = devm_request_irq(&pdev->dev, i2c->hlc_irq,
+                                         octeon_i2c_hlc_isr78, 0,
+                                         DRV_NAME, i2c);
+               if (result < 0) {
+                       dev_err(i2c->dev, "failed to attach interrupt\n");
+                       goto out;
+               }
+       } else {
+               i2c->int_enable = octeon_i2c_int_enable;
+               i2c->int_disable = octeon_i2c_int_disable;
+               i2c->hlc_int_enable = octeon_i2c_hlc_int_enable;
+               i2c->hlc_int_disable = octeon_i2c_int_disable;
+       }
+
+       result = devm_request_irq(&pdev->dev, i2c->irq,
+                                 octeon_i2c_isr, 0, DRV_NAME, i2c);
+       if (result < 0) {
+               dev_err(i2c->dev, "failed to attach interrupt\n");
+               goto out;
+       }
+
+       if (OCTEON_IS_MODEL(OCTEON_CN38XX))
+               i2c->broken_irq_check = true;
+
+       result = octeon_i2c_init_lowlevel(i2c);
+       if (result) {
+               dev_err(i2c->dev, "init low level failed\n");
+               goto  out;
+       }
+
+       octeon_i2c_set_clock(i2c);
+
+       i2c->adap = octeon_i2c_ops;
+       i2c->adap.timeout = msecs_to_jiffies(2);
+       i2c->adap.retries = 5;
+       i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
+       i2c->adap.dev.parent = &pdev->dev;
+       i2c->adap.dev.of_node = node;
+       i2c_set_adapdata(&i2c->adap, i2c);
+       platform_set_drvdata(pdev, i2c);
+
+       result = i2c_add_adapter(&i2c->adap);
+       if (result < 0)
+               goto out;
+       dev_info(i2c->dev, "probed\n");
+       return 0;
+
+out:
+       return result;
+};
+
+static int octeon_i2c_remove(struct platform_device *pdev)
+{
+       struct octeon_i2c *i2c = platform_get_drvdata(pdev);
+
+       i2c_del_adapter(&i2c->adap);
+       return 0;
+};
+
+static const struct of_device_id octeon_i2c_match[] = {
+       { .compatible = "cavium,octeon-3860-twsi", },
+       { .compatible = "cavium,octeon-7890-twsi", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, octeon_i2c_match);
+
+static struct platform_driver octeon_i2c_driver = {
+       .probe          = octeon_i2c_probe,
+       .remove         = octeon_i2c_remove,
+       .driver         = {
+               .name   = DRV_NAME,
+               .of_match_table = octeon_i2c_match,
+       },
+};
+
+module_platform_driver(octeon_i2c_driver);
+
+MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c
deleted file mode 100644 (file)
index 30ae351..0000000
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * (C) Copyright 2009-2010
- * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
- *
- * Portions Copyright (C) 2010 - 2016 Cavium, Inc.
- *
- * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/atomic.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/of.h>
-
-#include <asm/octeon/octeon.h>
-
-#define DRV_NAME "i2c-octeon"
-
-/* Register offsets */
-#define SW_TWSI                        0x00
-#define TWSI_INT               0x10
-#define SW_TWSI_EXT            0x18
-
-/* Controller command patterns */
-#define SW_TWSI_V              BIT_ULL(63)     /* Valid bit */
-#define SW_TWSI_EIA            BIT_ULL(61)     /* Extended internal address */
-#define SW_TWSI_R              BIT_ULL(56)     /* Result or read bit */
-#define SW_TWSI_SOVR           BIT_ULL(55)     /* Size override */
-#define SW_TWSI_SIZE_SHIFT     52
-#define SW_TWSI_ADDR_SHIFT     40
-#define SW_TWSI_IA_SHIFT       32              /* Internal address */
-
-/* Controller opcode word (bits 60:57) */
-#define SW_TWSI_OP_SHIFT       57
-#define SW_TWSI_OP_7           (0ULL << SW_TWSI_OP_SHIFT)
-#define SW_TWSI_OP_7_IA                (1ULL << SW_TWSI_OP_SHIFT)
-#define SW_TWSI_OP_10          (2ULL << SW_TWSI_OP_SHIFT)
-#define SW_TWSI_OP_10_IA       (3ULL << SW_TWSI_OP_SHIFT)
-#define SW_TWSI_OP_TWSI_CLK    (4ULL << SW_TWSI_OP_SHIFT)
-#define SW_TWSI_OP_EOP         (6ULL << SW_TWSI_OP_SHIFT) /* Extended opcode */
-
-/* Controller extended opcode word (bits 34:32) */
-#define SW_TWSI_EOP_SHIFT      32
-#define SW_TWSI_EOP_TWSI_DATA  (SW_TWSI_OP_EOP | 1ULL << SW_TWSI_EOP_SHIFT)
-#define SW_TWSI_EOP_TWSI_CTL   (SW_TWSI_OP_EOP | 2ULL << SW_TWSI_EOP_SHIFT)
-#define SW_TWSI_EOP_TWSI_CLKCTL        (SW_TWSI_OP_EOP | 3ULL << SW_TWSI_EOP_SHIFT)
-#define SW_TWSI_EOP_TWSI_STAT  (SW_TWSI_OP_EOP | 3ULL << SW_TWSI_EOP_SHIFT)
-#define SW_TWSI_EOP_TWSI_RST   (SW_TWSI_OP_EOP | 7ULL << SW_TWSI_EOP_SHIFT)
-
-/* Controller command and status bits */
-#define TWSI_CTL_CE            0x80    /* High level controller enable */
-#define TWSI_CTL_ENAB          0x40    /* Bus enable */
-#define TWSI_CTL_STA           0x20    /* Master-mode start, HW clears when done */
-#define TWSI_CTL_STP           0x10    /* Master-mode stop, HW clears when done */
-#define TWSI_CTL_IFLG          0x08    /* HW event, SW writes 0 to ACK */
-#define TWSI_CTL_AAK           0x04    /* Assert ACK */
-
-/* Status values */
-#define STAT_ERROR             0x00
-#define STAT_START             0x08
-#define STAT_REP_START         0x10
-#define STAT_TXADDR_ACK                0x18
-#define STAT_TXADDR_NAK                0x20
-#define STAT_TXDATA_ACK                0x28
-#define STAT_TXDATA_NAK                0x30
-#define STAT_LOST_ARB_38       0x38
-#define STAT_RXADDR_ACK                0x40
-#define STAT_RXADDR_NAK                0x48
-#define STAT_RXDATA_ACK                0x50
-#define STAT_RXDATA_NAK                0x58
-#define STAT_SLAVE_60          0x60
-#define STAT_LOST_ARB_68       0x68
-#define STAT_SLAVE_70          0x70
-#define STAT_LOST_ARB_78       0x78
-#define STAT_SLAVE_80          0x80
-#define STAT_SLAVE_88          0x88
-#define STAT_GENDATA_ACK       0x90
-#define STAT_GENDATA_NAK       0x98
-#define STAT_SLAVE_A0          0xA0
-#define STAT_SLAVE_A8          0xA8
-#define STAT_LOST_ARB_B0       0xB0
-#define STAT_SLAVE_LOST                0xB8
-#define STAT_SLAVE_NAK         0xC0
-#define STAT_SLAVE_ACK         0xC8
-#define STAT_AD2W_ACK          0xD0
-#define STAT_AD2W_NAK          0xD8
-#define STAT_IDLE              0xF8
-
-/* TWSI_INT values */
-#define TWSI_INT_ST_INT                BIT_ULL(0)
-#define TWSI_INT_TS_INT                BIT_ULL(1)
-#define TWSI_INT_CORE_INT      BIT_ULL(2)
-#define TWSI_INT_ST_EN         BIT_ULL(4)
-#define TWSI_INT_TS_EN         BIT_ULL(5)
-#define TWSI_INT_CORE_EN       BIT_ULL(6)
-#define TWSI_INT_SDA_OVR       BIT_ULL(8)
-#define TWSI_INT_SCL_OVR       BIT_ULL(9)
-#define TWSI_INT_SDA           BIT_ULL(10)
-#define TWSI_INT_SCL           BIT_ULL(11)
-
-#define I2C_OCTEON_EVENT_WAIT 80 /* microseconds */
-
-struct octeon_i2c {
-       wait_queue_head_t queue;
-       struct i2c_adapter adap;
-       int irq;
-       int hlc_irq;            /* For cn7890 only */
-       u32 twsi_freq;
-       int sys_freq;
-       void __iomem *twsi_base;
-       struct device *dev;
-       bool hlc_enabled;
-       bool broken_irq_mode;
-       bool broken_irq_check;
-       void (*int_enable)(struct octeon_i2c *);
-       void (*int_disable)(struct octeon_i2c *);
-       void (*hlc_int_enable)(struct octeon_i2c *);
-       void (*hlc_int_disable)(struct octeon_i2c *);
-       atomic_t int_enable_cnt;
-       atomic_t hlc_int_enable_cnt;
-};
-
-static void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
-{
-       __raw_writeq(val, addr);
-       __raw_readq(addr);      /* wait for write to land */
-}
-
-/**
- * octeon_i2c_reg_write - write an I2C core register
- * @i2c: The struct octeon_i2c
- * @eop_reg: Register selector
- * @data: Value to be written
- *
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
- */
-static void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
-{
-       u64 tmp;
-
-       __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI);
-       do {
-               tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
-       } while ((tmp & SW_TWSI_V) != 0);
-}
-
-#define octeon_i2c_ctl_write(i2c, val)                                 \
-       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, val)
-#define octeon_i2c_data_write(i2c, val)                                        \
-       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, val)
-
-/**
- * octeon_i2c_reg_read - read lower bits of an I2C core register
- * @i2c: The struct octeon_i2c
- * @eop_reg: Register selector
- *
- * Returns the data.
- *
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
- */
-static u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
-{
-       u64 tmp;
-
-       __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI);
-       do {
-               tmp = __raw_readq(i2c->twsi_base + SW_TWSI);
-       } while ((tmp & SW_TWSI_V) != 0);
-
-       return tmp & 0xFF;
-}
-
-#define octeon_i2c_ctl_read(i2c)                                       \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
-#define octeon_i2c_data_read(i2c)                                      \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
-#define octeon_i2c_stat_read(i2c)                                      \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
-
-/**
- * octeon_i2c_read_int - read the TWSI_INT register
- * @i2c: The struct octeon_i2c
- *
- * Returns the value of the register.
- */
-static u64 octeon_i2c_read_int(struct octeon_i2c *i2c)
-{
-       return __raw_readq(i2c->twsi_base + TWSI_INT);
-}
-
-/**
- * octeon_i2c_write_int - write the TWSI_INT register
- * @i2c: The struct octeon_i2c
- * @data: Value to be written
- */
-static void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
-{
-       octeon_i2c_writeq_flush(data, i2c->twsi_base + TWSI_INT);
-}
-
-/**
- * octeon_i2c_int_enable - enable the CORE interrupt
- * @i2c: The struct octeon_i2c
- *
- * The interrupt will be asserted when there is non-STAT_IDLE state in
- * the SW_TWSI_EOP_TWSI_STAT register.
- */
-static void octeon_i2c_int_enable(struct octeon_i2c *i2c)
-{
-       octeon_i2c_write_int(i2c, TWSI_INT_CORE_EN);
-}
-
-/* disable the CORE interrupt */
-static void octeon_i2c_int_disable(struct octeon_i2c *i2c)
-{
-       /* clear TS/ST/IFLG events */
-       octeon_i2c_write_int(i2c, 0);
-}
-
-/**
- * octeon_i2c_int_enable78 - enable the CORE interrupt
- * @i2c: The struct octeon_i2c
- *
- * The interrupt will be asserted when there is non-STAT_IDLE state in the
- * SW_TWSI_EOP_TWSI_STAT register.
- */
-static void octeon_i2c_int_enable78(struct octeon_i2c *i2c)
-{
-       atomic_inc_return(&i2c->int_enable_cnt);
-       enable_irq(i2c->irq);
-}
-
-static void __octeon_i2c_irq_disable(atomic_t *cnt, int irq)
-{
-       int count;
-
-       /*
-        * The interrupt can be disabled in two places, but we only
-        * want to make the disable_irq_nosync() call once, so keep
-        * track with the atomic variable.
-        */
-       count = atomic_dec_if_positive(cnt);
-       if (count >= 0)
-               disable_irq_nosync(irq);
-}
-
-/* disable the CORE interrupt */
-static void octeon_i2c_int_disable78(struct octeon_i2c *i2c)
-{
-       __octeon_i2c_irq_disable(&i2c->int_enable_cnt, i2c->irq);
-}
-
-/**
- * octeon_i2c_hlc_int_enable78 - enable the ST interrupt
- * @i2c: The struct octeon_i2c
- *
- * The interrupt will be asserted when there is non-STAT_IDLE state in
- * the SW_TWSI_EOP_TWSI_STAT register.
- */
-static void octeon_i2c_hlc_int_enable78(struct octeon_i2c *i2c)
-{
-       atomic_inc_return(&i2c->hlc_int_enable_cnt);
-       enable_irq(i2c->hlc_irq);
-}
-
-/* disable the ST interrupt */
-static void octeon_i2c_hlc_int_disable78(struct octeon_i2c *i2c)
-{
-       __octeon_i2c_irq_disable(&i2c->hlc_int_enable_cnt, i2c->hlc_irq);
-}
-
-/*
- * Cleanup low-level state & enable high-level controller.
- */
-static void octeon_i2c_hlc_enable(struct octeon_i2c *i2c)
-{
-       int try = 0;
-       u64 val;
-
-       if (i2c->hlc_enabled)
-               return;
-       i2c->hlc_enabled = true;
-
-       while (1) {
-               val = octeon_i2c_ctl_read(i2c);
-               if (!(val & (TWSI_CTL_STA | TWSI_CTL_STP)))
-                       break;
-
-               /* clear IFLG event */
-               if (val & TWSI_CTL_IFLG)
-                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-
-               if (try++ > 100) {
-                       pr_err("%s: giving up\n", __func__);
-                       break;
-               }
-
-               /* spin until any start/stop has finished */
-               udelay(10);
-       }
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_CE | TWSI_CTL_AAK | TWSI_CTL_ENAB);
-}
-
-static void octeon_i2c_hlc_disable(struct octeon_i2c *i2c)
-{
-       if (!i2c->hlc_enabled)
-               return;
-
-       i2c->hlc_enabled = false;
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-}
-
-/* interrupt service routine */
-static irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
-{
-       struct octeon_i2c *i2c = dev_id;
-
-       i2c->int_disable(i2c);
-       wake_up(&i2c->queue);
-
-       return IRQ_HANDLED;
-}
-
-/* HLC interrupt service routine */
-static irqreturn_t octeon_i2c_hlc_isr78(int irq, void *dev_id)
-{
-       struct octeon_i2c *i2c = dev_id;
-
-       i2c->hlc_int_disable(i2c);
-       wake_up(&i2c->queue);
-
-       return IRQ_HANDLED;
-}
-
-static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c)
-{
-       return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG);
-}
-
-static bool octeon_i2c_test_ready(struct octeon_i2c *i2c, bool *first)
-{
-       if (octeon_i2c_test_iflg(i2c))
-               return true;
-
-       if (*first) {
-               *first = false;
-               return false;
-       }
-
-       /*
-        * IRQ has signaled an event but IFLG hasn't changed.
-        * Sleep and retry once.
-        */
-       usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
-       return octeon_i2c_test_iflg(i2c);
-}
-
-/**
- * octeon_i2c_wait - wait for the IFLG to be set
- * @i2c: The struct octeon_i2c
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_wait(struct octeon_i2c *i2c)
-{
-       long time_left;
-       bool first = 1;
-
-       /*
-        * Some chip revisions don't assert the irq in the interrupt
-        * controller. So we must poll for the IFLG change.
-        */
-       if (i2c->broken_irq_mode) {
-               u64 end = get_jiffies_64() + i2c->adap.timeout;
-
-               while (!octeon_i2c_test_iflg(i2c) &&
-                      time_before64(get_jiffies_64(), end))
-                       usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
-
-               return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT;
-       }
-
-       i2c->int_enable(i2c);
-       time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_ready(i2c, &first),
-                                      i2c->adap.timeout);
-       i2c->int_disable(i2c);
-
-       if (i2c->broken_irq_check && !time_left &&
-           octeon_i2c_test_iflg(i2c)) {
-               dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
-               i2c->broken_irq_mode = true;
-               return 0;
-       }
-
-       if (!time_left)
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
-static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
-{
-       u8 stat = octeon_i2c_stat_read(i2c);
-
-       switch (stat) {
-       /* Everything is fine */
-       case STAT_IDLE:
-       case STAT_AD2W_ACK:
-       case STAT_RXADDR_ACK:
-       case STAT_TXADDR_ACK:
-       case STAT_TXDATA_ACK:
-               return 0;
-
-       /* ACK allowed on pre-terminal bytes only */
-       case STAT_RXDATA_ACK:
-               if (!final_read)
-                       return 0;
-               return -EIO;
-
-       /* NAK allowed on terminal byte only */
-       case STAT_RXDATA_NAK:
-               if (final_read)
-                       return 0;
-               return -EIO;
-
-       /* Arbitration lost */
-       case STAT_LOST_ARB_38:
-       case STAT_LOST_ARB_68:
-       case STAT_LOST_ARB_78:
-       case STAT_LOST_ARB_B0:
-               return -EAGAIN;
-
-       /* Being addressed as slave, should back off & listen */
-       case STAT_SLAVE_60:
-       case STAT_SLAVE_70:
-       case STAT_GENDATA_ACK:
-       case STAT_GENDATA_NAK:
-               return -EOPNOTSUPP;
-
-       /* Core busy as slave */
-       case STAT_SLAVE_80:
-       case STAT_SLAVE_88:
-       case STAT_SLAVE_A0:
-       case STAT_SLAVE_A8:
-       case STAT_SLAVE_LOST:
-       case STAT_SLAVE_NAK:
-       case STAT_SLAVE_ACK:
-               return -EOPNOTSUPP;
-
-       case STAT_TXDATA_NAK:
-               return -EIO;
-       case STAT_TXADDR_NAK:
-       case STAT_RXADDR_NAK:
-       case STAT_AD2W_NAK:
-               return -ENXIO;
-       default:
-               dev_err(i2c->dev, "unhandled state: %d\n", stat);
-               return -EIO;
-       }
-}
-
-static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
-{
-       return (__raw_readq(i2c->twsi_base + SW_TWSI) & SW_TWSI_V) == 0;
-}
-
-static bool octeon_i2c_hlc_test_ready(struct octeon_i2c *i2c, bool *first)
-{
-       /* check if valid bit is cleared */
-       if (octeon_i2c_hlc_test_valid(i2c))
-               return true;
-
-       if (*first) {
-               *first = false;
-               return false;
-       }
-
-       /*
-        * IRQ has signaled an event but valid bit isn't cleared.
-        * Sleep and retry once.
-        */
-       usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT);
-       return octeon_i2c_hlc_test_valid(i2c);
-}
-
-static void octeon_i2c_hlc_int_enable(struct octeon_i2c *i2c)
-{
-       octeon_i2c_write_int(i2c, TWSI_INT_ST_EN);
-}
-
-static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
-{
-       /* clear ST/TS events, listen for neither */
-       octeon_i2c_write_int(i2c, TWSI_INT_ST_INT | TWSI_INT_TS_INT);
-}
-
-/**
- * octeon_i2c_hlc_wait - wait for an HLC operation to complete
- * @i2c: The struct octeon_i2c
- *
- * Returns 0 on success, otherwise -ETIMEDOUT.
- */
-static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
-{
-       bool first = 1;
-       int time_left;
-
-       /*
-        * Some cn38xx boards don't assert the irq in the interrupt
-        * controller. So we must poll for the valid bit change.
-        */
-       if (i2c->broken_irq_mode) {
-               u64 end = get_jiffies_64() + i2c->adap.timeout;
-
-               while (!octeon_i2c_hlc_test_valid(i2c) &&
-                      time_before64(get_jiffies_64(), end))
-                       usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
-
-               return octeon_i2c_hlc_test_valid(i2c) ? 0 : -ETIMEDOUT;
-       }
-
-       i2c->hlc_int_enable(i2c);
-       time_left = wait_event_timeout(i2c->queue,
-                                      octeon_i2c_hlc_test_ready(i2c, &first),
-                                      i2c->adap.timeout);
-       i2c->hlc_int_disable(i2c);
-       if (!time_left)
-               octeon_i2c_hlc_int_clear(i2c);
-
-       if (i2c->broken_irq_check && !time_left &&
-           octeon_i2c_hlc_test_valid(i2c)) {
-               dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
-               i2c->broken_irq_mode = true;
-               return 0;
-       }
-
-       if (!time_left)
-               return -ETIMEDOUT;
-       return 0;
-}
-
-/* high-level-controller pure read of up to 8 bytes */
-static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
-{
-       int i, j, ret = 0;
-       u64 cmd;
-
-       octeon_i2c_hlc_enable(i2c);
-       octeon_i2c_hlc_int_clear(i2c);
-
-       cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
-       /* SIZE */
-       cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
-       /* A */
-       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
-
-       if (msgs[0].flags & I2C_M_TEN)
-               cmd |= SW_TWSI_OP_10;
-       else
-               cmd |= SW_TWSI_OP_7;
-
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI);
-       ret = octeon_i2c_hlc_wait(i2c);
-       if (ret)
-               goto err;
-
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI);
-       if ((cmd & SW_TWSI_R) == 0)
-               return -EAGAIN;
-
-       for (i = 0, j = msgs[0].len - 1; i  < msgs[0].len && i < 4; i++, j--)
-               msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
-
-       if (msgs[0].len > 4) {
-               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT);
-               for (i = 0; i  < msgs[0].len - 4 && i < 4; i++, j--)
-                       msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
-       }
-
-err:
-       return ret;
-}
-
-/* high-level-controller pure write of up to 8 bytes */
-static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
-{
-       int i, j, ret = 0;
-       u64 cmd;
-
-       octeon_i2c_hlc_enable(i2c);
-       octeon_i2c_hlc_int_clear(i2c);
-
-       cmd = SW_TWSI_V | SW_TWSI_SOVR;
-       /* SIZE */
-       cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
-       /* A */
-       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
-
-       if (msgs[0].flags & I2C_M_TEN)
-               cmd |= SW_TWSI_OP_10;
-       else
-               cmd |= SW_TWSI_OP_7;
-
-       for (i = 0, j = msgs[0].len - 1; i  < msgs[0].len && i < 4; i++, j--)
-               cmd |= (u64)msgs[0].buf[j] << (8 * i);
-
-       if (msgs[0].len > 4) {
-               u64 ext = 0;
-
-               for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
-                       ext |= (u64)msgs[0].buf[j] << (8 * i);
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT);
-       }
-
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI);
-       ret = octeon_i2c_hlc_wait(i2c);
-       if (ret)
-               goto err;
-
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI);
-       if ((cmd & SW_TWSI_R) == 0)
-               return -EAGAIN;
-
-       ret = octeon_i2c_check_status(i2c, false);
-
-err:
-       return ret;
-}
-
-/* high-level-controller composite write+read, msg0=addr, msg1=data */
-static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
-{
-       int i, j, ret = 0;
-       u64 cmd;
-
-       octeon_i2c_hlc_enable(i2c);
-
-       cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
-       /* SIZE */
-       cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
-       /* A */
-       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
-
-       if (msgs[0].flags & I2C_M_TEN)
-               cmd |= SW_TWSI_OP_10_IA;
-       else
-               cmd |= SW_TWSI_OP_7_IA;
-
-       if (msgs[0].len == 2) {
-               u64 ext = 0;
-
-               cmd |= SW_TWSI_EIA;
-               ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
-               cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT);
-       } else {
-               cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
-       }
-
-       octeon_i2c_hlc_int_clear(i2c);
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI);
-
-       ret = octeon_i2c_hlc_wait(i2c);
-       if (ret)
-               goto err;
-
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI);
-       if ((cmd & SW_TWSI_R) == 0)
-               return -EAGAIN;
-
-       for (i = 0, j = msgs[1].len - 1; i  < msgs[1].len && i < 4; i++, j--)
-               msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
-
-       if (msgs[1].len > 4) {
-               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT);
-               for (i = 0; i  < msgs[1].len - 4 && i < 4; i++, j--)
-                       msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
-       }
-
-err:
-       return ret;
-}
-
-/* high-level-controller composite write+write, m[0]len<=2, m[1]len<=8 */
-static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
-{
-       bool set_ext = false;
-       int i, j, ret = 0;
-       u64 cmd, ext = 0;
-
-       octeon_i2c_hlc_enable(i2c);
-
-       cmd = SW_TWSI_V | SW_TWSI_SOVR;
-       /* SIZE */
-       cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
-       /* A */
-       cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
-
-       if (msgs[0].flags & I2C_M_TEN)
-               cmd |= SW_TWSI_OP_10_IA;
-       else
-               cmd |= SW_TWSI_OP_7_IA;
-
-       if (msgs[0].len == 2) {
-               cmd |= SW_TWSI_EIA;
-               ext |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
-               set_ext = true;
-               cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
-       } else {
-               cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
-       }
-
-       for (i = 0, j = msgs[1].len - 1; i  < msgs[1].len && i < 4; i++, j--)
-               cmd |= (u64)msgs[1].buf[j] << (8 * i);
-
-       if (msgs[1].len > 4) {
-               for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--)
-                       ext |= (u64)msgs[1].buf[j] << (8 * i);
-               set_ext = true;
-       }
-       if (set_ext)
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT);
-
-       octeon_i2c_hlc_int_clear(i2c);
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI);
-
-       ret = octeon_i2c_hlc_wait(i2c);
-       if (ret)
-               goto err;
-
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI);
-       if ((cmd & SW_TWSI_R) == 0)
-               return -EAGAIN;
-
-       ret = octeon_i2c_check_status(i2c, false);
-
-err:
-       return ret;
-}
-
-/* calculate and set clock divisors */
-static void octeon_i2c_set_clock(struct octeon_i2c *i2c)
-{
-       int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
-       int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
-
-       for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
-               /*
-                * An mdiv value of less than 2 seems to not work well
-                * with ds1337 RTCs, so we constrain it to larger values.
-                */
-               for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
-                       /*
-                        * For given ndiv and mdiv values check the
-                        * two closest thp values.
-                        */
-                       tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
-                       tclk *= (1 << ndiv_idx);
-                       thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
-
-                       for (inc = 0; inc <= 1; inc++) {
-                               thp_idx = thp_base + inc;
-                               if (thp_idx < 5 || thp_idx > 0xff)
-                                       continue;
-
-                               foscl = i2c->sys_freq / (2 * (thp_idx + 1));
-                               foscl = foscl / (1 << ndiv_idx);
-                               foscl = foscl / (mdiv_idx + 1) / 10;
-                               diff = abs(foscl - i2c->twsi_freq);
-                               if (diff < delta_hz) {
-                                       delta_hz = diff;
-                                       thp = thp_idx;
-                                       mdiv = mdiv_idx;
-                                       ndiv = ndiv_idx;
-                               }
-                       }
-               }
-       }
-       octeon_i2c_reg_write(i2c, SW_TWSI_OP_TWSI_CLK, thp);
-       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
-}
-
-static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
-{
-       u8 status = 0;
-       int tries;
-
-       /* reset controller */
-       octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
-
-       for (tries = 10; tries && status != STAT_IDLE; tries--) {
-               udelay(1);
-               status = octeon_i2c_stat_read(i2c);
-               if (status == STAT_IDLE)
-                       break;
-       }
-
-       if (status != STAT_IDLE) {
-               dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n",
-                       __func__, status);
-               return -EIO;
-       }
-
-       /* toggle twice to force both teardowns */
-       octeon_i2c_hlc_enable(i2c);
-       octeon_i2c_hlc_disable(i2c);
-       return 0;
-}
-
-static int octeon_i2c_recovery(struct octeon_i2c *i2c)
-{
-       int ret;
-
-       ret = i2c_recover_bus(&i2c->adap);
-       if (ret)
-               /* recover failed, try hardware re-init */
-               ret = octeon_i2c_init_lowlevel(i2c);
-       return ret;
-}
-
-/**
- * octeon_i2c_start - send START to the bus
- * @i2c: The struct octeon_i2c
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_start(struct octeon_i2c *i2c)
-{
-       int ret;
-       u8 stat;
-
-       octeon_i2c_hlc_disable(i2c);
-
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STA);
-       ret = octeon_i2c_wait(i2c);
-       if (ret)
-               goto error;
-
-       stat = octeon_i2c_stat_read(i2c);
-       if (stat == STAT_START || stat == STAT_REP_START)
-               /* START successful, bail out */
-               return 0;
-
-error:
-       /* START failed, try to recover */
-       ret = octeon_i2c_recovery(i2c);
-       return (ret) ? ret : -EAGAIN;
-}
-
-/* send STOP to the bus */
-static void octeon_i2c_stop(struct octeon_i2c *i2c)
-{
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STP);
-}
-
-/**
- * octeon_i2c_write - send data to the bus via low-level controller
- * @i2c: The struct octeon_i2c
- * @target: Target address
- * @data: Pointer to the data to be sent
- * @length: Length of the data
- *
- * The address is sent over the bus, then the data.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
-                           const u8 *data, int length)
-{
-       int i, result;
-
-       octeon_i2c_data_write(i2c, target << 1);
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-
-       result = octeon_i2c_wait(i2c);
-       if (result)
-               return result;
-
-       for (i = 0; i < length; i++) {
-               result = octeon_i2c_check_status(i2c, false);
-               if (result)
-                       return result;
-
-               octeon_i2c_data_write(i2c, data[i]);
-               octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-
-               result = octeon_i2c_wait(i2c);
-               if (result)
-                       return result;
-       }
-
-       return 0;
-}
-
-/**
- * octeon_i2c_read - receive data from the bus via low-level controller
- * @i2c: The struct octeon_i2c
- * @target: Target address
- * @data: Pointer to the location to store the data
- * @rlength: Length of the data
- * @recv_len: flag for length byte
- *
- * The address is sent over the bus, then the data is read.
- *
- * Returns 0 on success, otherwise a negative errno.
- */
-static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
-                          u8 *data, u16 *rlength, bool recv_len)
-{
-       int i, result, length = *rlength;
-       bool final_read = false;
-
-       octeon_i2c_data_write(i2c, (target << 1) | 1);
-       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-
-       result = octeon_i2c_wait(i2c);
-       if (result)
-               return result;
-
-       /* address OK ? */
-       result = octeon_i2c_check_status(i2c, false);
-       if (result)
-               return result;
-
-       for (i = 0; i < length; i++) {
-               /*
-                * For the last byte to receive TWSI_CTL_AAK must not be set.
-                *
-                * A special case is I2C_M_RECV_LEN where we don't know the
-                * additional length yet. If recv_len is set we assume we're
-                * not reading the final byte and therefore need to set
-                * TWSI_CTL_AAK.
-                */
-               if ((i + 1 == length) && !(recv_len && i == 0))
-                       final_read = true;
-
-               /* clear iflg to allow next event */
-               if (final_read)
-                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
-               else
-                       octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_AAK);
-
-               result = octeon_i2c_wait(i2c);
-               if (result)
-                       return result;
-
-               data[i] = octeon_i2c_data_read(i2c);
-               if (recv_len && i == 0) {
-                       if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
-                               return -EPROTO;
-                       length += data[i];
-               }
-
-               result = octeon_i2c_check_status(i2c, final_read);
-               if (result)
-                       return result;
-       }
-       *rlength = length;
-       return 0;
-}
-
-/**
- * octeon_i2c_xfer - The driver's master_xfer function
- * @adap: Pointer to the i2c_adapter structure
- * @msgs: Pointer to the messages to be processed
- * @num: Length of the MSGS array
- *
- * Returns the number of messages processed, or a negative errno on failure.
- */
-static int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-                          int num)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-       int i, ret = 0;
-
-       if (num == 1) {
-               if (msgs[0].len > 0 && msgs[0].len <= 8) {
-                       if (msgs[0].flags & I2C_M_RD)
-                               ret = octeon_i2c_hlc_read(i2c, msgs);
-                       else
-                               ret = octeon_i2c_hlc_write(i2c, msgs);
-                       goto out;
-               }
-       } else if (num == 2) {
-               if ((msgs[0].flags & I2C_M_RD) == 0 &&
-                   (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
-                   msgs[0].len > 0 && msgs[0].len <= 2 &&
-                   msgs[1].len > 0 && msgs[1].len <= 8 &&
-                   msgs[0].addr == msgs[1].addr) {
-                       if (msgs[1].flags & I2C_M_RD)
-                               ret = octeon_i2c_hlc_comp_read(i2c, msgs);
-                       else
-                               ret = octeon_i2c_hlc_comp_write(i2c, msgs);
-                       goto out;
-               }
-       }
-
-       for (i = 0; ret == 0 && i < num; i++) {
-               struct i2c_msg *pmsg = &msgs[i];
-
-               /* zero-length messages are not supported */
-               if (!pmsg->len) {
-                       ret = -EOPNOTSUPP;
-                       break;
-               }
-
-               ret = octeon_i2c_start(i2c);
-               if (ret)
-                       return ret;
-
-               if (pmsg->flags & I2C_M_RD)
-                       ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf,
-                                             &pmsg->len, pmsg->flags & I2C_M_RECV_LEN);
-               else
-                       ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf,
-                                              pmsg->len);
-       }
-       octeon_i2c_stop(i2c);
-out:
-       return (ret != 0) ? ret : num;
-}
-
-static int octeon_i2c_get_scl(struct i2c_adapter *adap)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-       u64 state;
-
-       state = octeon_i2c_read_int(i2c);
-       return state & TWSI_INT_SCL;
-}
-
-static void octeon_i2c_set_scl(struct i2c_adapter *adap, int val)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-
-       octeon_i2c_write_int(i2c, TWSI_INT_SCL_OVR);
-}
-
-static int octeon_i2c_get_sda(struct i2c_adapter *adap)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-       u64 state;
-
-       state = octeon_i2c_read_int(i2c);
-       return state & TWSI_INT_SDA;
-}
-
-static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-
-       /*
-        * The stop resets the state machine, does not _transmit_ STOP unless
-        * engine was active.
-        */
-       octeon_i2c_stop(i2c);
-
-       octeon_i2c_hlc_disable(i2c);
-       octeon_i2c_write_int(i2c, 0);
-}
-
-static void octeon_i2c_unprepare_recovery(struct i2c_adapter *adap)
-{
-       struct octeon_i2c *i2c = i2c_get_adapdata(adap);
-
-       octeon_i2c_write_int(i2c, 0);
-}
-
-static struct i2c_bus_recovery_info octeon_i2c_recovery_info = {
-       .recover_bus = i2c_generic_scl_recovery,
-       .get_scl = octeon_i2c_get_scl,
-       .set_scl = octeon_i2c_set_scl,
-       .get_sda = octeon_i2c_get_sda,
-       .prepare_recovery = octeon_i2c_prepare_recovery,
-       .unprepare_recovery = octeon_i2c_unprepare_recovery,
-};
-
-static u32 octeon_i2c_functionality(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
-              I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_SMBUS_BLOCK_PROC_CALL;
-}
-
-static const struct i2c_algorithm octeon_i2c_algo = {
-       .master_xfer = octeon_i2c_xfer,
-       .functionality = octeon_i2c_functionality,
-};
-
-static struct i2c_adapter octeon_i2c_ops = {
-       .owner = THIS_MODULE,
-       .name = "OCTEON adapter",
-       .algo = &octeon_i2c_algo,
-};
-
-static int octeon_i2c_probe(struct platform_device *pdev)
-{
-       struct device_node *node = pdev->dev.of_node;
-       int irq, result = 0, hlc_irq = 0;
-       struct resource *res_mem;
-       struct octeon_i2c *i2c;
-       bool cn78xx_style;
-
-       cn78xx_style = of_device_is_compatible(node, "cavium,octeon-7890-twsi");
-       if (cn78xx_style) {
-               hlc_irq = platform_get_irq(pdev, 0);
-               if (hlc_irq < 0)
-                       return hlc_irq;
-
-               irq = platform_get_irq(pdev, 2);
-               if (irq < 0)
-                       return irq;
-       } else {
-               /* All adaptors have an irq.  */
-               irq = platform_get_irq(pdev, 0);
-               if (irq < 0)
-                       return irq;
-       }
-
-       i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
-       if (!i2c) {
-               result = -ENOMEM;
-               goto out;
-       }
-       i2c->dev = &pdev->dev;
-
-       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       i2c->twsi_base = devm_ioremap_resource(&pdev->dev, res_mem);
-       if (IS_ERR(i2c->twsi_base)) {
-               result = PTR_ERR(i2c->twsi_base);
-               goto out;
-       }
-
-       /*
-        * "clock-rate" is a legacy binding, the official binding is
-        * "clock-frequency".  Try the official one first and then
-        * fall back if it doesn't exist.
-        */
-       if (of_property_read_u32(node, "clock-frequency", &i2c->twsi_freq) &&
-           of_property_read_u32(node, "clock-rate", &i2c->twsi_freq)) {
-               dev_err(i2c->dev,
-                       "no I2C 'clock-rate' or 'clock-frequency' property\n");
-               result = -ENXIO;
-               goto out;
-       }
-
-       i2c->sys_freq = octeon_get_io_clock_rate();
-
-       init_waitqueue_head(&i2c->queue);
-
-       i2c->irq = irq;
-
-       if (cn78xx_style) {
-               i2c->hlc_irq = hlc_irq;
-
-               i2c->int_enable = octeon_i2c_int_enable78;
-               i2c->int_disable = octeon_i2c_int_disable78;
-               i2c->hlc_int_enable = octeon_i2c_hlc_int_enable78;
-               i2c->hlc_int_disable = octeon_i2c_hlc_int_disable78;
-
-               irq_set_status_flags(i2c->irq, IRQ_NOAUTOEN);
-               irq_set_status_flags(i2c->hlc_irq, IRQ_NOAUTOEN);
-
-               result = devm_request_irq(&pdev->dev, i2c->hlc_irq,
-                                         octeon_i2c_hlc_isr78, 0,
-                                         DRV_NAME, i2c);
-               if (result < 0) {
-                       dev_err(i2c->dev, "failed to attach interrupt\n");
-                       goto out;
-               }
-       } else {
-               i2c->int_enable = octeon_i2c_int_enable;
-               i2c->int_disable = octeon_i2c_int_disable;
-               i2c->hlc_int_enable = octeon_i2c_hlc_int_enable;
-               i2c->hlc_int_disable = octeon_i2c_int_disable;
-       }
-
-       result = devm_request_irq(&pdev->dev, i2c->irq,
-                                 octeon_i2c_isr, 0, DRV_NAME, i2c);
-       if (result < 0) {
-               dev_err(i2c->dev, "failed to attach interrupt\n");
-               goto out;
-       }
-
-       if (OCTEON_IS_MODEL(OCTEON_CN38XX))
-               i2c->broken_irq_check = true;
-
-       result = octeon_i2c_init_lowlevel(i2c);
-       if (result) {
-               dev_err(i2c->dev, "init low level failed\n");
-               goto  out;
-       }
-
-       octeon_i2c_set_clock(i2c);
-
-       i2c->adap = octeon_i2c_ops;
-       i2c->adap.timeout = msecs_to_jiffies(2);
-       i2c->adap.retries = 5;
-       i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
-       i2c->adap.dev.parent = &pdev->dev;
-       i2c->adap.dev.of_node = node;
-       i2c_set_adapdata(&i2c->adap, i2c);
-       platform_set_drvdata(pdev, i2c);
-
-       result = i2c_add_adapter(&i2c->adap);
-       if (result < 0) {
-               dev_err(i2c->dev, "failed to add adapter\n");
-               goto out;
-       }
-       dev_info(i2c->dev, "probed\n");
-       return 0;
-
-out:
-       return result;
-};
-
-static int octeon_i2c_remove(struct platform_device *pdev)
-{
-       struct octeon_i2c *i2c = platform_get_drvdata(pdev);
-
-       i2c_del_adapter(&i2c->adap);
-       return 0;
-};
-
-static const struct of_device_id octeon_i2c_match[] = {
-       { .compatible = "cavium,octeon-3860-twsi", },
-       { .compatible = "cavium,octeon-7890-twsi", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, octeon_i2c_match);
-
-static struct platform_driver octeon_i2c_driver = {
-       .probe          = octeon_i2c_probe,
-       .remove         = octeon_i2c_remove,
-       .driver         = {
-               .name   = DRV_NAME,
-               .of_match_table = octeon_i2c_match,
-       },
-};
-
-module_platform_driver(octeon_i2c_driver);
-
-MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");
-MODULE_LICENSE("GPL");
index ab1279b8e2407ae33353526788a0665bc03217b3..c7da0c42baeefa8689693a9b3d237ccaa7dd5db7 100644 (file)
@@ -1425,10 +1425,8 @@ omap_i2c_probe(struct platform_device *pdev)
        /* i2c device drivers may be active on return from add_adapter() */
        adap->nr = pdev->id;
        r = i2c_add_numbered_adapter(adap);
-       if (r) {
-               dev_err(omap->dev, "failure adding adapter\n");
+       if (r)
                goto err_unuse_clocks;
-       }
 
        dev_info(omap->dev, "bus %d rev%d.%d at %d kHz\n", adap->nr,
                 major, minor, omap->speed);
index 23d1c167b5d75204e98501a69398b2d826c53aa1..c2268cdf38e82348ae883c99d1f140a7fc2d0ecc 100644 (file)
@@ -694,7 +694,6 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
 
        retval = i2c_add_adapter(adap);
        if (retval) {
-               dev_err(&dev->dev, "Couldn't register adapter!\n");
                kfree(adapdata);
                kfree(adap);
                release_region(smba, SMBIOSIZE);
index 2c40edbf6224eb69a0cf720616b3ca8aee321502..217c78711d6501f71ed267df99256fd8b801ff78 100644 (file)
@@ -329,10 +329,8 @@ static int pmcmsptwi_probe(struct platform_device *pldev)
        i2c_set_adapdata(&pmcmsptwi_adapter, &pmcmsptwi_data);
 
        rc = i2c_add_adapter(&pmcmsptwi_adapter);
-       if (rc) {
-               dev_err(&pldev->dev, "Unable to register I2C adapter\n");
+       if (rc)
                goto ret_unmap;
-       }
 
        return 0;
 
index 7ea67aa46fb730d62342f8ec1a7be58369ca3122..fd5f9d2bf6d94eeaf1340e0ca260ffedcdcb135a 100644 (file)
@@ -714,10 +714,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
 
        /* Register this adapter with the I2C subsystem */
        ret = i2c_add_numbered_adapter(&alg_data->adapter);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "I2C: Failed to add bus\n");
+       if (ret < 0)
                goto out_clock;
-       }
 
        dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
                alg_data->adapter.name, res->start, alg_data->irq);
index 82b6f02544dae7735d42eced79db679c1ce48ed9..0c8b1571886d5b7e1b8fb7bfedb25eb63d97cfec 100644 (file)
@@ -212,11 +212,8 @@ static int puv3_i2c_probe(struct platform_device *pdev)
 
        adapter->nr = pdev->id;
        rc = i2c_add_numbered_adapter(adapter);
-       if (rc) {
-               dev_err(&pdev->dev, "Adapter '%s' registration failed\n",
-                               adapter->name);
+       if (rc)
                goto fail_add_adapter;
-       }
 
        dev_info(&pdev->dev, "PKUnity v3 i2c bus adapter.\n");
        return 0;
index 0d351954db02b9d0c80a9a34d354e3805b9106d2..e28b825b0433783799319db31e8471320dd7fb82 100644 (file)
@@ -1292,10 +1292,8 @@ static int i2c_pxa_probe(struct platform_device *dev)
 #endif
 
        ret = i2c_add_numbered_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&dev->dev, "failed to add bus: %d\n", ret);
+       if (ret < 0)
                goto ereqirq;
-       }
 
        platform_set_drvdata(dev, i2c);
 
index 9bd849dacee8724f1cbc3607f3bca013ee91e94b..726615e54f2a5ea4addfea0afcf528a425548a7b 100644 (file)
@@ -802,6 +802,7 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
        { .compatible = "renesas,i2c-r8a7793", .data = (void *)I2C_RCAR_GEN2 },
        { .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
        { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
+       { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
        {},
 };
 MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
@@ -875,10 +876,8 @@ static int rcar_i2c_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, priv);
 
        ret = i2c_add_numbered_adapter(adap);
-       if (ret < 0) {
-               dev_err(dev, "reg adap failed: %d\n", ret);
+       if (ret < 0)
                goto out_pm_disable;
-       }
 
        dev_info(dev, "probed\n");
 
index d7e3af67154373c226f543b1a8b6e11803debee2..6263ea82d6ac3b10b97905647c1dc6034b78c100 100644 (file)
@@ -383,10 +383,8 @@ static int riic_i2c_probe(struct platform_device *pdev)
 
 
        ret = i2c_add_adapter(adap);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add adapter\n");
+       if (ret)
                return ret;
-       }
 
        platform_set_drvdata(pdev, riic);
 
index 5c5b7cada8beef28d2d9e5c94bfa5d0c355d8af0..50702c7bb244beec821e4d04e0352c07ee516a21 100644 (file)
@@ -58,7 +58,7 @@ enum {
 #define REG_CON_LASTACK   BIT(5) /* 1: send NACK after last received byte */
 #define REG_CON_ACTACK    BIT(6) /* 1: stop if NACK is received */
 
-#define REG_CON_TUNING_MASK GENMASK(15, 8)
+#define REG_CON_TUNING_MASK GENMASK_ULL(15, 8)
 
 #define REG_CON_SDA_CFG(cfg) ((cfg) << 8)
 #define REG_CON_STA_CFG(cfg) ((cfg) << 12)
@@ -742,7 +742,7 @@ static int rk3x_i2c_v1_calc_timings(unsigned long clk_rate,
                                    struct i2c_timings *t,
                                    struct rk3x_i2c_calced_timings *t_calc)
 {
-       unsigned long min_low_ns, min_high_ns, min_total_ns;
+       unsigned long min_low_ns, min_high_ns;
        unsigned long min_setup_start_ns, min_setup_data_ns;
        unsigned long min_setup_stop_ns, max_hold_data_ns;
 
@@ -793,7 +793,6 @@ static int rk3x_i2c_v1_calc_timings(unsigned long clk_rate,
 
        /* These are the min dividers needed for min hold times. */
        min_div_for_hold = (min_low_div + min_high_div);
-       min_total_ns = min_low_ns + min_high_ns;
 
        /*
         * This is the maximum divider so we don't go over the maximum.
@@ -1312,10 +1311,8 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
        rk3x_i2c_adapt_div(i2c, clk_rate);
 
        ret = i2c_add_adapter(&i2c->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Could not register adapter\n");
+       if (ret < 0)
                goto err_clk_notifier;
-       }
 
        dev_info(&pdev->dev, "Initialized RK3xxx I2C bus at %p\n", i2c->regs);
 
index 38dc1cacfd8bba5d36da9e2638efb6a6ca93f455..499af26e736e7eb06aba01409faba3bbe0b20d59 100644 (file)
@@ -1215,7 +1215,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 
        ret = i2c_add_numbered_adapter(&i2c->adap);
        if (ret < 0) {
-               dev_err(&pdev->dev, "failed to add bus to i2c core\n");
                pm_runtime_disable(&pdev->dev);
                s3c24xx_i2c_deregister_cpufreq(i2c);
                clk_unprepare(i2c->clk);
index 24968384b4014f92d69aded3f1928ecf733e933f..c2005c789d2b09b8429368599d93683c5342b364 100644 (file)
@@ -510,10 +510,8 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
        }
 
        ret = i2c_add_numbered_adapter(&id->adap);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
+       if (ret < 0)
                goto out4;
-       }
 
        platform_set_drvdata(pdev, id);
 
index 05b1eeab9cf5f6a58b8af543a2c515cf7ee07498..192f36f00e4d3d345e556e75da9ee6b826604104 100644 (file)
@@ -981,7 +981,6 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
        ret = i2c_add_numbered_adapter(adap);
        if (ret < 0) {
                sh_mobile_i2c_release_dma(pd);
-               dev_err(&dev->dev, "cannot add numbered adapter\n");
                return ret;
        }
 
index 792a42bdd335b90d829702ec994292c8b0a241ea..95e81d0f72b4d243aeb6fade9968549d10145e37 100644 (file)
@@ -387,10 +387,8 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
                writel(regval, siic->base + SIRFSOC_I2C_SDA_DELAY);
 
        err = i2c_add_numbered_adapter(adap);
-       if (err < 0) {
-               dev_err(&pdev->dev, "Can't add new i2c adapter\n");
+       if (err < 0)
                goto out;
-       }
 
        clk_disable(clk);
 
index 944ec4205084878cd951a3a2f72451ee6567d866..1371547ce1a3a811dae12cdea2bd0592ec4342f7 100644 (file)
@@ -874,10 +874,8 @@ static int st_i2c_probe(struct platform_device *pdev)
        init_completion(&i2c_dev->complete);
 
        ret = i2c_add_adapter(adap);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add adapter\n");
+       if (ret)
                return ret;
-       }
 
        platform_set_drvdata(pdev, i2c_dev);
 
index 460c134832ac3039e9fd246f9263203b93453622..dc63236b45b21669922a77155bd2c244ec456dde 100644 (file)
@@ -920,11 +920,8 @@ static int stu300_probe(struct platform_device *pdev)
 
        /* i2c device drivers may be active on return from add_adapter() */
        ret = i2c_add_numbered_adapter(adap);
-       if (ret) {
-               dev_err(&pdev->dev, "failure adding ST Micro DDC "
-                      "I2C adapter\n");
+       if (ret)
                return ret;
-       }
 
        platform_set_drvdata(pdev, dev);
        dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
index b126dbaa47e37014acaf78ba528a6e177bffa9d8..4af9bbae20dfda19a5a5119b230bf2ebff01053b 100644 (file)
@@ -28,6 +28,9 @@
 #include <linux/of_device.h>
 #include <linux/module.h>
 #include <linux/reset.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
 
 #include <asm/unaligned.h>
 
 
 #define I2C_CNFG                               0x000
 #define I2C_CNFG_DEBOUNCE_CNT_SHIFT            12
-#define I2C_CNFG_PACKET_MODE_EN                        (1<<10)
-#define I2C_CNFG_NEW_MASTER_FSM                        (1<<11)
-#define I2C_CNFG_MULTI_MASTER_MODE             (1<<17)
+#define I2C_CNFG_PACKET_MODE_EN                        BIT(10)
+#define I2C_CNFG_NEW_MASTER_FSM                        BIT(11)
+#define I2C_CNFG_MULTI_MASTER_MODE             BIT(17)
 #define I2C_STATUS                             0x01C
 #define I2C_SL_CNFG                            0x020
-#define I2C_SL_CNFG_NACK                       (1<<1)
-#define I2C_SL_CNFG_NEWSL                      (1<<2)
+#define I2C_SL_CNFG_NACK                       BIT(1)
+#define I2C_SL_CNFG_NEWSL                      BIT(2)
 #define I2C_SL_ADDR1                           0x02c
 #define I2C_SL_ADDR2                           0x030
 #define I2C_TX_FIFO                            0x050
 #define I2C_RX_FIFO                            0x054
 #define I2C_PACKET_TRANSFER_STATUS             0x058
 #define I2C_FIFO_CONTROL                       0x05c
-#define I2C_FIFO_CONTROL_TX_FLUSH              (1<<1)
-#define I2C_FIFO_CONTROL_RX_FLUSH              (1<<0)
+#define I2C_FIFO_CONTROL_TX_FLUSH              BIT(1)
+#define I2C_FIFO_CONTROL_RX_FLUSH              BIT(0)
 #define I2C_FIFO_CONTROL_TX_TRIG_SHIFT         5
 #define I2C_FIFO_CONTROL_RX_TRIG_SHIFT         2
 #define I2C_FIFO_STATUS                                0x060
 #define I2C_FIFO_STATUS_RX_SHIFT               0
 #define I2C_INT_MASK                           0x064
 #define I2C_INT_STATUS                         0x068
-#define I2C_INT_PACKET_XFER_COMPLETE           (1<<7)
-#define I2C_INT_ALL_PACKETS_XFER_COMPLETE      (1<<6)
-#define I2C_INT_TX_FIFO_OVERFLOW               (1<<5)
-#define I2C_INT_RX_FIFO_UNDERFLOW              (1<<4)
-#define I2C_INT_NO_ACK                         (1<<3)
-#define I2C_INT_ARBITRATION_LOST               (1<<2)
-#define I2C_INT_TX_FIFO_DATA_REQ               (1<<1)
-#define I2C_INT_RX_FIFO_DATA_REQ               (1<<0)
+#define I2C_INT_PACKET_XFER_COMPLETE           BIT(7)
+#define I2C_INT_ALL_PACKETS_XFER_COMPLETE      BIT(6)
+#define I2C_INT_TX_FIFO_OVERFLOW               BIT(5)
+#define I2C_INT_RX_FIFO_UNDERFLOW              BIT(4)
+#define I2C_INT_NO_ACK                         BIT(3)
+#define I2C_INT_ARBITRATION_LOST               BIT(2)
+#define I2C_INT_TX_FIFO_DATA_REQ               BIT(1)
+#define I2C_INT_RX_FIFO_DATA_REQ               BIT(0)
 #define I2C_CLK_DIVISOR                                0x06c
 #define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT    16
 #define I2C_CLK_MULTIPLIER_STD_FAST_MODE       8
 
 #define DVC_CTRL_REG1                          0x000
-#define DVC_CTRL_REG1_INTR_EN                  (1<<10)
+#define DVC_CTRL_REG1_INTR_EN                  BIT(10)
 #define DVC_CTRL_REG2                          0x004
 #define DVC_CTRL_REG3                          0x008
-#define DVC_CTRL_REG3_SW_PROG                  (1<<26)
-#define DVC_CTRL_REG3_I2C_DONE_INTR_EN         (1<<30)
+#define DVC_CTRL_REG3_SW_PROG                  BIT(26)
+#define DVC_CTRL_REG3_I2C_DONE_INTR_EN         BIT(30)
 #define DVC_STATUS                             0x00c
-#define DVC_STATUS_I2C_DONE_INTR               (1<<30)
+#define DVC_STATUS_I2C_DONE_INTR               BIT(30)
 
 #define I2C_ERR_NONE                           0x00
 #define I2C_ERR_NO_ACK                         0x01
 #define PACKET_HEADER0_HEADER_SIZE_SHIFT       28
 #define PACKET_HEADER0_PACKET_ID_SHIFT         16
 #define PACKET_HEADER0_CONT_ID_SHIFT           12
-#define PACKET_HEADER0_PROTOCOL_I2C            (1<<4)
-
-#define I2C_HEADER_HIGHSPEED_MODE              (1<<22)
-#define I2C_HEADER_CONT_ON_NAK                 (1<<21)
-#define I2C_HEADER_SEND_START_BYTE             (1<<20)
-#define I2C_HEADER_READ                                (1<<19)
-#define I2C_HEADER_10BIT_ADDR                  (1<<18)
-#define I2C_HEADER_IE_ENABLE                   (1<<17)
-#define I2C_HEADER_REPEAT_START                        (1<<16)
-#define I2C_HEADER_CONTINUE_XFER               (1<<15)
+#define PACKET_HEADER0_PROTOCOL_I2C            BIT(4)
+
+#define I2C_HEADER_HIGHSPEED_MODE              BIT(22)
+#define I2C_HEADER_CONT_ON_NAK                 BIT(21)
+#define I2C_HEADER_SEND_START_BYTE             BIT(20)
+#define I2C_HEADER_READ                                BIT(19)
+#define I2C_HEADER_10BIT_ADDR                  BIT(18)
+#define I2C_HEADER_IE_ENABLE                   BIT(17)
+#define I2C_HEADER_REPEAT_START                        BIT(16)
+#define I2C_HEADER_CONTINUE_XFER               BIT(15)
 #define I2C_HEADER_MASTER_ADDR_SHIFT           12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT            1
 
 #define I2C_CONFIG_LOAD                                0x08C
-#define I2C_MSTR_CONFIG_LOAD                   (1 << 0)
-#define I2C_SLV_CONFIG_LOAD                    (1 << 1)
-#define I2C_TIMEOUT_CONFIG_LOAD                        (1 << 2)
+#define I2C_MSTR_CONFIG_LOAD                   BIT(0)
+#define I2C_SLV_CONFIG_LOAD                    BIT(1)
+#define I2C_TIMEOUT_CONFIG_LOAD                        BIT(2)
 
 #define I2C_CLKEN_OVERRIDE                     0x090
-#define I2C_MST_CORE_CLKEN_OVR                 (1 << 0)
+#define I2C_MST_CORE_CLKEN_OVR                 BIT(0)
+
+#define I2C_CONFIG_LOAD_TIMEOUT                        1000000
 
 /*
  * msg_end_type: The bus control which need to be send at end of transfer.
@@ -191,9 +196,11 @@ struct tegra_i2c_dev {
        u16 clk_divisor_non_hs_mode;
        bool is_suspended;
        bool is_multimaster_mode;
+       spinlock_t xfer_lock;
 };
 
-static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg)
+static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
+                      unsigned long reg)
 {
        writel(val, i2c_dev->base + reg);
 }
@@ -244,15 +251,17 @@ static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
 
 static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
 {
-       u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
-       int_mask &= ~mask;
+       u32 int_mask;
+
+       int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) & ~mask;
        i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
 }
 
 static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
 {
-       u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
-       int_mask |= mask;
+       u32 int_mask;
+
+       int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) | mask;
        i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
 }
 
@@ -260,6 +269,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 {
        unsigned long timeout = jiffies + HZ;
        u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL);
+
        val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH;
        i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
 
@@ -385,7 +395,8 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
  */
 static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
 {
-       u32 val = 0;
+       u32 val;
+
        val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
        val |= DVC_CTRL_REG3_SW_PROG;
        val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
@@ -396,9 +407,15 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
        dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
-static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
+static int tegra_i2c_runtime_resume(struct device *dev)
 {
+       struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
        int ret;
+
+       ret = pinctrl_pm_select_default_state(i2c_dev->dev);
+       if (ret)
+               return ret;
+
        if (!i2c_dev->hw->has_single_clk_source) {
                ret = clk_enable(i2c_dev->fast_clk);
                if (ret < 0) {
@@ -407,32 +424,66 @@ static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
                        return ret;
                }
        }
+
        ret = clk_enable(i2c_dev->div_clk);
        if (ret < 0) {
                dev_err(i2c_dev->dev,
                        "Enabling div clk failed, err %d\n", ret);
                clk_disable(i2c_dev->fast_clk);
+               return ret;
        }
-       return ret;
+
+       return 0;
 }
 
-static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
+static int tegra_i2c_runtime_suspend(struct device *dev)
 {
+       struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+
        clk_disable(i2c_dev->div_clk);
        if (!i2c_dev->hw->has_single_clk_source)
                clk_disable(i2c_dev->fast_clk);
+
+       return pinctrl_pm_select_idle_state(i2c_dev->dev);
+}
+
+static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
+{
+       unsigned long reg_offset;
+       void __iomem *addr;
+       u32 val;
+       int err;
+
+       if (i2c_dev->hw->has_config_load_reg) {
+               reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
+               addr = i2c_dev->base + reg_offset;
+               i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
+               if (in_interrupt())
+                       err = readl_poll_timeout_atomic(addr, val, val == 0,
+                                       1000, I2C_CONFIG_LOAD_TIMEOUT);
+               else
+                       err = readl_poll_timeout(addr, val, val == 0,
+                                       1000, I2C_CONFIG_LOAD_TIMEOUT);
+
+               if (err) {
+                       dev_warn(i2c_dev->dev,
+                                "timeout waiting for config load\n");
+                       return err;
+               }
+       }
+
+       return 0;
 }
 
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
        u32 val;
-       int err = 0;
+       int err;
        u32 clk_divisor;
-       unsigned long timeout = jiffies + HZ;
 
-       err = tegra_i2c_clock_enable(i2c_dev);
+       err = pm_runtime_get_sync(i2c_dev->dev);
        if (err < 0) {
-               dev_err(i2c_dev->dev, "Clock enable failed %d\n", err);
+               dev_err(i2c_dev->dev, "runtime resume failed %d\n", err);
                return err;
        }
 
@@ -460,54 +511,59 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 
        if (!i2c_dev->is_dvc) {
                u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
+
                sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
                i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
                i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
                i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
-
        }
 
        val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
                0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
        i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
 
-       if (tegra_i2c_flush_fifos(i2c_dev))
-               err = -ETIMEDOUT;
+       err = tegra_i2c_flush_fifos(i2c_dev);
+       if (err)
+               goto err;
 
        if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
                i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
 
-       if (i2c_dev->hw->has_config_load_reg) {
-               i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
-               while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) {
-                       if (time_after(jiffies, timeout)) {
-                               dev_warn(i2c_dev->dev,
-                                       "timeout waiting for config load\n");
-                               err = -ETIMEDOUT;
-                               goto err;
-                       }
-                       msleep(1);
-               }
-       }
+       err = tegra_i2c_wait_for_config_load(i2c_dev);
+       if (err)
+               goto err;
 
        if (i2c_dev->irq_disabled) {
-               i2c_dev->irq_disabled = 0;
+               i2c_dev->irq_disabled = false;
                enable_irq(i2c_dev->irq);
        }
 
 err:
-       tegra_i2c_clock_disable(i2c_dev);
+       pm_runtime_put(i2c_dev->dev);
        return err;
 }
 
+static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
+{
+       u32 cnfg;
+
+       cnfg = i2c_readl(i2c_dev, I2C_CNFG);
+       if (cnfg & I2C_CNFG_PACKET_MODE_EN)
+               i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
+
+       return tegra_i2c_wait_for_config_load(i2c_dev);
+}
+
 static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 {
        u32 status;
        const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
        struct tegra_i2c_dev *i2c_dev = dev_id;
+       unsigned long flags;
 
        status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
+       spin_lock_irqsave(&i2c_dev->xfer_lock, flags);
        if (status == 0) {
                dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
                         i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
@@ -517,12 +573,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 
                if (!i2c_dev->irq_disabled) {
                        disable_irq_nosync(i2c_dev->irq);
-                       i2c_dev->irq_disabled = 1;
+                       i2c_dev->irq_disabled = true;
                }
                goto err;
        }
 
        if (unlikely(status & status_err)) {
+               tegra_i2c_disable_packet_mode(i2c_dev);
                if (status & I2C_INT_NO_ACK)
                        i2c_dev->msg_err |= I2C_ERR_NO_ACK;
                if (status & I2C_INT_ARBITRATION_LOST)
@@ -552,7 +609,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
                BUG_ON(i2c_dev->msg_buf_remaining);
                complete(&i2c_dev->msg_complete);
        }
-       return IRQ_HANDLED;
+       goto done;
 err:
        /* An error occurred, mask all interrupts */
        tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
@@ -563,6 +620,8 @@ err:
                dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
 
        complete(&i2c_dev->msg_complete);
+done:
+       spin_unlock_irqrestore(&i2c_dev->xfer_lock, flags);
        return IRQ_HANDLED;
 }
 
@@ -572,6 +631,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        u32 packet_header;
        u32 int_mask;
        unsigned long time_left;
+       unsigned long flags;
 
        tegra_i2c_flush_fifos(i2c_dev);
 
@@ -584,6 +644,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        i2c_dev->msg_read = (msg->flags & I2C_M_RD);
        reinit_completion(&i2c_dev->msg_complete);
 
+       spin_lock_irqsave(&i2c_dev->xfer_lock, flags);
+
+       int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
+       tegra_i2c_unmask_irq(i2c_dev, int_mask);
+
        packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) |
                        PACKET_HEADER0_PROTOCOL_I2C |
                        (i2c_dev->cont_id << PACKET_HEADER0_CONT_ID_SHIFT) |
@@ -613,14 +678,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        if (!(msg->flags & I2C_M_RD))
                tegra_i2c_fill_tx_fifo(i2c_dev);
 
-       int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
        if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
                int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
        if (msg->flags & I2C_M_RD)
                int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
        else if (i2c_dev->msg_buf_remaining)
                int_mask |= I2C_INT_TX_FIFO_DATA_REQ;
+
        tegra_i2c_unmask_irq(i2c_dev, int_mask);
+       spin_unlock_irqrestore(&i2c_dev->xfer_lock, flags);
        dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
                i2c_readl(i2c_dev, I2C_INT_MASK));
 
@@ -643,9 +709,10 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                return 0;
 
        /*
-        * NACK interrupt is generated before the I2C controller generates the
-        * STOP condition on the bus. So wait for 2 clock periods before resetting
-        * the controller so that STOP condition has been delivered properly.
+        * NACK interrupt is generated before the I2C controller generates
+        * the STOP condition on the bus. So wait for 2 clock periods
+        * before resetting the controller so that the STOP condition has
+        * been delivered properly.
         */
        if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
                udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
@@ -670,14 +737,15 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
        if (i2c_dev->is_suspended)
                return -EBUSY;
 
-       ret = tegra_i2c_clock_enable(i2c_dev);
+       ret = pm_runtime_get_sync(i2c_dev->dev);
        if (ret < 0) {
-               dev_err(i2c_dev->dev, "Clock enable failed %d\n", ret);
+               dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret);
                return ret;
        }
 
        for (i = 0; i < num; i++) {
                enum msg_end_type end_type = MSG_END_STOP;
+
                if (i < (num - 1)) {
                        if (msgs[i + 1].flags & I2C_M_NOSTART)
                                end_type = MSG_END_CONTINUE;
@@ -688,7 +756,9 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
                if (ret)
                        break;
        }
-       tegra_i2c_clock_disable(i2c_dev);
+
+       pm_runtime_put(i2c_dev->dev);
+
        return ret ?: i;
 }
 
@@ -825,7 +895,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
        div_clk = devm_clk_get(&pdev->dev, "div-clk");
        if (IS_ERR(div_clk)) {
-               dev_err(&pdev->dev, "missing controller clock");
+               dev_err(&pdev->dev, "missing controller clock\n");
                return PTR_ERR(div_clk);
        }
 
@@ -843,27 +913,22 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
        i2c_dev->rst = devm_reset_control_get(&pdev->dev, "i2c");
        if (IS_ERR(i2c_dev->rst)) {
-               dev_err(&pdev->dev, "missing controller reset");
+               dev_err(&pdev->dev, "missing controller reset\n");
                return PTR_ERR(i2c_dev->rst);
        }
 
        tegra_i2c_parse_dt(i2c_dev);
 
-       i2c_dev->hw = &tegra20_i2c_hw;
-
-       if (pdev->dev.of_node) {
-               i2c_dev->hw = of_device_get_match_data(&pdev->dev);
-               i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
-                                               "nvidia,tegra20-i2c-dvc");
-       } else if (pdev->id == 3) {
-               i2c_dev->is_dvc = 1;
-       }
+       i2c_dev->hw = of_device_get_match_data(&pdev->dev);
+       i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
+                                                 "nvidia,tegra20-i2c-dvc");
        init_completion(&i2c_dev->msg_complete);
+       spin_lock_init(&i2c_dev->xfer_lock);
 
        if (!i2c_dev->hw->has_single_clk_source) {
                fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
                if (IS_ERR(fast_clk)) {
-                       dev_err(&pdev->dev, "missing fast clock");
+                       dev_err(&pdev->dev, "missing fast clock\n");
                        return PTR_ERR(fast_clk);
                }
                i2c_dev->fast_clk = fast_clk;
@@ -900,18 +965,27 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                goto unprepare_fast_clk;
        }
 
+       pm_runtime_enable(&pdev->dev);
+       if (!pm_runtime_enabled(&pdev->dev)) {
+               ret = tegra_i2c_runtime_resume(&pdev->dev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "runtime resume failed\n");
+                       goto unprepare_div_clk;
+               }
+       }
+
        if (i2c_dev->is_multimaster_mode) {
                ret = clk_enable(i2c_dev->div_clk);
                if (ret < 0) {
                        dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
                                ret);
-                       goto unprepare_div_clk;
+                       goto disable_rpm;
                }
        }
 
        ret = tegra_i2c_init(i2c_dev);
        if (ret) {
-               dev_err(&pdev->dev, "Failed to initialize i2c controller");
+               dev_err(&pdev->dev, "Failed to initialize i2c controller\n");
                goto disable_div_clk;
        }
 
@@ -925,17 +999,15 @@ static int tegra_i2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
        i2c_dev->adapter.owner = THIS_MODULE;
        i2c_dev->adapter.class = I2C_CLASS_DEPRECATED;
-       strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter",
+       strlcpy(i2c_dev->adapter.name, dev_name(&pdev->dev),
                sizeof(i2c_dev->adapter.name));
        i2c_dev->adapter.dev.parent = &pdev->dev;
        i2c_dev->adapter.nr = pdev->id;
        i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
 
        ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add I2C adapter\n");
+       if (ret)
                goto disable_div_clk;
-       }
 
        return 0;
 
@@ -943,6 +1015,11 @@ disable_div_clk:
        if (i2c_dev->is_multimaster_mode)
                clk_disable(i2c_dev->div_clk);
 
+disable_rpm:
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_i2c_runtime_suspend(&pdev->dev);
+
 unprepare_div_clk:
        clk_unprepare(i2c_dev->div_clk);
 
@@ -956,11 +1033,16 @@ unprepare_fast_clk:
 static int tegra_i2c_remove(struct platform_device *pdev)
 {
        struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
        i2c_del_adapter(&i2c_dev->adapter);
 
        if (i2c_dev->is_multimaster_mode)
                clk_disable(i2c_dev->div_clk);
 
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_i2c_runtime_suspend(&pdev->dev);
+
        clk_unprepare(i2c_dev->div_clk);
        if (!i2c_dev->hw->has_single_clk_source)
                clk_unprepare(i2c_dev->fast_clk);
@@ -988,20 +1070,19 @@ static int tegra_i2c_resume(struct device *dev)
        i2c_lock_adapter(&i2c_dev->adapter);
 
        ret = tegra_i2c_init(i2c_dev);
-
-       if (ret) {
-               i2c_unlock_adapter(&i2c_dev->adapter);
-               return ret;
-       }
-
-       i2c_dev->is_suspended = false;
+       if (!ret)
+               i2c_dev->is_suspended = false;
 
        i2c_unlock_adapter(&i2c_dev->adapter);
 
-       return 0;
+       return ret;
 }
 
-static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, tegra_i2c_resume);
+static const struct dev_pm_ops tegra_i2c_pm = {
+       SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
+                          NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
+};
 #define TEGRA_I2C_PM   (&tegra_i2c_pm)
 #else
 #define TEGRA_I2C_PM   NULL
diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
new file mode 100644 (file)
index 0000000..bba5b42
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Cavium ThunderX i2c driver.
+ *
+ * Copyright (C) 2015,2016 Cavium Inc.
+ * Authors: Fred Martin <fmartin@caviumnetworks.com>
+ *         Jan Glauber <jglauber@cavium.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-smbus.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/pci.h>
+
+#include "i2c-octeon-core.h"
+
+#define DRV_NAME "i2c-thunderx"
+
+#define PCI_DEVICE_ID_THUNDER_TWSI     0xa012
+
+#define SYS_FREQ_DEFAULT               700000000
+
+#define TWSI_INT_ENA_W1C               0x1028
+#define TWSI_INT_ENA_W1S               0x1030
+
+/*
+ * Enable the CORE interrupt.
+ * The interrupt will be asserted when there is non-STAT_IDLE state in the
+ * SW_TWSI_EOP_TWSI_STAT register.
+ */
+static void thunder_i2c_int_enable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_writeq_flush(TWSI_INT_CORE_INT,
+                               i2c->twsi_base + TWSI_INT_ENA_W1S);
+}
+
+/*
+ * Disable the CORE interrupt.
+ */
+static void thunder_i2c_int_disable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_writeq_flush(TWSI_INT_CORE_INT,
+                               i2c->twsi_base + TWSI_INT_ENA_W1C);
+}
+
+static void thunder_i2c_hlc_int_enable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_writeq_flush(TWSI_INT_ST_INT | TWSI_INT_TS_INT,
+                               i2c->twsi_base + TWSI_INT_ENA_W1S);
+}
+
+static void thunder_i2c_hlc_int_disable(struct octeon_i2c *i2c)
+{
+       octeon_i2c_writeq_flush(TWSI_INT_ST_INT | TWSI_INT_TS_INT,
+                               i2c->twsi_base + TWSI_INT_ENA_W1C);
+}
+
+static u32 thunderx_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
+              I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_SMBUS_BLOCK_PROC_CALL;
+}
+
+static const struct i2c_algorithm thunderx_i2c_algo = {
+       .master_xfer = octeon_i2c_xfer,
+       .functionality = thunderx_i2c_functionality,
+};
+
+static struct i2c_adapter thunderx_i2c_ops = {
+       .owner  = THIS_MODULE,
+       .name   = "ThunderX adapter",
+       .algo   = &thunderx_i2c_algo,
+};
+
+static void thunder_i2c_clock_enable(struct device *dev, struct octeon_i2c *i2c)
+{
+       int ret;
+
+       i2c->clk = clk_get(dev, NULL);
+       if (IS_ERR(i2c->clk)) {
+               i2c->clk = NULL;
+               goto skip;
+       }
+
+       ret = clk_prepare_enable(i2c->clk);
+       if (ret)
+               goto skip;
+       i2c->sys_freq = clk_get_rate(i2c->clk);
+
+skip:
+       if (!i2c->sys_freq)
+               i2c->sys_freq = SYS_FREQ_DEFAULT;
+}
+
+static void thunder_i2c_clock_disable(struct device *dev, struct clk *clk)
+{
+       if (!clk)
+               return;
+       clk_disable_unprepare(clk);
+       clk_put(clk);
+}
+
+static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c,
+                                     struct device_node *node)
+{
+       u32 type;
+
+       if (!node)
+               return -EINVAL;
+
+       i2c->alert_data.irq = irq_of_parse_and_map(node, 0);
+       if (!i2c->alert_data.irq)
+               return -EINVAL;
+
+       type = irqd_get_trigger_type(irq_get_irq_data(i2c->alert_data.irq));
+       i2c->alert_data.alert_edge_triggered =
+               (type & IRQ_TYPE_LEVEL_MASK) ? 1 : 0;
+
+       i2c->ara = i2c_setup_smbus_alert(&i2c->adap, &i2c->alert_data);
+       if (!i2c->ara)
+               return -ENODEV;
+       return 0;
+}
+
+static int thunder_i2c_smbus_setup(struct octeon_i2c *i2c,
+                                  struct device_node *node)
+{
+       /* TODO: ACPI support */
+       if (!acpi_disabled)
+               return -EOPNOTSUPP;
+
+       return thunder_i2c_smbus_setup_of(i2c, node);
+}
+
+static void thunder_i2c_smbus_remove(struct octeon_i2c *i2c)
+{
+       if (i2c->ara)
+               i2c_unregister_device(i2c->ara);
+}
+
+static int thunder_i2c_probe_pci(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+{
+       struct device *dev = &pdev->dev;
+       struct octeon_i2c *i2c;
+       int ret;
+
+       i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+       if (!i2c)
+               return -ENOMEM;
+
+       i2c->roff.sw_twsi = 0x1000;
+       i2c->roff.twsi_int = 0x1010;
+       i2c->roff.sw_twsi_ext = 0x1018;
+
+       i2c->dev = dev;
+       pci_set_drvdata(pdev, i2c);
+       ret = pcim_enable_device(pdev);
+       if (ret)
+               return ret;
+
+       ret = pci_request_regions(pdev, DRV_NAME);
+       if (ret)
+               return ret;
+
+       i2c->twsi_base = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0));
+       if (!i2c->twsi_base)
+               return -EINVAL;
+
+       thunder_i2c_clock_enable(dev, i2c);
+       ret = device_property_read_u32(dev, "clock-frequency", &i2c->twsi_freq);
+       if (ret)
+               i2c->twsi_freq = 100000;
+
+       init_waitqueue_head(&i2c->queue);
+
+       i2c->int_enable = thunder_i2c_int_enable;
+       i2c->int_disable = thunder_i2c_int_disable;
+       i2c->hlc_int_enable = thunder_i2c_hlc_int_enable;
+       i2c->hlc_int_disable = thunder_i2c_hlc_int_disable;
+
+       ret = pci_enable_msix(pdev, &i2c->i2c_msix, 1);
+       if (ret)
+               goto error;
+
+       ret = devm_request_irq(dev, i2c->i2c_msix.vector, octeon_i2c_isr, 0,
+                              DRV_NAME, i2c);
+       if (ret)
+               goto error;
+
+       ret = octeon_i2c_init_lowlevel(i2c);
+       if (ret)
+               goto error;
+
+       octeon_i2c_set_clock(i2c);
+
+       i2c->adap = thunderx_i2c_ops;
+       i2c->adap.retries = 5;
+       i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
+       i2c->adap.dev.parent = dev;
+       i2c->adap.dev.of_node = pdev->dev.of_node;
+       snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+                "Cavium ThunderX i2c adapter at %s", dev_name(dev));
+       i2c_set_adapdata(&i2c->adap, i2c);
+
+       ret = i2c_add_adapter(&i2c->adap);
+       if (ret)
+               goto error;
+
+       dev_info(i2c->dev, "Probed. Set system clock to %u\n", i2c->sys_freq);
+
+       ret = thunder_i2c_smbus_setup(i2c, pdev->dev.of_node);
+       if (ret)
+               dev_info(dev, "SMBUS alert not active on this bus\n");
+
+       return 0;
+
+error:
+       thunder_i2c_clock_disable(dev, i2c->clk);
+       return ret;
+}
+
+static void thunder_i2c_remove_pci(struct pci_dev *pdev)
+{
+       struct octeon_i2c *i2c = pci_get_drvdata(pdev);
+
+       thunder_i2c_smbus_remove(i2c);
+       thunder_i2c_clock_disable(&pdev->dev, i2c->clk);
+       i2c_del_adapter(&i2c->adap);
+}
+
+static const struct pci_device_id thunder_i2c_pci_id_table[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_TWSI) },
+       { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, thunder_i2c_pci_id_table);
+
+static struct pci_driver thunder_i2c_pci_driver = {
+       .name           = DRV_NAME,
+       .id_table       = thunder_i2c_pci_id_table,
+       .probe          = thunder_i2c_probe_pci,
+       .remove         = thunder_i2c_remove_pci,
+};
+
+module_pci_driver(thunder_i2c_pci_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fred Martin <fmartin@caviumnetworks.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter for Cavium ThunderX SOC");
index aeead0d27d1007ead1ac78429aa9491c1613ae8d..db9105e52c79a1ad7ba0c9b867a617244f40b874 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/clk.h>
 #include <linux/i2c.h>
+#include <linux/iopoll.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -348,14 +349,19 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
        dev_dbg(&adap->dev, "complete\n");
 
        if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) {
-               u32 status = readl(priv->membase + UNIPHIER_FI2C_SR);
-
-               if (!(status & UNIPHIER_FI2C_SR_STS) ||
-                   status & UNIPHIER_FI2C_SR_BB) {
+               u32 status;
+               int ret;
+
+               ret = readl_poll_timeout(priv->membase + UNIPHIER_FI2C_SR,
+                                        status,
+                                        (status & UNIPHIER_FI2C_SR_STS) &&
+                                        !(status & UNIPHIER_FI2C_SR_BB),
+                                        1, 20);
+               if (ret) {
                        dev_err(&adap->dev,
                                "stop condition was not completed.\n");
                        uniphier_fi2c_recover(priv);
-                       return -EBUSY;
+                       return ret;
                }
        }
 
@@ -455,54 +461,25 @@ static struct i2c_bus_recovery_info uniphier_fi2c_bus_recovery_info = {
        .unprepare_recovery = uniphier_fi2c_unprepare_recovery,
 };
 
-static int uniphier_fi2c_clk_init(struct device *dev,
-                                 struct uniphier_fi2c_priv *priv)
+static void uniphier_fi2c_hw_init(struct uniphier_fi2c_priv *priv,
+                                 u32 bus_speed, unsigned long clk_rate)
 {
-       struct device_node *np = dev->of_node;
-       unsigned long clk_rate;
-       u32 bus_speed, clk_count;
-       int ret;
-
-       if (of_property_read_u32(np, "clock-frequency", &bus_speed))
-               bus_speed = UNIPHIER_FI2C_DEFAULT_SPEED;
-
-       if (!bus_speed) {
-               dev_err(dev, "clock-frequency should not be zero\n");
-               return -EINVAL;
-       }
-
-       if (bus_speed > UNIPHIER_FI2C_MAX_SPEED)
-               bus_speed = UNIPHIER_FI2C_MAX_SPEED;
-
-       /* Get input clk rate through clk driver */
-       priv->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(dev, "failed to get clock\n");
-               return PTR_ERR(priv->clk);
-       }
+       u32 tmp;
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
-               return ret;
-
-       clk_rate = clk_get_rate(priv->clk);
-       if (!clk_rate) {
-               dev_err(dev, "input clock rate should not be zero\n");
-               return -EINVAL;
-       }
+       tmp = readl(priv->membase + UNIPHIER_FI2C_CR);
+       tmp |= UNIPHIER_FI2C_CR_MST;
+       writel(tmp, priv->membase + UNIPHIER_FI2C_CR);
 
        uniphier_fi2c_reset(priv);
 
-       clk_count = clk_rate / bus_speed;
+       tmp = clk_rate / bus_speed;
 
-       writel(clk_count, priv->membase + UNIPHIER_FI2C_CYC);
-       writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_LCTL);
-       writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_SSUT);
-       writel(clk_count / 16, priv->membase + UNIPHIER_FI2C_DSUT);
+       writel(tmp, priv->membase + UNIPHIER_FI2C_CYC);
+       writel(tmp / 2, priv->membase + UNIPHIER_FI2C_LCTL);
+       writel(tmp / 2, priv->membase + UNIPHIER_FI2C_SSUT);
+       writel(tmp / 16, priv->membase + UNIPHIER_FI2C_DSUT);
 
        uniphier_fi2c_prepare_operation(priv);
-
-       return 0;
 }
 
 static int uniphier_fi2c_probe(struct platform_device *pdev)
@@ -510,8 +487,9 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct uniphier_fi2c_priv *priv;
        struct resource *regs;
-       int irq;
-       int ret;
+       u32 bus_speed;
+       unsigned long clk_rate;
+       int irq, ret;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -528,6 +506,31 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
                return irq;
        }
 
+       if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
+               bus_speed = UNIPHIER_FI2C_DEFAULT_SPEED;
+
+       if (!bus_speed || bus_speed > UNIPHIER_FI2C_MAX_SPEED) {
+               dev_err(dev, "invalid clock-frequency %d\n", bus_speed);
+               return -EINVAL;
+       }
+
+       priv->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(priv->clk);
+       }
+
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return ret;
+
+       clk_rate = clk_get_rate(priv->clk);
+       if (!clk_rate) {
+               dev_err(dev, "input clock rate should not be zero\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
        init_completion(&priv->comp);
        priv->adap.owner = THIS_MODULE;
        priv->adap.algo = &uniphier_fi2c_algo;
@@ -538,9 +541,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(&priv->adap, priv);
        platform_set_drvdata(pdev, priv);
 
-       ret = uniphier_fi2c_clk_init(dev, priv);
-       if (ret)
-               goto err;
+       uniphier_fi2c_hw_init(priv, bus_speed, clk_rate);
 
        ret = devm_request_irq(dev, irq, uniphier_fi2c_interrupt, 0,
                               pdev->name, priv);
@@ -550,11 +551,6 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
        }
 
        ret = i2c_add_adapter(&priv->adap);
-       if (ret) {
-               dev_err(dev, "failed to add I2C adapter\n");
-               goto err;
-       }
-
 err:
        if (ret)
                clk_disable_unprepare(priv->clk);
index 475a5eb514e2153fec01a55c294fd0930110cb6a..56e92af46ddc40a1d8642fac92cf3afd86a7f3d0 100644 (file)
@@ -316,50 +316,15 @@ static struct i2c_bus_recovery_info uniphier_i2c_bus_recovery_info = {
        .unprepare_recovery = uniphier_i2c_unprepare_recovery,
 };
 
-static int uniphier_i2c_clk_init(struct device *dev,
-                                struct uniphier_i2c_priv *priv)
+static void uniphier_i2c_hw_init(struct uniphier_i2c_priv *priv,
+                                u32 bus_speed, unsigned long clk_rate)
 {
-       struct device_node *np = dev->of_node;
-       unsigned long clk_rate;
-       u32 bus_speed;
-       int ret;
-
-       if (of_property_read_u32(np, "clock-frequency", &bus_speed))
-               bus_speed = UNIPHIER_I2C_DEFAULT_SPEED;
-
-       if (!bus_speed) {
-               dev_err(dev, "clock-frequency should not be zero\n");
-               return -EINVAL;
-       }
-
-       if (bus_speed > UNIPHIER_I2C_MAX_SPEED)
-               bus_speed = UNIPHIER_I2C_MAX_SPEED;
-
-       /* Get input clk rate through clk driver */
-       priv->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(dev, "failed to get clock\n");
-               return PTR_ERR(priv->clk);
-       }
-
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
-               return ret;
-
-       clk_rate = clk_get_rate(priv->clk);
-       if (!clk_rate) {
-               dev_err(dev, "input clock rate should not be zero\n");
-               return -EINVAL;
-       }
-
        uniphier_i2c_reset(priv, true);
 
        writel((clk_rate / bus_speed / 2 << 16) | (clk_rate / bus_speed),
               priv->membase + UNIPHIER_I2C_CLK);
 
        uniphier_i2c_reset(priv, false);
-
-       return 0;
 }
 
 static int uniphier_i2c_probe(struct platform_device *pdev)
@@ -367,8 +332,9 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct uniphier_i2c_priv *priv;
        struct resource *regs;
-       int irq;
-       int ret;
+       u32 bus_speed;
+       unsigned long clk_rate;
+       int irq, ret;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -385,6 +351,31 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
                return irq;
        }
 
+       if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
+               bus_speed = UNIPHIER_I2C_DEFAULT_SPEED;
+
+       if (!bus_speed || bus_speed > UNIPHIER_I2C_MAX_SPEED) {
+               dev_err(dev, "invalid clock-frequency %d\n", bus_speed);
+               return -EINVAL;
+       }
+
+       priv->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(priv->clk);
+       }
+
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return ret;
+
+       clk_rate = clk_get_rate(priv->clk);
+       if (!clk_rate) {
+               dev_err(dev, "input clock rate should not be zero\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
        init_completion(&priv->comp);
        priv->adap.owner = THIS_MODULE;
        priv->adap.algo = &uniphier_i2c_algo;
@@ -395,9 +386,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(&priv->adap, priv);
        platform_set_drvdata(pdev, priv);
 
-       ret = uniphier_i2c_clk_init(dev, priv);
-       if (ret)
-               goto err;
+       uniphier_i2c_hw_init(priv, bus_speed, clk_rate);
 
        ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name,
                               priv);
@@ -407,11 +396,6 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
        }
 
        ret = i2c_add_adapter(&priv->adap);
-       if (ret) {
-               dev_err(dev, "failed to add I2C adapter\n");
-               goto err;
-       }
-
 err:
        if (ret)
                clk_disable_unprepare(priv->clk);
index e1e3a85596c56285cd9ec89bf03e255ec69784d3..fbd0fd59f31239d83299b1949da95b0952f06379 100644 (file)
@@ -432,10 +432,8 @@ static int wmt_i2c_probe(struct platform_device *pdev)
        }
 
        err = i2c_add_adapter(adap);
-       if (err) {
-               dev_err(&pdev->dev, "failed to add adapter\n");
+       if (err)
                return err;
-       }
 
        platform_set_drvdata(pdev, i2c_dev);
 
index 4233f5695352fdc951c54c54dc6fbb9de926d26e..263685c7a5128773f12dfc00bd4ba75324aeee4c 100644 (file)
@@ -418,7 +418,6 @@ static int xgene_slimpro_i2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(adapter, ctx);
        rc = i2c_add_adapter(adapter);
        if (rc) {
-               dev_err(&pdev->dev, "Adapter registeration failed\n");
                mbox_free_channel(ctx->mbox_chan);
                return rc;
        }
index 74f54f2f471fa7d311783ab1e34069e28d98e70d..66bce3b311a1998a1a446ff7012d50ead27fd987 100644 (file)
@@ -804,7 +804,6 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        /* add i2c adapter to i2c tree */
        ret = i2c_add_adapter(&i2c->adap);
        if (ret) {
-               dev_err(&pdev->dev, "Failed to add adapter\n");
                xiic_deinit(i2c);
                goto err_clk_dis;
        }
index 55a7bef1b2e1df643d5dac119678119b5134ddd0..2a972ed7aa0df113185b9fb567e76d11638739e4 100644 (file)
@@ -400,10 +400,8 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
        i2c_set_adapdata(&priv->adapter, priv);
 
        err = i2c_add_adapter(&priv->adapter);
-       if (err) {
-               dev_err(&pdev->dev, "failed to add I2C adapter!\n");
+       if (err)
                return err;
-       }
 
        platform_set_drvdata(pdev, priv);
        dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);
index 613c3a4f2c51426453397f73db5ef72c7a02eac7..0968f59b6df58690207b182b4fe192d5422e349b 100644 (file)
@@ -432,10 +432,8 @@ static int xlr_i2c_probe(struct platform_device *pdev)
 
        i2c_set_adapdata(&priv->adap, priv);
        ret = i2c_add_numbered_adapter(&priv->adap);
-       if (ret < 0) {
-               dev_err(&priv->adap.dev, "Failed to add i2c bus.\n");
+       if (ret < 0)
                return ret;
-       }
 
        platform_set_drvdata(pdev, priv);
        dev_info(&priv->adap.dev, "Added I2C Bus.\n");
index da3a02ef4a3187e2c97e1a8bcb795c318544c4d1..98fffa3a09f7fe5e716415c79963b7ac15587b9c 100644 (file)
@@ -88,7 +88,7 @@ void i2c_transfer_trace_unreg(void)
 }
 
 #if defined(CONFIG_ACPI)
-struct acpi_i2c_handler_data {
+struct i2c_acpi_handler_data {
        struct acpi_connection_info info;
        struct i2c_adapter *adapter;
 };
@@ -103,15 +103,18 @@ struct gsb_buffer {
        };
 } __packed;
 
-struct acpi_i2c_lookup {
+struct i2c_acpi_lookup {
        struct i2c_board_info *info;
        acpi_handle adapter_handle;
        acpi_handle device_handle;
+       acpi_handle search_handle;
+       u32 speed;
+       u32 min_speed;
 };
 
-static int acpi_i2c_fill_info(struct acpi_resource *ares, void *data)
+static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
 {
-       struct acpi_i2c_lookup *lookup = data;
+       struct i2c_acpi_lookup *lookup = data;
        struct i2c_board_info *info = lookup->info;
        struct acpi_resource_i2c_serialbus *sb;
        acpi_status status;
@@ -130,19 +133,18 @@ static int acpi_i2c_fill_info(struct acpi_resource *ares, void *data)
                return 1;
 
        info->addr = sb->slave_address;
+       lookup->speed = sb->connection_speed;
        if (sb->access_mode == ACPI_I2C_10BIT_MODE)
                info->flags |= I2C_CLIENT_TEN;
 
        return 1;
 }
 
-static int acpi_i2c_get_info(struct acpi_device *adev,
-                            struct i2c_board_info *info,
-                            acpi_handle *adapter_handle)
+static int i2c_acpi_do_lookup(struct acpi_device *adev,
+                             struct i2c_acpi_lookup *lookup)
 {
+       struct i2c_board_info *info = lookup->info;
        struct list_head resource_list;
-       struct resource_entry *entry;
-       struct acpi_i2c_lookup lookup;
        int ret;
 
        if (acpi_bus_get_status(adev) || !adev->status.present ||
@@ -150,24 +152,58 @@ static int acpi_i2c_get_info(struct acpi_device *adev,
                return -EINVAL;
 
        memset(info, 0, sizeof(*info));
-       info->fwnode = acpi_fwnode_handle(adev);
-
-       memset(&lookup, 0, sizeof(lookup));
-       lookup.device_handle = acpi_device_handle(adev);
-       lookup.info = info;
+       lookup->device_handle = acpi_device_handle(adev);
 
        /* Look up for I2cSerialBus resource */
        INIT_LIST_HEAD(&resource_list);
        ret = acpi_dev_get_resources(adev, &resource_list,
-                                    acpi_i2c_fill_info, &lookup);
+                                    i2c_acpi_fill_info, lookup);
        acpi_dev_free_resource_list(&resource_list);
 
        if (ret < 0 || !info->addr)
                return -EINVAL;
 
-       *adapter_handle = lookup.adapter_handle;
+       return 0;
+}
+
+static int i2c_acpi_get_info(struct acpi_device *adev,
+                            struct i2c_board_info *info,
+                            struct i2c_adapter *adapter,
+                            acpi_handle *adapter_handle)
+{
+       struct list_head resource_list;
+       struct resource_entry *entry;
+       struct i2c_acpi_lookup lookup;
+       int ret;
+
+       memset(&lookup, 0, sizeof(lookup));
+       lookup.info = info;
+
+       ret = i2c_acpi_do_lookup(adev, &lookup);
+       if (ret)
+               return ret;
+
+       if (adapter) {
+               /* The adapter must match the one in I2cSerialBus() connector */
+               if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle)
+                       return -ENODEV;
+       } else {
+               struct acpi_device *adapter_adev;
+
+               /* The adapter must be present */
+               if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev))
+                       return -ENODEV;
+               if (acpi_bus_get_status(adapter_adev) ||
+                   !adapter_adev->status.present)
+                       return -ENODEV;
+       }
+
+       info->fwnode = acpi_fwnode_handle(adev);
+       if (adapter_handle)
+               *adapter_handle = lookup.adapter_handle;
 
        /* Then fill IRQ number if any */
+       INIT_LIST_HEAD(&resource_list);
        ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
        if (ret < 0)
                return -EINVAL;
@@ -186,7 +222,7 @@ static int acpi_i2c_get_info(struct acpi_device *adev,
        return 0;
 }
 
-static void acpi_i2c_register_device(struct i2c_adapter *adapter,
+static void i2c_acpi_register_device(struct i2c_adapter *adapter,
                                     struct acpi_device *adev,
                                     struct i2c_board_info *info)
 {
@@ -201,39 +237,35 @@ static void acpi_i2c_register_device(struct i2c_adapter *adapter,
        }
 }
 
-static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
+static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
                                       void *data, void **return_value)
 {
        struct i2c_adapter *adapter = data;
        struct acpi_device *adev;
-       acpi_handle adapter_handle;
        struct i2c_board_info info;
 
        if (acpi_bus_get_device(handle, &adev))
                return AE_OK;
 
-       if (acpi_i2c_get_info(adev, &info, &adapter_handle))
+       if (i2c_acpi_get_info(adev, &info, adapter, NULL))
                return AE_OK;
 
-       if (adapter_handle != ACPI_HANDLE(&adapter->dev))
-               return AE_OK;
-
-       acpi_i2c_register_device(adapter, adev, &info);
+       i2c_acpi_register_device(adapter, adev, &info);
 
        return AE_OK;
 }
 
-#define ACPI_I2C_MAX_SCAN_DEPTH 32
+#define I2C_ACPI_MAX_SCAN_DEPTH 32
 
 /**
- * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
+ * i2c_acpi_register_devices - enumerate I2C slave devices behind adapter
  * @adap: pointer to adapter
  *
  * Enumerate all I2C slave devices behind this adapter by walking the ACPI
  * namespace. When a device is found it will be added to the Linux device
  * model and bound to the corresponding ACPI handle.
  */
-static void acpi_i2c_register_devices(struct i2c_adapter *adap)
+static void i2c_acpi_register_devices(struct i2c_adapter *adap)
 {
        acpi_status status;
 
@@ -241,14 +273,72 @@ static void acpi_i2c_register_devices(struct i2c_adapter *adap)
                return;
 
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-                                    ACPI_I2C_MAX_SCAN_DEPTH,
-                                    acpi_i2c_add_device, NULL,
+                                    I2C_ACPI_MAX_SCAN_DEPTH,
+                                    i2c_acpi_add_device, NULL,
                                     adap, NULL);
        if (ACPI_FAILURE(status))
                dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
 }
 
-static int acpi_i2c_match_adapter(struct device *dev, void *data)
+static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
+                                          void *data, void **return_value)
+{
+       struct i2c_acpi_lookup *lookup = data;
+       struct acpi_device *adev;
+
+       if (acpi_bus_get_device(handle, &adev))
+               return AE_OK;
+
+       if (i2c_acpi_do_lookup(adev, lookup))
+               return AE_OK;
+
+       if (lookup->search_handle != lookup->adapter_handle)
+               return AE_OK;
+
+       if (lookup->speed <= lookup->min_speed)
+               lookup->min_speed = lookup->speed;
+
+       return AE_OK;
+}
+
+/**
+ * i2c_acpi_find_bus_speed - find I2C bus speed from ACPI
+ * @dev: The device owning the bus
+ *
+ * Find the I2C bus speed by walking the ACPI namespace for all I2C slaves
+ * devices connected to this bus and use the speed of slowest device.
+ *
+ * Returns the speed in Hz or zero
+ */
+u32 i2c_acpi_find_bus_speed(struct device *dev)
+{
+       struct i2c_acpi_lookup lookup;
+       struct i2c_board_info dummy;
+       acpi_status status;
+
+       if (!has_acpi_companion(dev))
+               return 0;
+
+       memset(&lookup, 0, sizeof(lookup));
+       lookup.search_handle = ACPI_HANDLE(dev);
+       lookup.min_speed = UINT_MAX;
+       lookup.info = &dummy;
+
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                    I2C_ACPI_MAX_SCAN_DEPTH,
+                                    i2c_acpi_lookup_speed, NULL,
+                                    &lookup, NULL);
+
+       if (ACPI_FAILURE(status)) {
+               dev_warn(dev, "unable to find I2C bus speed from ACPI\n");
+               return 0;
+       }
+
+       return lookup.min_speed != UINT_MAX ? lookup.min_speed : 0;
+}
+EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
+
+static int i2c_acpi_match_adapter(struct device *dev, void *data)
 {
        struct i2c_adapter *adapter = i2c_verify_adapter(dev);
 
@@ -258,29 +348,29 @@ static int acpi_i2c_match_adapter(struct device *dev, void *data)
        return ACPI_HANDLE(dev) == (acpi_handle)data;
 }
 
-static int acpi_i2c_match_device(struct device *dev, void *data)
+static int i2c_acpi_match_device(struct device *dev, void *data)
 {
        return ACPI_COMPANION(dev) == data;
 }
 
-static struct i2c_adapter *acpi_i2c_find_adapter_by_handle(acpi_handle handle)
+static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
 {
        struct device *dev;
 
        dev = bus_find_device(&i2c_bus_type, NULL, handle,
-                             acpi_i2c_match_adapter);
+                             i2c_acpi_match_adapter);
        return dev ? i2c_verify_adapter(dev) : NULL;
 }
 
-static struct i2c_client *acpi_i2c_find_client_by_adev(struct acpi_device *adev)
+static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
 {
        struct device *dev;
 
-       dev = bus_find_device(&i2c_bus_type, NULL, adev, acpi_i2c_match_device);
+       dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device);
        return dev ? i2c_verify_client(dev) : NULL;
 }
 
-static int acpi_i2c_notify(struct notifier_block *nb, unsigned long value,
+static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
                           void *arg)
 {
        struct acpi_device *adev = arg;
@@ -291,20 +381,20 @@ static int acpi_i2c_notify(struct notifier_block *nb, unsigned long value,
 
        switch (value) {
        case ACPI_RECONFIG_DEVICE_ADD:
-               if (acpi_i2c_get_info(adev, &info, &adapter_handle))
+               if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle))
                        break;
 
-               adapter = acpi_i2c_find_adapter_by_handle(adapter_handle);
+               adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
                if (!adapter)
                        break;
 
-               acpi_i2c_register_device(adapter, adev, &info);
+               i2c_acpi_register_device(adapter, adev, &info);
                break;
        case ACPI_RECONFIG_DEVICE_REMOVE:
                if (!acpi_device_enumerated(adev))
                        break;
 
-               client = acpi_i2c_find_client_by_adev(adev);
+               client = i2c_acpi_find_client_by_adev(adev);
                if (!client)
                        break;
 
@@ -317,10 +407,10 @@ static int acpi_i2c_notify(struct notifier_block *nb, unsigned long value,
 }
 
 static struct notifier_block i2c_acpi_notifier = {
-       .notifier_call = acpi_i2c_notify,
+       .notifier_call = i2c_acpi_notify,
 };
 #else /* CONFIG_ACPI */
-static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) { }
+static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
 extern struct notifier_block i2c_acpi_notifier;
 #endif /* CONFIG_ACPI */
 
@@ -386,12 +476,12 @@ static int acpi_gsb_i2c_write_bytes(struct i2c_client *client,
 }
 
 static acpi_status
-acpi_i2c_space_handler(u32 function, acpi_physical_address command,
+i2c_acpi_space_handler(u32 function, acpi_physical_address command,
                        u32 bits, u64 *value64,
                        void *handler_context, void *region_context)
 {
        struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
-       struct acpi_i2c_handler_data *data = handler_context;
+       struct i2c_acpi_handler_data *data = handler_context;
        struct acpi_connection_info *info = &data->info;
        struct acpi_resource_i2c_serialbus *sb;
        struct i2c_adapter *adapter = data->adapter;
@@ -510,10 +600,10 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
 }
 
 
-static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
+static int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
 {
        acpi_handle handle;
-       struct acpi_i2c_handler_data *data;
+       struct i2c_acpi_handler_data *data;
        acpi_status status;
 
        if (!adapter->dev.parent)
@@ -524,7 +614,7 @@ static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
        if (!handle)
                return -ENODEV;
 
-       data = kzalloc(sizeof(struct acpi_i2c_handler_data),
+       data = kzalloc(sizeof(struct i2c_acpi_handler_data),
                            GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -538,7 +628,7 @@ static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
 
        status = acpi_install_address_space_handler(handle,
                                ACPI_ADR_SPACE_GSBUS,
-                               &acpi_i2c_space_handler,
+                               &i2c_acpi_space_handler,
                                NULL,
                                data);
        if (ACPI_FAILURE(status)) {
@@ -552,10 +642,10 @@ static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
        return 0;
 }
 
-static void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
+static void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
 {
        acpi_handle handle;
-       struct acpi_i2c_handler_data *data;
+       struct i2c_acpi_handler_data *data;
        acpi_status status;
 
        if (!adapter->dev.parent)
@@ -568,7 +658,7 @@ static void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
 
        acpi_remove_address_space_handler(handle,
                                ACPI_ADR_SPACE_GSBUS,
-                               &acpi_i2c_space_handler);
+                               &i2c_acpi_space_handler);
 
        status = acpi_bus_get_private_data(handle, (void **)&data);
        if (ACPI_SUCCESS(status))
@@ -577,10 +667,10 @@ static void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
        acpi_bus_detach_private_data(handle);
 }
 #else /* CONFIG_ACPI_I2C_OPREGION */
-static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
+static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
 { }
 
-static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
+static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
 { return 0; }
 #endif /* CONFIG_ACPI_I2C_OPREGION */
 
@@ -853,7 +943,7 @@ static int i2c_device_probe(struct device *dev)
                        status = 0;
 
                if (status)
-                       dev_warn(&client->dev, "failed to set up wakeup irq");
+                       dev_warn(&client->dev, "failed to set up wakeup irq\n");
        }
 
        dev_dbg(dev, "probe\n");
@@ -1208,8 +1298,9 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
        return client;
 
 out_err:
-       dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
-               "(%d)\n", client->name, client->addr, status);
+       dev_err(&adap->dev,
+               "Failed to register i2c client %s at 0x%02x (%d)\n",
+               client->name, client->addr, status);
 out_err_silent:
        kfree(client);
        return NULL;
@@ -1335,21 +1426,19 @@ static void i2c_adapter_dev_release(struct device *dev)
        complete(&adap->dev_released);
 }
 
-/*
- * This function is only needed for mutex_lock_nested, so it is never
- * called unless locking correctness checking is enabled. Thus we
- * make it inline to avoid a compiler warning. That's what gcc ends up
- * doing anyway.
- */
-static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter)
+unsigned int i2c_adapter_depth(struct i2c_adapter *adapter)
 {
        unsigned int depth = 0;
 
        while ((adapter = i2c_parent_is_i2c_adapter(adapter)))
                depth++;
 
+       WARN_ONCE(depth >= MAX_LOCKDEP_SUBCLASSES,
+                 "adapter depth exceeds lockdep subclass limit\n");
+
        return depth;
 }
+EXPORT_SYMBOL_GPL(i2c_adapter_depth);
 
 /*
  * Let users instantiate I2C devices through sysfs. This can be used when
@@ -1678,8 +1767,8 @@ static int i2c_do_add_adapter(struct i2c_driver *driver,
        if (driver->attach_adapter) {
                dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
                         driver->driver.name);
-               dev_warn(&adap->dev, "Please use another way to instantiate "
-                        "your i2c_client\n");
+               dev_warn(&adap->dev,
+                        "Please use another way to instantiate your i2c_client\n");
                /* We ignore the return code; if it fails, too bad */
                driver->attach_adapter(adap);
        }
@@ -1691,6 +1780,12 @@ static int __process_new_adapter(struct device_driver *d, void *data)
        return i2c_do_add_adapter(to_i2c_driver(d), data);
 }
 
+static const struct i2c_lock_operations i2c_adapter_lock_ops = {
+       .lock_bus =    i2c_adapter_lock_bus,
+       .trylock_bus = i2c_adapter_trylock_bus,
+       .unlock_bus =  i2c_adapter_unlock_bus,
+};
+
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
        int res = -EINVAL;
@@ -1710,11 +1805,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
                goto out_list;
        }
 
-       if (!adap->lock_bus) {
-               adap->lock_bus = i2c_adapter_lock_bus;
-               adap->trylock_bus = i2c_adapter_trylock_bus;
-               adap->unlock_bus = i2c_adapter_unlock_bus;
-       }
+       if (!adap->lock_ops)
+               adap->lock_ops = &i2c_adapter_lock_ops;
 
        rt_mutex_init(&adap->bus_lock);
        rt_mutex_init(&adap->mux_lock);
@@ -1752,8 +1844,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 
        /* create pre-declared device nodes */
        of_i2c_register_devices(adap);
-       acpi_i2c_register_devices(adap);
-       acpi_i2c_install_space_handler(adap);
+       i2c_acpi_register_devices(adap);
+       i2c_acpi_install_space_handler(adap);
 
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
@@ -1925,7 +2017,7 @@ void i2c_del_adapter(struct i2c_adapter *adap)
                return;
        }
 
-       acpi_i2c_remove_space_handler(adap);
+       i2c_acpi_remove_space_handler(adap);
        /* Tell drivers about this removal */
        mutex_lock(&core_lock);
        bus_for_each_drv(&i2c_bus_type, NULL, adap,
@@ -2451,15 +2543,16 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
        if (adap->algo->master_xfer) {
 #ifdef DEBUG
                for (ret = 0; ret < num; ret++) {
-                       dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
-                               "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
-                               ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
+                       dev_dbg(&adap->dev,
+                               "master_xfer[%d] %c, addr=0x%02x, len=%d%s\n",
+                               ret, (msgs[ret].flags & I2C_M_RD) ? 'R' : 'W',
+                               msgs[ret].addr, msgs[ret].len,
                                (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
                }
 #endif
 
                if (in_atomic() || irqs_disabled()) {
-                       ret = adap->trylock_bus(adap, I2C_LOCK_SEGMENT);
+                       ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT);
                        if (!ret)
                                /* I2C activity is ongoing. */
                                return -EAGAIN;
@@ -2619,9 +2712,9 @@ static int i2c_detect_address(struct i2c_client *temp_client,
 
        /* Consistency check */
        if (info.type[0] == '\0') {
-               dev_err(&adapter->dev, "%s detection function provided "
-                       "no name for 0x%x\n", driver->driver.name,
-                       addr);
+               dev_err(&adapter->dev,
+                       "%s detection function provided no name for 0x%x\n",
+                       driver->driver.name, addr);
        } else {
                struct i2c_client *client;
 
@@ -2659,9 +2752,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
        /* Warn that the adapter lost class based instantiation */
        if (adapter->class == I2C_CLASS_DEPRECATED) {
                dev_dbg(&adapter->dev,
-                       "This adapter dropped support for I2C classes and "
-                       "won't auto-detect %s devices anymore. If you need it, check "
-                       "'Documentation/i2c/instantiating-devices' for alternatives.\n",
+                       "This adapter dropped support for I2C classes and won't auto-detect %s devices anymore. "
+                       "If you need it, check 'Documentation/i2c/instantiating-devices' for alternatives.\n",
                        driver->driver.name);
                return 0;
        }
@@ -2677,8 +2769,9 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
        temp_client->adapter = adapter;
 
        for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
-               dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
-                       "addr 0x%02x\n", adap_id, address_list[i]);
+               dev_dbg(&adapter->dev,
+                       "found normal entry for adapter %d, addr 0x%02x\n",
+                       adap_id, address_list[i]);
                temp_client->addr = address_list[i];
                err = i2c_detect_address(temp_client, driver);
                if (unlikely(err))
@@ -2710,15 +2803,16 @@ i2c_new_probed_device(struct i2c_adapter *adap,
        for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
                /* Check address validity */
                if (i2c_check_7bit_addr_validity_strict(addr_list[i]) < 0) {
-                       dev_warn(&adap->dev, "Invalid 7-bit address "
-                                "0x%02x\n", addr_list[i]);
+                       dev_warn(&adap->dev, "Invalid 7-bit address 0x%02x\n",
+                                addr_list[i]);
                        continue;
                }
 
                /* Check address availability (7 bit, no need to encode flags) */
                if (i2c_check_addr_busy(adap, addr_list[i])) {
-                       dev_dbg(&adap->dev, "Address 0x%02x already in "
-                               "use, not probing\n", addr_list[i]);
+                       dev_dbg(&adap->dev,
+                               "Address 0x%02x already in use, not probing\n",
+                               addr_list[i]);
                        continue;
                }
 
index 8eee98634cda57839cda747708469715d6cfa271..83768e85a919cb5c6eb60af01ce5918027600962 100644 (file)
@@ -159,7 +159,7 @@ static int i2c_mux_trylock_bus(struct i2c_adapter *adapter, unsigned int flags)
                return 0;       /* mux_lock not locked, failure */
        if (!(flags & I2C_LOCK_ROOT_ADAPTER))
                return 1;       /* we only want mux_lock, success */
-       if (parent->trylock_bus(parent, flags))
+       if (i2c_trylock_bus(parent, flags))
                return 1;       /* parent locked too, success */
        rt_mutex_unlock(&parent->mux_lock);
        return 0;               /* parent not locked, failure */
@@ -193,7 +193,7 @@ static int i2c_parent_trylock_bus(struct i2c_adapter *adapter,
 
        if (!rt_mutex_trylock(&parent->mux_lock))
                return 0;       /* mux_lock not locked, failure */
-       if (parent->trylock_bus(parent, flags))
+       if (i2c_trylock_bus(parent, flags))
                return 1;       /* parent locked too, success */
        rt_mutex_unlock(&parent->mux_lock);
        return 0;               /* parent not locked, failure */
@@ -255,6 +255,10 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
        muxc->dev = dev;
        if (flags & I2C_MUX_LOCKED)
                muxc->mux_locked = true;
+       if (flags & I2C_MUX_ARBITRATOR)
+               muxc->arbitrator = true;
+       if (flags & I2C_MUX_GATE)
+               muxc->gate = true;
        muxc->select = select;
        muxc->deselect = deselect;
        muxc->max_adapters = max_adapters;
@@ -263,6 +267,18 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
 }
 EXPORT_SYMBOL_GPL(i2c_mux_alloc);
 
+static const struct i2c_lock_operations i2c_mux_lock_ops = {
+       .lock_bus =    i2c_mux_lock_bus,
+       .trylock_bus = i2c_mux_trylock_bus,
+       .unlock_bus =  i2c_mux_unlock_bus,
+};
+
+static const struct i2c_lock_operations i2c_parent_lock_ops = {
+       .lock_bus =    i2c_parent_lock_bus,
+       .trylock_bus = i2c_parent_trylock_bus,
+       .unlock_bus =  i2c_parent_unlock_bus,
+};
+
 int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
                        u32 force_nr, u32 chan_id,
                        unsigned int class)
@@ -312,15 +328,10 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
        priv->adap.retries = parent->retries;
        priv->adap.timeout = parent->timeout;
        priv->adap.quirks = parent->quirks;
-       if (muxc->mux_locked) {
-               priv->adap.lock_bus = i2c_mux_lock_bus;
-               priv->adap.trylock_bus = i2c_mux_trylock_bus;
-               priv->adap.unlock_bus = i2c_mux_unlock_bus;
-       } else {
-               priv->adap.lock_bus = i2c_parent_lock_bus;
-               priv->adap.trylock_bus = i2c_parent_trylock_bus;
-               priv->adap.unlock_bus = i2c_parent_unlock_bus;
-       }
+       if (muxc->mux_locked)
+               priv->adap.lock_ops = &i2c_mux_lock_ops;
+       else
+               priv->adap.lock_ops = &i2c_parent_lock_ops;
 
        /* Sanity check on class */
        if (i2c_mux_parent_classes(parent) & class)
@@ -335,18 +346,42 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
         * nothing if !CONFIG_OF.
         */
        if (muxc->dev->of_node) {
-               struct device_node *child;
+               struct device_node *dev_node = muxc->dev->of_node;
+               struct device_node *mux_node, *child = NULL;
                u32 reg;
 
-               for_each_child_of_node(muxc->dev->of_node, child) {
-                       ret = of_property_read_u32(child, "reg", &reg);
-                       if (ret)
-                               continue;
-                       if (chan_id == reg) {
-                               priv->adap.dev.of_node = child;
-                               break;
+               if (muxc->arbitrator)
+                       mux_node = of_get_child_by_name(dev_node, "i2c-arb");
+               else if (muxc->gate)
+                       mux_node = of_get_child_by_name(dev_node, "i2c-gate");
+               else
+                       mux_node = of_get_child_by_name(dev_node, "i2c-mux");
+
+               if (mux_node) {
+                       /* A "reg" property indicates an old-style DT entry */
+                       if (!of_property_read_u32(mux_node, "reg", &reg)) {
+                               of_node_put(mux_node);
+                               mux_node = NULL;
+                       }
+               }
+
+               if (!mux_node)
+                       mux_node = of_node_get(dev_node);
+               else if (muxc->arbitrator || muxc->gate)
+                       child = of_node_get(mux_node);
+
+               if (!child) {
+                       for_each_child_of_node(mux_node, child) {
+                               ret = of_property_read_u32(child, "reg", &reg);
+                               if (ret)
+                                       continue;
+                               if (chan_id == reg)
+                                       break;
                        }
                }
+
+               priv->adap.dev.of_node = child;
+               of_node_put(mux_node);
        }
 
        /*
index a90bbc4037dde3295a288c3a7d2b87197b92ba7e..86fc2d4c081b2eb4f265d7d69cd485d9ca9ec120 100644 (file)
@@ -130,7 +130,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), 0,
+       muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), I2C_MUX_ARBITRATOR,
                             i2c_arbitrator_select, i2c_arbitrator_deselect);
        if (!muxc)
                return -ENOMEM;
index 3cb8af635db5f8a2a812e12a9afc9be8655b1104..4ea7e691afc75bb9d6aa7166cd02c9cde7cad9a7 100644 (file)
@@ -85,6 +85,13 @@ static const struct i2c_device_id pca9541_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, pca9541_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id pca9541_of_match[] = {
+       { .compatible = "nxp,pca9541" },
+       {}
+};
+#endif
+
 /*
  * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
  * as they will try to lock the adapter a second time.
@@ -349,7 +356,8 @@ static int pca9541_probe(struct i2c_client *client,
        force = 0;
        if (pdata)
                force = pdata->modes[0].adap_id;
-       muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0,
+       muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
+                            I2C_MUX_ARBITRATOR,
                             pca9541_select_chan, pca9541_release_chan);
        if (!muxc)
                return -ENOMEM;
@@ -382,6 +390,7 @@ static int pca9541_remove(struct i2c_client *client)
 static struct i2c_driver pca9541_driver = {
        .driver = {
                   .name = "pca9541",
+                  .of_match_table = of_match_ptr(pca9541_of_match),
                   },
        .probe = pca9541_probe,
        .remove = pca9541_remove,
index 3278ebf1cc5ccda15321f46bd658a03f51273557..1091346f2480a6e4c4a79dd1836964894b9c8169 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/i2c/pca954x.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 
@@ -58,14 +59,6 @@ enum pca_type {
        pca_9548,
 };
 
-struct pca954x {
-       enum pca_type type;
-
-       u8 last_chan;           /* last register value */
-       u8 deselect;
-       struct i2c_client *client;
-};
-
 struct chip_desc {
        u8 nchans;
        u8 enable;      /* used for muxes only */
@@ -75,6 +68,14 @@ struct chip_desc {
        } muxtype;
 };
 
+struct pca954x {
+       const struct chip_desc *chip;
+
+       u8 last_chan;           /* last register value */
+       u8 deselect;
+       struct i2c_client *client;
+};
+
 /* Provide specs for the PCA954x types we know about */
 static const struct chip_desc chips[] = {
        [pca_9540] = {
@@ -119,6 +120,20 @@ static const struct i2c_device_id pca954x_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, pca954x_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id pca954x_of_match[] = {
+       { .compatible = "nxp,pca9540", .data = &chips[pca_9540] },
+       { .compatible = "nxp,pca9542", .data = &chips[pca_9542] },
+       { .compatible = "nxp,pca9543", .data = &chips[pca_9543] },
+       { .compatible = "nxp,pca9544", .data = &chips[pca_9544] },
+       { .compatible = "nxp,pca9545", .data = &chips[pca_9545] },
+       { .compatible = "nxp,pca9546", .data = &chips[pca_9546] },
+       { .compatible = "nxp,pca9547", .data = &chips[pca_9547] },
+       { .compatible = "nxp,pca9548", .data = &chips[pca_9548] },
+       {}
+};
+#endif
+
 /* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
    for this as they will try to lock adapter a second time */
 static int pca954x_reg_write(struct i2c_adapter *adap,
@@ -151,7 +166,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
        struct pca954x *data = i2c_mux_priv(muxc);
        struct i2c_client *client = data->client;
-       const struct chip_desc *chip = &chips[data->type];
+       const struct chip_desc *chip = data->chip;
        u8 regval;
        int ret = 0;
 
@@ -197,6 +212,7 @@ static int pca954x_probe(struct i2c_client *client,
        int num, force, class;
        struct i2c_mux_core *muxc;
        struct pca954x *data;
+       const struct of_device_id *match;
        int ret;
 
        if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
@@ -226,14 +242,19 @@ static int pca954x_probe(struct i2c_client *client,
                return -ENODEV;
        }
 
-       data->type = id->driver_data;
+       match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
+       if (match)
+               data->chip = of_device_get_match_data(&client->dev);
+       else
+               data->chip = &chips[id->driver_data];
+
        data->last_chan = 0;               /* force the first selection */
 
        idle_disconnect_dt = of_node &&
                of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
 
        /* Now create an adapter for each channel */
-       for (num = 0; num < chips[data->type].nchans; num++) {
+       for (num = 0; num < data->chip->nchans; num++) {
                bool idle_disconnect_pd = false;
 
                force = 0;                        /* dynamic adap number */
@@ -263,7 +284,7 @@ static int pca954x_probe(struct i2c_client *client,
 
        dev_info(&client->dev,
                 "registered %d multiplexed busses for I2C %s %s\n",
-                num, chips[data->type].muxtype == pca954x_ismux
+                num, data->chip->muxtype == pca954x_ismux
                                ? "mux" : "switch", client->name);
 
        return 0;
@@ -299,6 +320,7 @@ static struct i2c_driver pca954x_driver = {
        .driver         = {
                .name   = "pca954x",
                .pm     = &pca954x_pm,
+               .of_match_table = of_match_ptr(pca954x_of_match),
        },
        .probe          = pca954x_probe,
        .remove         = pca954x_remove,
index 3cdf8e1ca0add01db5295259af3b34f9ba4508b5..051b14766ef964984da6ff487db81f5a782cb3ba 100644 (file)
@@ -593,6 +593,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
        struct at24_data *at24;
        int err;
        unsigned i, num_addresses;
+       u8 test_byte;
 
        if (client->dev.platform_data) {
                chip = *(struct at24_platform_data *)client->dev.platform_data;
@@ -743,6 +744,18 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
                }
        }
 
+       i2c_set_clientdata(client, at24);
+
+       /*
+        * Perform a one-byte test read to verify that the
+        * chip is functional.
+        */
+       err = at24_read(at24, 0, &test_byte, 1);
+       if (err) {
+               err = -ENODEV;
+               goto err_clients;
+       }
+
        at24->nvmem_config.name = dev_name(&client->dev);
        at24->nvmem_config.dev = &client->dev;
        at24->nvmem_config.read_only = !writable;
@@ -764,8 +777,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
                goto err_clients;
        }
 
-       i2c_set_clientdata(client, at24);
-
        dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n",
                chip.byte_len, client->name,
                writable ? "writable" : "read-only", at24->write_max);
index d4c1d12f900d9aff084f360d76247d5b149b6dff..bd74d5706f3b4b7513e21ab26faf6ac7f1918361 100644 (file)
@@ -32,7 +32,9 @@
 struct i2c_mux_core {
        struct i2c_adapter *parent;
        struct device *dev;
-       bool mux_locked;
+       unsigned int mux_locked:1;
+       unsigned int arbitrator:1;
+       unsigned int gate:1;
 
        void *priv;
 
@@ -51,7 +53,9 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
                                   int (*deselect)(struct i2c_mux_core *, u32));
 
 /* flags for i2c_mux_alloc */
-#define I2C_MUX_LOCKED BIT(0)
+#define I2C_MUX_LOCKED     BIT(0)
+#define I2C_MUX_ARBITRATOR BIT(1)
+#define I2C_MUX_GATE       BIT(2)
 
 static inline void *i2c_mux_priv(struct i2c_mux_core *muxc)
 {
index fffdc270ca18518f4e3c05b5efd2749f52b28f50..6422eef428c4e2a97c244fa274405cac7c425c82 100644 (file)
@@ -426,6 +426,20 @@ struct i2c_algorithm {
 #endif
 };
 
+/**
+ * struct i2c_lock_operations - represent I2C locking operations
+ * @lock_bus: Get exclusive access to an I2C bus segment
+ * @trylock_bus: Try to get exclusive access to an I2C bus segment
+ * @unlock_bus: Release exclusive access to an I2C bus segment
+ *
+ * The main operations are wrapped by i2c_lock_bus and i2c_unlock_bus.
+ */
+struct i2c_lock_operations {
+       void (*lock_bus)(struct i2c_adapter *, unsigned int flags);
+       int (*trylock_bus)(struct i2c_adapter *, unsigned int flags);
+       void (*unlock_bus)(struct i2c_adapter *, unsigned int flags);
+};
+
 /**
  * struct i2c_timings - I2C timing information
  * @bus_freq_hz: the bus frequency in Hz
@@ -536,6 +550,7 @@ struct i2c_adapter {
        void *algo_data;
 
        /* data fields that are valid for all devices   */
+       const struct i2c_lock_operations *lock_ops;
        struct rt_mutex bus_lock;
        struct rt_mutex mux_lock;
 
@@ -552,10 +567,6 @@ struct i2c_adapter {
 
        struct i2c_bus_recovery_info *bus_recovery_info;
        const struct i2c_adapter_quirks *quirks;
-
-       void (*lock_bus)(struct i2c_adapter *, unsigned int flags);
-       int (*trylock_bus)(struct i2c_adapter *, unsigned int flags);
-       void (*unlock_bus)(struct i2c_adapter *, unsigned int flags);
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
@@ -597,7 +608,21 @@ int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *));
 static inline void
 i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags)
 {
-       adapter->lock_bus(adapter, flags);
+       adapter->lock_ops->lock_bus(adapter, flags);
+}
+
+/**
+ * i2c_trylock_bus - Try to get exclusive access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ * @flags: I2C_LOCK_ROOT_ADAPTER tries to locks the root i2c adapter,
+ *     I2C_LOCK_SEGMENT tries to lock only this branch in the adapter tree
+ *
+ * Return: true if the I2C bus segment is locked, false otherwise
+ */
+static inline int
+i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags)
+{
+       return adapter->lock_ops->trylock_bus(adapter, flags);
 }
 
 /**
@@ -609,7 +634,7 @@ i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags)
 static inline void
 i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
 {
-       adapter->unlock_bus(adapter, flags);
+       adapter->lock_ops->unlock_bus(adapter, flags);
 }
 
 static inline void
@@ -673,6 +698,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap,
 
 extern struct i2c_adapter *i2c_get_adapter(int nr);
 extern void i2c_put_adapter(struct i2c_adapter *adap);
+extern unsigned int i2c_adapter_depth(struct i2c_adapter *adapter);
 
 void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults);
 
@@ -766,4 +792,13 @@ static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node
 }
 #endif /* CONFIG_OF */
 
+#if IS_ENABLED(CONFIG_ACPI)
+u32 i2c_acpi_find_bus_speed(struct device *dev);
+#else
+static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
+{
+       return 0;
+}
+#endif /* CONFIG_ACPI */
+
 #endif /* _LINUX_I2C_H */
index eabe0138eb063c22bb5618a10f23d6950ff9711f..c1458fede1f96490768b6d93647a96367c530b85 100644 (file)
@@ -16,6 +16,8 @@ struct lockdep_map;
 extern int prove_locking;
 extern int lock_stat;
 
+#define MAX_LOCKDEP_SUBCLASSES         8UL
+
 #ifdef CONFIG_LOCKDEP
 
 #include <linux/linkage.h>
@@ -29,8 +31,6 @@ extern int lock_stat;
  */
 #define XXX_LOCK_USAGE_STATES          (1+3*4)
 
-#define MAX_LOCKDEP_SUBCLASSES         8UL
-
 /*
  * NR_LOCKDEP_CACHING_CLASSES ... Number of classes
  * cached in the instance of lockdep_map