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

Commit 7fe908dd authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

[PATCH] pcmcia: use mutexes instead of semaphores



Use mutexes in the PCMICA core, as they suffice for what needs to be done.
Includes a bugfix from and Signed-off-by Andrew Morton.

Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent cbbddd10
Loading
Loading
Loading
Loading
+20 −20
Original line number Diff line number Diff line
@@ -111,9 +111,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
		if (socket->dev.dev != dev)
			continue;
		down(&socket->skt_sem);
		mutex_lock(&socket->skt_mutex);
		socket_suspend(socket);
		up(&socket->skt_sem);
		mutex_unlock(&socket->skt_mutex);
	}
	up_read(&pcmcia_socket_list_rwsem);

@@ -129,9 +129,9 @@ int pcmcia_socket_dev_resume(struct device *dev)
	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
		if (socket->dev.dev != dev)
			continue;
		down(&socket->skt_sem);
		mutex_lock(&socket->skt_mutex);
		socket_resume(socket);
		up(&socket->skt_sem);
		mutex_unlock(&socket->skt_mutex);
	}
	up_read(&pcmcia_socket_list_rwsem);

@@ -237,7 +237,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
	init_completion(&socket->socket_released);
	init_completion(&socket->thread_done);
	init_waitqueue_head(&socket->thread_wait);
	init_MUTEX(&socket->skt_sem);
	mutex_init(&socket->skt_mutex);
	spin_lock_init(&socket->thread_lock);

	ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
@@ -662,7 +662,7 @@ static int pccardd(void *__skt)
		spin_unlock_irqrestore(&skt->thread_lock, flags);

		if (events) {
			down(&skt->skt_sem);
			mutex_lock(&skt->skt_mutex);
			if (events & SS_DETECT)
				socket_detect_change(skt);
			if (events & SS_BATDEAD)
@@ -671,7 +671,7 @@ static int pccardd(void *__skt)
				send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
			if (events & SS_READY)
				send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
			up(&skt->skt_sem);
			mutex_unlock(&skt->skt_mutex);
			continue;
		}

@@ -715,8 +715,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
{
        int ret = 0;

	/* s->skt_sem also protects s->callback */
	down(&s->skt_sem);
	/* s->skt_mutex also protects s->callback */
	mutex_lock(&s->skt_mutex);

	if (c) {
		/* registration */
@@ -732,7 +732,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
	} else
		s->callback = NULL;
 err:
	up(&s->skt_sem);
	mutex_unlock(&s->skt_mutex);

	return ret;
}
@@ -750,7 +750,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)

	cs_dbg(skt, 1, "resetting socket\n");

	down(&skt->skt_sem);
	mutex_lock(&skt->skt_mutex);
	do {
		if (!(skt->state & SOCKET_PRESENT)) {
			ret = CS_NO_CARD;
@@ -779,7 +779,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)

		ret = CS_SUCCESS;
	} while (0);
	up(&skt->skt_sem);
	mutex_unlock(&skt->skt_mutex);

	return ret;
} /* reset_card */
@@ -795,7 +795,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)

	cs_dbg(skt, 1, "suspending socket\n");

	down(&skt->skt_sem);
	mutex_lock(&skt->skt_mutex);
	do {
		if (!(skt->state & SOCKET_PRESENT)) {
			ret = CS_NO_CARD;
@@ -812,7 +812,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
		}
		ret = socket_suspend(skt);
	} while (0);
	up(&skt->skt_sem);
	mutex_unlock(&skt->skt_mutex);

	return ret;
} /* suspend_card */
@@ -825,7 +825,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
    
	cs_dbg(skt, 1, "waking up socket\n");

	down(&skt->skt_sem);
	mutex_lock(&skt->skt_mutex);
	do {
		if (!(skt->state & SOCKET_PRESENT)) {
			ret = CS_NO_CARD;
@@ -839,7 +839,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
		if (!ret && skt->callback)
			skt->callback->resume(skt);
	} while (0);
	up(&skt->skt_sem);
	mutex_unlock(&skt->skt_mutex);

	return ret;
} /* resume_card */
@@ -853,7 +853,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
    
	cs_dbg(skt, 1, "user eject request\n");

	down(&skt->skt_sem);
	mutex_lock(&skt->skt_mutex);
	do {
		if (!(skt->state & SOCKET_PRESENT)) {
			ret = -ENODEV;
@@ -869,7 +869,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
		socket_remove(skt);
		ret = 0;
	} while (0);
	up(&skt->skt_sem);
	mutex_unlock(&skt->skt_mutex);

	return ret;
} /* eject_card */
@@ -882,7 +882,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)

	cs_dbg(skt, 1, "user insert request\n");

	down(&skt->skt_sem);
	mutex_lock(&skt->skt_mutex);
	do {
		if (skt->state & SOCKET_PRESENT) {
			ret = -EBUSY;
@@ -894,7 +894,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
		}
		ret = 0;
	} while (0);
	up(&skt->skt_sem);
	mutex_unlock(&skt->skt_mutex);

	return ret;
} /* insert_card */
+7 −7
Original line number Diff line number Diff line
@@ -564,7 +564,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
 * won't work, this doesn't matter much at the moment: the driver core doesn't
 * support it either.
 */
