Skip to content

Commit

Permalink
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/wsa/linux

Pull i2c changes from Wolfram Sang:

 - an arbitration driver.  While the driver is quite simple, it caused
   discussion if we need additional arbitration on top of the one
   specified in the I2C standard.  Conclusion is that I accept a few
   generic mechanisms, but not very specific ones.

 - the core lost the detach_adapter() call.  It has no users anymore and
   was in the way for other cleanups.  attach_adapter() is sadly still
   there since there are users waiting to be converted.

 - the core gained a bus recovery infrastructure.  I2C defines a way to
   recover if the data line is stalled.  This mechanism is now in the
   core and drivers can now pass some data to make use of it.

 - bigger driver cleanups for designware, s3c2410

 - removing superfluous refcounting from drivers

 - removing Ben Dooks as second maintainer due to inactivity.  Thanks
   for all your work so far, Ben!

 - bugfixes, feature additions, devicetree fixups, simplifications...

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (38 commits)
  i2c: xiic: must always write 16-bit words to TX_FIFO
  i2c: octeon: use HZ in timeout value
  i2c: octeon: Fix i2c fail problem when a process is terminated by a signal
  i2c: designware-pci: drop superfluous {get|put}_device
  i2c: designware-plat: drop superfluous {get|put}_device
  i2c: davinci: drop superfluous {get|put}_device
  MAINTAINERS: Ben Dooks is inactive regarding I2C
  i2c: mux: Add i2c-arb-gpio-challenge 'mux' driver
  i2c: at91: convert to dma_request_slave_channel_compat()
  i2c: mxs: do error checking and handling in PIO mode
  i2c: mxs: remove races in PIO code
  i2c-designware: switch to use runtime PM autosuspend
  i2c-designware: use usleep_range() in the busy-loop
  i2c-designware: enable/disable the controller properly
  i2c-designware: use dynamic adapter numbering on Lynxpoint
  i2c-designware-pci: use managed functions pcim_* and devm_*
  i2c-designware-pci: use dev_err() instead of printk()
  i2c-designware: move to managed functions (devm_*)
  i2c: remove CONFIG_HOTPLUG ifdefs
  i2c: s3c2410: Add SMBus emulation for block read
  ...
  • Loading branch information
Linus Torvalds committed May 2, 2013
2 parents 736a2dd + c39e8e4 commit 99bece7
Show file tree
Hide file tree
Showing 42 changed files with 960 additions and 497 deletions.
80 changes: 80 additions & 0 deletions Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
GPIO-based I2C Arbitration Using a Challenge & Response Mechanism
=================================================================
This uses GPIO lines and a challenge & response mechanism to arbitrate who is
the master of an I2C bus in a multimaster situation.

In many cases using GPIOs to arbitrate is not needed and a design can use
the standard I2C multi-master rules. Using GPIOs is generally useful in
the case where there is a device on the bus that has errata and/or bugs
that makes standard multimaster mode not feasible.


Algorithm:

All masters on the bus have a 'bus claim' line which is an output that the
others can see. These are all active low with pull-ups enabled. We'll
describe these lines as:

- OUR_CLAIM: output from us signaling to other hosts that we want the bus
- THEIR_CLAIMS: output from others signaling that they want the bus

The basic algorithm is to assert your line when you want the bus, then make
sure that the other side doesn't want it also. A detailed explanation is best
done with an example.

Let's say we want to claim the bus. We:
1. Assert OUR_CLAIM.
2. Waits a little bit for the other sides to notice (slew time, say 10
microseconds).
3. Check THEIR_CLAIMS. If none are asserted then the we have the bus and we are
done.
4. Otherwise, wait for a few milliseconds and see if THEIR_CLAIMS are released.
5. If not, back off, release the claim and wait for a few more milliseconds.
6. Go back to 1 (until retry time has expired).


Required properties:
- compatible: i2c-arb-gpio-challenge
- our-claim-gpio: The GPIO that we use to claim the bus.
- their-claim-gpios: The GPIOs that the other sides use to claim the bus.
Note that some implementations may only support a single other master.
- Standard I2C mux properties. See mux.txt in this directory.
- Single I2C child bus node at reg 0. See mux.txt in this directory.

Optional properties:
- slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us.
- wait-retry-us: we'll attempt another claim after this many microseconds.
Default is 3000 us.
- wait-free-us: we'll give up after this many microseconds. Default is 50000 us.


Example:
i2c@12CA0000 {
compatible = "acme,some-i2c-device";
#address-cells = <1>;
#size-cells = <0>;
};

i2c-arbitrator {
compatible = "i2c-arb-gpio-challenge";
#address-cells = <1>;
#size-cells = <0>;

i2c-parent = <&{/i2c@12CA0000}>;

our-claim-gpio = <&gpf0 3 1>;
their-claim-gpios = <&gpe0 4 1>;
slew-delay-us = <10>;
wait-retry-us = <3000>;
wait-free-us = <50000>;

i2c@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;

i2c@52 {
// Normal I2C device
};
};
};
1 change: 0 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3919,7 +3919,6 @@ F: drivers/i2c/i2c-stub.c

I2C SUBSYSTEM
M: Wolfram Sang <wsa@the-dreams.de>
M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
Expand Down
1 change: 0 additions & 1 deletion arch/arm/mach-s3c24xx/mach-rx1950.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/regs-iic.h>
#include <plat/regs-serial.h>

