Commit 89555eeb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'i2c-for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "Mostly fixes for DTs or DT handling this time. And a few driver
  bugfixes"

* tag 'i2c-for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (28 commits)
  i2c: xiic: xiic_xfer(): Fix runtime PM leak on error path
  i2c: cadence: cdns_i2c_master_xfer(): Fix runtime PM leak on error path
  i2c: omap: Improve error reporting for problems during .remove()
  i2c: cadence: Add reset controller support
  dt-bindings: i2c: cadence: Document `resets` property
  i2c: mediatek: add support for MT7981 SoC
  dt-bindings: i2c: i2c-mt65xx: add MediaTek MT7981 SoC
  dt-bindings: i2c: Drop unneeded quotes
  i2c: brcmstb: use devm_platform_ioremap_resource_byname()
  i2c: cadence: Detect maximum transfer size
  i2c: cadence: Allow to specify the FIFO depth
  dt-bindings: i2c: cadence: Document `fifo-depth` property
  i2c: xiic: Use devm_platform_get_and_ioremap_resource()
  i2c: mpc: Use i2c-scl-clk-low-timeout-us i2c property
  i2c: mpc: Use of_property_read_u32 instead of of_get_property
  dt-bindings: i2c: mpc: Mark "fsl,timeout" as deprecated
  i2c: xiic: hide OF related data for COMPILE_TEST
  i2c: synquacer: mark OF related data as maybe unused
  dt-bindings: i2c: i2c-mt65xx: Add compatible for MT6795 Helio X10
  i2c: imx: Simplify using devm_clk_get_enabled()
  ...
