--- linux-v31/drivers/i2c/i2c-core.c 2004-02-19 19:31:07.000000000 -0600 +++ linux/drivers/i2c/i2c-core.c 2004-03-10 09:48:08.000000000 -0600 @@ -1256,6 +1256,12 @@ return (func & adap_func) == func; } +int i2c_spin_delay; +void i2c_set_spin_delay(int val) +{ + i2c_spin_delay = val; +} + EXPORT_SYMBOL(i2c_add_adapter); EXPORT_SYMBOL(i2c_del_adapter); EXPORT_SYMBOL(i2c_add_driver); @@ -1292,6 +1298,8 @@ EXPORT_SYMBOL(i2c_get_functionality); EXPORT_SYMBOL(i2c_check_functionality); +EXPORT_SYMBOL(i2c_set_spin_delay); +EXPORT_SYMBOL(i2c_spin_delay); MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus main module"); --- linux-v31/include/linux/i2c.h 2003-12-17 20:58:16.000000000 -0600 +++ linux/include/linux/i2c.h 2004-03-10 09:47:21.000000000 -0600 @@ -600,10 +600,24 @@ ((adapptr)->algo->id == I2C_ALGO_ISA) /* Tiny delay function used by the i2c bus drivers */ + +extern void i2c_set_spin_delay(int val); +extern int i2c_spin_delay; +#include static inline void i2c_delay(signed long timeout) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); + if( i2c_spin_delay ) { + /* spin delay is needed for panic threads and + shutdowns to avoid processing switching so IPMI + messages can be sent to the Baseboard Management + Controllers on the SMBus*/ + int i; + for( i=0 ; i<100 ; i++ ) + udelay(timeout*(1000000/HZ/100)); + } else { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(timeout); + } } #endif /* _LINUX_I2C_H */