X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fvideo%2Fintelfb%2Fintelfbdrv.c;h=b75eda84858f62ad62937242903ba36bcf471811;hb=89661adaaee2f85116b399e642129ccd4dafd195;hp=06af89d44a0ddc90e06ab7db005de0843d96014a;hpb=c80dc60b03d633047c7f96be87fd59cdcdbb929f;p=linux-2.6-omap-h63xx.git diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 06af89d44a0..b75eda84858 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -136,6 +136,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); @@ -194,6 +196,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, @@ -446,6 +450,8 @@ cleanup(struct intelfb_info *dinfo) if (!dinfo) return; + intelfbhw_disable_irq(dinfo); + fb_dealloc_cmap(&dinfo->info->cmap); kfree(dinfo->info->pixmap.addr); @@ -467,6 +473,11 @@ cleanup(struct intelfb_info *dinfo) agp_free_memory(dinfo->gtt_ring_mem); } +#ifdef CONFIG_FB_INTEL_I2C + /* un-register I2C bus */ + intelfb_delete_i2c_busses(dinfo); +#endif + if (dinfo->mmio_base) iounmap((void __iomem *)dinfo->mmio_base); if (dinfo->aperture.virtual) @@ -529,12 +540,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) dinfo->pdev = pdev; /* Reserve pixmap space. */ - info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL); + info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL); if (info->pixmap.addr == NULL) { ERR_MSG("Cannot reserve pixmap memory.\n"); goto err_out_pixmap; } - memset(info->pixmap.addr, 0, 64 * 1024); /* set early this option because it could be changed by tv encoder driver */ @@ -844,6 +854,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) if (bailearly == 5) bailout(dinfo); +#ifdef CONFIG_FB_INTEL_I2C + /* register I2C bus */ + intelfb_create_i2c_busses(dinfo); +#endif + if (bailearly == 6) bailout(dinfo); @@ -888,6 +903,13 @@ 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; + dinfo->vsync.pan_display = 0; + dinfo->vsync.pan_offset = 0; return 0; @@ -1035,10 +1057,9 @@ intelfb_init_var(struct intelfb_info *dinfo) u8 *edid_d = NULL; if (edid_s) { - edid_d = kmalloc(EDID_LENGTH, GFP_KERNEL); + edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL); if (edid_d) { - memcpy(edid_d, edid_s, EDID_LENGTH); fb_edid_to_monspecs(edid_d, &dinfo->info->monspecs); kfree(edid_d); @@ -1187,6 +1208,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) { @@ -1433,6 +1482,19 @@ static int intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { int retval = 0; + struct intelfb_info *dinfo = GET_DINFO(info); + u32 pipe = 0; + + switch (cmd) { + case FBIO_WAITFORVSYNC: + if (get_user(pipe, (__u32 __user *)arg)) + return -EFAULT; + + retval = intelfbhw_wait_for_vsync(dinfo, pipe); + break; + default: + break; + } return retval; }