diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/rtlx.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index e14ae09eda2b..16d3fdecf3ea 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
@@ -146,7 +146,7 @@ static void stopping(int vpe) | |||
146 | 146 | ||
147 | int rtlx_open(int index, int can_sleep) | 147 | int rtlx_open(int index, int can_sleep) |
148 | { | 148 | { |
149 | volatile struct rtlx_info **p; | 149 | struct rtlx_info **p; |
150 | struct rtlx_channel *chan; | 150 | struct rtlx_channel *chan; |
151 | enum rtlx_state state; | 151 | enum rtlx_state state; |
152 | int ret = 0; | 152 | int ret = 0; |
@@ -179,13 +179,24 @@ int rtlx_open(int index, int can_sleep) | |||
179 | } | 179 | } |
180 | } | 180 | } |
181 | 181 | ||
182 | smp_rmb(); | ||
182 | if (*p == NULL) { | 183 | if (*p == NULL) { |
183 | if (can_sleep) { | 184 | if (can_sleep) { |
184 | __wait_event_interruptible(channel_wqs[index].lx_queue, | 185 | DEFINE_WAIT(wait); |
185 | *p != NULL, | 186 | |
186 | ret); | 187 | for (;;) { |
187 | if (ret) | 188 | prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); |
189 | smp_rmb(); | ||
190 | if (*p != NULL) | ||
191 | break; | ||
192 | if (!signal_pending(current)) { | ||
193 | schedule(); | ||
194 | continue; | ||
195 | } | ||
196 | ret = -ERESTARTSYS; | ||
188 | goto out_fail; | 197 | goto out_fail; |
198 | } | ||
199 | finish_wait(&channel_wqs[index].lx_queue, &wait); | ||
189 | } else { | 200 | } else { |
190 | printk(" *vpe_get_shared is NULL. " | 201 | printk(" *vpe_get_shared is NULL. " |
191 | "Has an SP program been loaded?\n"); | 202 | "Has an SP program been loaded?\n"); |