Commit 29532455 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull i2c updates from Wolfram Sang:
 "Summary:

   - legacy PM code removed from the core, there were no users anymore
     (thanks to Lars-Peter Clausen)

   - new driver for Broadcom iProc

   - bigger driver updates for designware, rk3x, cadence, ocores

   - a bunch of smaller updates and bugfixes"

* 'i2c/for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (31 commits)
  i2c: ocores: rework clk code to handle NULL cookie
  i2c: designware-baytrail: another fixup for proper Kconfig dependencies
  i2c: fix reference to functionality constants definition
  i2c: iproc: Add Broadcom iProc I2C Driver
  i2c: designware-pci: update Intel copyright line
  i2c: ocores: add common clock support
  i2c: hix5hd2: add COMPILE_TEST
  i2c: clarify comments about the dev_released completion
  i2c: ocores: fix clock-frequency binding usage
  i2c: tegra: Maintain CPU endianness
  i2c: designware-baytrail: use proper Kconfig dependencies
  i2c: designware: Do not calculate SCL timing parameters needlessly
  i2c: do not try to load modules for of-registered devices
  i2c: designware: Add Intel Baytrail PMIC I2C bus support
  i2c: designware: Add i2c bus locking support
  of: i2c: Add i2c-mux-idle-disconnect DT property to PCA954x mux driver
  i2c: designware: use {readl|writel}_relaxed instead of readl/writel
  i2c: designware-pci: no need to provide clk_khz
  i2c: designware-pci: remove Moorestown support
  i2c: imx: whitespace and checkpatch cleanup
  ...
