aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/rtlx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/rtlx.c')
-rw-r--r--arch/mips/kernel/rtlx.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 0233798f7155..b88f1c18ff4d 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -72,6 +72,15 @@ static void rtlx_dispatch(void)
72static irqreturn_t rtlx_interrupt(int irq, void *dev_id) 72static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
73{ 73{
74 int i; 74 int i;
75 unsigned int flags, vpeflags;
76
77 /* Ought not to be strictly necessary for SMTC builds */
78 local_irq_save(flags);
79 vpeflags = dvpe();
80 set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
81 irq_enable_hazard();
82 evpe(vpeflags);
83 local_irq_restore(flags);
75 84
76 for (i = 0; i < RTLX_CHANNELS; i++) { 85 for (i = 0; i < RTLX_CHANNELS; i++) {
77 wake_up(&channel_wqs[i].lx_queue); 86 wake_up(&channel_wqs[i].lx_queue);
@@ -108,7 +117,8 @@ static void __used dump_rtlx(void)
108static int rtlx_init(struct rtlx_info *rtlxi) 117static int rtlx_init(struct rtlx_info *rtlxi)
109{ 118{
110 if (rtlxi->id != RTLX_ID) { 119 if (rtlxi->id != RTLX_ID) {
111 printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id); 120 printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
121 rtlxi, rtlxi->id);
112 return -ENOEXEC; 122 return -ENOEXEC;
113 } 123 }
114 124
@@ -162,18 +172,17 @@ int rtlx_open(int index, int can_sleep)
162 172
163 if (rtlx == NULL) { 173 if (rtlx == NULL) {
164 if( (p = vpe_get_shared(tclimit)) == NULL) { 174 if( (p = vpe_get_shared(tclimit)) == NULL) {
165 if (can_sleep) { 175 if (can_sleep) {
166 __wait_event_interruptible(channel_wqs[index].lx_queue, 176 __wait_event_interruptible(channel_wqs[index].lx_queue,
167 (p = vpe_get_shared(tclimit)), 177 (p = vpe_get_shared(tclimit)), ret);
168 ret); 178 if (ret)
169 if (ret)
170 goto out_fail;
171 } else {
172 printk(KERN_DEBUG "No SP program loaded, and device "
173 "opened with O_NONBLOCK\n");
174 ret = -ENOSYS;
175 goto out_fail; 179 goto out_fail;
176 } 180 } else {
181 printk(KERN_DEBUG "No SP program loaded, and device "
182 "opened with O_NONBLOCK\n");
183 ret = -ENOSYS;
184 goto out_fail;
185 }
177 } 186 }
178 187
179 smp_rmb(); 188 smp_rmb();
@@ -182,7 +191,9 @@ int rtlx_open(int index, int can_sleep)
182 DEFINE_WAIT(wait); 191 DEFINE_WAIT(wait);
183 192
184 for (;;) { 193 for (;;) {
185 prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); 194 prepare_to_wait(
195 &channel_wqs[index].lx_queue,
196 &wait, TASK_INTERRUPTIBLE);
186 smp_rmb(); 197 smp_rmb();
187 if (*p != NULL) 198 if (*p != NULL)
188 break; 199 break;
@@ -195,7 +206,7 @@ int rtlx_open(int index, int can_sleep)
195 } 206 }
196 finish_wait(&channel_wqs[index].lx_queue, &wait); 207 finish_wait(&channel_wqs[index].lx_queue, &wait);
197 } else { 208 } else {
198 printk(" *vpe_get_shared is NULL. " 209 pr_err(" *vpe_get_shared is NULL. "
199 "Has an SP program been loaded?\n"); 210 "Has an SP program been loaded?\n");
200 ret = -ENOSYS; 211 ret = -ENOSYS;
201 goto out_fail; 212 goto out_fail;
@@ -203,8 +214,9 @@ int rtlx_open(int index, int can_sleep)
203 } 214 }
204 215
205 if ((unsigned int)*p < KSEG0) { 216 if ((unsigned int)*p < KSEG0) {
206 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " 217 printk(KERN_WARNING "vpe_get_shared returned an "
207 "maybe an error code %d\n", (int)*p); 218 "invalid pointer maybe an error code %d\n",
219 (int)*p);
208 ret = -ENOSYS; 220 ret = -ENOSYS;
209 goto out_fail; 221 goto out_fail;
210 } 222 }
@@ -232,6 +244,10 @@ out_ret:
232 244
233int rtlx_release(int index) 245int rtlx_release(int index)
234{ 246{
247 if (rtlx == NULL) {
248 pr_err("rtlx_release() with null rtlx\n");
249 return 0;
250 }
235 rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; 251 rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
236 return 0; 252 return 0;
237} 253}
@@ -251,8 +267,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep)
251 int ret = 0; 267 int ret = 0;
252 268
253 __wait_event_interruptible(channel_wqs[index].lx_queue, 269 __wait_event_interruptible(channel_wqs[index].lx_queue,
254 chan->lx_read != chan->lx_write || sp_stopping, 270 (chan->lx_read != chan->lx_write) ||
255 ret); 271 sp_stopping, ret);
256 if (ret) 272 if (ret)
257 return ret; 273 return ret;
258 274
@@ -282,7 +298,9 @@ static inline int write_spacefree(int read, int write, int size)
282unsigned int rtlx_write_poll(int index) 298unsigned int rtlx_write_poll(int index)
283{ 299{
284 struct rtlx_channel *chan = &rtlx->channel[index]; 300 struct rtlx_channel *chan = &rtlx->channel[index];
285 return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); 301
302 return write_spacefree(chan->rt_read, chan->rt_write,
303 chan->buffer_size);
286} 304}
287 305
288ssize_t rtlx_read(int index, void __user *buff, size_t count) 306ssize_t rtlx_read(int index, void __user *buff, size_t count)
@@ -344,8 +362,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
344 rt_read = rt->rt_read; 362 rt_read = rt->rt_read;
345 363
346 /* total number of bytes to copy */ 364 /* total number of bytes to copy */
347 count = min(count, 365 count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
348 (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size)); 366 rt->buffer_size));
349 367
350 /* first bit from write pointer to the end of the buffer, or count */ 368 /* first bit from write pointer to the end of the buffer, or count */
351 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 369 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
@@ -514,6 +532,11 @@ static int __init rtlx_module_init(void)
514 532
515 if (cpu_has_vint) 533 if (cpu_has_vint)
516 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 534 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
535 else {
536 pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
537 err = -ENODEV;
538 goto out_chrdev;
539 }
517 540
518 rtlx_irq.dev_id = rtlx; 541 rtlx_irq.dev_id = rtlx;
519 setup_irq(rtlx_irq_num, &rtlx_irq); 542 setup_irq(rtlx_irq_num, &rtlx_irq);