static DECLARE_MUTEX(device_add_lock);
static DEFINE_MUTEX(device_add_lock);

struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
{
@@ -576,7 +576,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
	if (!s)
		return NULL;

	down(&device_add_lock);
	mutex_lock(&device_add_lock);

	/* max of 2 devices per card */
	if (s->device_count == 2)
@@ -640,7 +640,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
	if (device_register(&p_dev->dev))
		goto err_unreg;

	up(&device_add_lock);
	mutex_unlock(&device_add_lock);

	return p_dev;

@@ -654,7 +654,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
	kfree(p_dev);
	s->device_count--;
 err_put:
	up(&device_add_lock);
	mutex_unlock(&device_add_lock);
	pcmcia_put_socket(s);

	return NULL;
@@ -713,7 +713,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
	int no_devices=0;
	unsigned long flags;

	/* must be called with skt_sem held */
	/* must be called with skt_mutex held */
	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
	if (list_empty(&skt->devices_list))
		no_devices=1;
@@ -999,9 +999,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
	if (!count)
		return -EINVAL;

	down(&p_dev->socket->skt_sem);
	mutex_lock(&p_dev->socket->skt_mutex);
	p_dev->allow_func_id_match = 1;
	up(&p_dev->socket->skt_sem);
	mutex_unlock(&p_dev->socket->skt_mutex);

	bus_rescan_devices(&pcmcia_bus_type);

+6 −6
Original line number Diff line number Diff line
@@ -269,9 +269,9 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
	/*
	 * Prevent this racing with a card insertion.
	 */
	down(&s->skt_sem);
	mutex_lock(&s->skt_mutex);
	bus_rescan_devices(&pcmcia_bus_type);
	up(&s->skt_sem);
	mutex_unlock(&s->skt_mutex);

	/* check whether the driver indeed matched. I don't care if this
	 * is racy or not, because it can only happen on cardmgr access
@@ -606,9 +606,9 @@ static int ds_ioctl(struct inode * inode, struct file * file,
	}
	break;
    case DS_GET_FIRST_TUPLE:
	down(&s->skt_sem);
	mutex_lock(&s->skt_mutex);
	pcmcia_validate_mem(s);
	up(&s->skt_sem);
	mutex_unlock(&s->skt_mutex);
	ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
	break;
    case DS_GET_NEXT_TUPLE:
@@ -637,9 +637,9 @@ static int ds_ioctl(struct inode * inode, struct file * file,
	    }
	    break;
    case DS_VALIDATE_CIS:
	down(&s->skt_sem);
	mutex_lock(&s->skt_mutex);
	pcmcia_validate_mem(s);
	up(&s->skt_sem);
	mutex_unlock(&s->skt_mutex);
	ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
	break;
    case DS_SUSPEND_CARD:
+20 −20
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ struct socket_data {
	unsigned int			rsrc_mem_probe;
};

static DECLARE_MUTEX(rsrc_sem);
static DEFINE_MUTEX(rsrc_mutex);
#define MEM_PROBE_LOW	(1 << 0)
#define MEM_PROBE_HIGH	(1 << 1)

@@ -484,7 +484,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)


/*
 * Locking note: Must be called with skt_sem held!
 * Locking note: Must be called with skt_mutex held!
 */
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
{
@@ -495,7 +495,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
	if (!probe_mem)
		return 0;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);

	if (s->features & SS_CAP_PAGE_REGS)
		probe_mask = MEM_PROBE_HIGH;
@@ -507,7 +507,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
			s_data->rsrc_mem_probe |= probe_mask;
	}

	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);

	return ret;
}
@@ -585,7 +585,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
	struct socket_data *s_data = s->resource_data;
	int ret = -ENOMEM;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
		unsigned long start = m->base;
		unsigned long end = m->base + m->num - 1;
