aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 15:54:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 15:54:40 -0500
commit96895199c8648db475b38aac5fe6a04ec14a49c4 (patch)
tree3cb2a2a68a4750de20cf3deddd4a897189164ea9 /drivers/i2c/i2c-core.c
parent8fd9589ced9a4ab1cf23296fa1c17d07e883f734 (diff)
parent6cf710d47633be388e831713738626d1911163c8 (diff)
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.c64
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 @@
24 (c) 2013 Wolfram Sang <wsa@the-dreams.de> 24 (c) 2013 Wolfram Sang <wsa@the-dreams.de>
25 I2C ACPI code Copyright (C) 2014 Intel Corp 25 I2C ACPI code Copyright (C) 2014 Intel Corp
26 Author: Lan Tianyu <tianyu.lan@intel.com> 26 Author: Lan Tianyu <tianyu.lan@intel.com>
27 I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com>
27 */ 28 */
28 29
29#include <linux/module.h> 30#include <linux/module.h>
@@ -261,7 +262,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command,
261 struct acpi_resource *ares; 262 struct acpi_resource *ares;
262 u32 accessor_type = function >> 16; 263 u32 accessor_type = function >> 16;
263 u8 action = function & ACPI_IO_MASK; 264 u8 action = function & ACPI_IO_MASK;
264 acpi_status ret = AE_OK; 265 acpi_status ret;
265 int status; 266 int status;
266 267
267 ret = acpi_buffer_to_resource(info->connection, info->length, &ares); 268 ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
@@ -628,6 +629,17 @@ static int i2c_device_probe(struct device *dev)
628 if (!client) 629 if (!client)
629 return 0; 630 return 0;
630 631
632 if (!client->irq && dev->of_node) {
633 int irq = of_irq_get(dev->of_node, 0);
634
635 if (irq == -EPROBE_DEFER)
636 return irq;
637 if (irq < 0)
638 irq = 0;
639
640 client->irq = irq;
641 }
642
631 driver = to_i2c_driver(dev->driver); 643 driver = to_i2c_driver(dev->driver);
632 if (!driver->probe || !driver->id_table) 644 if (!driver->probe || !driver->id_table)
633 return -ENODEV; 645 return -ENODEV;
@@ -1401,7 +1413,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1401 return ERR_PTR(-EINVAL); 1413 return ERR_PTR(-EINVAL);
1402 } 1414 }
1403 1415
1404 info.irq = irq_of_parse_and_map(node, 0);
1405 info.of_node = of_node_get(node); 1416 info.of_node = of_node_get(node);
1406 info.archdata = &dev_ad; 1417 info.archdata = &dev_ad;
1407 1418
@@ -1415,7 +1426,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1415 dev_err(&adap->dev, "of_i2c: Failure registering %s\n", 1426 dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
1416 node->full_name); 1427 node->full_name);
1417 of_node_put(node); 1428 of_node_put(node);
1418 irq_dispose_mapping(info.irq);
1419 return ERR_PTR(-EINVAL); 1429 return ERR_PTR(-EINVAL);
1420 } 1430 }
1421 return result; 1431 return result;
@@ -2962,6 +2972,54 @@ trace:
2962} 2972}
2963EXPORT_SYMBOL(i2c_smbus_xfer); 2973EXPORT_SYMBOL(i2c_smbus_xfer);
2964 2974
2975int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
2976{
2977 int ret;
2978
2979 if (!client || !slave_cb)
2980 return -EINVAL;
2981
2982 if (!(client->flags & I2C_CLIENT_TEN)) {
2983 /* Enforce stricter address checking */
2984 ret = i2c_check_addr_validity(client->addr);
2985 if (ret)
2986 return ret;
2987 }
2988
2989 if (!client->adapter->algo->reg_slave)
2990 return -EOPNOTSUPP;
2991
2992 client->slave_cb = slave_cb;
2993
2994 i2c_lock_adapter(client->adapter);
2995 ret = client->adapter->algo->reg_slave(client);
2996 i2c_unlock_adapter(client->adapter);
2997
2998 if (ret)
2999 client->slave_cb = NULL;
3000
3001 return ret;
3002}
3003EXPORT_SYMBOL_GPL(i2c_slave_register);
3004
3005int i2c_slave_unregister(struct i2c_client *client)
3006{
3007 int ret;
3008
3009 if (!client->adapter->algo->unreg_slave)
3010 return -EOPNOTSUPP;
3011
3012 i2c_lock_adapter(client->adapter);
3013 ret = client->adapter->algo->unreg_slave(client);
3014 i2c_unlock_adapter(client->adapter);
3015
3016 if (ret == 0)
3017 client->slave_cb = NULL;
3018
3019 return ret;
3020}
3021EXPORT_SYMBOL_GPL(i2c_slave_unregister);
3022
2965MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); 3023MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
2966MODULE_DESCRIPTION("I2C-Bus main module"); 3024MODULE_DESCRIPTION("I2C-Bus main module");
2967MODULE_LICENSE("GPL"); 3025MODULE_LICENSE("GPL");