linux/drivers/media/video/zoran_procfs.c
Arjan van de Ven fa027c2a0a [PATCH] mark struct file_operations const 4
Many struct file_operations in the kernel can be "const".  Marking them const
moves these to the .rodata section, which avoids false sharing with potential
dirty data.  In addition it'll catch accidental writes at compile time to
these shared resources.

[akpm@sdl.org: dvb fix]
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-02-12 09:48:45 -08:00

234 lines
5.4 KiB
C

/*
* Zoran zr36057/zr36067 PCI controller driver, for the
* Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
* Media Labs LML33/LML33R10.
*
* This part handles the procFS entries (/proc/ZORAN[%d])
*
* Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
*
* Currently maintained by:
* Ronald Bultje <rbultje@ronald.bitfreak.net>
* Laurent Pinchart <laurent.pinchart@skynet.be>
* Mailinglist <mjpeg-users@lists.sf.net>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/videodev.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
#include <linux/poll.h>
#include <asm/io.h>
#include "videocodec.h"
#include "zoran.h"
#include "zoran_procfs.h"
extern int *zr_debug;
#define dprintk(num, format, args...) \
do { \
if (*zr_debug >= num) \
printk(format, ##args); \
} while (0)
#ifdef CONFIG_PROC_FS
struct procfs_params_zr36067 {
char *name;
short reg;
u32 mask;
short bit;
};
static const struct procfs_params_zr36067 zr67[] = {
{"HSPol", 0x000, 1, 30},
{"HStart", 0x000, 0x3ff, 10},
{"HEnd", 0x000, 0x3ff, 0},
{"VSPol", 0x004, 1, 30},
{"VStart", 0x004, 0x3ff, 10},
{"VEnd", 0x004, 0x3ff, 0},
{"ExtFl", 0x008, 1, 26},
{"TopField", 0x008, 1, 25},
{"VCLKPol", 0x008, 1, 24},
{"DupFld", 0x008, 1, 20},
{"LittleEndian", 0x008, 1, 0},
{"HsyncStart", 0x10c, 0xffff, 16},
{"LineTot", 0x10c, 0xffff, 0},
{"NAX", 0x110, 0xffff, 16},
{"PAX", 0x110, 0xffff, 0},
{"NAY", 0x114, 0xffff, 16},
{"PAY", 0x114, 0xffff, 0},
/* {"",,,}, */
{NULL, 0, 0, 0},
};
static void
setparam (struct zoran *zr,
char *name,
char *sval)
{
int i = 0, reg0, reg, val;
while (zr67[i].name != NULL) {
if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
reg = reg0 = btread(zr67[i].reg);
reg &= ~(zr67[i].mask << zr67[i].bit);
if (!isdigit(sval[0]))
break;
val = simple_strtoul(sval, NULL, 0);
if ((val & ~zr67[i].mask))
break;
reg |= (val & zr67[i].mask) << zr67[i].bit;
dprintk(4,
KERN_INFO
"%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
ZR_DEVNAME(zr), zr67[i].reg, reg0, reg,
zr67[i].name, val);
btwrite(reg, zr67[i].reg);
break;
}
i++;
}
}
static int zoran_show(struct seq_file *p, void *v)
{
struct zoran *zr = p->private;
int i;
seq_printf(p, "ZR36067 registers:\n");
for (i = 0; i < 0x130; i += 16)
seq_printf(p, "%03X %08X %08X %08X %08X \n", i,
btread(i), btread(i+4), btread(i+8), btread(i+12));
return 0;
}
static int zoran_open(struct inode *inode, struct file *file)
{
struct zoran *data = PDE(inode)->data;
return single_open(file, zoran_show, data);
}
static ssize_t zoran_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct zoran *zr = PDE(file->f_path.dentry->d_inode)->data;
char *string, *sp;
char *line, *ldelim, *varname, *svar, *tdelim;
if (count > 32768) /* Stupidity filter */
return -EINVAL;
string = sp = vmalloc(count + 1);
if (!string) {
dprintk(1,
KERN_ERR
"%s: write_proc: can not allocate memory\n",
ZR_DEVNAME(zr));
return -ENOMEM;
}
if (copy_from_user(string, buffer, count)) {
vfree (string);
return -EFAULT;
}
string[count] = 0;
dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n",
ZR_DEVNAME(zr), file->f_path.dentry->d_name.name, count, zr);
ldelim = " \t\n";
tdelim = "=";
line = strpbrk(sp, ldelim);
while (line) {
*line = 0;
svar = strpbrk(sp, tdelim);
if (svar) {
*svar = 0;
varname = sp;
svar++;
setparam(zr, varname, svar);
}
sp = line + 1;
line = strpbrk(sp, ldelim);
}
vfree(string);
return count;
}
static const struct file_operations zoran_operations = {
.open = zoran_open,
.read = seq_read,
.write = zoran_write,
.llseek = seq_lseek,
.release = single_release,
};
#endif
int
zoran_proc_init (struct zoran *zr)
{
#ifdef CONFIG_PROC_FS
char name[8];
snprintf(name, 7, "zoran%d", zr->id);
if ((zr->zoran_proc = create_proc_entry(name, 0, NULL))) {
zr->zoran_proc->data = zr;
zr->zoran_proc->owner = THIS_MODULE;
zr->zoran_proc->proc_fops = &zoran_operations;
dprintk(2,
KERN_INFO
"%s: procfs entry /proc/%s allocated. data=%p\n",
ZR_DEVNAME(zr), name, zr->zoran_proc->data);
} else {
dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
ZR_DEVNAME(zr), name);
return 1;
}
#endif
return 0;
}
void
zoran_proc_cleanup (struct zoran *zr)
{
#ifdef CONFIG_PROC_FS
char name[8];
snprintf(name, 7, "zoran%d", zr->id);
if (zr->zoran_proc)
remove_proc_entry(name, NULL);
zr->zoran_proc = NULL;
#endif
}