#include "common.h"
Expand Down
2 changes: 0 additions & 2 deletions arch/arm/mach-tegra/tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
#include <linux/pda_power.h>
#include <linux/platform_data/tegra_usb.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-tegra.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include <linux/usb/tegra_usb_phy.h>
Expand Down
1 change: 0 additions & 1 deletion arch/arm/plat-samsung/devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
#include <linux/platform_data/usb-s3c2410_udc.h>
#include <linux/platform_data/usb-ohci-s3c2410.h>
#include <plat/usb-phy.h>
#include <plat/regs-iic.h>
#include <plat/regs-serial.h>
#include <plat/regs-spi.h>
#include <linux/platform_data/spi-s3c64xx.h>
Expand Down
56 changes: 0 additions & 56 deletions arch/arm/plat-samsung/include/plat/regs-iic.h

This file was deleted.

3 changes: 1 addition & 2 deletions drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,7 @@ void oaktrail_hdmi_i2c_exit(struct pci_dev *dev)
struct hdmi_i2c_dev *i2c_dev;

hdmi_dev = pci_get_drvdata(dev);
if (i2c_del_adapter(&oaktrail_hdmi_i2c_adapter))
DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n");
i2c_del_adapter(&oaktrail_hdmi_i2c_adapter);

i2c_dev = hdmi_dev->i2c_dev;
kfree(i2c_dev);
Expand Down
6 changes: 1 addition & 5 deletions drivers/i2c/busses/i2c-amd756-s4882.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,7 @@ static int __init amd756_s4882_init(void)
}

/* Unregister physical bus */
error = i2c_del_adapter(&amd756_smbus);
if (error) {
dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
goto ERROR0;
}
i2c_del_adapter(&amd756_smbus);

printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");
/* Define the 5 virtual adapters and algorithms structures */
Expand Down
58 changes: 28 additions & 30 deletions drivers/i2c/busses/i2c-at91.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,15 +603,18 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
}
};
MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids);
#else
#define atmel_twi_dt_ids NULL
#endif

static bool filter(struct dma_chan *chan, void *slave)
static bool filter(struct dma_chan *chan, void *pdata)
{
struct at_dma_slave *sl = slave;
struct at91_twi_pdata *sl_pdata = pdata;
struct at_dma_slave *sl;

if (!sl_pdata)
return false;

if (sl->dma_dev == chan->device->dev) {
sl = &sl_pdata->dma_slave;
if (sl && (sl->dma_dev == chan->device->dev)) {
chan->private = sl;
return true;
} else {
Expand All @@ -622,11 +625,10 @@ static bool filter(struct dma_chan *chan, void *slave)
static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
{
int ret = 0;
struct at_dma_slave *sdata;
struct at91_twi_pdata *pdata = dev->pdata;
struct dma_slave_config slave_config;
struct at91_twi_dma *dma = &dev->dma;

sdata = &dev->pdata->dma_slave;
dma_cap_mask_t mask;

memset(&slave_config, 0, sizeof(slave_config));
slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR;
Expand All @@ -637,25 +639,22 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
slave_config.dst_maxburst = 1;
slave_config.device_fc = false;

if (sdata && sdata->dma_dev) {
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);

dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma->chan_tx = dma_request_channel(mask, filter, sdata);
if (!dma->chan_tx) {
dev_err(dev->dev, "no DMA channel available for tx\n");
ret = -EBUSY;
goto error;
}
dma->chan_rx = dma_request_channel(mask, filter, sdata);
if (!dma->chan_rx) {
dev_err(dev->dev, "no DMA channel available for rx\n");
ret = -EBUSY;
goto error;
}
} else {
ret = -EINVAL;
dma->chan_tx = dma_request_slave_channel_compat(mask, filter, pdata,
dev->dev, "tx");
if (!dma->chan_tx) {
dev_err(dev->dev, "can't get a DMA channel for tx\n");
ret = -EBUSY;
goto error;
}

dma->chan_rx = dma_request_slave_channel_compat(mask, filter, pdata,
dev->dev, "rx");
if (!dma->chan_rx) {
dev_err(dev->dev, "can't get a DMA channel for rx\n");
ret = -EBUSY;
goto error;
}

Expand Down Expand Up @@ -785,12 +784,11 @@ static int at91_twi_probe(struct platform_device *pdev)
static int at91_twi_remove(struct platform_device *pdev)
{
struct at91_twi_dev *dev = platform_get_drvdata(pdev);
int rc;

rc = i2c_del_adapter(&dev->adapter);
i2c_del_adapter(&dev->adapter);
clk_disable_unprepare(dev->clk);

return rc;
return 0;
}

#ifdef CONFIG_PM
Expand Down Expand Up @@ -828,7 +826,7 @@ static struct platform_driver at91_twi_driver = {
.driver = {
.name = "at91_i2c",
.owner = THIS_MODULE,
.of_match_table = atmel_twi_dt_ids,
.of_match_table = of_match_ptr(atmel_twi_dt_ids),
.pm = at91_twi_pm_ops,
},
};
Expand Down
4 changes: 3 additions & 1 deletion drivers/i2c/busses/i2c-cbus-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ static int cbus_i2c_remove(struct platform_device *pdev)
{
struct i2c_adapter *adapter = platform_get_drvdata(pdev);

return i2c_del_adapter(adapter);
i2c_del_adapter(adapter);

return 0;
}

static int cbus_i2c_probe(struct platform_device *pdev)
Expand Down
Loading

0 comments on commit 99bece7

Please sign in to comment.