From 41e1b8fb97646d0f8652669bdadf7cf2ca0bff4a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 5 Aug 2005 04:12:48 -0700 Subject: [PATCH] --- yaml --- r: 5668 b: refs/heads/master c: b7656e7f2944984befa3ab99a5b99f99a23b302b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/char/rtc.c | 7 ++----- trunk/drivers/sbus/char/vfc.h | 2 ++ trunk/drivers/sbus/char/vfc_dev.c | 1 + trunk/drivers/sbus/char/vfc_i2c.c | 19 +++++++++++++++++-- trunk/net/ipv4/fib_semantics.c | 9 ++++++++- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index d9dfaf5e713c..e62a756459d9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 107207aa8576963861e9f0c66b439d233f02a97d +refs/heads/master: b7656e7f2944984befa3ab99a5b99f99a23b302b diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index cd4fe8b1709f..d8f9e94ae475 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -1209,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file) void rtc_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long uip_watchdog = jiffies; unsigned char ctrl; #ifdef CONFIG_MACH_DECSTATION unsigned int real_year; @@ -1225,10 +1224,8 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) * Once the read clears, read the RTC time (again via ioctl). Easy. */ - while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + if (rtc_is_updating() != 0) + msleep(20); /* * Only the values that we read from the RTC are set. We leave diff --git a/trunk/drivers/sbus/char/vfc.h b/trunk/drivers/sbus/char/vfc.h index a7782e7da42e..e56a43af0f62 100644 --- a/trunk/drivers/sbus/char/vfc.h +++ b/trunk/drivers/sbus/char/vfc.h @@ -129,6 +129,8 @@ struct vfc_dev { struct vfc_regs *phys_regs; unsigned int control_reg; struct semaphore device_lock_sem; + struct timer_list poll_timer; + wait_queue_head_t poll_wait; int instance; int busy; unsigned long which_io; diff --git a/trunk/drivers/sbus/char/vfc_dev.c b/trunk/drivers/sbus/char/vfc_dev.c index 7a103698fa3c..86ce54130954 100644 --- a/trunk/drivers/sbus/char/vfc_dev.c +++ b/trunk/drivers/sbus/char/vfc_dev.c @@ -137,6 +137,7 @@ int init_vfc_devstruct(struct vfc_dev *dev, int instance) dev->instance=instance; init_MUTEX(&dev->device_lock_sem); dev->control_reg=0; + init_waitqueue_head(&dev->poll_wait); dev->busy=0; return 0; } diff --git a/trunk/drivers/sbus/char/vfc_i2c.c b/trunk/drivers/sbus/char/vfc_i2c.c index 739cad9b19a1..1faf1e75f71f 100644 --- a/trunk/drivers/sbus/char/vfc_i2c.c +++ b/trunk/drivers/sbus/char/vfc_i2c.c @@ -79,10 +79,25 @@ int vfc_pcf8584_init(struct vfc_dev *dev) return 0; } +void vfc_i2c_delay_wakeup(struct vfc_dev *dev) +{ + /* Used to profile code and eliminate too many delays */ + VFC_I2C_DEBUG_PRINTK(("vfc%d: Delaying\n", dev->instance)); + wake_up(&dev->poll_wait); +} + void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(usecs)); + DEFINE_WAIT(wait); + init_timer(&dev->poll_timer); + dev->poll_timer.expires = jiffies + usecs_to_jiffies(usecs); + dev->poll_timer.data=(unsigned long)dev; + dev->poll_timer.function=(void *)(unsigned long)vfc_i2c_delay_wakeup; + add_timer(&dev->poll_timer); + prepare_to_wait(&dev->poll_wait, &wait, TASK_UNINTERRUPTIBLE); + schedule(); + del_timer(&dev->poll_timer); + finish_wait(&dev->poll_wait, &wait); } void inline vfc_i2c_delay(struct vfc_dev *dev) diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index c886b28ba9f5..e278cb9d0075 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -593,10 +593,13 @@ static void fib_hash_move(struct hlist_head *new_info_hash, struct hlist_head *new_laddrhash, unsigned int new_size) { + struct hlist_head *old_info_hash, *old_laddrhash; unsigned int old_size = fib_hash_size; - unsigned int i; + unsigned int i, bytes; write_lock(&fib_info_lock); + old_info_hash = fib_info_hash; + old_laddrhash = fib_info_laddrhash; fib_hash_size = new_size; for (i = 0; i < old_size; i++) { @@ -636,6 +639,10 @@ static void fib_hash_move(struct hlist_head *new_info_hash, fib_info_laddrhash = new_laddrhash; write_unlock(&fib_info_lock); + + bytes = old_size * sizeof(struct hlist_head *); + fib_hash_free(old_info_hash, bytes); + fib_hash_free(old_laddrhash, bytes); } struct fib_info *