X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fi2c%2Fbusses%2Fi2c-iop3xx.c;h=cfae4ad00faee2bb6ca81b1ed34a7c71f1c66126;hb=185a257f2f73bcd89050ad02da5bedbc28fc43fa;hp=9888fae1f37a8f90ea34fd658573162e08b0007c;hpb=5615ca7906aefbdc3318604c89db5931d0a25910;p=pandora-kernel.git diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 9888fae1f37a..8e413150af37 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -11,7 +11,7 @@ * * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund * - * And which acknowledged Kyösti Mälkki , + * And which acknowledged Kyösti Mälkki , * Frodo Looijaard , Martin Bailey * * Major cleanup by Deepak Saxena , 01/2005: @@ -21,12 +21,14 @@ * - Make it work with IXP46x chips * - Cleanup function names, coding style, etc * + * - writing to slave address causes latchup on iop331. + * fix: driver refuses to address self. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ -#include #include #include #include @@ -35,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -73,12 +75,6 @@ iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); } -static void -iop3xx_i2c_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap) -{ - __raw_writel(MYSAR, iop3xx_adap->ioaddr + SAR_OFFSET); -} - static void iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) { @@ -184,7 +180,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, do { interrupted = wait_event_interruptible_timeout ( iop3xx_adap->waitq, - (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )), + (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )), 1 * HZ; ); if ((rc = iop3xx_i2c_error(sr)) < 0) { @@ -249,6 +245,13 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, int status; int rc; + /* avoid writing to my slave address (hangs on 80331), + * forbidden in Intel developer manual + */ + if (msg->addr == MYSAR) { + return -EBUSY; + } + __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); @@ -398,17 +401,16 @@ iop3xx_i2c_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm iop3xx_i2c_algo = { +static const struct i2c_algorithm iop3xx_i2c_algo = { .master_xfer = iop3xx_i2c_master_xfer, .algo_control = iop3xx_i2c_algo_control, .functionality = iop3xx_i2c_func, }; static int -iop3xx_i2c_remove(struct device *device) +iop3xx_i2c_remove(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(device); - struct i2c_adapter *padapter = dev_get_drvdata(&pdev->dev); + struct i2c_adapter *padapter = platform_get_drvdata(pdev); struct i2c_algo_iop3xx_data *adapter_data = (struct i2c_algo_iop3xx_data *)padapter->algo_data; struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -426,17 +428,16 @@ iop3xx_i2c_remove(struct device *device) kfree(adapter_data); kfree(padapter); - dev_set_drvdata(&pdev->dev, NULL); + platform_set_drvdata(pdev, NULL); return 0; } static int -iop3xx_i2c_probe(struct device *dev) +iop3xx_i2c_probe(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(dev); struct resource *res; - int ret; + int ret, irq; struct i2c_adapter *new_adapter; struct i2c_algo_iop3xx_data *adapter_data; @@ -472,9 +473,15 @@ iop3xx_i2c_probe(struct device *dev) goto release_region; } - res = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = -ENXIO; + goto unmap; + } + ret = request_irq(irq, iop3xx_i2c_irq_handler, 0, pdev->name, adapter_data); - if (res) { + + if (ret) { ret = -EIO; goto unmap; } @@ -495,10 +502,9 @@ iop3xx_i2c_probe(struct device *dev) spin_lock_init(&adapter_data->lock); iop3xx_i2c_reset(adapter_data); - iop3xx_i2c_set_slave_addr(adapter_data); iop3xx_i2c_enable(adapter_data); - dev_set_drvdata(&pdev->dev, new_adapter); + platform_set_drvdata(pdev, new_adapter); new_adapter->algo_data = adapter_data; i2c_add_adapter(new_adapter); @@ -522,24 +528,25 @@ out: } -static struct device_driver iop3xx_i2c_driver = { - .owner = THIS_MODULE, - .name = "IOP3xx-I2C", - .bus = &platform_bus_type, +static struct platform_driver iop3xx_i2c_driver = { .probe = iop3xx_i2c_probe, - .remove = iop3xx_i2c_remove + .remove = iop3xx_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = "IOP3xx-I2C", + }, }; static int __init i2c_iop3xx_init (void) { - return driver_register(&iop3xx_i2c_driver); + return platform_driver_register(&iop3xx_i2c_driver); } static void __exit i2c_iop3xx_exit (void) { - driver_unregister(&iop3xx_i2c_driver); + platform_driver_unregister(&iop3xx_i2c_driver); return; }