Commit a57941c2 authored by Marin Mitov's avatar Marin Mitov Committed by Greg Kroah-Hartman
Browse files

Staging: dt3155v4l: remove private memory allocator



This patch removes the private memory allocator
and all conjugated functions. Now the driver uses
videobuf-dma-contig module for allocations.
Added reserving 4MB coherent memory for private
per device allocations at probe time.

Signed-off-by: default avatarMarin Mitov <mitov@issp.bas.bg>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent abfc768d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ config VIDEO_DT3155
	  In doubt, say N.

	  To compile this driver as a module, choose M here: the
	  module will be called dt3155_v4l.
	  module will be called dt3155v4l.

config DT3155_CCIR
	bool "Selects CCIR/50Hz vertical refresh"
+1 −4
Original line number Diff line number Diff line
obj-$(CONFIG_VIDEO_DT3155)	+= dt3155_v4l.o
dt3155_v4l-objs :=	\
		dt3155-bufs.o	\
		dt3155v4l.o
obj-$(CONFIG_VIDEO_DT3155)	+= dt3155v4l.o
+0 −256
Original line number Diff line number Diff line
/***************************************************************************
 *   Copyright (C) 2006-2010 by Marin Mitov                                *
 *   mitov@issp.bas.bg                                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "dt3155-bufs.h"

/**
 * dt3155_init_chunks_buf - creates a chunk buffer and allocates memory for it
 *
 * returns:	a pointer to the struct dt3155_buf or NULL if failed
 *
 * Creates a struct dt3155_buf, then allocates a chunk of memory of
 * size DT3155_CHUNK_SIZE and sets all the pages in it as Reserved.
 * This is done to be able to use remap_pfn_range() on these buffers
 * (which do not work on normal memory if Reserved bit is not set)
 */
struct dt3155_buf *
dt3155_init_chunks_buf(void)
{	/*  could sleep  */
	struct dt3155_buf *buf;
	int i;

	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
	if (!buf)
		return NULL;
	buf->cpu = (void *)__get_free_pages(DT3155_CHUNK_FLAGS,
					get_order(DT3155_CHUNK_SIZE));
	if (!buf->cpu) {
		kfree(buf);
		return NULL;
	}
	for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE)
		SetPageReserved(virt_to_page(buf->cpu + i));
	return buf;  /*   success  */
}

/**
 * dt3155_free_chunks_buf - destroys the specified buffer
 *
 * @buf:	the buffer to be freed
 *
 * Clears Reserved bit of all pages in the chunk, frees the chunk memory
 * and destroys struct dt3155_buf.
 */
void
dt3155_free_chunks_buf(struct dt3155_buf *buf)
{
	int i;

	for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE)
		ClearPageReserved(virt_to_page(buf->cpu + i));
	free_pages((unsigned long)buf->cpu, get_order(DT3155_CHUNK_SIZE));
	kfree(buf);
}

/**
 * dt3155_init_fifo - creates and initializes a fifo
 *
 * returns:	a pointer to the crated and initialized struct dt3155_fifo
 *		or NULL if failed
 */
struct dt3155_fifo *
dt3155_init_fifo(void)
{	/* could sleep  */
	struct dt3155_fifo *fifo = kzalloc(sizeof(*fifo), GFP_KERNEL);
	if (fifo)
		spin_lock_init(&fifo->lock);
	return fifo;
}

/*	dt3155_free_fifo(x)  defined as macro in dt3155.h   */

/**
 * dt3155_get_buf - gets a buffer from the fifo
 *
 * @fifo:	the fifo to get a buffer from
 *
 * returns:	a pointer to the buffer or NULL if failed
 *
 * dt3155_get_buf gets the fifo's spin_lock and returns the
 * buffer pointed by the head. Could be used in any context.
 */
struct dt3155_buf *
dt3155_get_buf(struct dt3155_fifo *fifo)
{
	unsigned long flags;
	struct dt3155_buf *tmp_buf;

	spin_lock_irqsave(&fifo->lock, flags);
	tmp_buf = fifo->head;
	if (fifo->head)
		fifo->head = fifo->head->next;
	if (!fifo->head)
		fifo->tail = NULL;
	spin_unlock_irqrestore(&fifo->lock, flags);
	return tmp_buf;
}

/**
 * dt3155_put_buf - puts a buffer into a fifo
 *
 * @buf:	the buffer to put
 * @fifo:	the fifo to put the buffer in
 *
 * dt3155_put_buf gets the fifo's spin_lock and puts the buf
 * at the tail of the fifo. Could be used in any context.
 */
void
dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo)
{
	unsigned long flags;

	spin_lock_irqsave(&fifo->lock, flags);
	buf->next = NULL;
	if (fifo->tail)
		fifo->tail->next = buf;
	fifo->tail = buf;
	if (!fifo->head)
		fifo->head = buf;
	spin_unlock_irqrestore(&fifo->lock, flags);
}

/**
 * dt3155_init_chunks_fifo - creates and fills a chunks_fifo
 *
 * returns:	a pointer to the fifo or NULL if failed
 *
 * dt3155_init_chunks_fifo creates and fills the fifo with
 * a number of chunks <= DT3155_CHUNK_NUM. The returned fifo
 * contains at least one chunk.
 */
