Subject: i2c-parport: Fix a minor race on driver unload When unloading the driver, we really want to unregister the i2c adapter before we power it off, rather than the other way around. Also speed up the bus a bit when we can sense SCL. The slaves will stretch the line as needed. Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-parport.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) --- linux-2.6.21-rc3.orig/drivers/i2c/busses/i2c-parport.c 2007-03-08 07:41:02.000000000 +0100 +++ linux-2.6.21-rc3/drivers/i2c/busses/i2c-parport.c 2007-03-08 09:01:16.000000000 +0100 @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------ * * i2c-parport.c I2C bus over parallel port * * ------------------------------------------------------------------------ * - Copyright (C) 2003-2004 Jean Delvare + Copyright (C) 2003-2007 Jean Delvare Based on older i2c-philips-par.c driver Copyright (C) 1995-2000 Simon G. Vogl @@ -137,7 +137,7 @@ static struct i2c_algo_bit_data parport_ .setscl = parport_setscl, .getsda = parport_getsda, .getscl = parport_getscl, - .udelay = 60, + .udelay = 20, /* ~16 kbps */ .timeout = HZ, }; @@ -168,8 +168,11 @@ static void i2c_parport_attach (struct p strlcpy(adapter->adapter.name, "Parallel port adapter", sizeof(adapter->adapter.name)); adapter->algo_data = parport_algo_data; - if (!adapter_parm[type].getscl.val) + /* Slow down if we can't sense SCL */ + if (!adapter_parm[type].getscl.val) { adapter->algo_data.getscl = NULL; + adapter->algo_data.udelay = 55; /* ~6 kbps */ + } adapter->algo_data.data = port; adapter->adapter.algo_data = &adapter->algo_data; @@ -211,11 +214,12 @@ static void i2c_parport_detach (struct p for (prev = NULL, adapter = adapter_list; adapter; prev = adapter, adapter = adapter->next) { if (adapter->pdev->port == port) { + i2c_del_adapter(&adapter->adapter); + /* Un-init if needed (power off...) */ if (adapter_parm[type].init.val) line_set(port, 0, &adapter_parm[type].init); - i2c_del_adapter(&adapter->adapter); parport_unregister_device(adapter->pdev); if (prev) prev->next = adapter->next;