aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2006-09-29 05:01:08 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-29 12:18:20 -0400
commite8106b941ceab68cc5ff713df7b1276484554584 (patch)
tree6d8ad676796f4469aa334589565e971932049bc4
parent6ea36ddbd1abfe867f1e874a8312bfd811e5fd2c (diff)
[PATCH] lockdep: core, add enable/disable_irq_irqsave/irqrestore() APIs
Introduce the disable_irq_nosync_lockdep_irqsave() and enable_irq_lockdep_irqrestore() APIs. These are needed for NE2000; basically NE2000 calls disable_irq and enable_irq as locking against the IRQ handler, but both in cases where interrupts are on and off. This means that lockdep needs to track the old state of the virtual irq flags on disable_irq, and restore these at enable_irq time. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Jeff Garzik <jeff@garzik.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/net/8390.c6
-rw-r--r--include/linux/interrupt.h16
2 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index 5b6b05ed8f3c..9d34056147ad 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
299 * Slow phase with lock held. 299 * Slow phase with lock held.
300 */ 300 */
301 301
302 disable_irq_nosync_lockdep(dev->irq); 302 disable_irq_nosync_lockdep_irqsave(dev->irq, &flags);
303 303
304 spin_lock(&ei_local->page_lock); 304 spin_lock(&ei_local->page_lock);
305 305
@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
338 netif_stop_queue(dev); 338 netif_stop_queue(dev);
339 outb_p(ENISR_ALL, e8390_base + EN0_IMR); 339 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
340 spin_unlock(&ei_local->page_lock); 340 spin_unlock(&ei_local->page_lock);
341 enable_irq_lockdep(dev->irq); 341 enable_irq_lockdep_irqrestore(dev->irq, &flags);
342 ei_local->stat.tx_errors++; 342 ei_local->stat.tx_errors++;
343 return 1; 343 return 1;
344 } 344 }
@@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
379 outb_p(ENISR_ALL, e8390_base + EN0_IMR); 379 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
380 380
381 spin_unlock(&ei_local->page_lock); 381 spin_unlock(&ei_local->page_lock);
382 enable_irq_lockdep(dev->irq); 382 enable_irq_lockdep_irqrestore(dev->irq, &flags);
383 383
384 dev_kfree_skb (skb); 384 dev_kfree_skb (skb);
385 ei_local->stat.tx_bytes += send_length; 385 ei_local->stat.tx_bytes += send_length;
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index d5afee95fd43..1f97e3d92639 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
123#endif 123#endif
124} 124}
125 125
126static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
127{
128 disable_irq_nosync(irq);
129#ifdef CONFIG_LOCKDEP
130 local_irq_save(*flags);
131#endif
132}
133
126static inline void disable_irq_lockdep(unsigned int irq) 134static inline void disable_irq_lockdep(unsigned int irq)
127{ 135{
128 disable_irq(irq); 136 disable_irq(irq);
@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq)
139 enable_irq(irq); 147 enable_irq(irq);
140} 148}
141 149
150static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
151{
152#ifdef CONFIG_LOCKDEP
153 local_irq_restore(*flags);
154#endif
155 enable_irq(irq);
156}
157
142/* IRQ wakeup (PM) control: */ 158/* IRQ wakeup (PM) control: */
143extern int set_irq_wake(unsigned int irq, unsigned int on); 159extern int set_irq_wake(unsigned int irq, unsigned int on);
144 160