Commit 9487ff673d3cf100391aaeea7d56ef2daac2a36b

Authored by Dan Murphy

Merge branch 'audio-display-ti-linux-3.14.y' of git://git.ti.com/~darrene/ti-lin…

…ux-kernel/audio-display-linux-feature-tree into ti-linux-3.14.y

TI-Feature: audio-display
TI-Tree: git://git.ti.com/~darrene/ti-linux-kernel/audio-display-linux-feature-tree.git
TI-Branch: audio-display-ti-linux-3.14.y

* 'audio-display-ti-linux-3.14.y' of git://git.ti.com/~darrene/ti-linux-kernel/audio-display-linux-feature-tree:
  ASoC: tlv320aic31xx: Do not ignore errors in aic31xx_device_init()
  video/logo: prevent use of logos after they have been freed
  drm/omap: fix race conditon in DMM
  drm/omap: fix race condition with dev->obj_list

Signed-off-by: Dan Murphy <DMurphy@ti.com>

Showing 7 changed files Side-by-side Diff

drivers/gpu/drm/omapdrm/omap_dmm_priv.h
... ... @@ -148,7 +148,7 @@
148 148  
149 149 bool async;
150 150  
151   - wait_queue_head_t wait_for_refill;
  151 + struct completion compl;
152 152  
153 153 struct list_head idle_node;
154 154 };
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
... ... @@ -29,6 +29,7 @@
29 29 #include <linux/mm.h>
30 30 #include <linux/time.h>
31 31 #include <linux/list.h>
  32 +#include <linux/completion.h>
