diff options
Diffstat (limited to 'drivers')
173 files changed, 3181 insertions, 1448 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index d26891bfcd4..c7afc068c28 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -559,7 +559,40 @@ struct timer_rand_state { }; #ifndef CONFIG_SPARSE_IRQ -struct timer_rand_state *irq_timer_state[NR_IRQS]; + +static struct timer_rand_state *irq_timer_state[NR_IRQS]; + +static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + return irq_timer_state[irq]; +} + +static void set_timer_rand_state(unsigned int irq, + struct timer_rand_state *state) +{ + irq_timer_state[irq] = state; +} + +#else + +static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + return desc->timer_rand_state; +} + +static void set_timer_rand_state(unsigned int irq, + struct timer_rand_state *state) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + desc->timer_rand_state = state; +} #endif static struct timer_rand_state input_timer_state; @@ -919,11 +952,6 @@ void rand_initialize_irq(int irq) { struct timer_rand_state *state; -#ifndef CONFIG_SPARSE_IRQ - if (irq >= nr_irqs) - return; -#endif - state = get_timer_rand_state(irq); if (state) diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 7d844af8838..cf06f4d10ad 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -192,9 +192,9 @@ void saa7146_buffer_timeout(unsigned long data) /********************************************************************************/ /* file operations */ -static int fops_open(struct inode *inode, struct file *file) +static int fops_open(struct file *file) { - unsigned int minor = iminor(inode); + unsigned int minor = video_devdata(file)->minor; struct saa7146_dev *h = NULL, *dev = NULL; struct list_head *list; struct saa7146_fh *fh = NULL; @@ -202,7 +202,7 @@ static int fops_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor)); + DEB_EE(("file:%p, minor:%d\n", file, minor)); if (mutex_lock_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; @@ -255,7 +255,7 @@ static int fops_open(struct inode *inode, struct file *file) if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) result = saa7146_vbi_uops.open(dev,file); if (dev->ext_vv_data->vbi_fops.open) - dev->ext_vv_data->vbi_fops.open(inode, file); + dev->ext_vv_data->vbi_fops.open(file); } else { DEB_S(("initializing video...\n")); result = saa7146_video_uops.open(dev,file); @@ -280,12 +280,12 @@ out: return result; } -static int fops_release(struct inode *inode, struct file *file) +static int fops_release(struct file *file) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; - DEB_EE(("inode:%p, file:%p\n",inode,file)); + DEB_EE(("file:%p\n", file)); if (mutex_lock_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; @@ -294,7 +294,7 @@ static int fops_release(struct inode *inode, struct file *file) if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) saa7146_vbi_uops.release(dev,file); if (dev->ext_vv_data->vbi_fops.release) - dev->ext_vv_data->vbi_fops.release(inode, file); + dev->ext_vv_data->vbi_fops.release(file); } else { saa7146_video_uops.release(dev,file); } @@ -308,10 +308,10 @@ static int fops_release(struct inode *inode, struct file *file) return 0; } -static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* - DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg)); + DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg)); */ return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); } @@ -416,7 +416,7 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou } } -static const struct file_operations video_fops = +static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, .open = fops_open, @@ -426,7 +426,6 @@ static const struct file_operations video_fops = .poll = fops_poll, .mmap = fops_mmap, .ioctl = fops_ioctl, - .llseek = no_llseek, }; static void vv_callback(struct saa7146_dev *dev, unsigned long status) diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 101b01dbb8e..6098b626811 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -834,13 +834,14 @@ static int video_end(struct saa7146_fh *fh, struct file *file) * copying is done already, arg is a kernel pointer. */ -int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) +long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; - int err = 0, result = 0, ee = 0; + long err = 0; + int result = 0, ee = 0; struct saa7146_use_ops *ops; struct videobuf_queue *q; diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index fb3f3b3adab..de7adaf5fa5 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c @@ -820,6 +820,15 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, int ret; unsigned frequency = params->frequency / 62500; + if (!tun->stepsize) { + /* tuner-core was loaded before the digital tuner was + * configured and somehow picked the wrong tuner type */ + tuner_err("attempt to treat tuner %d (%s) as digital tuner " + "without stepsize defined.\n", + priv->type, priv->tun->name); + return 0; /* failure */ + } + t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); if (ret < 0) @@ -1059,7 +1068,12 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops)); - tuner_info("type set to %d (%s)\n", type, priv->tun->name); + if (type != priv->type) + tuner_warn("couldn't set type to %d. Using %d (%s) instead\n", + type, priv->type, priv->tun->name); + else + tuner_info("type set to %d (%s)\n", + priv->type, priv->tun->name); if ((debug) || ((atv_input[priv->nr] > 0) || (dtv_input[priv->nr] > 0))) { diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 6c571d9f011..65d69665f1f 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -436,8 +436,9 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct dvb_device *dvbdev = dev_get_drvdata(dev); - add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); + add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); + add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); return 0; } diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index c1da962cc88..3dd6843864e 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c @@ -187,7 +187,7 @@ int gp8psk_bcm4500_reload(struct dvb_usb_device *d) /* load BCM4500 firmware */ if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) if (gp8psk_load_bcm4500fw(d)) - return EINVAL; + return -EINVAL; return 0; } diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 9b6c89e93f1..4f514d39b98 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -1463,6 +1463,7 @@ static struct dvb_frontend_ops cx24116_ops = { FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_2G_MODULATION | FE_CAN_QPSK | FE_CAN_RECOVER }, diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h index 4cb3ddd6c62..b1b76b47a14 100644 --- a/drivers/media/dvb/frontends/cx24116.h +++ b/drivers/media/dvb/frontends/cx24116.h @@ -37,7 +37,8 @@ struct cx24116_config { u8 mpg_clk_pos_pol:0x02; }; -#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) +#if defined(CONFIG_DVB_CX24116) || \ + (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE)) extern struct dvb_frontend *cx24116_attach( const struct cx24116_config *config, struct i2c_adapter *i2c); diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 52882017022..bee28f77b93 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c @@ -1618,6 +1618,7 @@ static struct dvb_frontend_ops stb0899_ops = { .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | + FE_CAN_2G_MODULATION | FE_CAN_QPSK }, diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 5506f80e180..170720b0281 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -587,8 +587,15 @@ static int zl10353_init(struct dvb_frontend *fe) static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { + struct zl10353_state *state = fe->demodulator_priv; u8 val = 0x0a; + if (state->config.no_tuner) { + /* No tuner attached to the internal I2C bus */ + /* If set enable I2C bridge, the main I2C bus stopped hardly */ + return 0; + } + if (enable) val |= 0x10; diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index fd62e0b8562..4307e4e8aa3 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -120,7 +120,7 @@ static struct sms_board sms_boards[] = { .name = "Hauppauge WinTV MiniCard", .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .lna_ctrl = 1, + .lna_ctrl = -1, }, }; @@ -131,9 +131,10 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } -static int sms_set_gpio(struct smscore_device_t *coredev, u32 pin, int enable) +static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { - int ret; + int lvl, ret; + u32 gpio; struct smscore_gpio_config gpioconfig = { .direction = SMS_GPIO_DIRECTION_OUTPUT, .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, @@ -145,12 +146,20 @@ static int sms_set_gpio(struct smscore_device_t *coredev, u32 pin, int enable) if (pin == 0) return -EINVAL; - ret = smscore_configure_gpio(coredev, pin, &gpioconfig); + if (pin < 0) { + /* inverted gpio */ + gpio = pin * -1; + lvl = enable ? 0 : 1; + } else { + gpio = pin; + lvl = enable ? 1 : 0; + } + ret = smscore_configure_gpio(coredev, gpio, &gpioconfig); if (ret < 0) return ret; - return smscore_set_gpio(coredev, pin, enable); + return smscore_set_gpio(coredev, gpio, lvl); } int sms_board_setup(struct smscore_device_t *coredev) diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index b4a0cc5dc93..c5b9c70563d 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c @@ -316,7 +316,7 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) return 0; } -static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct av7110 *av7110 = (struct av7110*) dev->ext_priv; @@ -567,7 +567,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) return 0; } -static int av7110_vbi_reset(struct inode *inode, struct file *file) +static int av7110_vbi_reset(struct file *file) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index f996cef79ec..4182121d7e5 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -1493,7 +1493,7 @@ static struct saa7146_extension_ioctls ioctls[] = { {0, 0} }; -static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index f546bccdb99..2663ae39b88 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig @@ -1,6 +1,6 @@ config DVB_TTUSB_BUDGET tristate "Technotrend/Hauppauge Nova-USB devices" - depends on DVB_CORE && USB && I2C + depends on DVB_CORE && USB && I2C && PCI select DVB_CX22700 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_VES1820 if !DVB_FE_CUSTOMISE diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index d5f48a3102b..290254ab06d 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig @@ -1,6 +1,6 @@ config DVB_TTUSB_DEC tristate "Technotrend/Hauppauge USB DEC devices" - depends on DVB_CORE && USB && INPUT + depends on DVB_CORE && USB && INPUT && PCI select CRC32 help Support for external USB adapters designed by Technotrend and diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 5189c4eb439..3315cac875e 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -387,4 +387,23 @@ config USB_MR800 To compile this driver as a module, choose M here: the module will be called radio-mr800. +config RADIO_TEA5764 + tristate "TEA5764 I2C FM radio support" + depends on I2C && VIDEO_V4L2 + ---help--- + Say Y here if you want to use the TEA5764 FM chip found in + EZX phones. This FM chip is present in EZX phones from Motorola, + connected to internal pxa I2C bus. + + To compile this driver as a module, choose M here: the + module will be called radio-tea5764. + +config RADIO_TEA5764_XTAL + bool "TEA5764 crystal reference" + depends on RADIO_TEA5764=y + default y + help + Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N + here if TEA5764 reference frequency is connected in FREQIN. + endif # RADIO_ADAPTERS diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 240ec63cdaf..0f2b35b3e56 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -19,5 +19,6 @@ obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_USB_SI470X) += radio-si470x.o obj-$(CONFIG_USB_MR800) += radio-mr800.o +obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o EXTRA_CFLAGS += -Isound diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 5474a22c1b2..2014ebc4e98 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -154,8 +154,8 @@ devices, that would be 76 and 91. */ static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id); static void usb_dsbr100_disconnect(struct usb_interface *intf); -static int usb_dsbr100_open(struct inode *inode, struct file *file); -static int usb_dsbr100_close(struct inode *inode, struct file *file); +static int usb_dsbr100_open(struct file *file); +static int usb_dsbr100_close(struct file *file); static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message); static int usb_dsbr100_resume(struct usb_interface *intf); @@ -566,7 +566,7 @@ static int vidioc_s_audio(struct file *file, void *priv, return 0; } -static int usb_dsbr100_open(struct inode *inode, struct file *file) +static int usb_dsbr100_open(struct file *file) { struct dsbr100_device *radio = video_drvdata(file); int retval; @@ -593,7 +593,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) return 0; } -static int usb_dsbr100_close(struct inode *inode, struct file *file) +static int usb_dsbr100_close(struct file *file) { struct dsbr100_device *radio = video_drvdata(file); int retval; @@ -653,15 +653,11 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev) } /* File system interface */ -static const struct file_operations usb_dsbr100_fops = { +static const struct v4l2_file_operations usb_dsbr100_fops = { .owner = THIS_MODULE, .open = usb_dsbr100_open, .release = usb_dsbr100_close, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index dd6d3dfcd7d..bfa13b8b304 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -374,26 +374,22 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct rt_device rtrack_unit; -static int rtrack_exclusive_open(struct inode *inode, struct file *file) +static int rtrack_exclusive_open(struct file *file) { return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0; } -static int rtrack_exclusive_release(struct inode *inode, struct file *file) +static int rtrack_exclusive_release(struct file *file) { clear_bit(0, &rtrack_unit.in_use); return 0; } -static const struct file_operations rtrack_fops = { +static const struct v4l2_file_operations rtrack_fops = { .owner = THIS_MODULE, .open = rtrack_exclusive_open, .release = rtrack_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index d7848957323..5604e881e96 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -338,26 +338,22 @@ static int vidioc_s_ctrl (struct file *file, void *priv, static struct az_device aztech_unit; -static int aztech_exclusive_open(struct inode *inode, struct file *file) +static int aztech_exclusive_open(struct file *file) { return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0; } -static int aztech_exclusive_release(struct inode *inode, struct file *file) +static int aztech_exclusive_release(struct file *file) { clear_bit(0, &aztech_unit.in_use); return 0; } -static const struct file_operations aztech_fops = { +static const struct v4l2_file_operations aztech_fops = { .owner = THIS_MODULE, .open = aztech_exclusive_open, .release = aztech_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops aztech_ioctl_ops = { diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index bfd37f38b9a..cb3075ac104 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -529,7 +529,7 @@ static int vidioc_s_audio(struct file *file, void *priv, } static int -cadet_open(struct inode *inode, struct file *file) +cadet_open(struct file *file) { users++; if (1 == users) init_waitqueue_head(&read_queue); @@ -537,7 +537,7 @@ cadet_open(struct inode *inode, struct file *file) } static int -cadet_release(struct inode *inode, struct file *file) +cadet_release(struct file *file) { users--; if (0 == users){ @@ -557,17 +557,13 @@ cadet_poll(struct file *file, struct poll_table_struct *wait) } -static const struct file_operations cadet_fops = { +static const struct v4l2_file_operations cadet_fops = { .owner = THIS_MODULE, .open = cadet_open, .release = cadet_release, .read = cadet_read, .ioctl = video_ioctl2, .poll = cadet_poll, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops cadet_ioctl_ops = { diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index e15bee6d7cf..0c96bf8525b 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -358,26 +358,22 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); static int mx = 1; -static int gemtek_pci_exclusive_open(struct inode *inode, struct file *file) +static int gemtek_pci_exclusive_open(struct file *file) { return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int gemtek_pci_exclusive_release(struct inode *inode, struct file *file) +static int gemtek_pci_exclusive_release(struct file *file) { clear_bit(0, &in_use); return 0; } -static const struct file_operations gemtek_pci_fops = { +static const struct v4l2_file_operations gemtek_pci_fops = { .owner = THIS_MODULE, .open = gemtek_pci_exclusive_open, .release = gemtek_pci_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index e13118da307..2b68be773f1 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -394,26 +394,22 @@ static struct v4l2_queryctrl radio_qctrl[] = { } }; -static int gemtek_exclusive_open(struct inode *inode, struct file *file) +static int gemtek_exclusive_open(struct file *file) { return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int gemtek_exclusive_release(struct inode *inode, struct file *file) +static int gemtek_exclusive_release(struct file *file) { clear_bit(0, &in_use); return 0; } -static const struct file_operations gemtek_fops = { +static const struct v4l2_file_operations gemtek_fops = { .owner = THIS_MODULE, .open = gemtek_exclusive_open, .release = gemtek_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek }; static int vidioc_querycap(struct file *file, void *priv, diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 4bf4d007bcf..ba3a13a9001 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -79,12 +79,12 @@ static unsigned long in_use; static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static int maestro_exclusive_open(struct inode *inode, struct file *file) +static int maestro_exclusive_open(struct file *file) { return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int maestro_exclusive_release(struct inode *inode, struct file *file) +static int maestro_exclusive_release(struct file *file) { clear_bit(0, &in_use); return 0; @@ -110,15 +110,11 @@ static struct pci_driver maestro_r_driver = { .remove = __devexit_p(maestro_remove), }; -static const struct file_operations maestro_fops = { +static const struct v4l2_file_operations maestro_fops = { .owner = THIS_MODULE, .open = maestro_exclusive_open, .release = maestro_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; struct radio_device { diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index c777a17b00b..c5dc00aa9c9 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -100,26 +100,22 @@ static unsigned long in_use; #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) -static int maxiradio_exclusive_open(struct inode *inode, struct file *file) +static int maxiradio_exclusive_open(struct file *file) { return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int maxiradio_exclusive_release(struct inode *inode, struct file *file) +static int maxiradio_exclusive_release(struct file *file) { clear_bit(0, &in_use); return 0; } -static const struct file_operations maxiradio_fops = { +static const struct v4l2_file_operations maxiradio_fops = { .owner = THIS_MODULE, .open = maxiradio_exclusive_open, .release = maxiradio_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct radio_device diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index e730eddb2bb..0747dc8862b 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -127,8 +127,8 @@ static struct v4l2_queryctrl radio_qctrl[] = { static int usb_amradio_probe(struct usb_interface *intf, const struct usb_device_id *id); static void usb_amradio_disconnect(struct usb_interface *intf); -static int usb_amradio_open(struct inode *inode, struct file *file); -static int usb_amradio_close(struct inode *inode, struct file *file); +static int usb_amradio_open(struct file *file); +static int usb_amradio_close(struct file *file); static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message); static int usb_amradio_resume(struct usb_interface *intf); @@ -500,7 +500,7 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) } /* open device - amradio_start() and amradio_setfreq() */ -static int usb_amradio_open(struct inode *inode, struct file *file) +static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); @@ -525,7 +525,7 @@ static int usb_amradio_open(struct inode *inode, struct file *file) } /*close device */ -static int usb_amradio_close(struct inode *inode, struct file *file) +static int usb_amradio_close(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); int retval; @@ -572,15 +572,11 @@ static int usb_amradio_resume(struct usb_interface *intf) } /* File system interface */ -static const struct file_operations usb_amradio_fops = { +static const struct v4l2_file_operations usb_amradio_fops = { .owner = THIS_MODULE, .open = usb_amradio_open, .release = usb_amradio_close, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 7704f243b6f..2587227214b 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -280,26 +280,22 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct rt_device rtrack2_unit; -static int rtrack2_exclusive_open(struct inode *inode, struct file *file) +static int rtrack2_exclusive_open(struct file *file) { return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0; } -static int rtrack2_exclusive_release(struct inode *inode, struct file *file) +static int rtrack2_exclusive_release(struct file *file) { clear_bit(0, &rtrack2_unit.in_use); return 0; } -static const struct file_operations rtrack2_fops = { +static const struct v4l2_file_operations rtrack2_fops = { .owner = THIS_MODULE, .open = rtrack2_exclusive_open, .release = rtrack2_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 834d43651c7..d358e48c242 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -280,26 +280,22 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct fmi_device fmi_unit; -static int fmi_exclusive_open(struct inode *inode, struct file *file) +static int fmi_exclusive_open(struct file *file) { return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0; } -static int fmi_exclusive_release(struct inode *inode, struct file *file) +static int fmi_exclusive_release(struct file *file) { clear_bit(0, &fmi_unit.in_use); return 0; } -static const struct file_operations fmi_fops = { +static const struct v4l2_file_operations fmi_fops = { .owner = THIS_MODULE, .open = fmi_exclusive_open, .release = fmi_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops fmi_ioctl_ops = { diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index b1f47c322e0..92f17a347fa 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -396,26 +396,22 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct fmr2_device fmr2_unit; -static int fmr2_exclusive_open(struct inode *inode, struct file *file) +static int fmr2_exclusive_open(struct file *file) { return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0; } -static int fmr2_exclusive_release(struct inode *inode, struct file *file) +static int fmr2_exclusive_release(struct file *file) { clear_bit(0, &fmr2_unit.in_use); return 0; } -static const struct file_operations fmr2_fops = { +static const struct v4l2_file_operations fmr2_fops = { .owner = THIS_MODULE, .open = fmr2_exclusive_open, .release = fmr2_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 3e1830293de..67cbce82cb9 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -96,6 +96,8 @@ * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com> * - add support for KWorld USB FM Radio FM700 * - blacklisted KWorld radio in hid-core.c and hid-ids.h + * 2008-12-03 Mark Lord <mlord@pobox.com> + * - add support for DealExtreme USB Radio * * ToDo: * - add firmware download/update support @@ -138,6 +140,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, + /* DealExtreme USB Radio */ + { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; @@ -1075,7 +1079,7 @@ static unsigned int si470x_fops_poll(struct file *file, /* * si470x_fops_open - file open */ -static int si470x_fops_open(struct inode *inode, struct file *file) +static int si470x_fops_open(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval; @@ -1105,7 +1109,7 @@ done: /* * si470x_fops_release - file release */ -static int si470x_fops_release(struct inode *inode, struct file *file) +static int si470x_fops_release(struct file *file) { struct si470x_device *radio = video_drvdata(file); int retval = 0; @@ -1147,15 +1151,11 @@ done: /* * si470x_fops - file operations interface */ -static const struct file_operations si470x_fops = { +static const struct v4l2_file_operations si470x_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = si470x_fops_read, .poll = si470x_fops_poll, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .open = si470x_fops_open, .release = si470x_fops_release, }; diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c new file mode 100644 index 00000000000..4d35308fc1f --- /dev/null +++ b/drivers/media/radio/radio-tea5764.c @@ -0,0 +1,634 @@ +/* + * driver/media/radio/radio-tea5764.c + * + * Driver for TEA5764 radio chip for linux 2.6. + * This driver is for TEA5764 chip from NXP, used in EZX phones from Motorola. + * The I2C protocol is used for communicate with chip. + * + * Based in radio-tea5761.c Copyright (C) 2005 Nokia Corporation + * + * Copyright (c) 2008 Fabio Belavenuto <belavenuto@gmail.com> + * + * 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 + * + * History: + * 2008-12-06 Fabio Belavenuto <belavenuto@gmail.com> + * initial code + * + * TODO: + * add platform_data support for IRQs platform dependencies + * add RDS support + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> /* Initdata */ +#include <linux/videodev2.h> /* kernel radio structs */ +#include <linux/i2c.h> /* I2C */ +#include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> +#include <linux/version.h> /* for KERNEL_VERSION MACRO */ + +#define DRIVER_VERSION "v0.01" +#define RADIO_VERSION KERNEL_VERSION(0, 0, 1) + +#define DRIVER_AUTHOR "Fabio Belavenuto <belavenuto@gmail.com>" +#define DRIVER_DESC "A driver for the TEA5764 radio chip for EZX Phones." + +#define PINFO(format, ...)\ + printk(KERN_INFO KBUILD_MODNAME ": "\ + DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) +#define PWARN(format, ...)\ + printk(KERN_WARNING KBUILD_MODNAME ": "\ + DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) +# define PDEBUG(format, ...)\ + printk(KERN_DEBUG KBUILD_MODNAME ": "\ + DRIVER_VERSION ": " format "\n", ## __VA_ARGS__) + +/* Frequency limits in MHz -- these are European values. For Japanese +devices, that would be 76000 and 91000. */ +#define FREQ_MIN 87500 +#define FREQ_MAX 108000 +#define FREQ_MUL 16 + +/* TEA5764 registers */ +#define TEA5764_MANID 0x002b +#define TEA5764_CHIPID 0x5764 + +#define TEA5764_INTREG_BLMSK 0x0001 +#define TEA5764_INTREG_FRRMSK 0x0002 +#define TEA5764_INTREG_LEVMSK 0x0008 +#define TEA5764_INTREG_IFMSK 0x0010 +#define TEA5764_INTREG_BLMFLAG 0x0100 +#define TEA5764_INTREG_FRRFLAG 0x0200 +#define TEA5764_INTREG_LEVFLAG 0x0800 +#define TEA5764_INTREG_IFFLAG 0x1000 + +#define TEA5764_FRQSET_SUD 0x8000 +#define TEA5764_FRQSET_SM 0x4000 + +#define TEA5764_TNCTRL_PUPD1 0x8000 +#define TEA5764_TNCTRL_PUPD0 0x4000 +#define TEA5764_TNCTRL_BLIM 0x2000 +#define TEA5764_TNCTRL_SWPM 0x1000 +#define TEA5764_TNCTRL_IFCTC 0x0800 +#define TEA5764_TNCTRL_AFM 0x0400 +#define TEA5764_TNCTRL_SMUTE 0x0200 +#define TEA5764_TNCTRL_SNC 0x0100 +#define TEA5764_TNCTRL_MU 0x0080 +#define TEA5764_TNCTRL_SSL1 0x0040 +#define TEA5764_TNCTRL_SSL0 0x0020 +#define TEA5764_TNCTRL_HLSI 0x0010 +#define TEA5764_TNCTRL_MST 0x0008 +#define TEA5764_TNCTRL_SWP 0x0004 +#define TEA5764_TNCTRL_DTC 0x0002 +#define TEA5764_TNCTRL_AHLSI 0x0001 + +#define TEA5764_TUNCHK_LEVEL(x) (((x) & 0x00F0) >> 4) +#define TEA5764_TUNCHK_IFCNT(x) (((x) & 0xFE00) >> 9) +#define TEA5764_TUNCHK_TUNTO 0x0100 +#define TEA5764_TUNCHK_LD 0x0008 +#define TEA5764_TUNCHK_STEREO 0x0004 + +#define TEA5764_TESTREG_TRIGFR 0x0800 + +struct tea5764_regs { + u16 intreg; /* INTFLAG & INTMSK */ + u16 frqset; /* FRQSETMSB & FRQSETLSB */ + u16 tnctrl; /* TNCTRL1 & TNCTRL2 */ + u16 frqchk; /* FRQCHKMSB & FRQCHKLSB */ + u16 tunchk; /* IFCHK & LEVCHK */ + u16 testreg; /* TESTBITS & TESTMODE */ + u16 rdsstat; /* RDSSTAT1 & RDSSTAT2 */ + u16 rdslb; /* RDSLBMSB & RDSLBLSB */ + u16 rdspb; /* RDSPBMSB & RDSPBLSB */ + u16 rdsbc; /* RDSBBC & RDSGBC */ + u16 rdsctrl; /* RDSCTRL1 & RDSCTRL2 */ + u16 rdsbbl; /* PAUSEDET & RDSBBL */ + u16 manid; /* MANID1 & MANID2 */ + u16 chipid; /* CHIPID1 & CHIPID2 */ +} __attribute__ ((packed)); + +struct tea5764_write_regs { + u8 intreg; /* INTMSK */ + u16 frqset; /* FRQSETMSB & FRQSETLSB */ + u16 tnctrl; /* TNCTRL1 & TNCTRL2 */ + u16 testreg; /* TESTBITS & TESTMODE */ + u16 rdsctrl; /* RDSCTRL1 & RDSCTRL2 */ + u16 rdsbbl; /* PAUSEDET & RDSBBL */ +} __attribute__ ((packed)); + +#ifndef RADIO_TEA5764_XTAL +#define RADIO_TEA5764_XTAL 1 +#endif + +static int radio_nr = -1; +static int use_xtal = RADIO_TEA5764_XTAL; + +struct tea5764_device { + struct i2c_client *i2c_client; + struct video_device *videodev; + struct tea5764_regs regs; + struct mutex mutex; + int users; +}; + +/* I2C code related */ +int tea5764_i2c_read(struct tea5764_device *radio) +{ + int i; + u16 *p = (u16 *) &radio->regs; + + struct i2c_msg msgs[1] = { + { radio->i2c_client->addr, I2C_M_RD, sizeof(radio->regs), + (void *)&radio->regs }, + }; + if (i2c_transfer(radio->i2c_client->adapter, msgs, 1) != 1) + return -EIO; + for (i = 0; i < sizeof(struct tea5764_regs) / sizeof(u16); i++) + p[i] = __be16_to_cpu(p[i]); + + return 0; +} + +int tea5764_i2c_write(struct tea5764_device *radio) +{ + struct tea5764_write_regs wr; + struct tea5764_regs *r = &radio->regs; + struct i2c_msg msgs[1] = { + { radio->i2c_client->addr, 0, sizeof(wr), (void *) &wr }, + }; + wr.intreg = r->intreg & 0xff; + wr.frqset = __cpu_to_be16(r->frqset); + wr.tnctrl = __cpu_to_be16(r->tnctrl); + wr.testreg = __cpu_to_be16(r->testreg); + wr.rdsctrl = __cpu_to_be16(r->rdsctrl); + wr.rdsbbl = __cpu_to_be16(r->rdsbbl); + if (i2c_transfer(radio->i2c_client->adapter, msgs, 1) != 1) + return -EIO; + return 0; +} + +/* V4L2 code related */ +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + } +}; + +static void tea5764_power_up(struct tea5764_device *radio) +{ + struct tea5764_regs *r = &radio->regs; + + if (!(r->tnctrl & TEA5764_TNCTRL_PUPD0)) { + r->tnctrl &= ~(TEA5764_TNCTRL_AFM | TEA5764_TNCTRL_MU | + TEA5764_TNCTRL_HLSI); + if (!use_xtal) + r->testreg |= TEA5764_TESTREG_TRIGFR; + else + r->testreg &= ~TEA5764_TESTREG_TRIGFR; + + r->tnctrl |= TEA5764_TNCTRL_PUPD0; + tea5764_i2c_write(radio); + } +} + +static void tea5764_power_down(struct tea5764_device *radio) +{ + struct tea5764_regs *r = &radio->regs; + + if (r->tnctrl & TEA5764_TNCTRL_PUPD0) { + r->tnctrl &= ~TEA5764_TNCTRL_PUPD0; + tea5764_i2c_write(radio); + } +} + +static void tea5764_set_freq(struct tea5764_device *radio, int freq) +{ + struct tea5764_regs *r = &radio->regs; + + /* formula: (freq [+ or -] 225000) / 8192 */ + if (r->tnctrl & TEA5764_TNCTRL_HLSI) + r->frqset = (freq + 225000) / 8192; + else + r->frqset = (freq - 225000) / 8192; +} + +static int tea5764_get_freq(struct tea5764_device *radio) +{ + struct tea5764_regs *r = &radio->regs; + + if (r->tnctrl & TEA5764_TNCTRL_HLSI) + return (r->frqchk * 8192) - 225000; + else + return (r->frqchk * 8192) + 225000; +} + +/* tune an frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ +static void tea5764_tune(struct tea5764_device *radio, int freq) +{ + tea5764_set_freq(radio, freq); + if (tea5764_i2c_write(radio)) + PWARN("Could not set frequency!"); +} + +static void tea5764_set_audout_mode(struct tea5764_device *radio, int audmode) +{ + struct tea5764_regs *r = &radio->regs; + int tnctrl = r->tnctrl; + + if (audmode == V4L2_TUNER_MODE_MONO) + r->tnctrl |= TEA5764_TNCTRL_MST; + else + r->tnctrl &= ~TEA5764_TNCTRL_MST; + if (tnctrl != r->tnctrl) + tea5764_i2c_write(radio); +} + +static int tea5764_get_audout_mode(struct tea5764_device *radio) +{ + struct tea5764_regs *r = &radio->regs; + + if (r->tnctrl & TEA5764_TNCTRL_MST) + return V4L2_TUNER_MODE_MONO; + else + return V4L2_TUNER_MODE_STEREO; +} + +static void tea5764_mute(struct tea5764_device *radio, int on) +{ + struct tea5764_regs *r = &radio->regs; + int tnctrl = r->tnctrl; + + if (on) + r->tnctrl |= TEA5764_TNCTRL_MU; + else + r->tnctrl &= ~TEA5764_TNCTRL_MU; + if (tnctrl != r->tnctrl) + tea5764_i2c_write(radio); +} + +static int tea5764_is_muted(struct tea5764_device *radio) +{ + return radio->regs.tnctrl & TEA5764_TNCTRL_MU; +} + +/* V4L2 vidioc */ +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *v) +{ + struct tea5764_device *radio = video_drvdata(file); + struct video_device *dev = radio->videodev; + + strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver)); + strlcpy(v->card, dev->name, sizeof(v->card)); + snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + return 0; +} + +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + struct tea5764_device *radio = video_drvdata(file); + struct tea5764_regs *r = &radio->regs; + + if (v->index > 0) + return -EINVAL; + + memset(v, 0, sizeof(v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + tea5764_i2c_read(radio); + v->rangelow = FREQ_MIN * FREQ_MUL; + v->rangehigh = FREQ_MAX * FREQ_MUL; + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; + if (r->tunchk & TEA5764_TUNCHK_STEREO) + v->rxsubchans = V4L2_TUNER_SUB_STEREO; + v->audmode = tea5764_get_audout_mode(radio); + v->signal = TEA5764_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf; + v->afc = TEA5764_TUNCHK_IFCNT(r->tunchk); + + return 0; +} + +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + struct tea5764_device *radio = video_drvdata(file); + + if (v->index > 0) + return -EINVAL; + + tea5764_set_audout_mode(radio, v->audmode); + return 0; +} + +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct tea5764_device *radio = video_drvdata(file); + + if (f->tuner != 0) + return -EINVAL; + if (f->frequency == 0) { + /* We special case this as a power down control. */ + tea5764_power_down(radio); + } + if (f->frequency < (FREQ_MIN * FREQ_MUL)) + return -EINVAL; + if (f->frequency > (FREQ_MAX * FREQ_MUL)) + return -EINVAL; + tea5764_power_up(radio); + tea5764_tune(radio, (f->frequency * 125) / 2); + return 0; +} + +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct tea5764_device *radio = video_drvdata(file); + struct tea5764_regs *r = &radio->regs; + + tea5764_i2c_read(radio); + memset(f, 0, sizeof(f)); + f->type = V4L2_TUNER_RADIO; + if (r->tnctrl & TEA5764_TNCTRL_PUPD0) + f->frequency = (tea5764_get_freq(radio) * 2) / 125; + else + f->frequency = 0; + + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); + return 0; + } + } + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct tea5764_device *radio = video_drvdata(file); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + tea5764_i2c_read(radio); + ctrl->value = tea5764_is_muted(radio) ? 1 : 0; + return 0; + } + return -EINVAL; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct tea5764_device *radio = video_drvdata(file); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + tea5764_mute(radio, ctrl->value); + return 0; + } + return -EINVAL; +} + +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + return 0; +} + +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index != 0) + return -EINVAL; + + return 0; +} + +static int tea5764_open(struct file *file) +{ + /* Currently we support only one device */ + int minor = video_devdata(file)->minor; + struct tea5764_device *radio = video_drvdata(file); + + if (radio->videodev->minor != minor) + return -ENODEV; + + mutex_lock(&radio->mutex); + /* Only exclusive access */ + if (radio->users) { + mutex_unlock(&radio->mutex); + return -EBUSY; + } + radio->users++; + mutex_unlock(&radio->mutex); + file->private_data = radio; + return 0; +} + +static int tea5764_close(struct file *file) +{ + struct tea5764_device *radio = video_drvdata(file); + + if (!radio) + return -ENODEV; + mutex_lock(&radio->mutex); + radio->users--; + mutex_unlock(&radio->mutex); + return 0; +} + +/* File system interface */ +static const struct v4l2_file_operations tea5764_fops = { + .owner = THIS_MODULE, + .open = tea5764_open, + .release = tea5764_close, + .ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, +}; + +/* V4L2 interface */ +static struct video_device tea5764_radio_template = { + .name = "TEA5764 FM-Radio", + .fops = &tea5764_fops, + .ioctl_ops = &tea5764_ioctl_ops, + .release = video_device_release, +}; + +/* I2C probe: check if the device exists and register with v4l if it is */ +static int __devinit tea5764_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tea5764_device *radio; + struct tea5764_regs *r; + int ret; + + PDEBUG("probe"); + radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); + if (!radio) + return -ENOMEM; + + mutex_init(&radio->mutex); + radio->i2c_client = client; + ret = tea5764_i2c_read(radio); + if (ret) + goto errfr; + r = &radio->regs; + PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid); + if (r->chipid != TEA5764_CHIPID || + (r->manid & 0x0fff) != TEA5764_MANID) { + PWARN("This chip is not a TEA5764!"); + ret = -EINVAL; + goto errfr; + } + + radio->videodev = video_device_alloc(); + if (!(radio->videodev)) { + ret = -ENOMEM; + goto errfr; + } + memcpy(radio->videodev, &tea5764_radio_template, + sizeof(tea5764_radio_template)); + + i2c_set_clientdata(client, radio); + video_set_drvdata(radio->videodev, radio); + + ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); + if (ret < 0) { + PWARN("Could not register video device!"); + goto errrel; + } + + /* initialize and power off the chip */ + tea5764_i2c_read(radio); + tea5764_set_audout_mode(radio, V4L2_TUNER_MODE_STEREO); + tea5764_mute(radio, 1); + tea5764_power_down(radio); + + PINFO("registered."); + return 0; +errrel: + video_device_release(radio->videodev); +errfr: + kfree(radio); + return ret; +} + +static int __devexit tea5764_i2c_remove(struct i2c_client *client) +{ + struct tea5764_device *radio = i2c_get_clientdata(client); + + PDEBUG("remove"); + if (radio) { + tea5764_power_down(radio); + video_unregister_device(radio->videodev); + kfree(radio); + } + return 0; +} + +/* I2C subsystem interface */ +static const struct i2c_device_id tea5764_id[] = { + { "radio-tea5764", 0 }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(i2c, tea5764_id); + +static struct i2c_driver tea5764_i2c_driver = { + .driver = { + .name = "radio-tea5764", + .owner = THIS_MODULE, + }, + .probe = tea5764_i2c_probe, + .remove = __devexit_p(tea5764_i2c_remove), + .id_table = tea5764_id, +}; + +/* init the driver */ +static int __init tea5764_init(void) +{ + int ret = i2c_add_driver(&tea5764_i2c_driver); + + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": " + DRIVER_DESC "\n"); + return ret; +} + +/* cleanup the driver */ +static void __exit tea5764_exit(void) +{ + i2c_del_driver(&tea5764_i2c_driver); +} + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_param(use_xtal, int, 1); +MODULE_PARM_DESC(use_xtal, "Chip have a xtal connected in board"); +module_param(radio_nr, int, 0); +MODULE_PARM_DESC(radio_nr, "video4linux device number to use"); + +module_init(tea5764_init); +module_exit(tea5764_exit); diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 0abb186a947..0798d71abd0 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -352,26 +352,22 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct tt_device terratec_unit; -static int terratec_exclusive_open(struct inode *inode, struct file *file) +static int terratec_exclusive_open(struct file *file) { return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0; } -static int terratec_exclusive_release(struct inode *inode, struct file *file) +static int terratec_exclusive_release(struct file *file) { clear_bit(0, &terratec_unit.in_use); return 0; } -static const struct file_operations terratec_fops = { +static const struct v4l2_file_operations terratec_fops = { .owner = THIS_MODULE, .open = terratec_exclusive_open, .release = terratec_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops terratec_ioctl_ops = { diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index e7b111fcd10..bdf9cb6a75f 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -337,26 +337,22 @@ static int vidioc_s_audio(struct file *file, void *priv, return 0; } -static int trust_exclusive_open(struct inode *inode, struct file *file) +static int trust_exclusive_open(struct file *file) { return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int trust_exclusive_release(struct inode *inode, struct file *file) +static int trust_exclusive_release(struct file *file) { clear_bit(0, &in_use); return 0; } -static const struct file_operations trust_fops = { +static const struct v4l2_file_operations trust_fops = { .owner = THIS_MODULE, .open = trust_exclusive_open, .release = trust_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops trust_ioctl_ops = { diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 952ec35a841..5c3b319dab3 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -330,26 +330,22 @@ static struct typhoon_device typhoon_unit = .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, }; -static int typhoon_exclusive_open(struct inode *inode, struct file *file) +static int typhoon_exclusive_open(struct file *file) { return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0; } -static int typhoon_exclusive_release(struct inode *inode, struct file *file) +static int typhoon_exclusive_release(struct file *file) { clear_bit(0, &typhoon_unit.in_use); return 0; } -static const struct file_operations typhoon_fops = { +static const struct v4l2_file_operations typhoon_fops = { .owner = THIS_MODULE, .open = typhoon_exclusive_open, .release = typhoon_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 15b10bad679..d2ac17eeec5 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -401,27 +401,23 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct zol_device zoltrix_unit; -static int zoltrix_exclusive_open(struct inode *inode, struct file *file) +static int zoltrix_exclusive_open(struct file *file) { return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; } -static int zoltrix_exclusive_release(struct inode *inode, struct file *file) +static int zoltrix_exclusive_release(struct file *file) { clear_bit(0, &zoltrix_unit.in_use); return 0; } -static const struct file_operations zoltrix_fops = +static const struct v4l2_file_operations zoltrix_fops = { .owner = THIS_MODULE, .open = zoltrix_exclusive_open, .release = zoltrix_exclusive_release, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 1611c33b1ae..72f6d03d2d8 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -12,7 +12,10 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-compat-ioctl32.o v4l2-int-device.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o +ifeq ($(CONFIG_COMPAT),y) + obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o +endif obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 2ba6abd92b6..d137bac8451 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -396,7 +396,7 @@ out_up: return ret; } -static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct ar_device *ar = video_get_drvdata(dev); @@ -539,7 +539,7 @@ static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, +static long ar_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, ar_do_ioctl); @@ -744,27 +744,23 @@ void ar_release(struct video_device *vfd) ****************************************************************************/ static struct ar_device ardev; -static int ar_exclusive_open(struct inode *inode, struct file *file) +static int ar_exclusive_open(struct file *file) { return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0; } -static int ar_exclusive_release(struct inode *inode, struct file *file) +static int ar_exclusive_release(struct file *file) { clear_bit(0, &ardev.in_use); return 0; } -static const struct file_operations ar_fops = { +static const struct v4l2_file_operations ar_fops = { .owner = THIS_MODULE, .open = ar_exclusive_open, .release = ar_exclusive_release, .read = ar_read, .ioctl = ar_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device ar_template = { diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 9ec4cec2e52..c71f394fc0e 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -2039,7 +2039,7 @@ static int bttv_log_status(struct file *file, void *f) #ifdef CONFIG_VIDEO_ADV_DEBUG static int bttv_g_register(struct file *file, void *f, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; @@ -2047,18 +2047,19 @@ static int bttv_g_register(struct file *file, void *f, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; /* bt848 has a 12-bit register space */ reg->reg &= 0xfff; reg->val = btread(reg->reg); + reg->size = 1; return 0; } static int bttv_s_register(struct file *file, void *f, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; @@ -2066,7 +2067,7 @@ static int bttv_s_register(struct file *file, void *f, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; /* bt848 has a 12-bit register space */ @@ -3208,9 +3209,9 @@ err: return POLLERR; } -static int bttv_open(struct inode *inode, struct file *file) +static int bttv_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct bttv *btv = NULL; struct bttv_fh *fh; enum v4l2_buf_type type = 0; @@ -3291,7 +3292,7 @@ static int bttv_open(struct inode *inode, struct file *file) return 0; } -static int bttv_release(struct inode *inode, struct file *file) +static int bttv_release(struct file *file) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; @@ -3346,14 +3347,12 @@ bttv_mmap(struct file *file, struct vm_area_struct *vma) return videobuf_mmap_mapper(bttv_queue(fh),vma); } -static const struct file_operations bttv_fops = +static const struct v4l2_file_operations bttv_fops = { .owner = THIS_MODULE, .open = bttv_open, .release = bttv_release, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, .read = bttv_read, .mmap = bttv_mmap, .poll = bttv_poll, @@ -3422,9 +3421,9 @@ static struct video_device bttv_video_template = { /* ----------------------------------------------------------------------- */ /* radio interface */ -static int radio_open(struct inode *inode, struct file *file) +static int radio_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct bttv *btv = NULL; struct bttv_fh *fh; unsigned int i; @@ -3467,12 +3466,13 @@ static int radio_open(struct inode *inode, struct file *file) return 0; } -static int radio_release(struct inode *inode, struct file *file) +static int radio_release(struct file *file) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; struct rds_command cmd; + v4l2_prio_close(&btv->prio,&fh->prio); file->private_data = NULL; kfree(fh); @@ -3633,15 +3633,13 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) return cmd.result; } -static const struct file_operations radio_fops = +static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = radio_open, .read = radio_read, .release = radio_release, - .compat_ioctl = v4l_compat_ioctl32, .ioctl = video_ioctl2, - .llseek = no_llseek, .poll = radio_poll, }; diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 17f80d03f38..10dbd4a11b3 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -706,7 +706,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l * Video4linux interfacing */ -static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam=(struct qcam_device *)dev; @@ -863,7 +863,7 @@ static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int qcam_ioctl(struct inode *inode, struct file *file, +static long qcam_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, qcam_do_ioctl); @@ -893,7 +893,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct inode *inode, struct file *file) +static int qcam_exclusive_open(struct file *file) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam = (struct qcam_device *)dev; @@ -901,7 +901,7 @@ static int qcam_exclusive_open(struct inode *inode, struct file *file) return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; } -static int qcam_exclusive_release(struct inode *inode, struct file *file) +static int qcam_exclusive_release(struct file *file) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam = (struct qcam_device *)dev; @@ -910,16 +910,12 @@ static int qcam_exclusive_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations qcam_fops = { +static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = qcam_exclusive_open, .release = qcam_exclusive_release, .ioctl = qcam_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = qcam_read, - .llseek = no_llseek, }; static struct video_device qcam_template= { diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 21c71eb085d..85cf1778827 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -500,7 +500,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le * Video4linux interfacing */ -static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam=(struct qcam_device *)dev; @@ -665,7 +665,7 @@ static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int qcam_ioctl(struct inode *inode, struct file *file, +static long qcam_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, qcam_do_ioctl); @@ -687,7 +687,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct inode *inode, struct file *file) +static int qcam_exclusive_open(struct file *file) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam = (struct qcam_device *)dev; @@ -695,7 +695,7 @@ static int qcam_exclusive_open(struct inode *inode, struct file *file) return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; } -static int qcam_exclusive_release(struct inode *inode, struct file *file) +static int qcam_exclusive_release(struct file *file) { struct video_device *dev = video_devdata(file); struct qcam_device *qcam = (struct qcam_device *)dev; @@ -705,16 +705,12 @@ static int qcam_exclusive_release(struct inode *inode, struct file *file) } /* video device template */ -static const struct file_operations qcam_fops = { +static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = qcam_exclusive_open, .release = qcam_exclusive_release, .ioctl = qcam_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = qcam_read, - .llseek = no_llseek, }; static struct video_device qcam_template= diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 1740b9ebdce..34a39d2e470 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -859,7 +859,7 @@ static int __cafe_cam_reset(struct cafe_camera *cam) */ static int cafe_cam_init(struct cafe_camera *cam) { - struct v4l2_chip_ident chip = { V4L2_CHIP_MATCH_I2C_ADDR, 0, 0, 0 }; + struct v4l2_dbg_chip_ident chip; int ret; mutex_lock(&cam->s_mutex); @@ -869,8 +869,9 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = __cafe_cam_reset(cam); if (ret) goto out; - chip.match_chip = cam->sensor->addr; - ret = __cafe_cam_cmd(cam, VIDIOC_G_CHIP_IDENT, &chip); + chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; + chip.match.addr = cam->sensor->addr; + ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip); if (ret) goto out; cam->sensor_type = chip.ident; @@ -1472,11 +1473,11 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma) -static int cafe_v4l_open(struct inode *inode, struct file *filp) +static int cafe_v4l_open(struct file *filp) { struct cafe_camera *cam; - cam = cafe_find_dev(iminor(inode)); + cam = cafe_find_dev(video_devdata(filp)->minor); if (cam == NULL) return -ENODEV; filp->private_data = cam; @@ -1494,7 +1495,7 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) } -static int cafe_v4l_release(struct inode *inode, struct file *filp) +static int cafe_v4l_release(struct file *filp) { struct cafe_camera *cam = filp->private_data; @@ -1759,7 +1760,7 @@ static void cafe_v4l_dev_release(struct video_device *vd) * clone it for specific real devices. */ -static const struct file_operations cafe_v4l_fops = { +static const struct v4l2_file_operations cafe_v4l_fops = { .owner = THIS_MODULE, .open = cafe_v4l_open, .release = cafe_v4l_release, @@ -1767,7 +1768,6 @@ static const struct file_operations cafe_v4l_fops = { .poll = cafe_v4l_poll, .mmap = cafe_v4l_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 028a400d245..c3b0c8c63c7 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3148,7 +3148,7 @@ static void put_cam(struct cpia_camera_ops* ops) } /* ------------------------- V4L interface --------------------- */ -static int cpia_open(struct inode *inode, struct file *file) +static int cpia_open(struct file *file) { struct video_device *dev = video_devdata(file); struct cam_data *cam = video_get_drvdata(dev); @@ -3225,7 +3225,7 @@ static int cpia_open(struct inode *inode, struct file *file) return err; } -static int cpia_close(struct inode *inode, struct file *file) +static int cpia_close(struct file *file) { struct video_device *dev = file->private_data; struct cam_data *cam = video_get_drvdata(dev); @@ -3333,7 +3333,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf, return cam->decompressed_frame.count; } -static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = file->private_data; struct cam_data *cam = video_get_drvdata(dev); @@ -3720,7 +3720,7 @@ static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg) return retval; } -static int cpia_ioctl(struct inode *inode, struct file *file, +static long cpia_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, cpia_do_ioctl); @@ -3780,17 +3780,13 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static const struct file_operations cpia_fops = { +static const struct v4l2_file_operations cpia_fops = { .owner = THIS_MODULE, .open = cpia_open, .release = cpia_close, .read = cpia_read, .mmap = cpia_mmap, .ioctl = cpia_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device cpia_template = { diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 3c2d7eac119..9c25894fdd8 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -239,7 +239,7 @@ static struct v4l2_queryctrl controls[] = { * cpia2_open * *****************************************************************************/ -static int cpia2_open(struct inode *inode, struct file *file) +static int cpia2_open(struct file *file) { struct camera_data *cam = video_drvdata(file); int retval = 0; @@ -302,7 +302,7 @@ err_return: * cpia2_close * *****************************************************************************/ -static int cpia2_close(struct inode *inode, struct file *file) +static int cpia2_close(struct file *file) { struct video_device *dev = video_devdata(file); struct camera_data *cam = video_get_drvdata(dev); @@ -1572,10 +1572,10 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) * cpia2_ioctl * *****************************************************************************/ -static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct camera_data *cam = video_drvdata(file); - int retval = 0; + long retval = 0; if (!cam) return -ENOTTY; @@ -1841,7 +1841,7 @@ static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) return retval; } -static int cpia2_ioctl(struct inode *inode, struct file *file, +static long cpia2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, cpia2_do_ioctl); @@ -1912,17 +1912,13 @@ static void reset_camera_struct_v4l(struct camera_data *cam) /*** * The v4l video device structure initialized for this device ***/ -static const struct file_operations fops_template = { +static const struct v4l2_file_operations fops_template = { .owner = THIS_MODULE, .open = cpia2_open, .release = cpia2_close, .read = cpia2_v4l_read, .poll = cpia2_v4l_poll, .ioctl = cpia2_ioctl, - .llseek = no_llseek, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .mmap = cpia2_mmap, }; diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 70fcd0d5de1..14bebf8a116 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -95,25 +95,24 @@ static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + reg->size = 1; reg->val = cs5345_read(sd, reg->reg & 0x1f); return 0; } -static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -122,7 +121,7 @@ static int cs5345_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) } #endif -static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index cb65d519cf7..7292a6316e6 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -102,7 +102,7 @@ static int cs53l32a_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 425271a2951..055f6e004b2 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -552,7 +552,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end) } } -int cx18_v4l2_close(struct inode *inode, struct file *filp) +int cx18_v4l2_close(struct file *filp) { struct cx18_open_id *id = filp->private_data; struct cx18 *cx = id->cx; @@ -650,12 +650,12 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) return 0; } -int cx18_v4l2_open(struct inode *inode, struct file *filp) +int cx18_v4l2_open(struct file *filp) { int res, x, y = 0; struct cx18 *cx = NULL; struct cx18_stream *s = NULL; - int minor = iminor(inode); + int minor = video_devdata(filp)->minor; /* Find which card this open was on */ spin_lock(&cx18_cards_lock); diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h index 46da0282fc7..92e2d5dab93 100644 --- a/drivers/media/video/cx18/cx18-fileops.h +++ b/drivers/media/video/cx18/cx18-fileops.h @@ -22,12 +22,12 @@ */ /* Testing/Debugging */ -int cx18_v4l2_open(struct inode *inode, struct file *filp); +int cx18_v4l2_open(struct file *filp); ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, loff_t *pos); ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos); -int cx18_v4l2_close(struct inode *inode, struct file *filp); +int cx18_v4l2_close(struct file *filp); unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait); int cx18_start_capture(struct cx18_open_id *id); void cx18_stop_capture(struct cx18_open_id *id, int gop_end); diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 8941f58bed7..83e1c633312 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -242,7 +242,7 @@ int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg) return retval; } } - if (cmd != VIDIOC_G_CHIP_IDENT) + if (cmd != VIDIOC_DBG_G_CHIP_IDENT) CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", addr, cmd); return -ENODEV; @@ -268,17 +268,6 @@ static int cx18_i2c_id_addr(struct cx18 *cx, u32 id) return retval; } -/* Find the i2c device name matching the DRIVERID */ -static const char *cx18_i2c_id_name(u32 id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) - if (hw_driverids[i] == id) - return hw_devicenames[i]; - return "unknown device"; -} - /* Find the i2c device name matching the CX18_HW_ flag */ static const char *cx18_i2c_hw_name(u32 hw) { @@ -326,21 +315,6 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) return cx18_call_i2c_client(cx, addr, cmd, arg); } -/* Calls i2c device based on I2C driver ID. */ -int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg) -{ - int addr; - - addr = cx18_i2c_id_addr(cx, id); - if (addr < 0) { - if (cmd != VIDIOC_G_CHIP_IDENT) - CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n", - id, cx18_i2c_id_name(id), cmd); - return addr; - } - return cx18_call_i2c_client(cx, addr, cmd, arg); -} - /* broadcast cmd for all I2C clients and for the gpio subsystem */ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) { diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h index 113c3f9a2cc..4869739013b 100644 --- a/drivers/media/video/cx18/cx18-i2c.h +++ b/drivers/media/video/cx18/cx18-i2c.h @@ -23,7 +23,6 @@ int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw); int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg); -int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg); int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg); void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg); int cx18_i2c_register(struct cx18 *cx, unsigned idx); diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index e6087486f88..7086aaba77d 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -254,30 +254,24 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, } static int cx18_g_chip_ident(struct file *file, void *fh, - struct v4l2_chip_ident *chip) + struct v4l2_dbg_chip_ident *chip) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - if (chip->match_type == V4L2_CHIP_MATCH_HOST) { - if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) - chip->ident = V4L2_IDENT_CX23418; + if (v4l2_chip_match_host(&chip->match)) { + chip->ident = V4L2_IDENT_CX23418; return 0; } - if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT, - chip); - if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) - return cx18_call_i2c_client(cx, chip->match_chip, - VIDIOC_G_CHIP_IDENT, chip); - return -EINVAL; + cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip); + return 0; } #ifdef CONFIG_VIDEO_ADV_DEBUG static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) { - struct v4l2_register *regs = arg; + struct v4l2_dbg_register *regs = arg; unsigned long flags; if (!capable(CAP_SYS_ADMIN)) @@ -286,6 +280,7 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) return -EINVAL; spin_lock_irqsave(&cx18_cards_lock, flags); + regs->size = 4; if (cmd == VIDIOC_DBG_G_REGISTER) regs->val = cx18_read_enc(cx, regs->reg); else @@ -295,31 +290,25 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) } static int cx18_g_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (v4l2_chip_match_host(®->match)) return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, - reg); - return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, - reg); + cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg); + return 0; } static int cx18_s_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (v4l2_chip_match_host(®->match)) return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, - reg); - return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, - reg); + cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg); + return 0; } #endif @@ -755,7 +744,7 @@ static int cx18_log_status(struct file *file, void *fh) return 0; } -static int cx18_default(struct file *file, void *fh, int cmd, void *arg) +static long cx18_default(struct file *file, void *fh, int cmd, void *arg) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; @@ -783,19 +772,19 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg) return 0; } -int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, +long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct video_device *vfd = video_devdata(filp); struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; struct cx18 *cx = id->cx; - int res; + long res; mutex_lock(&cx->serialize_lock); if (cx18_debug & CX18_DBGFLG_IOCTL) vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; - res = video_ioctl2(inode, filp, cmd, arg); + res = video_ioctl2(filp, cmd, arg); vfd->debug = 0; mutex_unlock(&cx->serialize_lock); return res; diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h index 08fe24e9510..e2ca0d15211 100644 --- a/drivers/media/video/cx18/cx18-ioctl.h +++ b/drivers/media/video/cx18/cx18-ioctl.h @@ -29,5 +29,5 @@ void cx18_set_funcs(struct video_device *vdev); int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); int cx18_s_input(struct file *file, void *fh, unsigned int inp); -int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, +long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 63c336c95ff..89c1ec94f33 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -37,13 +37,12 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C -static struct file_operations cx18_v4l2_enc_fops = { +static struct v4l2_file_operations cx18_v4l2_enc_fops = { .owner = THIS_MODULE, .read = cx18_v4l2_read, .open = cx18_v4l2_open, /* FIXME change to video_ioctl2 if serialization lock can be removed */ .ioctl = cx18_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .release = cx18_v4l2_close, .poll = cx18_v4l2_enc_poll, }; @@ -61,49 +60,41 @@ static struct { int num_offset; int dma; enum v4l2_buf_type buf_type; - struct file_operations *fops; } cx18_stream_info[] = { { /* CX18_ENC_STREAM_TYPE_MPG */ "encoder MPEG", VFL_TYPE_GRABBER, 0, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_TS */ "TS", VFL_TYPE_GRABBER, -1, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_YUV */ "encoder YUV", VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_VBI */ "encoder VBI", VFL_TYPE_VBI, 0, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_PCM */ "encoder PCM audio", VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_IDX */ "encoder IDX", VFL_TYPE_GRABBER, -1, PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - &cx18_v4l2_enc_fops }, { /* CX18_ENC_STREAM_TYPE_RAD */ "encoder radio", VFL_TYPE_RADIO, 0, PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE, - &cx18_v4l2_enc_fops }, }; @@ -184,7 +175,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) s->v4l2dev->num = num; s->v4l2dev->parent = &cx->dev->dev; - s->v4l2dev->fops = cx18_stream_info[type].fops; + s->v4l2dev->fops = &cx18_v4l2_enc_fops; s->v4l2dev->release = video_device_release; s->v4l2dev->tvnorms = V4L2_STD_ALL; cx18_set_funcs(s->v4l2dev); diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 798d2402435..8f1db57bd1d 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1027,12 +1027,13 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev) printk(KERN_ERR "%s() f/w load failed\n", __func__); return retval; } - dev->cx23417_mailbox = cx23885_find_mailbox(dev); - if (dev->cx23417_mailbox < 0) { + retval = cx23885_find_mailbox(dev); + if (retval < 0) { printk(KERN_ERR "%s() mailbox < 0, error\n", __func__); return -1; } + dev->cx23417_mailbox = retval; retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { printk(KERN_ERR @@ -1573,9 +1574,9 @@ static int vidioc_queryctrl(struct file *file, void *priv, return cx23885_queryctrl(dev, c); } -static int mpeg_open(struct inode *inode, struct file *file) +static int mpeg_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct cx23885_dev *h, *dev = NULL; struct list_head *list; struct cx23885_fh *fh; @@ -1617,7 +1618,7 @@ static int mpeg_open(struct inode *inode, struct file *file) return 0; } -static int mpeg_release(struct inode *inode, struct file *file) +static int mpeg_release(struct file *file) { struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; @@ -1694,15 +1695,13 @@ static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) return videobuf_mmap_mapper(&fh->mpegq, vma); } -static struct file_operations mpeg_fops = { +static struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, .open = mpeg_open, .release = mpeg_release, .read = mpeg_read, .poll = mpeg_poll, .mmap = mpeg_mmap, - .ioctl = video_ioctl2, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index c742a10be5c..2d81c4d0434 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -718,9 +718,9 @@ static int get_resource(struct cx23885_fh *fh) } } -static int video_open(struct inode *inode, struct file *file) +static int video_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct cx23885_dev *h, *dev = NULL; struct cx23885_fh *fh; struct list_head *list; @@ -834,7 +834,7 @@ static unsigned int video_poll(struct file *file, return 0; } -static int video_release(struct inode *inode, struct file *file) +static int video_release(struct file *file) { struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; @@ -1326,11 +1326,11 @@ static int vidioc_s_frequency(struct file *file, void *priv, #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); @@ -1339,11 +1339,11 @@ static int vidioc_g_register(struct file *file, void *fh, } static int vidioc_s_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); @@ -1422,7 +1422,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) /* ----------------------------------------------------------- */ /* exported stuff */ -static const struct file_operations video_fops = { +static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, .open = video_open, .release = video_release, @@ -1430,8 +1430,6 @@ static const struct file_operations video_fops = { .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1479,13 +1477,11 @@ static struct video_device cx23885_video_template = { .current_norm = V4L2_STD_NTSC_M, }; -static const struct file_operations radio_fops = { +static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = video_open, .release = video_release, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 2ad277189da..88f2fd32bfe 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1120,25 +1120,24 @@ static int cx25840_init(struct v4l2_subdev *sd, u32 val) } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + reg->size = 1; reg->val = cx25840_read(client, reg->reg & 0x0fff); return 0; } -static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1362,7 +1361,7 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val) return 0; } -static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e162a70748c..7f5b8bfd08a 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1049,16 +1049,16 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) /* FIXME: cx88_ioctl_hook not implemented */ -static int mpeg_open(struct inode *inode, struct file *file) +static int mpeg_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct cx8802_dev *dev = NULL; struct cx8802_fh *fh; struct cx8802_driver *drv = NULL; int err; lock_kernel(); - dev = cx8802_get_device(inode); + dev = cx8802_get_device(minor); dprintk( 1, "%s\n", __func__); @@ -1114,7 +1114,7 @@ static int mpeg_open(struct inode *inode, struct file *file) return 0; } -static int mpeg_release(struct inode *inode, struct file *file) +static int mpeg_release(struct file *file) { struct cx8802_fh *fh = file->private_data; struct cx8802_dev *dev = fh->dev; @@ -1132,7 +1132,7 @@ static int mpeg_release(struct inode *inode, struct file *file) kfree(fh); /* Make sure we release the hardware */ - dev = cx8802_get_device(inode); + dev = cx8802_get_device(video_devdata(file)->minor); if (dev == NULL) return -ENODEV; @@ -1178,7 +1178,7 @@ mpeg_mmap(struct file *file, struct vm_area_struct * vma) return videobuf_mmap_mapper(&fh->mpegq, vma); } -static const struct file_operations mpeg_fops = +static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, .open = mpeg_open, @@ -1187,7 +1187,6 @@ static const struct file_operations mpeg_fops = .poll = mpeg_poll, .mmap = mpeg_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a04fee235db..59164fc94f5 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -578,9 +578,8 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) #if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \ defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE) -struct cx8802_dev * cx8802_get_device(struct inode *inode) +struct cx8802_dev *cx8802_get_device(int minor) { - int minor = iminor(inode); struct cx8802_dev *dev; list_for_each_entry(dev, &cx8802_devlist, devlist) diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b96ce991d96..791e69d804f 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -757,9 +757,9 @@ static int get_ressource(struct cx8800_fh *fh) } } -static int video_open(struct inode *inode, struct file *file) +static int video_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct cx8800_dev *h,*dev = NULL; struct cx88_core *core; struct cx8800_fh *fh; @@ -904,7 +904,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) return 0; } -static int video_release(struct inode *inode, struct file *file) +static int video_release(struct file *file) { struct cx8800_fh *fh = file->private_data; struct cx8800_dev *dev = fh->dev; @@ -1447,25 +1447,26 @@ static int vidioc_s_frequency (struct file *file, void *priv, #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register (struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; /* cx2388x has a 24-bit register space */ - reg->val = cx_read(reg->reg&0xffffff); + reg->val = cx_read(reg->reg & 0xffffff); + reg->size = 4; return 0; } static int vidioc_s_register (struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; - cx_write(reg->reg&0xffffff, reg->val); + cx_write(reg->reg & 0xffffff, reg->val); return 0; } #endif @@ -1693,7 +1694,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) /* ----------------------------------------------------------- */ /* exported stuff */ -static const struct file_operations video_fops = +static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, .open = video_open, @@ -1702,8 +1703,6 @@ static const struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1752,14 +1751,12 @@ static struct video_device cx8800_video_template = { .current_norm = V4L2_STD_NTSC_M, }; -static const struct file_operations radio_fops = +static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = video_open, .release = video_release, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 20649b25f7b..eb9ce30dc5e 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -643,7 +643,7 @@ int cx88_audio_thread(void *data); int cx8802_register_driver(struct cx8802_driver *drv); int cx8802_unregister_driver(struct cx8802_driver *drv); -struct cx8802_dev * cx8802_get_device(struct inode *inode); +struct cx8802_dev *cx8802_get_device(int minor); struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 15c03f0e69a..94378ccb750 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -62,9 +62,9 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) dprintk("Stopping isoc\n"); for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { - usb_unlink_urb(dev->adev->urb[i]); - usb_free_urb(dev->adev->urb[i]); - dev->adev->urb[i] = NULL; + usb_unlink_urb(dev->adev.urb[i]); + usb_free_urb(dev->adev.urb[i]); + dev->adev.urb[i] = NULL; } return 0; @@ -81,8 +81,8 @@ static void em28xx_audio_isocirq(struct urb *urb) unsigned int stride; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; - if (dev->adev->capture_pcm_substream) { - substream = dev->adev->capture_pcm_substream; + if (dev->adev.capture_pcm_substream) { + substream = dev->adev.capture_pcm_substream; runtime = substream->runtime; stride = runtime->frame_bits >> 3; @@ -95,7 +95,7 @@ static void em28xx_audio_isocirq(struct urb *urb) if (!length) continue; - oldptr = dev->adev->hwptr_done_capture; + oldptr = dev->adev.hwptr_done_capture; if (oldptr + length >= runtime->buffer_size) { unsigned int cnt = runtime->buffer_size - oldptr; @@ -110,16 +110,16 @@ static void em28xx_audio_isocirq(struct urb *urb) snd_pcm_stream_lock(substream); - dev->adev->hwptr_done_capture += length; - if (dev->adev->hwptr_done_capture >= + dev->adev.hwptr_done_capture += length; + if (dev->adev.hwptr_done_capture >= runtime->buffer_size) - dev->adev->hwptr_done_capture -= + dev->adev.hwptr_done_capture -= runtime->buffer_size; - dev->adev->capture_transfer_done += length; - if (dev->adev->capture_transfer_done >= + dev->adev.capture_transfer_done += length; + if (dev->adev.capture_transfer_done >= runtime->period_size) { - dev->adev->capture_transfer_done -= + dev->adev.capture_transfer_done -= runtime->period_size; period_elapsed = 1; } @@ -131,7 +131,7 @@ static void em28xx_audio_isocirq(struct urb *urb) } urb->status = 0; - if (dev->adev->shutdown) + if (dev->adev.shutdown) return; status = usb_submit_urb(urb, GFP_ATOMIC); @@ -154,17 +154,17 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) struct urb *urb; int j, k; - dev->adev->transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); - if (!dev->adev->transfer_buffer[i]) + dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); + if (!dev->adev.transfer_buffer[i]) return -ENOMEM; - memset(dev->adev->transfer_buffer[i], 0x80, sb_size); + memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { em28xx_errdev("usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { - usb_free_urb(dev->adev->urb[j]); - kfree(dev->adev->transfer_buffer[j]); + usb_free_urb(dev->adev.urb[j]); + kfree(dev->adev.transfer_buffer[j]); } return -ENOMEM; } @@ -173,7 +173,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) urb->context = dev; urb->pipe = usb_rcvisocpipe(dev->udev, 0x83); urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = dev->adev->transfer_buffer[i]; + urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->interval = 1; urb->complete = em28xx_audio_isocirq; urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; @@ -185,11 +185,11 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) urb->iso_frame_desc[j].length = EM28XX_AUDIO_MAX_PACKET_SIZE; } - dev->adev->urb[i] = urb; + dev->adev.urb[i] = urb; } for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { - errCode = usb_submit_urb(dev->adev->urb[i], GFP_ATOMIC); + errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { em28xx_isoc_audio_deinit(dev); @@ -202,16 +202,16 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) { - dprintk("%s transfer\n", (dev->adev->capture_stream == STREAM_ON)? + dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ? "stop" : "start"); switch (cmd) { case EM28XX_CAPTURE_STREAM_EN: - if (dev->adev->capture_stream == STREAM_OFF && arg == 1) { - dev->adev->capture_stream = STREAM_ON; + if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { + dev->adev.capture_stream = STREAM_ON; em28xx_init_audio_isoc(dev); - } else if (dev->adev->capture_stream == STREAM_ON && arg == 0) { - dev->adev->capture_stream = STREAM_OFF; + } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { + dev->adev.capture_stream = STREAM_OFF; em28xx_isoc_audio_deinit(dev); } else { printk(KERN_ERR "An underrun very likely occurred. " @@ -289,17 +289,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) goto err; runtime->hw = snd_em28xx_hw_capture; - if (dev->alt == 0 && dev->adev->users == 0) { + if (dev->alt == 0 && dev->adev.users == 0) { int errCode; dev->alt = 7; errCode = usb_set_interface(dev->udev, 0, 7); dprintk("changing alternate number to 7\n"); } - dev->adev->users++; + dev->adev.users++; snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - dev->adev->capture_pcm_substream = substream; + dev->adev.capture_pcm_substream = substream; runtime->private_data = dev; return 0; @@ -311,7 +311,7 @@ err: static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) { struct em28xx *dev = snd_pcm_substream_chip(substream); - dev->adev->users--; + dev->adev.users--; dprintk("closing device\n"); @@ -320,10 +320,10 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) em28xx_audio_analog_set(dev); mutex_unlock(&dev->lock); - if (dev->adev->users == 0 && dev->adev->shutdown == 1) { - dprintk("audio users: %d\n", dev->adev->users); + if (dev->adev.users == 0 && dev->adev.shutdown == 1) { + dprintk("audio users: %d\n", dev->adev.users); dprintk("disabling audio stream!\n"); - dev->adev->shutdown = 0; + dev->adev.shutdown = 0; dprintk("released lock\n"); em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); } @@ -356,7 +356,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) dprintk("Stop capture, if needed\n"); - if (dev->adev->capture_stream == STREAM_ON) + if (dev->adev.capture_stream == STREAM_ON) em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); return 0; @@ -379,7 +379,7 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); return 0; case SNDRV_PCM_TRIGGER_STOP: - dev->adev->shutdown = 1; + dev->adev.shutdown = 1; return 0; default: return -EINVAL; @@ -393,7 +393,7 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream snd_pcm_uframes_t hwptr_done; dev = snd_pcm_substream_chip(substream); - hwptr_done = dev->adev->hwptr_done_capture; + hwptr_done = dev->adev.hwptr_done_capture; return hwptr_done; } @@ -420,7 +420,7 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = { static int em28xx_audio_init(struct em28xx *dev) { - struct em28xx_audio *adev; + struct em28xx_audio *adev = &dev->adev; struct snd_pcm *pcm; struct snd_card *card; static int devnr; @@ -438,16 +438,9 @@ static int em28xx_audio_init(struct em28xx *dev) printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " "Rechberger\n"); - adev = kzalloc(sizeof(*adev), GFP_KERNEL); - if (!adev) { - printk(KERN_ERR "em28xx-audio.c: out of memory\n"); - return -1; - } card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); - if (card == NULL) { - kfree(adev); + if (card == NULL) return -ENOMEM; - } spin_lock_init(&adev->slock); err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); @@ -471,7 +464,6 @@ static int em28xx_audio_init(struct em28xx *dev) } adev->sndcard = card; adev->udev = dev->udev; - dev->adev = adev; return 0; } @@ -488,10 +480,9 @@ static int em28xx_audio_fini(struct em28xx *dev) return 0; } - if (dev->adev) { - snd_card_free(dev->adev->sndcard); - kfree(dev->adev); - dev->adev = NULL; + if (dev->adev.sndcard) { + snd_card_free(dev->adev.sndcard); + dev->adev.sndcard = NULL; } return 0; diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index f8504518586..819cceaa6ef 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -1000,12 +1000,11 @@ void em28xx_wake_i2c(struct em28xx *dev) static LIST_HEAD(em28xx_devlist); static DEFINE_MUTEX(em28xx_devlist_mutex); -struct em28xx *em28xx_get_device(struct inode *inode, +struct em28xx *em28xx_get_device(int minor, enum v4l2_buf_type *fh_type, int *has_radio) { struct em28xx *h, *dev = NULL; - int minor = iminor(inode); *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; *has_radio = 0; diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index 65dcb91bdcc..24e39c56811 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h @@ -160,7 +160,7 @@ /* FIXME: Need to be populated with the other chip ID's */ enum em28xx_chip_id { - CHIP_ID_EM2820 = 18, + CHIP_ID_EM2820 = 18, /* Also used by em2710 */ CHIP_ID_EM2840 = 20, CHIP_ID_EM2750 = 33, CHIP_ID_EM2860 = 34, diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 53527536481..416b691c33c 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1154,7 +1154,7 @@ static int em28xx_reg_len(int reg) } static int vidioc_g_chip_ident(struct file *file, void *priv, - struct v4l2_chip_ident *chip) + struct v4l2_dbg_chip_ident *chip) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; @@ -1162,20 +1162,20 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip); + em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); return 0; } static int vidioc_g_register(struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; int ret; - switch (reg->match_type) { + switch (reg->match.type) { case V4L2_CHIP_MATCH_AC97: mutex_lock(&dev->lock); ret = em28xx_read_ac97(dev, reg->reg); @@ -1184,6 +1184,7 @@ static int vidioc_g_register(struct file *file, void *priv, return ret; reg->val = ret; + reg->size = 1; return 0; case V4L2_CHIP_MATCH_I2C_DRIVER: em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg); @@ -1192,12 +1193,13 @@ static int vidioc_g_register(struct file *file, void *priv, /* Not supported yet */ return -EINVAL; default: - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; } /* Match host */ - if (em28xx_reg_len(reg->reg) == 1) { + reg->size = em28xx_reg_len(reg->reg); + if (reg->size == 1) { mutex_lock(&dev->lock); ret = em28xx_read_reg(dev, reg->reg); mutex_unlock(&dev->lock); @@ -1207,7 +1209,7 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { - __le64 val = 0; + __le16 val = 0; mutex_lock(&dev->lock); ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); @@ -1215,21 +1217,21 @@ static int vidioc_g_register(struct file *file, void *priv, if (ret < 0) return ret; - reg->val = le64_to_cpu(val); + reg->val = le16_to_cpu(val); } return 0; } static int vidioc_s_register(struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - __le64 buf; + __le16 buf; int rc; - switch (reg->match_type) { + switch (reg->match.type) { case V4L2_CHIP_MATCH_AC97: mutex_lock(&dev->lock); rc = em28xx_write_ac97(dev, reg->reg, reg->val); @@ -1243,12 +1245,12 @@ static int vidioc_s_register(struct file *file, void *priv, /* Not supported yet */ return -EINVAL; default: - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; } /* Match host */ - buf = cpu_to_le64(reg->val); + buf = cpu_to_le16(reg->val); mutex_lock(&dev->lock); rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, @@ -1582,15 +1584,15 @@ static int radio_queryctrl(struct file *file, void *priv, * em28xx_v4l2_open() * inits the device and starts isoc transfer */ -static int em28xx_v4l2_open(struct inode *inode, struct file *filp) +static int em28xx_v4l2_open(struct file *filp) { - int minor = iminor(inode); + int minor = video_devdata(filp)->minor; int errCode = 0, radio; struct em28xx *dev; enum v4l2_buf_type fh_type; struct em28xx_fh *fh; - dev = em28xx_get_device(inode, &fh_type, &radio); + dev = em28xx_get_device(minor, &fh_type, &radio); if (NULL == dev) return -ENODEV; @@ -1686,7 +1688,7 @@ void em28xx_release_analog_resources(struct em28xx *dev) * stops streaming and deallocates all resources allocated by the v4l2 * calls and ioctls */ -static int em28xx_v4l2_close(struct inode *inode, struct file *filp) +static int em28xx_v4l2_close(struct file *filp) { struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; @@ -1826,7 +1828,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) return rc; } -static const struct file_operations em28xx_v4l_fops = { +static const struct v4l2_file_operations em28xx_v4l_fops = { .owner = THIS_MODULE, .open = em28xx_v4l2_open, .release = em28xx_v4l2_close, @@ -1834,8 +1836,6 @@ static const struct file_operations em28xx_v4l_fops = { .poll = em28xx_v4l2_poll, .mmap = em28xx_v4l2_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, - .compat_ioctl = v4l_compat_ioctl32, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1890,13 +1890,11 @@ static const struct video_device em28xx_video_template = { .current_norm = V4L2_STD_PAL, }; -static const struct file_operations radio_fops = { +static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = em28xx_v4l2_open, .release = em28xx_v4l2_close, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index b5eddc26388..6c6b94aa05b 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -473,7 +473,7 @@ struct em28xx { unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */ - struct em28xx_audio *adev; + struct em28xx_audio adev; /* states */ enum em28xx_dev_state state; @@ -583,7 +583,7 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); void em28xx_wake_i2c(struct em28xx *dev); void em28xx_remove_from_devlist(struct em28xx *dev); void em28xx_add_into_devlist(struct em28xx *dev); -struct em28xx *em28xx_get_device(struct inode *inode, +struct em28xx *em28xx_get_device(int minor, enum v4l2_buf_type *fh_type, int *has_radio); int em28xx_register_extension(struct em28xx_ops *dev); diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 83c07112c59..d1c1e457f0b 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -1206,7 +1206,7 @@ static void et61x251_release_resources(struct kref *kref) } -static int et61x251_open(struct inode* inode, struct file* filp) +static int et61x251_open(struct file *filp) { struct et61x251_device* cam; int err = 0; @@ -1291,7 +1291,7 @@ out: } -static int et61x251_release(struct inode* inode, struct file* filp) +static int et61x251_release(struct file *filp) { struct et61x251_device* cam; @@ -2392,8 +2392,8 @@ et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg) } -static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) +static long et61x251_ioctl_v4l2(struct file *filp, + unsigned int cmd, void __user *arg) { struct et61x251_device *cam = video_drvdata(filp); @@ -2487,11 +2487,11 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, } -static int et61x251_ioctl(struct inode* inode, struct file* filp, +static long et61x251_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct et61x251_device *cam = video_drvdata(filp); - int err = 0; + long err = 0; if (mutex_lock_interruptible(&cam->fileop_mutex)) return -ERESTARTSYS; @@ -2511,7 +2511,7 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, V4LDBG(3, "et61x251", cmd); - err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); + err = et61x251_ioctl_v4l2(filp, cmd, (void __user *)arg); mutex_unlock(&cam->fileop_mutex); @@ -2519,18 +2519,14 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp, } -static const struct file_operations et61x251_fops = { +static const struct v4l2_file_operations et61x251_fops = { .owner = THIS_MODULE, .open = et61x251_open, .release = et61x251_release, .ioctl = et61x251_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = et61x251_read, .poll = et61x251_poll, .mmap = et61x251_mmap, - .llseek = no_llseek, }; /*****************************************************************************/ diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8b9f3bde574..5e36b9a4ae3 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -875,7 +875,7 @@ static void gspca_release(struct video_device *vfd) kfree(gspca_dev); } -static int dev_open(struct inode *inode, struct file *file) +static int dev_open(struct file *file) { struct gspca_dev *gspca_dev; int ret; @@ -922,7 +922,7 @@ out: return ret; } -static int dev_close(struct inode *inode, struct file *file) +static int dev_close(struct file *file) { struct gspca_dev *gspca_dev = file->private_data; @@ -1802,17 +1802,13 @@ out: return ret; } -static struct file_operations dev_fops = { +static struct v4l2_file_operations dev_fops = { .owner = THIS_MODULE, .open = dev_open, .release = dev_close, .read = dev_read, .mmap = dev_mmap, - .unlocked_ioctl = __video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, + .unlocked_ioctl = video_ioctl2, .poll = dev_poll, }; diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 352f84d440f..79393d1772e 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c @@ -306,7 +306,7 @@ static int hexium_detach(struct saa7146_dev *dev) return 0; } -static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct hexium *hexium = (struct hexium *) dev->ext_priv; diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 8d3c1482e7e..074bec711fe 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c @@ -370,7 +370,7 @@ static int hexium_detach(struct saa7146_dev *dev) return 0; } -static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct hexium *hexium = (struct hexium *) dev->ext_priv; diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 08b76295175..e8e5921cdc3 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -902,18 +902,19 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) } if (hw & IVTV_HW_SAA711X) { - struct v4l2_chip_ident v = { V4L2_CHIP_MATCH_I2C_DRIVER, I2C_DRIVERID_SAA711X }; + struct v4l2_dbg_chip_ident v; /* determine the exact saa711x model */ itv->hw_flags &= ~IVTV_HW_SAA711X; + v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER; + strlcpy(v.match.name, "saa7115", sizeof(v.match.name)); ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v); if (v.ident == V4L2_IDENT_SAA7114) { itv->hw_flags |= IVTV_HW_SAA7114; /* VBI is not yet supported by the saa7114 driver. */ itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE); - } - else { + } else { itv->hw_flags |= IVTV_HW_SAA7115; } itv->vbi.raw_decoder_line_size = 1443; diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 5eb587592e9..d594bc29f07 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -831,7 +831,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) ivtv_release_stream(s); } -int ivtv_v4l2_close(struct inode *inode, struct file *filp) +int ivtv_v4l2_close(struct file *filp) { struct ivtv_open_id *id = filp->private_data; struct ivtv *itv = id->itv; @@ -978,7 +978,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) return 0; } -int ivtv_v4l2_open(struct inode *inode, struct file *filp) +int ivtv_v4l2_open(struct file *filp) { int res; struct ivtv *itv = NULL; diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h index df81e790147..049a2923965 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.h +++ b/drivers/media/video/ivtv/ivtv-fileops.h @@ -22,12 +22,12 @@ #define IVTV_FILEOPS_H /* Testing/Debugging */ -int ivtv_v4l2_open(struct inode *inode, struct file *filp); +int ivtv_v4l2_open(struct file *filp); ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count, loff_t * pos); ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count, loff_t * pos); -int ivtv_v4l2_close(struct inode *inode, struct file *filp); +int ivtv_v4l2_close(struct file *filp); unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait); unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait); int ivtv_start_capture(struct ivtv_open_id *id); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index cd990a4b81a..f6b3ef6e691 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -674,19 +674,19 @@ static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_f return ret; } -static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip) +static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - if (chip->match_type == V4L2_CHIP_MATCH_HOST) { - if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) + if (chip->match.type == V4L2_CHIP_MATCH_HOST) { + if (v4l2_chip_match_host(&chip->match)) chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; return 0; } - if (chip->match_type != V4L2_CHIP_MATCH_I2C_DRIVER && - chip->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; /* TODO: is this correct? */ return ivtv_call_all_err(itv, core, g_chip_ident, chip); @@ -695,7 +695,7 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident #ifdef CONFIG_VIDEO_ADV_DEBUG static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) { - struct v4l2_register *regs = arg; + struct v4l2_dbg_register *regs = arg; volatile u8 __iomem *reg_start; if (!capable(CAP_SYS_ADMIN)) @@ -710,6 +710,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) else return -EINVAL; + regs->size = 4; if (cmd == VIDIOC_DBG_G_REGISTER) regs->val = readl(regs->reg + reg_start); else @@ -717,11 +718,11 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) return 0; } -static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) +static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (v4l2_chip_match_host(®->match)) return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); /* TODO: subdev errors should not be ignored, this should become a subdev helper function. */ @@ -729,11 +730,11 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *re return 0; } -static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg) +static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (v4l2_chip_match_host(®->match)) return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); /* TODO: subdev errors should not be ignored, this should become a subdev helper function. */ @@ -1725,7 +1726,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) return 0; } -static int ivtv_default(struct file *file, void *fh, int cmd, void *arg) +static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; @@ -1827,7 +1828,7 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, if (ivtv_debug & IVTV_DBGFLG_IOCTL) vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; - ret = __video_ioctl2(filp, cmd, arg); + ret = video_ioctl2(filp, cmd, arg); vfd->debug = 0; return ret; } diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index f77d764707b..854a950af78 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -43,24 +43,22 @@ #include "ivtv-cards.h" #include "ivtv-streams.h" -static const struct file_operations ivtv_v4l2_enc_fops = { +static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { .owner = THIS_MODULE, .read = ivtv_v4l2_read, .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, .unlocked_ioctl = ivtv_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .release = ivtv_v4l2_close, .poll = ivtv_v4l2_enc_poll, }; -static const struct file_operations ivtv_v4l2_dec_fops = { +static const struct v4l2_file_operations ivtv_v4l2_dec_fops = { .owner = THIS_MODULE, .read = ivtv_v4l2_read, .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, .unlocked_ioctl = ivtv_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .release = ivtv_v4l2_close, .poll = ivtv_v4l2_dec_poll, }; @@ -78,7 +76,7 @@ static struct { int num_offset; int dma, pio; enum v4l2_buf_type buf_type; - const struct file_operations *fops; + const struct v4l2_file_operations *fops; } ivtv_stream_info[] = { { /* IVTV_ENC_STREAM_TYPE_MPG */ "encoder MPG", diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 07be14a9fe7..de397ef57b4 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -80,29 +80,28 @@ static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct m52790_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (reg->reg != 0) return -EINVAL; + reg->size = 1; reg->val = state->input | state->output; return 0; } -static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct m52790_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -115,7 +114,7 @@ static int m52790_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) } #endif -static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 6418f4a78f2..b76e33d5c86 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -841,7 +841,7 @@ again: /* video4linux integration */ /****************************************************************************/ -static int meye_open(struct inode *inode, struct file *file) +static int meye_open(struct file *file) { int i; @@ -863,7 +863,7 @@ static int meye_open(struct inode *inode, struct file *file) return 0; } -static int meye_release(struct inode *inode, struct file *file) +static int meye_release(struct file *file) { mchip_hic_stop(); mchip_dma_free(); @@ -1577,7 +1577,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) return 0; } -static int vidioc_default(struct file *file, void *fh, int cmd, void *arg) +static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) { switch (cmd) { case MEYEIOC_G_PARAMS: @@ -1684,17 +1684,13 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static const struct file_operations meye_fops = { +static const struct v4l2_file_operations meye_fops = { .owner = THIS_MODULE, .open = meye_open, .release = meye_release, .mmap = meye_mmap, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .poll = meye_poll, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops meye_ioctl_ops = { diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index a622dbb72ed..4d7a9185211 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -483,7 +483,7 @@ static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) } #ifdef CONFIG_VIDEO_ALLOW_V4L1 -static int msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct msp_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -733,7 +733,7 @@ static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) return 0; } -static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct msp_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 1a1a1245367..c1bf75ef274 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -343,14 +343,14 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd, } static int mt9m001_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; - if (id->match_chip != mt9m001->client->addr) + if (id->match.addr != mt9m001->client->addr) return -ENODEV; id->ident = mt9m001->model; @@ -361,16 +361,17 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m001_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9m001->client->addr) + if (reg->match.addr != mt9m001->client->addr) return -ENODEV; + reg->size = 2; reg->val = reg_read(icd, reg->reg); if (reg->val > 0xffff) @@ -380,14 +381,14 @@ static int mt9m001_get_register(struct soc_camera_device *icd, } static int mt9m001_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9m001->client->addr) + if (reg->match.addr != mt9m001->client->addr) return -ENODEV; if (reg_write(icd, reg->reg, reg->val) < 0) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index c89ea41fe25..5b8e20979cc 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -514,14 +514,14 @@ static int mt9m111_try_fmt(struct soc_camera_device *icd, } static int mt9m111_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; - if (id->match_chip != mt9m111->client->addr) + if (id->match.addr != mt9m111->client->addr) return -ENODEV; id->ident = mt9m111->model; @@ -532,18 +532,19 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m111_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { int val; struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) return -EINVAL; - if (reg->match_chip != mt9m111->client->addr) + if (reg->match.addr != mt9m111->client->addr) return -ENODEV; val = mt9m111_reg_read(icd, reg->reg); + reg->size = 2; reg->val = (u64)val; if (reg->val > 0xffff) @@ -553,14 +554,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd, } static int mt9m111_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) return -EINVAL; - if (reg->match_chip != mt9m111->client->addr) + if (reg->match.addr != mt9m111->client->addr) return -ENODEV; if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 1a9d53966d0..349d8e36553 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -326,14 +326,14 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd, } static int mt9t031_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); - if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; - if (id->match_chip != mt9t031->client->addr) + if (id->match.addr != mt9t031->client->addr) return -ENODEV; id->ident = mt9t031->model; @@ -344,14 +344,14 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9t031_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9t031->client->addr) + if (reg->match.addr != mt9t031->client->addr) return -ENODEV; reg->val = reg_read(icd, reg->reg); @@ -363,14 +363,14 @@ static int mt9t031_get_register(struct soc_camera_device *icd, } static int mt9t031_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9t031->client->addr) + if (reg->match.addr != mt9t031->client->addr) return -ENODEV; if (reg_write(icd, reg->reg, reg->val) < 0) diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 14a5f9c21ff..b04c8cb1644 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -422,14 +422,14 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd, } static int mt9v022_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; - if (id->match_chip != mt9v022->client->addr) + if (id->match.addr != mt9v022->client->addr) return -ENODEV; id->ident = mt9v022->model; @@ -440,16 +440,17 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9v022_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9v022->client->addr) + if (reg->match.addr != mt9v022->client->addr) return -ENODEV; + reg->size = 2; reg->val = reg_read(icd, reg->reg); if (reg->val > 0xffff) @@ -459,14 +460,14 @@ static int mt9v022_get_register(struct soc_camera_device *icd, } static int mt9v022_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; - if (reg->match_chip != mt9v022->client->addr) + if (reg->match.addr != mt9v022->client->addr) return -ENODEV; if (reg_write(icd, reg->reg, reg->val) < 0) diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 7f130284b5c..e3cbe14c349 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -489,7 +489,7 @@ static int mxb_detach(struct saa7146_dev *dev) return 0; } -static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 85c3c7c92af..73eb656acfe 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -1454,9 +1454,9 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) return rval; } -static int omap24xxcam_open(struct inode *inode, struct file *file) +static int omap24xxcam_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct omap24xxcam_device *cam = omap24xxcam.priv; struct omap24xxcam_fh *fh; struct v4l2_format format; @@ -1511,7 +1511,7 @@ out_try_module_get: return -ENODEV; } -static int omap24xxcam_release(struct inode *inode, struct file *file) +static int omap24xxcam_release(struct file *file) { struct omap24xxcam_fh *fh = file->private_data; struct omap24xxcam_device *cam = fh->cam; @@ -1559,8 +1559,7 @@ static int omap24xxcam_release(struct inode *inode, struct file *file) return 0; } -static struct file_operations omap24xxcam_fops = { - .llseek = no_llseek, +static struct v4l2_file_operations omap24xxcam_fops = { .ioctl = video_ioctl2, .poll = omap24xxcam_poll, .mmap = omap24xxcam_mmap, diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 6ee9b69cc4a..9af5532db14 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -3915,7 +3915,7 @@ ov51x_dealloc(struct usb_ov511 *ov) ***************************************************************************/ static int -ov51x_v4l1_open(struct inode *inode, struct file *file) +ov51x_v4l1_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct usb_ov511 *ov = video_get_drvdata(vdev); @@ -3972,7 +3972,7 @@ out: } static int -ov51x_v4l1_close(struct inode *inode, struct file *file) +ov51x_v4l1_close(struct file *file) { struct video_device *vdev = file->private_data; struct usb_ov511 *ov = video_get_drvdata(vdev); @@ -4010,7 +4010,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) } /* Do not call this function directly! */ -static int +static long ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; @@ -4449,8 +4449,8 @@ redo: return 0; } -static int -ov51x_v4l1_ioctl(struct inode *inode, struct file *file, +static long +ov51x_v4l1_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct video_device *vdev = file->private_data; @@ -4661,17 +4661,13 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static const struct file_operations ov511_fops = { +static const struct v4l2_file_operations ov511_fops = { .owner = THIS_MODULE, .open = ov51x_v4l1_open, .release = ov51x_v4l1_close, .read = ov51x_v4l1_read, .mmap = ov51x_v4l1_mmap, .ioctl = ov51x_v4l1_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device vdev_template = { diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index ea032f5f2f4..ca26b0c50cf 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -1310,7 +1310,7 @@ static int ov7670_command(struct i2c_client *client, unsigned int cmd, void *arg) { switch (cmd) { - case VIDIOC_G_CHIP_IDENT: + case VIDIOC_DBG_G_CHIP_IDENT: return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0); case VIDIOC_INT_RESET: diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 54b736fcc07..3c9e0ba974e 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -724,7 +724,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) } static int ov772x_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); @@ -736,11 +736,12 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov772x_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); int ret; + reg->size = 1; if (reg->reg > 0xff) return -EINVAL; @@ -754,7 +755,7 @@ static int ov772x_get_register(struct soc_camera_device *icd, } static int ov772x_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 45730fac157..a1ad38fc49c 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -680,7 +680,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int * Video4linux interfacing */ -static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct pms_device *pd=(struct pms_device *)dev; @@ -862,7 +862,7 @@ static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int pms_ioctl(struct inode *inode, struct file *file, +static long pms_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, pms_do_ioctl); @@ -881,7 +881,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, return len; } -static int pms_exclusive_open(struct inode *inode, struct file *file) +static int pms_exclusive_open(struct file *file) { struct video_device *v = video_devdata(file); struct pms_device *pd = (struct pms_device *)v; @@ -889,7 +889,7 @@ static int pms_exclusive_open(struct inode *inode, struct file *file) return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; } -static int pms_exclusive_release(struct inode *inode, struct file *file) +static int pms_exclusive_release(struct file *file) { struct video_device *v = video_devdata(file); struct pms_device *pd = (struct pms_device *)v; @@ -898,16 +898,12 @@ static int pms_exclusive_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations pms_fops = { +static const struct v4l2_file_operations pms_fops = { .owner = THIS_MODULE, .open = pms_exclusive_open, .release = pms_exclusive_release, .ioctl = pms_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = pms_read, - .llseek = no_llseek, }; static struct video_device pms_template= diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 4358079f196..8fb92ac78c7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -4732,26 +4732,25 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) int pvr2_hdw_register_access(struct pvr2_hdw *hdw, - u32 match_type, u32 match_chip, u64 reg_id, - int setFl,u64 *val_ptr) + struct v4l2_dbg_match *match, u64 reg_id, + int setFl, u64 *val_ptr) { #ifdef CONFIG_VIDEO_ADV_DEBUG struct pvr2_i2c_client *cp; - struct v4l2_register req; + struct v4l2_dbg_register req; int stat = 0; int okFl = 0; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - req.match_type = match_type; - req.match_chip = match_chip; + req.match = *match; req.reg = reg_id; if (setFl) req.val = *val_ptr; mutex_lock(&hdw->i2c_list_lock); do { list_for_each_entry(cp, &hdw->i2c_clients, list) { if (!v4l2_chip_match_i2c_client( cp->client, - req.match_type, req.match_chip)) { + &req.match)) { continue; } stat = pvr2_i2c_client_cmd( diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 49482d1f2b2..1b4fec337c6 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -242,8 +242,8 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, setFl - true to set the register, false to read it val_ptr - storage location for source / result. */ int pvr2_hdw_register_access(struct pvr2_hdw *, - u32 match_type, u32 match_chip,u64 reg_id, - int setFl,u64 *val_ptr); + struct v4l2_dbg_match *match, u64 reg_id, + int setFl, u64 *val_ptr); /* The following entry points are all lower level things you normally don't want to worry about. */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 52af1c43596..878fd52a73b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -168,13 +168,13 @@ static const char *get_v4l_name(int v4l_type) * This is part of Video 4 Linux API. The procedure handles ioctl() calls. * */ -static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_v4l2 *vp = fh->vhead; struct pvr2_v4l2_dev *dev_info = fh->dev_info; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int ret = -EINVAL; + long ret = -EINVAL; if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); @@ -851,11 +851,11 @@ static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_DBG_G_REGISTER: { u64 val; - struct v4l2_register *req = (struct v4l2_register *)arg; + struct v4l2_dbg_register *req = (struct v4l2_dbg_register *)arg; if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val; ret = pvr2_hdw_register_access( - hdw,req->match_type,req->match_chip,req->reg, - cmd == VIDIOC_DBG_S_REGISTER,&val); + hdw, &req->match, req->reg, + cmd == VIDIOC_DBG_S_REGISTER, &val); if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val; break; } @@ -871,20 +871,20 @@ static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (ret < 0) { if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d",ret); + "pvr2_v4l2_do_ioctl failure, ret=%ld", ret); } else { if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d" - " command was:",ret); + "pvr2_v4l2_do_ioctl failure, ret=%ld" + " command was:", ret); v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); } } } else { pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)", - ret,ret); + "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)", + ret, ret); } return ret; } @@ -948,7 +948,7 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) } -static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, +static long pvr2_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -960,7 +960,7 @@ static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, } -static int pvr2_v4l2_release(struct inode *inode, struct file *file) +static int pvr2_v4l2_release(struct file *file) { struct pvr2_v4l2_fh *fhp = file->private_data; struct pvr2_v4l2 *vp = fhp->vhead; @@ -1008,7 +1008,7 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file) } -static int pvr2_v4l2_open(struct inode *inode, struct file *file) +static int pvr2_v4l2_open(struct file *file) { struct pvr2_v4l2_dev *dip; /* Our own context pointer */ struct pvr2_v4l2_fh *fhp; @@ -1235,13 +1235,12 @@ static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) } -static const struct file_operations vdev_fops = { +static const struct v4l2_file_operations vdev_fops = { .owner = THIS_MODULE, .open = pvr2_v4l2_open, .release = pvr2_v4l2_release, .read = pvr2_v4l2_read, .ioctl = pvr2_v4l2_ioctl, - .llseek = no_llseek, .poll = pvr2_v4l2_poll, }; diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index c6653021019..f9fbe02e0f6 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -1266,9 +1266,9 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) /* copy local variable to arg */ #define ARG_OUT(ARG_name) /* nothing */ -int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) +long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { - int ret = 0; + long ret = 0; switch(cmd) { case VIDIOCPWCRUSER: diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 1ce9da167b7..39fbc970f43 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -142,16 +142,16 @@ static struct { /***/ -static int pwc_video_open(struct inode *inode, struct file *file); -static int pwc_video_close(struct inode *inode, struct file *file); +static int pwc_video_open(struct file *file); +static int pwc_video_close(struct file *file); static ssize_t pwc_video_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); -static int pwc_video_ioctl(struct inode *inode, struct file *file, +static long pwc_video_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg); static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); -static const struct file_operations pwc_fops = { +static const struct v4l2_file_operations pwc_fops = { .owner = THIS_MODULE, .open = pwc_video_open, .release = pwc_video_close, @@ -159,10 +159,6 @@ static const struct file_operations pwc_fops = { .poll = pwc_video_poll, .mmap = pwc_video_mmap, .ioctl = pwc_video_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ @@ -1104,7 +1100,7 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type) /***************************************************************************/ /* Video4Linux functions */ -static int pwc_video_open(struct inode *inode, struct file *file) +static int pwc_video_open(struct file *file) { int i, ret; struct video_device *vdev = video_devdata(file); @@ -1224,7 +1220,7 @@ static void pwc_cleanup(struct pwc_device *pdev) } /* Note that all cleanup is done in the reverse order as in _open */ -static int pwc_video_close(struct inode *inode, struct file *file) +static int pwc_video_close(struct file *file) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; @@ -1399,12 +1395,12 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) return 0; } -static int pwc_video_ioctl(struct inode *inode, struct file *file, +static long pwc_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - int r = -ENODEV; + long r = -ENODEV; if (!vdev) goto out; diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index d7c147328e3..bc0a464295c 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -337,7 +337,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) } -int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) +long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct pwc_device *pdev; diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index c046a253566..01411fb2337 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -337,10 +337,10 @@ extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise); extern int pwc_camera_power(struct pwc_device *pdev, int power); /* Private ioctl()s; see pwc-ioctl.h */ -extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); +extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); /** Functions in pwc-v4l.c */ -extern int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); +extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); /** pwc-uncompress.c */ /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 3c3f8cf7310..13f85ad363c 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1502,9 +1502,9 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, dprintk(2, "setting jpeg quality %d\n", jc->quality); return 0; } -static int s2255_open(struct inode *inode, struct file *file) +static int s2255_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct s2255_dev *h, *dev = NULL; struct s2255_fh *fh; struct list_head *list; @@ -1711,11 +1711,11 @@ static void s2255_destroy(struct kref *kref) mutex_unlock(&dev->open_lock); } -static int s2255_close(struct inode *inode, struct file *file) +static int s2255_close(struct file *file) { struct s2255_fh *fh = file->private_data; struct s2255_dev *dev = fh->dev; - int minor = iminor(inode); + int minor = video_devdata(file)->minor; if (!dev) return -ENODEV; @@ -1759,15 +1759,13 @@ static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) return ret; } -static const struct file_operations s2255_fops_v4l = { +static const struct v4l2_file_operations s2255_fops_v4l = { .owner = THIS_MODULE, .open = s2255_open, .release = s2255_close, .poll = s2255_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ - .compat_ioctl = v4l_compat_ioctl32, .mmap = s2255_mmap_v4l, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops s2255_ioctl_ops = { diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index f159441e937..e637e440b6d 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -804,7 +804,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t, * * Returns 0 if successful */ -static int do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg) +static long do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg) { struct saa5246a_device *t = video_drvdata(file); @@ -944,11 +944,11 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) /* * Handle the locking */ -static int saa5246a_ioctl(struct inode *inode, struct file *file, +static long saa5246a_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct saa5246a_device *t = video_drvdata(file); - int err; + long err; cmd = vtx_fix_command(cmd); mutex_lock(&t->lock); @@ -957,7 +957,7 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file, return err; } -static int saa5246a_open(struct inode *inode, struct file *file) +static int saa5246a_open(struct file *file) { struct saa5246a_device *t = video_drvdata(file); @@ -999,7 +999,7 @@ static int saa5246a_open(struct inode *inode, struct file *file) return 0; } -static int saa5246a_release(struct inode *inode, struct file *file) +static int saa5246a_release(struct file *file) { struct saa5246a_device *t = video_drvdata(file); @@ -1018,12 +1018,11 @@ static int saa5246a_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations saa_fops = { +static const struct v4l2_file_operations saa_fops = { .owner = THIS_MODULE, .open = saa5246a_open, .release = saa5246a_release, .ioctl = saa5246a_ioctl, - .llseek = no_llseek, }; static struct video_device saa_template = diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 6ef3affb97f..e2976519246 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -190,7 +190,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) * Standard character-device-driver functions */ -static int do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg) +static long do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg) { static int virtual_mode = false; struct saa5249_device *t = video_drvdata(file); @@ -479,11 +479,11 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) * Handle the locking */ -static int saa5249_ioctl(struct inode *inode, struct file *file, +static long saa5249_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct saa5249_device *t = video_drvdata(file); - int err; + long err; cmd = vtx_fix_command(cmd); mutex_lock(&t->lock); @@ -492,7 +492,7 @@ static int saa5249_ioctl(struct inode *inode, struct file *file, return err; } -static int saa5249_open(struct inode *inode, struct file *file) +static int saa5249_open(struct file *file) { struct saa5249_device *t = video_drvdata(file); int pgbuf; @@ -529,7 +529,7 @@ static int saa5249_open(struct inode *inode, struct file *file) -static int saa5249_release(struct inode *inode, struct file *file) +static int saa5249_release(struct file *file) { struct saa5249_device *t = video_drvdata(file); @@ -539,15 +539,11 @@ static int saa5249_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations saa_fops = { +static const struct v4l2_file_operations saa_fops = { .owner = THIS_MODULE, .open = saa5249_open, .release = saa5249_release, .ioctl = saa5249_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device saa_template = diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 22708ecdf1b..46c796c3fec 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1371,25 +1371,24 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = saa711x_read(sd, reg->reg & 0xff); + reg->size = 1; return 0; } -static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1398,7 +1397,7 @@ static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) } #endif -static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct saa711x_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index bfc85654795..d6848f7a503 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -623,25 +623,24 @@ static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_v } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = saa7127_read(sd, reg->reg & 0xff); + reg->size = 1; return 0; } -static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -650,7 +649,7 @@ static int saa7127_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) } #endif -static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct saa7127_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 1fb6eccdade..1fee6e84a51 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -838,7 +838,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) h->standard = *((v4l2_std_id *) arg); break; - case VIDIOC_G_CHIP_IDENT: + case VIDIOC_DBG_G_CHIP_IDENT: return v4l2_chip_ident_i2c_client(client, arg, h->chip, h->revision); diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index a2e3f6729c5..e2febcd6e52 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4462,6 +4462,7 @@ struct saa7134_board saa7134_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, + .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 3, @@ -4480,8 +4481,6 @@ struct saa7134_board saa7134_boards[] = { .name = name_radio, .amux = LINE2, }, - /* no DVB support for now */ - /* .mpeg = SAA7134_MPEG_DVB, */ }, [SAA7134_BOARD_ASUSTeK_TIGER_3IN1] = { .name = "Asus Tiger 3in1", @@ -4643,6 +4642,38 @@ struct saa7134_board saa7134_boards[] = { .amux = 2, }, }, + [SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = { + .name = "Avermedia AVerTV GO 007 FM Plus", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 0x00300003, + /* .gpiomask = 0x8c240003, */ + .inputs = { { + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x01, + }, { + .name = name_svideo, + .vmux = 6, + .amux = LINE1, + .gpio = 0x02, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x00300001, + }, + .mute = { + .name = name_mute, + .amux = TV, + .gpio = 0x01, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -5702,6 +5733,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x7128, .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG, }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xf31d, + .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS, + + }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -5930,6 +5968,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_GENIUS_TVGO_A11MCE: case SAA7134_BOARD_REAL_ANGEL_220: case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: + case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -6025,6 +6064,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_BEHOLD_M6: case SAA7134_BOARD_BEHOLD_M63: case SAA7134_BOARD_BEHOLD_M6_EXTRA: + case SAA7134_BOARD_BEHOLD_H6: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index d9a5652595b..0776ecf56d2 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -49,6 +49,8 @@ #include "lnbp21.h" #include "tuner-simple.h" +#include "zl10353.h" + MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -854,6 +856,12 @@ static struct tda1004x_config ads_tech_duo_config = { .request_firmware = philips_tda1004x_request_firmware }; +static struct zl10353_config behold_h6_config = { + .demod_address = 0x1e>>1, + .no_tuner = 1, + .parallel_ts = 1, +}; + /* ================================================================== * tda10086 based DVB-S cards, helper functions */ @@ -1357,6 +1365,16 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_0) < 0) goto dettach_frontend; break; + case SAA7134_BOARD_BEHOLD_H6: + fe0->dvb.frontend = dvb_attach(zl10353_attach, + &behold_h6_config, + &dev->i2c_adap); + if (fe0->dvb.frontend) { + dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + &dev->i2c_adap, 0x61, + TUNER_PHILIPS_FMD1216ME_MK3); + } + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 7f40511bcc0..c9d8beb87a6 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -83,9 +83,9 @@ static int ts_init_encoder(struct saa7134_dev* dev) /* ------------------------------------------------------------------ */ -static int ts_open(struct inode *inode, struct file *file) +static int ts_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct saa7134_dev *dev; int err; @@ -119,7 +119,7 @@ done: return err; } -static int ts_release(struct inode *inode, struct file *file) +static int ts_release(struct file *file) { struct saa7134_dev *dev = file->private_data; @@ -405,7 +405,7 @@ static int empress_querymenu(struct file *file, void *priv, } static int empress_g_chip_ident(struct file *file, void *fh, - struct v4l2_chip_ident *chip) + struct v4l2_dbg_chip_ident *chip) { struct saa7134_dev *dev = file->private_data; @@ -413,12 +413,12 @@ static int empress_g_chip_ident(struct file *file, void *fh, chip->revision = 0; if (dev->mpeg_i2c_client == NULL) return -EINVAL; - if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER && - chip->match_chip == I2C_DRIVERID_SAA6752HS) - return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); - if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR && - chip->match_chip == dev->mpeg_i2c_client->addr) - return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); + if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER && + !strcmp(chip->match.name, "saa6752hs")) + return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); + if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR && + chip->match.addr == dev->mpeg_i2c_client->addr) + return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); return -EINVAL; } @@ -437,7 +437,7 @@ static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id) return 0; } -static const struct file_operations ts_fops = +static const struct v4l2_file_operations ts_fops = { .owner = THIS_MODULE, .open = ts_open, @@ -446,7 +446,6 @@ static const struct file_operations ts_fops = .poll = ts_poll, .mmap = ts_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops ts_ioctl_ops = { diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index d2124f64e4e..8a106d36e72 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -449,6 +449,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: case SAA7134_BOARD_AVERMEDIA_M102: + case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; mask_keydown = 0x000010; diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 02bb6747a39..a1f7e351f57 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1326,9 +1326,9 @@ static int saa7134_resource(struct saa7134_fh *fh) return 0; } -static int video_open(struct inode *inode, struct file *file) +static int video_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct saa7134_dev *dev; struct saa7134_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1462,7 +1462,7 @@ err: return POLLERR; } -static int video_release(struct inode *inode, struct file *file) +static int video_release(struct file *file) { struct saa7134_fh *fh = file->private_data; struct saa7134_dev *dev = fh->dev; @@ -2247,24 +2247,25 @@ static int saa7134_g_parm(struct file *file, void *fh, #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register (struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct saa7134_fh *fh = priv; struct saa7134_dev *dev = fh->dev; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; reg->val = saa_readb(reg->reg); + reg->size = 1; return 0; } static int vidioc_s_register (struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct saa7134_fh *fh = priv; struct saa7134_dev *dev = fh->dev; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; saa_writeb(reg->reg&0xffffff, reg->val); return 0; @@ -2377,7 +2378,7 @@ static int radio_queryctrl(struct file *file, void *priv, return 0; } -static const struct file_operations video_fops = +static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, .open = video_open, @@ -2386,8 +2387,6 @@ static const struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -2441,13 +2440,11 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { #endif }; -static const struct file_operations radio_fops = { +static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = video_open, .release = video_release, .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index f6c1fcc7207..14ee265f337 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -276,6 +276,7 @@ struct saa7134_format { #define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151 #define SAA7134_BOARD_ASUSTeK_TIGER 152 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153 +#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 9befca65905..454ad1dd750 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1171,25 +1171,26 @@ static int saa717x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = saa717x_read(sd, reg->reg); + reg->size = 1; return 0; } -static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); u16 addr = reg->reg & 0xffff; u8 val = reg->val & 0xff; - if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index d652f25eef0..5990ab38a12 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c @@ -932,7 +932,7 @@ static void usb_se401_remove_disconnected (struct usb_se401 *se401) ***************************************************************************/ -static int se401_open(struct inode *inode, struct file *file) +static int se401_open(struct file *file) { struct video_device *dev = video_devdata(file); struct usb_se401 *se401 = (struct usb_se401 *)dev; @@ -954,7 +954,7 @@ static int se401_open(struct inode *inode, struct file *file) return err; } -static int se401_close(struct inode *inode, struct file *file) +static int se401_close(struct file *file) { struct video_device *dev = file->private_data; struct usb_se401 *se401 = (struct usb_se401 *)dev; @@ -975,7 +975,7 @@ static int se401_close(struct inode *inode, struct file *file) return 0; } -static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; struct usb_se401 *se401 = (struct usb_se401 *)vdev; @@ -1138,7 +1138,7 @@ static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int se401_ioctl(struct inode *inode, struct file *file, +static long se401_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, se401_do_ioctl); @@ -1222,17 +1222,13 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static const struct file_operations se401_fops = { +static const struct v4l2_file_operations se401_fops = { .owner = THIS_MODULE, .open = se401_open, .release = se401_close, .read = se401_read, .mmap = se401_mmap, .ioctl = se401_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device se401_template = { .name = "se401 USB camera", diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 01a8efb8deb..23edfdc4d4b 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -1746,7 +1746,7 @@ static void sn9c102_release_resources(struct kref *kref) } -static int sn9c102_open(struct inode* inode, struct file* filp) +static int sn9c102_open(struct file *filp) { struct sn9c102_device* cam; int err = 0; @@ -1857,7 +1857,7 @@ out: } -static int sn9c102_release(struct inode* inode, struct file* filp) +static int sn9c102_release(struct file *filp) { struct sn9c102_device* cam; @@ -3092,8 +3092,8 @@ sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg) } -static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) +static long sn9c102_ioctl_v4l2(struct file *filp, + unsigned int cmd, void __user *arg) { struct sn9c102_device *cam = video_drvdata(filp); @@ -3196,7 +3196,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, } -static int sn9c102_ioctl(struct inode* inode, struct file* filp, +static long sn9c102_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct sn9c102_device *cam = video_drvdata(filp); @@ -3220,7 +3220,7 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, V4LDBG(3, "sn9c102", cmd); - err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); + err = sn9c102_ioctl_v4l2(filp, cmd, (void __user *)arg); mutex_unlock(&cam->fileop_mutex); @@ -3229,18 +3229,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, /*****************************************************************************/ -static const struct file_operations sn9c102_fops = { +static const struct v4l2_file_operations sn9c102_fops = { .owner = THIS_MODULE, .open = sn9c102_open, .release = sn9c102_release, .ioctl = sn9c102_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = sn9c102_read, .poll = sn9c102_poll, .mmap = sn9c102_mmap, - .llseek = no_llseek, }; /*****************************************************************************/ diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 90077cb4fe6..fcb05f06de8 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -256,7 +256,7 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) vfree(icd->user_formats); } -static int soc_camera_open(struct inode *inode, struct file *file) +static int soc_camera_open(struct file *file) { struct video_device *vdev; struct soc_camera_device *icd; @@ -330,7 +330,7 @@ emgd: return ret; } -static int soc_camera_close(struct inode *inode, struct file *file) +static int soc_camera_close(struct file *file) { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; @@ -400,7 +400,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt) return ici->ops->poll(file, pt); } -static struct file_operations soc_camera_fops = { +static struct v4l2_file_operations soc_camera_fops = { .owner = THIS_MODULE, .open = soc_camera_open, .release = soc_camera_close, @@ -408,7 +408,6 @@ static struct file_operations soc_camera_fops = { .read = soc_camera_read, .mmap = soc_camera_mmap, .poll = soc_camera_poll, - .llseek = no_llseek, }; static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, @@ -700,7 +699,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, } static int soc_camera_g_chip_ident(struct file *file, void *fh, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; @@ -713,7 +712,7 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh, #ifdef CONFIG_VIDEO_ADV_DEBUG static int soc_camera_g_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; @@ -725,7 +724,7 @@ static int soc_camera_g_register(struct file *file, void *fh, } static int soc_camera_s_register(struct file *file, void *fh, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index f9516d0f3c1..26378cf390f 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -664,7 +664,7 @@ static void stk_free_buffers(struct stk_camera *dev) /* v4l file operations */ -static int v4l_stk_open(struct inode *inode, struct file *fp) +static int v4l_stk_open(struct file *fp) { struct stk_camera *dev; struct video_device *vdev; @@ -684,7 +684,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) return 0; } -static int v4l_stk_release(struct inode *inode, struct file *fp) +static int v4l_stk_release(struct file *fp) { struct stk_camera *dev = fp->private_data; @@ -1281,7 +1281,7 @@ static int stk_vidioc_enum_framesizes(struct file *filp, } } -static struct file_operations v4l_stk_fops = { +static struct v4l2_file_operations v4l_stk_fops = { .owner = THIS_MODULE, .open = v4l_stk_open, .release = v4l_stk_release, @@ -1289,10 +1289,6 @@ static struct file_operations v4l_stk_fops = { .poll = v4l_stk_poll, .mmap = v4l_stk_mmap, .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek }; static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index bbad54f85c8..0eb313082c9 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1275,7 +1275,7 @@ static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr) clip_draw_rectangle(clipmap, 0, 0, 1024, -saa->win.y); } -static int saa_ioctl(struct inode *inode, struct file *file, +static long saa_ioctl(struct file *file, unsigned int cmd, unsigned long argl) { struct saa7146 *saa = file->private_data; @@ -1877,7 +1877,7 @@ static ssize_t saa_write(struct file *file, const char __user * buf, return count; } -static int saa_open(struct inode *inode, struct file *file) +static int saa_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev); @@ -1895,7 +1895,7 @@ static int saa_open(struct inode *inode, struct file *file) return 0; } -static int saa_release(struct inode *inode, struct file *file) +static int saa_release(struct file *file) { struct saa7146 *saa = file->private_data; saa->user--; @@ -1906,16 +1906,12 @@ static int saa_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations saa_fops = { +static const struct v4l2_file_operations saa_fops = { .owner = THIS_MODULE, .open = saa_open, .release = saa_release, .ioctl = saa_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = saa_read, - .llseek = no_llseek, .write = saa_write, .mmap = saa_mmap, }; diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 42acc92c182..75f286f7a2e 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1080,7 +1080,7 @@ static int stv680_newframe (struct usb_stv *stv680, int framenr) * Video4Linux *********************************************************************/ -static int stv_open (struct inode *inode, struct file *file) +static int stv_open(struct file *file) { struct video_device *dev = video_devdata(file); struct usb_stv *stv680 = video_get_drvdata(dev); @@ -1106,7 +1106,7 @@ static int stv_open (struct inode *inode, struct file *file) return err; } -static int stv_close (struct inode *inode, struct file *file) +static int stv_close(struct file *file) { struct video_device *dev = file->private_data; struct usb_stv *stv680 = video_get_drvdata(dev); @@ -1132,7 +1132,7 @@ static int stv_close (struct inode *inode, struct file *file) return 0; } -static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = file->private_data; struct usb_stv *stv680 = video_get_drvdata(vdev); @@ -1299,7 +1299,7 @@ static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int stv680_ioctl(struct inode *inode, struct file *file, +static long stv680_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, stv680_do_ioctl); @@ -1391,17 +1391,13 @@ static ssize_t stv680_read (struct file *file, char __user *buf, return realcount; } /* stv680_read */ -static const struct file_operations stv680_fops = { +static const struct v4l2_file_operations stv680_fops = { .owner = THIS_MODULE, .open = stv_open, .release = stv_close, .read = stv680_read, .mmap = stv680_mmap, .ioctl = stv680_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device stv680_template = { .name = "STV0680 USB camera", diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 2644e0dc925..6afb7059502 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -137,7 +137,7 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) return 0; } -static int tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { int byte; diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 31dde86f2df..7519fd1f57e 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -122,7 +122,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) return ret; } -static int tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { if (cmd == TEA6415C_SWITCH) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 38e519f04bd..081e74fa3b2 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -90,7 +90,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) return 0; } -static int tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) +static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { if (cmd == TEA6420_SWITCH) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 97d7509d212..30640fbfd0f 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -800,7 +800,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby) } #ifdef CONFIG_VIDEO_ALLOW_V4L1 -static int tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct tuner *t = to_tuner(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index d0c794da735..5aeccb301ce 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1762,7 +1762,7 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr return 0; } -static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index a388a9f0cb1..2cd64ef27b9 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -963,7 +963,7 @@ static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_chip_ident *chip) + struct v4l2_dbg_chip_ident *chip) { int rev; struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -977,25 +977,24 @@ static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, #ifdef CONFIG_VIDEO_ADV_DEBUG -static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = tvp5150_read(sd, reg->reg & 0xff); + reg->size = 1; return 0; } -static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index d5cdc4be1a3..52c0357faa5 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -575,7 +575,7 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) } static int tw9910_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) + struct v4l2_dbg_chip_ident *id) { id->ident = V4L2_IDENT_TW9910; id->revision = 0; @@ -606,7 +606,7 @@ static int tw9910_enum_input(struct soc_camera_device *icd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int tw9910_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); int ret; @@ -627,7 +627,7 @@ static int tw9910_get_register(struct soc_camera_device *icd, } static int tw9910_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 7a609a3a6db..4f16effb530 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c @@ -147,7 +147,7 @@ static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing return upd64031a_s_frequency(sd, NULL); } -static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -162,25 +162,24 @@ static int upd64031a_log_status(struct v4l2_subdev *sd) } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = upd64031a_read(sd, reg->reg & 0xff); + reg->size = 1; return 0; } -static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 58412cb9c01..4b712f69d1b 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c @@ -120,25 +120,24 @@ static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing } #ifdef CONFIG_VIDEO_ADV_DEBUG -static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; reg->val = upd64083_read(sd, reg->reg & 0xff); + reg->size = 1; return 0; } -static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) +static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (!v4l2_chip_match_i2c_client(client, - reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -147,7 +146,7 @@ static int upd64083_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg } #endif -static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 148a1f98c70..dea8b321fb4 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c @@ -41,13 +41,13 @@ module_param(video_nr, int, 0); static void usbvideo_Disconnect(struct usb_interface *intf); static void usbvideo_CameraRelease(struct uvd *uvd); -static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, +static long usbvideo_v4l_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); -static int usbvideo_v4l_open(struct inode *inode, struct file *file); +static int usbvideo_v4l_open(struct file *file); static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); -static int usbvideo_v4l_close(struct inode *inode, struct file *file); +static int usbvideo_v4l_close(struct file *file); static int usbvideo_StartDataPump(struct uvd *uvd); static void usbvideo_StopDataPump(struct uvd *uvd); @@ -942,17 +942,13 @@ static int usbvideo_find_struct(struct usbvideo *cams) return rv; } -static const struct file_operations usbvideo_fops = { +static const struct v4l2_file_operations usbvideo_fops = { .owner = THIS_MODULE, .open = usbvideo_v4l_open, .release =usbvideo_v4l_close, .read = usbvideo_v4l_read, .mmap = usbvideo_v4l_mmap, .ioctl = usbvideo_v4l_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static const struct video_device usbvideo_template = { .fops = &usbvideo_fops, @@ -1113,7 +1109,7 @@ static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma) * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). */ -static int usbvideo_v4l_open(struct inode *inode, struct file *file) +static int usbvideo_v4l_open(struct file *file) { struct video_device *dev = video_devdata(file); struct uvd *uvd = (struct uvd *) dev; @@ -1233,7 +1229,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers. * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep. */ -static int usbvideo_v4l_close(struct inode *inode, struct file *file) +static int usbvideo_v4l_close(struct file *file) { struct video_device *dev = file->private_data; struct uvd *uvd = (struct uvd *) dev; @@ -1281,7 +1277,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) * History: * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings. */ -static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct uvd *uvd = file->private_data; @@ -1501,7 +1497,7 @@ static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, +static long usbvideo_v4l_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl); diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 4602597ed8d..2f1106338c0 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -229,12 +229,12 @@ set_camera_power(struct vicam_camera *cam, int state) return 0; } -static int -vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg) +static long +vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) { void __user *user_arg = (void __user *)arg; struct vicam_camera *cam = file->private_data; - int retval = 0; + long retval = 0; if (!cam) return -ENODEV; @@ -470,7 +470,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign } static int -vicam_open(struct inode *inode, struct file *file) +vicam_open(struct file *file) { struct vicam_camera *cam = video_drvdata(file); @@ -536,7 +536,7 @@ vicam_open(struct inode *inode, struct file *file) } static int -vicam_close(struct inode *inode, struct file *file) +vicam_close(struct file *file) { struct vicam_camera *cam = file->private_data; int open_count; @@ -783,17 +783,13 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static const struct file_operations vicam_fops = { +static const struct v4l2_file_operations vicam_fops = { .owner = THIS_MODULE, .open = vicam_open, .release = vicam_close, .read = vicam_read, .mmap = vicam_mmap, .ioctl = vicam_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, }; static struct video_device vicam_template = { diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 85661b1848f..2be5e47ed08 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -355,7 +355,7 @@ static void usbvision_remove_sysfs(struct video_device *vdev) * then allocates buffers needed for video processing. * */ -static int usbvision_v4l2_open(struct inode *inode, struct file *file) +static int usbvision_v4l2_open(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); int errCode = 0; @@ -432,7 +432,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) * allocated in usbvision_v4l2_open(). * */ -static int usbvision_v4l2_close(struct inode *inode, struct file *file) +static int usbvision_v4l2_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); @@ -477,12 +477,12 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) */ #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register (struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct usb_usbvision *usbvision = video_drvdata(file); int errCode; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; /* NT100x has a 8-bit register space */ errCode = usbvision_read_reg(usbvision, reg->reg&0xff); @@ -492,16 +492,17 @@ static int vidioc_g_register (struct file *file, void *priv, return errCode; } reg->val = errCode; + reg->size = 1; return 0; } static int vidioc_s_register (struct file *file, void *priv, - struct v4l2_register *reg) + struct v4l2_dbg_register *reg) { struct usb_usbvision *usbvision = video_drvdata(file); int errCode; - if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + if (!v4l2_chip_match_host(®->match)) return -EINVAL; /* NT100x has a 8-bit register space */ errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); @@ -1178,7 +1179,7 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) * Here comes the stuff for radio on usbvision based devices * */ -static int usbvision_radio_open(struct inode *inode, struct file *file) +static int usbvision_radio_open(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); int errCode = 0; @@ -1228,7 +1229,7 @@ out: } -static int usbvision_radio_close(struct inode *inode, struct file *file) +static int usbvision_radio_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); int errCode = 0; @@ -1266,26 +1267,26 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) * Here comes the stuff for vbi on usbvision based devices * */ -static int usbvision_vbi_open(struct inode *inode, struct file *file) +static int usbvision_vbi_open(struct file *file) { /* TODO */ return -ENODEV; } -static int usbvision_vbi_close(struct inode *inode, struct file *file) +static int usbvision_vbi_close(struct file *file) { /* TODO */ return -ENODEV; } -static int usbvision_do_vbi_ioctl(struct file *file, +static long usbvision_do_vbi_ioctl(struct file *file, unsigned int cmd, void *arg) { /* TODO */ return -ENOIOCTLCMD; } -static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, +static long usbvision_vbi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl); @@ -1297,16 +1298,14 @@ static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, // // Video template -static const struct file_operations usbvision_fops = { +static const struct v4l2_file_operations usbvision_fops = { .owner = THIS_MODULE, .open = usbvision_v4l2_open, .release = usbvision_v4l2_close, .read = usbvision_v4l2_read, .mmap = usbvision_v4l2_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, /* .poll = video_poll, */ - .compat_ioctl = v4l_compat_ioctl32, }; static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { @@ -1355,13 +1354,11 @@ static struct video_device usbvision_video_template = { // Radio template -static const struct file_operations usbvision_radio_fops = { +static const struct v4l2_file_operations usbvision_radio_fops = { .owner = THIS_MODULE, .open = usbvision_radio_open, .release = usbvision_radio_close, .ioctl = video_ioctl2, - .llseek = no_llseek, - .compat_ioctl = v4l_compat_ioctl32, }; static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { @@ -1392,13 +1389,11 @@ static struct video_device usbvision_radio_template = { }; // vbi template -static const struct file_operations usbvision_vbi_fops = { +static const struct v4l2_file_operations usbvision_vbi_fops = { .owner = THIS_MODULE, .open = usbvision_vbi_open, .release = usbvision_vbi_close, .ioctl = usbvision_vbi_ioctl, - .llseek = no_llseek, - .compat_ioctl = v4l_compat_ioctl32, }; static struct video_device usbvision_vbi_template= diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index afcc6934559..fa150fff2c1 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -406,7 +406,7 @@ static int uvc_has_privileges(struct uvc_fh *handle) * V4L2 file operations */ -static int uvc_v4l2_open(struct inode *inode, struct file *file) +static int uvc_v4l2_open(struct file *file) { struct uvc_video_device *video; struct uvc_fh *handle; @@ -444,7 +444,7 @@ done: return ret; } -static int uvc_v4l2_release(struct inode *inode, struct file *file) +static int uvc_v4l2_release(struct file *file) { struct uvc_video_device *video = video_drvdata(file); struct uvc_fh *handle = (struct uvc_fh *)file->private_data; @@ -472,12 +472,12 @@ static int uvc_v4l2_release(struct inode *inode, struct file *file) return 0; } -static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct uvc_video_device *video = video_get_drvdata(vdev); struct uvc_fh *handle = (struct uvc_fh *)file->private_data; - int ret = 0; + long ret = 0; switch (cmd) { /* Query capabilities */ @@ -996,7 +996,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) return ret; } -static int uvc_v4l2_ioctl(struct inode *inode, struct file *file, +static long uvc_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { if (uvc_trace_param & UVC_TRACE_IOCTL) { @@ -1097,13 +1097,11 @@ static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) return uvc_queue_poll(&video->queue, file, wait); } -struct file_operations uvc_fops = { +const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, .ioctl = uvc_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, .read = uvc_v4l2_read, .mmap = uvc_v4l2_mmap, .poll = uvc_v4l2_poll, diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 896b791ece1..bcf4361dc1b 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -753,7 +753,7 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue) } /* V4L2 interface */ -extern struct file_operations uvc_fops; +extern const struct v4l2_file_operations uvc_fops; /* Video */ extern int uvc_video_init(struct uvc_video_device *video); diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index f13c0a9d684..d450cab20be 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c @@ -267,12 +267,12 @@ done: /* ----------------------------------------------------------------- */ -static noinline int v4l1_compat_get_capabilities( +static noinline long v4l1_compat_get_capabilities( struct video_capability *cap, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_framebuffer fbuf; struct v4l2_capability *cap2; @@ -286,13 +286,13 @@ static noinline int v4l1_compat_get_capabilities( err = drv(file, VIDIOC_QUERYCAP, cap2); if (err < 0) { - dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err); + dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %ld\n", err); goto done; } if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) { err = drv(file, VIDIOC_G_FBUF, &fbuf); if (err < 0) { - dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err); + dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %ld\n", err); memset(&fbuf, 0, sizeof(fbuf)); } err = 0; @@ -324,12 +324,12 @@ done: return err; } -static noinline int v4l1_compat_get_frame_buffer( +static noinline long v4l1_compat_get_frame_buffer( struct video_buffer *buffer, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_framebuffer fbuf; memset(buffer, 0, sizeof(*buffer)); @@ -337,7 +337,7 @@ static noinline int v4l1_compat_get_frame_buffer( err = drv(file, VIDIOC_G_FBUF, &fbuf); if (err < 0) { - dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err); + dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %ld\n", err); goto done; } buffer->base = fbuf.base; @@ -378,12 +378,12 @@ done: return err; } -static noinline int v4l1_compat_set_frame_buffer( +static noinline long v4l1_compat_set_frame_buffer( struct video_buffer *buffer, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_framebuffer fbuf; memset(&fbuf, 0, sizeof(fbuf)); @@ -410,16 +410,16 @@ static noinline int v4l1_compat_set_frame_buffer( fbuf.fmt.bytesperline = buffer->bytesperline; err = drv(file, VIDIOC_S_FBUF, &fbuf); if (err < 0) - dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err); + dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %ld\n", err); return err; } -static noinline int v4l1_compat_get_win_cap_dimensions( +static noinline long v4l1_compat_get_win_cap_dimensions( struct video_window *win, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); @@ -432,7 +432,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions( fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) - dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err); + dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %ld\n", err); if (err == 0) { win->x = fmt->fmt.win.w.left; win->y = fmt->fmt.win.w.top; @@ -447,7 +447,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions( fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) { - dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err); + dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %ld\n", err); goto done; } win->x = 0; @@ -462,12 +462,12 @@ done: return err; } -static noinline int v4l1_compat_set_win_cap_dimensions( +static noinline long v4l1_compat_set_win_cap_dimensions( struct video_window *win, struct file *file, v4l2_kioctl drv) { - int err, err1, err2; + long err, err1, err2; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); @@ -479,7 +479,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( drv(file, VIDIOC_STREAMOFF, &fmt->type); err1 = drv(file, VIDIOC_G_FMT, fmt); if (err1 < 0) - dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1); + dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %ld\n", err1); if (err1 == 0) { fmt->fmt.pix.width = win->width; fmt->fmt.pix.height = win->height; @@ -487,7 +487,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( fmt->fmt.pix.bytesperline = 0; err = drv(file, VIDIOC_S_FMT, fmt); if (err < 0) - dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n", + dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %ld\n", err); win->width = fmt->fmt.pix.width; win->height = fmt->fmt.pix.height; @@ -504,7 +504,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions( fmt->fmt.win.clipcount = win->clipcount; err2 = drv(file, VIDIOC_S_FMT, fmt); if (err2 < 0) - dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2); + dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %ld\n", err2); if (err1 != 0 && err2 != 0) err = err1; @@ -514,12 +514,12 @@ static noinline int v4l1_compat_set_win_cap_dimensions( return err; } -static noinline int v4l1_compat_turn_preview_on_off( +static noinline long v4l1_compat_turn_preview_on_off( int *on, struct file *file, v4l2_kioctl drv) { - int err; + long err; enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == *on) { @@ -530,16 +530,16 @@ static noinline int v4l1_compat_turn_preview_on_off( } err = drv(file, VIDIOC_OVERLAY, on); if (err < 0) - dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err); + dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld\n", err); return err; } -static noinline int v4l1_compat_get_input_info( +static noinline long v4l1_compat_get_input_info( struct video_channel *chan, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_input input2; v4l2_std_id sid; @@ -548,7 +548,7 @@ static noinline int v4l1_compat_get_input_info( err = drv(file, VIDIOC_ENUMINPUT, &input2); if (err < 0) { dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " - "channel=%d err=%d\n", chan->channel, err); + "channel=%d err=%ld\n", chan->channel, err); goto done; } chan->channel = input2.index; @@ -569,7 +569,7 @@ static noinline int v4l1_compat_get_input_info( chan->norm = 0; err = drv(file, VIDIOC_G_STD, &sid); if (err < 0) - dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err); + dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %ld\n", err); if (err == 0) { if (sid & V4L2_STD_PAL) chan->norm = VIDEO_MODE_PAL; @@ -582,17 +582,17 @@ done: return err; } -static noinline int v4l1_compat_set_input( +static noinline long v4l1_compat_set_input( struct video_channel *chan, struct file *file, v4l2_kioctl drv) { - int err; + long err; v4l2_std_id sid = 0; err = drv(file, VIDIOC_S_INPUT, &chan->channel); if (err < 0) - dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err); + dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %ld\n", err); switch (chan->norm) { case VIDEO_MODE_PAL: sid = V4L2_STD_PAL; @@ -607,17 +607,17 @@ static noinline int v4l1_compat_set_input( if (0 != sid) { err = drv(file, VIDIOC_S_STD, &sid); if (err < 0) - dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err); + dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %ld\n", err); } return err; } -static noinline int v4l1_compat_get_picture( +static noinline long v4l1_compat_get_picture( struct video_picture *pict, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); @@ -640,7 +640,7 @@ static noinline int v4l1_compat_get_picture( fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) { - dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err); + dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %ld\n", err); goto done; } @@ -654,12 +654,12 @@ done: return err; } -static noinline int v4l1_compat_set_picture( +static noinline long v4l1_compat_set_picture( struct video_picture *pict, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_framebuffer fbuf; int mem_err = 0, ovl_err = 0; struct v4l2_format *fmt; @@ -694,7 +694,7 @@ static noinline int v4l1_compat_set_picture( support memory capture. Trying to set the memory capture parameters would be pointless. */ if (err < 0) { - dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err); + dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %ld\n", err); mem_err = -1000; /* didn't even try */ } else if (fmt->fmt.pix.pixelformat != palette_to_pixelformat(pict->palette)) { @@ -711,7 +711,7 @@ static noinline int v4l1_compat_set_picture( support overlay. Trying to set the overlay parameters would be quite pointless. */ if (err < 0) { - dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err); + dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %ld\n", err); ovl_err = -1000; /* didn't even try */ } else if (fbuf.fmt.pixelformat != palette_to_pixelformat(pict->palette)) { @@ -736,12 +736,13 @@ static noinline int v4l1_compat_set_picture( return err; } -static noinline int v4l1_compat_get_tuner( +static noinline long v4l1_compat_get_tuner( struct video_tuner *tun, struct file *file, v4l2_kioctl drv) { - int err, i; + long err; + int i; struct v4l2_tuner tun2; struct v4l2_standard std2; v4l2_std_id sid; @@ -749,7 +750,7 @@ static noinline int v4l1_compat_get_tuner( memset(&tun2, 0, sizeof(tun2)); err = drv(file, VIDIOC_G_TUNER, &tun2); if (err < 0) { - dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err); + dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %ld\n", err); goto done; } memcpy(tun->name, tun2.name, @@ -775,7 +776,7 @@ static noinline int v4l1_compat_get_tuner( err = drv(file, VIDIOC_G_STD, &sid); if (err < 0) - dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err); + dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err); if (err == 0) { if (sid & V4L2_STD_PAL) tun->mode = VIDEO_MODE_PAL; @@ -794,12 +795,12 @@ done: return err; } -static noinline int v4l1_compat_select_tuner( +static noinline long v4l1_compat_select_tuner( struct video_tuner *tun, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_tuner t;/*84 bytes on x86_64*/ memset(&t, 0, sizeof(t)); @@ -807,34 +808,34 @@ static noinline int v4l1_compat_select_tuner( err = drv(file, VIDIOC_S_INPUT, &t); if (err < 0) - dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err); + dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err); return err; } -static noinline int v4l1_compat_get_frequency( +static noinline long v4l1_compat_get_frequency( unsigned long *freq, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_frequency freq2; memset(&freq2, 0, sizeof(freq2)); freq2.tuner = 0; err = drv(file, VIDIOC_G_FREQUENCY, &freq2); if (err < 0) - dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err); + dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld\n", err); if (0 == err) *freq = freq2.frequency; return err; } -static noinline int v4l1_compat_set_frequency( +static noinline long v4l1_compat_set_frequency( unsigned long *freq, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_frequency freq2; memset(&freq2, 0, sizeof(freq2)); @@ -842,16 +843,17 @@ static noinline int v4l1_compat_set_frequency( freq2.frequency = *freq; err = drv(file, VIDIOC_S_FREQUENCY, &freq2); if (err < 0) - dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err); + dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld\n", err); return err; } -static noinline int v4l1_compat_get_audio( +static noinline long v4l1_compat_get_audio( struct video_audio *aud, struct file *file, v4l2_kioctl drv) { - int err, i; + long err; + int i; struct v4l2_queryctrl qctrl2; struct v4l2_audio aud2; struct v4l2_tuner tun2; @@ -859,7 +861,7 @@ static noinline int v4l1_compat_get_audio( err = drv(file, VIDIOC_G_AUDIO, &aud2); if (err < 0) { - dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err); + dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld\n", err); goto done; } memcpy(aud->name, aud2.name, @@ -903,7 +905,7 @@ static noinline int v4l1_compat_get_audio( memset(&tun2, 0, sizeof(tun2)); err = drv(file, VIDIOC_G_TUNER, &tun2); if (err < 0) { - dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err); + dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld\n", err); err = 0; goto done; } @@ -918,12 +920,12 @@ done: return err; } -static noinline int v4l1_compat_set_audio( +static noinline long v4l1_compat_set_audio( struct video_audio *aud, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_audio aud2; struct v4l2_tuner tun2; @@ -933,7 +935,7 @@ static noinline int v4l1_compat_set_audio( aud2.index = aud->audio; err = drv(file, VIDIOC_S_AUDIO, &aud2); if (err < 0) { - dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err); + dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld\n", err); goto done; } @@ -950,7 +952,7 @@ static noinline int v4l1_compat_set_audio( err = drv(file, VIDIOC_G_TUNER, &tun2); if (err < 0) - dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err); + dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld\n", err); if (err == 0) { switch (aud->mode) { default: @@ -967,19 +969,19 @@ static noinline int v4l1_compat_set_audio( } err = drv(file, VIDIOC_S_TUNER, &tun2); if (err < 0) - dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err); + dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld\n", err); } err = 0; done: return err; } -static noinline int v4l1_compat_capture_frame( +static noinline long v4l1_compat_capture_frame( struct video_mmap *mm, struct file *file, v4l2_kioctl drv) { - int err; + long err; enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; struct v4l2_buffer buf; struct v4l2_format *fmt; @@ -994,7 +996,7 @@ static noinline int v4l1_compat_capture_frame( fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) { - dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err); + dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld\n", err); goto done; } if (mm->width != fmt->fmt.pix.width || @@ -1010,7 +1012,7 @@ static noinline int v4l1_compat_capture_frame( fmt->fmt.pix.bytesperline = 0; err = drv(file, VIDIOC_S_FMT, fmt); if (err < 0) { - dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err); + dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld\n", err); goto done; } } @@ -1018,28 +1020,28 @@ static noinline int v4l1_compat_capture_frame( buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_QUERYBUF, &buf); if (err < 0) { - dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err); + dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld\n", err); goto done; } err = drv(file, VIDIOC_QBUF, &buf); if (err < 0) { - dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err); + dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %ld\n", err); goto done; } err = drv(file, VIDIOC_STREAMON, &captype); if (err < 0) - dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err); + dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld\n", err); done: kfree(fmt); return err; } -static noinline int v4l1_compat_sync( +static noinline long v4l1_compat_sync( int *i, struct file *file, v4l2_kioctl drv) { - int err; + long err; enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; struct v4l2_buffer buf; struct poll_wqueues *pwq; @@ -1050,7 +1052,7 @@ static noinline int v4l1_compat_sync( err = drv(file, VIDIOC_QUERYBUF, &buf); if (err < 0) { /* No such buffer */ - dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); + dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); goto done; } if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) { @@ -1062,7 +1064,7 @@ static noinline int v4l1_compat_sync( /* make sure capture actually runs so we don't block forever */ err = drv(file, VIDIOC_STREAMON, &captype); if (err < 0) { - dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err); + dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %ld\n", err); goto done; } @@ -1076,7 +1078,7 @@ static noinline int v4l1_compat_sync( break; err = drv(file, VIDIOC_QUERYBUF, &buf); if (err < 0) - dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err); + dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %ld\n", err); } kfree(pwq); if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */ @@ -1084,18 +1086,18 @@ static noinline int v4l1_compat_sync( do { err = drv(file, VIDIOC_DQBUF, &buf); if (err < 0) - dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err); + dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %ld\n", err); } while (err == 0 && buf.index != *i); done: return err; } -static noinline int v4l1_compat_get_vbi_format( +static noinline long v4l1_compat_get_vbi_format( struct vbi_format *fmt, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_format *fmt2; fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL); @@ -1107,7 +1109,7 @@ static noinline int v4l1_compat_get_vbi_format( err = drv(file, VIDIOC_G_FMT, fmt2); if (err < 0) { - dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); + dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld\n", err); goto done; } if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { @@ -1128,12 +1130,12 @@ done: return err; } -static noinline int v4l1_compat_set_vbi_format( +static noinline long v4l1_compat_set_vbi_format( struct vbi_format *fmt, struct file *file, v4l2_kioctl drv) { - int err; + long err; struct v4l2_format *fmt2 = NULL; if (VIDEO_PALETTE_RAW != fmt->sample_format) { @@ -1157,7 +1159,7 @@ static noinline int v4l1_compat_set_vbi_format( fmt2->fmt.vbi.flags = fmt->flags; err = drv(file, VIDIOC_TRY_FMT, fmt2); if (err < 0) { - dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err); + dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld\n", err); goto done; } @@ -1174,7 +1176,7 @@ static noinline int v4l1_compat_set_vbi_format( } err = drv(file, VIDIOC_S_FMT, fmt2); if (err < 0) - dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err); + dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld\n", err); done: kfree(fmt2); return err; @@ -1183,13 +1185,13 @@ done: /* * This function is exported. */ -int +long v4l_compat_translate_ioctl(struct file *file, int cmd, void *arg, v4l2_kioctl drv) { - int err; + long err; switch (cmd) { case VIDIOCGCAP: /* capability */ diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index c676b0b0f70..b8f2be8d5c0 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -797,11 +797,11 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) } EXPORT_SYMBOL(v4l2_ctrl_next); -int v4l2_chip_match_host(u32 match_type, u32 match_chip) +int v4l2_chip_match_host(const struct v4l2_dbg_match *match) { - switch (match_type) { + switch (match->type) { case V4L2_CHIP_MATCH_HOST: - return match_chip == 0; + return match->addr == 0; default: return 0; } @@ -809,23 +809,34 @@ int v4l2_chip_match_host(u32 match_type, u32 match_chip) EXPORT_SYMBOL(v4l2_chip_match_host); #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) -int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) +int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match) { - switch (match_type) { + int len; + + if (c == NULL || match == NULL) + return 0; + + switch (match->type) { case V4L2_CHIP_MATCH_I2C_DRIVER: - return (c != NULL && c->driver != NULL && c->driver->id == match_chip); + if (c->driver == NULL || c->driver->driver.name == NULL) + return 0; + len = strlen(c->driver->driver.name); + /* legacy drivers have a ' suffix, don't try to match that */ + if (len && c->driver->driver.name[len - 1] == '\'') + len--; + return len && !strncmp(c->driver->driver.name, match->name, len); case V4L2_CHIP_MATCH_I2C_ADDR: - return (c != NULL && c->addr == match_chip); + return c->addr == match->addr; default: return 0; } } EXPORT_SYMBOL(v4l2_chip_match_i2c_client); -int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, +int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip, u32 ident, u32 revision) { - if (!v4l2_chip_match_i2c_client(c, chip->match_type, chip->match_chip)) + if (!v4l2_chip_match_i2c_client(c, &chip->match)) return 0; if (chip->ident == V4L2_IDENT_NONE) { chip->ident = ident; diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index d0e1bd3ace6..110376be5d2 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -222,9 +222,9 @@ static int get_microcode32(struct video_code *kp, struct video_code32 __user *up #endif -static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int ret = -ENOIOCTLCMD; + long ret = -ENOIOCTLCMD; if (file->f_op->unlocked_ioctl) ret = file->f_op->unlocked_ioctl(file, cmd, arg); @@ -705,7 +705,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) -static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { union { #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -726,7 +726,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg } karg; void __user *up = compat_ptr(arg); int compatible_arg = 1; - int err = 0; + long err = 0; /* First, convert the command. */ switch (cmd) { @@ -937,9 +937,9 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg return err; } -long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) +long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) { - int ret = -ENOIOCTLCMD; + long ret = -ENOIOCTLCMD; if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl) return ret; @@ -1046,7 +1046,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_TRY_ENCODER_CMD: case VIDIOC_DBG_S_REGISTER: case VIDIOC_DBG_G_REGISTER: - case VIDIOC_G_CHIP_IDENT: + case VIDIOC_DBG_G_CHIP_IDENT: + case VIDIOC_G_CHIP_IDENT_OLD: case VIDIOC_S_HW_FREQ_SEEK: ret = do_video_ioctl(file, cmd, arg); break; @@ -1065,18 +1066,14 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) break; #endif default: - v4l_print_ioctl("compat_ioctl32", cmd); - printk(KERN_CONT "\n"); + printk(KERN_WARNING "compat_ioctl32: " + "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", + _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); break; } return ret; } -#else -long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} +EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); #endif -EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 7ad6711ee32..13f87c22e78 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -31,6 +31,7 @@ #include <media/v4l2-common.h> #include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" @@ -182,7 +183,7 @@ static int v4l2_ioctl(struct inode *inode, struct file *filp, return -ENOTTY; /* Allow ioctl to continue even if the device was unregistered. Things like dequeueing buffers might still be useful. */ - return vdev->fops->ioctl(inode, filp, cmd, arg); + return vdev->fops->ioctl(filp, cmd, arg); } static long v4l2_unlocked_ioctl(struct file *filp, @@ -197,20 +198,6 @@ static long v4l2_unlocked_ioctl(struct file *filp, return vdev->fops->unlocked_ioctl(filp, cmd, arg); } -#ifdef CONFIG_COMPAT -static long v4l2_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct video_device *vdev = video_devdata(filp); - - if (!vdev->fops->compat_ioctl) - return -ENOIOCTLCMD; - /* Allow ioctl to continue even if the device was unregistered. - Things like dequeueing buffers might still be useful. */ - return vdev->fops->compat_ioctl(filp, cmd, arg); -} -#endif - static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) { struct video_device *vdev = video_devdata(filp); @@ -239,7 +226,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) /* and increase the device refcount */ video_get(vdev); mutex_unlock(&videodev_lock); - ret = vdev->fops->open(inode, filp); + ret = vdev->fops->open(filp); /* decrease the refcount in case of an error */ if (ret) video_put(vdev); @@ -250,7 +237,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) static int v4l2_release(struct inode *inode, struct file *filp) { struct video_device *vdev = video_devdata(filp); - int ret = vdev->fops->release(inode, filp); + int ret = vdev->fops->release(filp); /* decrease the refcount unconditionally since the release() return value is ignored. */ @@ -266,7 +253,7 @@ static const struct file_operations v4l2_unlocked_fops = { .mmap = v4l2_mmap, .unlocked_ioctl = v4l2_unlocked_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = v4l2_compat_ioctl, + .compat_ioctl = v4l2_compat_ioctl32, #endif .release = v4l2_release, .poll = v4l2_poll, @@ -281,7 +268,7 @@ static const struct file_operations v4l2_fops = { .mmap = v4l2_mmap, .ioctl = v4l2_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = v4l2_compat_ioctl, + .compat_ioctl = v4l2_compat_ioctl32, #endif .release = v4l2_release, .poll = v4l2_poll, diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index b063381f4b3..52d687b165e 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -266,7 +266,7 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", - [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", + [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", #endif }; @@ -392,14 +392,14 @@ video_fix_command(unsigned int cmd) /* * Obsolete usercopy function - Should be removed soon */ -int +long video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, v4l2_kioctl func) { char sbuf[128]; void *mbuf = NULL; void *parg = NULL; - int err = -EINVAL; + long err = -EINVAL; int is_ext_ctrl; size_t ctrls_size = 0; void __user *user_ptr = NULL; @@ -623,13 +623,13 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) return -EINVAL; } -static int __video_do_ioctl(struct file *file, +static long __video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vfd = video_devdata(file); const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; void *fh = file->private_data; - int ret = -EINVAL; + long ret = -EINVAL; if ((vfd->debug & V4L2_DEBUG_IOCTL) && !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { @@ -1720,7 +1720,7 @@ static int __video_do_ioctl(struct file *file, #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: { - struct v4l2_register *p = arg; + struct v4l2_dbg_register *p = arg; if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; @@ -1730,7 +1730,7 @@ static int __video_do_ioctl(struct file *file, } case VIDIOC_DBG_S_REGISTER: { - struct v4l2_register *p = arg; + struct v4l2_dbg_register *p = arg; if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; @@ -1739,9 +1739,9 @@ static int __video_do_ioctl(struct file *file, break; } #endif - case VIDIOC_G_CHIP_IDENT: + case VIDIOC_DBG_G_CHIP_IDENT: { - struct v4l2_chip_ident *p = arg; + struct v4l2_dbg_chip_ident *p = arg; if (!ops->vidioc_g_chip_ident) break; @@ -1750,6 +1750,11 @@ static int __video_do_ioctl(struct file *file, dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); break; } + case VIDIOC_G_CHIP_IDENT_OLD: + printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n"); + printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n"); + return -EINVAL; + case VIDIOC_S_HW_FREQ_SEEK: { struct v4l2_hw_freq_seek *p = arg; @@ -1845,20 +1850,20 @@ static int __video_do_ioctl(struct file *file, if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { if (ret < 0) { v4l_print_ioctl(vfd->name, cmd); - printk(KERN_CONT " error %d\n", ret); + printk(KERN_CONT " error %ld\n", ret); } } return ret; } -long __video_ioctl2(struct file *file, +long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg) { char sbuf[128]; void *mbuf = NULL; void *parg = NULL; - int err = -EINVAL; + long err = -EINVAL; int is_ext_ctrl; size_t ctrls_size = 0; void __user *user_ptr = NULL; @@ -1944,11 +1949,4 @@ out: kfree(mbuf); return err; } -EXPORT_SYMBOL(__video_ioctl2); - -int video_ioctl2(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return __video_ioctl2(file, cmd, arg); -} EXPORT_SYMBOL(video_ioctl2); diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index e3612f29d0d..fbe9cc0d433 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -37,7 +37,7 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) return v4l2_subdev_call(sd, core, queryctrl, arg); case VIDIOC_LOG_STATUS: return v4l2_subdev_call(sd, core, log_status); - case VIDIOC_G_CHIP_IDENT: + case VIDIOC_DBG_G_CHIP_IDENT: return v4l2_subdev_call(sd, core, g_chip_ident, arg); case VIDIOC_INT_S_STANDBY: return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0); diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index a72a361daad..88bf845a3d5 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -4019,7 +4019,7 @@ out: /* File operations */ -static int vino_open(struct inode *inode, struct file *file) +static int vino_open(struct file *file) { struct vino_channel_settings *vcs = video_drvdata(file); int ret = 0; @@ -4050,7 +4050,7 @@ static int vino_open(struct inode *inode, struct file *file) return ret; } -static int vino_close(struct inode *inode, struct file *file) +static int vino_close(struct file *file) { struct vino_channel_settings *vcs = video_drvdata(file); dprintk("close():\n"); @@ -4237,7 +4237,7 @@ error: return ret; } -static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct vino_channel_settings *vcs = video_drvdata(file); @@ -4343,11 +4343,11 @@ static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int vino_ioctl(struct inode *inode, struct file *file, +static long vino_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct vino_channel_settings *vcs = video_drvdata(file); - int ret; + long ret; if (mutex_lock_interruptible(&vcs->mutex)) return -EINTR; @@ -4364,14 +4364,13 @@ static int vino_ioctl(struct inode *inode, struct file *file, /* __initdata */ static int vino_init_stage; -static const struct file_operations vino_fops = { +static const struct v4l2_file_operations vino_fops = { .owner = THIS_MODULE, .open = vino_open, .release = vino_close, .ioctl = vino_ioctl, .mmap = vino_mmap, .poll = vino_poll, - .llseek = no_llseek, }; static struct video_device v4l_device_template = { diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index e15e48f04be..81d5aa5cf33 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1024,9 +1024,9 @@ static int vidioc_s_ctrl(struct file *file, void *priv, File operations for the device ------------------------------------------------------------------*/ -static int vivi_open(struct inode *inode, struct file *file) +static int vivi_open(struct file *file) { - int minor = iminor(inode); + int minor = video_devdata(file)->minor; struct vivi_dev *dev; struct vivi_fh *fh = NULL; int i; @@ -1127,13 +1127,13 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) return videobuf_poll_stream(file, q, wait); } -static int vivi_close(struct inode *inode, struct file *file) +static int vivi_close(struct file *file) { struct vivi_fh *fh = file->private_data; struct vivi_dev *dev = fh->dev; struct vivi_dmaqueue *vidq = &dev->vidq; - int minor = iminor(inode); + int minor = video_devdata(file)->minor; vivi_stop_thread(vidq); videobuf_stop(&fh->vb_vidq); @@ -1195,16 +1195,14 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma) return ret; } -static const struct file_operations vivi_fops = { +static const struct v4l2_file_operations vivi_fops = { .owner = THIS_MODULE, .open = vivi_open, .release = vivi_close, .read = vivi_read, .poll = vivi_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ - .compat_ioctl = v4l_compat_ioctl32, .mmap = vivi_mmap, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops vivi_ioctl_ops = { diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index f72b859486a..5d73f66d9f5 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -113,7 +113,7 @@ static int vp27smpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; } -static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 56c570c267e..038ff32b01b 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -180,19 +180,19 @@ static int w9966_i2c_wbyte(struct w9966_dev* cam, int data); static int w9966_i2c_rbyte(struct w9966_dev* cam); #endif -static int w9966_v4l_ioctl(struct inode *inode, struct file *file, +static long w9966_v4l_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t w9966_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); -static int w9966_exclusive_open(struct inode *inode, struct file *file) +static int w9966_exclusive_open(struct file *file) { struct w9966_dev *cam = video_drvdata(file); return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; } -static int w9966_exclusive_release(struct inode *inode, struct file *file) +static int w9966_exclusive_release(struct file *file) { struct w9966_dev *cam = video_drvdata(file); @@ -200,16 +200,12 @@ static int w9966_exclusive_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations w9966_fops = { +static const struct v4l2_file_operations w9966_fops = { .owner = THIS_MODULE, .open = w9966_exclusive_open, .release = w9966_exclusive_release, .ioctl = w9966_v4l_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = w9966_v4l_read, - .llseek = no_llseek, }; static struct video_device w9966_template = { .name = W9966_DRIVERNAME, @@ -727,7 +723,7 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data) * Video4linux interfacing */ -static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct w9966_dev *cam = video_drvdata(file); @@ -877,7 +873,7 @@ static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } -static int w9966_v4l_ioctl(struct inode *inode, struct file *file, +static long w9966_v4l_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl); diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 4dfb43bd184..a3997b7d436 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -399,13 +399,13 @@ MODULE_PARM_DESC(specific_debug, ****************************************************************************/ /* Video4linux interface */ -static const struct file_operations w9968cf_fops; -static int w9968cf_open(struct inode*, struct file*); -static int w9968cf_release(struct inode*, struct file*); -static int w9968cf_mmap(struct file*, struct vm_area_struct*); -static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long); -static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*); -static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, +static const struct v4l2_file_operations w9968cf_fops; +static int w9968cf_open(struct file *); +static int w9968cf_release(struct file *); +static int w9968cf_mmap(struct file *, struct vm_area_struct *); +static long w9968cf_ioctl(struct file *, unsigned, unsigned long); +static ssize_t w9968cf_read(struct file *, char __user *, size_t, loff_t *); +static long w9968cf_v4l_ioctl(struct file *, unsigned int, void __user *); /* USB-specific */ @@ -2662,7 +2662,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) * Video4Linux interface * ****************************************************************************/ -static int w9968cf_open(struct inode* inode, struct file* filp) +static int w9968cf_open(struct file *filp) { struct w9968cf_device* cam; int err; @@ -2748,7 +2748,7 @@ deallocate_memory: } -static int w9968cf_release(struct inode* inode, struct file* filp) +static int w9968cf_release(struct file *filp) { struct w9968cf_device* cam; @@ -2885,12 +2885,12 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma) } -static int -w9968cf_ioctl(struct inode* inode, struct file* filp, +static long +w9968cf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct w9968cf_device* cam; - int err; + long err; cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); @@ -2909,15 +2909,15 @@ w9968cf_ioctl(struct inode* inode, struct file* filp, return -EIO; } - err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg); + err = w9968cf_v4l_ioctl(filp, cmd, (void __user *)arg); mutex_unlock(&cam->fileop_mutex); return err; } -static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) +static long w9968cf_v4l_ioctl(struct file *filp, + unsigned int cmd, void __user *arg) { struct w9968cf_device* cam; const char* v4l1_ioctls[] = { @@ -3456,17 +3456,13 @@ ioctl_fail: } -static const struct file_operations w9968cf_fops = { +static const struct v4l2_file_operations w9968cf_fops = { .owner = THIS_MODULE, .open = w9968cf_open, .release = w9968cf_release, .read = w9968cf_read, .ioctl = w9968cf_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .mmap = w9968cf_mmap, - .llseek = no_llseek, }; diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index 12a31e7a5f6..f2864d5cd18 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -233,7 +233,7 @@ static int wm8739_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) return -EINVAL; } -static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index d0220b0ec0b..53fcd42843e 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -130,7 +130,7 @@ static int wm8775_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip) +static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 9d00e605649..96971044fc7 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -649,7 +649,7 @@ static void zc0301_release_resources(struct kref *kref) } -static int zc0301_open(struct inode* inode, struct file* filp) +static int zc0301_open(struct file *filp) { struct zc0301_device* cam; int err = 0; @@ -733,7 +733,7 @@ out: } -static int zc0301_release(struct inode* inode, struct file* filp) +static int zc0301_release(struct file *filp) { struct zc0301_device* cam; @@ -1793,8 +1793,8 @@ zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg) } -static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, - unsigned int cmd, void __user * arg) +static long zc0301_ioctl_v4l2(struct file *filp, + unsigned int cmd, void __user *arg) { struct zc0301_device *cam = video_drvdata(filp); @@ -1888,7 +1888,7 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, } -static int zc0301_ioctl(struct inode* inode, struct file* filp, +static long zc0301_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct zc0301_device *cam = video_drvdata(filp); @@ -1912,7 +1912,7 @@ static int zc0301_ioctl(struct inode* inode, struct file* filp, V4LDBG(3, "zc0301", cmd); - err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); + err = zc0301_ioctl_v4l2(filp, cmd, (void __user *)arg); mutex_unlock(&cam->fileop_mutex); @@ -1920,18 +1920,14 @@ static int zc0301_ioctl(struct inode* inode, struct file* filp, } -static const struct file_operations zc0301_fops = { +static const struct v4l2_file_operations zc0301_fops = { .owner = THIS_MODULE, .open = zc0301_open, .release = zc0301_release, .ioctl = zc0301_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif .read = zc0301_read, .poll = zc0301_poll, .mmap = zc0301_mmap, - .llseek = no_llseek, }; /*****************************************************************************/ diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 00b97d97aea..b58b9dda715 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1197,10 +1197,9 @@ zoran_close_end_session (struct file *file) */ static int -zoran_open (struct inode *inode, - struct file *file) +zoran_open(struct file *file) { - unsigned int minor = iminor(inode); + unsigned int minor = video_devdata(file)->minor; struct zoran *zr = NULL; struct zoran_fh *fh; int i, res, first_open = 0, have_module_locks = 0; @@ -1340,8 +1339,7 @@ open_unlock_and_return: } static int -zoran_close (struct inode *inode, - struct file *file) +zoran_close(struct file *file) { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; @@ -1940,7 +1938,7 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ -static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; @@ -4191,11 +4189,10 @@ static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) } -static int -zoran_ioctl (struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) +static long +zoran_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) { return video_usercopy(file, cmd, arg, zoran_do_ioctl); } @@ -4620,15 +4617,11 @@ zoran_mmap (struct file *file, return 0; } -static const struct file_operations zoran_fops = { +static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, .ioctl = zoran_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index a1d81ed44c7..93023560f32 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -634,7 +634,7 @@ static int zr364xx_vidioc_streamoff(struct file *file, void *priv, /* open the camera */ -static int zr364xx_open(struct inode *inode, struct file *file) +static int zr364xx_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam = video_get_drvdata(vdev); @@ -688,7 +688,7 @@ out: /* release the camera */ -static int zr364xx_release(struct inode *inode, struct file *file) +static int zr364xx_release(struct file *file) { struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam; @@ -761,14 +761,13 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) } -static const struct file_operations zr364xx_fops = { +static const struct v4l2_file_operations zr364xx_fops = { .owner = THIS_MODULE, .open = zr364xx_open, .release = zr364xx_release, .read = zr364xx_read, .mmap = zr364xx_mmap, .ioctl = video_ioctl2, - .llseek = no_llseek, }; static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { @@ -894,7 +893,6 @@ static void zr364xx_disconnect(struct usb_interface *intf) { struct zr364xx_camera *cam = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - dev_set_drvdata(&intf->dev, NULL); dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); if (cam->vdev) video_unregister_device(cam->vdev); diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3d067c35185..45b1f430685 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -145,7 +145,7 @@ struct mmc_blk_request { static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; - u32 blocks; + __be32 blocks; struct mmc_request mrq; struct mmc_command cmd; @@ -204,9 +204,24 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) if (cmd.error || data.error) return (u32)-1; - blocks = ntohl(blocks); + return ntohl(blocks); +} + +static u32 get_card_status(struct mmc_card *card, struct request *req) +{ + struct mmc_command cmd; + int err; - return blocks; + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + if (!mmc_host_is_spi(card->host)) + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + printk(KERN_ERR "%s: error %d sending status comand", + req->rq_disk->disk_name, err); + return cmd.resp[0]; } static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) @@ -214,13 +229,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request brq; - int ret = 1; + int ret = 1, disable_multi = 0; mmc_claim_host(card->host); do { struct mmc_command cmd; - u32 readcmd, writecmd; + u32 readcmd, writecmd, status = 0; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; @@ -236,6 +251,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; brq.data.blocks = req->nr_sectors; + /* + * After a read error, we redo the request one sector at a time + * in order to accurately determine which sectors can be read + * successfully. + */ + if (disable_multi && brq.data.blocks > 1) + brq.data.blocks = 1; + if (brq.data.blocks > 1) { /* SPI multiblock writes terminate using a special * token, not a STOP_TRANSMISSION request. @@ -264,6 +287,25 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.sg = mq->sg; brq.data.sg_len = mmc_queue_map_sg(mq); + /* + * Adjust the sg list so it is the same size as the + * request. + */ + if (brq.data.blocks != req->nr_sectors) { + int i, data_size = brq.data.blocks << 9; + struct scatterlist *sg; + + for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { + data_size -= sg->length; + if (data_size <= 0) { + sg->length += data_size; + i++; + break; + } + } + brq.data.sg_len = i; + } + mmc_queue_bounce_pre(mq); mmc_wait_for_req(card->host, &brq.mrq); @@ -275,19 +317,40 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * until later as we need to wait for the card to leave * programming mode even when things go wrong. */ + if (brq.cmd.error || brq.data.error || brq.stop.error) { + if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { + /* Redo read one sector at a time */ + printk(KERN_WARNING "%s: retrying using single " + "block read\n", req->rq_disk->disk_name); + disable_multi = 1; + continue; + } + status = get_card_status(card, req); + } + if (brq.cmd.error) { - printk(KERN_ERR "%s: error %d sending read/write command\n", - req->rq_disk->disk_name, brq.cmd.error); + printk(KERN_ERR "%s: error %d sending read/write " + "command, response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.cmd.error, + brq.cmd.resp[0], status); } if (brq.data.error) { - printk(KERN_ERR "%s: error %d transferring data\n", - req->rq_disk->disk_name, brq.data.error); + if (brq.data.error == -ETIMEDOUT && brq.mrq.stop) + /* 'Stop' response contains card status */ + status = brq.mrq.stop->resp[0]; + printk(KERN_ERR "%s: error %d transferring data," + " sector %u, nr %u, card status %#x\n", + req->rq_disk->disk_name, brq.data.error, + (unsigned)req->sector, + (unsigned)req->nr_sectors, status); } if (brq.stop.error) { - printk(KERN_ERR "%s: error %d sending stop command\n", - req->rq_disk->disk_name, brq.stop.error); + printk(KERN_ERR "%s: error %d sending stop command, " + "response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.stop.error, + brq.stop.resp[0], status); } if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { @@ -320,8 +383,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) #endif } - if (brq.cmd.error || brq.data.error || brq.stop.error) + if (brq.cmd.error || brq.stop.error || brq.data.error) { + if (rq_data_dir(req) == READ) { + /* + * After an error, we redo I/O one sector at a + * time, so we only reach here after trying to + * read a single sector. + */ + spin_lock_irq(&md->lock); + ret = __blk_end_request(req, -EIO, brq.data.blksz); + spin_unlock_irq(&md->lock); + continue; + } goto cmd_err; + } /* * A block was successfully transferred. @@ -343,25 +418,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * If the card is not SD, we can still ok written sectors * as reported by the controller (which might be less than * the real number of written sectors, but never more). - * - * For reads we just fail the entire chunk as that should - * be safe in all cases. */ - if (rq_data_dir(req) != READ) { - if (mmc_card_sd(card)) { - u32 blocks; + if (mmc_card_sd(card)) { + u32 blocks; - blocks = mmc_sd_num_wr_blocks(card); - if (blocks != (u32)-1) { - spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, blocks << 9); - spin_unlock_irq(&md->lock); - } - } else { + blocks = mmc_sd_num_wr_blocks(card); + if (blocks != (u32)-1) { spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, brq.data.bytes_xfered); + ret = __blk_end_request(req, 0, blocks << 9); spin_unlock_irq(&md->lock); } + } else { + spin_lock_irq(&md->lock); + ret = __blk_end_request(req, 0, brq.data.bytes_xfered); + spin_unlock_irq(&md->lock); } mmc_release_host(card->host); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f7284b905eb..df6ce4a06cf 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -20,6 +20,7 @@ #include <linux/err.h> #include <linux/leds.h> #include <linux/scatterlist.h> +#include <linux/log2.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -448,6 +449,80 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) mmc_set_ios(host); } +/** + * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number + * @vdd: voltage (mV) + * @low_bits: prefer low bits in boundary cases + * + * This function returns the OCR bit number according to the provided @vdd + * value. If conversion is not possible a negative errno value returned. + * + * Depending on the @low_bits flag the function prefers low or high OCR bits + * on boundary voltages. For example, + * with @low_bits = true, 3300 mV translates to ilog2(MMC_VDD_32_33); + * with @low_bits = false, 3300 mV translates to ilog2(MMC_VDD_33_34); + * + * Any value in the [1951:1999] range translates to the ilog2(MMC_VDD_20_21). + */ +static int mmc_vdd_to_ocrbitnum(int vdd, bool low_bits) +{ + const int max_bit = ilog2(MMC_VDD_35_36); + int bit; + + if (vdd < 1650 || vdd > 3600) + return -EINVAL; + + if (vdd >= 1650 && vdd <= 1950) + return ilog2(MMC_VDD_165_195); + + if (low_bits) + vdd -= 1; + + /* Base 2000 mV, step 100 mV, bit's base 8. */ + bit = (vdd - 2000) / 100 + 8; + if (bit > max_bit) + return max_bit; + return bit; +} + +/** + * mmc_vddrange_to_ocrmask - Convert a voltage range to the OCR mask + * @vdd_min: minimum voltage value (mV) + * @vdd_max: maximum voltage value (mV) + * + * This function returns the OCR mask bits according to the provided @vdd_min + * and @vdd_max values. If conversion is not possible the function returns 0. + * + * Notes wrt boundary cases: + * This function sets the OCR bits for all boundary voltages, for example + * [3300:3400] range is translated to MMC_VDD_32_33 | MMC_VDD_33_34 | + * MMC_VDD_34_35 mask. + */ +u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) +{ + u32 mask = 0; + + if (vdd_max < vdd_min) + return 0; + + /* Prefer high bits for the boundary vdd_max values. */ + vdd_max = mmc_vdd_to_ocrbitnum(vdd_max, false); + if (vdd_max < 0) + return 0; + + /* Prefer low bits for the boundary vdd_min values. */ + vdd_min = mmc_vdd_to_ocrbitnum(vdd_min, true); + if (vdd_min < 0) + return 0; + + /* Fill the mask, from max bit to min bit. */ + while (vdd_max >= vdd_min) + mask |= 1 << vdd_max--; + + return mask; +} +EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); + /* * Mask off any voltages we don't support and select * the lowest voltage @@ -467,6 +542,8 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) host->ios.vdd = bit; mmc_set_ios(host); } else { + pr_warning("%s: host doesn't support card's voltages\n", + mmc_hostname(host)); ocr = 0; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index fdd7c760be8..c232d11a7ed 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -434,13 +434,24 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && - (host->caps & MMC_CAP_4_BIT_DATA)) { + (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { + unsigned ext_csd_bit, bus_width; + + if (host->caps & MMC_CAP_8_BIT_DATA) { + ext_csd_bit = EXT_CSD_BUS_WIDTH_8; + bus_width = MMC_BUS_WIDTH_8; + } else { + ext_csd_bit = EXT_CSD_BUS_WIDTH_4; + bus_width = MMC_BUS_WIDTH_4; + } + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); + EXT_CSD_BUS_WIDTH, ext_csd_bit); + if (err) goto free_card; - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + mmc_set_bus_width(card->host, bus_width); } if (!oldcard) @@ -624,4 +635,3 @@ err: return err; } - diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c794cc5ce44..f4853288bbb 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -19,6 +19,9 @@ obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o +ifeq ($(CONFIG_OF),y) +obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o +endif obj-$(CONFIG_MMC_S3C) += s3cmci.o obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 1f8b5b36222..e556d42cc45 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -1088,6 +1088,8 @@ static int __init at91_mci_probe(struct platform_device *pdev) goto fail0; } + setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); /* @@ -1101,8 +1103,6 @@ static int __init at91_mci_probe(struct platform_device *pdev) mmc_add_host(mmc); - setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); - /* * monitor card insertion/removal if we can */ diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index ad00e163231..87e211df68a 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1285,7 +1285,7 @@ static int mmc_spi_probe(struct spi_device *spi) /* Platform data is used to hook up things like card sensing * and power switching gpios. */ - host->pdata = spi->dev.platform_data; + host->pdata = mmc_spi_get_pdata(spi); if (host->pdata) mmc->ocr_avail = host->pdata->ocr_mask; if (!mmc->ocr_avail) { @@ -1368,6 +1368,7 @@ fail_glue_init: fail_nobuf1: mmc_free_host(mmc); + mmc_spi_put_pdata(spi); dev_set_drvdata(&spi->dev, NULL); nomem: @@ -1402,6 +1403,7 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) spi->max_speed_hz = mmc->f_max; mmc_free_host(mmc); + mmc_spi_put_pdata(spi); dev_set_drvdata(&spi->dev, NULL); } return 0; diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c new file mode 100644 index 00000000000..fb2921f8099 --- /dev/null +++ b/drivers/mmc/host/of_mmc_spi.c @@ -0,0 +1,149 @@ +/* + * OpenFirmware bindings for the MMC-over-SPI driver + * + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.com> + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/spi/spi.h> +#include <linux/spi/mmc_spi.h> +#include <linux/mmc/core.h> +#include <linux/mmc/host.h> + +enum { + CD_GPIO = 0, + WP_GPIO, + NUM_GPIOS, +}; + +struct of_mmc_spi { + int gpios[NUM_GPIOS]; + bool alow_gpios[NUM_GPIOS]; + struct mmc_spi_platform_data pdata; +}; + +static struct of_mmc_spi *to_of_mmc_spi(struct device *dev) +{ + return container_of(dev->platform_data, struct of_mmc_spi, pdata); +} + +static int of_mmc_spi_read_gpio(struct device *dev, int gpio_num) +{ + struct of_mmc_spi *oms = to_of_mmc_spi(dev); + bool active_low = oms->alow_gpios[gpio_num]; + bool value = gpio_get_value(oms->gpios[gpio_num]); + + return active_low ^ value; +} + +static int of_mmc_spi_get_cd(struct device *dev) +{ + return of_mmc_spi_read_gpio(dev, CD_GPIO); +} + +static int of_mmc_spi_get_ro(struct device *dev) +{ + return of_mmc_spi_read_gpio(dev, WP_GPIO); +} + +struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct of_mmc_spi *oms; + const u32 *voltage_ranges; + int num_ranges; + int i; + int ret = -EINVAL; + + if (dev->platform_data || !np) + return dev->platform_data; + + oms = kzalloc(sizeof(*oms), GFP_KERNEL); + if (!oms) + return NULL; + + voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges); + num_ranges = num_ranges / sizeof(*voltage_ranges) / 2; + if (!voltage_ranges || !num_ranges) { + dev_err(dev, "OF: voltage-ranges unspecified\n"); + goto err_ocr; + } + + for (i = 0; i < num_ranges; i++) { + const int j = i * 2; + u32 mask; + + mask = mmc_vddrange_to_ocrmask(voltage_ranges[j], + voltage_ranges[j + 1]); + if (!mask) { + ret = -EINVAL; + dev_err(dev, "OF: voltage-range #%d is invalid\n", i); + goto err_ocr; + } + oms->pdata.ocr_mask |= mask; + } + + for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { + enum of_gpio_flags gpio_flags; + + oms->gpios[i] = of_get_gpio_flags(np, i, &gpio_flags); + if (!gpio_is_valid(oms->gpios[i])) + continue; + + ret = gpio_request(oms->gpios[i], dev->bus_id); + if (ret < 0) { + oms->gpios[i] = -EINVAL; + continue; + } + + if (gpio_flags & OF_GPIO_ACTIVE_LOW) + oms->alow_gpios[i] = true; + } + + if (gpio_is_valid(oms->gpios[CD_GPIO])) + oms->pdata.get_cd = of_mmc_spi_get_cd; + if (gpio_is_valid(oms->gpios[WP_GPIO])) + oms->pdata.get_ro = of_mmc_spi_get_ro; + + /* We don't support interrupts yet, let's poll. */ + oms->pdata.caps |= MMC_CAP_NEEDS_POLL; + + dev->platform_data = &oms->pdata; + return dev->platform_data; +err_ocr: + kfree(oms); + return NULL; +} +EXPORT_SYMBOL(mmc_spi_get_pdata); + +void mmc_spi_put_pdata(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct of_mmc_spi *oms = to_of_mmc_spi(dev); + int i; + + if (!dev->platform_data || !np) + return; + + for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) { + if (gpio_is_valid(oms->gpios[i])) + gpio_free(oms->gpios[i]); + } + kfree(oms); + dev->platform_data = NULL; +} +EXPORT_SYMBOL(mmc_spi_put_pdata); diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index f88cc740635..3c5483b75da 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) return 0; DCSR(host->dma) = 0; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); if (stat & STAT_READ_TIME_OUT) diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c index a16d7609e4e..be9e7b32b34 100644 --- a/drivers/mmc/host/ricoh_mmc.c +++ b/drivers/mmc/host/ricoh_mmc.c @@ -11,9 +11,10 @@ /* * This is a conceptually ridiculous driver, but it is required by the way - * the Ricoh multi-function R5C832 works. This chip implements firewire - * and four different memory card controllers. Two of those controllers are - * an SDHCI controller and a proprietary MMC controller. The linux SDHCI + * the Ricoh multi-function chips (R5CXXX) work. These chips implement + * the four main memory card controllers (SD, MMC, MS, xD) and one or both + * of cardbus or firewire. It happens that they implement SD and MMC + * support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller. @@ -21,8 +22,10 @@ * a detection event occurs immediately, even if the MMC card is already * in the reader. * - * The relevant registers live on the firewire function, so this is unavoidably - * ugly. Such is life. + * It seems to be the case that the relevant PCI registers to deactivate the + * MMC controller live on PCI function 0, which might be the cardbus controller + * or the firewire controller, depending on the particular chip in question. As + * such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include <linux/pci.h> @@ -143,6 +146,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -160,6 +164,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -172,7 +177,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n"); return -ENODEV; } diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 9bd7026b002..f07255cb17e 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -545,7 +545,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( } addr = pci_resource_start(pdev, bar); - host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar)); + host->ioaddr = pci_ioremap_bar(pdev, bar); if (!host->ioaddr) { dev_err(&pdev->dev, "failed to remap registers\n"); goto release; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4d010a984be..6b2d1f99af6 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -30,6 +30,11 @@ #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) +#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ + defined(CONFIG_MMC_SDHCI_MODULE)) +#define SDHCI_USE_LEDS_CLASS +#endif + static unsigned int debug_quirks = 0; static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); @@ -149,7 +154,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host) writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); } -#ifdef CONFIG_LEDS_CLASS +#ifdef SDHCI_USE_LEDS_CLASS static void sdhci_led_control(struct led_classdev *led, enum led_brightness brightness) { @@ -994,7 +999,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(host->mrq != NULL); -#ifndef CONFIG_LEDS_CLASS +#ifndef SDHCI_USE_LEDS_CLASS sdhci_activate_led(host); #endif @@ -1201,7 +1206,7 @@ static void sdhci_tasklet_finish(unsigned long param) host->cmd = NULL; host->data = NULL; -#ifndef CONFIG_LEDS_CLASS +#ifndef SDHCI_USE_LEDS_CLASS sdhci_deactivate_led(host); #endif @@ -1717,7 +1722,7 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_dumpregs(host); #endif -#ifdef CONFIG_LEDS_CLASS +#ifdef SDHCI_USE_LEDS_CLASS host->led.name = mmc_hostname(mmc); host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); @@ -1739,7 +1744,7 @@ int sdhci_add_host(struct sdhci_host *host) return 0; -#ifdef CONFIG_LEDS_CLASS +#ifdef SDHCI_USE_LEDS_CLASS reset: sdhci_reset(host, SDHCI_RESET_ALL); free_irq(host->irq, host); @@ -1775,7 +1780,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) mmc_remove_host(host->mmc); -#ifdef CONFIG_LEDS_CLASS +#ifdef SDHCI_USE_LEDS_CLASS led_classdev_unregister(&host->led); #endif diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 31f4b1528e7..3efba236394 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -220,7 +220,7 @@ struct sdhci_host { struct mmc_host *mmc; /* MMC structure */ u64 dma_mask; /* custom DMA mask */ -#ifdef CONFIG_LEDS_CLASS +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) struct led_classdev led; /* LED control */ #endif diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 1df44d966bd..cb41e9c3ac0 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -82,6 +82,8 @@ static struct pcmcia_device_id pcmcia_ids[] = { /* vendor and device strings followed by their crc32 hashes */ PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed, 0xc3901202), + PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay Controller", 0xd9f522ed, + 0xace80909), PCMCIA_DEVICE_NULL, }; @@ -463,7 +465,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev, err: if (iobase) - iounmap(iobase); + pci_iounmap(pci_dev, iobase); if (mmc) mmc_free_host(mmc); diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 95430b81ec1..6a7a6190483 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -224,7 +224,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) { void __iomem *ctl = host->ctl; struct mmc_data *data = host->data; - struct mmc_command *stop = data->stop; + struct mmc_command *stop; host->data = NULL; @@ -232,6 +232,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) pr_debug("Spurious data end IRQ\n"); return; } + stop = data->stop; /* FIXME - return correct transfer count on errors */ if (!data->error) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index c7630a22831..ba0bd3d5775 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -815,19 +815,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_free; + err = -ENOMEM; ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; ubi->peb_buf2 = vmalloc(ubi->peb_size); if (!ubi->peb_buf2) - goto out_free; + goto out_free; #ifdef CONFIG_MTD_UBI_DEBUG mutex_init(&ubi->dbg_buf_mutex); ubi->dbg_peb_buf = vmalloc(ubi->peb_size); if (!ubi->dbg_peb_buf) - goto out_free; + goto out_free; #endif err = attach_by_scanning(ubi); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index b30a0b83d7f..98cf31ed081 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -721,7 +721,8 @@ static int rename_volumes(struct ubi_device *ubi, * It seems we need to remove volume with name @re->new_name, * if it exists. */ - desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, UBI_EXCLUSIVE); + desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, + UBI_EXCLUSIVE); if (IS_ERR(desc)) { err = PTR_ERR(desc); if (err == -ENODEV) diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 78e914d23ec..13777e5beac 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -27,11 +27,11 @@ #define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) #define ubi_assert(expr) do { \ - if (unlikely(!(expr))) { \ - printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ - __func__, __LINE__, current->pid); \ - ubi_dbg_dump_stack(); \ - } \ + if (unlikely(!(expr))) { \ + printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ + __func__, __LINE__, current->pid); \ + ubi_dbg_dump_stack(); \ + } \ } while (0) #define dbg_msg(fmt, ...) \ diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index d8966bae0e0..048a606cebd 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, if (!vid_hdr) return -ENOMEM; - mutex_lock(&ubi->buf_mutex); - retry: new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); if (new_pnum < 0) { - mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return new_pnum; } @@ -529,20 +526,23 @@ retry: goto write_error; data_size = offset + len; + mutex_lock(&ubi->buf_mutex); memset(ubi->peb_buf1 + offset, 0xFF, len); /* Read everything before the area where the write failure happened */ if (offset > 0) { err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) - goto out_put; + goto out_unlock; } memcpy(ubi->peb_buf1 + offset, buf, len); err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); - if (err) + if (err) { + mutex_unlock(&ubi->buf_mutex); goto write_error; + } mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); @@ -553,8 +553,9 @@ retry: ubi_msg("data was successfully recovered"); return 0; -out_put: +out_unlock: mutex_unlock(&ubi->buf_mutex); +out_put: ubi_wl_put_peb(ubi, new_pnum, 1); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -567,7 +568,6 @@ write_error: ubi_warn("failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { - mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return err; } @@ -949,10 +949,14 @@ write_error: * This function copies logical eraseblock from physical eraseblock @from to * physical eraseblock @to. The @vid_hdr buffer may be changed by this * function. Returns: - * o %0 in case of success; - * o %1 if the operation was canceled and should be tried later (e.g., - * because a bit-flip was detected at the target PEB); - * o %2 if the volume is being deleted and this LEB should not be moved. + * o %0 in case of success; + * o %1 if the operation was canceled because the volume is being deleted + * or because the PEB was put meanwhile; + * o %2 if the operation was canceled because there was a write error to the + * target PEB; + * o %-EAGAIN if the operation was canceled because a bit-flip was detected + * in the target PEB; + * o a negative error code in case of failure. */ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr) @@ -978,7 +982,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* * Note, we may race with volume deletion, which means that the volume * this logical eraseblock belongs to might be being deleted. Since the - * volume deletion unmaps all the volume's logical eraseblocks, it will + * volume deletion un-maps all the volume's logical eraseblocks, it will * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. */ vol = ubi->volumes[idx]; @@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* No need to do further work, cancel */ dbg_eba("volume %d is being removed, cancel", vol_id); spin_unlock(&ubi->volumes_lock); - return 2; + return 1; } spin_unlock(&ubi->volumes_lock); @@ -1023,7 +1027,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* * OK, now the LEB is locked and we can safely start moving it. Since - * this function utilizes thie @ubi->peb1_buf buffer which is shared + * this function utilizes the @ubi->peb1_buf buffer which is shared * with some other functions, so lock the buffer by taking the * @ubi->buf_mutex. */ @@ -1068,8 +1072,11 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); - if (err) + if (err) { + if (err == -EIO) + err = 2; goto out_unlock_buf; + } cond_resched(); @@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, if (err != UBI_IO_BITFLIPS) ubi_warn("cannot read VID header back from PEB %d", to); else - err = 1; + err = -EAGAIN; goto out_unlock_buf; } if (data_size > 0) { err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); - if (err) + if (err) { + if (err == -EIO) + err = 2; goto out_unlock_buf; + } cond_resched(); @@ -1101,15 +1111,16 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ubi_warn("cannot read data back from PEB %d", to); else - err = 1; + err = -EAGAIN; goto out_unlock_buf; } cond_resched(); if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { - ubi_warn("read data back from PEB %d - it is different", - to); + ubi_warn("read data back from PEB %d and it is " + "different", to); + err = -EINVAL; goto out_unlock_buf; } } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 2fb64be44f1..a74118c0574 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -637,8 +637,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, dbg_io("read EC header from PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); - if (UBI_IO_DEBUG) - verbose = 1; err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); if (err) { @@ -685,6 +683,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (verbose) ubi_warn("no EC header found at PEB %d, " "only 0xFF bytes", pnum); + else if (UBI_IO_DEBUG) + dbg_msg("no EC header found at PEB %d, " + "only 0xFF bytes", pnum); return UBI_IO_PEB_EMPTY; } @@ -696,7 +697,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ubi_warn("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_EC_HDR_MAGIC); ubi_dbg_dump_ec_hdr(ec_hdr); - } + } else if (UBI_IO_DEBUG) + dbg_msg("bad magic number at PEB %d: %08x instead of " + "%08x", pnum, magic, UBI_EC_HDR_MAGIC); return UBI_IO_BAD_EC_HDR; } @@ -708,7 +711,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ubi_warn("bad EC header CRC at PEB %d, calculated " "%#08x, read %#08x", pnum, crc, hdr_crc); ubi_dbg_dump_ec_hdr(ec_hdr); - } + } else if (UBI_IO_DEBUG) + dbg_msg("bad EC header CRC at PEB %d, calculated " + "%#08x, read %#08x", pnum, crc, hdr_crc); return UBI_IO_BAD_EC_HDR; } @@ -912,8 +917,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, dbg_io("read VID header from PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); - if (UBI_IO_DEBUG) - verbose = 1; p = (char *)vid_hdr - ubi->vid_hdr_shift; err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, @@ -960,6 +963,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (verbose) ubi_warn("no VID header found at PEB %d, " "only 0xFF bytes", pnum); + else if (UBI_IO_DEBUG) + dbg_msg("no VID header found at PEB %d, " + "only 0xFF bytes", pnum); return UBI_IO_PEB_FREE; } @@ -971,7 +977,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ubi_warn("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_VID_HDR_MAGIC); ubi_dbg_dump_vid_hdr(vid_hdr); - } + } else if (UBI_IO_DEBUG) + dbg_msg("bad magic number at PEB %d: %08x instead of " + "%08x", pnum, magic, UBI_VID_HDR_MAGIC); return UBI_IO_BAD_VID_HDR; } @@ -983,7 +991,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ubi_warn("bad CRC at PEB %d, calculated %#08x, " "read %#08x", pnum, crc, hdr_crc); ubi_dbg_dump_vid_hdr(vid_hdr); - } + } else if (UBI_IO_DEBUG) + dbg_msg("bad CRC at PEB %d, calculated %#08x, " + "read %#08x", pnum, crc, hdr_crc); return UBI_IO_BAD_VID_HDR; } @@ -1024,7 +1034,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, err = paranoid_check_peb_ec_hdr(ubi, pnum); if (err) - return err > 0 ? -EINVAL: err; + return err > 0 ? -EINVAL : err; vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); vid_hdr->version = UBI_VERSION; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 1c3fa18c26a..4a8ec485c91 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -74,6 +74,13 @@ #define UBI_IO_RETRIES 3 /* + * Length of the protection queue. The length is effectively equivalent to the + * number of (global) erase cycles PEBs are protected from the wear-leveling + * worker. + */ +#define UBI_PROT_QUEUE_LEN 10 + +/* * Error codes returned by the I/O sub-system. * * UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only @@ -95,7 +102,8 @@ enum { /** * struct ubi_wl_entry - wear-leveling entry. - * @rb: link in the corresponding RB-tree + * @u.rb: link in the corresponding (free/used) RB-tree + * @u.list: link in the protection queue * @ec: erase counter * @pnum: physical eraseblock number * @@ -104,7 +112,10 @@ enum { * RB-trees. See WL sub-system for details. */ struct ubi_wl_entry { - struct rb_node rb; + union { + struct rb_node rb; + struct list_head list; + } u; int ec; int pnum; }; @@ -288,7 +299,7 @@ struct ubi_wl_entry; * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling * * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end - * of UBI ititializetion + * of UBI initialization * @vtbl_slots: how many slots are available in the volume table * @vtbl_size: size of the volume table in bytes * @vtbl: in-RAM volume table copy @@ -306,18 +317,17 @@ struct ubi_wl_entry; * @used: RB-tree of used physical eraseblocks * @free: RB-tree of free physical eraseblocks * @scrub: RB-tree of physical eraseblocks which need scrubbing - * @prot: protection trees - * @prot.pnum: protection tree indexed by physical eraseblock numbers - * @prot.aec: protection tree indexed by absolute erase counter value - * @wl_lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from, - * @move_to, @move_to_put @erase_pending, @wl_scheduled, and @works - * fields + * @pq: protection queue (contain physical eraseblocks which are temporarily + * protected from the wear-leveling worker) + * @pq_head: protection queue head + * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, + * @move_to, @move_to_put @erase_pending, @wl_scheduled and @works + * fields * @move_mutex: serializes eraseblock moves - * @work_sem: sycnhronizes the WL worker with use tasks + * @work_sem: synchronizes the WL worker with use tasks * @wl_scheduled: non-zero if the wear-leveling was scheduled * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any * physical eraseblock - * @abs_ec: absolute erase counter * @move_from: physical eraseblock from where the data is being moved * @move_to: physical eraseblock where the data is being moved to * @move_to_put: if the "to" PEB was put @@ -351,11 +361,11 @@ struct ubi_wl_entry; * * @peb_buf1: a buffer of PEB size used for different purposes * @peb_buf2: another buffer of PEB size used for different purposes - * @buf_mutex: proptects @peb_buf1 and @peb_buf2 + * @buf_mutex: protects @peb_buf1 and @peb_buf2 * @ckvol_mutex: serializes static volume checking when opening - * @mult_mutex: serializes operations on multiple volumes, like re-nameing + * @mult_mutex: serializes operations on multiple volumes, like re-naming * @dbg_peb_buf: buffer of PEB size used for debugging - * @dbg_buf_mutex: proptects @dbg_peb_buf + * @dbg_buf_mutex: protects @dbg_peb_buf */ struct ubi_device { struct cdev cdev; @@ -392,16 +402,13 @@ struct ubi_device { struct rb_root used; struct rb_root free; struct rb_root scrub; - struct { - struct rb_root pnum; - struct rb_root aec; - } prot; + struct list_head pq[UBI_PROT_QUEUE_LEN]; + int pq_head; spinlock_t wl_lock; struct mutex move_mutex; struct rw_semaphore work_sem; int wl_scheduled; struct ubi_wl_entry **lookuptbl; - unsigned long long abs_ec; struct ubi_wl_entry *move_from; struct ubi_wl_entry *move_to; int move_to_put; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index dcb6dac1dc5..14901cb82c1 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -22,7 +22,7 @@ * UBI wear-leveling sub-system. * * This sub-system is responsible for wear-leveling. It works in terms of - * physical* eraseblocks and erase counters and knows nothing about logical + * physical eraseblocks and erase counters and knows nothing about logical * eraseblocks, volumes, etc. From this sub-system's perspective all physical * eraseblocks are of two types - used and free. Used physical eraseblocks are * those that were "get" by the 'ubi_wl_get_peb()' function, and free physical @@ -55,8 +55,39 @@ * * As it was said, for the UBI sub-system all physical eraseblocks are either * "free" or "used". Free eraseblock are kept in the @wl->free RB-tree, while - * used eraseblocks are kept in a set of different RB-trees: @wl->used, - * @wl->prot.pnum, @wl->prot.aec, and @wl->scrub. + * used eraseblocks are kept in @wl->used or @wl->scrub RB-trees, or + * (temporarily) in the @wl->pq queue. + * + * When the WL sub-system returns a physical eraseblock, the physical + * eraseblock is protected from being moved for some "time". For this reason, + * the physical eraseblock is not directly moved from the @wl->free tree to the + * @wl->used tree. There is a protection queue in between where this + * physical eraseblock is temporarily stored (@wl->pq). + * + * All this protection stuff is needed because: + * o we don't want to move physical eraseblocks just after we have given them + * to the user; instead, we first want to let users fill them up with data; + * + * o there is a chance that the user will put the physical eraseblock very + * soon, so it makes sense not to move it for some time, but wait; this is + * especially important in case of "short term" physical eraseblocks. + * + * Physical eraseblocks stay protected only for limited time. But the "time" is + * measured in erase cycles in this case. This is implemented with help of the + * protection queue. Eraseblocks are put to the tail of this queue when they + * are returned by the 'ubi_wl_get_peb()', and eraseblocks are removed from the + * head of the queue on each erase operation (for any eraseblock). So the + * length of the queue defines how may (global) erase cycles PEBs are protected. + * + * To put it differently, each physical eraseblock has 2 main states: free and + * used. The former state corresponds to the @wl->free tree. The latter state + * is split up on several sub-states: + * o the WL movement is allowed (@wl->used tree); + * o the WL movement is temporarily prohibited (@wl->pq queue); + * o scrubbing is needed (@wl->scrub tree). + * + * Depending on the sub-state, wear-leveling entries of the used physical + * eraseblocks may be kept in one of those structures. * * Note, in this implementation, we keep a small in-RAM object for each physical * eraseblock. This is surely not a scalable solution. But it appears to be good @@ -70,9 +101,6 @@ * target PEB, we pick a PEB with the highest EC if our PEB is "old" and we * pick target PEB with an average EC if our PEB is not very "old". This is a * room for future re-works of the WL sub-system. - * - * Note: the stuff with protection trees looks too complex and is difficult to - * understand. Should be fixed. */ #include <linux/slab.h> @@ -85,14 +113,6 @@ #define WL_RESERVED_PEBS 1 /* - * How many erase cycles are short term, unknown, and long term physical - * eraseblocks protected. - */ -#define ST_PROTECTION 16 -#define U_PROTECTION 10 -#define LT_PROTECTION 4 - -/* * Maximum difference between two erase counters. If this threshold is * exceeded, the WL sub-system starts moving data from used physical * eraseblocks with low erase counter to free physical eraseblocks with high @@ -120,64 +140,9 @@ #define WL_MAX_FAILURES 32 /** - * struct ubi_wl_prot_entry - PEB protection entry. - * @rb_pnum: link in the @wl->prot.pnum RB-tree - * @rb_aec: link in the @wl->prot.aec RB-tree - * @abs_ec: the absolute erase counter value when the protection ends - * @e: the wear-leveling entry of the physical eraseblock under protection - * - * When the WL sub-system returns a physical eraseblock, the physical - * eraseblock is protected from being moved for some "time". For this reason, - * the physical eraseblock is not directly moved from the @wl->free tree to the - * @wl->used tree. There is one more tree in between where this physical - * eraseblock is temporarily stored (@wl->prot). - * - * All this protection stuff is needed because: - * o we don't want to move physical eraseblocks just after we have given them - * to the user; instead, we first want to let users fill them up with data; - * - * o there is a chance that the user will put the physical eraseblock very - * soon, so it makes sense not to move it for some time, but wait; this is - * especially important in case of "short term" physical eraseblocks. - * - * Physical eraseblocks stay protected only for limited time. But the "time" is - * measured in erase cycles in this case. This is implemented with help of the - * absolute erase counter (@wl->abs_ec). When it reaches certain value, the - * physical eraseblocks are moved from the protection trees (@wl->prot.*) to - * the @wl->used tree. - * - * Protected physical eraseblocks are searched by physical eraseblock number - * (when they are put) and by the absolute erase counter (to check if it is - * time to move them to the @wl->used tree). So there are actually 2 RB-trees - * storing the protected physical eraseblocks: @wl->prot.pnum and - * @wl->prot.aec. They are referred to as the "protection" trees. The - * first one is indexed by the physical eraseblock number. The second one is - * indexed by the absolute erase counter. Both trees store - * &struct ubi_wl_prot_entry objects. - * - * Each physical eraseblock has 2 main states: free and used. The former state - * corresponds to the @wl->free tree. The latter state is split up on several - * sub-states: - * o the WL movement is allowed (@wl->used tree); - * o the WL movement is temporarily prohibited (@wl->prot.pnum and - * @wl->prot.aec trees); - * o scrubbing is needed (@wl->scrub tree). - * - * Depending on the sub-state, wear-leveling entries of the used physical - * eraseblocks may be kept in one of those trees. - */ -struct ubi_wl_prot_entry { - struct rb_node rb_pnum; - struct rb_node rb_aec; - unsigned long long abs_ec; - struct ubi_wl_entry *e; -}; - -/** * struct ubi_work - UBI work description data structure. * @list: a link in the list of pending works * @func: worker function - * @priv: private data of the worker function * @e: physical eraseblock to erase * @torture: if the physical eraseblock has to be tortured * @@ -198,9 +163,11 @@ struct ubi_work { static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root); +static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e); #else #define paranoid_check_ec(ubi, pnum, ec) 0 #define paranoid_check_in_wl_tree(e, root) +#define paranoid_check_in_pq(ubi, e) 0 #endif /** @@ -220,7 +187,7 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) struct ubi_wl_entry *e1; parent = *p; - e1 = rb_entry(parent, struct ubi_wl_entry, rb); + e1 = rb_entry(parent, struct ubi_wl_entry, u.rb); if (e->ec < e1->ec) p = &(*p)->rb_left; @@ -235,8 +202,8 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) } } - rb_link_node(&e->rb, parent, p); - rb_insert_color(&e->rb, root); + rb_link_node(&e->u.rb, parent, p); + rb_insert_color(&e->u.rb, root); } /** @@ -331,7 +298,7 @@ static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root) while (p) { struct ubi_wl_entry *e1; - e1 = rb_entry(p, struct ubi_wl_entry, rb); + e1 = rb_entry(p, struct ubi_wl_entry, u.rb); if (e->pnum == e1->pnum) { ubi_assert(e == e1); @@ -355,50 +322,24 @@ static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root) } /** - * prot_tree_add - add physical eraseblock to protection trees. + * prot_queue_add - add physical eraseblock to the protection queue. * @ubi: UBI device description object * @e: the physical eraseblock to add - * @pe: protection entry object to use - * @abs_ec: absolute erase counter value when this physical eraseblock has - * to be removed from the protection trees. * - * @wl->lock has to be locked. + * This function adds @e to the tail of the protection queue @ubi->pq, where + * @e will stay for %UBI_PROT_QUEUE_LEN erase operations and will be + * temporarily protected from the wear-leveling worker. Note, @wl->lock has to + * be locked. */ -static void prot_tree_add(struct ubi_device *ubi, struct ubi_wl_entry *e, - struct ubi_wl_prot_entry *pe, int abs_ec) +static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e) { - struct rb_node **p, *parent = NULL; - struct ubi_wl_prot_entry *pe1; - - pe->e = e; - pe->abs_ec = ubi->abs_ec + abs_ec; - - p = &ubi->prot.pnum.rb_node; - while (*p) { - parent = *p; - pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_pnum); - - if (e->pnum < pe1->e->pnum) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - rb_link_node(&pe->rb_pnum, parent, p); - rb_insert_color(&pe->rb_pnum, &ubi->prot.pnum); - - p = &ubi->prot.aec.rb_node; - parent = NULL; - while (*p) { - parent = *p; - pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_aec); + int pq_tail = ubi->pq_head - 1; - if (pe->abs_ec < pe1->abs_ec) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - rb_link_node(&pe->rb_aec, parent, p); - rb_insert_color(&pe->rb_aec, &ubi->prot.aec); + if (pq_tail < 0) + pq_tail = UBI_PROT_QUEUE_LEN - 1; + ubi_assert(pq_tail >= 0 && pq_tail < UBI_PROT_QUEUE_LEN); + list_add_tail(&e->u.list, &ubi->pq[pq_tail]); + dbg_wl("added PEB %d EC %d to the protection queue", e->pnum, e->ec); } /** @@ -414,14 +355,14 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) struct rb_node *p; struct ubi_wl_entry *e; - e = rb_entry(rb_first(root), struct ubi_wl_entry, rb); + e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); max += e->ec; p = root->rb_node; while (p) { struct ubi_wl_entry *e1; - e1 = rb_entry(p, struct ubi_wl_entry, rb); + e1 = rb_entry(p, struct ubi_wl_entry, u.rb); if (e1->ec >= max) p = p->rb_left; else { @@ -443,17 +384,12 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) */ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) { - int err, protect, medium_ec; + int err, medium_ec; struct ubi_wl_entry *e, *first, *last; - struct ubi_wl_prot_entry *pe; ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || dtype == UBI_UNKNOWN); - pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); - if (!pe) - return -ENOMEM; - retry: spin_lock(&ubi->wl_lock); if (!ubi->free.rb_node) { @@ -461,16 +397,13 @@ retry: ubi_assert(list_empty(&ubi->works)); ubi_err("no free eraseblocks"); spin_unlock(&ubi->wl_lock); - kfree(pe); return -ENOSPC; } spin_unlock(&ubi->wl_lock); err = produce_free_peb(ubi); - if (err < 0) { - kfree(pe); + if (err < 0) return err; - } goto retry; } @@ -483,7 +416,6 @@ retry: * %WL_FREE_MAX_DIFF. */ e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); - protect = LT_PROTECTION; break; case UBI_UNKNOWN: /* @@ -492,81 +424,63 @@ retry: * eraseblock with erase counter greater or equivalent than the * lowest erase counter plus %WL_FREE_MAX_DIFF. */ - first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); - last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, rb); + first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, + u.rb); + last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); if (last->ec - first->ec < WL_FREE_MAX_DIFF) e = rb_entry(ubi->free.rb_node, - struct ubi_wl_entry, rb); + struct ubi_wl_entry, u.rb); else { medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; e = find_wl_entry(&ubi->free, medium_ec); } - protect = U_PROTECTION; break; case UBI_SHORTTERM: /* * For short term data we pick a physical eraseblock with the * lowest erase counter as we expect it will be erased soon. */ - e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); - protect = ST_PROTECTION; + e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); break; default: - protect = 0; - e = NULL; BUG(); } + paranoid_check_in_wl_tree(e, &ubi->free); + /* - * Move the physical eraseblock to the protection trees where it will + * Move the physical eraseblock to the protection queue where it will * be protected from being moved for some time. */ - paranoid_check_in_wl_tree(e, &ubi->free); - rb_erase(&e->rb, &ubi->free); - prot_tree_add(ubi, e, pe, protect); - - dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect); + rb_erase(&e->u.rb, &ubi->free); + dbg_wl("PEB %d EC %d", e->pnum, e->ec); + prot_queue_add(ubi, e); spin_unlock(&ubi->wl_lock); - return e->pnum; } /** - * prot_tree_del - remove a physical eraseblock from the protection trees + * prot_queue_del - remove a physical eraseblock from the protection queue. * @ubi: UBI device description object * @pnum: the physical eraseblock to remove * - * This function returns PEB @pnum from the protection trees and returns zero - * in case of success and %-ENODEV if the PEB was not found in the protection - * trees. + * This function deletes PEB @pnum from the protection queue and returns zero + * in case of success and %-ENODEV if the PEB was not found. */ -static int prot_tree_del(struct ubi_device *ubi, int pnum) +static int prot_queue_del(struct ubi_device *ubi, int pnum) { - struct rb_node *p; - struct ubi_wl_prot_entry *pe = NULL; - - p = ubi->prot.pnum.rb_node; - while (p) { - - pe = rb_entry(p, struct ubi_wl_prot_entry, rb_pnum); - - if (pnum == pe->e->pnum) - goto found; + struct ubi_wl_entry *e; - if (pnum < pe->e->pnum) - p = p->rb_left; - else - p = p->rb_right; - } + e = ubi->lookuptbl[pnum]; + if (!e) + return -ENODEV; - return -ENODEV; + if (paranoid_check_in_pq(ubi, e)) + return -ENODEV; -found: - ubi_assert(pe->e->pnum == pnum); - rb_erase(&pe->rb_aec, &ubi->prot.aec); - rb_erase(&pe->rb_pnum, &ubi->prot.pnum); - kfree(pe); + list_del(&e->u.list); + dbg_wl("deleted PEB %d from the protection queue", e->pnum); return 0; } @@ -632,47 +546,47 @@ out_free: } /** - * check_protection_over - check if it is time to stop protecting some PEBs. + * serve_prot_queue - check if it is time to stop protecting PEBs. * @ubi: UBI device description object * - * This function is called after each erase operation, when the absolute erase - * counter is incremented, to check if some physical eraseblock have not to be - * protected any longer. These physical eraseblocks are moved from the - * protection trees to the used tree. + * This function is called after each erase operation and removes PEBs from the + * tail of the protection queue. These PEBs have been protected for long enough + * and should be moved to the used tree. */ -static void check_protection_over(struct ubi_device *ubi) +static void serve_prot_queue(struct ubi_device *ubi) { - struct ubi_wl_prot_entry *pe; + struct ubi_wl_entry *e, *tmp; + int count; /* * There may be several protected physical eraseblock to remove, * process them all. */ - while (1) { - spin_lock(&ubi->wl_lock); - if (!ubi->prot.aec.rb_node) { - spin_unlock(&ubi->wl_lock); - break; - } - - pe = rb_entry(rb_first(&ubi->prot.aec), - struct ubi_wl_prot_entry, rb_aec); +repeat: + count = 0; + spin_lock(&ubi->wl_lock); + list_for_each_entry_safe(e, tmp, &ubi->pq[ubi->pq_head], u.list) { + dbg_wl("PEB %d EC %d protection over, move to used tree", + e->pnum, e->ec); - if (pe->abs_ec > ubi->abs_ec) { + list_del(&e->u.list); + wl_tree_add(e, &ubi->used); + if (count++ > 32) { + /* + * Let's be nice and avoid holding the spinlock for + * too long. + */ spin_unlock(&ubi->wl_lock); - break; + cond_resched(); + goto repeat; } - - dbg_wl("PEB %d protection over, abs_ec %llu, PEB abs_ec %llu", - pe->e->pnum, ubi->abs_ec, pe->abs_ec); - rb_erase(&pe->rb_aec, &ubi->prot.aec); - rb_erase(&pe->rb_pnum, &ubi->prot.pnum); - wl_tree_add(pe->e, &ubi->used); - spin_unlock(&ubi->wl_lock); - - kfree(pe); - cond_resched(); } + + ubi->pq_head += 1; + if (ubi->pq_head == UBI_PROT_QUEUE_LEN) + ubi->pq_head = 0; + ubi_assert(ubi->pq_head >= 0 && ubi->pq_head < UBI_PROT_QUEUE_LEN); + spin_unlock(&ubi->wl_lock); } /** @@ -680,8 +594,8 @@ static void check_protection_over(struct ubi_device *ubi) * @ubi: UBI device description object * @wrk: the work to schedule * - * This function enqueues a work defined by @wrk to the tail of the pending - * works list. + * This function adds a work defined by @wrk to the tail of the pending works + * list. */ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) { @@ -739,13 +653,11 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, int cancel) { - int err, put = 0, scrubbing = 0, protect = 0; - struct ubi_wl_prot_entry *uninitialized_var(pe); + int err, scrubbing = 0, torture = 0; struct ubi_wl_entry *e1, *e2; struct ubi_vid_hdr *vid_hdr; kfree(wrk); - if (cancel) return 0; @@ -781,7 +693,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, * highly worn-out free physical eraseblock. If the erase * counters differ much enough, start wear-leveling. */ - e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); + e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { @@ -790,21 +702,21 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_cancel; } paranoid_check_in_wl_tree(e1, &ubi->used); - rb_erase(&e1->rb, &ubi->used); + rb_erase(&e1->u.rb, &ubi->used); dbg_wl("move PEB %d EC %d to PEB %d EC %d", e1->pnum, e1->ec, e2->pnum, e2->ec); } else { /* Perform scrubbing */ scrubbing = 1; - e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, rb); + e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); paranoid_check_in_wl_tree(e1, &ubi->scrub); - rb_erase(&e1->rb, &ubi->scrub); + rb_erase(&e1->u.rb, &ubi->scrub); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); } paranoid_check_in_wl_tree(e2, &ubi->free); - rb_erase(&e2->rb, &ubi->free); + rb_erase(&e2->u.rb, &ubi->free); ubi->move_from = e1; ubi->move_to = e2; spin_unlock(&ubi->wl_lock); @@ -844,46 +756,67 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); if (err) { - + if (err == -EAGAIN) + goto out_not_moved; if (err < 0) goto out_error; - if (err == 1) + if (err == 2) { + /* Target PEB write error, torture it */ + torture = 1; goto out_not_moved; + } /* - * For some reason the LEB was not moved - it might be because - * the volume is being deleted. We should prevent this PEB from - * being selected for wear-levelling movement for some "time", - * so put it to the protection tree. + * The LEB has not been moved because the volume is being + * deleted or the PEB has been put meanwhile. We should prevent + * this PEB from being selected for wear-leveling movement + * again, so put it to the protection queue. */ - dbg_wl("cancelled moving PEB %d", e1->pnum); - pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); - if (!pe) { - err = -ENOMEM; - goto out_error; - } + dbg_wl("canceled moving PEB %d", e1->pnum); + ubi_assert(err == 1); + + ubi_free_vid_hdr(ubi, vid_hdr); + vid_hdr = NULL; + + spin_lock(&ubi->wl_lock); + prot_queue_add(ubi, e1); + ubi_assert(!ubi->move_to_put); + ubi->move_from = ubi->move_to = NULL; + ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); - protect = 1; + e1 = NULL; + err = schedule_erase(ubi, e2, 0); + if (err) + goto out_error; + mutex_unlock(&ubi->move_mutex); + return 0; } + /* The PEB has been successfully moved */ ubi_free_vid_hdr(ubi, vid_hdr); - if (scrubbing && !protect) + vid_hdr = NULL; + if (scrubbing) ubi_msg("scrubbed PEB %d, data moved to PEB %d", e1->pnum, e2->pnum); spin_lock(&ubi->wl_lock); - if (protect) - prot_tree_add(ubi, e1, pe, protect); - if (!ubi->move_to_put) + if (!ubi->move_to_put) { wl_tree_add(e2, &ubi->used); - else - put = 1; + e2 = NULL; + } ubi->move_from = ubi->move_to = NULL; ubi->move_to_put = ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); - if (put) { + err = schedule_erase(ubi, e1, 0); + if (err) { + e1 = NULL; + goto out_error; + } + + if (e2) { /* * Well, the target PEB was put meanwhile, schedule it for * erasure. @@ -894,13 +827,6 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_error; } - if (!protect) { - err = schedule_erase(ubi, e1, 0); - if (err) - goto out_error; - } - - dbg_wl("done"); mutex_unlock(&ubi->move_mutex); return 0; @@ -908,20 +834,24 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, /* * For some reasons the LEB was not moved, might be an error, might be * something else. @e1 was not changed, so return it back. @e2 might - * be changed, schedule it for erasure. + * have been changed, schedule it for erasure. */ out_not_moved: + dbg_wl("canceled moving PEB %d", e1->pnum); ubi_free_vid_hdr(ubi, vid_hdr); + vid_hdr = NULL; spin_lock(&ubi->wl_lock); if (scrubbing) wl_tree_add(e1, &ubi->scrub); else wl_tree_add(e1, &ubi->used); + ubi_assert(!ubi->move_to_put); ubi->move_from = ubi->move_to = NULL; - ubi->move_to_put = ubi->wl_scheduled = 0; + ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); - err = schedule_erase(ubi, e2, 0); + e1 = NULL; + err = schedule_erase(ubi, e2, torture); if (err) goto out_error; @@ -938,8 +868,10 @@ out_error: ubi->move_to_put = ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); - kmem_cache_free(ubi_wl_entry_slab, e1); - kmem_cache_free(ubi_wl_entry_slab, e2); + if (e1) + kmem_cache_free(ubi_wl_entry_slab, e1); + if (e2) + kmem_cache_free(ubi_wl_entry_slab, e2); ubi_ro_mode(ubi); mutex_unlock(&ubi->move_mutex); @@ -988,7 +920,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi) * erase counter of free physical eraseblocks is greater then * %UBI_WL_THRESHOLD. */ - e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); + e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) @@ -1050,7 +982,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, kfree(wl_wrk); spin_lock(&ubi->wl_lock); - ubi->abs_ec += 1; wl_tree_add(e, &ubi->free); spin_unlock(&ubi->wl_lock); @@ -1058,7 +989,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, * One more erase operation has happened, take care about * protected physical eraseblocks. */ - check_protection_over(ubi); + serve_prot_queue(ubi); /* And take care about wear-leveling */ err = ensure_wear_leveling(ubi); @@ -1190,12 +1121,12 @@ retry: } else { if (in_wl_tree(e, &ubi->used)) { paranoid_check_in_wl_tree(e, &ubi->used); - rb_erase(&e->rb, &ubi->used); + rb_erase(&e->u.rb, &ubi->used); } else if (in_wl_tree(e, &ubi->scrub)) { paranoid_check_in_wl_tree(e, &ubi->scrub); - rb_erase(&e->rb, &ubi->scrub); + rb_erase(&e->u.rb, &ubi->scrub); } else { - err = prot_tree_del(ubi, e->pnum); + err = prot_queue_del(ubi, e->pnum); if (err) { ubi_err("PEB %d not found", pnum); ubi_ro_mode(ubi); @@ -1255,11 +1186,11 @@ retry: if (in_wl_tree(e, &ubi->used)) { paranoid_check_in_wl_tree(e, &ubi->used); - rb_erase(&e->rb, &ubi->used); + rb_erase(&e->u.rb, &ubi->used); } else { int err; - err = prot_tree_del(ubi, e->pnum); + err = prot_queue_del(ubi, e->pnum); if (err) { ubi_err("PEB %d not found", pnum); ubi_ro_mode(ubi); @@ -1290,7 +1221,7 @@ int ubi_wl_flush(struct ubi_device *ubi) int err; /* - * Erase while the pending works queue is not empty, but not more then + * Erase while the pending works queue is not empty, but not more than * the number of currently pending works. */ dbg_wl("flush (%d pending works)", ubi->works_count); @@ -1308,7 +1239,7 @@ int ubi_wl_flush(struct ubi_device *ubi) up_write(&ubi->work_sem); /* - * And in case last was the WL worker and it cancelled the LEB + * And in case last was the WL worker and it canceled the LEB * movement, flush again. */ while (ubi->works_count) { @@ -1337,11 +1268,11 @@ static void tree_destroy(struct rb_root *root) else if (rb->rb_right) rb = rb->rb_right; else { - e = rb_entry(rb, struct ubi_wl_entry, rb); + e = rb_entry(rb, struct ubi_wl_entry, u.rb); rb = rb_parent(rb); if (rb) { - if (rb->rb_left == &e->rb) + if (rb->rb_left == &e->u.rb) rb->rb_left = NULL; else rb->rb_right = NULL; @@ -1436,15 +1367,13 @@ static void cancel_pending(struct ubi_device *ubi) */ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) { - int err; + int err, i; struct rb_node *rb1, *rb2; struct ubi_scan_volume *sv; struct ubi_scan_leb *seb, *tmp; struct ubi_wl_entry *e; - ubi->used = ubi->free = ubi->scrub = RB_ROOT; - ubi->prot.pnum = ubi->prot.aec = RB_ROOT; spin_lock_init(&ubi->wl_lock); mutex_init(&ubi->move_mutex); init_rwsem(&ubi->work_sem); @@ -1458,6 +1387,10 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) if (!ubi->lookuptbl) return err; + for (i = 0; i < UBI_PROT_QUEUE_LEN; i++) + INIT_LIST_HEAD(&ubi->pq[i]); + ubi->pq_head = 0; + list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { cond_resched(); @@ -1552,33 +1485,18 @@ out_free: } /** - * protection_trees_destroy - destroy the protection RB-trees. + * protection_queue_destroy - destroy the protection queue. * @ubi: UBI device description object */ -static void protection_trees_destroy(struct ubi_device *ubi) +static void protection_queue_destroy(struct ubi_device *ubi) { - struct rb_node *rb; - struct ubi_wl_prot_entry *pe; - - rb = ubi->prot.aec.rb_node; - while (rb) { - if (rb->rb_left) - rb = rb->rb_left; - else if (rb->rb_right) - rb = rb->rb_right; - else { - pe = rb_entry(rb, struct ubi_wl_prot_entry, rb_aec); - - rb = rb_parent(rb); - if (rb) { - if (rb->rb_left == &pe->rb_aec) - rb->rb_left = NULL; - else - rb->rb_right = NULL; - } + int i; + struct ubi_wl_entry *e, *tmp; - kmem_cache_free(ubi_wl_entry_slab, pe->e); - kfree(pe); + for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) { + list_for_each_entry_safe(e, tmp, &ubi->pq[i], u.list) { + list_del(&e->u.list); + kmem_cache_free(ubi_wl_entry_slab, e); } } } @@ -1591,7 +1509,7 @@ void ubi_wl_close(struct ubi_device *ubi) { dbg_wl("close the WL sub-system"); cancel_pending(ubi); - protection_trees_destroy(ubi); + protection_queue_destroy(ubi); tree_destroy(&ubi->used); tree_destroy(&ubi->free); tree_destroy(&ubi->scrub); @@ -1661,4 +1579,27 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, return 1; } +/** + * paranoid_check_in_pq - check if wear-leveling entry is in the protection + * queue. + * @ubi: UBI device description object + * @e: the wear-leveling entry to check + * + * This function returns zero if @e is in @ubi->pq and %1 if it is not. + */ +static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) +{ + struct ubi_wl_entry *p; + int i; + + for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) + list_for_each_entry(p, &ubi->pq[i], u.list) + if (p == e) + return 0; + + ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue", + e->pnum, e->ec); + ubi_dbg_dump_stack(); + return 1; +} #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 8514c3a1746..c2e1bcbb28a 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -45,7 +45,7 @@ #include "cpqphp.h" #include "cpqphp_nvram.h" -#include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */ +#include <asm/pci_x86.h> /* Global variables */ diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 09021930589..df146be9d2e 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -37,7 +37,7 @@ #include "../pci.h" #include "cpqphp.h" #include "cpqphp_nvram.h" -#include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */ +#include <asm/pci_x86.h> u8 cpqhp_nic_irq; diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 633e743442a..dd18f857dfb 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -35,7 +35,7 @@ #include <linux/delay.h> #include <linux/wait.h> #include "../pci.h" -#include "../../../arch/x86/pci/pci.h" /* for struct irq_routing_table */ +#include <asm/pci_x86.h> /* for struct irq_routing_table */ #include "ibmphp.h" #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 8a8df755296..06b71823f39 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -632,8 +632,8 @@ do_IRQ (struct pt_regs *regs) struct pt_regs *old_regs; old_regs = set_irq_regs(regs); - irq_enter(); s390_idle_check(); + irq_enter(); if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ clock_comparator_work(); diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 834e9ee7e93..92b0417f8e1 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -18,6 +18,7 @@ #include <asm/etr.h> #include <asm/lowcore.h> #include <asm/cio.h> +#include <asm/cpu.h> #include "s390mach.h" static struct semaphore m_sem; @@ -369,6 +370,8 @@ s390_do_machine_check(struct pt_regs *regs) lockdep_off(); + s390_idle_check(); + mci = (struct mci *) &S390_lowcore.mcck_interruption_code; mcck = &__get_cpu_var(cpu_mcck); umode = user_mode(regs); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4fd3fa5546b..ec68c741b56 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -55,6 +55,13 @@ config SOFT_WATCHDOG To compile this driver as a module, choose M here: the module will be called softdog. +config WM8350_WATCHDOG + tristate "WM8350 watchdog" + depends on MFD_WM8350 + help + Support for the watchdog in the WM8350 AudioPlus PMIC. When + the watchdog triggers the system will be reset. + # ALPHA Architecture # ARM Architecture @@ -551,6 +558,18 @@ config CPU5_WDT To compile this driver as a module, choose M here: the module will be called cpu5wdt. +config SMSC_SCH311X_WDT + tristate "SMSC SCH311X Watchdog Timer" + depends on X86 + ---help--- + This is the driver for the hardware watchdog timer on the + SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset + (LPC IO with 8042 KBC, Reset Generation, HWM and multiple + serial ports). + + To compile this driver as a module, choose M here: the + module will be called sch311x_wdt. + config SMSC37B787_WDT tristate "Winbond SMsC37B787 Watchdog Timer" depends on X86 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e352bbb7630..c19b866f5ed 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o +obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o @@ -133,4 +134,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o # XTENSA Architecture # Architecture Independant +obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 317ef2b16cf..4bef3ddff4a 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -91,32 +91,16 @@ static char expect_close; * */ -static int wd_times[] = { - 30, /* 0x0 */ - 28, /* 0x1 */ - 26, /* 0x2 */ - 24, /* 0x3 */ - 22, /* 0x4 */ - 20, /* 0x5 */ - 18, /* 0x6 */ - 16, /* 0x7 */ - 14, /* 0x8 */ - 12, /* 0x9 */ - 10, /* 0xA */ - 8, /* 0xB */ - 6, /* 0xC */ - 4, /* 0xD */ - 2, /* 0xE */ - 0, /* 0xF */ -}; - #define WDT_STOP 0x441 #define WDT_START 0x443 /* Default timeout */ -#define WD_TIMO 0 /* 30 seconds +/- 20%, from table */ - -static int wd_margin = WD_TIMO; +#define WATCHDOG_TIMEOUT 30 /* 30 seconds +/- 20% */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, + "Watchdog timeout in seconds. 0<= timeout <=30, default=" + __MODULE_STRING(WATCHDOG_TIMEOUT) "."); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); @@ -131,6 +115,8 @@ MODULE_PARM_DESC(nowayout, static void ibwdt_ping(void) { + int wd_margin = 15 - ((timeout + 1) / 2); + spin_lock(&ibwdt_lock); /* Write a watchdog value */ @@ -148,15 +134,10 @@ static void ibwdt_disable(void) static int ibwdt_set_heartbeat(int t) { - int i; - - if ((t < 0) || (t > 30)) + if (t < 0 || t > 30) return -EINVAL; - for (i = 0x0F; i > -1; i--) - if (wd_times[i] >= t) - break; - wd_margin = i; + timeout = t; return 0; } @@ -240,7 +221,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(wd_times[wd_margin], p); + return put_user(timeout, p); default: return -ENOTTY; @@ -317,6 +298,14 @@ static int __devinit ibwdt_probe(struct platform_device *dev) goto out_nostartreg; } + /* Check that the heartbeat value is within it's range ; + * if not reset to the default */ + if (ibwdt_set_heartbeat(timeout)) { + ibwdt_set_heartbeat(WATCHDOG_TIMEOUT); + printk(KERN_INFO PFX + "timeout value must be 0<=x<=30, using %d\n", timeout); + } + res = misc_register(&ibwdt_miscdev); if (res) { printk(KERN_ERR PFX "failed to register misc device\n"); diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c new file mode 100644 index 00000000000..569eb295a7a --- /dev/null +++ b/drivers/watchdog/sch311x_wdt.c @@ -0,0 +1,578 @@ +/* + * sch311x_wdt.c - Driver for the SCH311x Super-I/O chips + * integrated watchdog. + * + * (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>. + * + * 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. + * + * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + */ + +/* + * Includes, defines, variables, module parameters, ... + */ + +/* Includes */ +#include <linux/module.h> /* For module specific items */ +#include <linux/moduleparam.h> /* For new moduleparam's */ +#include <linux/types.h> /* For standard types (like size_t) */ +#include <linux/errno.h> /* For the -ENODEV/... values */ +#include <linux/kernel.h> /* For printk/... */ +#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV + (WATCHDOG_MINOR) */ +#include <linux/watchdog.h> /* For the watchdog specific items */ +#include <linux/init.h> /* For __init/__exit/... */ +#include <linux/fs.h> /* For file operations */ +#include <linux/platform_device.h> /* For platform_driver framework */ +#include <linux/ioport.h> /* For io-port access */ +#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ +#include <linux/uaccess.h> /* For copy_to_user/put_user/... */ +#include <linux/io.h> /* For inb/outb/... */ + +/* Module and version information */ +#define DRV_NAME "sch311x_wdt" +#define PFX DRV_NAME ": " + +/* Runtime registers */ +#define RESGEN 0x1d +#define GP60 0x47 +#define WDT_TIME_OUT 0x65 +#define WDT_VAL 0x66 +#define WDT_CFG 0x67 +#define WDT_CTRL 0x68 + +/* internal variables */ +static unsigned long sch311x_wdt_is_open; +static char sch311x_wdt_expect_close; +static struct platform_device *sch311x_wdt_pdev; + +static int sch311x_ioports[] = { 0x2e, 0x4e, 0x162e, 0x164e, 0x00 }; + +static struct { /* The devices private data */ + /* the Runtime Register base address */ + unsigned short runtime_reg; + /* The card's boot status */ + int boot_status; + /* the lock for io operations */ + spinlock_t io_lock; +} sch311x_wdt_data; + +/* Module load parameters */ +static unsigned short force_id; +module_param(force_id, ushort, 0); +MODULE_PARM_DESC(force_id, "Override the detected device ID"); + +static unsigned short therm_trip; +module_param(therm_trip, ushort, 0); +MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator"); + +#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ +static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, + "Watchdog timeout in seconds. 1<= timeout <=15300, default=" + __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +/* + * Super-IO functions + */ + +static inline void sch311x_sio_enter(int sio_config_port) +{ + outb(0x55, sio_config_port); +} + +static inline void sch311x_sio_exit(int sio_config_port) +{ + outb(0xaa, sio_config_port); +} + +static inline int sch311x_sio_inb(int sio_config_port, int reg) +{ + outb(reg, sio_config_port); + return inb(sio_config_port + 1); +} + +static inline void sch311x_sio_outb(int sio_config_port, int reg, int val) +{ + outb(reg, sio_config_port); + outb(val, sio_config_port + 1); +} + +/* + * Watchdog Operations + */ + +static void sch311x_wdt_set_timeout(int t) +{ + unsigned char timeout_unit = 0x80; + + /* When new timeout is bigger then 255 seconds, we will use minutes */ + if (t > 255) { + timeout_unit = 0; + t /= 60; + } + + /* -- Watchdog Timeout -- + * Bit 0-6 (Reserved) + * Bit 7 WDT Time-out Value Units Select + * (0 = Minutes, 1 = Seconds) + */ + outb(timeout_unit, sch311x_wdt_data.runtime_reg + WDT_TIME_OUT); + + /* -- Watchdog Timer Time-out Value -- + * Bit 0-7 Binary coded units (0=Disabled, 1..255) + */ + outb(t, sch311x_wdt_data.runtime_reg + WDT_VAL); +} + +static void sch311x_wdt_start(void) +{ + spin_lock(&sch311x_wdt_data.io_lock); + + /* set watchdog's timeout */ + sch311x_wdt_set_timeout(timeout); + /* enable the watchdog */ + /* -- General Purpose I/O Bit 6.0 -- + * Bit 0, In/Out: 0 = Output, 1 = Input + * Bit 1, Polarity: 0 = No Invert, 1 = Invert + * Bit 2-3, Function select: 00 = GPI/O, 01 = LED1, 11 = WDT, + * 10 = Either Edge Triggered Intr.4 + * Bit 4-6 (Reserved) + * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain + */ + outb(0x0e, sch311x_wdt_data.runtime_reg + GP60); + + spin_unlock(&sch311x_wdt_data.io_lock); + +} + +static void sch311x_wdt_stop(void) +{ + spin_lock(&sch311x_wdt_data.io_lock); + + /* stop the watchdog */ + outb(0x01, sch311x_wdt_data.runtime_reg + GP60); + /* disable timeout by setting it to 0 */ + sch311x_wdt_set_timeout(0); + + spin_unlock(&sch311x_wdt_data.io_lock); +} + +static void sch311x_wdt_keepalive(void) +{ + spin_lock(&sch311x_wdt_data.io_lock); + sch311x_wdt_set_timeout(timeout); + spin_unlock(&sch311x_wdt_data.io_lock); +} + +static int sch311x_wdt_set_heartbeat(int t) +{ + if (t < 1 || t > (255*60)) + return -EINVAL; + + /* When new timeout is bigger then 255 seconds, + * we will round up to minutes (with a max of 255) */ + if (t > 255) + t = (((t - 1) / 60) + 1) * 60; + + timeout = t; + return 0; +} + +static void sch311x_wdt_get_status(int *status) +{ + unsigned char new_status; + + *status = 0; + + spin_lock(&sch311x_wdt_data.io_lock); + + /* -- Watchdog timer control -- + * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured + * Bit 1 Reserved + * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) + * Bit 3 P20 Force Timeout enabled: + * 0 = P20 activity does not generate the WD timeout event + * 1 = P20 Allows rising edge of P20, from the keyboard + * controller, to force the WD timeout event. + * Bit 4-7 Reserved + */ + new_status = inb(sch311x_wdt_data.runtime_reg + WDT_CTRL); + if (new_status & 0x01) + *status |= WDIOF_CARDRESET; + + spin_unlock(&sch311x_wdt_data.io_lock); +} + +/* + * /dev/watchdog handling + */ + +static ssize_t sch311x_wdt_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + if (count) { + if (!nowayout) { + size_t i; + + sch311x_wdt_expect_close = 0; + + for (i = 0; i != count; i++) { + char c; + if (get_user(c, buf + i)) + return -EFAULT; + if (c == 'V') + sch311x_wdt_expect_close = 42; + } + } + sch311x_wdt_keepalive(); + } + return count; +} + +static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int status; + int new_timeout; + void __user *argp = (void __user *)arg; + int __user *p = argp; + static struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | + WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE, + .firmware_version = 1, + .identity = DRV_NAME, + }; + + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user(argp, &ident, sizeof(ident))) + return -EFAULT; + break; + + case WDIOC_GETSTATUS: + { + sch311x_wdt_get_status(&status); + return put_user(status, p); + } + case WDIOC_GETBOOTSTATUS: + return put_user(sch311x_wdt_data.boot_status, p); + + case WDIOC_SETOPTIONS: + { + int options, retval = -EINVAL; + + if (get_user(options, p)) + return -EFAULT; + if (options & WDIOS_DISABLECARD) { + sch311x_wdt_stop(); + retval = 0; + } + if (options & WDIOS_ENABLECARD) { + sch311x_wdt_start(); + retval = 0; + } + return retval; + } + case WDIOC_KEEPALIVE: + sch311x_wdt_keepalive(); + break; + + case WDIOC_SETTIMEOUT: + if (get_user(new_timeout, p)) + return -EFAULT; + if (sch311x_wdt_set_heartbeat(new_timeout)) + return -EINVAL; + sch311x_wdt_keepalive(); + /* Fall */ + case WDIOC_GETTIMEOUT: + return put_user(timeout, p); + default: + return -ENOTTY; + } + return 0; +} + +static int sch311x_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(0, &sch311x_wdt_is_open)) + return -EBUSY; + /* + * Activate + */ + sch311x_wdt_start(); + return nonseekable_open(inode, file); +} + +static int sch311x_wdt_close(struct inode *inode, struct file *file) +{ + if (sch311x_wdt_expect_close == 42) { + sch311x_wdt_stop(); + } else { + printk(KERN_CRIT PFX + "Unexpected close, not stopping watchdog!\n"); + sch311x_wdt_keepalive(); + } + clear_bit(0, &sch311x_wdt_is_open); + sch311x_wdt_expect_close = 0; + return 0; +} + +/* + * Kernel Interfaces + */ + +static const struct file_operations sch311x_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = sch311x_wdt_write, + .unlocked_ioctl = sch311x_wdt_ioctl, + .open = sch311x_wdt_open, + .release = sch311x_wdt_close, +}; + +static struct miscdevice sch311x_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &sch311x_wdt_fops, +}; + +/* + * Init & exit routines + */ + +static int __devinit sch311x_wdt_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + unsigned char val; + int err; + + spin_lock_init(&sch311x_wdt_data.io_lock); + + if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1, + DRV_NAME)) { + dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", + sch311x_wdt_data.runtime_reg + RESGEN, + sch311x_wdt_data.runtime_reg + RESGEN); + err = -EBUSY; + goto exit; + } + + if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) { + dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", + sch311x_wdt_data.runtime_reg + GP60, + sch311x_wdt_data.runtime_reg + GP60); + err = -EBUSY; + goto exit_release_region; + } + + if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4, + DRV_NAME)) { + dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", + sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, + sch311x_wdt_data.runtime_reg + WDT_CTRL); + err = -EBUSY; + goto exit_release_region2; + } + + /* Make sure that the watchdog is not running */ + sch311x_wdt_stop(); + + /* Disable keyboard and mouse interaction and interrupt */ + /* -- Watchdog timer configuration -- + * Bit 0 Reserved + * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. + * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr + * Bit 3 Reserved + * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, + * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) + */ + outb(0, sch311x_wdt_data.runtime_reg + WDT_CFG); + + /* Check that the heartbeat value is within it's range ; + * if not reset to the default */ + if (sch311x_wdt_set_heartbeat(timeout)) { + sch311x_wdt_set_heartbeat(WATCHDOG_TIMEOUT); + dev_info(dev, "timeout value must be 1<=x<=15300, using %d\n", + timeout); + } + + /* Get status at boot */ + sch311x_wdt_get_status(&sch311x_wdt_data.boot_status); + + /* enable watchdog */ + /* -- Reset Generator -- + * Bit 0 Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled + * Bit 1 Thermtrip Source Select: O* = No Source, 1 = Source + * Bit 2 WDT2_CTL: WDT input bit + * Bit 3-7 Reserved + */ + outb(0, sch311x_wdt_data.runtime_reg + RESGEN); + val = therm_trip ? 0x06 : 0x04; + outb(val, sch311x_wdt_data.runtime_reg + RESGEN); + + err = misc_register(&sch311x_wdt_miscdev); + if (err != 0) { + dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, err); + goto exit_release_region3; + } + + sch311x_wdt_miscdev.parent = dev; + + dev_info(dev, + "SMSC SCH311x WDT initialized. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); + + return 0; + +exit_release_region3: + release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); +exit_release_region2: + release_region(sch311x_wdt_data.runtime_reg + GP60, 1); +exit_release_region: + release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); + sch311x_wdt_data.runtime_reg = 0; +exit: + return err; +} + +static int __devexit sch311x_wdt_remove(struct platform_device *pdev) +{ + /* Stop the timer before we leave */ + if (!nowayout) + sch311x_wdt_stop(); + + /* Deregister */ + misc_deregister(&sch311x_wdt_miscdev); + release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); + release_region(sch311x_wdt_data.runtime_reg + GP60, 1); + release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); + sch311x_wdt_data.runtime_reg = 0; + return 0; +} + +static void sch311x_wdt_shutdown(struct platform_device *dev) +{ + /* Turn the WDT off if we have a soft shutdown */ + sch311x_wdt_stop(); +} + +#define sch311x_wdt_suspend NULL +#define sch311x_wdt_resume NULL + +static struct platform_driver sch311x_wdt_driver = { + .probe = sch311x_wdt_probe, + .remove = __devexit_p(sch311x_wdt_remove), + .shutdown = sch311x_wdt_shutdown, + .suspend = sch311x_wdt_suspend, + .resume = sch311x_wdt_resume, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + }, +}; + +static int __init sch311x_detect(int sio_config_port, unsigned short *addr) +{ + int err = 0, reg; + unsigned short base_addr; + unsigned char dev_id; + + sch311x_sio_enter(sio_config_port); + + /* Check device ID. We currently know about: + * SCH3112 (0x7c), SCH3114 (0x7d), and SCH3116 (0x7f). */ + reg = force_id ? force_id : sch311x_sio_inb(sio_config_port, 0x20); + if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { + err = -ENODEV; + goto exit; + } + dev_id = reg == 0x7c ? 2 : reg == 0x7d ? 4 : 6; + + /* Select logical device A (runtime registers) */ + sch311x_sio_outb(sio_config_port, 0x07, 0x0a); + + /* Check if Logical Device Register is currently active */ + if (sch311x_sio_inb(sio_config_port, 0x30) && 0x01 == 0) + printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); + + /* Get the base address of the runtime registers */ + base_addr = (sch311x_sio_inb(sio_config_port, 0x60) << 8) | + sch311x_sio_inb(sio_config_port, 0x61); + if (!base_addr) { + printk(KERN_ERR PFX "Base address not set.\n"); + err = -ENODEV; + goto exit; + } + *addr = base_addr; + + printk(KERN_INFO PFX "Found an SMSC SCH311%d chip at 0x%04x\n", + dev_id, base_addr); + +exit: + sch311x_sio_exit(sio_config_port); + return err; +} + +static int __init sch311x_wdt_init(void) +{ + int err, i, found = 0; + unsigned short addr = 0; + + for (i = 0; !found && sch311x_ioports[i]; i++) + if (sch311x_detect(sch311x_ioports[i], &addr) == 0) + found++; + + if (!found) + return -ENODEV; + + sch311x_wdt_data.runtime_reg = addr; + + err = platform_driver_register(&sch311x_wdt_driver); + if (err) + return err; + + sch311x_wdt_pdev = platform_device_register_simple(DRV_NAME, addr, + NULL, 0); + + if (IS_ERR(sch311x_wdt_pdev)) { + err = PTR_ERR(sch311x_wdt_pdev); + goto unreg_platform_driver; + } + + return 0; + +unreg_platform_driver: + platform_driver_unregister(&sch311x_wdt_driver); + return err; +} + +static void __exit sch311x_wdt_exit(void) +{ + platform_device_unregister(sch311x_wdt_pdev); + platform_driver_unregister(&sch311x_wdt_driver); +} + +module_init(sch311x_wdt_init); +module_exit(sch311x_wdt_exit); + +MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); +MODULE_DESCRIPTION("SMSC SCH311x WatchDog Timer Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c new file mode 100644 index 00000000000..2bc0d4d4b41 --- /dev/null +++ b/drivers/watchdog/wm8350_wdt.c @@ -0,0 +1,329 @@ +/* + * Watchdog driver for the wm8350 + * + * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com> + * + * 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 + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> +#include <linux/uaccess.h> +#include <linux/mfd/wm8350/core.h> + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static unsigned long wm8350_wdt_users; +static struct miscdevice wm8350_wdt_miscdev; +static int wm8350_wdt_expect_close; +static DEFINE_MUTEX(wdt_mutex); + +static struct { + int time; /* Seconds */ + u16 val; /* To be set in WM8350_SYSTEM_CONTROL_2 */ +} wm8350_wdt_cfgs[] = { + { 1, 0x02 }, + { 2, 0x04 }, + { 4, 0x05 }, +}; + +static struct wm8350 *get_wm8350(void) +{ + return dev_get_drvdata(wm8350_wdt_miscdev.parent); +} + +static int wm8350_wdt_set_timeout(struct wm8350 *wm8350, u16 value) +{ + int ret; + u16 reg; + + mutex_lock(&wdt_mutex); + wm8350_reg_unlock(wm8350); + + reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); + reg &= ~WM8350_WDOG_TO_MASK; + reg |= value; + ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); + + wm8350_reg_lock(wm8350); + mutex_unlock(&wdt_mutex); + + return ret; +} + +static int wm8350_wdt_start(struct wm8350 *wm8350) +{ + int ret; + u16 reg; + + mutex_lock(&wdt_mutex); + wm8350_reg_unlock(wm8350); + + reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); + reg &= ~WM8350_WDOG_MODE_MASK; + reg |= 0x20; + ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); + + wm8350_reg_lock(wm8350); + mutex_unlock(&wdt_mutex); + + return ret; +} + +static int wm8350_wdt_stop(struct wm8350 *wm8350) +{ + int ret; + u16 reg; + + mutex_lock(&wdt_mutex); + wm8350_reg_unlock(wm8350); + + reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); + reg &= ~WM8350_WDOG_MODE_MASK; + ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); + + wm8350_reg_lock(wm8350); + mutex_unlock(&wdt_mutex); + + return ret; +} + +static int wm8350_wdt_kick(struct wm8350 *wm8350) +{ + int ret; + u16 reg; + + mutex_lock(&wdt_mutex); + + reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); + ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); + + mutex_unlock(&wdt_mutex); + + return ret; +} + +static int wm8350_wdt_open(struct inode *inode, struct file *file) +{ + struct wm8350 *wm8350 = get_wm8350(); + int ret; + + if (!wm8350) + return -ENODEV; + + if (test_and_set_bit(0, &wm8350_wdt_users)) + return -EBUSY; + + ret = wm8350_wdt_start(wm8350); + if (ret != 0) + return ret; + + return nonseekable_open(inode, file); +} + +static int wm8350_wdt_release(struct inode *inode, struct file *file) +{ + struct wm8350 *wm8350 = get_wm8350(); + + if (wm8350_wdt_expect_close) + wm8350_wdt_stop(wm8350); + else { + dev_warn(wm8350->dev, "Watchdog device closed uncleanly\n"); + wm8350_wdt_kick(wm8350); + } + + clear_bit(0, &wm8350_wdt_users); + + return 0; +} + +static ssize_t wm8350_wdt_write(struct file *file, + const char __user *data, size_t count, + loff_t *ppos) +{ + struct wm8350 *wm8350 = get_wm8350(); + size_t i; + + if (count) { + wm8350_wdt_kick(wm8350); + + if (!nowayout) { + /* In case it was set long ago */ + wm8350_wdt_expect_close = 0; + + /* scan to see whether or not we got the magic + character */ + for (i = 0; i != count; i++) { + char c; + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + wm8350_wdt_expect_close = 42; + } + } + } + return count; +} + +static struct watchdog_info ident = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .identity = "WM8350 Watchdog", +}; + +static long wm8350_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct wm8350 *wm8350 = get_wm8350(); + int ret = -ENOTTY, time, i; + void __user *argp = (void __user *)arg; + int __user *p = argp; + u16 reg; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + ret = put_user(0, p); + break; + + case WDIOC_SETOPTIONS: + { + int options; + + if (get_user(options, p)) + return -EFAULT; + + ret = -EINVAL; + + /* Setting both simultaneously means at least one must fail */ + if (options == WDIOS_DISABLECARD) + ret = wm8350_wdt_start(wm8350); + + if (options == WDIOS_ENABLECARD) + ret = wm8350_wdt_stop(wm8350); + break; + } + + case WDIOC_KEEPALIVE: + ret = wm8350_wdt_kick(wm8350); + break; + + case WDIOC_SETTIMEOUT: + ret = get_user(time, p); + if (ret) + break; + + if (time == 0) { + if (nowayout) + ret = -EINVAL; + else + wm8350_wdt_stop(wm8350); + break; + } + + for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++) + if (wm8350_wdt_cfgs[i].time == time) + break; + if (i == ARRAY_SIZE(wm8350_wdt_cfgs)) + ret = -EINVAL; + else + ret = wm8350_wdt_set_timeout(wm8350, + wm8350_wdt_cfgs[i].val); + break; + + case WDIOC_GETTIMEOUT: + reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); + reg &= WM8350_WDOG_TO_MASK; + for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++) + if (wm8350_wdt_cfgs[i].val == reg) + break; + if (i == ARRAY_SIZE(wm8350_wdt_cfgs)) { + dev_warn(wm8350->dev, + "Unknown watchdog configuration: %x\n", reg); + ret = -EINVAL; + } else + ret = put_user(wm8350_wdt_cfgs[i].time, p); + + } + + return ret; +} + +static const struct file_operations wm8350_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wm8350_wdt_write, + .unlocked_ioctl = wm8350_wdt_ioctl, + .open = wm8350_wdt_open, + .release = wm8350_wdt_release, +}; + +static struct miscdevice wm8350_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wm8350_wdt_fops, +}; + +static int wm8350_wdt_probe(struct platform_device *pdev) +{ + struct wm8350 *wm8350 = platform_get_drvdata(pdev); + + if (!wm8350) { + dev_err(wm8350->dev, "No driver data supplied\n"); + return -ENODEV; + } + + /* Default to 4s timeout */ + wm8350_wdt_set_timeout(wm8350, 0x05); + + wm8350_wdt_miscdev.parent = &pdev->dev; + + return misc_register(&wm8350_wdt_miscdev); +} + +static int __exit wm8350_wdt_remove(struct platform_device *pdev) +{ + misc_deregister(&wm8350_wdt_miscdev); + + return 0; +} + +static struct platform_driver wm8350_wdt_driver = { + .probe = wm8350_wdt_probe, + .remove = wm8350_wdt_remove, + .driver = { + .name = "wm8350-wdt", + }, +}; + +static int __init wm8350_wdt_init(void) +{ + return platform_driver_register(&wm8350_wdt_driver); +} +module_init(wm8350_wdt_init); + +static void __exit wm8350_wdt_exit(void) +{ + platform_driver_unregister(&wm8350_wdt_driver); +} +module_exit(wm8350_wdt_exit); + +MODULE_AUTHOR("Mark Brown"); +MODULE_DESCRIPTION("WM8350 Watchdog"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm8350-wdt"); |