Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e82d5b6 authored by Matthias Kaehlcke's avatar Matthias Kaehlcke Committed by Linus Torvalds
Browse files

use mutex instead of semaphore for misc char devices



The misc character device driver uses a semaphore as mutex.  Use the mutex API
instead of the (binary) semaphore.

Signed-off-by: default avatarMatthias Kaehlcke <matthias.kaehlcke@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6acc369a
Loading
Loading
Loading
Loading
+14 −13
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/stat.h>
@@ -53,7 +54,7 @@
 * Head entry for the doubly linked miscdevice list
 * Head entry for the doubly linked miscdevice list
 */
 */
static LIST_HEAD(misc_list);
static LIST_HEAD(misc_list);
static DECLARE_MUTEX(misc_sem);
static DEFINE_MUTEX(misc_mtx);


/*
/*
 * Assigned numbers, used for dynamic minors
 * Assigned numbers, used for dynamic minors
@@ -69,7 +70,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
	struct miscdevice *p;
	struct miscdevice *p;
	loff_t off = 0;
	loff_t off = 0;


	down(&misc_sem);
	mutex_lock(&misc_mtx);
	list_for_each_entry(p, &misc_list, list) {
	list_for_each_entry(p, &misc_list, list) {
		if (*pos == off++) 
		if (*pos == off++) 
			return p;
			return p;
@@ -89,7 +90,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos)


static void misc_seq_stop(struct seq_file *seq, void *v)
static void misc_seq_stop(struct seq_file *seq, void *v)
{
{
	up(&misc_sem);
	mutex_unlock(&misc_mtx);
}
}


static int misc_seq_show(struct seq_file *seq, void *v)
static int misc_seq_show(struct seq_file *seq, void *v)
@@ -129,7 +130,7 @@ static int misc_open(struct inode * inode, struct file * file)
	int err = -ENODEV;
	int err = -ENODEV;
	const struct file_operations *old_fops, *new_fops = NULL;
	const struct file_operations *old_fops, *new_fops = NULL;
	
	
	down(&misc_sem);
	mutex_lock(&misc_mtx);
	
	
	list_for_each_entry(c, &misc_list, list) {
	list_for_each_entry(c, &misc_list, list) {
		if (c->minor == minor) {
		if (c->minor == minor) {
@@ -139,9 +140,9 @@ static int misc_open(struct inode * inode, struct file * file)
	}
	}
		
		
	if (!new_fops) {
	if (!new_fops) {
		up(&misc_sem);
		mutex_unlock(&misc_mtx);
		request_module("char-major-%d-%d", MISC_MAJOR, minor);
		request_module("char-major-%d-%d", MISC_MAJOR, minor);
		down(&misc_sem);
		mutex_lock(&misc_mtx);


		list_for_each_entry(c, &misc_list, list) {
		list_for_each_entry(c, &misc_list, list) {
			if (c->minor == minor) {
			if (c->minor == minor) {
@@ -165,7 +166,7 @@ static int misc_open(struct inode * inode, struct file * file)
	}
	}
	fops_put(old_fops);
	fops_put(old_fops);
fail:
fail:
	up(&misc_sem);
	mutex_unlock(&misc_mtx);
	return err;
	return err;
}
}


@@ -201,10 +202,10 @@ int misc_register(struct miscdevice * misc)


	INIT_LIST_HEAD(&misc->list);
	INIT_LIST_HEAD(&misc->list);


	down(&misc_sem);
	mutex_lock(&misc_mtx);
	list_for_each_entry(c, &misc_list, list) {
	list_for_each_entry(c, &misc_list, list) {
		if (c->minor == misc->minor) {
		if (c->minor == misc->minor) {
			up(&misc_sem);
			mutex_unlock(&misc_mtx);
			return -EBUSY;
			return -EBUSY;
		}
		}
	}
	}
@@ -215,7 +216,7 @@ int misc_register(struct miscdevice * misc)
			if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
			if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
				break;
				break;
		if (i<0) {
		if (i<0) {
			up(&misc_sem);
			mutex_unlock(&misc_mtx);
			return -EBUSY;
			return -EBUSY;
		}
		}
		misc->minor = i;
		misc->minor = i;
@@ -238,7 +239,7 @@ int misc_register(struct miscdevice * misc)
	 */
	 */
	list_add(&misc->list, &misc_list);
	list_add(&misc->list, &misc_list);
 out:
 out:
	up(&misc_sem);
	mutex_unlock(&misc_mtx);
	return err;
	return err;
}
}


@@ -259,13 +260,13 @@ int misc_deregister(struct miscdevice * misc)
	if (list_empty(&misc->list))
	if (list_empty(&misc->list))
		return -EINVAL;
		return -EINVAL;


	down(&misc_sem);
	mutex_lock(&misc_mtx);
	list_del(&misc->list);
	list_del(&misc->list);
	device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
	device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
	if (i < DYNAMIC_MINORS && i>0) {
	if (i < DYNAMIC_MINORS && i>0) {
		misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
		misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
	}
	}
	up(&misc_sem);
	mutex_unlock(&misc_mtx);
	return 0;
	return 0;
}
}