diff options
| -rw-r--r-- | arch/mips/kernel/rtlx.c | 15 | ||||
| -rw-r--r-- | arch/mips/kernel/vpe.c | 77 |
2 files changed, 50 insertions, 42 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index a10ebfdc28ae..364f066cb497 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
| @@ -72,8 +72,9 @@ static void rtlx_dispatch(void) | |||
| 72 | */ | 72 | */ |
| 73 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id) | 73 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id) |
| 74 | { | 74 | { |
| 75 | unsigned int vpeflags; | ||
| 76 | unsigned long flags; | ||
| 75 | int i; | 77 | int i; |
| 76 | unsigned int flags, vpeflags; | ||
| 77 | 78 | ||
| 78 | /* Ought not to be strictly necessary for SMTC builds */ | 79 | /* Ought not to be strictly necessary for SMTC builds */ |
| 79 | local_irq_save(flags); | 80 | local_irq_save(flags); |
| @@ -392,20 +393,12 @@ out: | |||
| 392 | 393 | ||
| 393 | static int file_open(struct inode *inode, struct file *filp) | 394 | static int file_open(struct inode *inode, struct file *filp) |
| 394 | { | 395 | { |
| 395 | int minor = iminor(inode); | 396 | return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1); |
| 396 | int err; | ||
| 397 | |||
| 398 | lock_kernel(); | ||
| 399 | err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); | ||
| 400 | unlock_kernel(); | ||
| 401 | return err; | ||
| 402 | } | 397 | } |
| 403 | 398 | ||
| 404 | static int file_release(struct inode *inode, struct file *filp) | 399 | static int file_release(struct inode *inode, struct file *filp) |
| 405 | { | 400 | { |
| 406 | int minor = iminor(inode); | 401 | return rtlx_release(iminor(inode)); |
| 407 | |||
| 408 | return rtlx_release(minor); | ||
| 409 | } | 402 | } |
| 410 | 403 | ||
| 411 | static unsigned int file_poll(struct file *file, poll_table * wait) | 404 | static unsigned int file_poll(struct file *file, poll_table * wait) |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index eb6c4c5b7fbe..03092ab2a296 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
| @@ -144,14 +144,15 @@ struct tc { | |||
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | struct { | 146 | struct { |
| 147 | /* Virtual processing elements */ | 147 | spinlock_t vpe_list_lock; |
| 148 | struct list_head vpe_list; | 148 | struct list_head vpe_list; /* Virtual processing elements */ |
| 149 | 149 | spinlock_t tc_list_lock; | |
| 150 | /* Thread contexts */ | 150 | struct list_head tc_list; /* Thread contexts */ |
| 151 | struct list_head tc_list; | ||
| 152 | } vpecontrol = { | 151 | } vpecontrol = { |
| 153 | .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), | 152 | .vpe_list_lock = SPIN_LOCK_UNLOCKED, |
| 154 | .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) | 153 | .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), |
| 154 | .tc_list_lock = SPIN_LOCK_UNLOCKED, | ||
| 155 | .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) | ||
| 155 | }; | 156 | }; |
| 156 | 157 | ||
| 157 | static void release_progmem(void *ptr); | 158 | static void release_progmem(void *ptr); |
| @@ -159,28 +160,38 @@ static void release_progmem(void *ptr); | |||
| 159 | /* get the vpe associated with this minor */ | 160 | /* get the vpe associated with this minor */ |
| 160 | static struct vpe *get_vpe(int minor) | 161 | static struct vpe *get_vpe(int minor) |
| 161 | { | 162 | { |
| 162 | struct vpe *v; | 163 | struct vpe *res, *v; |
| 163 | 164 | ||
| 164 | if (!cpu_has_mipsmt) | 165 | if (!cpu_has_mipsmt) |
| 165 | return NULL; | 166 | return NULL; |
| 166 | 167 | ||
| 168 | res = NULL; | ||
| 169 | spin_lock(&vpecontrol.vpe_list_lock); | ||
| 167 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { | 170 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { |
| 168 | if (v->minor == minor) | 171 | if (v->minor == minor) { |
| 169 | return v; | 172 | res = v; |
| 173 | break; | ||
| 174 | } | ||
| 170 | } | 175 | } |
| 176 | spin_unlock(&vpecontrol.vpe_list_lock); | ||
| 171 | 177 | ||
| 172 | return NULL; | 178 | return res; |
| 173 | } | 179 | } |
| 174 | 180 | ||
| 175 | /* get the vpe associated with this minor */ | 181 | /* get the vpe associated with this minor */ |
| 176 | static struct tc *get_tc(int index) | 182 | static struct tc *get_tc(int index) |
| 177 | { | 183 | { |
| 178 | struct tc *t; | 184 | struct tc *res, *t; |
| 179 | 185 | ||
| 186 | res = NULL; | ||
| 187 | spin_lock(&vpecontrol.tc_list_lock); | ||
| 180 | list_for_each_entry(t, &vpecontrol.tc_list, list) { | 188 | list_for_each_entry(t, &vpecontrol.tc_list, list) { |
| 181 | if (t->index == index) | 189 | if (t->index == index) { |
| 182 | return t; | 190 | res = t; |
| 191 | break; | ||
| 192 | } | ||
| 183 | } | 193 | } |
| 194 | spin_unlock(&vpecontrol.tc_list_lock); | ||
| 184 | 195 | ||
| 185 | return NULL; | 196 | return NULL; |
| 186 | } | 197 | } |
| @@ -190,15 +201,17 @@ static struct vpe *alloc_vpe(int minor) | |||
| 190 | { | 201 | { |
| 191 | struct vpe *v; | 202 | struct vpe *v; |
| 192 | 203 | ||
| 193 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { | 204 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) |
| 194 | return NULL; | 205 | return NULL; |
| 195 | } | ||
| 196 | 206 | ||
| 197 | INIT_LIST_HEAD(&v->tc); | 207 | INIT_LIST_HEAD(&v->tc); |
| 208 | spin_lock(&vpecontrol.vpe_list_lock); | ||
| 198 | list_add_tail(&v->list, &vpecontrol.vpe_list); | 209 | list_add_tail(&v->list, &vpecontrol.vpe_list); |
| 210 | spin_unlock(&vpecontrol.vpe_list_lock); | ||
| 199 | 211 | ||
| 200 | INIT_LIST_HEAD(&v->notify); | 212 | INIT_LIST_HEAD(&v->notify); |
| 201 | v->minor = minor; | 213 | v->minor = minor; |
| 214 | |||
| 202 | return v; | 215 | return v; |
| 203 | } | 216 | } |
| 204 | 217 | ||
| @@ -212,7 +225,10 @@ static struct tc *alloc_tc(int index) | |||
| 212 | 225 | ||
| 213 | INIT_LIST_HEAD(&tc->tc); | 226 | INIT_LIST_HEAD(&tc->tc); |
| 214 | tc->index = index; | 227 | tc->index = index; |
| 228 | |||
| 229 | spin_lock(&vpecontrol.tc_list_lock); | ||
| 215 | list_add_tail(&tc->list, &vpecontrol.tc_list); | 230 | list_add_tail(&tc->list, &vpecontrol.tc_list); |
| 231 | spin_unlock(&vpecontrol.tc_list_lock); | ||
| 216 | 232 | ||
| 217 | out: | 233 | out: |
| 218 | return tc; | 234 | return tc; |
| @@ -227,7 +243,7 @@ static void release_vpe(struct vpe *v) | |||
| 227 | kfree(v); | 243 | kfree(v); |
| 228 | } | 244 | } |
| 229 | 245 | ||
| 230 | static void dump_mtregs(void) | 246 | static void __maybe_unused dump_mtregs(void) |
| 231 | { | 247 | { |
| 232 | unsigned long val; | 248 | unsigned long val; |
| 233 | 249 | ||
| @@ -1048,20 +1064,19 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
| 1048 | enum vpe_state state; | 1064 | enum vpe_state state; |
| 1049 | struct vpe_notifications *not; | 1065 | struct vpe_notifications *not; |
| 1050 | struct vpe *v; | 1066 | struct vpe *v; |
| 1051 | int ret, err = 0; | 1067 | int ret; |
| 1052 | 1068 | ||
| 1053 | lock_kernel(); | ||
| 1054 | if (minor != iminor(inode)) { | 1069 | if (minor != iminor(inode)) { |
| 1055 | /* assume only 1 device at the moment. */ | 1070 | /* assume only 1 device at the moment. */ |
| 1056 | printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); | 1071 | pr_warning("VPE loader: only vpe1 is supported\n"); |
| 1057 | err = -ENODEV; | 1072 | |
| 1058 | goto out; | 1073 | return -ENODEV; |
| 1059 | } | 1074 | } |
| 1060 | 1075 | ||
| 1061 | if ((v = get_vpe(tclimit)) == NULL) { | 1076 | if ((v = get_vpe(tclimit)) == NULL) { |
| 1062 | printk(KERN_WARNING "VPE loader: unable to get vpe\n"); | 1077 | pr_warning("VPE loader: unable to get vpe\n"); |
| 1063 | err = -ENODEV; | 1078 | |
| 1064 | goto out; | 1079 | return -ENODEV; |
| 1065 | } | 1080 | } |
| 1066 | 1081 | ||
| 1067 | state = xchg(&v->state, VPE_STATE_INUSE); | 1082 | state = xchg(&v->state, VPE_STATE_INUSE); |
| @@ -1101,8 +1116,8 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
| 1101 | v->shared_ptr = NULL; | 1116 | v->shared_ptr = NULL; |
| 1102 | v->__start = 0; | 1117 | v->__start = 0; |
| 1103 | 1118 | ||
| 1104 | out: | ||
| 1105 | unlock_kernel(); | 1119 | unlock_kernel(); |
| 1120 | |||
| 1106 | return 0; | 1121 | return 0; |
| 1107 | } | 1122 | } |
| 1108 | 1123 | ||
| @@ -1594,14 +1609,14 @@ static void __exit vpe_module_exit(void) | |||
| 1594 | { | 1609 | { |
| 1595 | struct vpe *v, *n; | 1610 | struct vpe *v, *n; |
| 1596 | 1611 | ||
| 1612 | device_del(&vpe_device); | ||
| 1613 | unregister_chrdev(major, module_name); | ||
| 1614 | |||
| 1615 | /* No locking needed here */ | ||
| 1597 | list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) { | 1616 | list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) { |
| 1598 | if (v->state != VPE_STATE_UNUSED) { | 1617 | if (v->state != VPE_STATE_UNUSED) |
| 1599 | release_vpe(v); | 1618 | release_vpe(v); |
| 1600 | } | ||
| 1601 | } | 1619 | } |
| 1602 | |||
| 1603 | device_del(&vpe_device); | ||
| 1604 | unregister_chrdev(major, module_name); | ||
| 1605 | } | 1620 | } |
| 1606 | 1621 | ||
| 1607 | module_init(vpe_module_init); | 1622 | module_init(vpe_module_init); |
