Commit 52caa59e 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:
 "Highlights:

   - new drivers for Intel ismt & Broadcom bcm2835
   - a number of drivers got support for more variants and mostly got
     cleaned up on the way (sis630, i801, at91, tegra, designware)
   - i2c got rid of all *_set_drvdata(..., NULL) on remove/probe failure
   - removed the i2c_smbus_process_call from the core since there are no
     users
   - mxs can now switch between PIO and DMA depending on the message
     size and the bus speed can now be arbitrary

  In addition, there is the usual bunch of fixes, cleanups, devm_*
  conversions, etc"

Fixed conflict (and buggy devm_* conversion) in i2c-s3c2410.c

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (39 commits)
  i2c: Remove unneeded xxx_set_drvdata(..., NULL) calls
  i2c: pxa: remove incorrect __exit annotations
  i2c: ocores: Fix pointer to integer cast warning
  i2c: tegra: remove warning dump if timeout happen in transfer
  i2c: fix i2c-ismt.c printk format warning
  i2c: i801: Add Device IDs for Intel Wellsburg PCH
  i2c: add bcm2835 driver
  i2c: ismt: Add Seth and Myself as maintainers
  i2c: sis630: checkpatch cleanup
  i2c: sis630: display unsigned hex
  i2c: sis630: use hex to constants for SMBus commands
  i2c: sis630: fix behavior after collision
  i2c: sis630: clear sticky bits
  i2c: sis630: Add SIS964 support
  i2c: isch: Add module parameter for backbone clock rate if divider is unset
  i2c: at91: fix unsed variable warning when building with !CONFIG_OF
  i2c: Adding support for Intel iSMT SMBus 2.0 host controller
  i2c: sh_mobile: don't send a stop condition by default inside transfers
  i2c: sh_mobile: eliminate an open-coded "goto" loop
  i2c: sh_mobile: fix timeout error handling
  ...