parents 18a8d499 0d8fb599
Broadcom iProc I2C controller
Required properties:
- compatible:
Must be "brcm,iproc-i2c"
- reg:
Define the base and range of the I/O address space that contain the iProc
I2C controller registers
- interrupts:
Should contain the I2C interrupt
- clock-frequency:
This is the I2C bus clock. Need to be either 100000 or 400000
- #address-cells:
Always 1 (for I2C addresses)
- #size-cells:
Always 0
Example:
i2c0: i2c@18008000 {
compatible = "brcm,iproc-i2c";
reg = <0x18008000 0x100>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
clock-frequency = <100000>;
codec: wm8750@1a {
compatible = "wlf,wm8750";
reg = <0x1a>;
};
};
......@@ -16,6 +16,9 @@ Required Properties:
Optional Properties:
- reset-gpios: Reference to the GPIO connected to the reset input.
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
Example:
......
......@@ -4,24 +4,60 @@ Required properties:
- compatible : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst"
- reg : bus address start and address range size of device
- interrupts : interrupt number
- clock-frequency : frequency of bus clock in Hz
- clocks : handle to the controller clock; see the note below.
Mutually exclusive with opencores,ip-clock-frequency
- opencores,ip-clock-frequency: frequency of the controller clock in Hz;
see the note below. Mutually exclusive with clocks
- #address-cells : should be <1>
- #size-cells : should be <0>
Optional properties:
- clock-frequency : frequency of bus clock in Hz; see the note below.
Defaults to 100 KHz when the property is not specified
- reg-shift : device register offsets are shifted by this value
- reg-io-width : io register width in bytes (1, 2 or 4)
- regstep : deprecated, use reg-shift above
Example:
Note
clock-frequency property is meant to control the bus frequency for i2c bus
drivers, but it was incorrectly used to specify i2c controller input clock
frequency. So the following rules are set to fix this situation:
- if clock-frequency is present and neither opencores,ip-clock-frequency nor
clocks are, then clock-frequency specifies i2c controller clock frequency.
This is to keep backwards compatibility with setups using old DTB. i2c bus
frequency is fixed at 100 KHz.
- if clocks is present it specifies i2c controller clock. clock-frequency
property specifies i2c bus frequency.
- if opencores,ip-clock-frequency is present it specifies i2c controller
clock frequency. clock-frequency property specifies i2c bus frequency.
Examples:
i2c0: ocores@a0000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
interrupts = <10>;
opencores,ip-clock-frequency = <20000000>;
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
dummy@60 {
compatible = "dummy";
reg = <0x60>;
};
};
or
i2c0: ocores@a0000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
interrupts = <10>;
clock-frequency = <20000000>;
clocks = <&osc>;
clock-frequency = <400000>; /* i2c bus frequency 400 KHz */
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
......
......@@ -21,6 +21,17 @@ Required on RK3066, RK3188 :
Optional properties :
- clock-frequency : SCL frequency to use (in Hz). If omitted, 100kHz is used.
- i2c-scl-rising-time-ns : Number of nanoseconds the SCL signal takes to rise
(t(r) in I2C specification). If not specified this is assumed to be
the maximum the specification allows(1000 ns for Standard-mode,
300 ns for Fast-mode) which might cause slightly slower communication.
- i2c-scl-falling-time-ns : Number of nanoseconds the SCL signal takes to fall
(t(f) in the I2C specification). If not specified this is assumed to
be the maximum the specification allows (300 ns) which might cause
slightly slower communication.
- i2c-sda-falling-time-ns : Number of nanoseconds the SDA signal takes to fall
(t(f) in the I2C specification). If not specified we'll use the SCL
value since they are the same in nearly all cases.
Example:
......@@ -39,4 +50,7 @@ i2c0: i2c@2002d000 {
clock-names = "i2c";
clocks = <&cru PCLK_I2C0>;
i2c-scl-rising-time-ns = <800>;
i2c-scl-falling-time-ns = <100>;
};
......@@ -61,9 +61,8 @@ fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec
gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
isl,isl12057 Intersil ISL12057 I2C RTC Chip
isil,isl29028 (deprecated, use isl)
isl,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
isil,isl12057 Intersil ISL12057 I2C RTC Chip
isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
......
......@@ -12,7 +12,7 @@ FUNCTIONALITY CONSTANTS
-----------------------
For the most up-to-date list of functionality constants, please check
<linux/i2c.h>!
<uapi/linux/i2c.h>!
I2C_FUNC_I2C Plain i2c-level commands (Pure SMBus
adapters typically can not do these)
......
......@@ -79,7 +79,7 @@ config I2C_AMD8111
config I2C_HIX5HD2
tristate "Hix5hd2 high-speed I2C driver"
depends on ARCH_HIX5HD2
depends on ARCH_HIX5HD2 || COMPILE_TEST
help
Say Y here to include support for high-speed I2C controller in the
Hisilicon based hix5hd2 SoCs.
......@@ -372,6 +372,16 @@ config I2C_BCM2835
This support is also available as a module. If so, the module
will be called i2c-bcm2835.
config I2C_BCM_IPROC
tristate "Broadcom iProc I2C controller"
depends on ARCH_BCM_IPROC || COMPILE_TEST
default ARCH_BCM_IPROC
help
If you say yes to this option, support will be included for the
Broadcom iProc I2C controller.
If you don't know what to do here, say N.
config I2C_BCM_KONA
tristate "BCM Kona I2C adapter"
depends on ARCH_BCM_MOBILE
......@@ -465,6 +475,16 @@ config I2C_DESIGNWARE_PCI
This driver can also be built as a module. If so, the module
will be called i2c-designware-pci.
config I2C_DESIGNWARE_BAYTRAIL
bool "Intel Baytrail I2C semaphore support"
depends on I2C_DESIGNWARE_PLATFORM && IOSF_MBI=y && ACPI
help
This driver enables managed host access to the PMIC I2C bus on select
Intel BayTrail platforms using the X-Powers AXP288 PMIC. It allows
the host to request uninterrupted access to the PMIC's I2C bus from
the platform firmware controlling it. You should say Y if running on
a BayTrail system using the AXP288.
config I2C_EFM32
tristate "EFM32 I2C controller"
depends on ARCH_EFM32 || COMPILE_TEST
......
......@@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_AXXIA) += i2c-axxia.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
obj-$(CONFIG_I2C_BCM_IPROC) += i2c-bcm-iproc.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
......@@ -41,6 +42,7 @@ obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o
obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
i2c-designware-platform-objs := i2c-designware-platdrv.o
i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o
obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
i2c-designware-pci-objs := i2c-designware-pcidrv.o
obj-$(CONFIG_I2C_EFM32) += i2c-efm32.o
......
/*
* Copyright (C) 2014 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#define CFG_OFFSET 0x00
#define CFG_RESET_SHIFT 31
#define CFG_EN_SHIFT 30
#define CFG_M_RETRY_CNT_SHIFT 16
#define CFG_M_RETRY_CNT_MASK 0x0f
#define TIM_CFG_OFFSET 0x04
#define TIM_CFG_MODE_400_SHIFT 31
#define M_FIFO_CTRL_OFFSET 0x0c
#define M_FIFO_RX_FLUSH_SHIFT 31
#define M_FIFO_TX_FLUSH_SHIFT 30
#define M_FIFO_RX_CNT_SHIFT 16
#define M_FIFO_RX_CNT_MASK 0x7f
#define M_FIFO_RX_THLD_SHIFT 8
#define M_FIFO_RX_THLD_MASK 0x3f
#define M_CMD_OFFSET 0x30
#define M_CMD_START_BUSY_SHIFT 31
#define M_CMD_STATUS_SHIFT 25
#define M_CMD_STATUS_MASK 0x07
#define M_CMD_STATUS_SUCCESS 0x0
#define M_CMD_STATUS_LOST_ARB 0x1
#define M_CMD_STATUS_NACK_ADDR 0x2
#define M_CMD_STATUS_NACK_DATA 0x3
#define M_CMD_STATUS_TIMEOUT 0x4
#define M_CMD_PROTOCOL_SHIFT 9
#define M_CMD_PROTOCOL_MASK 0xf
#define M_CMD_PROTOCOL_BLK_WR 0x7
#define M_CMD_PROTOCOL_BLK_RD 0x8
#define M_CMD_PEC_SHIFT 8
#define M_CMD_RD_CNT_SHIFT 0
#define M_CMD_RD_CNT_MASK 0xff
#define IE_OFFSET 0x38
#define IE_M_RX_FIFO_FULL_SHIFT 31
#define IE_M_RX_THLD_SHIFT 30
#define IE_M_START_BUSY_SHIFT 28
#define IS_OFFSET 0x3c
#define IS_M_RX_FIFO_FULL_SHIFT 31
#define IS_M_RX_THLD_SHIFT 30
#define IS_M_START_BUSY_SHIFT 28
#define M_TX_OFFSET 0x40
#define M_TX_WR_STATUS_SHIFT 31
#define M_TX_DATA_SHIFT 0
#define M_TX_DATA_MASK 0xff
#define M_RX_OFFSET 0x44
#define M_RX_STATUS_SHIFT 30
#define M_RX_STATUS_MASK 0x03
#define M_RX_PEC_ERR_SHIFT 29
#define M_RX_DATA_SHIFT 0
#define M_RX_DATA_MASK 0xff
#define I2C_TIMEOUT_MESC 100
#define M_TX_RX_FIFO_SIZE 64
enum bus_speed_index {
I2C_SPD_100K = 0,
I2C_SPD_400K,
};
struct bcm_iproc_i2c_dev {
struct device *device;
int irq;
void __iomem *base;
struct i2c_adapter adapter;
struct completion done;
int xfer_is_done;
};
/*
* Can be expanded in the future if more interrupt status bits are utilized
*/
#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT)
static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data)
{
struct bcm_iproc_i2c_dev *iproc_i2c = data;
u32 status = readl(iproc_i2c->base + IS_OFFSET);
status &= ISR_MASK;
if (!status)
return IRQ_NONE;
writel(status, iproc_i2c->base + IS_OFFSET);
iproc_i2c->xfer_is_done = 1;
complete_all(&iproc_i2c->done);
return IRQ_HANDLED;
}
static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c,
struct i2c_msg *msg)
{
u32 val;
val = readl(iproc_i2c->base + M_CMD_OFFSET);
val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK;
switch (val) {
case M_CMD_STATUS_SUCCESS:
return 0;
case M_CMD_STATUS_LOST_ARB:
dev_dbg(iproc_i2c->device, "lost bus arbitration\n");
return -EAGAIN;
case M_CMD_STATUS_NACK_ADDR:
dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr);
return -ENXIO;
case M_CMD_STATUS_NACK_DATA:
dev_dbg(iproc_i2c->device, "NAK data\n");
return -ENXIO;
case M_CMD_STATUS_TIMEOUT:
dev_dbg(iproc_i2c->device, "bus timeout\n");
return -ETIMEDOUT;
default:
dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val);
return -EIO;
}
}
static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
struct i2c_msg *msg)
{
int ret, i;
u8 addr;
u32 val;
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC);
/* need to reserve one byte in the FIFO for the slave address */
if (msg->len > M_TX_RX_FIFO_SIZE - 1) {
dev_err(iproc_i2c->device,
"only support data length up to %u bytes\n",
M_TX_RX_FIFO_SIZE - 1);
return -EOPNOTSUPP;
}
/* check if bus is busy */
if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) &
BIT(M_CMD_START_BUSY_SHIFT))) {
dev_warn(iproc_i2c->device, "bus is busy\n");
return -EBUSY;
}
/* format and load slave address into the TX FIFO */
addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0);
writel(addr, iproc_i2c->base + M_TX_OFFSET);
/* for a write transaction, load data into the TX FIFO */
if (!(msg->flags & I2C_M_RD)) {
for (i = 0; i < msg->len; i++) {
val = msg->buf[i];
/* mark the last byte */
if (i == msg->len - 1)
val |= 1 << M_TX_WR_STATUS_SHIFT;
writel(val, iproc_i2c->base + M_TX_OFFSET);
}
}
/* mark as incomplete before starting the transaction */
reinit_completion(&iproc_i2c->done);
iproc_i2c->xfer_is_done = 0;
/*
* Enable the "start busy" interrupt, which will be triggered after the
* transaction is done, i.e., the internal start_busy bit, transitions
* from 1 to 0.
*/
writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET);
/*
* Now we can activate the transfer. For a read operation, specify the
* number of bytes to read
*/
val = 1 << M_CMD_START_BUSY_SHIFT;
if (msg->flags & I2C_M_RD) {
val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) |
(msg->len << M_CMD_RD_CNT_SHIFT);
} else {
val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT);
}
writel(val, iproc_i2c->base + M_CMD_OFFSET);
time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left);
/* disable all interrupts */
writel(0, iproc_i2c->base + IE_OFFSET);
/* read it back to flush the write */
readl(iproc_i2c->base + IE_OFFSET);
/* make sure the interrupt handler isn't running */
synchronize_irq(iproc_i2c->irq);
if (!time_left && !iproc_i2c->xfer_is_done) {
dev_err(iproc_i2c->device, "transaction timed out\n");
/* flush FIFOs */
val = (1 << M_FIFO_RX_FLUSH_SHIFT) |
(1 << M_FIFO_TX_FLUSH_SHIFT);
writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET);
return -ETIMEDOUT;
}
ret = bcm_iproc_i2c_check_status(iproc_i2c, msg);
if (ret) {
/* flush both TX/RX FIFOs */
val = (1 << M_FIFO_RX_FLUSH_SHIFT) |
(1 << M_FIFO_TX_FLUSH_SHIFT);
writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET);
return ret;
}
/*
* For a read operation, we now need to load the data from FIFO
* into the memory buffer
*/
if (msg->flags & I2C_M_RD) {
for (i = 0; i < msg->len; i++) {
msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >>
M_RX_DATA_SHIFT) & M_RX_DATA_MASK;
}
}
return 0;
}
static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num)
{
struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter);
int ret, i;
/* go through all messages */
for (i = 0; i < num; i++) {
ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]);
if (ret) {
dev_dbg(iproc_i2c->device, "xfer failed\n");
return ret;
}
}
return num;
}
static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm bcm_iproc_algo = {
.master_xfer = bcm_iproc_i2c_xfer,
.functionality = bcm_iproc_i2c_functionality,
};
static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c)
{
unsigned int bus_speed;
u32 val;
int ret = of_property_read_u32(iproc_i2c->device->of_node,
"clock-frequency", &bus_speed);
if (ret < 0) {
dev_info(iproc_i2c->device,
"unable to interpret clock-frequency DT property\n");
bus_speed = 100000;
}
if (bus_speed < 100000) {
dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n",
bus_speed);
dev_err(iproc_i2c->device,
"valid speeds are 100khz and 400khz\n");
return -EINVAL;
} else if (bus_speed < 400000) {
bus_speed = 100000;
} else {
bus_speed = 400000;
}
val = readl(iproc_i2c->base + TIM_CFG_OFFSET);
val &= ~(1 << TIM_CFG_MODE_400_SHIFT);
val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT;
writel(val, iproc_i2c->base + TIM_CFG_OFFSET);
dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed);
return 0;
}
static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c)
{
u32 val;
/* put controller in reset */
val = readl(iproc_i2c->base + CFG_OFFSET);
val |= 1 << CFG_RESET_SHIFT;
val &= ~(1 << CFG_EN_SHIFT);
writel(val, iproc_i2c->base + CFG_OFFSET);
/* wait 100 usec per spec */
udelay(100);
/* bring controller out of reset */
val &= ~(1 << CFG_RESET_SHIFT);
writel(val, iproc_i2c->base + CFG_OFFSET);
/* flush TX/RX FIFOs and set RX FIFO threshold to zero */
val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT);
writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET);
/* disable all interrupts */
writel(0, iproc_i2c->base + IE_OFFSET);
/* clear all pending interrupts */
writel(0xffffffff, iproc_i2c->base + IS_OFFSET);
return 0;
}
static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c,
bool enable)
{
u32 val;
val = readl(iproc_i2c->base + CFG_OFFSET);
if (enable)
val |= BIT(CFG_EN_SHIFT);
else
val &= ~BIT(CFG_EN_SHIFT);
writel(val, iproc_i2c->base + CFG_OFFSET);
}
static int bcm_iproc_i2c_probe(struct platform_device *pdev)
{
int irq, ret = 0;
struct bcm_iproc_i2c_dev *iproc_i2c;
struct i2c_adapter *adap;
struct resource *res;
iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c),
GFP_KERNEL);
if (!iproc_i2c)
return -ENOMEM;
platform_set_drvdata(pdev, iproc_i2c);
iproc_i2c->device = &pdev->dev;
init_completion(&iproc_i2c->done);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res);
if (IS_ERR(iproc_i2c->base))
return PTR_ERR(iproc_i2c->base);
ret = bcm_iproc_i2c_init(iproc_i2c);
if (ret)
return ret;
ret = bcm_iproc_i2c_cfg_speed(iproc_i2c);
if (ret)
return ret;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(iproc_i2c->device, "no irq resource\n");
return irq;
}
iproc_i2c->irq = irq;
ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0,