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); |