struct dt3155_fifo *
dt3155_init_chunks_fifo(void)
{	/*  could sleep  */
	int i;

	struct dt3155_fifo *chunks;
	struct dt3155_buf *tmp_buf;

	chunks = dt3155_init_fifo();
	if (!chunks)
		return NULL;
	tmp_buf = dt3155_init_chunks_buf();
	if (!tmp_buf) {
		dt3155_free_fifo(chunks);
		return NULL;
	}
	dt3155_put_buf(tmp_buf, chunks);
	for (i = 1; i < DT3155_CHUNK_NUM; i++) {
		tmp_buf = dt3155_init_chunks_buf();
		if (!tmp_buf)
			break;
		dt3155_put_buf(tmp_buf, chunks);
	}
	return chunks;
}

/**
 * dt3155_free_chunks_fifo - empties and destroys the chunks_fifo
 *
 * @chunks:	the chunks_fifo to be freed
 *
 * dt3155_free_chunks_fifo deallocates all chunks in the fifo and
 * destroys it.
 */
void
dt3155_free_chunks_fifo(struct dt3155_fifo *chunks)
{
	int buf_count = 0;
	struct dt3155_buf *buf;

	while ((buf = dt3155_get_buf(chunks))) {
		dt3155_free_chunks_buf(buf);
		buf_count++;
	}
	dt3155_free_fifo(chunks);
	printk(KERN_INFO "dt3155: %i chunks freed\n", buf_count);
}

/**
 * dt3155_init_ibufs_fifo - creates and fills an image buffer fifo
 *
 * @chunks:	chunks_fifo to take memory from
 * @buf_size:	the size of image buffers
 *
 * returns:	a pointer to the fifo filled with image buffers
 *
 * dt3155_init_ibufs_fifo takes chunks from chunks_fifo, chops them
 * into pieces of size buf_size and fills image fifo with them.
 */
struct dt3155_fifo *
dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size)
{	/*  could sleep  */
	int i, buf_count = 0;
	struct dt3155_buf *tmp_ibuf, *chunks_buf, *last_chunk;
	struct dt3155_fifo *tmp_fifo;

	tmp_fifo = dt3155_init_fifo();
	if (!tmp_fifo)
		return NULL;
	last_chunk = chunks->tail;
	do {
		chunks_buf = dt3155_get_buf(chunks);
		dt3155_put_buf(chunks_buf, chunks);
		for (i = 0; i < DT3155_CHUNK_SIZE / buf_size; i++) {
			tmp_ibuf = kzalloc(sizeof(*tmp_ibuf), GFP_KERNEL);
			if (tmp_ibuf) {
				tmp_ibuf->cpu =
					chunks_buf->cpu + DT3155_BUF_SIZE * i;
				dt3155_put_buf(tmp_ibuf, tmp_fifo);
				buf_count++;
			} else {
				if (buf_count) {
					goto print_num_bufs;
				} else {
					dt3155_free_fifo(tmp_fifo);
					return NULL;
				}
			}
		}
	} while (chunks_buf != last_chunk);
print_num_bufs:
	printk(KERN_INFO "dt3155: %i image buffers available\n", buf_count);
	return tmp_fifo;
}

/**
 * dt3155_free_ibufs_fifo - empties and destroys an image fifo
 *
 * @fifo:	the fifo to free
 */
void
dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo)
{
	struct dt3155_buf *tmp_ibuf;

	while ((tmp_ibuf = dt3155_get_buf(fifo)))
		kfree(tmp_ibuf);
	kfree(fifo);
}
+0 −88
Original line number Diff line number Diff line
/***************************************************************************
 *   Copyright (C) 2006-2010 by Marin Mitov                                *
 *   mitov@issp.bas.bg                                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _DT3155_BUFS_H_
#define _DT3155_BUFS_H_

#include <linux/pci.h>

/* 4 chunks of 4MB, 9 buffers each = 36 buffers (> VIDEO_MAX_FRAME) */
#define DT3155_CHUNK_NUM 4

/* DT3155_CHUNK_SIZE should be 4M (2^22) or less, but more than image size */
#define DT3155_CHUNK_SIZE (1U << 22)
#define DT3155_CHUNK_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN)

/* DT3155_BUF_SIZE = 108 * PAGE_SIZE, so each buf is PAGE_SIZE alligned  */
#define DT3155_BUF_SIZE (768 * 576)

/**
 * struct dt3155_buf - image buffer structure
 *
 * @cpu:	virtual kernel address of the buffer
 * @dma:	dma (bus) address of the buffer
 * @next:	pointer to the next buffer in the fifo
 * @tv:		time value when the image has been acquired
 */
struct dt3155_buf {
	void *cpu;
	dma_addr_t dma;
	struct dt3155_buf *next;
	struct timeval tv;
};

/**
 * struct dt3155_fifo - fifo structure
 *
 * @head:	pointer to the head of the fifo
 * @tail:	pionter to the tail of the fifo
 * @lock:	spin_lock to protect the fifo
 */
struct dt3155_fifo {
	struct dt3155_buf *head;
	struct dt3155_buf *tail;
	spinlock_t lock;
};

struct dt3155_buf * __must_check
dt3155_init_chunks_buf(void);
void
dt3155_free_chunks_buf(struct dt3155_buf *buf);

struct dt3155_fifo * __must_check
dt3155_init_fifo(void);
#define dt3155_free_fifo(x) kfree(x)

struct dt3155_buf * __must_check
dt3155_get_buf(struct dt3155_fifo *fifo);
void
dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo);

struct dt3155_fifo * __must_check
dt3155_init_chunks_fifo(void);
void
dt3155_free_chunks_fifo(struct dt3155_fifo *chunks);

struct dt3155_fifo * __must_check
dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size);
void
dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo);

#endif /*  _DT3155_BUFS_H_  */
+103 −500

File changed.

Preview size limit exceeded, changes collapsed.

Loading