Rev 2131 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2131 | Rev 2456 | ||
---|---|---|---|
Line 49... | Line 49... | ||
49 | #include <console/console.h> |
49 | #include <console/console.h> |
50 | #include <interrupt.h> |
50 | #include <interrupt.h> |
51 | #include <arch/interrupt.h> |
51 | #include <arch/interrupt.h> |
52 | #include <sysinfo/sysinfo.h> |
52 | #include <sysinfo/sysinfo.h> |
53 | #include <synch/spinlock.h> |
53 | #include <synch/spinlock.h> |
- | 54 | #include <synch/rcu.h> |
|
54 | 55 | ||
55 | #define LSR_DATA_READY 0x01 |
56 | #define LSR_DATA_READY 0x01 |
56 | 57 | ||
57 | /** Structure representing the ns16550. */ |
58 | /** Structure representing the ns16550. */ |
58 | static ns16550_t ns16550; |
59 | static ns16550_t ns16550; |
Line 84... | Line 85... | ||
84 | ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */ |
85 | ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */ |
85 | 86 | ||
86 | while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) |
87 | while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) |
87 | (void) ns16550_rbr_read(&ns16550); |
88 | (void) ns16550_rbr_read(&ns16550); |
88 | 89 | ||
89 | spinlock_lock(&ns16550_irq.lock); |
90 | //rcu_read_lock() is not needed, ints are disabled |
90 | ns16550_irq.notif_cfg.notify = false; |
91 | //rcu: atomic update doesn't need reallocation |
91 | spinlock_unlock(&ns16550_irq.lock); |
92 | rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = false; |
92 | interrupts_restore(ipl); |
93 | interrupts_restore(ipl); |
93 | } |
94 | } |
94 | 95 | ||
95 | /** Resume the former interrupt vector */ |
96 | /** Resume the former interrupt vector */ |
96 | void ns16550_release(void) |
97 | void ns16550_release(void) |
97 | { |
98 | { |
98 | ipl_t ipl = interrupts_disable(); |
99 | ipl_t ipl = interrupts_disable(); |
- | 100 | //rcu: atomic update doesn't need reallocation |
|
99 | spinlock_lock(&ns16550_irq.lock); |
101 | spinlock_lock(&ns16550_irq.lock); |
100 | if (ns16550_irq.notif_cfg.answerbox) |
102 | if (rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox) |
101 | ns16550_irq.notif_cfg.notify = true; |
103 | rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = true; |
102 | spinlock_unlock(&ns16550_irq.lock); |
104 | spinlock_unlock(&ns16550_irq.lock); |
103 | interrupts_restore(ipl); |
105 | interrupts_restore(ipl); |
104 | } |
106 | } |
105 | 107 | ||
106 | /** Initialize ns16550. |
108 | /** Initialize ns16550. |
Line 181... | Line 183... | ||
181 | 183 | ||
182 | ipl = interrupts_disable(); |
184 | ipl = interrupts_disable(); |
183 | spinlock_lock(&ns16550_irq.lock); |
185 | spinlock_lock(&ns16550_irq.lock); |
184 | 186 | ||
185 | if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
187 | if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
186 | if (ns16550_irq.notif_cfg.notify && ns16550_irq.notif_cfg.answerbox) { |
188 | if (rcu_dereference_pointer(ns16550_irq.notif_cfg).notify && rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox) { |
187 | /* |
189 | /* |
188 | * Send IPC notification. |
190 | * Send IPC notification. |
189 | */ |
191 | */ |
190 | ipc_irq_send_notif(&ns16550_irq); |
192 | ipc_irq_send_notif(&ns16550_irq); |
191 | spinlock_unlock(&ns16550_irq.lock); |
193 | spinlock_unlock(&ns16550_irq.lock); |