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; 403 unsigned int mask = 0; 404 405 minor = iminor(file->f_path.dentry->d_inode); 406 407 poll_wait(file, &channel_wqs[minor].rt_queue, wait); 408 poll_wait(file, &channel_wqs[minor].lx_queue, wait); 409 410 if (rtlx == NULL) 411 return 0; 412 413 /* data available to read? */ 414 if (rtlx_read_poll(minor, 0)) 415 mask |= POLLIN | POLLRDNORM; 416 417 /* space to write */ 418 if (rtlx_write_poll(minor)) 419 mask |= POLLOUT | POLLWRNORM; 420 421 return mask; 422 } 423 424 static ssize_t file_read(struct file *file, char __user * buffer, size_t count, 425 loff_t * ppos) 426 { 427 int minor = iminor(file->f_path.dentry->d_inode); 428 429 /* data available? */ 430 if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { 431 return 0; // -EAGAIN makes cat whinge 432 } 433 434 return rtlx_read(minor, buffer, count); 435 } 436 437 static ssize_t file_write(struct file *file, const char __user * buffer, 438 size_t count, loff_t * ppos) 439 { 440 int minor; 441 struct rtlx_channel *rt; 442 443 minor = iminor(file->f_path.dentry->d_inode); 444 rt = &rtlx->channel[minor]; 445 446 /* any space left... */ 447 if (!rtlx_write_poll(minor)) { 448 int ret = 0; 449 450 if (file->f_flags & O_NONBLOCK) 451 return -EAGAIN; 452 453 __wait_event_interruptible(channel_wqs[minor].rt_queue, 454 rtlx_write_poll(minor), 455 ret); 456 if (ret) 457 return ret; 458 } 459 460 return rtlx_write(minor, buffer, count); 461 } 462 463 static const struct file_operations rtlx_fops = { 464 .owner = THIS_MODULE, 465 .open = file_open, 466 .release = file_release, 467 .write = file_write, 468 .read = file_read, 469 .poll = file_poll, 470 .llseek = noop_llseek, 471 }; 472 473 static struct irqaction rtlx_irq = { 474 .handler = rtlx_interrupt, 475 .name = "RTLX", 476 }; 477 478 static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ; 479 480 static char register_chrdev_failed[] __initdata = 481 KERN_ERR "rtlx_module_init: unable to register device\n"; 482 483 static int __init rtlx_module_init(void) 484 { 485 struct device *dev; 486 int i, err; 487 488 if (!cpu_has_mipsmt) { 489 printk("VPE loader: not a MIPS MT capable processor\n"); 490 return -ENODEV; 491 } 492 493 if (tclimit == 0) { 494 printk(KERN_WARNING "No TCs reserved for AP/SP, not " 495 "initializing RTLX.\nPass maxtcs=<n> argument as kernel " 496 "argument\n"); 497 498 return -ENODEV; 499 } 500 501 major = register_chrdev(0, module_name, &rtlx_fops); 502 if (major < 0) { 503 printk(register_chrdev_failed); 504 return major; 505 } 506 507 /* initialise the wait queues */ 508 for (i = 0; i < RTLX_CHANNELS; i++) { 509 init_waitqueue_head(&channel_wqs[i].rt_queue); 510 init_waitqueue_head(&channel_wqs[i].lx_queue); 511 atomic_set(&channel_wqs[i].in_open, 0); 512 mutex_init(&channel_wqs[i].mutex); 513 514 dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, 515 "%s%d", module_name, i); 516 if (IS_ERR(dev)) { 517 err = PTR_ERR(dev); 518 goto out_chrdev; 519 } 520 } 521 522 /* set up notifiers */ 523 notify.start = starting; 524 notify.stop = stopping; 525 vpe_notify(tclimit, ¬ify); 526 527 if (cpu_has_vint) 528 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 529 else { 530 pr_err("APRP RTLX init on non-vectored-interrupt processor\n"); 531 err = -ENODEV; 532 goto out_chrdev; 533 } 534 535 rtlx_irq.dev_id = rtlx; 536 setup_irq(rtlx_irq_num, &rtlx_irq); 537 538 return 0; 539 540 out_chrdev: 541 for (i = 0; i < RTLX_CHANNELS; i++) 542 device_destroy(mt_class, MKDEV(major, i)); 543 544 return err; 545 } 546 547 static void __exit rtlx_module_exit(void) 548 { 549 int i; 550 551 for (i = 0; i < RTLX_CHANNELS; i++) 552 device_destroy(mt_class, MKDEV(major, i)); 553 554 unregister_chrdev(major, module_name); 555 } 556 557 module_init(rtlx_module_init); 558 module_exit(rtlx_module_exit); 559 560 MODULE_DESCRIPTION("MIPS RTLX"); 561 MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); 562 MODULE_LICENSE("GPL"); 563