diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-cpm.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-cpm.c | 56 |
1 files changed, 21 insertions, 35 deletions
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f2de3be35df..f3b89a4698b 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -33,16 +33,16 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/errno.h> #include <linux/stddef.h> #include <linux/i2c.h> #include <linux/io.h> #include <linux/dma-mapping.h> +#include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> -#include <linux/of_i2c.h> #include <sysdev/fsl_soc.h> #include <asm/cpm.h> @@ -338,6 +338,14 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) tptr = 0; rptr = 0; + /* + * If there was a collision in the last i2c transaction, + * Set I2COM_MASTER as it was cleared during collision. + */ + if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) { + out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); + } + while (tptr < num) { pmsg = &msgs[tptr]; dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr); @@ -426,7 +434,7 @@ static const struct i2c_adapter cpm_ops = { .algo = &cpm_i2c_algo, }; -static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) +static int cpm_i2c_setup(struct cpm_i2c *cpm) { struct platform_device *ofdev = cpm->ofdev; const u32 *data; @@ -440,7 +448,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) init_waitqueue_head(&cpm->i2c_wait); - cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); + cpm->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (!cpm->irq) return -EINVAL; @@ -634,8 +642,7 @@ static void cpm_i2c_shutdown(struct cpm_i2c *cpm) cpm_muram_free(cpm->i2c_addr); } -static int __devinit cpm_i2c_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int cpm_i2c_probe(struct platform_device *ofdev) { int result, len; struct cpm_i2c *cpm; @@ -647,7 +654,7 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, cpm->ofdev = ofdev; - dev_set_drvdata(&ofdev->dev, cpm); + platform_set_drvdata(ofdev, cpm); cpm->adap = cpm_ops; i2c_set_adapdata(&cpm->adap, cpm); @@ -663,11 +670,8 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, /* register new adapter to i2c module... */ data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len); - if (data && len == 4) { - cpm->adap.nr = *data; - result = i2c_add_numbered_adapter(&cpm->adap); - } else - result = i2c_add_adapter(&cpm->adap); + cpm->adap.nr = (data && len == 4) ? be32_to_cpup(data) : -1; + result = i2c_add_numbered_adapter(&cpm->adap); if (result < 0) { dev_err(&ofdev->dev, "Unable to register with I2C\n"); @@ -677,30 +681,23 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", cpm->adap.name); - /* - * register OF I2C devices - */ - of_i2c_register_devices(&cpm->adap); - return 0; out_shut: cpm_i2c_shutdown(cpm); out_free: - dev_set_drvdata(&ofdev->dev, NULL); kfree(cpm); return result; } -static int __devexit cpm_i2c_remove(struct platform_device *ofdev) +static int cpm_i2c_remove(struct platform_device *ofdev) { - struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev); + struct cpm_i2c *cpm = platform_get_drvdata(ofdev); i2c_del_adapter(&cpm->adap); cpm_i2c_shutdown(cpm); - dev_set_drvdata(&ofdev->dev, NULL); kfree(cpm); return 0; @@ -718,9 +715,9 @@ static const struct of_device_id cpm_i2c_match[] = { MODULE_DEVICE_TABLE(of, cpm_i2c_match); -static struct of_platform_driver cpm_i2c_driver = { +static struct platform_driver cpm_i2c_driver = { .probe = cpm_i2c_probe, - .remove = __devexit_p(cpm_i2c_remove), + .remove = cpm_i2c_remove, .driver = { .name = "fsl-i2c-cpm", .owner = THIS_MODULE, @@ -728,18 +725,7 @@ static struct of_platform_driver cpm_i2c_driver = { }, }; -static int __init cpm_i2c_init(void) -{ - return of_register_platform_driver(&cpm_i2c_driver); -} - -static void __exit cpm_i2c_exit(void) -{ - of_unregister_platform_driver(&cpm_i2c_driver); -} - -module_init(cpm_i2c_init); -module_exit(cpm_i2c_exit); +module_platform_driver(cpm_i2c_driver); MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>"); MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards"); |
