Commit 39de65aa authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "Here is the pull request from the i2c subsystem.  It got a little
  delayed because I needed to wait for a dependency to be included
  (commit b424080a: "reset: Add optional resets and stubs").  Plus,
  I had some email problems.  All done now, the highlights are:

   - drivers can now deprecate their use of i2c classes.  That shouldn't
     be used on embedded platforms anyhow and was often blindly
     copy&pasted.  This mechanism gives users time to switch away and
     ultimately boot faster once the use of classes for those drivers is
     gone for good.

   - new drivers for QUP, Cadence, efm32

   - tracepoint support for I2C and SMBus

   - bigger cleanups for the mv64xxx, nomadik, and designware drivers

  And the usual bugfixes, cleanups, feature additions.  Most stuff has
  been in linux-next for a while.  Just some hot fixes and new drivers
  were added a bit more recently."

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (63 commits)
  i2c: cadence: fix Kconfig dependency
  i2c: Add driver for Cadence I2C controller
  i2c: cadence: Document device tree bindings
  Documentation: i2c: improve section about flags mangling the protocol
  i2c: qup: use proper type fro clk_freq
  i2c: qup: off by ones in qup_i2c_probe()
  i2c: efm32: fix binding doc
  MAINTAINERS: update I2C web resources
  i2c: qup: New bus driver for the Qualcomm QUP I2C controller
  i2c: qup: Add device tree bindings information
  i2c: i2c-xiic: deprecate class based instantiation
  i2c: i2c-sirf: deprecate class based instantiation
  i2c: i2c-mv64xxx: deprecate class based instantiation
  i2c: i2c-designware-platdrv: deprecate class based instantiation
  i2c: i2c-davinci: deprecate class based instantiation
  i2c: i2c-bcm2835: deprecate class based instantiation
  i2c: mv64xxx: Fix reset controller handling
  i2c: omap: fix usage of IS_ERR_VALUE with pm_runtime_get_sync
  i2c: efm32: new bus driver
  i2c: exynos5: remove unnecessary cast of void pointer
  ...
