aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/rtlx.c
diff options
context:
space:
mode:
authorDeng-Cheng Zhu <dengcheng.zhu@imgtec.com>2014-01-01 10:26:46 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-22 14:19:02 -0500
commit2c973ef0cc3f981bfb137c3e42e08de5e8f1cc18 (patch)
tree8f15ba20262f53e7465348db0581f16befb130db /arch/mips/kernel/rtlx.c
parent17a1d523aa5826dec25f2362e1630be365167bda (diff)
MIPS: APRP: Split RTLX support into separate files.
Split the RTLX functionality in preparation for adding support for CMP platforms. Common functions remain in the original file and a new file contains code specific to platforms that do not have a CMP. Signed-off-by: Deng-Cheng Zhu <dengcheng.zhu@imgtec.com> Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com> Reviewed-by: Qais Yousef <Qais.Yousef@imgtec.com> Patchwork: http://patchwork.linux-mips.org/patch/6093/ Reviewed-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/kernel/rtlx.c')
-rw-r--r--arch/mips/kernel/rtlx.c142
1 files changed, 10 insertions, 132 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 2c12ea1668d1..59db407d0499 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -42,52 +42,12 @@
42#include <asm/rtlx.h> 42#include <asm/rtlx.h>
43#include <asm/setup.h> 43#include <asm/setup.h>
44 44
45static struct rtlx_info *rtlx;
46static int major;
47static char module_name[] = "rtlx";
48
49static struct chan_waitqueues {
50 wait_queue_head_t rt_queue;
51 wait_queue_head_t lx_queue;
52 atomic_t in_open;
53 struct mutex mutex;
54} channel_wqs[RTLX_CHANNELS];
55
56static struct vpe_notifications notify;
57static int sp_stopping; 45static int sp_stopping;
58 46struct rtlx_info *rtlx;
59extern void *vpe_get_shared(int index); 47struct chan_waitqueues channel_wqs[RTLX_CHANNELS];
60 48struct vpe_notifications rtlx_notify;
61static void rtlx_dispatch(void) 49void (*aprp_hook)(void) = NULL;
62{ 50EXPORT_SYMBOL(aprp_hook);
63 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ);
64}
65
66
67/* Interrupt handler may be called before rtlx_init has otherwise had
68 a chance to run.
69*/
70static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
71{
72 unsigned int vpeflags;
73 unsigned long flags;
74 int i;
75
76 /* Ought not to be strictly necessary for SMTC builds */
77 local_irq_save(flags);
78 vpeflags = dvpe();
79 set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
80 irq_enable_hazard();
81 evpe(vpeflags);
82 local_irq_restore(flags);
83
84 for (i = 0; i < RTLX_CHANNELS; i++) {
85 wake_up(&channel_wqs[i].lx_queue);
86 wake_up(&channel_wqs[i].rt_queue);
87 }
88
89 return IRQ_HANDLED;
90}
91 51
92static void __used dump_rtlx(void) 52static void __used dump_rtlx(void)
93{ 53{
@@ -127,7 +87,7 @@ static int rtlx_init(struct rtlx_info *rtlxi)
127} 87}
128 88
129/* notifications */ 89/* notifications */
130static void starting(int vpe) 90void rtlx_starting(int vpe)
131{ 91{
132 int i; 92 int i;
133 sp_stopping = 0; 93 sp_stopping = 0;
@@ -140,7 +100,7 @@ static void starting(int vpe)
140 wake_up_interruptible(&channel_wqs[i].lx_queue); 100 wake_up_interruptible(&channel_wqs[i].lx_queue);
141} 101}
142 102
143static void stopping(int vpe) 103void rtlx_stopping(int vpe)
144{ 104{
145 int i; 105 int i;
146 106
@@ -384,6 +344,8 @@ out:
384 smp_wmb(); 344 smp_wmb();
385 mutex_unlock(&channel_wqs[index].mutex); 345 mutex_unlock(&channel_wqs[index].mutex);
386 346
347 _interrupt_sp();
348
387 return count; 349 return count;
388} 350}
389 351
@@ -454,7 +416,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
454 return rtlx_write(minor, buffer, count); 416 return rtlx_write(minor, buffer, count);
455} 417}
456 418
457static const struct file_operations rtlx_fops = { 419const struct file_operations rtlx_fops = {
458 .owner = THIS_MODULE, 420 .owner = THIS_MODULE,
459 .open = file_open, 421 .open = file_open,
460 .release = file_release, 422 .release = file_release,
@@ -464,90 +426,6 @@ static const struct file_operations rtlx_fops = {
464 .llseek = noop_llseek, 426 .llseek = noop_llseek,
465}; 427};
466 428
467static struct irqaction rtlx_irq = {
468 .handler = rtlx_interrupt,
469 .name = "RTLX",
470};
471
472static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ;
473
474static char register_chrdev_failed[] __initdata =
475 KERN_ERR "rtlx_module_init: unable to register device\n";
476
477static int __init rtlx_module_init(void)
478{
479 struct device *dev;
480 int i, err;
481
482 if (!cpu_has_mipsmt) {
483 printk("VPE loader: not a MIPS MT capable processor\n");
484 return -ENODEV;
485 }
486
487 if (tclimit == 0) {
488 printk(KERN_WARNING "No TCs reserved for AP/SP, not "
489 "initializing RTLX.\nPass maxtcs=<n> argument as kernel "
490 "argument\n");
491
492 return -ENODEV;
493 }
494
495 major = register_chrdev(0, module_name, &rtlx_fops);
496 if (major < 0) {
497 printk(register_chrdev_failed);
498 return major;
499 }
500
501 /* initialise the wait queues */
502 for (i = 0; i < RTLX_CHANNELS; i++) {
503 init_waitqueue_head(&channel_wqs[i].rt_queue);
504 init_waitqueue_head(&channel_wqs[i].lx_queue);
505 atomic_set(&channel_wqs[i].in_open, 0);
506 mutex_init(&channel_wqs[i].mutex);
507
508 dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
509 "%s%d", module_name, i);
510 if (IS_ERR(dev)) {
511 err = PTR_ERR(dev);
512 goto out_chrdev;
513 }
514 }
515
516 /* set up notifiers */
517 notify.start = starting;
518 notify.stop = stopping;
519 vpe_notify(tclimit, &notify);
520
521 if (cpu_has_vint)
522 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
523 else {
524 pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
525 err = -ENODEV;
526 goto out_chrdev;
527 }
528
529 rtlx_irq.dev_id = rtlx;
530 setup_irq(rtlx_irq_num, &rtlx_irq);
531
532 return 0;
533
534out_chrdev:
535 for (i = 0; i < RTLX_CHANNELS; i++)
536 device_destroy(mt_class, MKDEV(major, i));
537
538 return err;
539}
540
541static void __exit rtlx_module_exit(void)
542{
543 int i;
544
545 for (i = 0; i < RTLX_CHANNELS; i++)
546 device_destroy(mt_class, MKDEV(major, i));
547
548 unregister_chrdev(major, module_name);
549}
550
551module_init(rtlx_module_init); 429module_init(rtlx_module_init);
552module_exit(rtlx_module_exit); 430module_exit(rtlx_module_exit);
553 431