summaryrefslogtreecommitdiff
path: root/drivers/media/pci/saa7164/saa7164-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/saa7164/saa7164-core.c')
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c397
1 files changed, 227 insertions, 170 deletions
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index d37ee37aaefe..a8a004f28ca0 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1,22 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for the NXP SAA7164 PCIe bridge
*
- * Copyright (c) 2010 Steven Toth <stoth@kernellabs.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
*/
#include <linux/init.h>
@@ -27,12 +13,10 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <asm/div64.h>
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#endif
#include "saa7164.h"
MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
@@ -52,7 +36,7 @@ unsigned int saa_debug;
module_param_named(debug, saa_debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
-unsigned int fw_debug;
+static unsigned int fw_debug;
module_param(fw_debug, int, 0644);
MODULE_PARM_DESC(fw_debug, "Firmware debug level def:2");
@@ -72,7 +56,7 @@ static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(card, "card type");
-unsigned int print_histogram = 64;
+static unsigned int print_histogram = 64;
module_param(print_histogram, int, 0644);
MODULE_PARM_DESC(print_histogram, "print histogram values once");
@@ -80,11 +64,16 @@ unsigned int crc_checking = 1;
module_param(crc_checking, int, 0644);
MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
-unsigned int guard_checking = 1;
+static unsigned int guard_checking = 1;
module_param(guard_checking, int, 0644);
MODULE_PARM_DESC(guard_checking,
"enable dma sanity checking for buffer overruns");
+static bool enable_msi = true;
+module_param(enable_msi, bool, 0444);
+MODULE_PARM_DESC(enable_msi,
+ "enable the use of an msi interrupt if available");
+
static unsigned int saa7164_devcount;
static DEFINE_MUTEX(devlist);
@@ -119,7 +108,7 @@ static void saa7164_ts_verifier(struct saa7164_buffer *buf)
u32 i;
u8 cc, a;
u16 pid;
- u8 __iomem *bufcpu = (u8 *)buf->cpu;
+ u8 *bufcpu = (u8 *)buf->cpu;
port->sync_errors = 0;
port->v_cc_errors = 0;
@@ -156,7 +145,7 @@ static void saa7164_ts_verifier(struct saa7164_buffer *buf)
}
- /* Only report errors if we've been through this function atleast
+ /* Only report errors if we've been through this function at least
* once already and the cached cc values are primed. First time through
* always generates errors.
*/
@@ -178,7 +167,7 @@ static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
int i;
memset(hg, 0, sizeof(struct saa7164_histogram));
- strcpy(hg->name, name);
+ strscpy(hg->name, name, sizeof(hg->name));
/* First 30ms x 1ms */
for (i = 0; i < 30; i++)
@@ -260,7 +249,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
struct saa7164_user_buffer *ubuf = NULL;
struct list_head *c, *n;
int i = 0;
- u8 __iomem *p;
+ u8 *p;
mutex_lock(&port->dmaqueue_lock);
list_for_each_safe(c, n, &port->dmaqueue.list) {
@@ -318,8 +307,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
if (buf->actual_size <= ubuf->actual_size) {
- memcpy_fromio(ubuf->data, buf->cpu,
- ubuf->actual_size);
+ memcpy(ubuf->data, buf->cpu, ubuf->actual_size);
if (crc_checking) {
/* Throw a new checksum on the read buffer */
@@ -346,7 +334,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
* with known bad data. We check for this data at a later point
* in time. */
saa7164_buffer_zero_offsets(port, bufnr);
- memset_io(buf->cpu, 0xff, buf->pci_size);
+ memset(buf->cpu, 0xff, buf->pci_size);
if (crc_checking) {
/* Throw yet aanother new checksum on the dma buffer */
buf->crc = crc32(0, buf->cpu, buf->actual_size);
@@ -364,7 +352,7 @@ static void saa7164_work_enchandler(struct work_struct *w)
container_of(w, struct saa7164_port, workenc);
struct saa7164_dev *dev = port->dev;
- u32 wp, mcb, rp, cnt = 0;
+ u32 wp, mcb, rp;
port->last_svc_msecs_diff = port->last_svc_msecs;
port->last_svc_msecs = jiffies_to_msecs(jiffies);
@@ -417,7 +405,6 @@ static void saa7164_work_enchandler(struct work_struct *w)
saa7164_work_enchandler_helper(port, rp);
port->last_svc_rp = rp;
- cnt++;
if (rp == mcb)
break;
@@ -441,7 +428,7 @@ static void saa7164_work_vbihandler(struct work_struct *w)
container_of(w, struct saa7164_port, workenc);
struct saa7164_dev *dev = port->dev;
- u32 wp, mcb, rp, cnt = 0;
+ u32 wp, mcb, rp;
port->last_svc_msecs_diff = port->last_svc_msecs;
port->last_svc_msecs = jiffies_to_msecs(jiffies);
@@ -493,7 +480,6 @@ static void saa7164_work_vbihandler(struct work_struct *w)
saa7164_work_enchandler_helper(port, rp);
port->last_svc_rp = rp;
- cnt++;
if (rp == mcb)
break;
@@ -587,8 +573,8 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
/* Find the current write point from the hardware */
wp = saa7164_readl(port->bufcounter);
- if (wp > (port->hwcfg.buffercount - 1))
- BUG();
+
+ BUG_ON(wp > (port->hwcfg.buffercount - 1));
/* Find the previous buffer to the current write point */
if (wp == 0)
@@ -600,8 +586,8 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
/* TODO: turn this into a worker thread */
list_for_each_safe(c, n, &port->dmaqueue.list) {
buf = list_entry(c, struct saa7164_buffer, list);
- if (i++ > port->hwcfg.buffercount)
- BUG();
+ BUG_ON(i > port->hwcfg.buffercount);
+ i++;
if (buf->idx == rp) {
/* Found the buffer, deal with it */
@@ -619,12 +605,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_port *port)
static irqreturn_t saa7164_irq(int irq, void *dev_id)
{
struct saa7164_dev *dev = dev_id;
- struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1];
- struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2];
- struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1];
- struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2];
- struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1];
- struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2];
+ struct saa7164_port *porta, *portb, *portc, *portd, *porte, *portf;
u32 intid, intstat[INT_SIZE/4];
int i, handled = 0, bit;
@@ -635,8 +616,15 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
goto out;
}
+ porta = &dev->ports[SAA7164_PORT_TS1];
+ portb = &dev->ports[SAA7164_PORT_TS2];
+ portc = &dev->ports[SAA7164_PORT_ENC1];
+ portd = &dev->ports[SAA7164_PORT_ENC2];
+ porte = &dev->ports[SAA7164_PORT_VBI1];
+ portf = &dev->ports[SAA7164_PORT_VBI2];
+
/* Check that the hardware is accessible. If the status bytes are
- * 0xFF then the device is not accessible, the the IRQ belongs
+ * 0xFF then the device is not accessible, the IRQ belongs
* to another driver.
* 4 x u32 interrupt registers.
*/
@@ -704,9 +692,7 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
} else {
/* Find the function */
dprintk(DBGLVL_IRQ,
- "%s() unhandled interrupt "
- "reg 0x%x bit 0x%x "
- "intid = 0x%x\n",
+ "%s() unhandled interrupt reg 0x%x bit 0x%x intid = 0x%x\n",
__func__, i, bit, intid);
}
}
@@ -761,13 +747,11 @@ void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
{
int i;
- dprintk(1, "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+ dprintk(1, "--------------------> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
for (i = 0; i < 0x100; i += 16)
- dprintk(1, "region0[0x%08x] = "
- "%02x %02x %02x %02x %02x %02x %02x %02x"
- " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ dprintk(1, "region0[0x%08x] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ i,
(u8)saa7164_readb(addr + i + 0),
(u8)saa7164_readb(addr + i + 1),
(u8)saa7164_readb(addr + i + 2),
@@ -819,8 +803,7 @@ static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
{
- dprintk(1, "@0x%p intfdesc "
- "sizeof(struct tmComResInterfaceDescr) = %d bytes\n",
+ dprintk(1, "@0x%p intfdesc sizeof(struct tmComResInterfaceDescr) = %d bytes\n",
&dev->intfdesc, (u32)sizeof(struct tmComResInterfaceDescr));
dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
@@ -909,8 +892,7 @@ static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
{
struct saa7164_port *port = NULL;
- if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
- BUG();
+ BUG_ON((portnr < 0) || (portnr >= SAA7164_MAX_PORTS));
port = &dev->ports[portnr];
@@ -1005,8 +987,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
saa7164_port_init(dev, SAA7164_PORT_VBI2);
if (get_resources(dev) < 0) {
- printk(KERN_ERR "CORE %s No more PCIe resources for "
- "subsystem: %04x:%04x\n",
+ printk(KERN_ERR "CORE %s No more PCIe resources for subsystem: %04x:%04x\n",
dev->name, dev->pci->subsystem_vendor,
dev->pci->subsystem_device);
@@ -1024,7 +1005,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
dev->bmmio = (u8 __iomem *)dev->lmmio;
dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
- /* Inerrupt and ack register locations offset of bmmio */
+ /* Interrupt and ack register locations offset of bmmio */
dev->int_status = 0x183000 + 0xf80;
dev->int_ack = 0x183000 + 0xf90;
@@ -1059,95 +1040,127 @@ static void saa7164_dev_unregister(struct saa7164_dev *dev)
return;
}
-#ifdef CONFIG_PROC_FS
-static int saa7164_proc_show(struct seq_file *m, void *v)
+#ifdef CONFIG_DEBUG_FS
+static void *saa7164_seq_start(struct seq_file *s, loff_t *pos)
{
struct saa7164_dev *dev;
- struct tmComResBusInfo *b;
- struct list_head *list;
- int i, c;
+ loff_t index = *pos;
- if (saa7164_devcount == 0)
- return 0;
+ mutex_lock(&devlist);
+ list_for_each_entry(dev, &saa7164_devlist, devlist) {
+ if (index-- == 0) {
+ mutex_unlock(&devlist);
+ return dev;
+ }
+ }
+ mutex_unlock(&devlist);
- list_for_each(list, &saa7164_devlist) {
- dev = list_entry(list, struct saa7164_dev, devlist);
- seq_printf(m, "%s = %p\n", dev->name, dev);
+ return NULL;
+}
- /* Lock the bus from any other access */
- b = &dev->bus;
- mutex_lock(&b->lock);
+static void *saa7164_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct saa7164_dev *dev = v;
+ void *ret;
- seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
- b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
+ mutex_lock(&devlist);
+ if (list_is_last(&dev->devlist, &saa7164_devlist))
+ ret = NULL;
+ else
+ ret = list_next_entry(dev, devlist);
+ mutex_unlock(&devlist);
- seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n",
- b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
+ ++*pos;
- seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
- b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
+ return ret;
+}
- seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n",
- b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
- c = 0;
- seq_printf(m, "\n Set Ring:\n");
- seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
- for (i = 0; i < b->m_dwSizeSetRing; i++) {
- if (c == 0)
- seq_printf(m, " %04x:", i);
+static void saa7164_seq_stop(struct seq_file *s, void *v)
+{
+}
- seq_printf(m, " %02x", *(b->m_pdwSetRing + i));
+static int saa7164_seq_show(struct seq_file *m, void *v)
+{
+ struct saa7164_dev *dev = v;
+ struct tmComResBusInfo *b;
+ int i, c;
- if (++c == 16) {
- seq_printf(m, "\n");
- c = 0;
- }
- }
+ seq_printf(m, "%s = %p\n", dev->name, dev);
- c = 0;
- seq_printf(m, "\n Get Ring:\n");
- seq_printf(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
- for (i = 0; i < b->m_dwSizeGetRing; i++) {
- if (c == 0)
- seq_printf(m, " %04x:", i);
+ /* Lock the bus from any other access */
+ b = &dev->bus;
+ mutex_lock(&b->lock);
- seq_printf(m, " %02x", *(b->m_pdwGetRing + i));
+ seq_printf(m, " .m_pdwSetWritePos = 0x%x (0x%08x)\n",
+ b->m_dwSetReadPos, saa7164_readl(b->m_dwSetReadPos));
- if (++c == 16) {
- seq_printf(m, "\n");
- c = 0;
- }
+ seq_printf(m, " .m_pdwSetReadPos = 0x%x (0x%08x)\n",
+ b->m_dwSetWritePos, saa7164_readl(b->m_dwSetWritePos));
+
+ seq_printf(m, " .m_pdwGetWritePos = 0x%x (0x%08x)\n",
+ b->m_dwGetReadPos, saa7164_readl(b->m_dwGetReadPos));
+
+ seq_printf(m, " .m_pdwGetReadPos = 0x%x (0x%08x)\n",
+ b->m_dwGetWritePos, saa7164_readl(b->m_dwGetWritePos));
+ c = 0;
+ seq_puts(m, "\n Set Ring:\n");
+ seq_puts(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+ for (i = 0; i < b->m_dwSizeSetRing; i++) {
+ if (c == 0)
+ seq_printf(m, " %04x:", i);
+
+ seq_printf(m, " %02x", readb(b->m_pdwSetRing + i));
+
+ if (++c == 16) {
+ seq_puts(m, "\n");
+ c = 0;
}
+ }
+
+ c = 0;
+ seq_puts(m, "\n Get Ring:\n");
+ seq_puts(m, "\n addr 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+ for (i = 0; i < b->m_dwSizeGetRing; i++) {
+ if (c == 0)
+ seq_printf(m, " %04x:", i);
- mutex_unlock(&b->lock);
+ seq_printf(m, " %02x", readb(b->m_pdwGetRing + i));
+ if (++c == 16) {
+ seq_puts(m, "\n");
+ c = 0;
+ }
}
- return 0;
-}
+ mutex_unlock(&b->lock);
-static int saa7164_proc_open(struct inode *inode, struct file *filp)
-{
- return single_open(filp, saa7164_proc_show, NULL);
+ return 0;
}
-static const struct file_operations saa7164_proc_fops = {
- .open = saa7164_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct seq_operations saa7164_sops = {
+ .start = saa7164_seq_start,
+ .next = saa7164_seq_next,
+ .stop = saa7164_seq_stop,
+ .show = saa7164_seq_show,
};
-static int saa7164_proc_create(void)
-{
- struct proc_dir_entry *pe;
+DEFINE_SEQ_ATTRIBUTE(saa7164);
- pe = proc_create("saa7164", S_IRUGO, NULL, &saa7164_proc_fops);
- if (!pe)
- return -ENOMEM;
+static struct dentry *saa7614_dentry;
- return 0;
+static void __init saa7164_debugfs_create(void)
+{
+ saa7614_dentry = debugfs_create_file("saa7164", 0444, NULL, NULL,
+ &saa7164_fops);
+}
+
+static void __exit saa7164_debugfs_remove(void)
+{
+ debugfs_remove(saa7614_dentry);
}
+#else
+static void saa7164_debugfs_create(void) { }
+static void saa7164_debugfs_remove(void) { }
#endif
static int saa7164_thread_function(void *data)
@@ -1185,6 +1198,39 @@ static int saa7164_thread_function(void *data)
return 0;
}
+static bool saa7164_enable_msi(struct pci_dev *pci_dev, struct saa7164_dev *dev)
+{
+ int err;
+
+ if (!enable_msi) {
+ printk(KERN_WARNING "%s() MSI disabled by module parameter 'enable_msi'"
+ , __func__);
+ return false;
+ }
+
+ err = pci_enable_msi(pci_dev);
+
+ if (err) {
+ printk(KERN_ERR "%s() Failed to enable MSI interrupt. Falling back to a shared IRQ\n",
+ __func__);
+ return false;
+ }
+
+ /* no error - so request an msi interrupt */
+ err = request_irq(pci_dev->irq, saa7164_irq, 0,
+ dev->name, dev);
+
+ if (err) {
+ /* fall back to legacy interrupt */
+ printk(KERN_ERR "%s() Failed to get an MSI interrupt. Falling back to a shared IRQ\n",
+ __func__);
+ pci_disable_msi(pci_dev);
+ return false;
+ }
+
+ return true;
+}
+
static int saa7164_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
@@ -1211,33 +1257,42 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
if (saa7164_dev_setup(dev) < 0) {
err = -EINVAL;
- goto fail_free;
+ goto fail_dev;
}
/* print pci info */
dev->pci_rev = pci_dev->revision;
pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
+ printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
+ dev->name,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat,
(unsigned long long)pci_resource_start(pci_dev, 0));
pci_set_master(pci_dev);
/* TODO */
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+ err = dma_set_mask(&pci_dev->dev, 0xffffffff);
+ if (err) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
- err = -EIO;
goto fail_irq;
}
- err = request_irq(pci_dev->irq, saa7164_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
- if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
- pci_dev->irq);
- err = -EIO;
- goto fail_irq;
+ /* irq bit */
+ if (saa7164_enable_msi(pci_dev, dev)) {
+ dev->msi = true;
+ } else {
+ /* if we have an error (i.e. we don't have an interrupt)
+ or msi is not enabled - fallback to shared interrupt */
+
+ err = request_irq(pci_dev->irq, saa7164_irq,
+ IRQF_SHARED, dev->name, dev);
+
+ if (err < 0) {
+ printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
+ pci_dev->irq);
+ err = -EIO;
+ goto fail_irq;
+ }
}
pci_set_drvdata(pci_dev, dev);
@@ -1259,8 +1314,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
err = saa7164_downloadfirmware(dev);
if (err < 0) {
printk(KERN_ERR
- "Failed to boot firmware, no features "
- "registered\n");
+ "Failed to boot firmware, no features registered\n");
goto fail_fw;
}
@@ -1279,8 +1333,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
*/
version = 0;
if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
- dprintk(1, "Bus is operating correctly using "
- "version %d.%d.%d.%d (0x%x)\n",
+ dprintk(1, "Bus is operating correctly using version %d.%d.%d.%d (0x%x)\n",
(version & 0x0000fc00) >> 10,
(version & 0x000003e0) >> 5,
(version & 0x0000001f),
@@ -1308,45 +1361,43 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
/* Begin to create the video sub-systems and register funcs */
if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS1]) < 0) {
- printk(KERN_ERR "%s() Failed to register "
- "dvb adapters on porta\n",
+ printk(KERN_ERR "%s() Failed to register dvb adapters on porta\n",
__func__);
}
}
if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
if (saa7164_dvb_register(&dev->ports[SAA7164_PORT_TS2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "dvb adapters on portb\n",
+ printk(KERN_ERR"%s() Failed to register dvb adapters on portb\n",
__func__);
}
}
if (saa7164_boards[dev->board].portc == SAA7164_MPEG_ENCODER) {
if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC1]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "mpeg encoder\n", __func__);
+ printk(KERN_ERR"%s() Failed to register mpeg encoder\n",
+ __func__);
}
}
if (saa7164_boards[dev->board].portd == SAA7164_MPEG_ENCODER) {
if (saa7164_encoder_register(&dev->ports[SAA7164_PORT_ENC2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "mpeg encoder\n", __func__);
+ printk(KERN_ERR"%s() Failed to register mpeg encoder\n",
+ __func__);
}
}
if (saa7164_boards[dev->board].porte == SAA7164_MPEG_VBI) {
if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI1]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "vbi device\n", __func__);
+ printk(KERN_ERR"%s() Failed to register vbi device\n",
+ __func__);
}
}
if (saa7164_boards[dev->board].portf == SAA7164_MPEG_VBI) {
if (saa7164_vbi_register(&dev->ports[SAA7164_PORT_VBI2]) < 0) {
- printk(KERN_ERR"%s() Failed to register "
- "vbi device\n", __func__);
+ printk(KERN_ERR"%s() Failed to register vbi device\n",
+ __func__);
}
}
saa7164_api_set_debug(dev, fw_debug);
@@ -1354,15 +1405,17 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
if (fw_debug) {
dev->kthread = kthread_run(saa7164_thread_function, dev,
"saa7164 debug");
- if (!dev->kthread)
- printk(KERN_ERR "%s() Failed to create "
- "debug kernel thread\n", __func__);
+ if (IS_ERR(dev->kthread)) {
+ dev->kthread = NULL;
+ printk(KERN_ERR "%s() Failed to create debug kernel thread\n",
+ __func__);
+ }
}
} /* != BOARD_UNKNOWN */
else
- printk(KERN_ERR "%s() Unsupported board detected, "
- "registering without firmware\n", __func__);
+ printk(KERN_ERR "%s() Unsupported board detected, registering without firmware\n",
+ __func__);
dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug);
dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
@@ -1372,6 +1425,8 @@ fail_fw:
fail_irq:
saa7164_dev_unregister(dev);
+fail_dev:
+ pci_disable_device(pci_dev);
fail_free:
v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev);
@@ -1435,11 +1490,15 @@ static void saa7164_finidev(struct pci_dev *pci_dev)
saa7164_i2c_unregister(&dev->i2c_bus[1]);
saa7164_i2c_unregister(&dev->i2c_bus[2]);
- pci_disable_device(pci_dev);
-
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_set_drvdata(pci_dev, NULL);
+
+ if (dev->msi) {
+ pci_disable_msi(pci_dev);
+ dev->msi = false;
+ }
+
+ pci_disable_device(pci_dev);
mutex_lock(&devlist);
list_del(&dev->devlist);
@@ -1450,7 +1509,7 @@ static void saa7164_finidev(struct pci_dev *pci_dev)
kfree(dev);
}
-static struct pci_device_id saa7164_pci_tbl[] = {
+static const struct pci_device_id saa7164_pci_tbl[] = {
{
/* SAA7164 */
.vendor = 0x1131,
@@ -1468,29 +1527,27 @@ static struct pci_driver saa7164_pci_driver = {
.id_table = saa7164_pci_tbl,
.probe = saa7164_initdev,
.remove = saa7164_finidev,
- /* TODO */
- .suspend = NULL,
- .resume = NULL,
};
static int __init saa7164_init(void)
{
- printk(KERN_INFO "saa7164 driver loaded\n");
+ int ret = pci_register_driver(&saa7164_pci_driver);
-#ifdef CONFIG_PROC_FS
- saa7164_proc_create();
-#endif
- return pci_register_driver(&saa7164_pci_driver);
+ if (ret)
+ return ret;
+
+ saa7164_debugfs_create();
+
+ pr_info("saa7164 driver loaded\n");
+
+ return 0;
}
static void __exit saa7164_fini(void)
{
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("saa7164", NULL);
-#endif
+ saa7164_debugfs_remove();
pci_unregister_driver(&saa7164_pci_driver);
}
module_init(saa7164_init);
module_exit(saa7164_fini);
-