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

Commit 4ae0ff16 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'timer-fixes-for-linus' of...

Merge branch 'timer-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timer-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  RTC: rtc-omap: Fix a leak of the IRQ during init failure
  posix clocks: Replace mutex with reader/writer semaphore
parents 96ad9999 2dd93c4f
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -394,7 +394,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
	return 0;
	return 0;


fail2:
fail2:
	free_irq(omap_rtc_timer, NULL);
	free_irq(omap_rtc_timer, rtc);
fail1:
fail1:
	rtc_device_unregister(rtc);
	rtc_device_unregister(rtc);
fail0:
fail0:
+3 −2
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/poll.h>
#include <linux/posix-timers.h>
#include <linux/posix-timers.h>
#include <linux/rwsem.h>


struct posix_clock;
struct posix_clock;


@@ -104,7 +105,7 @@ struct posix_clock_operations {
 * @ops:     Functional interface to the clock
 * @ops:     Functional interface to the clock
 * @cdev:    Character device instance for this clock
 * @cdev:    Character device instance for this clock
 * @kref:    Reference count.
 * @kref:    Reference count.
 * @mutex:   Protects the 'zombie' field from concurrent access.
 * @rwsem:   Protects the 'zombie' field from concurrent access.
 * @zombie:  If 'zombie' is true, then the hardware has disappeared.
 * @zombie:  If 'zombie' is true, then the hardware has disappeared.
 * @release: A function to free the structure when the reference count reaches
 * @release: A function to free the structure when the reference count reaches
 *           zero. May be NULL if structure is statically allocated.
 *           zero. May be NULL if structure is statically allocated.
@@ -117,7 +118,7 @@ struct posix_clock {
	struct posix_clock_operations ops;
	struct posix_clock_operations ops;
	struct cdev cdev;
	struct cdev cdev;
	struct kref kref;
	struct kref kref;
	struct mutex mutex;
	struct rw_semaphore rwsem;
	bool zombie;
	bool zombie;
	void (*release)(struct posix_clock *clk);
	void (*release)(struct posix_clock *clk);
};
};
+9 −15
Original line number Original line Diff line number Diff line
@@ -19,7 +19,6 @@
 */
 */
#include <linux/device.h>
#include <linux/device.h>
#include <linux/file.h>
#include <linux/file.h>
#include <linux/mutex.h>
#include <linux/posix-clock.h>
#include <linux/posix-clock.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/syscalls.h>
@@ -34,19 +33,19 @@ static struct posix_clock *get_posix_clock(struct file *fp)
{
{
	struct posix_clock *clk = fp->private_data;
	struct posix_clock *clk = fp->private_data;


	mutex_lock(&clk->mutex);
	down_read(&clk->rwsem);


	if (!clk->zombie)
	if (!clk->zombie)
		return clk;
		return clk;


	mutex_unlock(&clk->mutex);
	up_read(&clk->rwsem);


	return NULL;
	return NULL;
}
}


static void put_posix_clock(struct posix_clock *clk)
static void put_posix_clock(struct posix_clock *clk)
{
{
	mutex_unlock(&clk->mutex);
	up_read(&clk->rwsem);
}
}


static ssize_t posix_clock_read(struct file *fp, char __user *buf,
static ssize_t posix_clock_read(struct file *fp, char __user *buf,
@@ -156,7 +155,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
	struct posix_clock *clk =
	struct posix_clock *clk =
		container_of(inode->i_cdev, struct posix_clock, cdev);
		container_of(inode->i_cdev, struct posix_clock, cdev);


	mutex_lock(&clk->mutex);
	down_read(&clk->rwsem);


	if (clk->zombie) {
	if (clk->zombie) {
		err = -ENODEV;
		err = -ENODEV;
@@ -172,7 +171,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
		fp->private_data = clk;
		fp->private_data = clk;
	}
	}
out:
out:
	mutex_unlock(&clk->mutex);
	up_read(&clk->rwsem);
	return err;
	return err;
}
}


@@ -211,25 +210,20 @@ int posix_clock_register(struct posix_clock *clk, dev_t devid)
	int err;
	int err;


	kref_init(&clk->kref);
	kref_init(&clk->kref);
	mutex_init(&clk->mutex);
	init_rwsem(&clk->rwsem);


	cdev_init(&clk->cdev, &posix_clock_file_operations);
	cdev_init(&clk->cdev, &posix_clock_file_operations);
	clk->cdev.owner = clk->ops.owner;
	clk->cdev.owner = clk->ops.owner;
	err = cdev_add(&clk->cdev, devid, 1);
	err = cdev_add(&clk->cdev, devid, 1);
	if (err)
		goto no_cdev;


	return err;
	return err;
no_cdev:
	mutex_destroy(&clk->mutex);
	return err;
}
}
EXPORT_SYMBOL_GPL(posix_clock_register);
EXPORT_SYMBOL_GPL(posix_clock_register);


static void delete_clock(struct kref *kref)
static void delete_clock(struct kref *kref)
{
{
	struct posix_clock *clk = container_of(kref, struct posix_clock, kref);
	struct posix_clock *clk = container_of(kref, struct posix_clock, kref);
	mutex_destroy(&clk->mutex);

	if (clk->release)
	if (clk->release)
		clk->release(clk);
		clk->release(clk);
}
}
@@ -238,9 +232,9 @@ void posix_clock_unregister(struct posix_clock *clk)
{
{
	cdev_del(&clk->cdev);
	cdev_del(&clk->cdev);


	mutex_lock(&clk->mutex);
	down_write(&clk->rwsem);
	clk->zombie = true;
	clk->zombie = true;
	mutex_unlock(&clk->mutex);
	up_write(&clk->rwsem);


	kref_put(&clk->kref, delete_clock);
	kref_put(&clk->kref, delete_clock);
}
}