1 /* 2 * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. 3 * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org) 4 * 5 * This program is free software; you can distribute it and/or modify it 6 * under the terms of the GNU General Public License (Version 2) as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 * 18 */ 19 20 #include <linux/device.h> 21 #include <linux/kernel.h> 22 #include <linux/fs.h> 23 #include <linux/init.h> 24 #include <asm/uaccess.h> 25 #include <linux/list.h> 26 #include <linux/vmalloc.h> 27 #include <linux/elf.h> 28 #include <linux/seq_file.h> 29 #include <linux/syscalls.h> 30 #include <linux/moduleloader.h> 31 #include <linux/interrupt.h> 32 #include <linux/poll.h> 33 #include <linux/sched.h> 34 #include <linux/wait.h> 35 #include <asm/mipsmtregs.h> 36 #include <asm/mips_mt.h> 37 #include <asm/cacheflush.h> 38 #include <linux/atomic.h> 39 #include <asm/cpu.h> 40 #include <asm/processor.h> 41 #include <asm/vpe.h> 42 #include <asm/rtlx.h> 43 44 static struct rtlx_info *rtlx; 45 static int major; 46 static char module_name[] = "rtlx"; 47 48 static struct chan_waitqueues { 49 wait_queue_head_t rt_queue; 50 wait_queue_head_t lx_queue; 51 atomic_t in_open; 52 struct mutex mutex; 53 } channel_wqs[RTLX_CHANNELS]; 54 55 static struct vpe_notifications notify; 56 static int sp_stopping; 57 58 extern void *vpe_get_shared(int index); 59 60 static void rtlx_dispatch(void) 61 { 62 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ); 63 } 64 65 66 /* Interrupt handler may be called before rtlx_init has otherwise had 67 a chance to run. 68 */ 69 static irqreturn_t rtlx_interrupt(int irq, void *dev_id) 70 { 71 unsigned int vpeflags; 72 unsigned long flags; 73 int i; 74 75 /* Ought not to be strictly necessary for SMTC builds */ 76 local_irq_save(flags); 77 vpeflags = dvpe(); 78 set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ); 79 irq_enable_hazard(); 80 evpe(vpeflags); 81 local_irq_restore(flags); 82 83 for (i = 0; i < RTLX_CHANNELS; i++) { 84 wake_up(&channel_wqs[i].lx_queue); 85 wake_up(&channel_wqs[i].rt_queue); 86 } 87 88 return IRQ_HANDLED; 89 } 90 91 static void __used dump_rtlx(void) 92 { 93 int i; 94 95 printk("id 0x%lx state %d\n", rtlx->id, rtlx->state); 96 97 for (i = 0; i < RTLX_CHANNELS; i++) { 98 struct rtlx_channel *chan = &rtlx->channel[i]; 99 100 printk(" rt_state %d lx_state %d buffer_size %d\n", 101 chan->rt_state, chan->lx_state, chan->buffer_size); 102 103 printk(" rt_read %d rt_write %d\n", 104 chan->rt_read, chan->rt_write); 105 106 printk(" lx_read %d lx_write %d\n", 107 chan->lx_read, chan->lx_write); 108 109 printk(" rt_buffer <%s>\n", chan->rt_buffer); 110 printk(" lx_buffer <%s>\n", chan->lx_buffer); 111 } 112 } 113 114 /* call when we have the address of the shared structure from the SP side. */ 115 static int rtlx_init(struct rtlx_info *rtlxi) 116 { 117 if (rtlxi->id != RTLX_ID) { 118 printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", 119 rtlxi, rtlxi->id); 120 return -ENOEXEC; 121 } 122 123 rtlx = rtlxi; 124 125 return 0; 126 } 127 128 /* notifications */ 129 static void starting(int vpe) 130 { 131 int i; 132 sp_stopping = 0; 133 134 /* force a reload of rtlx */ 135 rtlx=NULL; 136 137 /* wake up any sleeping rtlx_open's */ 138 for (i = 0; i < RTLX_CHANNELS; i++) 139 wake_up_interruptible(&channel_wqs[i].lx_queue); 140 } 141 142 static void stopping(int vpe) 143 { 144 int i; 145 146 sp_stopping = 1; 147 for (i = 0; i < RTLX_CHANNELS; i++) 148 wake_up_interruptible(&channel_wqs[i].lx_queue); 149 } 150 151 152 int rtlx_open(int index, int can_sleep) 153 { 154 struct rtlx_info **p; 155 struct rtlx_channel *chan; 156 enum rtlx_state state; 157 int ret = 0; 158 159 if (index >= RTLX_CHANNELS) { 160 printk(KERN_DEBUG "rtlx_open index out of range\n"); 161 return -ENOSYS; 162 } 163 164 if (atomic_inc_return(&channel_wqs[index].in_open) > 1) { 165 printk(KERN_DEBUG "rtlx_open channel %d already opened\n", 166 index); 167 ret = -EBUSY; 168 goto out_fail; 169 } 170 171 if (rtlx == NULL) { 172 if( (p = vpe_get_shared(tclimit)) == NULL) { 173 if (can_sleep) { 174 __wait_event_interruptible(channel_wqs[index].lx_queue, 175 (p = vpe_get_shared(tclimit)), ret); 176 if (ret) 177 goto out_fail; 178 } else { 179 printk(KERN_DEBUG "No SP program loaded, and device " 180 "opened with O_NONBLOCK\n"); 181 ret = -ENOSYS; 182 goto out_fail; 183 } 184 } 185 186 smp_rmb(); 187 if (*p == NULL) { 188 if (can_sleep) { 189 DEFINE_WAIT(wait); 190 191 for (;;) { 192 prepare_to_wait( 193 &channel_wqs[index].lx_queue, 194 &wait, TASK_INTERRUPTIBLE); 195 smp_rmb(); 196 if (*p != NULL) 197 break; 198 if (!signal_pending(current)) { 199 schedule(); 200 continue; 201 } 202 ret = -ERESTARTSYS; 203 goto out_fail; 204 } 205 finish_wait(&channel_wqs[index].lx_queue, &wait); 206 } else { 207 pr_err(" *vpe_get_shared is NULL. " 208 "Has an SP program been loaded?\n"); 209 ret = -ENOSYS; 210 goto out_fail; 211 } 212 } 213 214 if ((unsigned int)*p < KSEG0) { 215 printk(KERN_WARNING "vpe_get_shared returned an " 216 "invalid pointer maybe an error code %d\n", 217 (int)*p); 218 ret = -ENOSYS; 219 goto out_fail; 220 } 221 222 if ((ret = rtlx_init(*p)) < 0) 223 goto out_ret; 224 } 225 226 chan = &rtlx->channel[index]; 227 228 state = xchg(&chan->lx_state, RTLX_STATE_OPENED); 229 if (state == RTLX_STATE_OPENED) { 230 ret = -EBUSY; 231 goto out_fail; 232 } 233 234 out_fail: 235 smp_mb(); 236 atomic_dec(&channel_wqs[index].in_open); 237 smp_mb(); 238 239 out_ret: 240 return ret; 241 } 242 243 int rtlx_release(int index) 244 { 245 if (rtlx == NULL) { 246 pr_err("rtlx_release() with null rtlx\n"); 247 return 0; 248 } 249 rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; 250 return 0; 251 } 252 253 unsigned int rtlx_read_poll(int index, int can_sleep) 254 { 255 struct rtlx_channel *chan; 256 257 if (rtlx == NULL) 258 return 0; 259 260 chan = &rtlx->channel[index]; 261 262 /* data available to read? */ 263 if (chan->lx_read == chan->lx_write) { 264 if (can_sleep) { 265 int ret = 0; 266 267 __wait_event_interruptible(channel_wqs[index].lx_queue, 268 (chan->lx_read != chan->lx_write) || 269 sp_stopping, ret); 270 if (ret) 271 return ret; 272 273 if (sp_stopping) 274 return 0; 275 } else 276 return 0; 277 } 278 279 return (chan->lx_write + chan->buffer_size - chan->lx_read) 280 % chan->buffer_size; 281 } 282 283 static inline int write_spacefree(int read, int write, int size) 284 { 285 if (read == write) { 286 /* 287 * Never fill the buffer completely, so indexes are always 288 * equal if empty and only empty, or !equal if data available 289 */ 290 return size - 1; 291 } 292 293 return ((read + size - write) % size) - 1; 294 } 295 296 unsigned int rtlx_write_poll(int index) 297 { 298 struct rtlx_channel *chan = &rtlx->channel[index]; 299 300 return write_spacefree(chan->rt_read, chan->rt_write, 301 chan->buffer_size); 302 } 303 304 ssize_t rtlx_read(int index, void __user *buff, size_t count) 305 { 306 size_t lx_write, fl = 0L; 307 struct rtlx_channel *lx; 308 unsigned long failed; 309 310 if (rtlx == NULL) 311 return -ENOSYS; 312 313 lx = &rtlx->channel[index]; 314 315 mutex_lock(&channel_wqs[index].mutex); 316 smp_rmb(); 317 lx_write = lx->lx_write; 318 319 /* find out how much in total */ 320 count = min(count, 321 (size_t)(lx_write + lx->buffer_size - lx->lx_read) 322 % lx->buffer_size); 323 324 /* then how much from the read pointer onwards */ 325 fl = min(count, (size_t)lx->buffer_size - lx->lx_read); 326 327 failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl); 328 if (failed) 329 goto out; 330 331 /* and if there is anything left at the beginning of the buffer */ 332 if (count - fl) 333 failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl); 334 335 out: 336 count -= failed; 337 338 smp_wmb(); 339 lx->lx_read = (lx->lx_read + count) % lx->buffer_size; 340 smp_wmb(); 341 mutex_unlock(&channel_wqs[index].mutex); 342 343 return count; 344 } 345 346 ssize_t rtlx_write(int index, const void __user *buffer, size_t count) 347 { 348 struct rtlx_channel *rt; 349 unsigned long failed; 350 size_t rt_read; 351 size_t fl; 352 353 if (rtlx == NULL) 354 return(-ENOSYS); 355 356 rt = &rtlx->channel[index]; 357 358 mutex_lock(&channel_wqs[index].mutex); 359 smp_rmb(); 360 rt_read = rt->rt_read; 361 362 /* total number of bytes to copy */ 363 count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write, 364 rt->buffer_size)); 365 366 /* first bit from write pointer to the end of the buffer, or count */ 367 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 368 369 failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl); 370 if (failed) 371 goto out; 372 373 /* if there's any left copy to the beginning of the buffer */ 374 if (count - fl) { 375 failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl); 376 } 377 378 out: 379 count -= failed; 380 381 smp_wmb(); 382 rt->rt_write = (rt->rt_write + count) % rt->buffer_size; 383 smp_wmb(); 384 mutex_unlock(&channel_wqs[index].mutex); 385 386 return count; 387 } 388 389 390 static int file_open(struct inode *inode, struct file *filp) 391 { 392 return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1); 393 } 394 395 static int file_release(struct inode *inode, struct file *filp) 396 { 397 return rtlx_release(iminor(inode)); 398 } 399 400 static unsigned int file_poll(struct file *file, poll_table * wait) 401 { 402 int minor = iminor(file_inode(file)); 403 unsigned int mask = 0; 404 405 poll_wait(file, &channel_wqs[minor].rt_queue, wait); 406 poll_wait(file, &channel_wqs[minor].lx_queue, wait); 407 408 if (rtlx == NULL) 409 return 0; 410 411 /* data available to read? */ 412 if (rtlx_read_poll(minor, 0)) 413 mask |= POLLIN | POLLRDNORM; 414 415 /* space to write */ 416 if (rtlx_write_poll(minor)) 417 mask |= POLLOUT | POLLWRNORM; 418 419 return mask; 420 } 421 422 static ssize_t file_read(struct file *file, char __user * buffer, size_t count, 423 loff_t * ppos) 424 { 425 int minor = iminor(file_inode(file)); 426 427 /* data available? */ 428 if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { 429 return 0; // -EAGAIN makes cat whinge 430 } 431 432 return rtlx_read(minor, buffer, count); 433 } 434 435 static ssize_t file_write(struct file *file, const char __user * buffer, 436 size_t count, loff_t * ppos) 437 { 438 int minor = iminor(file_inode(file)); 439 struct rtlx_channel *rt = &rtlx->channel[minor]; 440 441 /* any space left... */ 442 if (!rtlx_write_poll(minor)) { 443 int ret = 0; 444 445 if (file->f_flags & O_NONBLOCK) 446 return -EAGAIN; 447 448 __wait_event_interruptible(channel_wqs[minor].rt_queue, 449 rtlx_write_poll(minor), 450 ret); 451 if (ret) 452 return ret; 453 } 454 455 return rtlx_write(minor, buffer, count); 456 } 457 458 static const struct file_operations rtlx_fops = { 459 .owner = THIS_MODULE, 460 .open = file_open, 461 .release = file_release, 462 .write = file_write, 463 .read = file_read, 464 .poll = file_poll, 465 .llseek = noop_llseek, 466 }; 467 468 static struct irqaction rtlx_irq = { 469 .handler = rtlx_interrupt, 470 .name = "RTLX", 471 }; 472 473 static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ; 474 475 static char register_chrdev_failed[] __initdata = 476 KERN_ERR "rtlx_module_init: unable to register device\n"; 477 478 static int __init rtlx_module_init(void) 479 { 480 struct device *dev; 481 int i, err; 482 483 if (!cpu_has_mipsmt) { 484 printk("VPE loader: not a MIPS MT capable processor\n"); 485 return -ENODEV; 486 } 487 488 if (tclimit == 0) { 489 printk(KERN_WARNING "No TCs reserved for AP/SP, not " 490 "initializing RTLX.\nPass maxtcs=<n> argument as kernel " 491 "argument\n"); 492 493 return -ENODEV; 494 } 495 496 major = register_chrdev(0, module_name, &rtlx_fops); 497 if (major < 0) { 498 printk(register_chrdev_failed); 499 return major; 500 } 501 502 /* initialise the wait queues */ 503 for (i = 0; i < RTLX_CHANNELS; i++) { 504 init_waitqueue_head(&channel_wqs[i].rt_queue); 505 init_waitqueue_head(&channel_wqs[i].lx_queue); 506 atomic_set(&channel_wqs[i].in_open, 0); 507 mutex_init(&channel_wqs[i].mutex); 508 509 dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, 510 "%s%d", module_name, i); 511 if (IS_ERR(dev)) { 512 err = PTR_ERR(dev); 513 goto out_chrdev; 514 } 515 } 516 517 /* set up notifiers */ 518 notify.start = starting; 519 notify.stop = stopping; 520 vpe_notify(tclimit, ¬ify); 521 522 if (cpu_has_vint) 523 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 524 else { 525 pr_err("APRP RTLX init on non-vectored-interrupt processor\n"); 526 err = -ENODEV; 527 goto out_chrdev; 528 } 529 530 rtlx_irq.dev_id = rtlx; 531 setup_irq(rtlx_irq_num, &rtlx_irq); 532 533 return 0; 534 535 out_chrdev: 536 for (i = 0; i < RTLX_CHANNELS; i++) 537 device_destroy(mt_class, MKDEV(major, i)); 538 539 return err; 540 } 541 542 static void __exit rtlx_module_exit(void) 543 { 544 int i; 545 546 for (i = 0; i < RTLX_CHANNELS; i++) 547 device_destroy(mt_class, MKDEV(major, i)); 548 549 unregister_chrdev(major, module_name); 550 } 551 552 module_init(rtlx_module_init); 553 module_exit(rtlx_module_exit); 554 555 MODULE_DESCRIPTION("MIPS RTLX"); 556 MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); 557 MODULE_LICENSE("GPL"); 558