parents 4c8c225a 55827f4a
Broadcom BCM2835 I2C controller
Required properties:
- compatible : Should be "brcm,bcm2835-i2c".
- reg: Should contain register location and length.
- interrupts: Should contain interrupt.
- clocks : The clock feeding the I2C controller.
Recommended properties:
- clock-frequency : desired I2C bus clock frequency in Hz.
Example:
i2c@20205000 {
compatible = "brcm,bcm2835-i2c";
reg = <0x7e205000 0x1000>;
interrupts = <2 21>;
clocks = <&clk_i2c>;
clock-frequency = <100000>;
};
......@@ -8,6 +8,8 @@ Required properties:
(b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c.
(c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used
inside HDMIPHY block found on several samsung SoCs
(d) "samsung, exynos5440-i2c", for s3c2440-like i2c used
on EXYNOS5440 which does not need GPIO configuration.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
......
......@@ -22,6 +22,8 @@ Supported adapters:
* Intel Panther Point (PCH)
* Intel Lynx Point (PCH)
* Intel Lynx Point-LP (PCH)
* Intel Avoton (SOC)
* Intel Wellsburg (PCH)
Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller
......
Kernel driver i2c-ismt
Supported adapters:
* Intel S12xx series SOCs
Authors:
Bill Brown <bill.e.brown@intel.com>
Module Parameters
-----------------
* bus_speed (unsigned int)
Allows changing of the bus speed. Normally, the bus speed is set by the BIOS
and never needs to be changed. However, some SMBus analyzers are too slow for
monitoring the bus during debug, thus the need for this module parameter.
Specify the bus speed in kHz.
Available bus frequency settings:
0 no change
80 kHz
100 kHz
400 kHz
1000 kHz
Description
-----------
The S12xx series of SOCs have a pair of integrated SMBus 2.0 controllers
targeted primarily at the microserver and storage markets.
The S12xx series contain a pair of PCI functions. An output of lspci will show
something similar to the following:
00:13.0 System peripheral: Intel Corporation Centerton SMBus 2.0 Controller 0
00:13.1 System peripheral: Intel Corporation Centerton SMBus 2.0 Controller 1
......@@ -4,9 +4,11 @@ Supported adapters:
* Silicon Integrated Systems Corp (SiS)
630 chipset (Datasheet: available at http://www.sfr-fresh.com/linux)
730 chipset
964 chipset
* Possible other SiS chipsets ?
Author: Alexander Malysh <amalysh@web.de>
Amaury Decrême <amaury.decreme@gmail.com> - SiS964 support
Module Parameters
-----------------
......@@ -18,6 +20,7 @@ Module Parameters
* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default,
what your BIOS use). DANGEROUS! This should be a bit
faster, but freeze some systems (i.e. my Laptop).
SIS630/730 chip only.
Description
......@@ -36,6 +39,12 @@ or like this:
00:00.0 Host bridge: Silicon Integrated Systems [SiS] 730 Host (rev 02)
00:01.0 ISA bridge: Silicon Integrated Systems [SiS] 85C503/5513
or like this:
00:00.0 Host bridge: Silicon Integrated Systems [SiS] 760/M760 Host (rev 02)
00:02.0 ISA bridge: Silicon Integrated Systems [SiS] SiS964 [MuTIOL Media IO]
LPC Controller (rev 36)
in your 'lspci' output , then this driver is for your chipset.
Thank You
......
......@@ -137,8 +137,8 @@ available for writes where the two data bytes are the other way
around (not SMBus compliant, but very popular.)
SMBus Process Call: i2c_smbus_process_call()
=============================================
SMBus Process Call:
===================
This command selects a device register (through the Comm byte), sends
16 bits of data to it, and reads 16 bits of data in return.
......
......@@ -365,8 +365,6 @@ in terms of it. Never use this function directly!
s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
s32 i2c_smbus_write_word_data(struct i2c_client *client,
u8 command, u16 value);
s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
s32 i2c_smbus_read_block_data(struct i2c_client *client,
u8 command, u8 *values);
s32 i2c_smbus_write_block_data(struct i2c_client *client,
......@@ -381,6 +379,8 @@ These ones were removed from i2c-core because they had no users, but could
be added back later if needed:
s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value);
s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
s32 i2c_smbus_block_process_call(struct i2c_client *client,
u8 command, u8 length, u8 *values);
......
......@@ -3852,6 +3852,13 @@ F: drivers/i2c/busses/i2c-sis96x.c
F: drivers/i2c/busses/i2c-via.c
F: drivers/i2c/busses/i2c-viapro.c
I2C/SMBUS ISMT DRIVER
M: Seth Heasley <seth.heasley@intel.com>
M: Neil Horman <nhorman@tuxdriver.com>
L: linux-i2c@vger.kernel.org
F: drivers/i2c/busses/i2c-ismt.c
F: Documentation/i2c/busses/i2c-ismt
I2C/SMBUS STUB DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
L: linux-i2c@vger.kernel.org
......
......@@ -106,6 +106,8 @@ config I2C_I801
Panther Point (PCH)
Lynx Point (PCH)
Lynx Point-LP (PCH)
Avoton (SOC)
Wellsburg (PCH)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
......@@ -121,6 +123,16 @@ config I2C_ISCH
This driver can also be built as a module. If so, the module
will be called i2c-isch.
config I2C_ISMT
tristate "Intel iSMT SMBus Controller"
depends on PCI && X86
help
If you say yes to this option, support will be included for the Intel
iSMT SMBus host controller interface.
This driver can also be built as a module. If so, the module will be
called i2c-ismt.
config I2C_PIIX4
tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)"
depends on PCI
......@@ -186,11 +198,11 @@ config I2C_SIS5595
will be called i2c-sis5595.
config I2C_SIS630
tristate "SiS 630/730"
tristate "SiS 630/730/964"
depends on PCI
help
If you say yes to this option, support will be included for the
SiS630 and SiS730 SMBus (a subset of I2C) interface.
SiS630, SiS730 and SiS964 SMBus (a subset of I2C) interface.
This driver can also be built as a module. If so, the module
will be called i2c-sis630.
......@@ -319,6 +331,18 @@ config I2C_AU1550
This driver can also be built as a module. If so, the module
will be called i2c-au1550.
config I2C_BCM2835
tristate "Broadcom BCM2835 I2C controller"
depends on ARCH_BCM2835
help
If you say yes to this option, support will be included for the
BCM2835 I2C controller.
If you don't know what to do here, say N.
This support is also available as a module. If so, the module
will be called i2c-bcm2835.
config I2C_BLACKFIN_TWI
tristate "Blackfin TWI I2C support"
depends on BLACKFIN
......
......@@ -14,6 +14,7 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_ISCH) += i2c-isch.o
obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o
obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o
obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
......@@ -30,6 +31,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
# Embedded system I2C/SMBus host controller drivers
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
......
......@@ -553,13 +553,6 @@ static struct at91_twi_pdata at91sam9g10_config = {
.has_dma_support = false,
};
static struct at91_twi_pdata at91sam9x5_config = {
.clk_max_div = 7,
.clk_offset = 4,
.has_unre_flag = false,
.has_dma_support = true,
};
static const struct platform_device_id at91_twi_devtypes[] = {
{
.name = "i2c-at91rm9200",
......@@ -582,8 +575,18 @@ static const struct platform_device_id at91_twi_devtypes[] = {
};
#if defined(CONFIG_OF)
static struct at91_twi_pdata at91sam9x5_config = {
.clk_max_div = 7,
.clk_offset = 4,
.has_unre_flag = false,
.has_dma_support = true,
};
static const struct of_device_id atmel_twi_dt_ids[] = {
{
.compatible = "atmel,at91rm9200-i2c",
.data = &at91rm9200_config,
} , {
.compatible = "atmel,at91sam9260-i2c",
.data = &at91sam9260_config,
} , {
......
......@@ -376,7 +376,6 @@ static int i2c_au1550_remove(struct platform_device *pdev)
{
struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&priv->adap);
i2c_au1550_disable(priv);
iounmap(priv->psc_base);
......
/*
* BCM2835 master mode driver
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#define BCM2835_I2C_C 0x0
#define BCM2835_I2C_S 0x4
#define BCM2835_I2C_DLEN 0x8
#define BCM2835_I2C_A 0xc
#define BCM2835_I2C_FIFO 0x10
#define BCM2835_I2C_DIV 0x14
#define BCM2835_I2C_DEL 0x18
#define BCM2835_I2C_CLKT 0x1c
#define BCM2835_I2C_C_READ BIT(0)
#define BCM2835_I2C_C_CLEAR BIT(4) /* bits 4 and 5 both clear */
#define BCM2835_I2C_C_ST BIT(7)
#define BCM2835_I2C_C_INTD BIT(8)
#define BCM2835_I2C_C_INTT BIT(9)
#define BCM2835_I2C_C_INTR BIT(10)
#define BCM2835_I2C_C_I2CEN BIT(15)
#define BCM2835_I2C_S_TA BIT(0)
#define BCM2835_I2C_S_DONE BIT(1)
#define BCM2835_I2C_S_TXW BIT(2)
#define BCM2835_I2C_S_RXR BIT(3)
#define BCM2835_I2C_S_TXD BIT(4)
#define BCM2835_I2C_S_RXD BIT(5)
#define BCM2835_I2C_S_TXE BIT(6)
#define BCM2835_I2C_S_RXF BIT(7)
#define BCM2835_I2C_S_ERR BIT(8)
#define BCM2835_I2C_S_CLKT BIT(9)
#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */
#define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000))
struct bcm2835_i2c_dev {
struct device *dev;
void __iomem *regs;
struct clk *clk;
int irq;
struct i2c_adapter adapter;
struct completion completion;
u32 msg_err;
u8 *msg_buf;
size_t msg_buf_remaining;
};
static inline void bcm2835_i2c_writel(struct bcm2835_i2c_dev *i2c_dev,
u32 reg, u32 val)
{
writel(val, i2c_dev->regs + reg);
}
static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg)
{
return readl(i2c_dev->regs + reg);
}
static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev)
{
u32 val;
while (i2c_dev->msg_buf_remaining) {
val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S);
if (!(val & BCM2835_I2C_S_TXD))
break;
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_FIFO,
*i2c_dev->msg_buf);
i2c_dev->msg_buf++;
i2c_dev->msg_buf_remaining--;
}
}
static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev)
{
u32 val;
while (i2c_dev->msg_buf_remaining) {
val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S);
if (!(val & BCM2835_I2C_S_RXD))
break;
*i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev,
BCM2835_I2C_FIFO);
i2c_dev->msg_buf++;
i2c_dev->msg_buf_remaining--;
}
}
static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data)
{
struct bcm2835_i2c_dev *i2c_dev = data;
u32 val, err;
val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, val);
err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR);
if (err) {
i2c_dev->msg_err = err;
complete(&i2c_dev->completion);
return IRQ_HANDLED;
}
if (val & BCM2835_I2C_S_RXD) {
bcm2835_drain_rxfifo(i2c_dev);
if (!(val & BCM2835_I2C_S_DONE))
return IRQ_HANDLED;
}
if (val & BCM2835_I2C_S_DONE) {
if (i2c_dev->msg_buf_remaining)
i2c_dev->msg_err = BCM2835_I2C_S_LEN;
else
i2c_dev->msg_err = 0;
complete(&i2c_dev->completion);
return IRQ_HANDLED;
}
if (val & BCM2835_I2C_S_TXD) {
bcm2835_fill_txfifo(i2c_dev);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,
struct i2c_msg *msg)
{
u32 c;
int time_left;
i2c_dev->msg_buf = msg->buf;
i2c_dev->msg_buf_remaining = msg->len;
INIT_COMPLETION(i2c_dev->completion);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR);
if (msg->flags & I2C_M_RD) {
c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR;
} else {
c = BCM2835_I2C_C_INTT;
bcm2835_fill_txfifo(i2c_dev);
}
c |= BCM2835_I2C_C_ST | BCM2835_I2C_C_INTD | BCM2835_I2C_C_I2CEN;
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c);
time_left = wait_for_completion_timeout(&i2c_dev->completion,
BCM2835_I2C_TIMEOUT);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR);
if (!time_left) {
dev_err(i2c_dev->dev, "i2c transfer timed out\n");
return -ETIMEDOUT;
}
if (likely(!i2c_dev->msg_err))
return 0;
if ((i2c_dev->msg_err & BCM2835_I2C_S_ERR) &&
(msg->flags & I2C_M_IGNORE_NAK))
return 0;
dev_err(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err);
if (i2c_dev->msg_err & BCM2835_I2C_S_ERR)
return -EREMOTEIO;
else
return -EIO;
}
static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
int num)
{
struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
int i;
int ret = 0;
for (i = 0; i < num; i++) {
ret = bcm2835_i2c_xfer_msg(i2c_dev, &msgs[i]);
if (ret)
break;
}
return ret ?: i;
}
static u32 bcm2835_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm bcm2835_i2c_algo = {
.master_xfer = bcm2835_i2c_xfer,
.functionality = bcm2835_i2c_func,
};
static int bcm2835_i2c_probe(struct platform_device *pdev)
{
struct bcm2835_i2c_dev *i2c_dev;
struct resource *mem, *requested, *irq;
u32 bus_clk_rate, divider;
int ret;
struct i2c_adapter *adap;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev) {
dev_err(&pdev->dev, "Cannot allocate i2c_dev\n");
return -ENOMEM;
}
platform_set_drvdata(pdev, i2c_dev);
i2c_dev->dev = &pdev->dev;
init_completion(&i2c_dev->completion);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "No mem resource\n");
return -ENODEV;
}
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);
if (IS_ERR(i2c_dev->clk)) {
dev_err(&pdev->dev, "Could not get clock\n");
return PTR_ERR(i2c_dev->clk);
}
ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
&bus_clk_rate);
if (ret < 0) {
dev_warn(&pdev->dev,
"Could not read clock-frequency property\n");
bus_clk_rate = 100000;
}
divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate);
/*
* Per the datasheet, the register is always interpreted as an even
* number, by rounding down. In other words, the LSB is ignored. So,
* if the LSB is set, increment the divider to avoid any issue.
*/
if (divider & 1)
divider++;
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "No IRQ resource\n");
return -ENODEV;
}
i2c_dev->irq = irq->start;
ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED,
dev_name(&pdev->dev), i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Could not request IRQ\n");
return -ENODEV;
}
adap = &i2c_dev->adapter;
i2c_set_adapdata(adap, i2c_dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));
adap->algo = &bcm2835_i2c_algo;
adap->dev.parent = &pdev->dev;
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
ret = i2c_add_adapter(adap);
if (ret)
free_irq(i2c_dev->irq, i2c_dev);
return ret;
}
static int bcm2835_i2c_remove(struct platform_device *pdev)
{
struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
free_irq(i2c_dev->irq, i2c_dev);
i2c_del_adapter(&i2c_dev->adapter);
return 0;
}
static const struct of_device_id bcm2835_i2c_of_match[] = {
{ .compatible = "brcm,bcm2835-i2c" },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match);
static struct platform_driver bcm2835_i2c_driver = {
.probe = bcm2835_i2c_probe,
.remove = bcm2835_i2c_remove,
.driver = {
.name = "i2c-bcm2835",
.owner = THIS_MODULE,
.of_match_table = bcm2835_i2c_of_match,
},
};
module_platform_driver(bcm2835_i2c_driver);
MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
MODULE_DESCRIPTION("BCM2835 I2C bus adapter");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:i2c-bcm2835");
......@@ -724,8 +724,6 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
{
struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&(iface->adap));
free_irq(iface->irq, iface);
peripheral_free_list((unsigned short *)pdev->dev.platform_data);
......
......@@ -682,7 +682,6 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
out_shut:
cpm_i2c_shutdown(cpm);
out_free:
dev_set_drvdata(&ofdev->dev, NULL);
kfree(cpm);
return result;
......@@ -696,7 +695,6 @@ static int cpm_i2c_remove(struct platform_device *ofdev)
cpm_i2c_shutdown(cpm);
dev_set_drvdata(&ofdev->dev, NULL);
kfree(cpm);
return 0;
......
......@@ -755,7 +755,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
clk_put(dev->clk);
dev->clk = NULL;
err_free_mem:
platform_set_drvdata(pdev, NULL);
put_device(&pdev->dev);
kfree(dev);
err_release_region:
......@@ -771,7 +770,6 @@ static int davinci_i2c_remove(struct platform_device *pdev)
i2c_davinci_cpufreq_deregister(dev);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
......
......@@ -413,11 +413,23 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
u32 cmd = 0;
/*
* If IC_EMPTYFIFO_HOLD_MASTER_EN is set we must
* manually set the stop bit. However, it cannot be
* detected from the registers so we set it always
* when writing/reading the last byte.
*/
if (dev->msg_write_idx == dev->msgs_num - 1 &&
buf_len == 1)
cmd |= BIT(9);
if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
dw_writel(dev, 0x100, DW_IC_DATA_CMD);
dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);
rx_limit--;
} else
dw_writel(dev, *buf++, DW_IC_DATA_CMD);
dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD);
tx_limit--; buf_len--;
}
......
......@@ -319,7 +319,6 @@ const struct pci_device_id *id)
free_irq(pdev->irq, dev);
err_iounmap:
iounmap(dev->base);
pci_set_drvdata(pdev, NULL);
put_device(&pdev->dev);
kfree(dev);
err_release_region:
......@@ -336,7 +335,6 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
pm_runtime_forbid(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
pci_set_drvdata(pdev, NULL);
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
......
......@@ -37,8 +37,10 @@
#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include "i2c-designware-core.h"
static struct i2c_algorithm i2c_dw_algo = {
......@@ -50,6 +52,42 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
return clk_get_rate(dev->clk)/1000;
}
#ifdef CONFIG_ACPI
static int dw_i2c_acpi_configure(struct platform_device *pdev)
{
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
struct acpi_device *adev;
int busno, ret;
if (!ACPI_HANDLE(&pdev->dev))
return -ENODEV;
ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev);
if (ret)
return -ENODEV;
dev->adapter.nr = -1;
if (adev->pnp.unique_id && !kstrtoint(adev->pnp.unique_id, 0, &busno))
dev->adapter.nr = busno;
dev->tx_fifo_depth = 32;
dev->rx_fifo_depth = 32;
return 0;
}
static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT33C2", 0 },
{ "INT33C3", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
#else
static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
{
return -ENODEV;
}
#endif
static int dw_i2c_probe(struct platform_device *pdev)
{
struct dw_i2c_dev *dev;
......@@ -114,18 +152,22 @@ static int dw_i2c_probe(struct platform_device *pdev)
r = -EBUSY;
goto err_unuse_clocks;
}
{
/* Try first if we can configure the device from ACPI */
r = dw_i2c_acpi_configure(pdev);
if (r) {
u32 param1 = i2c_dw_read_comp_param(dev);
dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
dev->adapter.nr = pdev->id;
}
r = i2c_dw_init(dev);
if (r)
goto err_iounmap;
i2c_dw_disable_int(dev);
r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
r = request_irq(dev->irq, i2c_dw_isr, IRQF_SHARED, pdev->name, dev);
if (r) {
dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
goto err_iounmap;
......@@ -140,14 +182,19 @@ static int dw_i2c_probe(struct platform_device *pdev)
adap->algo = &i2c_dw_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
ACPI_HANDLE_SET(&adap->dev, ACPI_HANDLE(&pdev->dev));
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(&pdev->dev, "failure adding adapter\n");
goto err_free_irq;
}
of_i2c_register_devices(adap);
acpi_i2c_register_devices(adap);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_put(&pdev->dev);
return 0;
......@@ -160,7 +207,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
clk_put(dev->clk);
dev->clk = NULL;
err_free_mem:
platform_set_drvdata(pdev, NULL);
put_device(&pdev->dev);
kfree(dev);
err_release_region:
......@@ -174,7 +220,8 @@ static int dw_i2c_remove(struct platform_device *pdev)
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
platform_set_drvdata(pdev, NULL);
pm_runtime_get_sync(&pdev->dev);
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
......@@ -186,6 +233,9 @@ static int dw_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev);
kfree(dev);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
return 0;
......@@ -233,6 +283,7 @@ static struct platform_driver dw_i2c_driver = {
.name = "i2c_designware",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(dw_i2c_of_match),
.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
.pm = &dw_i2c_dev_pm_ops,
},
};
......
......@@ -869,8 +869,6 @@ static void pch_i2c_remove(struct pci_dev *pdev)
for (i = 0; i < adap_info->ch_num; i++)
adap_info->pch_data[i].pch_base_address = NULL;
pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
......
......@@ -436,8 +436,6 @@ static int highlander_i2c_probe(struct platform_device *pdev)
err:
kfree(dev);
platform_set_drvdata(pdev, NULL);
return ret;
}
......@@ -453,8 +451,6 @@ static int highlander_i2c_remove(struct platform_device *pdev)
iounmap(dev->base);
kfree(dev);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -53,6 +53,11 @@
Panther Point (PCH) 0x1e22 32 hard yes yes yes
Lynx Point (PCH) 0x8c22 32 hard yes yes yes
Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes
Avoton (SOC) 0x1f3c 32 hard yes yes yes
Wellsburg (PCH) 0x8d22 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
Features supported by this driver:
Software PEC no
......@@ -162,9 +167,14 @@
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c
#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0 0x8d7d
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
struct i801_mux_config {
......@@ -798,6 +808,11 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
{ 0, }
};
......@@ -1103,6 +1118,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0:
case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1:
case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2:
priv->features |= FEATURE_IDF;
/* fall through */
default:
......@@ -1236,7 +1254,6 @@ static void i801_remove(struct pci_dev *dev)
free_irq(dev->irq, priv);
pci_release_region(dev, SMBBAR);
pci_set_drvdata(dev, NULL);
kfree(priv);
/*
* do not call pci_disable_device(dev) since it can cause hard hangs on
......
......@@ -773,7 +773,6 @@ static int iic_probe(struct platform_device *ofdev)
if (dev->vaddr)
iounmap(dev->vaddr);
dev_set_drvdata(&ofdev->dev, NULL);
kfree(dev);
return ret;
}
......@@ -785,8 +784,6 @@ static int iic_remove(struct platform_device *ofdev)
{
struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
dev_set_drvdata(&ofdev->dev, NULL);
i2c_del_adapter(&dev->adap);
if (dev->irq) {
......
......@@ -605,7 +605,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
/* remove adapter */
dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
i2c_del_adapter(&i2c_imx->adapter);
platform_set_drvdata(pdev, NULL);
/* setup chip registers to defaults */
writeb(0, i2c_imx->base + IMX_I2C_IADR);
......
......@@ -1069,7 +1069,6 @@ static int intel_mid_i2c_probe(struct pci_dev *dev,
fail3:
free_irq(dev->irq, mrst);
fail2:
pci_set_drvdata(dev, NULL);
kfree(mrst);
fail1:
iounmap(base);
......@@ -1087,7 +1086,6 @@ static void intel_mid_i2c_remove(struct pci_dev *dev)
dev_err(&dev->dev, "Failed to delete i2c adapter");
free_irq(dev->irq, mrst);
pci_set_drvdata(dev, NULL);
iounmap(mrst->base);
kfree(mrst);
pci_release_region(dev, 0);
......
......@@ -415,8 +415,6 @@ iop3xx_i2c_remove(struct platform_device *pdev)
kfree(adapter_data);
kfree(padapter);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -40,6 +40,7 @@
/* SCH SMBus address offsets */
#define SMBHSTCNT (0 + sch_smba)
#define SMBHSTSTS (1 + sch_smba)
#define SMBHSTCLK (2 + sch_smba)
#define SMBHSTADD (4 + sch_smba) /* TSA */
#define SMBHSTCMD (5 + sch_smba)
#define SMBHSTDAT0 (6 + sch_smba)
......@@ -58,6 +59,9 @@
static unsigned short sch_smba;
static struct i2c_adapter sch_adapter;
static int backbone_speed = 33000; /* backbone speed in kHz */
module_param(backbone_speed, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(backbone_speed, "Backbone speed in kHz, (default = 33000)");
/*
* Start the i2c transaction -- the i2c_access will prepare the transaction
......@@ -156,6 +160,19 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr,
dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp);
return -EAGAIN;
}
temp = inw(SMBHSTCLK);
if (!temp) {
/*
* We can't determine if we have 33 or 25 MHz clock for
* SMBus, so expect 33 MHz and calculate a bus clock of
* 100 kHz. If we actually run at 25 MHz the bus will be
* run ~75 kHz instead which should do no harm.
*/
dev_notice(&sch_adapter.dev,
"Clock divider unitialized. Setting defaults\n");
outw(backbone_speed / (4 * 100), SMBHSTCLK);
}
dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size,
(read_write)?"READ":"WRITE");
switch (size) {
......
This diff is collapsed.
......@@ -696,7 +696,6 @@ static int fsl_i2c_probe(struct platform_device *op)
return result;
fail_add:
dev_set_drvdata(&op->dev, NULL);
free_irq(i2c->irq, i2c);
fail_request:
irq_dispose_mapping(i2c->irq);
......@@ -711,7 +710,6 @@ static int fsl_i2c_remove(struct platform_device *op)
struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
i2c_del_adapter(&i2c->adap);
dev_set_drvdata(&op->dev, NULL);
if (i2c->irq)
free_irq(i2c->irq, i2c);
......
......@@ -39,6 +39,7 @@
#define MXS_I2C_CTRL0_SET (0x04)
#define MXS_I2C_CTRL0_SFTRST 0x80000000
#define MXS_I2C_CTRL0_RUN 0x20000000
#define MXS_I2C_CTRL0_SEND_NAK_ON_LAST 0x02000000
#define MXS_I2C_CTRL0_RETAIN_CLOCK 0x00200000
#define MXS_I2C_CTRL0_POST_SEND_STOP 0x00100000
......@@ -64,6 +65,13 @@
#define MXS_I2C_CTRL1_SLAVE_STOP_IRQ 0x02
#define MXS_I2C_CTRL1_SLAVE_IRQ 0x01
#define MXS_I2C_DATA (0xa0)
#define MXS_I2C_DEBUG0 (0xb0)
#define MXS_I2C_DEBUG0_CLR (0xb8)
#define MXS_I2C_DEBUG0_DMAREQ 0x80000000
#define MXS_I2C_IRQ_MASK (MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | \
MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ | \
MXS_I2C_CTRL1_EARLY_TERM_IRQ | \
......@@ -85,35 +93,6 @@
#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
MXS_I2C_CTRL0_MASTER_MODE)
struct mxs_i2c_speed_config {
uint32_t timing0;
uint32_t timing1;
uint32_t timing2;
};
/*
* Timing values for the default 24MHz clock supplied into the i2c block.
*
* The bus can operate at 95kHz or at 400kHz with the following timing
* register configurations. The 100kHz mode isn't present because it's
* values are not stated in the i.MX233/i.MX28 datasheet. The 95kHz mode
* shall be close enough replacement. Therefore when the bus is configured
* for 100kHz operation, 95kHz timing settings are actually loaded.
*
* For details, see i.MX233 [25.4.2 - 25.4.4] and i.MX28 [27.5.2 - 27.5.4].
*/
static const struct mxs_i2c_speed_config mxs_i2c_95kHz_config = {
.timing0 = 0x00780030,
.timing1 = 0x00800030,
.timing2 = 0x00300030,
};
static const struct mxs_i2c_speed_config mxs_i2c_400kHz_config = {
.timing0 = 0x000f0007,
.timing1 = 0x001f000f,
.timing2 = 0x00300030,
};
/**
* struct mxs_i2c_dev - per device, private MXS-I2C data
*
......@@ -129,7 +108,9 @@ struct mxs_i2c_dev {
struct completion cmd_complete;
int cmd_err;
struct i2c_adapter adapter;
const struct mxs_i2c_speed_config *speed;
uint32_t timing0;
uint32_t timing1;
/* DMA support components */
int dma_channel;
......@@ -145,9 +126,16 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
{
stmp_reset_block(i2c->regs);
writel(i2c->speed->timing0, i2c->regs + MXS_I2C_TIMING0);
writel(i2c->speed->timing1, i2c->regs + MXS_I2C_TIMING1);
writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
/*
* Configure timing for the I2C block. The I2C TIMING2 register has to
* be programmed with this particular magic number. The rest is derived
* from the XTAL speed and requested I2C speed.
*
* For details, see i.MX233 [25.4.2 - 25.4.4] and i.MX28 [27.5.2 - 27.5.4].
*/
writel(i2c->timing0, i2c->regs + MXS_I2C_TIMING0);
writel(i2c->timing1, i2c->regs + MXS_I2C_TIMING1);
writel(0x00300030, i2c->regs + MXS_I2C_TIMING2);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
}
......@@ -298,6 +286,135 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
return -EINVAL;
}
static int mxs_i2c_pio_wait_dmareq(struct mxs_i2c_dev *i2c)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
while (!(readl(i2c->regs + MXS_I2C_DEBUG0) &
MXS_I2C_DEBUG0_DMAREQ)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
}
writel(MXS_I2C_DEBUG0_DMAREQ, i2c->regs + MXS_I2C_DEBUG0_CLR);
return 0;
}
static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
/*
* We do not use interrupts in the PIO mode. Due to the
* maximum transfer length being 8 bytes in PIO mode, the
* overhead of interrupt would be too large and this would
* neglect the gain from using the PIO mode.
*/
while (!(readl(i2c->regs + MXS_I2C_CTRL1) &
MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
}
writel(MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ,
i2c->regs + MXS_I2C_CTRL1_CLR);
return 0;
}
static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
struct i2c_msg *msg, uint32_t flags)
{
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
uint32_t addr_data = msg->addr << 1;
uint32_t data = 0;
int i, shifts_left, ret;
/* Mute IRQs coming from this block. */
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_CLR);
if (msg->flags & I2C_M_RD) {
addr_data |= I2C_SMBUS_READ;
/* SELECT command. */
writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_SELECT,
i2c->regs + MXS_I2C_CTRL0);
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(addr_data, i2c->regs + MXS_I2C_DATA);
ret = mxs_i2c_pio_wait_cplt(i2c);
if (ret)
return ret;
/* READ command. */
writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_READ | flags |
MXS_I2C_CTRL0_XFER_COUNT(msg->len),
i2c->regs + MXS_I2C_CTRL0);
for (i = 0; i < msg->len; i++) {
if ((i & 3) == 0) {
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
data = readl(i2c->regs + MXS_I2C_DATA);
}
msg->buf[i] = data & 0xff;
data >>= 8;
}
} else {
addr_data |= I2C_SMBUS_WRITE;
/* WRITE command. */
writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_WRITE | flags |
MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1),
i2c->regs + MXS_I2C_CTRL0);
/*
* The LSB of data buffer is the first byte blasted across
* the bus. Higher order bytes follow. Thus the following
* filling schematic.
*/
data = addr_data << 24;
for (i = 0; i < msg->len; i++) {
data >>= 8;
data |= (msg->buf[i] << 24);
if ((i & 3) == 2) {
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(data, i2c->regs + MXS_I2C_DATA);
}
}
shifts_left = 24 - (i & 3) * 8;
if (shifts_left) {
data >>= shifts_left;
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(data, i2c->regs + MXS_I2C_DATA);
}
}
ret = mxs_i2c_pio_wait_cplt(i2c);
if (ret)
return ret;
/* Clear any dangling IRQs and re-enable interrupts. */
writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
return 0;
}
/*
* Low level master read/write transaction.
*/
......@@ -316,9 +433,19 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (msg->len == 0)
return -EINVAL;
INIT_COMPLETION(i2c->cmd_complete);
/*
* The current boundary to select between PIO/DMA transfer method
* is set to 8 bytes, transfers shorter than 8 bytes are transfered
* using PIO mode while longer transfers use DMA. The 8 byte border is
* based on this empirical measurement and a lot of previous frobbing.
*/
if (msg->len < 8) {
ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
if (ret)
mxs_i2c_reset(i2c);
} else {
i2c->cmd_err = 0;
INIT_COMPLETION(i2c->cmd_complete);
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
if (ret)
return ret;
......@@ -331,9 +458,12 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (i2c->cmd_err == -ENXIO)
mxs_i2c_reset(i2c);
dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
ret = i2c->cmd_err;
}
return i2c->cmd_err;
dev_dbg(i2c->dev, "Done with err=%d\n", ret);
return ret;
timeout:
dev_dbg(i2c->dev, "Timeout!\n");
......@@ -403,6 +533,43 @@ static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param)
return true;
}
static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
{
/* The I2C block clock run at 24MHz */
const uint32_t clk = 24000000;
uint32_t base;
uint16_t high_count, low_count, rcv_count, xmit_count;
struct device *dev = i2c->dev;
if (speed > 540000) {
dev_warn(dev, "Speed too high (%d Hz), using 540 kHz\n", speed);
speed = 540000;
} else if (speed < 12000) {
dev_warn(dev, "Speed too low (%d Hz), using 12 kHz\n", speed);
speed = 12000;
}
/*
* The timing derivation algorithm. There is no documentation for this
* algorithm available, it was derived by using the scope and fiddling
* with constants until the result observed on the scope was good enough
* for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be
* possible to assume the algorithm works for other frequencies as well.
*
* Note it was necessary to cap the frequency on both ends as it's not
* possible to configure completely arbitrary frequency for the I2C bus
* clock.
*/
base = ((clk / speed) - 38) / 2;
high_count = base + 3;
low_count = base - 3;
rcv_count = (high_count * 3) / 4;
xmit_count = low_count / 4;
i2c->timing0 = (high_count << 16) | rcv_count;
i2c->timing1 = (low_count << 16) | xmit_count;
}
static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
{
uint32_t speed;
......@@ -422,12 +589,12 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
}
ret = of_property_read_u32(node, "clock-frequency", &speed);
if (ret)
if (ret) {
dev_warn(dev, "No I2C speed selected, using 100kHz\n");
else if (speed == 400000)
i2c->speed = &mxs_i2c_400kHz_config;
else if (speed != 100000)
dev_warn(dev, "Unsupported I2C speed selected, using 100kHz\n");
speed = 100000;
}
mxs_i2c_derive_timing(i2c, speed);
return 0;
}
......@@ -471,7 +638,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
return err;
i2c->dev = dev;
i2c->speed = &mxs_i2c_95kHz_config;
init_completion(&i2c->cmd_complete);
......@@ -531,8 +697,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -60,7 +60,7 @@
#include <linux/io.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
......@@ -188,9 +188,9 @@ static int nforce2_check_status(struct i2c_adapter *adap)
}
/* Return negative errno on error */
static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data)
u8 command, int size, union i2c_smbus_data *data)
{
struct nforce2_smbus *smbus = adap->algo_data;
unsigned char protocol, pec;
......@@ -202,7 +202,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0;
switch (size) {
case I2C_SMBUS_QUICK:
protocol |= NVIDIA_SMB_PRTCL_QUICK;
read_write = I2C_SMBUS_WRITE;
......@@ -225,7 +224,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
outb_p(command, NVIDIA_SMB_CMD);
if (read_write == I2C_SMBUS_WRITE) {
outb_p(data->word, NVIDIA_SMB_DATA);
outb_p(data->word >> 8, NVIDIA_SMB_DATA+1);
outb_p(data->word >> 8, NVIDIA_SMB_DATA + 1);
}
protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
break;
......@@ -236,15 +235,14 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
len = data->block[0];
if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
dev_err(&adap->dev,
"Transaction failed "
"(requested block size: %d)\n",
"Transaction failed (requested block size: %d)\n",
len);
return -EINVAL;
}
outb_p(len, NVIDIA_SMB_BCNT);
for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
outb_p(data->block[i + 1],
NVIDIA_SMB_DATA+i);
NVIDIA_SMB_DATA + i);
}
protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
break;
......@@ -265,26 +263,26 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
return 0;
switch (size) {
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
data->byte = inb_p(NVIDIA_SMB_DATA);
break;
case I2C_SMBUS_WORD_DATA:
data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
data->word = inb_p(NVIDIA_SMB_DATA) |
(inb_p(NVIDIA_SMB_DATA + 1) << 8);
break;
case I2C_SMBUS_BLOCK_DATA:
len = inb_p(NVIDIA_SMB_BCNT);
if ((len <= 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
dev_err(&adap->dev, "Transaction failed "
"(received block size: 0x%02x)\n",
dev_err(&adap->dev,
"Transaction failed (received block size: 0x%02x)\n",
len);
return -EPROTO;
}
for (i = 0; i < len; i++)
data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
data->block[i + 1] = inb_p(NVIDIA_SMB_DATA + i);
data->block[0] = len;
break;
}
......@@ -299,7 +297,7 @@ static u32 nforce2_func(struct i2c_adapter *adapter)
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_PEC |
(((struct nforce2_smbus*)adapter->algo_data)->blockops ?
(((struct nforce2_smbus *)adapter->algo_data)->blockops ?
I2C_FUNC_SMBUS_BLOCK_DATA : 0);
}
......@@ -327,7 +325,7 @@ static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
{ 0 }
};
MODULE_DEVICE_TABLE (pci, nforce2_ids);
MODULE_DEVICE_TABLE(pci, nforce2_ids);
static int nforce2_probe_smb(struct pci_dev *dev, int bar, int alt_reg,
......@@ -377,7 +375,8 @@ static int nforce2_probe_smb(struct pci_dev *dev, int bar, int alt_reg,
release_region(smbus->base, smbus->size);
return error;
}
dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n",
smbus->base);
return 0;
}
......@@ -388,11 +387,12 @@ static int nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id)
int res1, res2;
/* we support 2 SMBus adapters */
if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
smbuses = kzalloc(2 * sizeof(struct nforce2_smbus), GFP_KERNEL);
if (!smbuses)
return -ENOMEM;
pci_set_drvdata(dev, smbuses);
switch(dev->device) {
switch (dev->device) {
case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS:
case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
......
......@@ -26,6 +26,7 @@
#include <linux/platform_data/i2c-nomadik.h>
#include <linux/of.h>
#include <linux/of_i2c.h>
#include <linux/pinctrl/consumer.h>
#define DRIVER_NAME "nmk-i2c"
......@@ -147,6 +148,10 @@ struct i2c_nmk_client {
* @stop: stop condition.
* @xfer_complete: acknowledge completion for a I2C message.
* @result: controller propogated result.
* @pinctrl: pinctrl handle.
* @pins_default: default state for the pins.
* @pins_idle: idle state for the pins.
* @pins_sleep: sleep state for the pins.
* @busy: Busy doing transfer.
*/
struct nmk_i2c_dev {
......@@ -160,6 +165,11 @@ struct nmk_i2c_dev {
int stop;
struct completion xfer_complete;
int result;
/* Three pin states - default, idle & sleep */
struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_idle;
struct pinctrl_state *pins_sleep;
bool busy;
};
......@@ -402,8 +412,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
{
u32 status = 0;
u32 mcr;
u32 irq_mask = 0;
u32 mcr, irq_mask;
int timeout;
mcr = load_i2c_mcr_reg(dev, flags);
......@@ -472,8 +481,7 @@ static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
{
u32 status = 0;
u32 mcr;
u32 irq_mask = 0;
u32 mcr, irq_mask;
int timeout;
mcr = load_i2c_mcr_reg(dev, flags);
......@@ -636,6 +644,15 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
goto out_clk;
}
/* Optionaly enable pins to be muxed in and configured */
if (!IS_ERR(dev->pins_default)) {
status = pinctrl_select_state(dev->pinctrl,
dev->pins_default);
if (status)
dev_err(&dev->adev->dev,
"could not set default pins\n");
}
status = init_hw(dev);
if (status)
goto out;
......@@ -663,6 +680,15 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
out:
clk_disable_unprepare(dev->clk);
out_clk:
/* Optionally let pins go into idle state */
if (!IS_ERR(dev->pins_idle)) {
status = pinctrl_select_state(dev->pinctrl,
dev->pins_idle);
if (status)
dev_err(&dev->adev->dev,
"could not set pins to idle state\n");
}
pm_runtime_put_sync(&dev->adev->dev);
dev->busy = false;
......@@ -703,8 +729,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
struct nmk_i2c_dev *dev = arg;
u32 tft, rft;
u32 count;
u32 misr;
u32 src = 0;
u32 misr, src;
/* load Tx FIFO and Rx FIFO threshold values */
tft = readl(dev->virtbase + I2C_TFTR);
......@@ -857,15 +882,41 @@ static int nmk_i2c_suspend(struct device *dev)
{
struct amba_device *adev = to_amba_device(dev);
struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
int ret;
if (nmk_i2c->busy)
return -EBUSY;
if (!IS_ERR(nmk_i2c->pins_sleep)) {
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_sleep);
if (ret)
dev_err(dev, "could not set pins to sleep state\n");
}
return 0;
}
static int nmk_i2c_resume(struct device *dev)
{
struct amba_device *adev = to_amba_device(dev);
struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
int ret;
/* First go to the default state */
if (!IS_ERR(nmk_i2c->pins_default)) {
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_default);
if (ret)
dev_err(dev, "could not set pins to default state\n");
}
/* Then let's idle the pins until the next transfer happens */
if (!IS_ERR(nmk_i2c->pins_idle)) {
ret = pinctrl_select_state(nmk_i2c->pinctrl,
nmk_i2c->pins_idle);
if (ret)
dev_err(dev, "could not set pins to idle state\n");
}
return 0;
}
#else
......@@ -953,6 +1004,40 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
dev->adev = adev;
amba_set_drvdata(adev, dev);
dev->pinctrl = devm_pinctrl_get(&adev->dev);
if (IS_ERR(dev->pinctrl)) {
ret = PTR_ERR(dev->pinctrl);
goto err_pinctrl;
}
dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(dev->pins_default)) {
dev_err(&adev->dev, "could not get default pinstate\n");
} else {
ret = pinctrl_select_state(dev->pinctrl,
dev->pins_default);
if (ret)
dev_dbg(&adev->dev, "could not set default pinstate\n");
}
dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_IDLE);
if (IS_ERR(dev->pins_idle)) {
dev_dbg(&adev->dev, "could not get idle pinstate\n");
} else {
/* If possible, let's go to idle until the first transfer */
ret = pinctrl_select_state(dev->pinctrl,
dev->pins_idle);
if (ret)
dev_dbg(&adev->dev, "could not set idle pinstate\n");
}
dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
PINCTRL_STATE_SLEEP);
if (IS_ERR(dev->pins_sleep))
dev_dbg(&adev->dev, "could not get sleep pinstate\n");
dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res));
if (!dev->virtbase) {
ret = -ENOMEM;
......@@ -1020,8 +1105,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
err_irq:
iounmap(dev->virtbase);
err_no_ioremap:
amba_set_drvdata(adev, NULL);
kfree(dev);
err_pinctrl:
err_no_mem:
return ret;
......@@ -1044,7 +1129,6 @@ static int nmk_i2c_remove(struct amba_device *adev)
release_mem_region(res->start, resource_size(res));
clk_put(dev->clk);
pm_runtime_disable(&adev->dev);
amba_set_drvdata(adev, NULL);
kfree(dev);
return 0;
......
......@@ -332,7 +332,7 @@ static int ocores_i2c_of_probe(struct platform_device *pdev,
&i2c->reg_io_width);
match = of_match_node(ocores_i2c_match, pdev->dev.of_node);
if (match && (int)match->data == TYPE_GRLIB) {
if (match && (long)match->data == TYPE_GRLIB) {
dev_dbg(&pdev->dev, "GRLIB variant of i2c-ocores\n");
i2c->setreg = oc_setreg_grlib;
i2c->getreg = oc_getreg_grlib;
......@@ -452,7 +452,6 @@ static int ocores_i2c_remove(struct platform_device *pdev)
/* remove adapter & data */
i2c_del_adapter(&i2c->adap);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -595,7 +595,7 @@ static int octeon_i2c_probe(struct platform_device *pdev)
result = i2c_add_adapter(&i2c->adap);
if (result < 0) {
dev_err(i2c->dev, "failed to add adapter\n");
goto fail_add;
goto out;
}
dev_info(i2c->dev, "version %s\n", DRV_VERSION);
......@@ -603,8 +603,6 @@ static int octeon_i2c_probe(struct platform_device *pdev)
return 0;
fail_add:
platform_set_drvdata(pdev, NULL);
out:
return result;
};
......@@ -614,7 +612,6 @@ static int octeon_i2c_remove(struct platform_device *pdev)
struct octeon_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
platform_set_drvdata(pdev, NULL);
return 0;
};
......
......@@ -1260,7 +1260,6 @@ omap_i2c_probe(struct platform_device *pdev)
pm_runtime_put(dev->dev);
pm_runtime_disable(&pdev->dev);
err_free_mem:
platform_set_drvdata(pdev, NULL);
return r;
}
......@@ -1270,8 +1269,6 @@ static int omap_i2c_remove(struct platform_device *pdev)
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
int ret;
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev);
if (IS_ERR_VALUE(ret))
......
......@@ -260,7 +260,6 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
static int i2c_pca_pf_remove(struct platform_device *pdev)
{
struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&i2c->adap);
......
......@@ -349,7 +349,6 @@ static int pmcmsptwi_probe(struct platform_device *pldev)
return 0;
ret_unmap:
platform_set_drvdata(pldev, NULL);
if (pmcmsptwi_data.irq) {
pmcmsptwi_writel(0,
pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
......@@ -374,7 +373,6 @@ static int pmcmsptwi_remove(struct platform_device *pldev)
i2c_del_adapter(&pmcmsptwi_adapter);
platform_set_drvdata(pldev, NULL);
if (pmcmsptwi_data.irq) {
pmcmsptwi_writel(0,
pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
......
......@@ -761,7 +761,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
out_drvdata:
kfree(alg_data);
err_kzalloc:
platform_set_drvdata(pdev, NULL);
return ret;
}
......@@ -776,7 +775,6 @@ static int i2c_pnx_remove(struct platform_device *pdev)
release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
clk_put(alg_data->clk);
kfree(alg_data);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -221,7 +221,6 @@ static int i2c_powermac_remove(struct platform_device *dev)
printk(KERN_WARNING
"i2c-powermac.c: Failed to remove bus %s !\n",
adapter->name);
platform_set_drvdata(dev, NULL);
memset(adapter, 0, sizeof(*adapter));
return 0;
......
......@@ -223,7 +223,6 @@ static int puv3_i2c_probe(struct platform_device *pdev)
return 0;
fail_add_adapter:
platform_set_drvdata(pdev, NULL);
kfree(adapter);
fail_nomem:
release_mem_region(mem->start, resource_size(mem));
......@@ -245,7 +244,6 @@ static int puv3_i2c_remove(struct platform_device *pdev)
}
put_device(&pdev->dev);
platform_set_drvdata(pdev, NULL);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
......
......@@ -128,7 +128,6 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
return 0;
err_dev_add:
pci_set_drvdata(dev, NULL);
kfree(sds);
err_mem:
pci_disable_device(dev);
......@@ -141,7 +140,6 @@ static void ce4100_i2c_remove(struct pci_dev *dev)
unsigned int i;
sds = pci_get_drvdata(dev);
pci_set_drvdata(dev, NULL);
for (i = 0; i < ARRAY_SIZE(sds->pdev); i++)
platform_device_unregister(sds->pdev[i]);
......
......@@ -1215,12 +1215,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
return ret;
}
static int __exit i2c_pxa_remove(struct platform_device *dev)
static int i2c_pxa_remove(struct platform_device *dev)
{
struct pxa_i2c *i2c = platform_get_drvdata(dev);
platform_set_drvdata(dev, NULL);
i2c_del_adapter(&i2c->adap);
if (!i2c->use_pio)
free_irq(i2c->irq, i2c);
......@@ -1269,7 +1267,7 @@ static const struct dev_pm_ops i2c_pxa_dev_pm_ops = {
static struct platform_driver i2c_pxa_driver = {
.probe = i2c_pxa_probe,
.remove = __exit_p(i2c_pxa_remove),
.remove = i2c_pxa_remove,
.driver = {
.name = "pxa2xx-i2c",
.owner = THIS_MODULE,
......
......@@ -111,6 +111,8 @@ static const struct of_device_id s3c24xx_i2c_match[] = {
{ .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
{ .compatible = "samsung,s3c2440-hdmiphy-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
{ .compatible = "samsung,exynos5440-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_NO_GPIO) },
{},
};
MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
......@@ -1000,8 +1002,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!i2c->pdata) {
ret = -ENOMEM;
goto err_noclk;
dev_err(&pdev->dev, "no memory for platform data\n");
return -ENOMEM;
}
i2c->quirks = s3c24xx_get_device_quirks(pdev);
......@@ -1022,32 +1024,27 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
/* find the clock and enable it */
i2c->dev = &pdev->dev;
i2c->clk = clk_get(&pdev->dev, "i2c");
i2c->clk = devm_clk_get(&pdev->dev, "i2c");
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;
goto err_noclk;
return -ENOENT;
}
dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
clk_prepare_enable(i2c->clk);
/* map the registers */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "cannot find IO resource\n");
ret = -ENOENT;
goto err_clk;
return -ENOENT;
}
i2c->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c->regs)) {
ret = PTR_ERR(i2c->regs);
goto err_clk;
}
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
dev_dbg(&pdev->dev, "registers %p (%p)\n",
i2c->regs, res);
......@@ -1064,16 +1061,18 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (i2c->pdata->cfg_gpio) {
i2c->pdata->cfg_gpio(to_platform_device(i2c->dev));
} else if (IS_ERR(i2c->pctrl) && s3c24xx_i2c_parse_dt_gpio(i2c)) {
ret = -EINVAL;
goto err_clk;
return -EINVAL;
}
/* initialise the i2c controller */
clk_prepare_enable(i2c->clk);
ret = s3c24xx_i2c_init(i2c);
if (ret != 0)
goto err_clk;
clk_disable_unprepare(i2c->clk);
if (ret != 0) {
dev_err(&pdev->dev, "I2C controller init failed\n");
return ret;
}
/* find the IRQ for this unit (note, this relies on the init call to
* ensure no current IRQs pending
*/
......@@ -1081,21 +1080,21 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
goto err_clk;
return ret;
}
ret = request_irq(i2c->irq, s3c24xx_i2c_irq, 0,
ret = devm_request_irq(&pdev->dev, i2c->irq, s3c24xx_i2c_irq, 0,
dev_name(&pdev->dev), i2c);
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
goto err_clk;
return ret;
}
ret = s3c24xx_i2c_register_cpufreq(i2c);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
goto err_irq;
return ret;
}
/* Note, previous versions of the driver used i2c_add_adapter()
......@@ -1110,7 +1109,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto err_cpufreq;
s3c24xx_i2c_deregister_cpufreq(i2c);
return ret;
}
of_i2c_register_devices(&i2c->adap);
......@@ -1120,21 +1120,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
pm_runtime_enable(&i2c->adap.dev);
dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
clk_disable_unprepare(i2c->clk);
return 0;
err_cpufreq:
s3c24xx_i2c_deregister_cpufreq(i2c);
err_irq:
free_irq(i2c->irq, i2c);
err_clk:
clk_disable_unprepare(i2c->clk);
clk_put(i2c->clk);
err_noclk:
return ret;
}
/* s3c24xx_i2c_remove
......@@ -1152,10 +1138,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
s3c24xx_i2c_deregister_cpufreq(i2c);
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq, i2c);
clk_disable_unprepare(i2c->clk);
clk_put(i2c->clk);
if (pdev->dev.of_node && IS_ERR(i2c->pctrl))
s3c24xx_i2c_dt_gpio_free(i2c);
......
......@@ -365,7 +365,6 @@ static int s6i2c_remove(struct platform_device *pdev)
{
struct s6i2c_if *iface = platform_get_drvdata(pdev);
i2c_wr16(iface, S6_I2C_ENABLE, 0);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&iface->adap);
free_irq(iface->irq, iface);
clk_disable(iface->clk);
......
......@@ -546,7 +546,6 @@ static int sh7760_i2c_remove(struct platform_device *pdev)
release_resource(id->ioarea);
kfree(id->ioarea);
kfree(id);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -38,21 +38,21 @@
/* Transmit operation: */
/* */
/* 0 byte transmit */
/* BUS: S A8 ACK P */
/* BUS: S A8 ACK P(*) */
/* IRQ: DTE WAIT */
/* ICIC: */
/* ICCR: 0x94 0x90 */
/* ICDR: A8 */
/* */
/* 1 byte transmit */
/* BUS: S A8 ACK D8(1) ACK P */
/* BUS: S A8 ACK D8(1) ACK P(*) */
/* IRQ: DTE WAIT WAIT */
/* ICIC: -DTE */
/* ICCR: 0x94 0x90 */
/* ICDR: A8 D8(1) */
/* */
/* 2 byte transmit */
/* BUS: S A8 ACK D8(1) ACK D8(2) ACK P */
/* BUS: S A8 ACK D8(1) ACK D8(2) ACK P(*) */
/* IRQ: DTE WAIT WAIT WAIT */
/* ICIC: -DTE */
/* ICCR: 0x94 0x90 */
......@@ -66,20 +66,20 @@
/* 0 byte receive - not supported since slave may hold SDA low */
/* */
/* 1 byte receive [TX] | [RX] */
/* BUS: S A8 ACK | D8(1) ACK P */
/* BUS: S A8 ACK | D8(1) ACK P(*) */
/* IRQ: DTE WAIT | WAIT DTE */
/* ICIC: -DTE | +DTE */
/* ICCR: 0x94 0x81 | 0xc0 */
/* ICDR: A8 | D8(1) */
/* */
/* 2 byte receive [TX]| [RX] */
/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK P */
/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK P(*) */
/* IRQ: DTE WAIT | WAIT WAIT DTE */
/* ICIC: -DTE | +DTE */
/* ICCR: 0x94 0x81 | 0xc0 */
/* ICDR: A8 | D8(1) D8(2) */
/* */
/* 3 byte receive [TX] | [RX] */
/* 3 byte receive [TX] | [RX] (*) */
/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK D8(3) ACK P */
/* IRQ: DTE WAIT | WAIT WAIT WAIT DTE */
/* ICIC: -DTE | +DTE */
......@@ -94,7 +94,7 @@
/* SDA ___\___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAA___/ */
/* SCL \_/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\___/9\_____/ */
/* */
/* S D7 D6 D5 D4 D3 D2 D1 D0 P */
/* S D7 D6 D5 D4 D3 D2 D1 D0 P(*) */
/* ___ */
/* WAIT IRQ ________________________________/ \___________ */
/* TACK IRQ ____________________________________/ \_______ */
......@@ -103,6 +103,11 @@
/* _______________________________________________ */
/* BUSY __/ \_ */
/* */
/* (*) The STOP condition is only sent by the master at the end of the last */
/* I2C message or if the I2C_M_STOP flag is set. Similarly, the BUSY bit is */
/* only cleared after the STOP condition, so, between messages we have to */
/* poll for the DTE bit. */
/* */
enum sh_mobile_i2c_op {
OP_START = 0,
......@@ -132,6 +137,7 @@ struct sh_mobile_i2c_data {
struct i2c_msg *msg;
int pos;
int sr;
bool send_stop;
};
#define IIC_FLAG_HAS_ICIC67 (1 << 0)
......@@ -322,7 +328,7 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
break;
case OP_TX_STOP: /* write data and issue a stop afterwards */
iic_wr(pd, ICDR, data);
iic_wr(pd, ICCR, 0x90);
iic_wr(pd, ICCR, pd->send_stop ? 0x90 : 0x94);
break;
case OP_TX_TO_RX: /* select read mode */
iic_wr(pd, ICCR, 0x81);
......@@ -349,20 +355,14 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
return ret;
}
static int sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd)
static bool sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd)
{
if (pd->pos == -1)
return 1;
return 0;
return pd->pos == -1;
}
static int sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd)
static bool sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd)
{
if (pd->pos == (pd->msg->len - 1))
return 1;
return 0;
return pd->pos == pd->msg->len - 1;
}
static void sh_mobile_i2c_get_data(struct sh_mobile_i2c_data *pd,
......@@ -475,13 +475,15 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
bool do_init)
{
if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) {
dev_err(pd->dev, "Unsupported zero length i2c read\n");
return -EIO;
}
if (do_init) {
/* Initialize channel registers */
iic_set_clr(pd, ICCR, 0, ICCR_ICE);
......@@ -491,6 +493,7 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
/* Set the clock */
iic_wr(pd, ICCL, pd->iccl & 0xff);
iic_wr(pd, ICCH, pd->icch & 0xff);
}
pd->msg = usr_msg;
pd->pos = -1;
......@@ -501,6 +504,61 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
return 0;
}
static int poll_dte(struct sh_mobile_i2c_data *pd)
{
int i;
for (i = 1000; i; i--) {
u_int8_t val = iic_rd(pd, ICSR);
if (val & ICSR_DTE)
break;
if (val & ICSR_TACK)
return -EIO;
udelay(10);
}
if (!i) {
dev_warn(pd->dev, "Timeout polling for DTE!\n");
return -ETIMEDOUT;
}
return 0;
}
static int poll_busy(struct sh_mobile_i2c_data *pd)
{
int i;
for (i = 1000; i; i--) {
u_int8_t val = iic_rd(pd, ICSR);
dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
/* the interrupt handler may wake us up before the
* transfer is finished, so poll the hardware
* until we're done.
*/
if (!(val & ICSR_BUSY)) {
/* handle missing acknowledge and arbitration lost */
if ((val | pd->sr) & (ICSR_TACK | ICSR_AL))
return -EIO;
break;
}
udelay(10);
}
if (!i) {
dev_err(pd->dev, "Polling timed out\n");
return -ETIMEDOUT;
}
return 0;
}
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs,
int num)
......@@ -508,54 +566,40 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
struct i2c_msg *msg;
int err = 0;
u_int8_t val;
int i, k, retry_count;
int i, k;
activate_ch(pd);
/* Process all messages */
for (i = 0; i < num; i++) {
bool do_start = pd->send_stop || !i;
msg = &msgs[i];
pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;
err = start_ch(pd, msg);
err = start_ch(pd, msg, do_start);
if (err)
break;
if (do_start)
i2c_op(pd, OP_START, 0);
/* The interrupt handler takes care of the rest... */
k = wait_event_timeout(pd->wait,
pd->sr & (ICSR_TACK | SW_DONE),
5 * HZ);
if (!k)
if (!k) {
dev_err(pd->dev, "Transfer request timed out\n");
retry_count = 1000;
again:
val = iic_rd(pd, ICSR);
dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
/* the interrupt handler may wake us up before the
* transfer is finished, so poll the hardware
* until we're done.
*/
if (val & ICSR_BUSY) {
udelay(10);
if (retry_count--)
goto again;
err = -EIO;
dev_err(pd->dev, "Polling timed out\n");
err = -ETIMEDOUT;
break;
}
/* handle missing acknowledge and arbitration lost */
if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
err = -EIO;
if (pd->send_stop)
err = poll_busy(pd);
else
err = poll_dte(pd);
if (err < 0)
break;
}
}
deactivate_ch(pd);
......@@ -566,7 +610,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
}
static struct i2c_algorithm sh_mobile_i2c_algorithm = {
......
This diff is collapsed.
......@@ -975,7 +975,6 @@ stu300_remove(struct platform_device *pdev)
i2c_del_adapter(&dev->adapter);
/* Turn off everything */
stu300_wr8(0x00, dev->virtbase + I2C_CR);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -271,7 +271,6 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
exit_close:
serio_close(serio);
exit_kfree:
serio_set_drvdata(serio, NULL);
kfree(taos);
exit:
return err;
......@@ -285,7 +284,6 @@ static void taos_disconnect(struct serio *serio)
i2c_unregister_device(taos->client);
i2c_del_adapter(&taos->adapter);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(taos);
dev_info(&serio->dev, "Disconnected from TAOS EVM\n");
......
......@@ -70,6 +70,8 @@
#define I2C_INT_TX_FIFO_DATA_REQ (1<<1)
#define I2C_INT_RX_FIFO_DATA_REQ (1<<0)
#define I2C_CLK_DIVISOR 0x06c
#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT 16
#define I2C_CLK_MULTIPLIER_STD_FAST_MODE 8
#define DVC_CTRL_REG1 0x000
#define DVC_CTRL_REG1_INTR_EN (1<<10)
......@@ -116,10 +118,23 @@ enum msg_end_type {
/**
* struct tegra_i2c_hw_feature : Different HW support on Tegra
* @has_continue_xfer_support: Continue transfer supports.
* @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
* complete interrupt per packet basis.
* @has_single_clk_source: The i2c controller has single clock source. Tegra30
* and earlier Socs has two clock sources i.e. div-clk and
* fast-clk.
* @clk_divisor_hs_mode: Clock divisor in HS mode.
* @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
* applicable if there is no fast clock source i.e. single clock
* source.
*/
struct tegra_i2c_hw_feature {
bool has_continue_xfer_support;
bool has_per_pkt_xfer_complete_irq;
bool has_single_clk_source;
int clk_divisor_hs_mode;
int clk_divisor_std_fast_mode;
};
/**
......@@ -365,12 +380,14 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
{
int ret;
if (!i2c_dev->hw->has_single_clk_source) {
ret = clk_prepare_enable(i2c_dev->fast_clk);
if (ret < 0) {
dev_err(i2c_dev->dev,
"Enabling fast clk failed, err %d\n", ret);
return ret;
}
}
ret = clk_prepare_enable(i2c_dev->div_clk);
if (ret < 0) {
dev_err(i2c_dev->dev,
......@@ -383,6 +400,7 @@ static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
{
clk_disable_unprepare(i2c_dev->div_clk);
if (!i2c_dev->hw->has_single_clk_source)
clk_disable_unprepare(i2c_dev->fast_clk);
}
......@@ -390,6 +408,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
{
u32 val;
int err = 0;
int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE;
u32 clk_divisor;
tegra_i2c_clock_enable(i2c_dev);
......@@ -404,7 +424,15 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
clk_set_rate(i2c_dev->div_clk, i2c_dev->bus_clk_rate * 8);
clk_multiplier *= (i2c_dev->hw->clk_divisor_std_fast_mode + 1);
clk_set_rate(i2c_dev->div_clk, i2c_dev->bus_clk_rate * clk_multiplier);
/* Make sure clock divisor programmed correctly */
clk_divisor = i2c_dev->hw->clk_divisor_hs_mode;
clk_divisor |= i2c_dev->hw->clk_divisor_std_fast_mode <<
I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
if (!i2c_dev->is_dvc) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
......@@ -546,6 +574,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
tegra_i2c_fill_tx_fifo(i2c_dev);
int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
if (msg->flags & I2C_M_RD)
int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
else if (i2c_dev->msg_buf_remaining)
......@@ -557,7 +587,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT);
tegra_i2c_mask_irq(i2c_dev, int_mask);
if (WARN_ON(ret == 0)) {
if (ret == 0) {
dev_err(i2c_dev->dev, "i2c transfer timed out\n");
tegra_i2c_init(i2c_dev);
......@@ -633,15 +663,32 @@ static const struct i2c_algorithm tegra_i2c_algo = {
static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
.has_continue_xfer_support = false,
.has_per_pkt_xfer_complete_irq = false,
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
};
static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
.has_continue_xfer_support = true,
.has_per_pkt_xfer_complete_irq = false,
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
};
static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
.has_continue_xfer_support = true,
.has_per_pkt_xfer_complete_irq = true,
.has_single_clk_source = true,
.clk_divisor_hs_mode = 1,
.clk_divisor_std_fast_mode = 0x19,
};
#if defined(CONFIG_OF)
/* Match table for of_platform binding */
static const struct of_device_id tegra_i2c_of_match[] = {
{ .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
{ .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
{ .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
{ .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
......@@ -685,12 +732,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
return PTR_ERR(div_clk);
}
fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
if (IS_ERR(fast_clk)) {
dev_err(&pdev->dev, "missing bus clock");
return PTR_ERR(fast_clk);
}
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev) {
dev_err(&pdev->dev, "Could not allocate struct tegra_i2c_dev");
......@@ -699,7 +740,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->base = base;
i2c_dev->div_clk = div_clk;
i2c_dev->fast_clk = fast_clk;
i2c_dev->adapter.algo = &tegra_i2c_algo;
i2c_dev->irq = irq;
i2c_dev->cont_id = pdev->id;
......@@ -730,6 +770,15 @@ static int tegra_i2c_probe(struct platform_device *pdev)
}
init_completion(&i2c_dev->msg_complete);
if (!i2c_dev->hw->has_single_clk_source) {
fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
if (IS_ERR(fast_clk)) {
dev_err(&pdev->dev, "missing fast clock");
return PTR_ERR(fast_clk);
}
i2c_dev->fast_clk = fast_clk;
}
platform_set_drvdata(pdev, i2c_dev);
ret = tegra_i2c_init(i2c_dev);
......
......@@ -125,8 +125,6 @@ static int i2c_versatile_remove(struct platform_device *dev)
{
struct i2c_versatile *i2c = platform_get_drvdata(dev);
platform_set_drvdata(dev, NULL);
i2c_del_adapter(&i2c->adap);
return 0;
}
......
......@@ -784,8 +784,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)
xiic_deinit(i2c);
platform_set_drvdata(pdev, NULL);
free_irq(platform_get_irq(pdev, 0), i2c);
iounmap(i2c->base);
......
......@@ -256,7 +256,6 @@ static int xlr_i2c_remove(struct platform_device *pdev)
priv = platform_get_drvdata(pdev);
i2c_del_adapter(&priv->adap);
platform_set_drvdata(pdev, NULL);
return 0;
}
......
......@@ -542,7 +542,6 @@ static int scx200_remove(struct platform_device *pdev)
struct scx200_acb_iface *iface;
iface = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
scx200_cleanup_iface(iface);
return 0;
......
......@@ -1865,29 +1865,6 @@ s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command,
}
EXPORT_SYMBOL(i2c_smbus_write_word_data);
/**
* i2c_smbus_process_call - SMBus "process call" protocol
* @client: Handle to slave device
* @command: Byte interpreted by slave
* @value: 16-bit "word" being written
*
* This executes the SMBus "process call" protocol, returning negative errno
* else a 16-bit unsigned "word" received from the device.
*/
s32 i2c_smbus_process_call(const struct i2c_client *client, u8 command,
u16 value)
{
union i2c_smbus_data data;
int status;
data.word = value;
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_PROC_CALL, &data);
return (status < 0) ? status : data.word;
}
EXPORT_SYMBOL(i2c_smbus_process_call);
/**
* i2c_smbus_read_block_data - SMBus "block read" protocol
* @client: Handle to slave device
......
......@@ -250,7 +250,6 @@ static int i2c_mux_gpio_remove(struct platform_device *pdev)
for (i = 0; i < mux->data.n_gpios; i++)
gpio_free(mux->gpio_base + mux->data.gpios[i]);
platform_set_drvdata(pdev, NULL);
i2c_put_adapter(mux->parent);
return 0;
......
menu "EEPROM support"
config EEPROM_AT24
tristate "I2C EEPROMs from most vendors"
tristate "I2C EEPROMs / RAMs / ROMs from most vendors"
depends on I2C && SYSFS
help
Enable this driver to get read/write support to most I2C EEPROMs,
after you configure the driver to know about each EEPROM on
your target board. Use these generic chip names, instead of
vendor-specific ones like at24c64 or 24lc02:
Enable this driver to get read/write support to most I2C EEPROMs
and compatible devices like FRAMs, SRAMs, ROMs etc. After you
configure the driver to know about each chip on your target
board. Use these generic chip names, instead of vendor-specific
ones like at24c64, 24lc02 or fm24c04:
24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
......
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