32 33  
33 34 #include "omap_dmm_tiler.h"
34 35 #include "omap_dmm_priv.h"
35 36  
... ... @@ -146,10 +147,10 @@
146 147  
147 148 for (i = 0; i < dmm->num_engines; i++) {
148 149 if (status & DMM_IRQSTAT_LST) {
149   - wake_up_interruptible(&dmm->engines[i].wait_for_refill);
150   -
151 150 if (dmm->engines[i].async)
152 151 release_engine(&dmm->engines[i]);
  152 +
  153 + complete(&dmm->engines[i].compl);
153 154 }
154 155  
155 156 status >>= 8;
... ... @@ -273,7 +274,8 @@
273 274  
274 275 /* mark whether it is async to denote list management in IRQ handler */
275 276 engine->async = wait ? false : true;
276   - /* verify that the irq handler sees the 'async' value */
  277 + reinit_completion(&engine->compl);
  278 + /* verify that the irq handler sees the 'async' and completion value */
277 279 smp_mb();
278 280  
279 281 /* kick reload */
... ... @@ -281,9 +283,8 @@
281 283 dmm->base + reg[PAT_DESCR][engine->id]);
282 284  
283 285 if (wait) {
284   - if (wait_event_interruptible_timeout(engine->wait_for_refill,
285   - wait_status(engine, DMM_PATSTATUS_READY) == 0,
286   - msecs_to_jiffies(1)) <= 0) {
  286 + if (!wait_for_completion_timeout(&engine->compl,
  287 + msecs_to_jiffies(1))) {
287 288 dev_err(dmm->dev, "timed out waiting for done\n");
288 289 ret = -ETIMEDOUT;
289 290 }
... ... @@ -719,7 +720,7 @@
719 720 (REFILL_BUFFER_SIZE * i);
720 721 omap_dmm->engines[i].refill_pa = omap_dmm->refill_pa +
721 722 (REFILL_BUFFER_SIZE * i);
722   - init_waitqueue_head(&omap_dmm->engines[i].wait_for_refill);
  723 + init_completion(&omap_dmm->engines[i].compl);
723 724  
724 725 list_add(&omap_dmm->engines[i].idle_node, &omap_dmm->idle_head);
725 726 }
drivers/gpu/drm/omapdrm/omap_drv.c
... ... @@ -479,6 +479,7 @@
479 479  
480 480 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
481 481  
  482 + spin_lock_init(&priv->list_lock);
482 483 INIT_LIST_HEAD(&priv->obj_list);
483 484  
484 485 omap_gem_init(dev);
drivers/gpu/drm/omapdrm/omap_drv.h
... ... @@ -104,6 +104,9 @@
104 104  
105 105 struct workqueue_struct *wq;
106 106  
  107 + /* lock for obj_list below */
  108 + spinlock_t list_lock;
  109 +
107 110 /* list of GEM objects: */
108 111 struct list_head obj_list;
109 112  
drivers/gpu/drm/omapdrm/omap_gem.c
... ... @@ -1280,13 +1280,16 @@
1280 1280 void omap_gem_free_object(struct drm_gem_object *obj)
1281 1281 {
1282 1282 struct drm_device *dev = obj->dev;
  1283 + struct omap_drm_private *priv = dev->dev_private;
1283 1284 struct omap_gem_object *omap_obj = to_omap_bo(obj);
1284 1285  
1285 1286 evict(obj);
1286 1287  
1287 1288 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
1288 1289  
  1290 + spin_lock(&priv->list_lock);
1289 1291 list_del(&omap_obj->mm_list);
  1292 + spin_unlock(&priv->list_lock);
1290 1293  
1291 1294 drm_gem_free_mmap_offset(obj);
1292 1295  
1293 1296  
... ... @@ -1383,7 +1386,9 @@
1383 1386 if (!omap_obj)
1384 1387 goto fail;
1385 1388  
  1389 + spin_lock(&priv->list_lock);
1386 1390 list_add(&omap_obj->mm_list, &priv->obj_list);
  1391 + spin_unlock(&priv->list_lock);
1387 1392  
1388 1393 obj = &omap_obj->base;
1389 1394  
drivers/video/logo/logo.c
... ... @@ -21,6 +21,21 @@
21 21 module_param(nologo, bool, 0);
22 22 MODULE_PARM_DESC(nologo, "Disables startup logo");
23 23  
  24 +/*
  25 + * Logos are located in the initdata, and will be freed in kernel_init.
  26 + * Use late_init to mark the logos as freed to prevent any further use.
  27 + */
  28 +
  29 +static bool logos_freed;
  30 +
  31 +static int __init fb_logo_late_init(void)
  32 +{
  33 + logos_freed = true;
  34 + return 0;
  35 +}
  36 +
  37 +late_initcall(fb_logo_late_init);
  38 +
24 39 /* logo's are marked __initdata. Use __init_refok to tell
25 40 * modpost that it is intended that this function uses data
26 41 * marked __initdata.
... ... @@ -29,7 +44,7 @@
29 44 {
30 45 const struct linux_logo *logo = NULL;
31 46  
32   - if (nologo)
  47 + if (nologo || logos_freed)
33 48 return NULL;
34 49  
35 50 if (depth >= 1) {
sound/soc/codecs/tlv320aic31xx.c
... ... @@ -1210,7 +1210,7 @@
1210 1210 }
1211 1211 #endif /* CONFIG_OF */
1212 1212  
1213   -void aic31xx_device_init(struct aic31xx_priv *aic31xx)
  1213 +static int aic31xx_device_init(struct aic31xx_priv *aic31xx)
1214 1214 {
1215 1215 int ret, i;
1216 1216  
... ... @@ -1229,7 +1229,7 @@
1229 1229 "aic31xx-reset-pin");
1230 1230 if (ret < 0) {
1231 1231 dev_err(aic31xx->dev, "not able to acquire gpio\n");
1232   - return;
  1232 + return ret;
1233 1233 }
1234 1234 }
1235 1235  
... ... @@ -1242,6 +1242,7 @@
1242 1242 if (ret != 0)
1243 1243 dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
1244 1244  
  1245 + return ret;
1245 1246 }
1246 1247  
1247 1248 static int aic31xx_i2c_probe(struct i2c_client *i2c,
... ... @@ -1272,7 +1273,9 @@
1272 1273  
1273 1274 aic31xx->pdata.codec_type = id->driver_data;
1274 1275  
1275   - aic31xx_device_init(aic31xx);
  1276 + ret = aic31xx_device_init(aic31xx);
  1277 + if (ret)
  1278 + return ret;
1276 1279  
1277 1280 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx,
1278 1281 aic31xx_dai_driver,