Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
*/
static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
{
*/
static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
{
+ unsigned int vpeflags;
+ unsigned long flags;
- unsigned int flags, vpeflags;
/* Ought not to be strictly necessary for SMTC builds */
local_irq_save(flags);
/* Ought not to be strictly necessary for SMTC builds */
local_irq_save(flags);
static int file_open(struct inode *inode, struct file *filp)
{
static int file_open(struct inode *inode, struct file *filp)
{
- int minor = iminor(inode);
- int err;
-
- lock_kernel();
- err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
- unlock_kernel();
- return err;
+ return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1);
}
static int file_release(struct inode *inode, struct file *filp)
{
}
static int file_release(struct inode *inode, struct file *filp)
{
- int minor = iminor(inode);
-
- return rtlx_release(minor);
+ return rtlx_release(iminor(inode));
}
static unsigned int file_poll(struct file *file, poll_table * wait)
}
static unsigned int file_poll(struct file *file, poll_table * wait)
- /* Virtual processing elements */
- struct list_head vpe_list;
-
- /* Thread contexts */
- struct list_head tc_list;
+ spinlock_t vpe_list_lock;
+ struct list_head vpe_list; /* Virtual processing elements */
+ spinlock_t tc_list_lock;
+ struct list_head tc_list; /* Thread contexts */
- .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
- .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
+ .vpe_list_lock = SPIN_LOCK_UNLOCKED,
+ .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
+ .tc_list_lock = SPIN_LOCK_UNLOCKED,
+ .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
};
static void release_progmem(void *ptr);
};
static void release_progmem(void *ptr);
/* get the vpe associated with this minor */
static struct vpe *get_vpe(int minor)
{
/* get the vpe associated with this minor */
static struct vpe *get_vpe(int minor)
{
if (!cpu_has_mipsmt)
return NULL;
if (!cpu_has_mipsmt)
return NULL;
+ res = NULL;
+ spin_lock(&vpecontrol.vpe_list_lock);
list_for_each_entry(v, &vpecontrol.vpe_list, list) {
list_for_each_entry(v, &vpecontrol.vpe_list, list) {
- if (v->minor == minor)
- return v;
+ if (v->minor == minor) {
+ res = v;
+ break;
+ }
+ spin_unlock(&vpecontrol.vpe_list_lock);
}
/* get the vpe associated with this minor */
static struct tc *get_tc(int index)
{
}
/* get the vpe associated with this minor */
static struct tc *get_tc(int index)
{
+ res = NULL;
+ spin_lock(&vpecontrol.tc_list_lock);
list_for_each_entry(t, &vpecontrol.tc_list, list) {
list_for_each_entry(t, &vpecontrol.tc_list, list) {
- if (t->index == index)
- return t;
+ if (t->index == index) {
+ res = t;
+ break;
+ }
+ spin_unlock(&vpecontrol.tc_list_lock);
- if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
+ if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL)
+ spin_lock(&vpecontrol.vpe_list_lock);
list_add_tail(&v->list, &vpecontrol.vpe_list);
list_add_tail(&v->list, &vpecontrol.vpe_list);
+ spin_unlock(&vpecontrol.vpe_list_lock);
INIT_LIST_HEAD(&v->notify);
v->minor = minor;
INIT_LIST_HEAD(&v->notify);
v->minor = minor;
INIT_LIST_HEAD(&tc->tc);
tc->index = index;
INIT_LIST_HEAD(&tc->tc);
tc->index = index;
+
+ spin_lock(&vpecontrol.tc_list_lock);
list_add_tail(&tc->list, &vpecontrol.tc_list);
list_add_tail(&tc->list, &vpecontrol.tc_list);
+ spin_unlock(&vpecontrol.tc_list_lock);
-static void dump_mtregs(void)
+static void __maybe_unused dump_mtregs(void)
enum vpe_state state;
struct vpe_notifications *not;
struct vpe *v;
enum vpe_state state;
struct vpe_notifications *not;
struct vpe *v;
if (minor != iminor(inode)) {
/* assume only 1 device at the moment. */
if (minor != iminor(inode)) {
/* assume only 1 device at the moment. */
- printk(KERN_WARNING "VPE loader: only vpe1 is supported\n");
- err = -ENODEV;
- goto out;
+ pr_warning("VPE loader: only vpe1 is supported\n");
+
+ return -ENODEV;
}
if ((v = get_vpe(tclimit)) == NULL) {
}
if ((v = get_vpe(tclimit)) == NULL) {
- printk(KERN_WARNING "VPE loader: unable to get vpe\n");
- err = -ENODEV;
- goto out;
+ pr_warning("VPE loader: unable to get vpe\n");
+
+ return -ENODEV;
}
state = xchg(&v->state, VPE_STATE_INUSE);
}
state = xchg(&v->state, VPE_STATE_INUSE);
v->shared_ptr = NULL;
v->__start = 0;
v->shared_ptr = NULL;
v->__start = 0;
+ device_del(&vpe_device);
+ unregister_chrdev(major, module_name);
+
+ /* No locking needed here */
list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
- if (v->state != VPE_STATE_UNUSED) {
+ if (v->state != VPE_STATE_UNUSED)
-
- device_del(&vpe_device);
- unregister_chrdev(major, module_name);
}
module_init(vpe_module_init);
}
module_init(vpe_module_init);