/*
 * linux/drivers/video/omap2/dsscomp/queue.c
 *
 * DSS Composition queueing support
 *
 * Copyright (C) 2011 Texas Instruments, Inc
 * Author: Lajos Molnar <molnar@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/ratelimit.h>

#include <video/omapdss.h>
#include <video/dsscomp.h>
#include <plat/dsscomp.h>

#include <linux/debugfs.h>

#include "dsscomp.h"
/* queue state */

static DEFINE_MUTEX(mtx);

/* free overlay structs */
struct maskref {
	u32 mask;
	u32 refs[MAX_OVERLAYS];
};

static struct {
	struct workqueue_struct *apply_workq;

	u32 ovl_mask;		/* overlays used on this display */
	struct maskref ovl_qmask;		/* overlays queued to this display */
	bool blanking;
} mgrq[MAX_MANAGERS];

static struct workqueue_struct *cb_wkq;		/* callback work queue */
static struct dsscomp_dev *cdev;

#ifdef CONFIG_DEBUG_FS
LIST_HEAD(dbg_comps);
DEFINE_MUTEX(dbg_mtx);
#endif

#ifdef CONFIG_DSSCOMP_DEBUG_LOG
struct dbg_event_t dbg_events[128];
u32 dbg_event_ix;
#endif

static inline void __log_state(dsscomp_t c, void *fn, u32 ev)
{
#ifdef CONFIG_DSSCOMP_DEBUG_LOG
	if (c->dbg_used < ARRAY_SIZE(c->dbg_log)) {
		u32 t = (u32) ktime_to_ms(ktime_get());
		c->dbg_log[c->dbg_used].t = t;
		c->dbg_log[c->dbg_used++].state = c->state;
		__log_event(20 * c->ix + 20, t, c, ev ? "%pf on %s" : "%pf",
				(u32) fn, (u32) log_status_str(ev));
	}
#endif
}
#define log_state(c, fn, ev) DO_IF_DEBUG_FS(__log_state(c, fn, ev))

static inline void maskref_incbit(struct maskref *om, u32 ix)
{
	om->refs[ix]++;
	om->mask |= 1 << ix;
}

static void maskref_decmask(struct maskref *om, u32 mask)
{
	while (mask) {
		u32 ix = fls(mask) - 1, m = 1 << ix;
		if (!--om->refs[ix])
			om->mask &= ~m;
		mask &= ~m;
	}
}

/*
 * ===========================================================================
 *		EXIT
 * ===========================================================================
 */

/* Initialize queue structures, and set up state of the displays */
int dsscomp_queue_init(struct dsscomp_dev *cdev_)
{
	u32 i, j;
	cdev = cdev_;

	if (ARRAY_SIZE(mgrq) < cdev->num_mgrs)
		return -EINVAL;

	ZERO(mgrq);
	for (i = 0; i < cdev->num_mgrs; i++) {
		struct omap_overlay_manager *mgr;
		mgrq[i].apply_workq = create_singlethread_workqueue("dsscomp_apply");
		if (!mgrq[i].apply_workq)
			goto error;

		/* record overlays on this display */
		mgr = cdev->mgrs[i];
		for (j = 0; j < cdev->num_ovls; j++) {
			if (cdev->ovls[j]->info.enabled &&
			    mgr &&
			    cdev->ovls[j]->manager == mgr)
				mgrq[i].ovl_mask |= 1 << j;
		}
	}

	cb_wkq = create_singlethread_workqueue("dsscomp_cb");
	if (!cb_wkq)
		goto error;

	return 0;
error:
	while (i--)
		destroy_workqueue(mgrq[i].apply_workq);
	return -ENOMEM;
}

/* get display index from manager */
static u32 get_display_ix(struct omap_overlay_manager *mgr)
{
	u32 i;

	/* handle if manager is not attached to a display */
	if (!mgr || !mgr->device)
		return cdev->num_displays;

	/* find manager's display */
	for (i = 0; i < cdev->num_displays; i++)
		if (cdev->displays[i] == mgr->device)
			break;

	return i;
}

/*
 * ===========================================================================
 *		QUEUING SETUP OPERATIONS
 * ===========================================================================
 */

/* create a new composition for a display */
dsscomp_t dsscomp_new(struct omap_overlay_manager *mgr)
{
	struct dsscomp_data *comp = NULL;
	u32 display_ix = get_display_ix(mgr);

	/* check manager */
	u32 ix = mgr ? mgr->id : cdev->num_mgrs;
	if (ix >= cdev->num_mgrs || display_ix >= cdev->num_displays)
		return ERR_PTR(-EINVAL);

	/* allocate composition */
	comp = kzalloc(sizeof(*comp), GFP_KERNEL);
	if (!comp)
		return NULL;

	/* initialize new composition */
	comp->ix = ix;	/* save where this composition came from */
	comp->ovl_mask = comp->ovl_dmask = 0;
	comp->frm.sync_id = 0;
	comp->frm.mgr.ix = display_ix;
	comp->state = DSSCOMP_STATE_ACTIVE;

	DO_IF_DEBUG_FS({
		__log_state(comp, dsscomp_new, 0);
		list_add(&comp->dbg_q, &dbg_comps);
	});

	return comp;
}
EXPORT_SYMBOL(dsscomp_new);

/* returns overlays used in a composition */
u32 dsscomp_get_ovls(dsscomp_t comp)
{
	u32 mask;

	mutex_lock(&mtx);
	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);
	mask = comp->ovl_mask;
	mutex_unlock(&mtx);

	return mask;
}
EXPORT_SYMBOL(dsscomp_get_ovls);

/* set overlay info */
int dsscomp_set_ovl(dsscomp_t comp, struct dss2_ovl_info *ovl)
{
	int r = -EBUSY;
	u32 i, mask, oix, ix;
	struct omap_overlay *o;

	mutex_lock(&mtx);

	BUG_ON(!ovl);
	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);

	ix = comp->ix;

	if (ovl->cfg.ix >= cdev->num_ovls) {
		r = -EINVAL;
		goto done;
	}

	/* if overlay is already part of the composition */
	mask = 1 << ovl->cfg.ix;
	if (mask & comp->ovl_mask) {
		/* look up overlay */
		for (oix = 0; oix < comp->frm.num_ovls; oix++) {
			if (comp->ovls[oix].cfg.ix == ovl->cfg.ix)
				break;
		}
		BUG_ON(oix == comp->frm.num_ovls);
	} else {
		/* check if ovl is free to use */
		if (comp->frm.num_ovls >= ARRAY_SIZE(comp->ovls))
			goto done;

		/* not in any other displays queue */
		if (mask & ~mgrq[ix].ovl_qmask.mask) {
			for (i = 0; i < cdev->num_mgrs; i++) {
				if (i == ix)
					continue;
				if (mgrq[i].ovl_qmask.mask & mask)
					goto done;
			}
		}

		/* and disabled (unless forced) if on another manager */
		o = cdev->ovls[ovl->cfg.ix];
		if (o->info.enabled && (!o->manager || o->manager->id != ix))
			goto done;

		/* add overlay to composition & display */
		comp->ovl_mask |= mask;
		oix = comp->frm.num_ovls++;
		maskref_incbit(&mgrq[ix].ovl_qmask, ovl->cfg.ix);
	}

	comp->ovls[oix] = *ovl;
	r = 0;
done:
	mutex_unlock(&mtx);

	return r;
}
EXPORT_SYMBOL(dsscomp_set_ovl);

/* get overlay info */
int dsscomp_get_ovl(dsscomp_t comp, u32 ix, struct dss2_ovl_info *ovl)
{
	int r;
	u32 oix;

	mutex_lock(&mtx);

	BUG_ON(!ovl);
	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);

	if (ix >= cdev->num_ovls) {
		r = -EINVAL;
	} else if (comp->ovl_mask & (1 << ix)) {
		r = 0;
		for (oix = 0; oix < comp->frm.num_ovls; oix++)
			if (comp->ovls[oix].cfg.ix == ovl->cfg.ix) {
				*ovl = comp->ovls[oix];
				break;
			}
		BUG_ON(oix == comp->frm.num_ovls);
	} else {
		r = -ENOENT;
	}

	mutex_unlock(&mtx);

	return r;
}
EXPORT_SYMBOL(dsscomp_get_ovl);

/* set manager info */
int dsscomp_set_mgr(dsscomp_t comp, struct dss2_mgr_info *mgr)
{
	mutex_lock(&mtx);

	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);
	BUG_ON(mgr->ix != comp->frm.mgr.ix);

	comp->frm.mgr = *mgr;

	mutex_unlock(&mtx);

	return 0;
}
EXPORT_SYMBOL(dsscomp_set_mgr);

/* get manager info */
int dsscomp_get_mgr(dsscomp_t comp, struct dss2_mgr_info *mgr)
{
	mutex_lock(&mtx);

	BUG_ON(!mgr);
	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);

	*mgr = comp->frm.mgr;

	mutex_unlock(&mtx);

	return 0;
}
EXPORT_SYMBOL(dsscomp_get_mgr);

/* get manager info */
int dsscomp_setup(dsscomp_t comp, enum dsscomp_setup_mode mode,
			struct dss2_rect_t win)
{
	mutex_lock(&mtx);

	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);

	comp->frm.mode = mode;
	comp->frm.win = win;

	mutex_unlock(&mtx);

	return 0;
}
EXPORT_SYMBOL(dsscomp_setup);

/*
 * ===========================================================================
 *		QUEUING COMMITTING OPERATIONS
 * ===========================================================================
 */
void dsscomp_drop(dsscomp_t comp)
{
	/* decrement unprogrammed references */
	if (comp->state < DSSCOMP_STATE_PROGRAMMED)
		maskref_decmask(&mgrq[comp->ix].ovl_qmask, comp->ovl_mask);
	comp->state = 0;

	if (debug & DEBUG_COMPOSITIONS)
		dev_info(DEV(cdev), "[%p] released\n", comp);

	DO_IF_DEBUG_FS(list_del(&comp->dbg_q));

	kfree(comp);
}
EXPORT_SYMBOL(dsscomp_drop);

struct dsscomp_cb_work {
	struct work_struct work;
	struct dsscomp_data *comp;
	int status;
};

static void dsscomp_mgr_delayed_cb(struct work_struct *work)
{
	struct dsscomp_cb_work *wk = container_of(work, typeof(*wk), work);
	struct dsscomp_data *comp = wk->comp;
	int status = wk->status;
	u32 ix;

	kfree(work);

	mutex_lock(&mtx);

	BUG_ON(comp->state == DSSCOMP_STATE_ACTIVE);
	ix = comp->ix;

	/* call extra callbacks if requested */
	if (comp->extra_cb)
		comp->extra_cb(comp->extra_cb_data, status);

	/* handle programming & release */
	if (status == DSS_COMPLETION_PROGRAMMED) {
		comp->state = DSSCOMP_STATE_PROGRAMMED;
		log_state(comp, dsscomp_mgr_delayed_cb, status);

		/* update used overlay mask */
		mgrq[ix].ovl_mask = comp->ovl_mask & ~comp->ovl_dmask;
		maskref_decmask(&mgrq[ix].ovl_qmask, comp->ovl_mask);

		if (debug & DEBUG_PHASES)
			dev_info(DEV(cdev), "[%p] programmed\n", comp);
	} else if ((status == DSS_COMPLETION_DISPLAYED) &&
		   comp->state == DSSCOMP_STATE_PROGRAMMED) {
		/* composition is 1st displayed */
		comp->state = DSSCOMP_STATE_DISPLAYED;
		log_state(comp, dsscomp_mgr_delayed_cb, status);
		if (debug & DEBUG_PHASES)
			dev_info(DEV(cdev), "[%p] displayed\n", comp);
	} else if (status & DSS_COMPLETION_RELEASED) {
		/* composition is no longer displayed */
		log_event(20 * comp->ix + 20, 0, comp, "%pf on %s",
				(u32) dsscomp_mgr_delayed_cb,
				(u32) log_status_str(status));
		dsscomp_drop(comp);
	}
	mutex_unlock(&mtx);
}

static u32 dsscomp_mgr_callback(void *data, int id, int status)
{
	struct dsscomp_data *comp = data;

	if (status == DSS_COMPLETION_PROGRAMMED ||
	    (status == DSS_COMPLETION_DISPLAYED &&
	     comp->state != DSSCOMP_STATE_DISPLAYED) ||
	    (status & DSS_COMPLETION_RELEASED)) {
		struct dsscomp_cb_work *wk = kzalloc(sizeof(*wk), GFP_ATOMIC);
		wk->comp = comp;
		wk->status = status;
		INIT_WORK(&wk->work, dsscomp_mgr_delayed_cb);
		queue_work(cb_wkq, &wk->work);
	}

	/* get each callback only once */
	return ~status;
}

static inline bool dssdev_manually_updated(struct omap_dss_device *dev)
{
	return dev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
		dev->driver->get_update_mode(dev) != OMAP_DSS_UPDATE_AUTO;
}

/* apply composition */
/* at this point the composition is not on any queue */
static int dsscomp_apply(dsscomp_t comp)
{
	int i, r = -EFAULT;
	u32 dmask, display_ix;
	struct omap_dss_device *dssdev;
	struct omap_dss_driver *drv;
	struct omap_overlay_manager *mgr;
	struct omap_overlay *ovl;
	struct dsscomp_setup_mgr_data *d;
	u32 oix;
	bool cb_programmed = false;

	struct omapdss_ovl_cb cb = {
		.fn = dsscomp_mgr_callback,
		.data = comp,
		.mask = DSS_COMPLETION_DISPLAYED |
		DSS_COMPLETION_PROGRAMMED | DSS_COMPLETION_RELEASED,
	};

	BUG_ON(comp->state != DSSCOMP_STATE_APPLYING);

	/* check if the display is valid and used */
	r = -ENODEV;
	d = &comp->frm;
	display_ix = d->mgr.ix;
	if (display_ix >= cdev->num_displays)
		goto done;
	dssdev = cdev->displays[display_ix];
	if (!dssdev)
		goto done;

	drv = dssdev->driver;
	mgr = dssdev->manager;
	if (!mgr || !drv || mgr->id >= cdev->num_mgrs)
		goto done;

	dump_comp_info(cdev, d, "apply");

	r = 0;
	dmask = 0;
	for (oix = 0; oix < comp->frm.num_ovls; oix++) {
		struct dss2_ovl_info *oi = comp->ovls + oix;

		/* keep track of disabled overlays */
		if (!oi->cfg.enabled)
			dmask |= 1 << oi->cfg.ix;

		if (r && !comp->must_apply)
			continue;

		dump_ovl_info(cdev, oi);

		if (oi->cfg.ix >= cdev->num_ovls) {
			r = -EINVAL;
			continue;
		}
		ovl = cdev->ovls[oi->cfg.ix];

		/* set overlays' manager & info */
		if (ovl->info.enabled && ovl->manager != mgr) {
			r = -EBUSY;
			goto skip_ovl_set;
		}
		if (ovl->manager != mgr) {
			/*
			 * Ideally, we should call ovl->unset_manager(ovl),
			 * but it may block on go even though the disabling
			 * of the overlay already went through.  So instead,
			 * we are just clearing the manager.
			 */
			ovl->manager = NULL;
			r = ovl->set_manager(ovl, mgr);
			if (r)
				goto skip_ovl_set;
		}

		r = set_dss_ovl_info(oi);
skip_ovl_set:
		if (r && comp->must_apply) {
			dev_err(DEV(cdev), "[%p] set ovl%d failed %d", comp,
								oi->cfg.ix, r);
			oi->cfg.enabled = false;
			dmask |= 1 << oi->cfg.ix;
			set_dss_ovl_info(oi);
		}
	}

	/*
	 * set manager's info - this also sets the completion callback,
	 * so if it succeeds, we will use the callback to complete the
	 * composition.  Otherwise, we can skip the composition now.
	 */
	if (!r || comp->must_apply) {
		r = set_dss_mgr_info(&d->mgr, &cb);
		cb_programmed = r == 0;
	}

	if (r && !comp->must_apply) {
		dev_err(DEV(cdev), "[%p] set failed %d\n", comp, r);
		goto done;
	} else {
		if (r)
			dev_warn(DEV(cdev), "[%p] ignoring set failure %d\n",
								comp, r);
		comp->blank = dmask == comp->ovl_mask;
		comp->ovl_dmask = dmask;

		/*
		 * Check other overlays that may also use this display.
		 * NOTE: This is only needed in case someone changes
		 * overlays via sysfs.  We use comp->ovl_mask to refresh
		 * the overlays actually used on a manager when the
		 * composition is programmed.
		 */
		for (i = 0; i < cdev->num_ovls; i++) {
			u32 mask = 1 << i;
			if ((~comp->ovl_mask & mask) &&
			    cdev->ovls[i]->info.enabled &&
			    cdev->ovls[i]->manager == mgr) {
				mutex_lock(&mtx);
				comp->ovl_mask |= mask;
				maskref_incbit(&mgrq[comp->ix].ovl_qmask, i);
				mutex_unlock(&mtx);
			}
		}
	}

	/* apply changes and call update on manual panels */
	/* no need for mutex as no callbacks are scheduled yet */
	comp->state = DSSCOMP_STATE_APPLIED;
	log_state(comp, dsscomp_apply, 0);

	if (!d->win.w && !d->win.x)
		d->win.w = dssdev->panel.timings.x_res - d->win.x;
	if (!d->win.h && !d->win.y)
		d->win.h = dssdev->panel.timings.y_res - d->win.y;

	mutex_lock(&mtx);
	if (mgrq[comp->ix].blanking) {
		pr_info_ratelimited("ignoring apply mgr(%s) while blanking\n",
				    mgr->name);
		r = -ENODEV;
	} else {
		r = mgr->apply(mgr);
		/* keep error if set_mgr_info failed */
		if (!r && !cb_programmed)
			r = -EINVAL;
	}
	mutex_unlock(&mtx);

	/*
	 * TRICKY: try to unregister callback to see if callbacks have
	 * been applied (moved into DSS2 pipeline).  Unregistering also
	 * avoids having to unnecessarily kick out compositions (which
	 * would result in screen blinking).  If callbacks failed to apply,
	 * (e.g. could not set them or apply them) we will need to call
	 * them ourselves (we note this by returning an error).
	 */
	if (cb_programmed && r) {
		/* clear error if callback already registered */
		if (omap_dss_manager_unregister_callback(mgr, &cb))
			r = 0;
	}
	/* if failed to apply, kick out prior composition */
	if (comp->must_apply && r)
		mgr->blank(mgr, true);

	if (!r && (d->mode & DSSCOMP_SETUP_MODE_DISPLAY)) {
		/* cannot handle update errors, so ignore them */
		if (dssdev_manually_updated(dssdev) && drv->update)
			drv->update(dssdev, d->win.x,
					d->win.y, d->win.w, d->win.h);
		else
			/* wait for sync to do smooth animations */
			mgr->wait_for_vsync(mgr);
	}

done:
	return r;
}

struct dsscomp_apply_work {
	struct work_struct work;
	dsscomp_t comp;
};

int dsscomp_state_notifier(struct notifier_block *nb,
						unsigned long arg, void *ptr)
{
	struct omap_dss_device *dssdev = ptr;
	enum omap_dss_display_state state = arg;
	struct omap_overlay_manager *mgr = dssdev->manager;
	if (mgr) {
		mutex_lock(&mtx);
		if (state == OMAP_DSS_DISPLAY_DISABLED) {
			mgr->blank(mgr, true);
			mgrq[mgr->id].blanking = true;
		} else if (state == OMAP_DSS_DISPLAY_ACTIVE) {
			mgrq[mgr->id].blanking = false;
		}
		mutex_unlock(&mtx);
	}
	return 0;
}


static void dsscomp_do_apply(struct work_struct *work)
{
	struct dsscomp_apply_work *wk = container_of(work, typeof(*wk), work);
	/* complete compositions that failed to apply */
	if (dsscomp_apply(wk->comp))
		dsscomp_mgr_callback(wk->comp, -1, DSS_COMPLETION_ECLIPSED_SET);
	kfree(wk);
}

int dsscomp_delayed_apply(dsscomp_t comp)
{
	/* don't block in case we are called from interrupt context */
	struct dsscomp_apply_work *wk = kzalloc(sizeof(*wk), GFP_NOWAIT);
	if (!wk)
		return -ENOMEM;

	mutex_lock(&mtx);

	BUG_ON(comp->state != DSSCOMP_STATE_ACTIVE);
	comp->state = DSSCOMP_STATE_APPLYING;
	log_state(comp, dsscomp_delayed_apply, 0);

	if (debug & DEBUG_PHASES)
		dev_info(DEV(cdev), "[%p] applying\n", comp);
	mutex_unlock(&mtx);

	wk->comp = comp;
	INIT_WORK(&wk->work, dsscomp_do_apply);
	return queue_work(mgrq[comp->ix].apply_workq, &wk->work) ? 0 : -EBUSY;
}
EXPORT_SYMBOL(dsscomp_delayed_apply);

/*
 * ===========================================================================
 *		DEBUGFS
 * ===========================================================================
 */

#ifdef CONFIG_DEBUG_FS
void seq_print_comp(struct seq_file *s, dsscomp_t c)
{
	struct dsscomp_setup_mgr_data *d = &c->frm;
	int i;

	seq_printf(s, "  [%p]: %s%s\n", c, c->blank ? "blank " : "",
		   c->state == DSSCOMP_STATE_ACTIVE ? "ACTIVE" :
		   c->state == DSSCOMP_STATE_APPLYING ? "APPLYING" :
		   c->state == DSSCOMP_STATE_APPLIED ? "APPLIED" :
		   c->state == DSSCOMP_STATE_PROGRAMMED ? "PROGRAMMED" :
		   c->state == DSSCOMP_STATE_DISPLAYED ? "DISPLAYED" :
		   "???");
	seq_printf(s, "    sync_id=%x, flags=%c%c%c\n",
		   d->sync_id,
		   (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-',
		   (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-',
		   (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-');
	for (i = 0; i < d->num_ovls; i++) {
		struct dss2_ovl_info *oi;
		struct dss2_ovl_cfg *g;
		oi = d->ovls + i;
		g = &oi->cfg;
		if (g->zonly) {
			seq_printf(s, "    ovl%d={%s z%d}\n",
				   g->ix, g->enabled ? "ON" : "off", g->zorder);
		} else {
			seq_printf(s, "    ovl%d={%s z%d %s%s *%d%%"
						" %d*%d:%d,%d+%d,%d rot%d%s"
						" => %d,%d+%d,%d %p/%p|%d}\n",
				g->ix, g->enabled ? "ON" : "off", g->zorder,
				dsscomp_get_color_name(g->color_mode) ? : "N/A",
				g->pre_mult_alpha ? " premult" : "",
				(g->global_alpha * 100 + 128) / 255,
				g->width, g->height, g->crop.x, g->crop.y,
				g->crop.w, g->crop.h,
				g->rotation, g->mirror ? "+mir" : "",
				g->win.x, g->win.y, g->win.w, g->win.h,
				(void *) oi->ba, (void *) oi->uv, g->stride);
		}
	}
	if (c->extra_cb)
		seq_printf(s, "    gsync=[%p] %pf\n\n", c->extra_cb_data,
								c->extra_cb);
	else
		seq_printf(s, "    gsync=[%p] (called)\n\n", c->extra_cb_data);
}
#endif

void dsscomp_dbg_comps(struct seq_file *s)
{
#ifdef CONFIG_DEBUG_FS
	dsscomp_t c;
	u32 i;

	mutex_lock(&dbg_mtx);
	for (i = 0; i < cdev->num_mgrs; i++) {
		struct omap_overlay_manager *mgr = cdev->mgrs[i];
		seq_printf(s, "ACTIVE COMPOSITIONS on %s\n\n", mgr->name);
		list_for_each_entry(c, &dbg_comps, dbg_q) {
			struct dss2_mgr_info *mi = &c->frm.mgr;
			if (mi->ix < cdev->num_displays &&
			    cdev->displays[mi->ix]->manager == mgr)
				seq_print_comp(s, c);
		}

		/* print manager cache */
		mgr->dump_cb(mgr, s);
	}
	mutex_unlock(&dbg_mtx);
#endif
}

void dsscomp_dbg_events(struct seq_file *s)
{
#ifdef CONFIG_DSSCOMP_DEBUG_LOG
	u32 i;
	struct dbg_event_t *d;

	mutex_lock(&dbg_mtx);
	for (i = dbg_event_ix; i < dbg_event_ix + ARRAY_SIZE(dbg_events); i++) {
		d = dbg_events + (i % ARRAY_SIZE(dbg_events));
		if (!d->ms)
			continue;
		seq_printf(s, "[% 5d.%03d] %*s[%08x] ",
			   d->ms / 1000, d->ms % 1000,
			   d->ix + ((u32) d->data) % 7,
			   "", (u32) d->data);
		seq_printf(s, d->fmt, d->a1, d->a2);
		seq_printf(s, "\n");
	}
	mutex_unlock(&dbg_mtx);
#endif
}

/*
 * ===========================================================================
 *		EXIT
 * ===========================================================================
 */
void dsscomp_queue_exit(void)
{
	if (cdev) {
		int i;
		for (i = 0; i < cdev->num_displays; i++)
			destroy_workqueue(mgrq[i].apply_workq);
		destroy_workqueue(cb_wkq);
		cdev = NULL;
	}
}
EXPORT_SYMBOL(dsscomp_queue_exit);
