diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 12:54:40 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 12:54:40 -0800 |
commit | 96895199c8648db475b38aac5fe6a04ec14a49c4 (patch) | |
tree | 3cb2a2a68a4750de20cf3deddd4a897189164ea9 /drivers/i2c/i2c-core.c | |
parent | 8fd9589ced9a4ab1cf23296fa1c17d07e883f734 (diff) | |
parent | 6cf710d47633be388e831713738626d1911163c8 (diff) | |
download | linux-96895199c8648db475b38aac5fe6a04ec14a49c4.tar.bz2 |
Merge branch 'i2c/for-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"For 3.19, the I2C subsystem has to offer special candy this time.
Right in time for Christmas :)
- I2C slave framework: finally, a generic mechanism for Linux being
an I2C slave (if the bus driver supports that). Docs are still
missing but will come later this cycle, the code is good enough to
go.
- I2C muxes represent their topology in sysfs much more detailed.
This will help users to navigate around much easier.
- irq population of i2c clients is now done at probe time, not device
creation time, to have better support for deferred probing.
- new drivers for Imagination SCB, Amlogic Meson
- DMA support added for Freescale IMX, Renesas SHMobile
- slightly bigger driver updates to OMAP, i801, AT91, and rk3x
(mostly quirk handling, timing updates, and using better kernel
interfaces)
- eeprom driver can now write with byte-access (very slow, but OK to
have)
- and the bunch of smaller fixes, cleanups, ID updates..."
* 'i2c/for-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (56 commits)
i2c: sh_mobile: remove unneeded DMA mask
i2c: rcar: add slave support
i2c: slave-eeprom: add eeprom simulator driver
i2c: core changes for slave support
MAINTAINERS: add I2C dt bindings also to I2C realm
i2c: designware: Fix falling time bindings doc
i2c: davinci: switch to use platform_get_irq
Documentation: i2c: Use PM ops instead of legacy suspend/resume
i2c: sh_mobile: optimize irq entry
i2c: pxa: add support for SCCB devices
omap: i2c: don't check bus state IP rev3.3 and earlier
i2c: s3c2410: Handle i2c sys_cfg register in i2c driver
i2c: rk3x: add Kconfig dependency on COMMON_CLK
i2c: omap: add notes related to i2c multimaster mode
i2c: omap: don't reset controller if Arbitration Lost detected
i2c: omap: implement workaround for handling invalid BB-bit values
i2c: omap: cleanup register definitions
i2c: rk3x: handle dynamic clock rate changes correctly
i2c: at91: enable probe deferring on dma channel request
i2c: at91: remove legacy DMA support
...
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 229a89e84b0f..39d25a8cb1ad 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -24,6 +24,7 @@ (c) 2013 Wolfram Sang <wsa@the-dreams.de> I2C ACPI code Copyright (C) 2014 Intel Corp Author: Lan Tianyu <tianyu.lan@intel.com> + I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com> */ #include <linux/module.h> @@ -261,7 +262,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, struct acpi_resource *ares; u32 accessor_type = function >> 16; u8 action = function & ACPI_IO_MASK; - acpi_status ret = AE_OK; + acpi_status ret; int status; ret = acpi_buffer_to_resource(info->connection, info->length, &ares); @@ -628,6 +629,17 @@ static int i2c_device_probe(struct device *dev) if (!client) return 0; + if (!client->irq && dev->of_node) { + int irq = of_irq_get(dev->of_node, 0); + + if (irq == -EPROBE_DEFER) + return irq; + if (irq < 0) + irq = 0; + + client->irq = irq; + } + driver = to_i2c_driver(dev->driver); if (!driver->probe || !driver->id_table) return -ENODEV; @@ -1401,7 +1413,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, return ERR_PTR(-EINVAL); } - info.irq = irq_of_parse_and_map(node, 0); info.of_node = of_node_get(node); info.archdata = &dev_ad; @@ -1415,7 +1426,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, dev_err(&adap->dev, "of_i2c: Failure registering %s\n", node->full_name); of_node_put(node); - irq_dispose_mapping(info.irq); return ERR_PTR(-EINVAL); } return result; @@ -2962,6 +2972,54 @@ trace: } EXPORT_SYMBOL(i2c_smbus_xfer); +int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) +{ + int ret; + + if (!client || !slave_cb) + return -EINVAL; + + if (!(client->flags & I2C_CLIENT_TEN)) { + /* Enforce stricter address checking */ + ret = i2c_check_addr_validity(client->addr); + if (ret) + return ret; + } + + if (!client->adapter->algo->reg_slave) + return -EOPNOTSUPP; + + client->slave_cb = slave_cb; + + i2c_lock_adapter(client->adapter); + ret = client->adapter->algo->reg_slave(client); + i2c_unlock_adapter(client->adapter); + + if (ret) + client->slave_cb = NULL; + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_slave_register); + +int i2c_slave_unregister(struct i2c_client *client) +{ + int ret; + + if (!client->adapter->algo->unreg_slave) + return -EOPNOTSUPP; + + i2c_lock_adapter(client->adapter); + ret = client->adapter->algo->unreg_slave(client); + i2c_unlock_adapter(client->adapter); + + if (ret == 0) + client->slave_cb = NULL; + + return ret; +} +EXPORT_SYMBOL_GPL(i2c_slave_unregister); + MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); MODULE_DESCRIPTION("I2C-Bus main module"); MODULE_LICENSE("GPL"); |