parents d91f6a73 38c87827
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# Copyright 2019 BayLibre, SAS # Copyright 2019 BayLibre, SAS
%YAML 1.2 %YAML 1.2
--- ---
$id: "http://devicetree.org/schemas/i2c/amlogic,meson6-i2c.yaml#" $id: http://devicetree.org/schemas/i2c/amlogic,meson6-i2c.yaml#
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic Meson I2C Controller title: Amlogic Meson I2C Controller
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2 %YAML 1.2
--- ---
$id: "http://devicetree.org/schemas/i2c/apple,i2c.yaml#" $id: http://devicetree.org/schemas/i2c/apple,i2c.yaml#
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple/PASemi I2C controller title: Apple/PASemi I2C controller
......
...@@ -75,7 +75,7 @@ required: ...@@ -75,7 +75,7 @@ required:
- clocks - clocks
allOf: allOf:
- $ref: "i2c-controller.yaml" - $ref: i2c-controller.yaml
- if: - if:
properties: properties:
compatible: compatible:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2 %YAML 1.2
--- ---
$id: "http://devicetree.org/schemas/i2c/cdns,i2c-r1p10.yaml#" $id: http://devicetree.org/schemas/i2c/cdns,i2c-r1p10.yaml#
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cadence I2C controller title: Cadence I2C controller
...@@ -24,6 +24,9 @@ properties: ...@@ -24,6 +24,9 @@ properties:
clocks: clocks:
minItems: 1 minItems: 1
resets:
maxItems: 1
interrupts: interrupts:
maxItems: 1 maxItems: 1
...@@ -38,6 +41,13 @@ properties: ...@@ -38,6 +41,13 @@ properties:
description: | description: |
Input clock name. Input clock name.
fifo-depth:
description:
Size of the data FIFO in bytes.
$ref: /schemas/types.yaml#/definitions/uint32
default: 16
enum: [2, 4, 8, 16, 32, 64, 128, 256]
required: required:
- compatible - compatible
- reg - reg
...@@ -52,9 +62,11 @@ examples: ...@@ -52,9 +62,11 @@ examples:
i2c@e0004000 { i2c@e0004000 {
compatible = "cdns,i2c-r1p10"; compatible = "cdns,i2c-r1p10";
clocks = <&clkc 38>; clocks = <&clkc 38>;
resets = <&rstc 288>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xe0004000 0x1000>; reg = <0xe0004000 0x1000>;
clock-frequency = <400000>; clock-frequency = <400000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
fifo-depth = <8>;
}; };
...@@ -43,6 +43,7 @@ properties: ...@@ -43,6 +43,7 @@ properties:
fsl,timeout: fsl,timeout:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
deprecated: true
description: | description: |
I2C bus timeout in microseconds I2C bus timeout in microseconds
...@@ -95,6 +96,6 @@ examples: ...@@ -95,6 +96,6 @@ examples:
interrupts = <43 2>; interrupts = <43 2>;
interrupt-parent = <&mpic>; interrupt-parent = <&mpic>;
clock-frequency = <400000>; clock-frequency = <400000>;
fsl,timeout = <10000>; i2c-scl-clk-low-timeout-us = <10000>;
}; };
... ...
...@@ -23,6 +23,7 @@ properties: ...@@ -23,6 +23,7 @@ properties:
- const: mediatek,mt6577-i2c - const: mediatek,mt6577-i2c
- const: mediatek,mt6589-i2c - const: mediatek,mt6589-i2c
- const: mediatek,mt7622-i2c - const: mediatek,mt7622-i2c
- const: mediatek,mt7981-i2c
- const: mediatek,mt7986-i2c - const: mediatek,mt7986-i2c
- const: mediatek,mt8168-i2c - const: mediatek,mt8168-i2c
- const: mediatek,mt8173-i2c - const: mediatek,mt8173-i2c
...@@ -45,6 +46,10 @@ properties: ...@@ -45,6 +46,10 @@ properties:
- enum: - enum:
- mediatek,mt8365-i2c - mediatek,mt8365-i2c
- const: mediatek,mt8168-i2c - const: mediatek,mt8168-i2c
- items:
- enum:
- mediatek,mt6795-i2c
- const: mediatek,mt8173-i2c
- items: - items:
- enum: - enum:
- mediatek,mt8195-i2c - mediatek,mt8195-i2c
......
...@@ -45,7 +45,7 @@ properties: ...@@ -45,7 +45,7 @@ properties:
i2c-parent: i2c-parent:
description: phandle of the I2C bus that this multiplexer's master-side port is connected to description: phandle of the I2C bus that this multiplexer's master-side port is connected to
$ref: "/schemas/types.yaml#/definitions/phandle" $ref: /schemas/types.yaml#/definitions/phandle
mux-gpios: mux-gpios:
description: list of GPIOs used to control the muxer description: list of GPIOs used to control the muxer
...@@ -55,7 +55,7 @@ properties: ...@@ -55,7 +55,7 @@ properties:
idle-state: idle-state:
description: Value to set the muxer to when idle. When no value is given, it defaults to the description: Value to set the muxer to when idle. When no value is given, it defaults to the
last value used. last value used.
$ref: "/schemas/types.yaml#/definitions/uint32" $ref: /schemas/types.yaml#/definitions/uint32
allOf: allOf:
- $ref: i2c-mux.yaml - $ref: i2c-mux.yaml
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2 %YAML 1.2
--- ---
$id: "http://devicetree.org/schemas/i2c/qcom,i2c-geni-qcom.yaml#" $id: http://devicetree.org/schemas/i2c/qcom,i2c-geni-qcom.yaml#
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Geni based QUP I2C Controller title: Qualcomm Geni based QUP I2C Controller
......
...@@ -90,7 +90,7 @@ properties: ...@@ -90,7 +90,7 @@ properties:
st,syscfg-fmp: st,syscfg-fmp:
description: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode description: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode
Plus speed is selected by slave. Plus speed is selected by slave.
$ref: "/schemas/types.yaml#/definitions/phandle-array" $ref: /schemas/types.yaml#/definitions/phandle-array
items: items:
- items: - items:
- description: phandle to syscfg - description: phandle to syscfg
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2 %YAML 1.2
--- ---
$id: "http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#" $id: http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx IIC controller title: Xilinx IIC controller
......
...@@ -807,7 +807,7 @@ config I2C_MESON ...@@ -807,7 +807,7 @@ config I2C_MESON
config I2C_MICROCHIP_CORE config I2C_MICROCHIP_CORE
tristate "Microchip FPGA I2C controller" tristate "Microchip FPGA I2C controller"
depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
depends on OF depends on OF
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
......
...@@ -575,12 +575,10 @@ static void brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev *dev) ...@@ -575,12 +575,10 @@ static void brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev *dev)
static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev) static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev)
{ {
struct platform_device *pdev = to_platform_device(dev->device); struct platform_device *pdev = to_platform_device(dev->device);
struct resource *iomem;
void __iomem *autoi2c; void __iomem *autoi2c;
/* Map hardware registers */ /* Map hardware registers */
iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c"); autoi2c = devm_platform_ioremap_resource_byname(pdev, "auto-i2c");
autoi2c = devm_ioremap_resource(&pdev->dev, iomem);
if (IS_ERR(autoi2c)) if (IS_ERR(autoi2c))
return PTR_ERR(autoi2c); return PTR_ERR(autoi2c);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/reset.h>
/* Register offsets for the I2C device. */ /* Register offsets for the I2C device. */
#define CDNS_I2C_CR_OFFSET 0x00 /* Control Register, RW */ #define CDNS_I2C_CR_OFFSET 0x00 /* Control Register, RW */
...@@ -114,10 +115,10 @@ ...@@ -114,10 +115,10 @@
/* timeout for pm runtime autosuspend */ /* timeout for pm runtime autosuspend */
#define CNDS_I2C_PM_TIMEOUT 1000 /* ms */ #define CNDS_I2C_PM_TIMEOUT 1000 /* ms */
#define CDNS_I2C_FIFO_DEPTH 16 #define CDNS_I2C_FIFO_DEPTH_DEFAULT 16
#define CDNS_I2C_MAX_TRANSFER_SIZE 255 #define CDNS_I2C_MAX_TRANSFER_SIZE 255
/* Transfer size in multiples of data interrupt depth */ /* Transfer size in multiples of data interrupt depth */
#define CDNS_I2C_TRANSFER_SIZE (CDNS_I2C_MAX_TRANSFER_SIZE - 3) #define CDNS_I2C_TRANSFER_SIZE(max) ((max) - 3)
#define DRIVER_NAME "cdns-i2c" #define DRIVER_NAME "cdns-i2c"
...@@ -178,12 +179,15 @@ enum cdns_i2c_slave_state { ...@@ -178,12 +179,15 @@ enum cdns_i2c_slave_state {
* @bus_hold_flag: Flag used in repeated start for clearing HOLD bit * @bus_hold_flag: Flag used in repeated start for clearing HOLD bit
* @clk: Pointer to struct clk * @clk: Pointer to struct clk
* @clk_rate_change_nb: Notifier block for clock rate changes * @clk_rate_change_nb: Notifier block for clock rate changes
* @reset: Reset control for the device
* @quirks: flag for broken hold bit usage in r1p10 * @quirks: flag for broken hold bit usage in r1p10
* @ctrl_reg: Cached value of the control register. * @ctrl_reg: Cached value of the control register.
* @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register
* @slave: Registered slave instance. * @slave: Registered slave instance.
* @dev_mode: I2C operating role(master/slave). * @dev_mode: I2C operating role(master/slave).
* @slave_state: I2C Slave state(idle/read/write). * @slave_state: I2C Slave state(idle/read/write).
* @fifo_depth: The depth of the transfer FIFO
* @transfer_size: The maximum number of bytes in one transfer
*/ */
struct cdns_i2c { struct cdns_i2c {
struct device *dev; struct device *dev;
...@@ -202,6 +206,7 @@ struct cdns_i2c { ...@@ -202,6 +206,7 @@ struct cdns_i2c {
unsigned int bus_hold_flag; unsigned int bus_hold_flag;
struct clk *clk; struct clk *clk;
struct notifier_block clk_rate_change_nb; struct notifier_block clk_rate_change_nb;
struct reset_control *reset;
u32 quirks; u32 quirks;
u32 ctrl_reg; u32 ctrl_reg;
struct i2c_bus_recovery_info rinfo; struct i2c_bus_recovery_info rinfo;
...@@ -211,6 +216,8 @@ struct cdns_i2c { ...@@ -211,6 +216,8 @@ struct cdns_i2c {
enum cdns_i2c_mode dev_mode; enum cdns_i2c_mode dev_mode;
enum cdns_i2c_slave_state slave_state; enum cdns_i2c_slave_state slave_state;
#endif #endif
u32 fifo_depth;
unsigned int transfer_size;
}; };
struct cdns_platform_data { struct cdns_platform_data {
...@@ -236,7 +243,7 @@ static void cdns_i2c_clear_bus_hold(struct cdns_i2c *id) ...@@ -236,7 +243,7 @@ static void cdns_i2c_clear_bus_hold(struct cdns_i2c *id)
static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround) static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround)
{ {
return (hold_wrkaround && return (hold_wrkaround &&
(id->curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1)); (id->curr_recv_count == id->fifo_depth + 1));
} }
#if IS_ENABLED(CONFIG_I2C_SLAVE) #if IS_ENABLED(CONFIG_I2C_SLAVE)
...@@ -431,7 +438,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr) ...@@ -431,7 +438,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
* if RX data left is less than or equal to * if RX data left is less than or equal to
* FIFO DEPTH unless repeated start is selected * FIFO DEPTH unless repeated start is selected
*/ */
if (id->recv_count <= CDNS_I2C_FIFO_DEPTH && if (id->recv_count <= id->fifo_depth &&
!id->bus_hold_flag) !id->bus_hold_flag)
cdns_i2c_clear_bus_hold(id); cdns_i2c_clear_bus_hold(id);
...@@ -456,22 +463,22 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr) ...@@ -456,22 +463,22 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
if (cdns_is_holdquirk(id, updatetx)) { if (cdns_is_holdquirk(id, updatetx)) {
/* wait while fifo is full */ /* wait while fifo is full */
while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) != while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) !=
(id->curr_recv_count - CDNS_I2C_FIFO_DEPTH)) (id->curr_recv_count - id->fifo_depth))
; ;
/* /*
* Check number of bytes to be received against maximum * Check number of bytes to be received against maximum
* transfer size and update register accordingly. * transfer size and update register accordingly.
*/ */
if (((int)(id->recv_count) - CDNS_I2C_FIFO_DEPTH) > if (((int)(id->recv_count) - id->fifo_depth) >
CDNS_I2C_TRANSFER_SIZE) { id->transfer_size) {
cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, cdns_i2c_writereg(id->transfer_size,
CDNS_I2C_XFER_SIZE_OFFSET); CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE + id->curr_recv_count = id->transfer_size +
CDNS_I2C_FIFO_DEPTH; id->fifo_depth;
} else { } else {
cdns_i2c_writereg(id->recv_count - cdns_i2c_writereg(id->recv_count -
CDNS_I2C_FIFO_DEPTH, id->fifo_depth,
CDNS_I2C_XFER_SIZE_OFFSET); CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = id->recv_count; id->curr_recv_count = id->recv_count;
} }
...@@ -494,7 +501,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr) ...@@ -494,7 +501,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
* space available in FIFO and fill with that many bytes. * space available in FIFO and fill with that many bytes.
*/ */
if (id->send_count) { if (id->send_count) {
avail_bytes = CDNS_I2C_FIFO_DEPTH - avail_bytes = id->fifo_depth -
cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);
if (id->send_count > avail_bytes) if (id->send_count > avail_bytes)
bytes_to_send = avail_bytes; bytes_to_send = avail_bytes;
...@@ -588,7 +595,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ...@@ -588,7 +595,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the * Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth. * 'hold bus' bit if it is greater than FIFO depth.
*/ */
if (id->recv_count > CDNS_I2C_FIFO_DEPTH) if (id->recv_count > id->fifo_depth)
ctrl_reg |= CDNS_I2C_CR_HOLD; ctrl_reg |= CDNS_I2C_CR_HOLD;
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
...@@ -603,17 +610,17 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ...@@ -603,17 +610,17 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
* receive if it is less than transfer size and transfer size if * receive if it is less than transfer size and transfer size if
* it is more. Enable the interrupts. * it is more. Enable the interrupts.
*/ */
if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { if (id->recv_count > id->transfer_size) {
cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, cdns_i2c_writereg(id->transfer_size,
CDNS_I2C_XFER_SIZE_OFFSET); CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; id->curr_recv_count = id->transfer_size;
} else { } else {
cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);
} }
/* Determine hold_clear based on number of bytes to receive and hold flag */ /* Determine hold_clear based on number of bytes to receive and hold flag */
if (!id->bus_hold_flag && id->recv_count <= CDNS_I2C_FIFO_DEPTH) { if (!id->bus_hold_flag && id->recv_count <= id->fifo_depth) {
if (cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & CDNS_I2C_CR_HOLD) { if (ctrl_reg & CDNS_I2C_CR_HOLD) {
hold_clear = true; hold_clear = true;
if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT)
irq_save = true; irq_save = true;
...@@ -624,7 +631,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ...@@ -624,7 +631,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
addr &= CDNS_I2C_ADDR_MASK; addr &= CDNS_I2C_ADDR_MASK;
if (hold_clear) { if (hold_clear) {
ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & ~CDNS_I2C_CR_HOLD; ctrl_reg &= ~CDNS_I2C_CR_HOLD;
/* /*
* In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
* register reaches '0'. This is an IP bug which causes transfer size * register reaches '0'. This is an IP bug which causes transfer size
...@@ -673,7 +680,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id) ...@@ -673,7 +680,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the * Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth. * 'hold bus' bit if it is greater than FIFO depth.
*/ */
if (id->send_count > CDNS_I2C_FIFO_DEPTH) if (id->send_count > id->fifo_depth)
ctrl_reg |= CDNS_I2C_CR_HOLD; ctrl_reg |= CDNS_I2C_CR_HOLD;
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
...@@ -686,7 +693,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id) ...@@ -686,7 +693,7 @@ static void cdns_i2c_msend(struct cdns_i2c *id)
* against the space available, and fill the FIFO accordingly. * against the space available, and fill the FIFO accordingly.
* Enable the interrupts. * Enable the interrupts.
*/ */
avail_bytes = CDNS_I2C_FIFO_DEPTH - avail_bytes = id->fifo_depth -
cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);
if (id->send_count > avail_bytes) if (id->send_count > avail_bytes)
...@@ -827,8 +834,10 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -827,8 +834,10 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
#if IS_ENABLED(CONFIG_I2C_SLAVE) #if IS_ENABLED(CONFIG_I2C_SLAVE)
/* Check i2c operating mode and switch if possible */ /* Check i2c operating mode and switch if possible */
if (id->dev_mode == CDNS_I2C_MODE_SLAVE) { if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) {
return -EAGAIN; ret = -EAGAIN;
goto out;
}
/* Set mode to master */ /* Set mode to master */
cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id); cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
...@@ -1030,8 +1039,7 @@ static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk, ...@@ -1030,8 +1039,7 @@ static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk,
if (actual_fscl > fscl) if (actual_fscl > fscl)
continue; continue;
current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) : current_error = fscl - actual_fscl;
(fscl - actual_fscl));
if (last_error > current_error) { if (last_error > current_error) {
calc_div_a = div_a; calc_div_a = div_a;
...@@ -1226,6 +1234,37 @@ static const struct of_device_id cdns_i2c_of_match[] = { ...@@ -1226,6 +1234,37 @@ static const struct of_device_id cdns_i2c_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, cdns_i2c_of_match); MODULE_DEVICE_TABLE(of, cdns_i2c_of_match);
/**
* cdns_i2c_detect_transfer_size - Detect the maximum transfer size supported
* @id: Device private data structure
*
* Detect the maximum transfer size that is supported by this instance of the
* Cadence I2C controller.
*/
static void cdns_i2c_detect_transfer_size(struct cdns_i2c *id)
{
u32 val;
/*
* Writing to the transfer size register is only possible if these two bits
* are set in the control register.
*/
cdns_i2c_writereg(CDNS_I2C_CR_MS | CDNS_I2C_CR_RW, CDNS_I2C_CR_OFFSET);
/*
* The number of writable bits of the transfer size register can be between
* 4 and 8. This is a controlled through a synthesis parameter of the IP
* core and can vary from instance to instance. The unused MSBs always read
* back as 0. Writing 0xff and then reading the value back will report the
* maximum supported transfer size.
*/
cdns_i2c_writereg(CDNS_I2C_MAX_TRANSFER_SIZE, CDNS_I2C_XFER_SIZE_OFFSET);
val = cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);
id->transfer_size = CDNS_I2C_TRANSFER_SIZE(val);
cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET);
cdns_i2c_writereg(0, CDNS_I2C_CR_OFFSET);
}
/** /**
* cdns_i2c_probe - Platform registration call * cdns_i2c_probe - Platform registration call
* @pdev: Handle to the platform device structure * @pdev: Handle to the platform device structure
...@@ -1291,10 +1330,22 @@ static int cdns_i2c_probe(struct platform_device *pdev) ...@@ -1291,10 +1330,22 @@ static int cdns_i2c_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(id->clk), return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),
"input clock not found.\n"); "input clock not found.\n");
id->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
if (IS_ERR(id->reset))
return dev_err_probe(&pdev->dev, PTR_ERR(id->reset),
"Failed to request reset.\n");
ret = clk_prepare_enable(id->clk); ret = clk_prepare_enable(id->clk);
if (ret) if (ret)
dev_err(&pdev->dev, "Unable to enable clock.\n"); dev_err(&pdev->dev, "Unable to enable clock.\n");
ret = reset_control_deassert(id->reset);
if (ret) {
dev_err_probe(&pdev->dev, ret,
"Failed to de-assert reset.\n");
goto err_clk_dis;
}
pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT); pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(id->dev); pm_runtime_use_autosuspend(id->dev);
pm_runtime_set_active(id->dev); pm_runtime_set_active(id->dev);
...@@ -1317,32 +1368,39 @@ static int cdns_i2c_probe(struct platform_device *pdev) ...@@ -1317,32 +1368,39 @@ static int cdns_i2c_probe(struct platform_device *pdev)
#endif #endif
id->ctrl_reg = CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS; id->ctrl_reg = CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS;
id->fifo_depth = CDNS_I2C_FIFO_DEPTH_DEFAULT;
of_property_read_u32(pdev->dev.of_node, "fifo-depth", &id->fifo_depth);
cdns_i2c_detect_transfer_size(id);
ret = cdns_i2c_setclk(id->input_clk, id); ret = cdns_i2c_setclk(id->input_clk, id);
if (ret) { if (ret) {
dev_err(&pdev->dev, "invalid SCL clock: %u Hz\n", id->i2c_clk); dev_err(&pdev->dev, "invalid SCL clock: %u Hz\n", id->i2c_clk);
ret = -EINVAL; ret = -EINVAL;
goto err_clk_dis; goto err_clk_notifier_unregister;
} }
ret = devm_request_irq(&pdev->dev, irq, cdns_i2c_isr, 0, ret = devm_request_irq(&pdev->dev, irq, cdns_i2c_isr, 0,
DRIVER_NAME, id); DRIVER_NAME, id);
if (ret) { if (ret) {
dev_err(&pdev->dev, "cannot get irq %d\n", irq); dev_err(&pdev->dev, "cannot get irq %d\n", irq);
goto err_clk_dis; goto err_clk_notifier_unregister;
} }
cdns_i2c_init(id); cdns_i2c_init(id);
ret = i2c_add_adapter(&id->adap); ret = i2c_add_adapter(&id->adap);
if (ret < 0) if (ret < 0)
goto err_clk_dis; goto err_clk_notifier_unregister;
dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n", dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n",
id->i2c_clk / 1000, (unsigned long)r_mem->start, irq); id->i2c_clk / 1000, (unsigned long)r_mem->start, irq);
return 0; return 0;
err_clk_dis: err_clk_notifier_unregister:
clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
reset_control_assert(id->reset);
err_clk_dis:
clk_disable_unprepare(id->clk); clk_disable_unprepare(id->clk);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
...@@ -1367,6 +1425,7 @@ static int cdns_i2c_remove(struct platform_device *pdev) ...@@ -1367,6 +1425,7 @@ static int cdns_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&id->adap); i2c_del_adapter(&id->adap);
clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
reset_control_assert(id->reset);
clk_disable_unprepare(id->clk); clk_disable_unprepare(id->clk);
return 0; return 0;
......
...@@ -292,13 +292,13 @@ static int ec_i2c_remove(struct platform_device *dev) ...@@ -292,13 +292,13 @@ static int ec_i2c_remove(struct platform_device *dev)
return 0; return 0;
} }
static const struct of_device_id cros_ec_i2c_of_match[] = { static const struct of_device_id cros_ec_i2c_of_match[] __maybe_unused = {
{ .compatible = "google,cros-ec-i2c-tunnel" }, { .compatible = "google,cros-ec-i2c-tunnel" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = { static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] __maybe_unused = {
{ "GOOG0012", 0 }, { "GOOG0012", 0 },
{ } { }
}; };
......
...@@ -764,11 +764,8 @@ static int davinci_i2c_probe(struct platform_device *pdev) ...@@ -764,11 +764,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
int r, irq; int r, irq;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq <= 0) { if (irq < 0)
if (!irq)
irq = -ENXIO;
return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n"); return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n");
}
dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev), dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev),
GFP_KERNEL); GFP_KERNEL);
......
...@@ -1482,17 +1482,11 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1482,17 +1482,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev)); ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));
/* Get I2C clock */ /* Get I2C clock */
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL); i2c_imx->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(i2c_imx->clk)) if (IS_ERR(i2c_imx->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(i2c_imx->clk), return dev_err_probe(&pdev->dev, PTR_ERR(i2c_imx->clk),
"can't get I2C clock\n"); "can't get I2C clock\n");
ret = clk_prepare_enable(i2c_imx->clk);
if (ret) {
dev_err(&pdev->dev, "can't enable I2C clock, ret=%d\n", ret);
return ret;
}
/* Init queue */ /* Init queue */
init_waitqueue_head(&i2c_imx->queue); init_waitqueue_head(&i2c_imx->queue);
...@@ -1564,7 +1558,6 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1564,7 +1558,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
clk_disable_unprepare(i2c_imx->clk);
return ret; return ret;
} }
...@@ -1590,7 +1583,6 @@ static int i2c_imx_remove(struct platform_device *pdev) ...@@ -1590,7 +1583,6 @@ static int i2c_imx_remove(struct platform_device *pdev)
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR); imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR); imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR); imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
clk_disable(i2c_imx->clk);
} }
clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb); clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb);
...@@ -1598,8 +1590,6 @@ static int i2c_imx_remove(struct platform_device *pdev) ...@@ -1598,8 +1590,6 @@ static int i2c_imx_remove(struct platform_device *pdev)
if (irq >= 0) if (irq >= 0)
free_irq(irq, i2c_imx); free_irq(irq, i2c_imx);
clk_unprepare(i2c_imx->clk);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
......
...@@ -770,7 +770,6 @@ static const struct i2c_algorithm mpc_algo = { ...@@ -770,7 +770,6 @@ static const struct i2c_algorithm mpc_algo = {
static struct i2c_adapter mpc_ops = { static struct i2c_adapter mpc_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.algo = &mpc_algo, .algo = &mpc_algo,
.timeout = HZ,
}; };
static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { static struct i2c_bus_recovery_info fsl_i2c_recovery_info = {
...@@ -781,11 +780,9 @@ static int fsl_i2c_probe(struct platform_device *op) ...@@ -781,11 +780,9 @@ static int fsl_i2c_probe(struct platform_device *op)
{ {
const struct mpc_i2c_data *data; const struct mpc_i2c_data *data;
struct mpc_i2c *i2c; struct mpc_i2c *i2c;
const u32 *prop;
u32 clock = MPC_I2C_CLOCK_LEGACY;
int result = 0;
int plen;
struct clk *clk; struct clk *clk;
int result;
u32 clock;
int err; int err;
i2c = devm_kzalloc(&op->dev, sizeof(*i2c), GFP_KERNEL); i2c = devm_kzalloc(&op->dev, sizeof(*i2c), GFP_KERNEL);
...@@ -831,10 +828,10 @@ static int fsl_i2c_probe(struct platform_device *op) ...@@ -831,10 +828,10 @@ static int fsl_i2c_probe(struct platform_device *op)
if (of_property_read_bool(op->dev.of_node, "fsl,preserve-clocking")) { if (of_property_read_bool(op->dev.of_node, "fsl,preserve-clocking")) {
clock = MPC_I2C_CLOCK_PRESERVE; clock = MPC_I2C_CLOCK_PRESERVE;
} else { } else {
prop = of_get_property(op->dev.of_node, "clock-frequency", result = of_property_read_u32(op->dev.of_node,
&plen); "clock-frequency", &clock);
if (prop && plen == sizeof(u32)) if (result)
clock = *prop; clock = MPC_I2C_CLOCK_LEGACY;
} }
data = device_get_match_data(&op->dev); data = device_get_match_data(&op->dev);
...@@ -842,16 +839,30 @@ static int fsl_i2c_probe(struct platform_device *op) ...@@ -842,16 +839,30 @@ static int fsl_i2c_probe(struct platform_device *op)
data->setup(op->dev.of_node, i2c, clock); data->setup(op->dev.of_node, i2c, clock);
} else { } else {
/* Backwards compatibility */ /* Backwards compatibility */
if (of_get_property(op->dev.of_node, "dfsrr", NULL)) if (of_property_read_bool(op->dev.of_node, "dfsrr"))
mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock); mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock);
} }
prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); /*
if (prop && plen == sizeof(u32)) { * "fsl,timeout" has been marked as deprecated and, to maintain
mpc_ops.timeout = *prop * HZ / 1000000; * backward compatibility, we will only look for it if
* "i2c-scl-clk-low-timeout-us" is not present.
*/
result = of_property_read_u32(op->dev.of_node,
"i2c-scl-clk-low-timeout-us",
&mpc_ops.timeout);
if (result == -EINVAL)
result = of_property_read_u32(op->dev.of_node,
"fsl,timeout", &mpc_ops.timeout);
if (!result) {
mpc_ops.timeout *= HZ / 1000000;
if (mpc_ops.timeout < 5) if (mpc_ops.timeout < 5)
mpc_ops.timeout = 5; mpc_ops.timeout = 5;
} else {
mpc_ops.timeout = HZ;
} }
dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447"))
......
...@@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible mt8168_compat = { ...@@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible mt8168_compat = {
.max_dma_support = 33, .max_dma_support = 33,
}; };
static const struct mtk_i2c_compatible mt7981_compat = {
.regs = mt_i2c_regs_v3,
.pmic_i2c = 0,
.dcm = 0,
.auto_restart = 1,
.aux_len_reg = 1,
.timing_adjust = 1,
.dma_sync = 1,
.ltiming_adjust = 1,
.max_dma_support = 33
};
static const struct mtk_i2c_compatible mt7986_compat = { static const struct mtk_i2c_compatible mt7986_compat = {
.quirks = &mt7622_i2c_quirks, .quirks = &mt7622_i2c_quirks,
.regs = mt_i2c_regs_v1, .regs = mt_i2c_regs_v1,
...@@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c_of_match[] = { ...@@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c_of_match[] = {
{ .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat }, { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
{ .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat }, { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat }, { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
{ .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
{ .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat }, { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
{ .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat }, { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat }, { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
...@@ -1546,7 +1559,7 @@ static struct platform_driver mtk_i2c_driver = { ...@@ -1546,7 +1559,7 @@ static struct platform_driver mtk_i2c_driver = {
.driver = { .driver = {
.name = I2C_DRV_NAME, .name = I2C_DRV_NAME,
.pm = &mtk_i2c_pm, .pm = &mtk_i2c_pm,
.of_match_table = of_match_ptr(mtk_i2c_of_match), .of_match_table = mtk_i2c_of_match,
}, },
}; };
......
...@@ -1525,14 +1525,17 @@ static int omap_i2c_remove(struct platform_device *pdev) ...@@ -1525,14 +1525,17 @@ static int omap_i2c_remove(struct platform_device *pdev)
int ret; int ret;
i2c_del_adapter(&omap->adapter); i2c_del_adapter(&omap->adapter);
ret = pm_runtime_resume_and_get(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) if (ret < 0)
return ret; dev_err(omap->dev, "Failed to resume hardware, skip disable\n");
else
omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0; return 0;
} }
......
...@@ -519,7 +519,7 @@ static struct platform_driver owl_i2c_driver = { ...@@ -519,7 +519,7 @@ static struct platform_driver owl_i2c_driver = {
.probe = owl_i2c_probe, .probe = owl_i2c_probe,
.driver = { .driver = {
.name = "owl-i2c", .name = "owl-i2c",
.of_match_table = of_match_ptr(owl_i2c_of_match), .of_match_table = owl_i2c_of_match,
.probe_type = PROBE_PREFER_ASYNCHRONOUS, .probe_type = PROBE_PREFER_ASYNCHRONOUS,
}, },
}; };
......
...@@ -1261,10 +1261,8 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, ...@@ -1261,10 +1261,8 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
/* For device tree we always use the dynamic or alias-assigned ID */ /* For device tree we always use the dynamic or alias-assigned ID */
i2c->adap.nr = -1; i2c->adap.nr = -1;
if (of_get_property(np, "mrvl,i2c-polling", NULL)) i2c->use_pio = of_property_read_bool(np, "mrvl,i2c-polling");
i2c->use_pio = 1; i2c->fast_mode = of_property_read_bool(np, "mrvl,i2c-fast-mode");
if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
i2c->fast_mode = 1;
*i2c_types = (enum pxa_i2c_types)(of_id->data); *i2c_types = (enum pxa_i2c_types)(of_id->data);
......
...@@ -629,7 +629,7 @@ static int synquacer_i2c_remove(struct platform_device *pdev) ...@@ -629,7 +629,7 @@ static int synquacer_i2c_remove(struct platform_device *pdev)
return 0; return 0;
}; };
static const struct of_device_id synquacer_i2c_dt_ids[] = { static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {
{ .compatible = "socionext,synquacer-i2c" }, { .compatible = "socionext,synquacer-i2c" },
{ /* sentinel */ } { /* sentinel */ }
}; };
......
...@@ -1164,7 +1164,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1164,7 +1164,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
err = xiic_start_xfer(i2c, msgs, num); err = xiic_start_xfer(i2c, msgs, num);
if (err < 0) { if (err < 0) {
dev_err(adap->dev.parent, "Error xiic_start_xfer\n"); dev_err(adap->dev.parent, "Error xiic_start_xfer\n");
return err; goto out;
} }
err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT); err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT);
...@@ -1178,6 +1178,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1178,6 +1178,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
err = (i2c->state == STATE_DONE) ? num : -EIO; err = (i2c->state == STATE_DONE) ? num : -EIO;
} }
mutex_unlock(&i2c->lock); mutex_unlock(&i2c->lock);
out:
pm_runtime_mark_last_busy(i2c->dev); pm_runtime_mark_last_busy(i2c->dev);
pm_runtime_put_autosuspend(i2c->dev); pm_runtime_put_autosuspend(i2c->dev);
return err; return err;
...@@ -1199,11 +1201,11 @@ static const struct i2c_adapter xiic_adapter = { ...@@ -1199,11 +1201,11 @@ static const struct i2c_adapter xiic_adapter = {
.algo = &xiic_algorithm, .algo = &xiic_algorithm,
}; };
#if defined(CONFIG_OF)
static const struct xiic_version_data xiic_2_00 = { static const struct xiic_version_data xiic_2_00 = {
.quirks = DYNAMIC_MODE_READ_BROKEN_BIT, .quirks = DYNAMIC_MODE_READ_BROKEN_BIT,
}; };
#if defined(CONFIG_OF)
static const struct of_device_id xiic_of_match[] = { static const struct of_device_id xiic_of_match[] = {
{ .compatible = "xlnx,xps-iic-2.00.a", .data = &xiic_2_00 }, { .compatible = "xlnx,xps-iic-2.00.a", .data = &xiic_2_00 },
{ .compatible = "xlnx,axi-iic-2.1", }, { .compatible = "xlnx,axi-iic-2.1", },
...@@ -1233,8 +1235,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) ...@@ -1233,8 +1235,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
i2c->quirks = data->quirks; i2c->quirks = data->quirks;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
i2c->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c->base)) if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base); return PTR_ERR(i2c->base);
......
...@@ -55,7 +55,7 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node, ...@@ -55,7 +55,7 @@ int of_i2c_get_board_info(struct device *dev, struct device_node *node,
if (of_property_read_bool(node, "host-notify")) if (of_property_read_bool(node, "host-notify"))
info->flags |= I2C_CLIENT_HOST_NOTIFY; info->flags |= I2C_CLIENT_HOST_NOTIFY;
if (of_get_property(node, "wakeup-source", NULL)) if (of_property_read_bool(node, "wakeup-source"))
info->flags |= I2C_CLIENT_WAKE; info->flags |= I2C_CLIENT_WAKE;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment