Commit e8bae927 authored by Stelian Pop's avatar Stelian Pop Committed by Linus Torvalds

[PATCH] meye driver update

* replace the pci_alloc_consistent calls with dma_alloc_coherent
  because we want to do the allocations at GFP_KERNEL priority and
  not GFP_ATOMIC because we request quite a bit of memory and the
  allocation fails quite frequently.

  It would be better to have a pci_alloc_consistent with an extra
  parameter (priority) but since we haven't, and the meye driver is
  supposed to work only on ix86 platforms we can safely do the
  change.

* fix the DMA engine stop request. The hard freezes encountered
  when using this driver and repeatedly opening/closing the device
  have been tracked down to this particular piece of code. The new
  version seems to work way better, I haven't had a single freeze
  since the change.

* fix the irq handler prototype (irqreturn_t changes).
parent aa3432a2
...@@ -167,9 +167,10 @@ static int ptable_alloc(void) { ...@@ -167,9 +167,10 @@ static int ptable_alloc(void) {
memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, meye.mchip_ptable[MCHIP_NB_PAGES] = dma_alloc_coherent(&meye.mchip_dev->dev,
PAGE_SIZE, PAGE_SIZE,
&meye.mchip_dmahandle); &meye.mchip_dmahandle,
GFP_KERNEL);
if (!meye.mchip_ptable[MCHIP_NB_PAGES]) { if (!meye.mchip_ptable[MCHIP_NB_PAGES]) {
meye.mchip_dmahandle = 0; meye.mchip_dmahandle = 0;
return -1; return -1;
...@@ -177,16 +178,17 @@ static int ptable_alloc(void) { ...@@ -177,16 +178,17 @@ static int ptable_alloc(void) {
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (i = 0; i < MCHIP_NB_PAGES; i++) { for (i = 0; i < MCHIP_NB_PAGES; i++) {
meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
PAGE_SIZE, PAGE_SIZE,
pt); pt,
GFP_KERNEL);
if (!meye.mchip_ptable[i]) { if (!meye.mchip_ptable[i]) {
int j; int j;
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (j = 0; j < i; ++j) { for (j = 0; j < i; ++j) {
pci_free_consistent(meye.mchip_dev, dma_free_coherent(&meye.mchip_dev->dev,
PAGE_SIZE, PAGE_SIZE,
meye.mchip_ptable[j], *pt); meye.mchip_ptable[j], *pt);
pt++; pt++;
} }
meye.mchip_dmahandle = 0; meye.mchip_dmahandle = 0;
...@@ -204,17 +206,17 @@ static void ptable_free(void) { ...@@ -204,17 +206,17 @@ static void ptable_free(void) {
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (i = 0; i < MCHIP_NB_PAGES; i++) { for (i = 0; i < MCHIP_NB_PAGES; i++) {
if (meye.mchip_ptable[i]) if (meye.mchip_ptable[i])
pci_free_consistent(meye.mchip_dev, dma_free_coherent(&meye.mchip_dev->dev,
PAGE_SIZE, PAGE_SIZE,
meye.mchip_ptable[i], *pt); meye.mchip_ptable[i], *pt);
pt++; pt++;
} }
if (meye.mchip_ptable[MCHIP_NB_PAGES]) if (meye.mchip_ptable[MCHIP_NB_PAGES])
pci_free_consistent(meye.mchip_dev, dma_free_coherent(&meye.mchip_dev->dev,
PAGE_SIZE, PAGE_SIZE,
meye.mchip_ptable[MCHIP_NB_PAGES], meye.mchip_ptable[MCHIP_NB_PAGES],
meye.mchip_dmahandle); meye.mchip_dmahandle);
memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
meye.mchip_dmahandle = 0; meye.mchip_dmahandle = 0;
...@@ -613,25 +615,25 @@ static void mchip_dma_free(void) { ...@@ -613,25 +615,25 @@ static void mchip_dma_free(void) {
/* stop any existing HIC action and wait for any dma to complete then /* stop any existing HIC action and wait for any dma to complete then
reset the dma engine */ reset the dma engine */
static void mchip_hic_stop(void) { static void mchip_hic_stop(void) {
int i = 0; int i, j;
meye.mchip_mode = MCHIP_HIC_MODE_NOOP; meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
return; return;
mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); for (i = 0; i < 20; ++i) {
mchip_delay(MCHIP_HIC_CMD, 0);
while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) {
/* resetting HIC */
mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
mchip_delay(MCHIP_HIC_CMD, 0); mchip_delay(MCHIP_HIC_CMD, 0);
for (j = 0; j < 100; ++j) {
if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
return;
wait_ms(1);
}
printk(KERN_ERR "meye: need to reset HIC!\n");
mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET); mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
wait_ms(250); wait_ms(250);
if (i++ > 20) {
printk(KERN_ERR "meye: resetting HIC hanged!\n");
break;
}
} }
wait_ms(100); printk(KERN_ERR "meye: resetting HIC hanged!\n");
} }
/****************************************************************************/ /****************************************************************************/
...@@ -832,7 +834,7 @@ static void mchip_cont_compression_start(void) { ...@@ -832,7 +834,7 @@ static void mchip_cont_compression_start(void) {
/* Interrupt handling */ /* Interrupt handling */
/****************************************************************************/ /****************************************************************************/
static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
u32 v; u32 v;
int reqnr; int reqnr;
v = mchip_read(MCHIP_MM_INTA); v = mchip_read(MCHIP_MM_INTA);
...@@ -840,7 +842,7 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -840,7 +842,7 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
while (1) { while (1) {
v = mchip_get_frame(); v = mchip_get_frame();
if (!(v & MCHIP_MM_FIR_RDY)) if (!(v & MCHIP_MM_FIR_RDY))
return; return IRQ_NONE;
switch (meye.mchip_mode) { switch (meye.mchip_mode) {
case MCHIP_HIC_MODE_CONT_OUT: case MCHIP_HIC_MODE_CONT_OUT:
...@@ -873,11 +875,12 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -873,11 +875,12 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
default: default:
/* do not free frame, since it can be a snap */ /* do not free frame, since it can be a snap */
return; return IRQ_NONE;
} /* switch */ } /* switch */
mchip_free_frame(); mchip_free_frame();
} }
return IRQ_HANDLED;
} }
/****************************************************************************/ /****************************************************************************/
...@@ -1391,6 +1394,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { ...@@ -1391,6 +1394,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev) {
mchip_hic_stop(); mchip_hic_stop();
mchip_dma_free();
/* disable interrupts */ /* disable interrupts */
mchip_set(MCHIP_MM_INTA, 0x0); mchip_set(MCHIP_MM_INTA, 0x0);
...@@ -1403,8 +1408,6 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { ...@@ -1403,8 +1408,6 @@ static void __devexit meye_remove(struct pci_dev *pcidev) {
pci_disable_device(meye.mchip_dev); pci_disable_device(meye.mchip_dev);
mchip_dma_free();
if (meye.grab_fbuffer) if (meye.grab_fbuffer)
rvfree(meye.grab_fbuffer, gbuffers*gbufsize); rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define _MEYE_PRIV_H_ #define _MEYE_PRIV_H_
#define MEYE_DRIVER_MAJORVERSION 1 #define MEYE_DRIVER_MAJORVERSION 1
#define MEYE_DRIVER_MINORVERSION 6 #define MEYE_DRIVER_MINORVERSION 7
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment