/*
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.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 "msm_drv.h"
#include "mdp_kms.h"


struct mdp_irq_wait {
	struct mdp_irq irq;
	int count;
};

static DECLARE_WAIT_QUEUE_HEAD(wait_event);

static DEFINE_SPINLOCK(list_lock);

static void update_irq(struct mdp_kms *mdp_kms)
{
	struct mdp_irq *irq;
	uint32_t irqmask = mdp_kms->vblank_mask;

	BUG_ON(!spin_is_locked(&list_lock));

	list_for_each_entry(irq, &mdp_kms->irq_list, node)
		irqmask |= irq->irqmask;

	mdp_kms->funcs->set_irqmask(mdp_kms, irqmask);
}

static void update_irq_unlocked(struct mdp_kms *mdp_kms)
{
	unsigned long flags;
	spin_lock_irqsave(&list_lock, flags);
	update_irq(mdp_kms);
	spin_unlock_irqrestore(&list_lock, flags);
}

void mdp_dispatch_irqs(struct mdp_kms *mdp_kms, uint32_t status)
{
	struct mdp_irq *handler, *n;
	unsigned long flags;

	spin_lock_irqsave(&list_lock, flags);
	mdp_kms->in_irq = true;
	list_for_each_entry_safe(handler, n, &mdp_kms->irq_list, node) {
		if (handler->irqmask & status) {
			spin_unlock_irqrestore(&list_lock, flags);
			handler->irq(handler, handler->irqmask & status);
			spin_lock_irqsave(&list_lock, flags);
		}
	}
	mdp_kms->in_irq = false;
	update_irq(mdp_kms);
	spin_unlock_irqrestore(&list_lock, flags);

}

void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable)
{
	unsigned long flags;

	spin_lock_irqsave(&list_lock, flags);
	if (enable)
		mdp_kms->vblank_mask |= mask;
	else
		mdp_kms->vblank_mask &= ~mask;
	update_irq(mdp_kms);
	spin_unlock_irqrestore(&list_lock, flags);
}

static void wait_irq(struct mdp_irq *irq, uint32_t irqstatus)
{
	struct mdp_irq_wait *wait =
			container_of(irq, struct mdp_irq_wait, irq);
	wait->count--;
	wake_up_all(&wait_event);
}

void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask)
{
	struct mdp_irq_wait wait = {
		.irq = {
			.irq = wait_irq,
			.irqmask = irqmask,
		},
		.count = 1,
	};
	mdp_irq_register(mdp_kms, &wait.irq);
	wait_event(wait_event, (wait.count <= 0));
	mdp_irq_unregister(mdp_kms, &wait.irq);
}

void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
{
	unsigned long flags;
	bool needs_update = false;

	spin_lock_irqsave(&list_lock, flags);

	if (!irq->registered) {
		irq->registered = true;
		list_add(&irq->node, &mdp_kms->irq_list);
		needs_update = !mdp_kms->in_irq;
	}

	spin_unlock_irqrestore(&list_lock, flags);

	if (needs_update)
		update_irq_unlocked(mdp_kms);
}

void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
{
	unsigned long flags;
	bool needs_update = false;

	spin_lock_irqsave(&list_lock, flags);

	if (irq->registered) {
		irq->registered = false;
		list_del(&irq->node);
		needs_update = !mdp_kms->in_irq;
	}

	spin_unlock_irqrestore(&list_lock, flags);

	if (needs_update)
		update_irq_unlocked(mdp_kms);
}
