Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37241
b: refs/heads/master
c: 7649757
h: refs/heads/master
i:
  37239: 5bc37cb
v: v3
  • Loading branch information
Eric Hustvedt authored and Dave Airlie committed Jul 3, 2006
1 parent 69dc6b6 commit e7d5a94
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9a5f019b1a9ea6a75ba36d7c312ff069006ed479
refs/heads/master: 7649757bd900bc900adcd95ab08903cdc28342fa
11 changes: 11 additions & 0 deletions trunk/drivers/video/intelfb/intelfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ struct intelfb_heap_data {
u32 size; // in bytes
};

struct intelfb_vsync {
wait_queue_head_t wait;
unsigned int count;
};

struct intelfb_info {
struct fb_info *info;
struct fb_ops *fbops;
Expand Down Expand Up @@ -271,6 +276,12 @@ struct intelfb_info {
int fixed_mode;
int ring_active;
int flag;
unsigned long irq_flags;
int open;

/* vsync */
struct intelfb_vsync vsync;
spinlock_t int_lock;

/* hw cursor */
int cursor_on;
Expand Down
39 changes: 39 additions & 0 deletions trunk/drivers/video/intelfb/intelfbdrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
static void __devinit get_initial_mode(struct intelfb_info *dinfo);
static void update_dinfo(struct intelfb_info *dinfo,
struct fb_var_screeninfo *var);
static int intelfb_open(struct fb_info *info, int user);
static int intelfb_release(struct fb_info *info, int user);
static int intelfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
static int intelfb_set_par(struct fb_info *info);
Expand Down Expand Up @@ -195,6 +197,8 @@ static int num_registered = 0;
/* fb ops */
static struct fb_ops intel_fb_ops = {
.owner = THIS_MODULE,
.fb_open = intelfb_open,
.fb_release = intelfb_release,
.fb_check_var = intelfb_check_var,
.fb_set_par = intelfb_set_par,
.fb_setcolreg = intelfb_setcolreg,
Expand Down Expand Up @@ -447,6 +451,8 @@ cleanup(struct intelfb_info *dinfo)
if (!dinfo)
return;

intelfbhw_disable_irq(dinfo);

fb_dealloc_cmap(&dinfo->info->cmap);
kfree(dinfo->info->pixmap.addr);

Expand Down Expand Up @@ -889,6 +895,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}

dinfo->registered = 1;
dinfo->open = 0;

init_waitqueue_head(&dinfo->vsync.wait);
spin_lock_init(&dinfo->int_lock);
dinfo->irq_flags = 0;

return 0;

Expand Down Expand Up @@ -1188,6 +1199,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
* fbdev interface *
***************************************************************/

static int
intelfb_open(struct fb_info *info, int user)
{
struct intelfb_info *dinfo = GET_DINFO(info);

if (user) {
dinfo->open++;
}

return 0;
}

static int
intelfb_release(struct fb_info *info, int user)
{
struct intelfb_info *dinfo = GET_DINFO(info);

if (user) {
dinfo->open--;
msleep(1);
if (!dinfo->open) {
intelfbhw_disable_irq(dinfo);
}
}

return 0;
}

static int
intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
Expand Down
76 changes: 76 additions & 0 deletions trunk/drivers/video/intelfb/intelfbhw.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/interrupt.h>

#include <asm/io.h>

Expand Down Expand Up @@ -1943,3 +1944,78 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
addr += 16;
}
}

static irqreturn_t
intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) {
int handled = 0;
u16 tmp;
struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;

spin_lock(&dinfo->int_lock);

tmp = INREG16(IIR);
tmp &= VSYNC_PIPE_A_INTERRUPT;

if (tmp == 0) {
spin_unlock(&dinfo->int_lock);
return IRQ_RETVAL(handled);
}

OUTREG16(IIR, tmp);

if (tmp & VSYNC_PIPE_A_INTERRUPT) {
dinfo->vsync.count++;
wake_up_interruptible(&dinfo->vsync.wait);
handled = 1;
}

spin_unlock(&dinfo->int_lock);

return IRQ_RETVAL(handled);
}

int
intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) {

if (!test_and_set_bit(0, &dinfo->irq_flags)) {
if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) {
clear_bit(0, &dinfo->irq_flags);
return -EINVAL;
}

spin_lock_irq(&dinfo->int_lock);
OUTREG16(HWSTAM, 0xfffe);
OUTREG16(IMR, 0x0);
OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT);
spin_unlock_irq(&dinfo->int_lock);
} else if (reenable) {
u16 ier;

spin_lock_irq(&dinfo->int_lock);
ier = INREG16(IER);
if ((ier & VSYNC_PIPE_A_INTERRUPT)) {
DBG_MSG("someone disabled the IRQ [%08X]\n", ier);
OUTREG(IER, VSYNC_PIPE_A_INTERRUPT);
}
spin_unlock_irq(&dinfo->int_lock);
}
return 0;
}

void
intelfbhw_disable_irq(struct intelfb_info *dinfo) {
u16 tmp;

if (test_and_clear_bit(0, &dinfo->irq_flags)) {
spin_lock_irq(&dinfo->int_lock);
OUTREG16(HWSTAM, 0xffff);
OUTREG16(IMR, 0xffff);
OUTREG16(IER, 0x0);

tmp = INREG16(IIR);
OUTREG16(IIR, tmp);
spin_unlock_irq(&dinfo->int_lock);

free_irq(dinfo->pdev->irq, dinfo);
}
}
2 changes: 2 additions & 0 deletions trunk/drivers/video/intelfb/intelfbhw.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,5 +561,7 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
int height, u8 *data);
extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable);
extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);

#endif /* _INTELFBHW_H */

0 comments on commit e7d5a94

Please sign in to comment.