@@ -596,7 +596,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
		ret = adjust_resource(res, r_start, r_end - r_start + 1);
		break;
	}
	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);

	return ret;
}
@@ -630,7 +630,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
	data.offset = base & data.mask;
	data.map = &s_data->io_db;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
#ifdef CONFIG_PCI
	if (s->cb_dev) {
		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -639,7 +639,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
#endif
		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
					1, pcmcia_align, &data);
	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);

	if (ret != 0) {
		kfree(res);
@@ -672,7 +672,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
			min = 0x100000UL + base;
		}

		down(&rsrc_sem);
		mutex_lock(&rsrc_mutex);
#ifdef CONFIG_PCI
		if (s->cb_dev) {
			ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
@@ -682,7 +682,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
#endif
			ret = allocate_resource(&iomem_resource, res, num, min,
						max, 1, pcmcia_align, &data);
		up(&rsrc_sem);
		mutex_unlock(&rsrc_mutex);
		if (ret == 0 || low)
			break;
		low = 1;
@@ -705,7 +705,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
	if (end < start)
		return -EINVAL;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	switch (action) {
	case ADD_MANAGED_RESOURCE:
		ret = add_interval(&data->mem_db, start, size);
@@ -723,7 +723,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
	default:
		ret = -EINVAL;
	}
	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);

	return ret;
}
@@ -741,7 +741,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
	if (end > IO_SPACE_LIMIT)
		return -EINVAL;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	switch (action) {
	case ADD_MANAGED_RESOURCE:
		if (add_interval(&data->io_db, start, size) != 0) {
@@ -760,7 +760,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
		ret = -EINVAL;
		break;
	}
	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);

	return ret;
}
@@ -867,7 +867,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
	struct socket_data *data = s->resource_data;
	struct resource_map *p, *q;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	for (p = data->mem_db.next; p != &data->mem_db; p = q) {
		q = p->next;
		kfree(p);
@@ -876,7 +876,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
		q = p->next;
		kfree(p);
	}
	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);
}


@@ -901,7 +901,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
	struct resource_map *p;
	ssize_t ret = 0;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	data = s->resource_data;

	for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -913,7 +913,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
				 ((unsigned long) p->base + p->num - 1));
	}

	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);
	return (ret);
}

@@ -953,7 +953,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
	struct resource_map *p;
	ssize_t ret = 0;

	down(&rsrc_sem);
	mutex_lock(&rsrc_mutex);
	data = s->resource_data;

	for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
@@ -965,7 +965,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
				 ((unsigned long) p->base + p->num - 1));
	}

	up(&rsrc_sem);
	mutex_unlock(&rsrc_mutex);
	return (ret);
}

+5 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <asm/system.h>
#include <asm/irq.h>

@@ -183,7 +184,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
		s->resource_setup_done = 1;
	spin_unlock_irqrestore(&s->lock, flags);

	down(&s->skt_sem);
	mutex_lock(&s->skt_mutex);
	if ((s->callback) &&
	    (s->state & SOCKET_PRESENT) &&
	    !(s->state & SOCKET_CARDBUS)) {
@@ -192,7 +193,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
			module_put(s->callback->owner);
		}
	}
	up(&s->skt_sem);
	mutex_unlock(&s->skt_mutex);

	return count;
}
@@ -322,7 +323,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
	kfree(cis);

	if (!ret) {
		down(&s->skt_sem);
		mutex_lock(&s->skt_mutex);
		if ((s->callback) && (s->state & SOCKET_PRESENT) &&
		    !(s->state & SOCKET_CARDBUS)) {
			if (try_module_get(s->callback->owner)) {
@@ -330,7 +331,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
				module_put(s->callback->owner);
			}
		}
		up(&s->skt_sem);
		mutex_unlock(&s->skt_mutex);
	}


Loading