parents 97e18dc0 1fbeab0b
...@@ -12,6 +12,7 @@ Required properties : ...@@ -12,6 +12,7 @@ Required properties :
- clocks: phandles to input clocks. - clocks: phandles to input clocks.
Optional properties: Optional properties:
- clock-frequency: Desired I2C bus frequency in Hz, otherwise defaults to 100000
- Child nodes conforming to i2c bus binding - Child nodes conforming to i2c bus binding
Examples : Examples :
...@@ -23,6 +24,7 @@ i2c0: i2c@fff84000 { ...@@ -23,6 +24,7 @@ i2c0: i2c@fff84000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&twi0_clk>; clocks = <&twi0_clk>;
clock-frequency = <400000>;
24c512@50 { 24c512@50 {
compatible = "24c512"; compatible = "24c512";
......
Binding for the Cadence I2C controller
Required properties:
- reg: Physical base address and size of the controller's register area.
- compatible: Compatibility string. Must be 'cdns,i2c-r1p10'.
- clocks: Input clock specifier. Refer to common clock bindings.
- interrupts: Interrupt specifier. Refer to interrupt bindings.
- #address-cells: Should be 1.
- #size-cells: Should be 0.
Optional properties:
- clock-frequency: Desired operating frequency, in Hz, of the bus.
- clock-names: Input clock name, should be 'pclk'.
Example:
i2c@e0004000 {
compatible = "cdns,i2c-r1p10";
clocks = <&clkc 38>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xe0004000 0x1000>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
};
...@@ -14,6 +14,12 @@ Optional properties : ...@@ -14,6 +14,12 @@ Optional properties :
- i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds. - i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
This option is only supported in hardware blocks version 1.11a or newer. This option is only supported in hardware blocks version 1.11a or newer.
- i2c-scl-falling-time : should contain the SCL falling time in nanoseconds.
This value which is by default 300ns is used to compute the tLOW period.
- i2c-sda-falling-time : should contain the SDA falling time in nanoseconds.
This value which is by default 300ns is used to compute the tHIGH period.
Example : Example :
i2c@f0000 { i2c@f0000 {
...@@ -34,4 +40,6 @@ Example : ...@@ -34,4 +40,6 @@ Example :
interrupts = <12 1>; interrupts = <12 1>;
clock-frequency = <400000>; clock-frequency = <400000>;
i2c-sda-hold-time-ns = <300>; i2c-sda-hold-time-ns = <300>;
i2c-sda-falling-time-ns = <300>;
i2c-scl-falling-time-ns = <300>;
}; };
* Energymicro efm32 i2c controller
Required properties :
- reg : Offset and length of the register set for the device
- compatible : should be "energymicro,efm32-i2c"
- interrupts : the interrupt number
- clocks : reference to the module clock
Recommended properties :
- clock-frequency : maximal I2C bus clock frequency in Hz.
- efm32,location : Decides the location of the USART I/O pins.
Allowed range : [0 .. 6]
Example:
i2c0: i2c@4000a000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "energymicro,efm32-i2c";
reg = <0x4000a000 0x400>;
interrupts = <9>;
clocks = <&cmu clk_HFPERCLKI2C0>;
clock-frequency = <100000>;
status = "ok";
efm32,location = <3>;
eeprom@50 {
compatible = "microchip,24c02";
reg = <0x50>;
pagesize = <16>;
};
};
...@@ -4,12 +4,16 @@ ...@@ -4,12 +4,16 @@
Required properties : Required properties :
- reg : Offset and length of the register set for the device - reg : Offset and length of the register set for the device
- compatible : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c" - compatible : Should be either:
or "marvell,mv78230-i2c" or "marvell,mv78230-a0-i2c" - "allwinner,sun4i-i2c"
Note: Only use "marvell,mv78230-a0-i2c" for a very rare, - "allwinner,sun6i-a31-i2c"
initial version of the SoC which had broken offload - "marvell,mv64xxx-i2c"
support. Linux auto-detects this and sets it - "marvell,mv78230-i2c"
appropriately. - "marvell,mv78230-a0-i2c"
* Note: Only use "marvell,mv78230-a0-i2c" for a
very rare, initial version of the SoC which
had broken offload support. Linux
auto-detects this and sets it appropriately.
- interrupts : The interrupt number - interrupts : The interrupt number
Optional properties : Optional properties :
...@@ -17,6 +21,10 @@ Optional properties : ...@@ -17,6 +21,10 @@ Optional properties :
- clock-frequency : Desired I2C bus clock frequency in Hz. If not set the - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
default frequency is 100kHz default frequency is 100kHz
- resets : phandle to the parent reset controller. Mandatory
whenever you're using the "allwinner,sun6i-a31-i2c"
compatible.
Examples: Examples:
i2c@11000 { i2c@11000 {
......
...@@ -6,6 +6,7 @@ Required properties: ...@@ -6,6 +6,7 @@ Required properties:
"renesas,i2c-r8a7778" "renesas,i2c-r8a7778"
"renesas,i2c-r8a7779" "renesas,i2c-r8a7779"
"renesas,i2c-r8a7790" "renesas,i2c-r8a7790"
"renesas,i2c-r8a7791"
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
- interrupts: interrupt specifier. - interrupts: interrupt specifier.
...@@ -13,11 +14,16 @@ Required properties: ...@@ -13,11 +14,16 @@ Required properties:
Optional properties: Optional properties:
- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this - clock-frequency: desired I2C bus clock frequency in Hz. The absence of this
propoerty indicates the default frequency 100 kHz. propoerty indicates the default frequency 100 kHz.
- clocks: clock specifier.
Examples : Examples :
i2c0: i2c@e6500000 { i2c0: i2c@e6508000 {
compatible = "renesas,i2c-rcar-h2"; #address-cells = <1>;
reg = <0 0xe6500000 0 0x428>; #size-cells = <0>;
interrupts = <0 174 0x4>; compatible = "renesas,i2c-r8a7791";
reg = <0 0xe6508000 0 0x40>;
interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
clock-frequency = <400000>;
}; };
Qualcomm Universal Peripheral (QUP) I2C controller
Required properties:
- compatible: Should be:
* "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
* "qcom,i2c-qup-v2.1.1" for 8974 v1.
* "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
- reg: Should contain QUP register address and length.
- interrupts: Should contain I2C interrupt.
- clocks: A list of phandles + clock-specifiers, one for each entry in
clock-names.
- clock-names: Should contain:
* "core" for the core clock
* "iface" for the AHB clock
- #address-cells: Should be <1> Address cells for i2c device address
- #size-cells: Should be <0> as i2c addresses have no size component
Optional properties:
- clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
defaults to 100kHz if omitted.
Child nodes should conform to i2c bus binding.
Example:
i2c@f9924000 {
compatible = "qcom,i2c-qup-v2.2.1";
reg = <0xf9924000 0x1000>;
interrupts = <0 96 0>;
clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
clock-names = "core", "iface";
clock-frequency = <355000>;
#address-cells = <1>;
#size-cells = <0>;
};
...@@ -26,6 +26,7 @@ Supported adapters: ...@@ -26,6 +26,7 @@ Supported adapters:
* Intel Wellsburg (PCH) * Intel Wellsburg (PCH)
* Intel Coleto Creek (PCH) * Intel Coleto Creek (PCH)
* Intel Wildcat Point-LP (PCH) * Intel Wildcat Point-LP (PCH)
* Intel BayTrail (SOC)
Datasheets: Publicly available at the Intel website Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller On Intel Patsburg and later chipsets, both the normal host SMBus controller
......
...@@ -46,7 +46,7 @@ A few combinations of the above flags are also defined for your convenience: ...@@ -46,7 +46,7 @@ A few combinations of the above flags are also defined for your convenience:
and write_block_data commands and write_block_data commands
I2C_FUNC_SMBUS_I2C_BLOCK Handles the SMBus read_i2c_block_data I2C_FUNC_SMBUS_I2C_BLOCK Handles the SMBus read_i2c_block_data
and write_i2c_block_data commands and write_i2c_block_data commands
I2C_FUNC_SMBUS_EMUL Handles all SMBus commands than can be I2C_FUNC_SMBUS_EMUL Handles all SMBus commands that can be
emulated by a real I2C adapter (using emulated by a real I2C adapter (using
the transparent emulation layer) the transparent emulation layer)
......
...@@ -49,11 +49,20 @@ a byte read, followed by a byte write: ...@@ -49,11 +49,20 @@ a byte read, followed by a byte write:
Modified transactions Modified transactions
===================== =====================
The following modifications to the I2C protocol can also be generated, The following modifications to the I2C protocol can also be generated by
with the exception of I2C_M_NOSTART these are usually only needed to setting these flags for i2c messages. With the exception of I2C_M_NOSTART, they
work around device issues: are usually only needed to work around device issues:
Flag I2C_M_NOSTART: I2C_M_IGNORE_NAK:
Normally message is interrupted immediately if there is [NA] from the
client. Setting this flag treats any [NA] as [A], and all of
message is sent.
These messages may still fail to SCL lo->hi timeout.
I2C_M_NO_RD_ACK:
In a read message, master A/NA bit is skipped.
I2C_M_NOSTART:
In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some
point. For example, setting I2C_M_NOSTART on the second partial message point. For example, setting I2C_M_NOSTART on the second partial message
generates something like: generates something like:
...@@ -67,17 +76,13 @@ work around device issues: ...@@ -67,17 +76,13 @@ work around device issues:
I2C device but may also be used between direction changes by some I2C device but may also be used between direction changes by some
rare devices. rare devices.
Flags I2C_M_REV_DIR_ADDR I2C_M_REV_DIR_ADDR:
This toggles the Rd/Wr flag. That is, if you want to do a write, but This toggles the Rd/Wr flag. That is, if you want to do a write, but
need to emit an Rd instead of a Wr, or vice versa, you set this need to emit an Rd instead of a Wr, or vice versa, you set this
flag. For example: flag. For example:
S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P
Flags I2C_M_IGNORE_NAK I2C_M_STOP:
Normally message is interrupted immediately if there is [NA] from the Force a stop condition (P) after the message. Some I2C related protocols
client. Setting this flag treats any [NA] as [A], and all of like SCCB require that. Normally, you really don't want to get interrupted
message is sent. between the messages of one transfer.
These messages may still fail to SCL lo->hi timeout.
Flags I2C_M_NO_RD_ACK
In a read message, master A/NA bit is skipped.
...@@ -1427,6 +1427,7 @@ F: drivers/cpuidle/cpuidle-zynq.c ...@@ -1427,6 +1427,7 @@ F: drivers/cpuidle/cpuidle-zynq.c
N: zynq N: zynq
N: xilinx N: xilinx
F: drivers/clocksource/cadence_ttc_timer.c F: drivers/clocksource/cadence_ttc_timer.c
F: drivers/i2c/busses/i2c-cadence.c
F: drivers/mmc/host/sdhci-of-arasan.c F: drivers/mmc/host/sdhci-of-arasan.c
ARM SMMU DRIVER ARM SMMU DRIVER
...@@ -4308,7 +4309,8 @@ F: drivers/i2c/i2c-stub.c ...@@ -4308,7 +4309,8 @@ F: drivers/i2c/i2c-stub.c
I2C SUBSYSTEM I2C SUBSYSTEM
M: Wolfram Sang <wsa@the-dreams.de> M: Wolfram Sang <wsa@the-dreams.de>
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/ W: https://i2c.wiki.kernel.org/
Q: https://patchwork.ozlabs.org/project/linux-i2c/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
S: Maintained S: Maintained
F: Documentation/i2c/ F: Documentation/i2c/
......
...@@ -9,60 +9,7 @@ ...@@ -9,60 +9,7 @@
#ifndef __ASM_BFIN_TWI_H__ #ifndef __ASM_BFIN_TWI_H__
#define __ASM_BFIN_TWI_H__ #define __ASM_BFIN_TWI_H__
#include <linux/types.h> #include <asm/blackfin.h>
#include <linux/i2c.h>
/*
* All Blackfin system MMRs are padded to 32bits even if the register
* itself is only 16bits. So use a helper macro to streamline this.
*/
#define __BFP(m) u16 m; u16 __pad_##m
/*
* bfin twi registers layout
*/
struct bfin_twi_regs {
__BFP(clkdiv);
__BFP(control);
__BFP(slave_ctl);
__BFP(slave_stat);
__BFP(slave_addr);
__BFP(master_ctl);
__BFP(master_stat);
__BFP(master_addr);
__BFP(int_stat);
__BFP(int_mask);
__BFP(fifo_ctl);
__BFP(fifo_stat);
u32 __pad[20];
__BFP(xmt_data8);
__BFP(xmt_data16);
__BFP(rcv_data8);
__BFP(rcv_data16);
};
#undef __BFP
struct bfin_twi_iface {
int irq;
spinlock_t lock;
char read_write;
u8 command;
u8 *transPtr;
int readNum;
int writeNum;
int cur_mode;
int manual_stop;
int result;
struct i2c_adapter adap;
struct completion complete;
struct i2c_msg *pmsg;
int msg_num;
int cur_msg;
u16 saved_clkdiv;
u16 saved_control;
struct bfin_twi_regs __iomem *regs_base;
};
#define DEFINE_TWI_REG(reg_name, reg) \ #define DEFINE_TWI_REG(reg_name, reg) \
static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \ static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \
...@@ -71,7 +18,6 @@ static inline void write_##reg_name(struct bfin_twi_iface *iface, u16 v) \ ...@@ -71,7 +18,6 @@ static inline void write_##reg_name(struct bfin_twi_iface *iface, u16 v) \
{ bfin_write16(&iface->regs_base->reg, v); } { bfin_write16(&iface->regs_base->reg, v); }
DEFINE_TWI_REG(CLKDIV, clkdiv) DEFINE_TWI_REG(CLKDIV, clkdiv)
DEFINE_TWI_REG(CONTROL, control)
DEFINE_TWI_REG(SLAVE_CTL, slave_ctl) DEFINE_TWI_REG(SLAVE_CTL, slave_ctl)
DEFINE_TWI_REG(SLAVE_STAT, slave_stat) DEFINE_TWI_REG(SLAVE_STAT, slave_stat)
DEFINE_TWI_REG(SLAVE_ADDR, slave_addr) DEFINE_TWI_REG(SLAVE_ADDR, slave_addr)
...@@ -80,7 +26,6 @@ DEFINE_TWI_REG(MASTER_STAT, master_stat) ...@@ -80,7 +26,6 @@ DEFINE_TWI_REG(MASTER_STAT, master_stat)
DEFINE_TWI_REG(MASTER_ADDR, master_addr) DEFINE_TWI_REG(MASTER_ADDR, master_addr)
DEFINE_TWI_REG(INT_STAT, int_stat) DEFINE_TWI_REG(INT_STAT, int_stat)
DEFINE_TWI_REG(INT_MASK, int_mask) DEFINE_TWI_REG(INT_MASK, int_mask)
DEFINE_TWI_REG(FIFO_CTL, fifo_ctl)
DEFINE_TWI_REG(FIFO_STAT, fifo_stat) DEFINE_TWI_REG(FIFO_STAT, fifo_stat)
DEFINE_TWI_REG(XMT_DATA8, xmt_data8) DEFINE_TWI_REG(XMT_DATA8, xmt_data8)
DEFINE_TWI_REG(XMT_DATA16, xmt_data16) DEFINE_TWI_REG(XMT_DATA16, xmt_data16)
...@@ -113,75 +58,25 @@ static inline u16 read_RCV_DATA16(struct bfin_twi_iface *iface) ...@@ -113,75 +58,25 @@ static inline u16 read_RCV_DATA16(struct bfin_twi_iface *iface)
} }
#endif #endif
static inline u16 read_FIFO_CTL(struct bfin_twi_iface *iface)
{
return bfin_read16(&iface->regs_base->fifo_ctl);
}
/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ static inline void write_FIFO_CTL(struct bfin_twi_iface *iface, u16 v)
/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ {
#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ bfin_write16(&iface->regs_base->fifo_ctl, v);
#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ SSYNC();
}
/* TWI_PRESCALE Masks */
#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
#define TWI_ENA 0x0080 /* TWI Enable */
#define SCCB 0x0200 /* SCCB Compatibility Enable */
/* TWI_SLAVE_CTL Masks */
#define SEN 0x0001 /* Slave Enable */
#define SADD_LEN 0x0002 /* Slave Address Length */
#define STDVAL 0x0004 /* Slave Transmit Data Valid */
#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
#define GEN 0x0010 /* General Call Address Matching Enabled */
/* TWI_SLAVE_STAT Masks */
#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
#define GCALL 0x0002 /* General Call Indicator */
/* TWI_MASTER_CTL Masks */
#define MEN 0x0001 /* Master Mode Enable */
#define MADD_LEN 0x0002 /* Master Address Length */
#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
#define FAST 0x0008 /* Use Fast Mode Timing Specs */
#define STOP 0x0010 /* Issue Stop Condition */
#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
#define DCNT 0x3FC0 /* Data Bytes To Transfer */
#define SDAOVR 0x4000 /* Serial Data Override */
#define SCLOVR 0x8000 /* Serial Clock Override */
/* TWI_MASTER_STAT Masks */
#define MPROG 0x0001 /* Master Transfer In Progress */
#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
#define ANAK 0x0004 /* Address Not Acknowledged */
#define DNAK 0x0008 /* Data Not Acknowledged */
#define BUFRDERR 0x0010 /* Buffer Read Error */
#define BUFWRERR 0x0020 /* Buffer Write Error */
#define SDASEN 0x0040 /* Serial Data Sense */
#define SCLSEN 0x0080 /* Serial Clock Sense */
#define BUSBUSY 0x0100 /* Bus Busy Indicator */
/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
#define SINIT 0x0001 /* Slave Transfer Initiated */
#define SCOMP 0x0002 /* Slave Transfer Complete */
#define SERR 0x0004 /* Slave Transfer Error */
#define SOVF 0x0008 /* Slave Overflow */
#define MCOMP 0x0010 /* Master Transfer Complete */
#define MERR 0x0020 /* Master Transfer Error */
#define XMTSERV 0x0040 /* Transmit FIFO Service */
#define RCVSERV 0x0080 /* Receive FIFO Service */
/* TWI_FIFO_CTRL Masks */
#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
/* TWI_FIFO_STAT Masks */
#define XMTSTAT 0x0003 /* Transmit FIFO Status */
#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
#define RCVSTAT 0x000C /* Receive FIFO Status */ static inline u16 read_CONTROL(struct bfin_twi_iface *iface)
#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ {
#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ return bfin_read16(&iface->regs_base->control);
#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ }
static inline void write_CONTROL(struct bfin_twi_iface *iface, u16 v)
{
SSYNC();
bfin_write16(&iface->regs_base->control, v);
}
#endif #endif
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c/bfin_twi.h>
#include <asm/blackfin.h> #include <asm/blackfin.h>
#include <asm/gpio.h> #include <asm/gpio.h>
......
...@@ -110,6 +110,7 @@ config I2C_I801 ...@@ -110,6 +110,7 @@ config I2C_I801
Wellsburg (PCH) Wellsburg (PCH)
Coleto Creek (PCH) Coleto Creek (PCH)
Wildcat Point-LP (PCH) Wildcat Point-LP (PCH)
BayTrail (SOC)
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-i801. will be called i2c-i801.
...@@ -375,6 +376,13 @@ config I2C_BLACKFIN_TWI_CLK_KHZ ...@@ -375,6 +376,13 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
help help
The unit of the TWI clock is kHz. The unit of the TWI clock is kHz.
config I2C_CADENCE
tristate "Cadence I2C Controller"
depends on ARCH_ZYNQ
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.
config I2C_CBUS_GPIO config I2C_CBUS_GPIO
tristate "CBUS I2C driver" tristate "CBUS I2C driver"
depends on GPIOLIB depends on GPIOLIB
...@@ -432,6 +440,13 @@ config I2C_DESIGNWARE_PCI ...@@ -432,6 +440,13 @@ config I2C_DESIGNWARE_PCI
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-designware-pci. will be called i2c-designware-pci.
config I2C_EFM32
tristate "EFM32 I2C controller"
depends on ARCH_EFM32 || COMPILE_TEST
help
This driver supports the i2c block found in Energy Micro's EFM32
SoCs.
config I2C_EG20T config I2C_EG20T
tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C" tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C"
depends on PCI depends on PCI
...@@ -527,7 +542,7 @@ config I2C_MPC ...@@ -527,7 +542,7 @@ config I2C_MPC
config I2C_MV64XXX config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller" tristate "Marvell mv64xxx I2C Controller"
depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI) depends on MV64X60 || PLAT_ORION || ARCH_SUNXI
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
built-in I2C interface on the Marvell 64xxx line of host bridges. built-in I2C interface on the Marvell 64xxx line of host bridges.
...@@ -648,6 +663,16 @@ config I2C_PXA_SLAVE ...@@ -648,6 +663,16 @@ config I2C_PXA_SLAVE
is necessary for systems where the PXA may be a target on the is necessary for systems where the PXA may be a target on the
I2C bus. I2C bus.
config I2C_QUP
tristate "Qualcomm QUP based I2C controller"
depends on ARCH_QCOM
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Qualcomm SoCs.
This driver can also be built as a module. If so, the module
will be called i2c-qup.
config I2C_RIIC config I2C_RIIC
tristate "Renesas RIIC adapter" tristate "Renesas RIIC adapter"
depends on ARCH_SHMOBILE || COMPILE_TEST depends on ARCH_SHMOBILE || COMPILE_TEST
......
...@@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_AT91) += i2c-at91.o ...@@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o
obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
...@@ -41,6 +42,7 @@ obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o ...@@ -41,6 +42,7 @@ obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-platform-objs := i2c-designware-platdrv.o
obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-pci-objs := i2c-designware-pcidrv.o
obj-$(CONFIG_I2C_EFM32) += i2c-efm32.o
obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
...@@ -63,6 +65,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o ...@@ -63,6 +65,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_S6000) += i2c-s6000.o obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
......
...@@ -494,7 +494,7 @@ static struct i2c_adapter ali1535_adapter = { ...@@ -494,7 +494,7 @@ static struct i2c_adapter ali1535_adapter = {
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
}; };
static DEFINE_PCI_DEVICE_TABLE(ali1535_ids) = { static const struct pci_device_id ali1535_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
{ }, { },
}; };
......
...@@ -416,7 +416,7 @@ static void ali1563_remove(struct pci_dev *dev) ...@@ -416,7 +416,7 @@ static void ali1563_remove(struct pci_dev *dev)
ali1563_shutdown(dev); ali1563_shutdown(dev);
} }
static DEFINE_PCI_DEVICE_TABLE(ali1563_id_table) = { static const struct pci_device_id ali1563_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) }, { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },
{}, {},
}; };
......
...@@ -476,7 +476,7 @@ static struct i2c_adapter ali15x3_adapter = { ...@@ -476,7 +476,7 @@ static struct i2c_adapter ali15x3_adapter = {
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
}; };
static DEFINE_PCI_DEVICE_TABLE(ali15x3_ids) = { static const struct pci_device_id ali15x3_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
{ 0, } { 0, }
}; };
......
...@@ -307,7 +307,7 @@ static const char* chipname[] = { ...@@ -307,7 +307,7 @@ static const char* chipname[] = {
"nVidia nForce", "AMD8111", "nVidia nForce", "AMD8111",
}; };
static DEFINE_PCI_DEVICE_TABLE(amd756_ids) = { static const struct pci_device_id amd756_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B), { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),
.driver_data = AMD756 }, .driver_data = AMD756 },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413), { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413),
......
...@@ -414,7 +414,7 @@ static const struct i2c_algorithm smbus_algorithm = { ...@@ -414,7 +414,7 @@ static const struct i2c_algorithm smbus_algorithm = {
}; };
static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = { static const struct pci_device_id amd8111_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
{ 0, } { 0, }
}; };
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_data/dma-atmel.h> #include <linux/platform_data/dma-atmel.h>
#define TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define DEFAULT_TWI_CLK_HZ 100000 /* max 400 Kbits/s */
#define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */
#define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ #define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */
...@@ -711,6 +711,7 @@ static int at91_twi_probe(struct platform_device *pdev) ...@@ -711,6 +711,7 @@ static int at91_twi_probe(struct platform_device *pdev)
struct resource *mem; struct resource *mem;
int rc; int rc;
u32 phy_addr; u32 phy_addr;
u32 bus_clk_rate;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev) if (!dev)
...@@ -756,13 +757,18 @@ static int at91_twi_probe(struct platform_device *pdev) ...@@ -756,13 +757,18 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->use_dma = true; dev->use_dma = true;
} }
at91_calc_twi_clock(dev, TWI_CLK_HZ); rc = of_property_read_u32(dev->dev->of_node, "clock-frequency",
&bus_clk_rate);
if (rc)
bus_clk_rate = DEFAULT_TWI_CLK_HZ;
at91_calc_twi_clock(dev, bus_clk_rate);
at91_init_twi_bus(dev); at91_init_twi_bus(dev);
snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91"); snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91");
i2c_set_adapdata(&dev->adapter, dev); i2c_set_adapdata(&dev->adapter, dev);
dev->adapter.owner = THIS_MODULE; dev->adapter.owner = THIS_MODULE;
dev->adapter.class = I2C_CLASS_HWMON; dev->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
dev->adapter.algo = &at91_twi_algorithm; dev->adapter.algo = &at91_twi_algorithm;
dev->adapter.dev.parent = dev->dev; dev->adapter.dev.parent = dev->dev;
dev->adapter.nr = pdev->id; dev->adapter.nr = pdev->id;
......
...@@ -219,7 +219,7 @@ static const struct i2c_algorithm bcm2835_i2c_algo = { ...@@ -219,7 +219,7 @@ static const struct i2c_algorithm bcm2835_i2c_algo = {
static int bcm2835_i2c_probe(struct platform_device *pdev) static int bcm2835_i2c_probe(struct platform_device *pdev)
{ {
struct bcm2835_i2c_dev *i2c_dev; struct bcm2835_i2c_dev *i2c_dev;
struct resource *mem, *requested, *irq; struct resource *mem, *irq;
u32 bus_clk_rate, divider; u32 bus_clk_rate, divider;
int ret; int ret;
struct i2c_adapter *adap; struct i2c_adapter *adap;
...@@ -234,25 +234,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) ...@@ -234,25 +234,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
init_completion(&i2c_dev->completion); init_completion(&i2c_dev->completion);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) { i2c_dev->regs = devm_ioremap_resource(&pdev->dev, mem);
dev_err(&pdev->dev, "No mem resource\n"); if (IS_ERR(i2c_dev->regs))
return -ENODEV; return PTR_ERR(i2c_dev->regs);
}
requested = devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem),
dev_name(&pdev->dev));
if (!requested) {
dev_err(&pdev->dev, "Could not claim register region\n");
return -EBUSY;
}
i2c_dev->regs = devm_ioremap(&pdev->dev, mem->start,
resource_size(mem));
if (!i2c_dev->regs) {
dev_err(&pdev->dev, "Could not map registers\n");
return -ENOMEM;
}
i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c_dev->clk)) { if (IS_ERR(i2c_dev->clk)) {
...@@ -295,7 +279,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) ...@@ -295,7 +279,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
adap = &i2c_dev->adapter; adap = &i2c_dev->adapter;
i2c_set_adapdata(adap, i2c_dev); i2c_set_adapdata(adap, i2c_dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON; adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name)); strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));
adap->algo = &bcm2835_i2c_algo; adap->algo = &bcm2835_i2c_algo;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c/bfin_twi.h>
#include <asm/blackfin.h>
#include <asm/portmux.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/portmux.h>
#include <asm/bfin_twi.h> #include <asm/bfin_twi.h>
/* SMBus mode*/ /* SMBus mode*/
...@@ -65,7 +65,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, ...@@ -65,7 +65,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
/* Transmit next data */ /* Transmit next data */
while (iface->writeNum > 0 && while (iface->writeNum > 0 &&
(read_FIFO_STAT(iface) & XMTSTAT) != XMT_FULL) { (read_FIFO_STAT(iface) & XMTSTAT) != XMT_FULL) {
SSYNC();
write_XMT_DATA8(iface, *(iface->transPtr++)); write_XMT_DATA8(iface, *(iface->transPtr++));
iface->writeNum--; iface->writeNum--;
} }
...@@ -248,7 +247,6 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id) ...@@ -248,7 +247,6 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)
/* Clear interrupt status */ /* Clear interrupt status */
write_INT_STAT(iface, twi_int_status); write_INT_STAT(iface, twi_int_status);
bfin_twi_handle_interrupt(iface, twi_int_status); bfin_twi_handle_interrupt(iface, twi_int_status);
SSYNC();
} }
spin_unlock_irqrestore(&iface->lock, flags); spin_unlock_irqrestore(&iface->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -294,9 +292,7 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, ...@@ -294,9 +292,7 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
* discarded before start a new operation. * discarded before start a new operation.
*/ */
write_FIFO_CTL(iface, 0x3); write_FIFO_CTL(iface, 0x3);
SSYNC();
write_FIFO_CTL(iface, 0); write_FIFO_CTL(iface, 0);
SSYNC();
if (pmsg->flags & I2C_M_RD) if (pmsg->flags & I2C_M_RD)
iface->read_write = I2C_SMBUS_READ; iface->read_write = I2C_SMBUS_READ;
...@@ -306,7 +302,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, ...@@ -306,7 +302,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
if (iface->writeNum > 0) { if (iface->writeNum > 0) {
write_XMT_DATA8(iface, *(iface->transPtr++)); write_XMT_DATA8(iface, *(iface->transPtr++));
iface->writeNum--; iface->writeNum--;
SSYNC();
} }
} }
...@@ -315,7 +310,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, ...@@ -315,7 +310,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
/* Interrupt mask . Enable XMT, RCV interrupt */ /* Interrupt mask . Enable XMT, RCV interrupt */
write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
SSYNC();
if (pmsg->len <= 255) if (pmsg->len <= 255)
write_MASTER_CTL(iface, pmsg->len << 6); write_MASTER_CTL(iface, pmsg->len << 6);
...@@ -329,7 +323,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, ...@@ -329,7 +323,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
(iface->msg_num > 1 ? RSTART : 0) | (iface->msg_num > 1 ? RSTART : 0) |
((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
SSYNC();
while (!iface->result) { while (!iface->result) {
if (!wait_for_completion_timeout(&iface->complete, if (!wait_for_completion_timeout(&iface->complete,
...@@ -453,7 +446,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -453,7 +446,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
* start a new operation. * start a new operation.
*/ */
write_FIFO_CTL(iface, 0x3); write_FIFO_CTL(iface, 0x3);
SSYNC();
write_FIFO_CTL(iface, 0); write_FIFO_CTL(iface, 0);
/* clear int stat */ /* clear int stat */
...@@ -461,7 +453,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -461,7 +453,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
/* Set Transmit device address */ /* Set Transmit device address */
write_MASTER_ADDR(iface, addr); write_MASTER_ADDR(iface, addr);
SSYNC();
switch (iface->cur_mode) { switch (iface->cur_mode) {
case TWI_I2C_MODE_STANDARDSUB: case TWI_I2C_MODE_STANDARDSUB:
...@@ -469,7 +460,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -469,7 +460,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
write_INT_MASK(iface, MCOMP | MERR | write_INT_MASK(iface, MCOMP | MERR |
((iface->read_write == I2C_SMBUS_READ) ? ((iface->read_write == I2C_SMBUS_READ) ?
RCVSERV : XMTSERV)); RCVSERV : XMTSERV));
SSYNC();
if (iface->writeNum + 1 <= 255) if (iface->writeNum + 1 <= 255)
write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
...@@ -484,7 +474,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -484,7 +474,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
case TWI_I2C_MODE_COMBINED: case TWI_I2C_MODE_COMBINED:
write_XMT_DATA8(iface, iface->command); write_XMT_DATA8(iface, iface->command);
write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
SSYNC();
if (iface->writeNum > 0) if (iface->writeNum > 0)
write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
...@@ -531,7 +520,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -531,7 +520,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
write_INT_MASK(iface, MCOMP | MERR | write_INT_MASK(iface, MCOMP | MERR |
((iface->read_write == I2C_SMBUS_READ) ? ((iface->read_write == I2C_SMBUS_READ) ?
RCVSERV : XMTSERV)); RCVSERV : XMTSERV));
SSYNC();
/* Master enable */ /* Master enable */
write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
...@@ -539,7 +527,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, ...@@ -539,7 +527,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
break; break;
} }
SSYNC();
while (!iface->result) { while (!iface->result) {
if (!wait_for_completion_timeout(&iface->complete, if (!wait_for_completion_timeout(&iface->complete,
...@@ -669,7 +656,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) ...@@ -669,7 +656,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name)); strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
p_adap->algo = &bfin_twi_algorithm; p_adap->algo = &bfin_twi_algorithm;
p_adap->algo_data = iface; p_adap->algo_data = iface;
p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;
p_adap->dev.parent = &pdev->dev; p_adap->dev.parent = &pdev->dev;
p_adap->timeout = 5 * HZ; p_adap->timeout = 5 * HZ;
p_adap->retries = 3; p_adap->retries = 3;
...@@ -704,7 +691,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) ...@@ -704,7 +691,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
/* Enable TWI */ /* Enable TWI */
write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
SSYNC();
rc = i2c_add_numbered_adapter(p_adap); rc = i2c_add_numbered_adapter(p_adap);
if (rc < 0) { if (rc < 0) {
......
This diff is collapsed.
...@@ -712,7 +712,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) ...@@ -712,7 +712,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
adap = &dev->adapter; adap = &dev->adapter;
i2c_set_adapdata(adap, dev); i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON; adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name)); strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
adap->algo = &i2c_davinci_algo; adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
......
...@@ -218,7 +218,7 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) ...@@ -218,7 +218,7 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
* *
* If your hardware is free from tHD;STA issue, try this one. * If your hardware is free from tHD;STA issue, try this one.
*/ */
return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset;
else else
/* /*
* Conditional expression: * Conditional expression:
...@@ -234,7 +234,8 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) ...@@ -234,7 +234,8 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
* The reason why we need to take into account "tf" here, * The reason why we need to take into account "tf" here,
* is the same as described in i2c_dw_scl_lcnt(). * is the same as described in i2c_dw_scl_lcnt().
*/ */
return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000
- 3 + offset;
} }
static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
...@@ -250,7 +251,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) ...@@ -250,7 +251,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
* account the fall time of SCL signal (tf). Default tf value * account the fall time of SCL signal (tf). Default tf value
* should be 0.3 us, for safety. * should be 0.3 us, for safety.
*/ */
return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;
} }
static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable)
...@@ -287,6 +288,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) ...@@ -287,6 +288,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
u32 input_clock_khz; u32 input_clock_khz;
u32 hcnt, lcnt; u32 hcnt, lcnt;
u32 reg; u32 reg;
u32 sda_falling_time, scl_falling_time;
input_clock_khz = dev->get_clk_rate_khz(dev); input_clock_khz = dev->get_clk_rate_khz(dev);
...@@ -308,15 +310,18 @@ int i2c_dw_init(struct dw_i2c_dev *dev) ...@@ -308,15 +310,18 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
/* set standard and fast speed deviders for high/low periods */ /* set standard and fast speed deviders for high/low periods */
sda_falling_time = dev->sda_falling_time ?: 300; /* ns */
scl_falling_time = dev->scl_falling_time ?: 300; /* ns */
/* Standard-mode */ /* Standard-mode */
hcnt = i2c_dw_scl_hcnt(input_clock_khz, hcnt = i2c_dw_scl_hcnt(input_clock_khz,
40, /* tHD;STA = tHIGH = 4.0 us */ 4000, /* tHD;STA = tHIGH = 4.0 us */
3, /* tf = 0.3 us */ sda_falling_time,
0, /* 0: DW default, 1: Ideal */ 0, /* 0: DW default, 1: Ideal */
0); /* No offset */ 0); /* No offset */
lcnt = i2c_dw_scl_lcnt(input_clock_khz, lcnt = i2c_dw_scl_lcnt(input_clock_khz,
47, /* tLOW = 4.7 us */ 4700, /* tLOW = 4.7 us */
3, /* tf = 0.3 us */ scl_falling_time,
0); /* No offset */ 0); /* No offset */
/* Allow platforms to specify the ideal HCNT and LCNT values */ /* Allow platforms to specify the ideal HCNT and LCNT values */
...@@ -330,13 +335,13 @@ int i2c_dw_init(struct dw_i2c_dev *dev) ...@@ -330,13 +335,13 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
/* Fast-mode */ /* Fast-mode */
hcnt = i2c_dw_scl_hcnt(input_clock_khz, hcnt = i2c_dw_scl_hcnt(input_clock_khz,
6, /* tHD;STA = tHIGH = 0.6 us */ 600, /* tHD;STA = tHIGH = 0.6 us */
3, /* tf = 0.3 us */ sda_falling_time,
0, /* 0: DW default, 1: Ideal */ 0, /* 0: DW default, 1: Ideal */
0); /* No offset */ 0); /* No offset */
lcnt = i2c_dw_scl_lcnt(input_clock_khz, lcnt = i2c_dw_scl_lcnt(input_clock_khz,
13, /* tLOW = 1.3 us */ 1300, /* tLOW = 1.3 us */
3, /* tf = 0.3 us */ scl_falling_time,
0); /* No offset */ 0); /* No offset */
if (dev->fs_hcnt && dev->fs_lcnt) { if (dev->fs_hcnt && dev->fs_lcnt) {
......
...@@ -99,6 +99,8 @@ struct dw_i2c_dev { ...@@ -99,6 +99,8 @@ struct dw_i2c_dev {
unsigned int rx_fifo_depth; unsigned int rx_fifo_depth;
int rx_outstanding; int rx_outstanding;
u32 sda_hold_time; u32 sda_hold_time;
u32 sda_falling_time;
u32 scl_falling_time;
u16 ss_hcnt; u16 ss_hcnt;
u16 ss_lcnt; u16 ss_lcnt;
u16 fs_hcnt; u16 fs_hcnt;
......
...@@ -54,6 +54,16 @@ enum dw_pci_ctl_id_t { ...@@ -54,6 +54,16 @@ enum dw_pci_ctl_id_t {
medfield_3, medfield_3,
medfield_4, medfield_4,
medfield_5, medfield_5,
baytrail,
};
struct dw_scl_sda_cfg {
u32 ss_hcnt;
u32 fs_hcnt;
u32 ss_lcnt;
u32 fs_lcnt;
u32 sda_hold;
}; };
struct dw_pci_controller { struct dw_pci_controller {
...@@ -62,12 +72,29 @@ struct dw_pci_controller { ...@@ -62,12 +72,29 @@ struct dw_pci_controller {
u32 tx_fifo_depth; u32 tx_fifo_depth;
u32 rx_fifo_depth; u32 rx_fifo_depth;
u32 clk_khz; u32 clk_khz;
u32 functionality;
struct dw_scl_sda_cfg *scl_sda_cfg;
}; };
#define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \ #define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \
DW_IC_CON_SLAVE_DISABLE | \ DW_IC_CON_SLAVE_DISABLE | \
DW_IC_CON_RESTART_EN) DW_IC_CON_RESTART_EN)
#define DW_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
I2C_FUNC_SMBUS_BYTE | \
I2C_FUNC_SMBUS_BYTE_DATA | \
I2C_FUNC_SMBUS_WORD_DATA | \
I2C_FUNC_SMBUS_I2C_BLOCK)
/* BayTrail HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
.fs_hcnt = 0x55,
.ss_lcnt = 0x200,
.fs_lcnt = 0x99,
.sda_hold = 0x6,
};
static struct dw_pci_controller dw_pci_controllers[] = { static struct dw_pci_controller dw_pci_controllers[] = {
[moorestown_0] = { [moorestown_0] = {
.bus_num = 0, .bus_num = 0,
...@@ -132,75 +159,40 @@ static struct dw_pci_controller dw_pci_controllers[] = { ...@@ -132,75 +159,40 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.rx_fifo_depth = 32, .rx_fifo_depth = 32,
.clk_khz = 25000, .clk_khz = 25000,
}, },
[baytrail] = {
.bus_num = -1,
.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
.tx_fifo_depth = 32,
.rx_fifo_depth = 32,
.clk_khz = 100000,
.functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &byt_config,
},
}; };
static struct i2c_algorithm i2c_dw_algo = { static struct i2c_algorithm i2c_dw_algo = {
.master_xfer = i2c_dw_xfer, .master_xfer = i2c_dw_xfer,
.functionality = i2c_dw_func, .functionality = i2c_dw_func,
}; };
#ifdef CONFIG_PM
static int i2c_dw_pci_suspend(struct device *dev) static int i2c_dw_pci_suspend(struct device *dev)
{ {
struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
int err;
i2c_dw_disable(i2c);
err = pci_save_state(pdev);
if (err) {
dev_err(&pdev->dev, "pci_save_state failed\n");
return err;
}
err = pci_set_power_state(pdev, PCI_D3hot);
if (err) {
dev_err(&pdev->dev, "pci_set_power_state failed\n");
return err;
}
i2c_dw_disable(pci_get_drvdata(pdev));
return 0; return 0;
} }
static int i2c_dw_pci_resume(struct device *dev) static int i2c_dw_pci_resume(struct device *dev)
{ {
struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
int err;
u32 enabled;
enabled = i2c_dw_is_enabled(i2c); return i2c_dw_init(pci_get_drvdata(pdev));
if (enabled)
return 0;
err = pci_set_power_state(pdev, PCI_D0);
if (err) {
dev_err(&pdev->dev, "pci_set_power_state() failed\n");
return err;
}
pci_restore_state(pdev);
i2c_dw_init(i2c);
return 0;
} }
#endif
static int i2c_dw_pci_runtime_idle(struct device *dev) static UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend,
{ i2c_dw_pci_resume, NULL);
int err = pm_schedule_suspend(dev, 500);
dev_dbg(dev, "runtime_idle called\n");
if (err != 0)
return 0;
return -EBUSY;
}
static const struct dev_pm_ops i2c_dw_pm_ops = {
.resume = i2c_dw_pci_resume,
.suspend = i2c_dw_pci_suspend,
SET_RUNTIME_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume,
i2c_dw_pci_runtime_idle)
};
static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
{ {
...@@ -214,6 +206,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -214,6 +206,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
struct i2c_adapter *adap; struct i2c_adapter *adap;
int r; int r;
struct dw_pci_controller *controller; struct dw_pci_controller *controller;
struct dw_scl_sda_cfg *cfg;
if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) { if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) {
dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__, dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__,
...@@ -247,13 +240,18 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -247,13 +240,18 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
dev->base = pcim_iomap_table(pdev)[0]; dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->functionality = dev->functionality = controller->functionality |
I2C_FUNC_I2C | DW_DEFAULT_FUNCTIONALITY;
I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK;
dev->master_cfg = controller->bus_cfg; dev->master_cfg = controller->bus_cfg;
if (controller->scl_sda_cfg) {
cfg = controller->scl_sda_cfg;
dev->ss_hcnt = cfg->ss_hcnt;
dev->fs_hcnt = cfg->fs_hcnt;
dev->ss_lcnt = cfg->ss_lcnt;
dev->fs_lcnt = cfg->fs_lcnt;
dev->sda_hold_time = cfg->sda_hold;
}
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
...@@ -270,8 +268,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -270,8 +268,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
adap->algo = &i2c_dw_algo; adap->algo = &i2c_dw_algo;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
adap->nr = controller->bus_num; adap->nr = controller->bus_num;
snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci-%d",
adap->nr); snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci");
r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr, IRQF_SHARED, r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr, IRQF_SHARED,
adap->name, dev); adap->name, dev);
...@@ -290,6 +288,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -290,6 +288,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
pm_runtime_allow(&pdev->dev); pm_runtime_allow(&pdev->dev);
return 0; return 0;
...@@ -309,7 +308,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) ...@@ -309,7 +308,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
/* work with hotplug and coldplug */ /* work with hotplug and coldplug */
MODULE_ALIAS("i2c_designware-pci"); MODULE_ALIAS("i2c_designware-pci");
static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = { static const struct pci_device_id i2_designware_pci_ids[] = {
/* Moorestown */ /* Moorestown */
{ PCI_VDEVICE(INTEL, 0x0802), moorestown_0 }, { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 },
{ PCI_VDEVICE(INTEL, 0x0803), moorestown_1 }, { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 },
...@@ -321,6 +320,14 @@ static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = { ...@@ -321,6 +320,14 @@ static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {
{ PCI_VDEVICE(INTEL, 0x082C), medfield_0 }, { PCI_VDEVICE(INTEL, 0x082C), medfield_0 },
{ PCI_VDEVICE(INTEL, 0x082D), medfield_1 }, { PCI_VDEVICE(INTEL, 0x082D), medfield_1 },
{ PCI_VDEVICE(INTEL, 0x082E), medfield_2 }, { PCI_VDEVICE(INTEL, 0x082E), medfield_2 },
/* Baytrail */
{ PCI_VDEVICE(INTEL, 0x0F41), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F42), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F43), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F44), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F45), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F46), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F47), baytrail },
{ 0,} { 0,}
}; };
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
......
...@@ -159,6 +159,13 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -159,6 +159,13 @@ static int dw_i2c_probe(struct platform_device *pdev)
"i2c-sda-hold-time-ns", &ht); "i2c-sda-hold-time-ns", &ht);
dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000, dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
1000000); 1000000);
of_property_read_u32(pdev->dev.of_node,
"i2c-sda-falling-time-ns",
&dev->sda_falling_time);
of_property_read_u32(pdev->dev.of_node,
"i2c-scl-falling-time-ns",
&dev->scl_falling_time);
} }
dev->functionality = dev->functionality =
...@@ -195,7 +202,7 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -195,7 +202,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
adap = &dev->adapter; adap = &dev->adapter;
i2c_set_adapdata(adap, dev); i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON; adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "Synopsys DesignWare I2C adapter", strlcpy(adap->name, "Synopsys DesignWare I2C adapter",
sizeof(adap->name)); sizeof(adap->name));
adap->algo = &i2c_dw_algo; adap->algo = &i2c_dw_algo;
......
This diff is collapsed.
...@@ -186,7 +186,7 @@ static DEFINE_MUTEX(pch_mutex); ...@@ -186,7 +186,7 @@ static DEFINE_MUTEX(pch_mutex);
#define PCI_DEVICE_ID_ML7223_I2C 0x8010 #define PCI_DEVICE_ID_ML7223_I2C 0x8010
#define PCI_DEVICE_ID_ML7831_I2C 0x8817 #define PCI_DEVICE_ID_ML7831_I2C 0x8817
static DEFINE_PCI_DEVICE_TABLE(pch_pcidev_id) = { static const struct pci_device_id pch_pcidev_id[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, },
......
...@@ -566,7 +566,7 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c, ...@@ -566,7 +566,7 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
static int exynos5_i2c_xfer(struct i2c_adapter *adap, static int exynos5_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num) struct i2c_msg *msgs, int num)
{ {
struct exynos5_i2c *i2c = (struct exynos5_i2c *)adap->algo_data; struct exynos5_i2c *i2c = adap->algo_data;
int i = 0, ret = 0, stop = 0; int i = 0, ret = 0, stop = 0;
if (i2c->suspended) { if (i2c->suspended) {
...@@ -715,6 +715,7 @@ static int exynos5_i2c_remove(struct platform_device *pdev) ...@@ -715,6 +715,7 @@ static int exynos5_i2c_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int exynos5_i2c_suspend_noirq(struct device *dev) static int exynos5_i2c_suspend_noirq(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
...@@ -745,6 +746,7 @@ static int exynos5_i2c_resume_noirq(struct device *dev) ...@@ -745,6 +746,7 @@ static int exynos5_i2c_resume_noirq(struct device *dev)
return 0; return 0;
} }
#endif
static SIMPLE_DEV_PM_OPS(exynos5_i2c_dev_pm_ops, exynos5_i2c_suspend_noirq, static SIMPLE_DEV_PM_OPS(exynos5_i2c_dev_pm_ops, exynos5_i2c_suspend_noirq,
exynos5_i2c_resume_noirq); exynos5_i2c_resume_noirq);
......
...@@ -94,6 +94,9 @@ static int of_i2c_gpio_get_pins(struct device_node *np, ...@@ -94,6 +94,9 @@ static int of_i2c_gpio_get_pins(struct device_node *np,
*sda_pin = of_get_gpio(np, 0); *sda_pin = of_get_gpio(np, 0);
*scl_pin = of_get_gpio(np, 1); *scl_pin = of_get_gpio(np, 1);
if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) { if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) {
pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
np->full_name, *sda_pin, *scl_pin); np->full_name, *sda_pin, *scl_pin);
......
...@@ -104,7 +104,7 @@ static struct i2c_adapter hydra_adap = { ...@@ -104,7 +104,7 @@ static struct i2c_adapter hydra_adap = {
.algo_data = &hydra_bit_data, .algo_data = &hydra_bit_data,
}; };
static DEFINE_PCI_DEVICE_TABLE(hydra_ids) = { static const struct pci_device_id hydra_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
{ 0, } { 0, }
}; };
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
Coleto Creek (PCH) 0x23b0 32 hard yes yes yes Coleto Creek (PCH) 0x23b0 32 hard yes yes yes
Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes
BayTrail (SOC) 0x0f12 32 hard yes yes yes
Features supported by this driver: Features supported by this driver:
Software PEC no Software PEC no
...@@ -161,6 +162,7 @@ ...@@ -161,6 +162,7 @@
STATUS_ERROR_FLAGS) STATUS_ERROR_FLAGS)
/* Older devices have their ID defined in <linux/pci_ids.h> */ /* Older devices have their ID defined in <linux/pci_ids.h> */
#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
/* Patsburg also has three 'Integrated Device Function' SMBus controllers */ /* Patsburg also has three 'Integrated Device Function' SMBus controllers */
...@@ -789,7 +791,7 @@ static const struct i2c_algorithm smbus_algorithm = { ...@@ -789,7 +791,7 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality = i801_func, .functionality = i801_func,
}; };
static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
...@@ -822,6 +824,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { ...@@ -822,6 +824,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },
{ 0, } { 0, }
}; };
......
...@@ -182,7 +182,7 @@ struct ismt_priv { ...@@ -182,7 +182,7 @@ struct ismt_priv {
/** /**
* ismt_ids - PCI device IDs supported by this driver * ismt_ids - PCI device IDs supported by this driver
*/ */
static DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { static const struct pci_device_id ismt_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) },
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mv643xx_i2c.h> #include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
...@@ -97,7 +98,6 @@ enum { ...@@ -97,7 +98,6 @@ enum {
enum { enum {
MV64XXX_I2C_ACTION_INVALID, MV64XXX_I2C_ACTION_INVALID,
MV64XXX_I2C_ACTION_CONTINUE, MV64XXX_I2C_ACTION_CONTINUE,
MV64XXX_I2C_ACTION_SEND_START,
MV64XXX_I2C_ACTION_SEND_RESTART, MV64XXX_I2C_ACTION_SEND_RESTART,
MV64XXX_I2C_ACTION_OFFLOAD_RESTART, MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
MV64XXX_I2C_ACTION_SEND_ADDR_1, MV64XXX_I2C_ACTION_SEND_ADDR_1,
...@@ -148,6 +148,8 @@ struct mv64xxx_i2c_data { ...@@ -148,6 +148,8 @@ struct mv64xxx_i2c_data {
bool offload_enabled; bool offload_enabled;
/* 5us delay in order to avoid repeated start timing violation */ /* 5us delay in order to avoid repeated start timing violation */
bool errata_delay; bool errata_delay;
struct reset_control *rstc;
bool irq_clear_inverted;
}; };
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
...@@ -176,11 +178,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, ...@@ -176,11 +178,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
{ {
u32 dir = 0; u32 dir = 0;
drv_data->msg = msg;
drv_data->byte_posn = 0;
drv_data->bytes_left = msg->len;
drv_data->aborting = 0;
drv_data->rc = 0;
drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
...@@ -206,11 +203,6 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) ...@@ -206,11 +203,6 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)
if (!drv_data->offload_enabled) if (!drv_data->offload_enabled)
return -EOPNOTSUPP; return -EOPNOTSUPP;
drv_data->msg = msg;
drv_data->byte_posn = 0;
drv_data->bytes_left = msg->len;
drv_data->aborting = 0;
drv_data->rc = 0;
/* Only regular transactions can be offloaded */ /* Only regular transactions can be offloaded */
if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0) if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0)
return -EINVAL; return -EINVAL;
...@@ -419,6 +411,23 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) ...@@ -419,6 +411,23 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
} }
} }
static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data)
{
drv_data->msg = drv_data->msgs;
drv_data->byte_posn = 0;
drv_data->bytes_left = drv_data->msg->len;
drv_data->aborting = 0;
drv_data->rc = 0;
/* Can we offload this msg ? */
if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
/* No, switch to standard path */
mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
drv_data->reg_base + drv_data->reg_offsets.control);
}
}
static void static void
mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
{ {
...@@ -435,14 +444,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) ...@@ -435,14 +444,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->msgs++; drv_data->msgs++;
drv_data->num_msgs--; drv_data->num_msgs--;
if (mv64xxx_i2c_offload_msg(drv_data) < 0) { mv64xxx_i2c_send_start(drv_data);
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
writel(drv_data->cntl_bits,
drv_data->reg_base + drv_data->reg_offsets.control);
/* Setup for the next message */
mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
}
if (drv_data->errata_delay) if (drv_data->errata_delay)
udelay(5); udelay(5);
...@@ -459,16 +462,6 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) ...@@ -459,16 +462,6 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->reg_base + drv_data->reg_offsets.control); drv_data->reg_base + drv_data->reg_offsets.control);
break; break;
case MV64XXX_I2C_ACTION_SEND_START:
/* Can we offload this msg ? */
if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
/* No, switch to standard path */
mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
drv_data->reg_base + drv_data->reg_offsets.control);
}
break;
case MV64XXX_I2C_ACTION_SEND_ADDR_1: case MV64XXX_I2C_ACTION_SEND_ADDR_1:
writel(drv_data->addr1, writel(drv_data->addr1,
drv_data->reg_base + drv_data->reg_offsets.data); drv_data->reg_base + drv_data->reg_offsets.data);
...@@ -566,6 +559,11 @@ mv64xxx_i2c_intr(int irq, void *dev_id) ...@@ -566,6 +559,11 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
status = readl(drv_data->reg_base + drv_data->reg_offsets.status); status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
mv64xxx_i2c_fsm(drv_data, status); mv64xxx_i2c_fsm(drv_data, status);
mv64xxx_i2c_do_action(drv_data); mv64xxx_i2c_do_action(drv_data);
if (drv_data->irq_clear_inverted)
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_IFLG,
drv_data->reg_base + drv_data->reg_offsets.control);
rc = IRQ_HANDLED; rc = IRQ_HANDLED;
} }
spin_unlock_irqrestore(&drv_data->lock, flags); spin_unlock_irqrestore(&drv_data->lock, flags);
...@@ -626,12 +624,11 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, ...@@ -626,12 +624,11 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
spin_lock_irqsave(&drv_data->lock, flags); spin_lock_irqsave(&drv_data->lock, flags);
drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
drv_data->send_stop = is_last; drv_data->send_stop = is_last;
drv_data->block = 1; drv_data->block = 1;
mv64xxx_i2c_do_action(drv_data); mv64xxx_i2c_send_start(drv_data);
spin_unlock_irqrestore(&drv_data->lock, flags); spin_unlock_irqrestore(&drv_data->lock, flags);
mv64xxx_i2c_wait_for_completion(drv_data); mv64xxx_i2c_wait_for_completion(drv_data);
...@@ -685,6 +682,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = { ...@@ -685,6 +682,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
*/ */
static const struct of_device_id mv64xxx_i2c_of_match_table[] = { static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
{ .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i}, { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
{ .compatible = "allwinner,sun6i-a31-i2c", .data = &mv64xxx_i2c_regs_sun4i},
{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
{ .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, { .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
{ .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, { .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
...@@ -759,6 +757,16 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, ...@@ -759,6 +757,16 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
} }
drv_data->irq = irq_of_parse_and_map(np, 0); drv_data->irq = irq_of_parse_and_map(np, 0);
drv_data->rstc = devm_reset_control_get_optional(dev, NULL);
if (IS_ERR(drv_data->rstc)) {
if (PTR_ERR(drv_data->rstc) == -EPROBE_DEFER) {
rc = -EPROBE_DEFER;
goto out;
}
} else {
reset_control_deassert(drv_data->rstc);
}
/* Its not yet defined how timeouts will be specified in device tree. /* Its not yet defined how timeouts will be specified in device tree.
* So hard code the value to 1 second. * So hard code the value to 1 second.
*/ */
...@@ -783,6 +791,10 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, ...@@ -783,6 +791,10 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
drv_data->offload_enabled = false; drv_data->offload_enabled = false;
drv_data->errata_delay = true; drv_data->errata_delay = true;
} }
if (of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
drv_data->irq_clear_inverted = true;
out: out:
return rc; return rc;
#endif #endif
...@@ -845,13 +857,13 @@ mv64xxx_i2c_probe(struct platform_device *pd) ...@@ -845,13 +857,13 @@ mv64xxx_i2c_probe(struct platform_device *pd)
} }
if (drv_data->irq < 0) { if (drv_data->irq < 0) {
rc = -ENXIO; rc = -ENXIO;
goto exit_clk; goto exit_reset;
} }
drv_data->adapter.dev.parent = &pd->dev; drv_data->adapter.dev.parent = &pd->dev;
drv_data->adapter.algo = &mv64xxx_i2c_algo; drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE; drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;
drv_data->adapter.nr = pd->id; drv_data->adapter.nr = pd->id;
drv_data->adapter.dev.of_node = pd->dev.of_node; drv_data->adapter.dev.of_node = pd->dev.of_node;
platform_set_drvdata(pd, drv_data); platform_set_drvdata(pd, drv_data);
...@@ -865,7 +877,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) ...@@ -865,7 +877,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
dev_err(&drv_data->adapter.dev, dev_err(&drv_data->adapter.dev,
"mv64xxx: Can't register intr handler irq%d: %d\n", "mv64xxx: Can't register intr handler irq%d: %d\n",
drv_data->irq, rc); drv_data->irq, rc);
goto exit_clk; goto exit_reset;
} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) { } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
dev_err(&drv_data->adapter.dev, dev_err(&drv_data->adapter.dev,
"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
...@@ -876,6 +888,9 @@ mv64xxx_i2c_probe(struct platform_device *pd) ...@@ -876,6 +888,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
exit_free_irq: exit_free_irq:
free_irq(drv_data->irq, drv_data); free_irq(drv_data->irq, drv_data);
exit_reset:
if (!IS_ERR_OR_NULL(drv_data->rstc))
reset_control_assert(drv_data->rstc);
exit_clk: exit_clk:
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
/* Not all platforms have a clk */ /* Not all platforms have a clk */
...@@ -894,6 +909,8 @@ mv64xxx_i2c_remove(struct platform_device *dev) ...@@ -894,6 +909,8 @@ mv64xxx_i2c_remove(struct platform_device *dev)
i2c_del_adapter(&drv_data->adapter); i2c_del_adapter(&drv_data->adapter);
free_irq(drv_data->irq, drv_data); free_irq(drv_data->irq, drv_data);
if (!IS_ERR_OR_NULL(drv_data->rstc))
reset_control_assert(drv_data->rstc);
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
/* Not all platforms have a clk */ /* Not all platforms have a clk */
if (!IS_ERR(drv_data->clk)) { if (!IS_ERR(drv_data->clk)) {
......
...@@ -806,7 +806,6 @@ static int mxs_i2c_probe(struct platform_device *pdev) ...@@ -806,7 +806,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
struct mxs_i2c_dev *i2c; struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct resource *res; struct resource *res;
resource_size_t res_size;
int err, irq; int err, irq;
i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL); i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
...@@ -819,18 +818,13 @@ static int mxs_i2c_probe(struct platform_device *pdev) ...@@ -819,18 +818,13 @@ static int mxs_i2c_probe(struct platform_device *pdev)
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0); i2c->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c->regs))
if (!res || irq < 0) return PTR_ERR(i2c->regs);
return -ENOENT;
res_size = resource_size(res); irq = platform_get_irq(pdev, 0);
if (!devm_request_mem_region(dev, res->start, res_size, res->name)) if (irq < 0)
return -EBUSY; return irq;
i2c->regs = devm_ioremap_nocache(dev, res->start, res_size);
if (!i2c->regs)
return -EBUSY;
err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c); err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);
if (err) if (err)
......
...@@ -306,7 +306,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -306,7 +306,7 @@ static struct i2c_algorithm smbus_algorithm = {
}; };
static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { static const struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
......
This diff is collapsed.
...@@ -246,7 +246,7 @@ static const struct i2c_algorithm ocores_algorithm = { ...@@ -246,7 +246,7 @@ static const struct i2c_algorithm ocores_algorithm = {
static struct i2c_adapter ocores_adapter = { static struct i2c_adapter ocores_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "i2c-ocores", .name = "i2c-ocores",
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED,
.algo = &ocores_algorithm, .algo = &ocores_algorithm,
}; };
......
...@@ -636,7 +636,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ...@@ -636,7 +636,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
int r; int r;
r = pm_runtime_get_sync(dev->dev); r = pm_runtime_get_sync(dev->dev);
if (IS_ERR_VALUE(r)) if (r < 0)
goto out; goto out;
r = omap_i2c_wait_for_bb(dev); r = omap_i2c_wait_for_bb(dev);
...@@ -1155,7 +1155,7 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -1155,7 +1155,7 @@ omap_i2c_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(dev->dev); pm_runtime_use_autosuspend(dev->dev);
r = pm_runtime_get_sync(dev->dev); r = pm_runtime_get_sync(dev->dev);
if (IS_ERR_VALUE(r)) if (r < 0)
goto err_free_mem; goto err_free_mem;
/* /*
...@@ -1238,7 +1238,7 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -1238,7 +1238,7 @@ omap_i2c_probe(struct platform_device *pdev)
adap = &dev->adapter; adap = &dev->adapter;
i2c_set_adapdata(adap, dev); i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON; adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
adap->algo = &omap_i2c_algo; adap->algo = &omap_i2c_algo;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
...@@ -1276,7 +1276,7 @@ static int omap_i2c_remove(struct platform_device *pdev) ...@@ -1276,7 +1276,7 @@ static int omap_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&dev->adapter); i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev);
if (IS_ERR_VALUE(ret)) if (ret < 0)
return ret; return ret;
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
......
...@@ -401,7 +401,7 @@ static void pasemi_smb_remove(struct pci_dev *dev) ...@@ -401,7 +401,7 @@ static void pasemi_smb_remove(struct pci_dev *dev)
kfree(smbus); kfree(smbus);
} }
static DEFINE_PCI_DEVICE_TABLE(pasemi_smb_ids) = { static const struct pci_device_id pasemi_smb_ids[] = {
{ PCI_DEVICE(0x1959, 0xa003) }, { PCI_DEVICE(0x1959, 0xa003) },
{ 0, } { 0, }
}; };
......
...@@ -540,7 +540,7 @@ static const struct i2c_algorithm smbus_algorithm = { ...@@ -540,7 +540,7 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality = piix4_func, .functionality = piix4_func,
}; };
static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { static const struct pci_device_id piix4_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) }, { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
......
...@@ -148,7 +148,7 @@ static void ce4100_i2c_remove(struct pci_dev *dev) ...@@ -148,7 +148,7 @@ static void ce4100_i2c_remove(struct pci_dev *dev)
kfree(sds); kfree(sds);
} }
static DEFINE_PCI_DEVICE_TABLE(ce4100_i2c_devices) = { static const struct pci_device_id ce4100_i2c_devices[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
{ }, { },
}; };
......
This diff is collapsed.
...@@ -638,6 +638,7 @@ static const struct of_device_id rcar_i2c_dt_ids[] = { ...@@ -638,6 +638,7 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 }, { .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 }, { .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 }, { .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,i2c-r8a7791", .data = (void *)I2C_RCAR_GEN2 },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
...@@ -691,7 +692,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) ...@@ -691,7 +692,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
adap = &priv->adap; adap = &priv->adap;
adap->nr = pdev->id; adap->nr = pdev->id;
adap->algo = &rcar_i2c_algo; adap->algo = &rcar_i2c_algo;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;
adap->retries = 3; adap->retries = 3;
adap->dev.parent = dev; adap->dev.parent = dev;
adap->dev.of_node = dev->of_node; adap->dev.of_node = dev->of_node;
......
...@@ -601,6 +601,31 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id) ...@@ -601,6 +601,31 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/*
* Disable the bus so that we won't get any interrupts from now on, or try
* to drive any lines. This is the default state when we don't have
* anything to send/receive.
*
* If there is an event on the bus, or we have a pre-existing event at
* kernel boot time, we may not notice the event and the I2C controller
* will lock the bus with the I2C clock line low indefinitely.
*/
static inline void s3c24xx_i2c_disable_bus(struct s3c24xx_i2c *i2c)
{
unsigned long tmp;
/* Stop driving the I2C pins */
tmp = readl(i2c->regs + S3C2410_IICSTAT);
tmp &= ~S3C2410_IICSTAT_TXRXEN;
writel(tmp, i2c->regs + S3C2410_IICSTAT);
/* We don't expect any interrupts now, and don't want send acks */
tmp = readl(i2c->regs + S3C2410_IICCON);
tmp &= ~(S3C2410_IICCON_IRQEN | S3C2410_IICCON_IRQPEND |
S3C2410_IICCON_ACKEN);
writel(tmp, i2c->regs + S3C2410_IICCON);
}
/* s3c24xx_i2c_set_master /* s3c24xx_i2c_set_master
* *
...@@ -735,7 +760,11 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, ...@@ -735,7 +760,11 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
s3c24xx_i2c_wait_idle(i2c); s3c24xx_i2c_wait_idle(i2c);
s3c24xx_i2c_disable_bus(i2c);
out: out:
i2c->state = STATE_IDLE;
return ret; return ret;
} }
...@@ -1004,7 +1033,6 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) ...@@ -1004,7 +1033,6 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
{ {
unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;
struct s3c2410_platform_i2c *pdata; struct s3c2410_platform_i2c *pdata;
unsigned int freq; unsigned int freq;
...@@ -1018,12 +1046,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) ...@@ -1018,12 +1046,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr); dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
writel(iicon, i2c->regs + S3C2410_IICCON); writel(0, i2c->regs + S3C2410_IICCON);
writel(0, i2c->regs + S3C2410_IICSTAT);
/* we need to work out the divisors for the clock... */ /* we need to work out the divisors for the clock... */
if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) { if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
writel(0, i2c->regs + S3C2410_IICCON);
dev_err(i2c->dev, "cannot meet bus frequency required\n"); dev_err(i2c->dev, "cannot meet bus frequency required\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1031,7 +1059,8 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) ...@@ -1031,7 +1059,8 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
/* todo - check that the i2c lines aren't being dragged anywhere */ /* todo - check that the i2c lines aren't being dragged anywhere */
dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02x\n",
readl(i2c->regs + S3C2410_IICCON));
return 0; return 0;
} }
...@@ -1106,7 +1135,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ...@@ -1106,7 +1135,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->adap.owner = THIS_MODULE; i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &s3c24xx_i2c_algorithm; i2c->adap.algo = &s3c24xx_i2c_algorithm;
i2c->adap.retries = 2; i2c->adap.retries = 2;
i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;
i2c->tx_setup = 50; i2c->tx_setup = 50;
init_waitqueue_head(&i2c->wait); init_waitqueue_head(&i2c->wait);
......
...@@ -312,7 +312,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev) ...@@ -312,7 +312,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
goto out; goto out;
} }
adap = &siic->adapter; adap = &siic->adapter;
adap->class = I2C_CLASS_HWMON; adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
siic->base = devm_ioremap_resource(&pdev->dev, mem_res); siic->base = devm_ioremap_resource(&pdev->dev, mem_res);
......
...@@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapter = { ...@@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapter = {
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
}; };
static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = { static const struct pci_device_id sis5595_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ 0, } { 0, }
}; };
......
...@@ -510,7 +510,7 @@ static struct i2c_adapter sis630_adapter = { ...@@ -510,7 +510,7 @@ static struct i2c_adapter sis630_adapter = {
.retries = 3 .retries = 3
}; };
static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = { static const struct pci_device_id sis630_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_964) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_964) },
......
...@@ -244,7 +244,7 @@ static struct i2c_adapter sis96x_adapter = { ...@@ -244,7 +244,7 @@ static struct i2c_adapter sis96x_adapter = {
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
}; };
static DEFINE_PCI_DEVICE_TABLE(sis96x_ids) = { static const struct pci_device_id sis96x_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
{ 0, } { 0, }
}; };
......
...@@ -574,7 +574,7 @@ static irqreturn_t st_i2c_isr_thread(int irq, void *data) ...@@ -574,7 +574,7 @@ static irqreturn_t st_i2c_isr_thread(int irq, void *data)
writel_relaxed(it, i2c_dev->base + SSC_IEN); writel_relaxed(it, i2c_dev->base + SSC_IEN);
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG); st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
c->result = -EIO; c->result = -EAGAIN;
break; break;
default: default:
......
...@@ -911,7 +911,7 @@ static int stu300_probe(struct platform_device *pdev) ...@@ -911,7 +911,7 @@ static int stu300_probe(struct platform_device *pdev)
adap = &dev->adapter; adap = &dev->adapter;
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
/* DDC class but actually often used for more generic I2C */ /* DDC class but actually often used for more generic I2C */
adap->class = I2C_CLASS_DDC; adap->class = I2C_CLASS_DDC | I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "ST Microelectronics DDC I2C adapter", strlcpy(adap->name, "ST Microelectronics DDC I2C adapter",
sizeof(adap->name)); sizeof(adap->name));
adap->nr = bus_nr; adap->nr = bus_nr;
......
...@@ -794,7 +794,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -794,7 +794,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(&i2c_dev->adapter, i2c_dev); i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
i2c_dev->adapter.owner = THIS_MODULE; i2c_dev->adapter.owner = THIS_MODULE;
i2c_dev->adapter.class = I2C_CLASS_HWMON; i2c_dev->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;
strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter", strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter",
sizeof(i2c_dev->adapter.name)); sizeof(i2c_dev->adapter.name));
i2c_dev->adapter.algo = &tegra_i2c_algo; i2c_dev->adapter.algo = &tegra_i2c_algo;
......
...@@ -88,7 +88,7 @@ static struct i2c_adapter vt586b_adapter = { ...@@ -88,7 +88,7 @@ static struct i2c_adapter vt586b_adapter = {
}; };
static DEFINE_PCI_DEVICE_TABLE(vt586b_ids) = { static const struct pci_device_id vt586b_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },
{ 0, } { 0, }
}; };
......
...@@ -442,7 +442,7 @@ static int vt596_probe(struct pci_dev *pdev, ...@@ -442,7 +442,7 @@ static int vt596_probe(struct pci_dev *pdev,
return error; return error;
} }
static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = { static const struct pci_device_id vt596_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3), { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
.driver_data = SMBBA1 }, .driver_data = SMBBA1 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3), { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
......
...@@ -684,7 +684,7 @@ static const struct i2c_algorithm xiic_algorithm = { ...@@ -684,7 +684,7 @@ static const struct i2c_algorithm xiic_algorithm = {
static struct i2c_adapter xiic_adapter = { static struct i2c_adapter xiic_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = DRIVER_NAME, .name = DRIVER_NAME,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED,
.algo = &xiic_algorithm, .algo = &xiic_algorithm,
}; };
......
...@@ -556,7 +556,7 @@ static struct platform_driver scx200_pci_driver = { ...@@ -556,7 +556,7 @@ static struct platform_driver scx200_pci_driver = {
.remove = scx200_remove, .remove = scx200_remove,
}; };
static DEFINE_PCI_DEVICE_TABLE(scx200_isa) = { static const struct pci_device_id scx200_isa[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
{ 0, } { 0, }
......
...@@ -48,10 +48,13 @@ ...@@ -48,10 +48,13 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/jump_label.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "i2c-core.h" #include "i2c-core.h"
#define CREATE_TRACE_POINTS
#include <trace/events/i2c.h>
/* core_lock protects i2c_adapter_idr, and guarantees /* core_lock protects i2c_adapter_idr, and guarantees
that device detection, deletion of detected devices, and attach_adapter that device detection, deletion of detected devices, and attach_adapter
...@@ -62,6 +65,18 @@ static DEFINE_IDR(i2c_adapter_idr); ...@@ -62,6 +65,18 @@ static DEFINE_IDR(i2c_adapter_idr);
static struct device_type i2c_client_type; static struct device_type i2c_client_type;
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
void i2c_transfer_trace_reg(void)
{
static_key_slow_inc(&i2c_trace_msg);
}
void i2c_transfer_trace_unreg(void)
{
static_key_slow_dec(&i2c_trace_msg);
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
...@@ -1686,6 +1701,7 @@ static void __exit i2c_exit(void) ...@@ -1686,6 +1701,7 @@ static void __exit i2c_exit(void)
class_compat_unregister(i2c_adapter_compat_class); class_compat_unregister(i2c_adapter_compat_class);
#endif #endif
bus_unregister(&i2c_bus_type); bus_unregister(&i2c_bus_type);
tracepoint_synchronize_unregister();
} }
/* We must initialize early, because some subsystems register i2c drivers /* We must initialize early, because some subsystems register i2c drivers
...@@ -1716,6 +1732,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1716,6 +1732,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
unsigned long orig_jiffies; unsigned long orig_jiffies;
int ret, try; int ret, try;
/* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
* enabled. This is an efficient way of keeping the for-loop from
* being executed when not needed.
*/
if (static_key_false(&i2c_trace_msg)) {
int i;
for (i = 0; i < num; i++)
if (msgs[i].flags & I2C_M_RD)
trace_i2c_read(adap, &msgs[i], i);
else
trace_i2c_write(adap, &msgs[i], i);
}
/* Retry automatically on arbitration loss */ /* Retry automatically on arbitration loss */
orig_jiffies = jiffies; orig_jiffies = jiffies;
for (ret = 0, try = 0; try <= adap->retries; try++) { for (ret = 0, try = 0; try <= adap->retries; try++) {
...@@ -1726,6 +1755,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1726,6 +1755,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
break; break;
} }
if (static_key_false(&i2c_trace_msg)) {
int i;
for (i = 0; i < ret; i++)
if (msgs[i].flags & I2C_M_RD)
trace_i2c_reply(adap, &msgs[i], i);
trace_i2c_result(adap, i, ret);
}
return ret; return ret;
} }
EXPORT_SYMBOL(__i2c_transfer); EXPORT_SYMBOL(__i2c_transfer);
...@@ -1941,6 +1978,13 @@ static int i2c_detect_address(struct i2c_client *temp_client, ...@@ -1941,6 +1978,13 @@ static int i2c_detect_address(struct i2c_client *temp_client,
struct i2c_client *client; struct i2c_client *client;
/* Detection succeeded, instantiate the device */ /* Detection succeeded, instantiate the device */
if (adapter->class & I2C_CLASS_DEPRECATED)
dev_warn(&adapter->dev,
"This adapter will soon drop class based instantiation of devices. "
"Please make sure client 0x%02x gets instantiated by other means. "
"Check 'Documentation/i2c/instantiating-devices' for details.\n",
info.addr);
dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n", dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
info.type, info.addr); info.type, info.addr);
client = i2c_new_device(adapter, &info); client = i2c_new_device(adapter, &info);
...@@ -2521,6 +2565,14 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, ...@@ -2521,6 +2565,14 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
int try; int try;
s32 res; s32 res;
/* If enabled, the following two tracepoints are conditional on
* read_write and protocol.
*/
trace_smbus_write(adapter, addr, flags, read_write,
command, protocol, data);
trace_smbus_read(adapter, addr, flags, read_write,
command, protocol);
flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
if (adapter->algo->smbus_xfer) { if (adapter->algo->smbus_xfer) {
...@@ -2541,15 +2593,24 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, ...@@ -2541,15 +2593,24 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
i2c_unlock_adapter(adapter); i2c_unlock_adapter(adapter);
if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
return res; goto trace;
/* /*
* Fall back to i2c_smbus_xfer_emulated if the adapter doesn't * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't
* implement native support for the SMBus operation. * implement native support for the SMBus operation.
*/ */
} }
return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
command, protocol, data);
trace:
/* If enabled, the reply tracepoint is conditional on read_write. */
trace_smbus_reply(adapter, addr, flags, read_write,
command, protocol, data); command, protocol, data);
trace_smbus_result(adapter, addr, flags, read_write,
command, protocol, res);
return res;
} }
EXPORT_SYMBOL(i2c_smbus_xfer); EXPORT_SYMBOL(i2c_smbus_xfer);
......
...@@ -487,6 +487,7 @@ void i2c_unlock_adapter(struct i2c_adapter *); ...@@ -487,6 +487,7 @@ void i2c_unlock_adapter(struct i2c_adapter *);
#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */
#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */
#define I2C_CLASS_SPD (1<<7) /* Memory modules */ #define I2C_CLASS_SPD (1<<7) /* Memory modules */
#define I2C_CLASS_DEPRECATED (1<<8) /* Warn users that adapter will stop using classes */
/* Internal numbers to terminate lists */ /* Internal numbers to terminate lists */
#define I2C_CLIENT_END 0xfffeU #define I2C_CLIENT_END 0xfffeU
......
/*
* i2c-bfin-twi.h - interface to ADI TWI controller
*
* Copyright 2005-2014 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef __I2C_BFIN_TWI_H__
#define __I2C_BFIN_TWI_H__
#include <linux/types.h>
#include <linux/i2c.h>
/*
* ADI twi registers layout
*/
struct bfin_twi_regs {
u16 clkdiv;
u16 dummy1;
u16 control;
u16 dummy2;
u16 slave_ctl;
u16 dummy3;
u16 slave_stat;
u16 dummy4;
u16 slave_addr;
u16 dummy5;
u16 master_ctl;
u16 dummy6;
u16 master_stat;
u16 dummy7;
u16 master_addr;
u16 dummy8;
u16 int_stat;
u16 dummy9;
u16 int_mask;
u16 dummy10;
u16 fifo_ctl;
u16 dummy11;
u16 fifo_stat;
u16 dummy12;
u32 __pad[20];
u16 xmt_data8;
u16 dummy13;
u16 xmt_data16;
u16 dummy14;
u16 rcv_data8;
u16 dummy15;
u16 rcv_data16;
u16 dummy16;
};
struct bfin_twi_iface {
int irq;
spinlock_t lock;
char read_write;
u8 command;
u8 *transPtr;
int readNum;
int writeNum;
int cur_mode;
int manual_stop;
int result;
struct i2c_adapter adap;
struct completion complete;
struct i2c_msg *pmsg;
int msg_num;
int cur_msg;
u16 saved_clkdiv;
u16 saved_control;
struct bfin_twi_regs __iomem *regs_base;
};
/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ********************/
/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
/* TWI_PRESCALE Masks */
#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
#define TWI_ENA 0x0080 /* TWI Enable */
#define SCCB 0x0200 /* SCCB Compatibility Enable */
/* TWI_SLAVE_CTL Masks */
#define SEN 0x0001 /* Slave Enable */
#define SADD_LEN 0x0002 /* Slave Address Length */
#define STDVAL 0x0004 /* Slave Transmit Data Valid */
#define NAK 0x0008 /* NAK Generated At Conclusion Of Transfer */
#define GEN 0x0010 /* General Call Address Matching Enabled */
/* TWI_SLAVE_STAT Masks */
#define SDIR 0x0001 /* Slave Transfer Direction (RX/TX*) */
#define GCALL 0x0002 /* General Call Indicator */
/* TWI_MASTER_CTL Masks */
#define MEN 0x0001 /* Master Mode Enable */
#define MADD_LEN 0x0002 /* Master Address Length */
#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
#define FAST 0x0008 /* Use Fast Mode Timing Specs */
#define STOP 0x0010 /* Issue Stop Condition */
#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
#define DCNT 0x3FC0 /* Data Bytes To Transfer */
#define SDAOVR 0x4000 /* Serial Data Override */
#define SCLOVR 0x8000 /* Serial Clock Override */
/* TWI_MASTER_STAT Masks */
#define MPROG 0x0001 /* Master Transfer In Progress */
#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
#define ANAK 0x0004 /* Address Not Acknowledged */
#define DNAK 0x0008 /* Data Not Acknowledged */
#define BUFRDERR 0x0010 /* Buffer Read Error */
#define BUFWRERR 0x0020 /* Buffer Write Error */
#define SDASEN 0x0040 /* Serial Data Sense */
#define SCLSEN 0x0080 /* Serial Clock Sense */
#define BUSBUSY 0x0100 /* Bus Busy Indicator */
/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
#define SINIT 0x0001 /* Slave Transfer Initiated */
#define SCOMP 0x0002 /* Slave Transfer Complete */
#define SERR 0x0004 /* Slave Transfer Error */
#define SOVF 0x0008 /* Slave Overflow */
#define MCOMP 0x0010 /* Master Transfer Complete */
#define MERR 0x0020 /* Master Transfer Error */
#define XMTSERV 0x0040 /* Transmit FIFO Service */
#define RCVSERV 0x0080 /* Receive FIFO Service */
/* TWI_FIFO_CTRL Masks */
#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
/* TWI_FIFO_STAT Masks */
#define XMTSTAT 0x0003 /* Transmit FIFO Status */
#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
#define RCVSTAT 0x000C /* Receive FIFO Status */
#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
#endif
/* arch/arm/plat-s3c/include/plat/iic.h /*
*
* Copyright 2004-2009 Simtec Electronics * Copyright 2004-2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk> * Ben Dooks <ben@simtec.co.uk>
* *
...@@ -10,8 +9,8 @@ ...@@ -10,8 +9,8 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#ifndef __ASM_ARCH_IIC_H #ifndef __I2C_S3C2410_H
#define __ASM_ARCH_IIC_H __FILE__ #define __I2C_S3C2410_H __FILE__
#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */ #define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */
...@@ -76,4 +75,4 @@ extern void s3c_i2c7_cfg_gpio(struct platform_device *dev); ...@@ -76,4 +75,4 @@ extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
extern struct s3c2410_platform_i2c default_i2c_data; extern struct s3c2410_platform_i2c default_i2c_data;
#endif /* __ASM_ARCH_IIC_H */ #endif /* __I2C_S3C2410_H */
This diff is collapsed.
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