diff options
author | Dan Willemsen <dwillemsen@nvidia.com> | 2011-02-18 12:09:07 -0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-02-20 00:50:33 -0800 |
commit | 583326a49c6ec777d510892dc11b92b0be4a1307 (patch) | |
tree | b657c6ff2e0d318b8b520d8ddb317f615116afc5 | |
parent | ec0500529918b7b24520d6478d73a7293fc3a972 (diff) |
video: tegra: Change overlay spinlock to mutex
We call tegra_overlay_put inside the overlay lock, which can do a flip.
It's not safe to do a flip in an atomic context.
Change-Id: I4b043737a3eede0d47b8269a2d40e7c739f75df3
Reviewed-on: http://git-master/r/20087
Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com>
Tested-by: Daniel Willemsen <dwillemsen@nvidia.com>
Reviewed-by: Prajakta Gudadhe <pgudadhe@nvidia.com>
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
-rw-r--r-- | drivers/video/tegra/dc/overlay.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/video/tegra/dc/overlay.c b/drivers/video/tegra/dc/overlay.c index d522b394fcc6..94d5d6349273 100644 --- a/drivers/video/tegra/dc/overlay.c +++ b/drivers/video/tegra/dc/overlay.c @@ -22,6 +22,7 @@ #include <linux/list.h> #include <linux/miscdevice.h> #include <linux/mm.h> +#include <linux/mutex.h> #include <linux/sched.h> #include <linux/spinlock.h> #include <linux/tegra_overlay.h> @@ -50,7 +51,7 @@ struct tegra_overlay_info { spinlock_t clients_lock; struct overlay overlays[DC_N_WINDOWS]; - spinlock_t overlays_lock; + struct mutex overlays_lock; struct nvhost_device *ndev; @@ -309,24 +310,23 @@ surf_err: /* Overlay functions */ static bool tegra_overlay_get(struct overlay_client *client, int idx) { - unsigned long flags; struct tegra_overlay_info *dev = client->dev; bool ret = false; if (idx < 0 || idx > dev->dc->n_windows) return ret; - spin_lock_irqsave(&dev->overlays_lock, flags); + mutex_lock(&dev->overlays_lock); if (dev->overlays[idx].owner == NULL) { dev->overlays[idx].owner = client; ret = true; } - spin_unlock_irqrestore(&dev->overlays_lock, flags); + mutex_unlock(&dev->overlays_lock); return ret; } -static void tegra_overlay_put_unlocked(struct overlay_client *client, int idx) +static void tegra_overlay_put_locked(struct overlay_client *client, int idx) { struct tegra_overlay_flip_args flip_args; struct tegra_overlay_info *dev = client->dev; @@ -349,11 +349,9 @@ static void tegra_overlay_put_unlocked(struct overlay_client *client, int idx) static void tegra_overlay_put(struct overlay_client *client, int idx) { - unsigned long flags; - - spin_lock_irqsave(&client->dev->overlays_lock, flags); - tegra_overlay_put_unlocked(client, idx); - spin_unlock_irqrestore(&client->dev->overlays_lock, flags); + mutex_lock(&client->dev->overlays_lock); + tegra_overlay_put_locked(client, idx); + mutex_unlock(&client->dev->overlays_lock); } /* Ioctl implementations */ @@ -381,7 +379,6 @@ static int tegra_overlay_ioctl_close(struct overlay_client *client, { int err = 0; int idx; - unsigned long flags; if (copy_from_user(&idx, arg, sizeof(idx))) return -EFAULT; @@ -389,12 +386,12 @@ static int tegra_overlay_ioctl_close(struct overlay_client *client, if (idx < 0 || idx > client->dev->dc->n_windows) return -EINVAL; - spin_lock_irqsave(&client->dev->overlays_lock, flags); + mutex_lock(&client->dev->overlays_lock); if (client->dev->overlays[idx].owner == client) - tegra_overlay_put_unlocked(client, idx); + tegra_overlay_put_locked(client, idx); else err = -EINVAL; - spin_unlock_irqrestore(&client->dev->overlays_lock, flags); + mutex_unlock(&client->dev->overlays_lock); return err; } @@ -509,11 +506,11 @@ static int tegra_overlay_release(struct inode *inode, struct file *filp) unsigned long flags; int i; - spin_lock_irqsave(&client->dev->overlays_lock, flags); + mutex_lock(&client->dev->overlays_lock); for (i = 0; i < client->dev->dc->n_windows; i++) if (client->dev->overlays[i].owner == client) - tegra_overlay_put_unlocked(client, i); - spin_unlock_irqrestore(&client->dev->overlays_lock, flags); + tegra_overlay_put_locked(client, i); + mutex_unlock(&client->dev->overlays_lock); spin_lock_irqsave(&client->dev->clients_lock, flags); list_del(&client->list); @@ -599,7 +596,7 @@ struct tegra_overlay_info *tegra_overlay_register(struct nvhost_device *ndev, spin_lock_init(&dev->clients_lock); INIT_LIST_HEAD(&dev->clients); - spin_lock_init(&dev->overlays_lock); + mutex_init(&dev->overlays_lock); e = misc_register(&dev->dev); if (e) { |