/*
 * Tegra host1x Channel
 *
 * Copyright (c) 2010-2013, NVIDIA Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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/slab.h>
#include <linux/module.h>

#include "channel.h"
#include "dev.h"
#include "job.h"

/* Constructor for the host1x device list */
int host1x_channel_list_init(struct host1x *host)
{
	INIT_LIST_HEAD(&host->chlist.list);
	mutex_init(&host->chlist_mutex);

	if (host->info->nb_channels > BITS_PER_LONG) {
		WARN(1, "host1x hardware has more channels than supported by the driver\n");
		return -ENOSYS;
	}

	return 0;
}

int host1x_job_submit(struct host1x_job *job)
{
	struct host1x *host = dev_get_drvdata(job->channel->dev->parent);

	return host1x_hw_channel_submit(host, job);
}

struct host1x_channel *host1x_channel_get(struct host1x_channel *channel)
{
	int err = 0;

	mutex_lock(&channel->reflock);

	if (channel->refcount == 0)
		err = host1x_cdma_init(&channel->cdma);

	if (!err)
		channel->refcount++;

	mutex_unlock(&channel->reflock);

	return err ? NULL : channel;
}

void host1x_channel_put(struct host1x_channel *channel)
{
	mutex_lock(&channel->reflock);

	if (channel->refcount == 1) {
		struct host1x *host = dev_get_drvdata(channel->dev->parent);

		host1x_hw_cdma_stop(host, &channel->cdma);
		host1x_cdma_deinit(&channel->cdma);
	}

	channel->refcount--;

	mutex_unlock(&channel->reflock);
}

struct host1x_channel *host1x_channel_request(struct device *dev)
{
	struct host1x *host = dev_get_drvdata(dev->parent);
	int max_channels = host->info->nb_channels;
	struct host1x_channel *channel = NULL;
	int index, err;

	mutex_lock(&host->chlist_mutex);

	index = find_first_zero_bit(&host->allocated_channels, max_channels);
	if (index >= max_channels)
		goto fail;

	channel = kzalloc(sizeof(*channel), GFP_KERNEL);
	if (!channel)
		goto fail;

	err = host1x_hw_channel_init(host, channel, index);
	if (err < 0)
		goto fail;

	/* Link device to host1x_channel */
	channel->dev = dev;

	/* Add to channel list */
	list_add_tail(&channel->list, &host->chlist.list);

	host->allocated_channels |= BIT(index);

	mutex_unlock(&host->chlist_mutex);
	return channel;

fail:
	dev_err(dev, "failed to init channel\n");
	kfree(channel);
	mutex_unlock(&host->chlist_mutex);
	return NULL;
}

void host1x_channel_free(struct host1x_channel *channel)
{
	struct host1x *host = dev_get_drvdata(channel->dev->parent);

	host->allocated_channels &= ~BIT(channel->id);
	list_del(&channel->list);
	kfree(channel);
}
