aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--drivers/char/agp/amd-k7-agp.c3
-rw-r--r--drivers/char/agp/frontend.c4
-rw-r--r--drivers/char/drm/ati_pcigart.c7
-rw-r--r--drivers/char/drm/drm.h17
-rw-r--r--drivers/char/drm/drmP.h133
-rw-r--r--drivers/char/drm/drm_agpsupport.c2
-rw-r--r--drivers/char/drm/drm_drv.c60
-rw-r--r--drivers/char/drm/drm_fops.c41
-rw-r--r--drivers/char/drm/drm_irq.c381
-rw-r--r--drivers/char/drm/drm_proc.c61
-rw-r--r--drivers/char/drm/drm_stub.c138
-rw-r--r--drivers/char/drm/drm_sysfs.c46
-rw-r--r--drivers/char/drm/drm_vm.c22
-rw-r--r--drivers/char/drm/i810_dma.c4
-rw-r--r--drivers/char/drm/i830_dma.c4
-rw-r--r--drivers/char/drm/i915_dma.c160
-rw-r--r--drivers/char/drm/i915_drm.h45
-rw-r--r--drivers/char/drm/i915_drv.c8
-rw-r--r--drivers/char/drm/i915_drv.h103
-rw-r--r--drivers/char/drm/i915_irq.c605
-rw-r--r--drivers/char/drm/mga_drv.c7
-rw-r--r--drivers/char/drm/mga_drv.h6
-rw-r--r--drivers/char/drm/mga_irq.c69
-rw-r--r--drivers/char/drm/r128_drv.c7
-rw-r--r--drivers/char/drm/r128_drv.h9
-rw-r--r--drivers/char/drm/r128_irq.c55
-rw-r--r--drivers/char/drm/radeon_drv.c8
-rw-r--r--drivers/char/drm/radeon_drv.h19
-rw-r--r--drivers/char/drm/radeon_irq.c171
-rw-r--r--drivers/char/drm/via_drv.c6
-rw-r--r--drivers/char/drm/via_drv.h7
-rw-r--r--drivers/char/drm/via_irq.c81
-rw-r--r--kernel/fork.c2
34 files changed, 1628 insertions, 667 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 4d350b5cbc71..4aa4180b106c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1049,9 +1049,9 @@ config MTRR
1049 See <file:Documentation/mtrr.txt> for more information. 1049 See <file:Documentation/mtrr.txt> for more information.
1050 1050
1051config X86_PAT 1051config X86_PAT
1052 def_bool y 1052 bool
1053 prompt "x86 PAT support" 1053 prompt "x86 PAT support"
1054 depends on MTRR && NONPROMISC_DEVMEM 1054 depends on MTRR
1055 help 1055 help
1056 Use PAT attributes to setup page level cache control. 1056 Use PAT attributes to setup page level cache control.
1057 1057
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index d28669992147..96bdb9296b07 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -436,8 +436,9 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
436 system controller may experience noise due to strong drive strengths 436 system controller may experience noise due to strong drive strengths
437 */ 437 */
438 if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) { 438 if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) {
439 u8 cap_ptr=0;
440 struct pci_dev *gfxcard=NULL; 439 struct pci_dev *gfxcard=NULL;
440
441 cap_ptr = 0;
441 while (!cap_ptr) { 442 while (!cap_ptr) {
442 gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); 443 gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard);
443 if (!gfxcard) { 444 if (!gfxcard) {
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 55d7a82bd071..857b26227d87 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -967,7 +967,7 @@ int agpioc_chipset_flush_wrap(struct agp_file_private *priv)
967 return 0; 967 return 0;
968} 968}
969 969
970static int agp_ioctl(struct inode *inode, struct file *file, 970static long agp_ioctl(struct file *file,
971 unsigned int cmd, unsigned long arg) 971 unsigned int cmd, unsigned long arg)
972{ 972{
973 struct agp_file_private *curr_priv = file->private_data; 973 struct agp_file_private *curr_priv = file->private_data;
@@ -1058,7 +1058,7 @@ static const struct file_operations agp_fops =
1058 .llseek = no_llseek, 1058 .llseek = no_llseek,
1059 .read = agp_read, 1059 .read = agp_read,
1060 .write = agp_write, 1060 .write = agp_write,
1061 .ioctl = agp_ioctl, 1061 .unlocked_ioctl = agp_ioctl,
1062#ifdef CONFIG_COMPAT 1062#ifdef CONFIG_COMPAT
1063 .compat_ioctl = compat_agp_ioctl, 1063 .compat_ioctl = compat_agp_ioctl,
1064#endif 1064#endif
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 141f4dfa0a11..b710426bab3e 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -167,13 +167,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
167 page_base += ATI_PCIGART_PAGE_SIZE; 167 page_base += ATI_PCIGART_PAGE_SIZE;
168 } 168 }
169 } 169 }
170
171 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
172 dma_sync_single_for_device(&dev->pdev->dev,
173 bus_address,
174 max_pages * sizeof(u32),
175 PCI_DMA_TODEVICE);
176
177 ret = 1; 170 ret = 1;
178 171
179#if defined(__i386__) || defined(__x86_64__) 172#if defined(__i386__) || defined(__x86_64__)
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 3a05c6d5ebe1..6874f31ca8ca 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -471,6 +471,7 @@ struct drm_irq_busid {
471enum drm_vblank_seq_type { 471enum drm_vblank_seq_type {
472 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ 472 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
473 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ 473 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
474 _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
474 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ 475 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
475 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ 476 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
476 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ 477 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
@@ -503,6 +504,21 @@ union drm_wait_vblank {
503 struct drm_wait_vblank_reply reply; 504 struct drm_wait_vblank_reply reply;
504}; 505};
505 506
507enum drm_modeset_ctl_cmd {
508 _DRM_PRE_MODESET = 1,
509 _DRM_POST_MODESET = 2,
510};
511
512/**
513 * DRM_IOCTL_MODESET_CTL ioctl argument type
514 *
515 * \sa drmModesetCtl().
516 */
517struct drm_modeset_ctl {
518 unsigned long arg;
519 enum drm_modeset_ctl_cmd cmd;
520};
521
506/** 522/**
507 * DRM_IOCTL_AGP_ENABLE ioctl argument type. 523 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
508 * 524 *
@@ -587,6 +603,7 @@ struct drm_set_version {
587#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) 603#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
588#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) 604#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
589#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) 605#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
606#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
590 607
591#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) 608#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
592#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) 609#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 6540948d5176..ecee3547a13f 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -100,10 +100,8 @@ struct drm_device;
100#define DRIVER_HAVE_DMA 0x20 100#define DRIVER_HAVE_DMA 0x20
101#define DRIVER_HAVE_IRQ 0x40 101#define DRIVER_HAVE_IRQ 0x40
102#define DRIVER_IRQ_SHARED 0x80 102#define DRIVER_IRQ_SHARED 0x80
103#define DRIVER_IRQ_VBL 0x100
104#define DRIVER_DMA_QUEUE 0x200 103#define DRIVER_DMA_QUEUE 0x200
105#define DRIVER_FB_DMA 0x400 104#define DRIVER_FB_DMA 0x400
106#define DRIVER_IRQ_VBL2 0x800
107 105
108/***********************************************************************/ 106/***********************************************************************/
109/** \name Begin the DRM... */ 107/** \name Begin the DRM... */
@@ -379,13 +377,12 @@ struct drm_buf_entry {
379struct drm_file { 377struct drm_file {
380 int authenticated; 378 int authenticated;
381 int master; 379 int master;
382 int minor;
383 pid_t pid; 380 pid_t pid;
384 uid_t uid; 381 uid_t uid;
385 drm_magic_t magic; 382 drm_magic_t magic;
386 unsigned long ioctl_count; 383 unsigned long ioctl_count;
387 struct list_head lhead; 384 struct list_head lhead;
388 struct drm_head *head; 385 struct drm_minor *minor;
389 int remove_auth_on_close; 386 int remove_auth_on_close;
390 unsigned long lock_count; 387 unsigned long lock_count;
391 struct file *filp; 388 struct file *filp;
@@ -580,10 +577,52 @@ struct drm_driver {
580 int (*context_dtor) (struct drm_device *dev, int context); 577 int (*context_dtor) (struct drm_device *dev, int context);
581 int (*kernel_context_switch) (struct drm_device *dev, int old, 578 int (*kernel_context_switch) (struct drm_device *dev, int old,
582 int new); 579 int new);
583 void (*kernel_context_switch_unlock) (struct drm_device *dev); 580 void (*kernel_context_switch_unlock) (struct drm_device * dev);
584 int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); 581 /**
585 int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); 582 * get_vblank_counter - get raw hardware vblank counter
586 int (*dri_library_name) (struct drm_device *dev, char *buf); 583 * @dev: DRM device
584 * @crtc: counter to fetch
585 *
586 * Driver callback for fetching a raw hardware vblank counter
587 * for @crtc. If a device doesn't have a hardware counter, the
588 * driver can simply return the value of drm_vblank_count and
589 * make the enable_vblank() and disable_vblank() hooks into no-ops,
590 * leaving interrupts enabled at all times.
591 *
592 * Wraparound handling and loss of events due to modesetting is dealt
593 * with in the DRM core code.
594 *
595 * RETURNS
596 * Raw vblank counter value.
597 */
598 u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
599
600 /**
601 * enable_vblank - enable vblank interrupt events
602 * @dev: DRM device
603 * @crtc: which irq to enable
604 *
605 * Enable vblank interrupts for @crtc. If the device doesn't have
606 * a hardware vblank counter, this routine should be a no-op, since
607 * interrupts will have to stay on to keep the count accurate.
608 *
609 * RETURNS
610 * Zero on success, appropriate errno if the given @crtc's vblank
611 * interrupt cannot be enabled.
612 */
613 int (*enable_vblank) (struct drm_device *dev, int crtc);
614
615 /**
616 * disable_vblank - disable vblank interrupt events
617 * @dev: DRM device
618 * @crtc: which irq to enable
619 *
620 * Disable vblank interrupts for @crtc. If the device doesn't have
621 * a hardware vblank counter, this routine should be a no-op, since
622 * interrupts will have to stay on to keep the count accurate.
623 */
624 void (*disable_vblank) (struct drm_device *dev, int crtc);
625 int (*dri_library_name) (struct drm_device *dev, char * buf);
587 626
588 /** 627 /**
589 * Called by \c drm_device_is_agp. Typically used to determine if a 628 * Called by \c drm_device_is_agp. Typically used to determine if a
@@ -602,7 +641,7 @@ struct drm_driver {
602 641
603 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); 642 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
604 void (*irq_preinstall) (struct drm_device *dev); 643 void (*irq_preinstall) (struct drm_device *dev);
605 void (*irq_postinstall) (struct drm_device *dev); 644 int (*irq_postinstall) (struct drm_device *dev);
606 void (*irq_uninstall) (struct drm_device *dev); 645 void (*irq_uninstall) (struct drm_device *dev);
607 void (*reclaim_buffers) (struct drm_device *dev, 646 void (*reclaim_buffers) (struct drm_device *dev,
608 struct drm_file * file_priv); 647 struct drm_file * file_priv);
@@ -630,16 +669,19 @@ struct drm_driver {
630 struct pci_driver pci_driver; 669 struct pci_driver pci_driver;
631}; 670};
632 671
672#define DRM_MINOR_UNASSIGNED 0
673#define DRM_MINOR_LEGACY 1
674
633/** 675/**
634 * DRM head structure. This structure represent a video head on a card 676 * DRM minor structure. This structure represents a drm minor number.
635 * that may contain multiple heads. Embed one per head of these in the
636 * private drm_device structure.
637 */ 677 */
638struct drm_head { 678struct drm_minor {
639 int minor; /**< Minor device number */ 679 int index; /**< Minor device number */
680 int type; /**< Control or render */
681 dev_t device; /**< Device number for mknod */
682 struct device kdev; /**< Linux device */
640 struct drm_device *dev; 683 struct drm_device *dev;
641 struct proc_dir_entry *dev_root; /**< proc directory entry */ 684 struct proc_dir_entry *dev_root; /**< proc directory entry */
642 dev_t device; /**< Device number for mknod */
643}; 685};
644 686
645/** 687/**
@@ -647,7 +689,6 @@ struct drm_head {
647 * may contain multiple heads. 689 * may contain multiple heads.
648 */ 690 */
649struct drm_device { 691struct drm_device {
650 struct device dev; /**< Linux device */
651 char *unique; /**< Unique identifier: e.g., busid */ 692 char *unique; /**< Unique identifier: e.g., busid */
652 int unique_len; /**< Length of unique field */ 693 int unique_len; /**< Length of unique field */
653 char *devname; /**< For /proc/interrupts */ 694 char *devname; /**< For /proc/interrupts */
@@ -729,13 +770,21 @@ struct drm_device {
729 /** \name VBLANK IRQ support */ 770 /** \name VBLANK IRQ support */
730 /*@{ */ 771 /*@{ */
731 772
732 wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ 773 wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
733 atomic_t vbl_received; 774 atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
734 atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
735 spinlock_t vbl_lock; 775 spinlock_t vbl_lock;
736 struct list_head vbl_sigs; /**< signal list to send on VBLANK */ 776 struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
737 struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ 777 atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
738 unsigned int vbl_pending; 778 atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */
779 u32 *last_vblank; /* protected by dev->vbl_lock, used */
780 /* for wraparound handling */
781 u32 *vblank_offset; /* used to track how many vblanks */
782 int *vblank_enabled; /* so we don't call enable more than
783 once per disable */
784 u32 *vblank_premodeset; /* were lost during modeset */
785 struct timer_list vblank_disable_timer;
786
787 unsigned long max_vblank_count; /**< size of vblank counter register */
739 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ 788 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
740 void (*locked_tasklet_func)(struct drm_device *dev); 789 void (*locked_tasklet_func)(struct drm_device *dev);
741 790
@@ -755,6 +804,7 @@ struct drm_device {
755#ifdef __alpha__ 804#ifdef __alpha__
756 struct pci_controller *hose; 805 struct pci_controller *hose;
757#endif 806#endif
807 int num_crtcs; /**< Number of CRTCs on this device */
758 struct drm_sg_mem *sg; /**< Scatter gather memory */ 808 struct drm_sg_mem *sg; /**< Scatter gather memory */
759 void *dev_private; /**< device private data */ 809 void *dev_private; /**< device private data */
760 struct drm_sigdata sigdata; /**< For block_all_signals */ 810 struct drm_sigdata sigdata; /**< For block_all_signals */
@@ -763,7 +813,7 @@ struct drm_device {
763 struct drm_driver *driver; 813 struct drm_driver *driver;
764 drm_local_map_t *agp_buffer_map; 814 drm_local_map_t *agp_buffer_map;
765 unsigned int agp_buffer_token; 815 unsigned int agp_buffer_token;
766 struct drm_head primary; /**< primary screen head */ 816 struct drm_minor *primary; /**< render type primary screen head */
767 817
768 /** \name Drawable information */ 818 /** \name Drawable information */
769 /*@{ */ 819 /*@{ */
@@ -989,11 +1039,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
989extern void drm_driver_irq_postinstall(struct drm_device *dev); 1039extern void drm_driver_irq_postinstall(struct drm_device *dev);
990extern void drm_driver_irq_uninstall(struct drm_device *dev); 1040extern void drm_driver_irq_uninstall(struct drm_device *dev);
991 1041
992extern int drm_wait_vblank(struct drm_device *dev, void *data, 1042extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
993 struct drm_file *file_priv); 1043extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp);
994extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); 1044extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
995extern void drm_vbl_send_signals(struct drm_device *dev);
996extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); 1045extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1046extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1047extern void drm_update_vblank_count(struct drm_device *dev, int crtc);
1048extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1049extern int drm_vblank_get(struct drm_device *dev, int crtc);
1050extern void drm_vblank_put(struct drm_device *dev, int crtc);
1051
1052 /* Modesetting support */
1053extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1054 struct drm_file *file_priv);
997 1055
998 /* AGP/GART support (drm_agpsupport.h) */ 1056 /* AGP/GART support (drm_agpsupport.h) */
999extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); 1057extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
@@ -1030,23 +1088,20 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
1030extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, 1088extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
1031 struct drm_driver *driver); 1089 struct drm_driver *driver);
1032extern int drm_put_dev(struct drm_device *dev); 1090extern int drm_put_dev(struct drm_device *dev);
1033extern int drm_put_head(struct drm_head *head); 1091extern int drm_put_minor(struct drm_minor **minor);
1034extern unsigned int drm_debug; 1092extern unsigned int drm_debug;
1035extern unsigned int drm_cards_limit; 1093
1036extern struct drm_head **drm_heads;
1037extern struct class *drm_class; 1094extern struct class *drm_class;
1038extern struct proc_dir_entry *drm_proc_root; 1095extern struct proc_dir_entry *drm_proc_root;
1039 1096
1097extern struct idr drm_minors_idr;
1098
1040extern drm_local_map_t *drm_getsarea(struct drm_device *dev); 1099extern drm_local_map_t *drm_getsarea(struct drm_device *dev);
1041 1100
1042 /* Proc support (drm_proc.h) */ 1101 /* Proc support (drm_proc.h) */
1043extern int drm_proc_init(struct drm_device *dev, 1102extern int drm_proc_init(struct drm_minor *minor, int minor_id,
1044 int minor, 1103 struct proc_dir_entry *root);
1045 struct proc_dir_entry *root, 1104extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);
1046 struct proc_dir_entry **dev_root);
1047extern int drm_proc_cleanup(int minor,
1048 struct proc_dir_entry *root,
1049 struct proc_dir_entry *dev_root);
1050 1105
1051 /* Scatter Gather Support (drm_scatter.h) */ 1106 /* Scatter Gather Support (drm_scatter.h) */
1052extern void drm_sg_cleanup(struct drm_sg_mem * entry); 1107extern void drm_sg_cleanup(struct drm_sg_mem * entry);
@@ -1071,8 +1126,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
1071struct drm_sysfs_class; 1126struct drm_sysfs_class;
1072extern struct class *drm_sysfs_create(struct module *owner, char *name); 1127extern struct class *drm_sysfs_create(struct module *owner, char *name);
1073extern void drm_sysfs_destroy(void); 1128extern void drm_sysfs_destroy(void);
1074extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); 1129extern int drm_sysfs_device_add(struct drm_minor *minor);
1075extern void drm_sysfs_device_remove(struct drm_device *dev); 1130extern void drm_sysfs_device_remove(struct drm_minor *minor);
1076 1131
1077/* 1132/*
1078 * Basic memory manager support (drm_mm.c) 1133 * Basic memory manager support (drm_mm.c)
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 9468c7889ff1..aefa5ac4c0b1 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -122,7 +122,7 @@ EXPORT_SYMBOL(drm_agp_acquire);
122int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, 122int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
123 struct drm_file *file_priv) 123 struct drm_file *file_priv)
124{ 124{
125 return drm_agp_acquire((struct drm_device *) file_priv->head->dev); 125 return drm_agp_acquire((struct drm_device *) file_priv->minor->dev);
126} 126}
127 127
128/** 128/**
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 0e7af53c87de..fc54140551a7 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -313,35 +313,36 @@ static void drm_cleanup(struct drm_device * dev)
313 drm_ht_remove(&dev->map_hash); 313 drm_ht_remove(&dev->map_hash);
314 drm_ctxbitmap_cleanup(dev); 314 drm_ctxbitmap_cleanup(dev);
315 315
316 drm_put_head(&dev->primary); 316 drm_put_minor(&dev->primary);
317 if (drm_put_dev(dev)) 317 if (drm_put_dev(dev))
318 DRM_ERROR("Cannot unload module\n"); 318 DRM_ERROR("Cannot unload module\n");
319} 319}
320 320
321void drm_exit(struct drm_driver *driver) 321int drm_minors_cleanup(int id, void *ptr, void *data)
322{ 322{
323 int i; 323 struct drm_minor *minor = ptr;
324 struct drm_device *dev = NULL; 324 struct drm_device *dev;
325 struct drm_head *head; 325 struct drm_driver *driver = data;
326
327 dev = minor->dev;
328 if (minor->dev->driver != driver)
329 return 0;
330
331 if (minor->type != DRM_MINOR_LEGACY)
332 return 0;
326 333
334 if (dev)
335 pci_dev_put(dev->pdev);
336 drm_cleanup(dev);
337 return 1;
338}
339
340void drm_exit(struct drm_driver *driver)
341{
327 DRM_DEBUG("\n"); 342 DRM_DEBUG("\n");
328 343
329 for (i = 0; i < drm_cards_limit; i++) { 344 idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);
330 head = drm_heads[i]; 345
331 if (!head)
332 continue;
333 if (!head->dev)
334 continue;
335 if (head->dev->driver != driver)
336 continue;
337 dev = head->dev;
338 if (dev) {
339 /* release the pci driver */
340 if (dev->pdev)
341 pci_dev_put(dev->pdev);
342 drm_cleanup(dev);
343 }
344 }
345 DRM_INFO("Module unloaded\n"); 346 DRM_INFO("Module unloaded\n");
346} 347}
347 348
@@ -357,13 +358,7 @@ static int __init drm_core_init(void)
357{ 358{
358 int ret = -ENOMEM; 359 int ret = -ENOMEM;
359 360
360 drm_cards_limit = 361 idr_init(&drm_minors_idr);
361 (drm_cards_limit <
362 DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
363 drm_heads =
364 drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
365 if (!drm_heads)
366 goto err_p1;
367 362
368 if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) 363 if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
369 goto err_p1; 364 goto err_p1;
@@ -391,7 +386,8 @@ err_p3:
391 drm_sysfs_destroy(); 386 drm_sysfs_destroy();
392err_p2: 387err_p2:
393 unregister_chrdev(DRM_MAJOR, "drm"); 388 unregister_chrdev(DRM_MAJOR, "drm");
394 drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); 389
390 idr_destroy(&drm_minors_idr);
395err_p1: 391err_p1:
396 return ret; 392 return ret;
397} 393}
@@ -403,7 +399,7 @@ static void __exit drm_core_exit(void)
403 399
404 unregister_chrdev(DRM_MAJOR, "drm"); 400 unregister_chrdev(DRM_MAJOR, "drm");
405 401
406 drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); 402 idr_destroy(&drm_minors_idr);
407} 403}
408 404
409module_init(drm_core_init); 405module_init(drm_core_init);
@@ -452,7 +448,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
452 unsigned int cmd, unsigned long arg) 448 unsigned int cmd, unsigned long arg)
453{ 449{
454 struct drm_file *file_priv = filp->private_data; 450 struct drm_file *file_priv = filp->private_data;
455 struct drm_device *dev = file_priv->head->dev; 451 struct drm_device *dev = file_priv->minor->dev;
456 struct drm_ioctl_desc *ioctl; 452 struct drm_ioctl_desc *ioctl;
457 drm_ioctl_t *func; 453 drm_ioctl_t *func;
458 unsigned int nr = DRM_IOCTL_NR(cmd); 454 unsigned int nr = DRM_IOCTL_NR(cmd);
@@ -465,7 +461,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
465 461
466 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", 462 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
467 task_pid_nr(current), cmd, nr, 463 task_pid_nr(current), cmd, nr,
468 (long)old_encode_dev(file_priv->head->device), 464 (long)old_encode_dev(file_priv->minor->device),
469 file_priv->authenticated); 465 file_priv->authenticated);
470 466
471 if ((nr >= DRM_CORE_IOCTL_COUNT) && 467 if ((nr >= DRM_CORE_IOCTL_COUNT) &&
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index f09d4b5002b0..68f0da801ed8 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -129,16 +129,15 @@ static int drm_setup(struct drm_device * dev)
129int drm_open(struct inode *inode, struct file *filp) 129int drm_open(struct inode *inode, struct file *filp)
130{ 130{
131 struct drm_device *dev = NULL; 131 struct drm_device *dev = NULL;
132 int minor = iminor(inode); 132 int minor_id = iminor(inode);
133 struct drm_minor *minor;
133 int retcode = 0; 134 int retcode = 0;
134 135
135 if (!((minor >= 0) && (minor < drm_cards_limit))) 136 minor = idr_find(&drm_minors_idr, minor_id);
137 if (!minor)
136 return -ENODEV; 138 return -ENODEV;
137 139
138 if (!drm_heads[minor]) 140 if (!(dev = minor->dev))
139 return -ENODEV;
140
141 if (!(dev = drm_heads[minor]->dev))
142 return -ENODEV; 141 return -ENODEV;
143 142
144 retcode = drm_open_helper(inode, filp, dev); 143 retcode = drm_open_helper(inode, filp, dev);
@@ -168,19 +167,18 @@ EXPORT_SYMBOL(drm_open);
168int drm_stub_open(struct inode *inode, struct file *filp) 167int drm_stub_open(struct inode *inode, struct file *filp)
169{ 168{
170 struct drm_device *dev = NULL; 169 struct drm_device *dev = NULL;
171 int minor = iminor(inode); 170 struct drm_minor *minor;
171 int minor_id = iminor(inode);
172 int err = -ENODEV; 172 int err = -ENODEV;
173 const struct file_operations *old_fops; 173 const struct file_operations *old_fops;
174 174
175 DRM_DEBUG("\n"); 175 DRM_DEBUG("\n");
176 176
177 if (!((minor >= 0) && (minor < drm_cards_limit))) 177 minor = idr_find(&drm_minors_idr, minor_id);
178 return -ENODEV; 178 if (!minor)
179
180 if (!drm_heads[minor])
181 return -ENODEV; 179 return -ENODEV;
182 180
183 if (!(dev = drm_heads[minor]->dev)) 181 if (!(dev = minor->dev))
184 return -ENODEV; 182 return -ENODEV;
185 183
186 old_fops = filp->f_op; 184 old_fops = filp->f_op;
@@ -225,7 +223,7 @@ static int drm_cpu_valid(void)
225static int drm_open_helper(struct inode *inode, struct file *filp, 223static int drm_open_helper(struct inode *inode, struct file *filp,
226 struct drm_device * dev) 224 struct drm_device * dev)
227{ 225{
228 int minor = iminor(inode); 226 int minor_id = iminor(inode);
229 struct drm_file *priv; 227 struct drm_file *priv;
230 int ret; 228 int ret;
231 229
@@ -234,7 +232,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
234 if (!drm_cpu_valid()) 232 if (!drm_cpu_valid())
235 return -EINVAL; 233 return -EINVAL;
236 234
237 DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor); 235 DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);
238 236
239 priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); 237 priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
240 if (!priv) 238 if (!priv)
@@ -245,8 +243,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
245 priv->filp = filp; 243 priv->filp = filp;
246 priv->uid = current->euid; 244 priv->uid = current->euid;
247 priv->pid = task_pid_nr(current); 245 priv->pid = task_pid_nr(current);
248 priv->minor = minor; 246 priv->minor = idr_find(&drm_minors_idr, minor_id);
249 priv->head = drm_heads[minor];
250 priv->ioctl_count = 0; 247 priv->ioctl_count = 0;
251 /* for compatibility root is always authenticated */ 248 /* for compatibility root is always authenticated */
252 priv->authenticated = capable(CAP_SYS_ADMIN); 249 priv->authenticated = capable(CAP_SYS_ADMIN);
@@ -297,11 +294,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
297int drm_fasync(int fd, struct file *filp, int on) 294int drm_fasync(int fd, struct file *filp, int on)
298{ 295{
299 struct drm_file *priv = filp->private_data; 296 struct drm_file *priv = filp->private_data;
300 struct drm_device *dev = priv->head->dev; 297 struct drm_device *dev = priv->minor->dev;
301 int retcode; 298 int retcode;
302 299
303 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, 300 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
304 (long)old_encode_dev(priv->head->device)); 301 (long)old_encode_dev(priv->minor->device));
305 retcode = fasync_helper(fd, filp, on, &dev->buf_async); 302 retcode = fasync_helper(fd, filp, on, &dev->buf_async);
306 if (retcode < 0) 303 if (retcode < 0)
307 return retcode; 304 return retcode;
@@ -324,7 +321,7 @@ EXPORT_SYMBOL(drm_fasync);
324int drm_release(struct inode *inode, struct file *filp) 321int drm_release(struct inode *inode, struct file *filp)
325{ 322{
326 struct drm_file *file_priv = filp->private_data; 323 struct drm_file *file_priv = filp->private_data;
327 struct drm_device *dev = file_priv->head->dev; 324 struct drm_device *dev = file_priv->minor->dev;
328 int retcode = 0; 325 int retcode = 0;
329 unsigned long irqflags; 326 unsigned long irqflags;
330 327
@@ -341,14 +338,14 @@ int drm_release(struct inode *inode, struct file *filp)
341 338
342 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", 339 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
343 task_pid_nr(current), 340 task_pid_nr(current),
344 (long)old_encode_dev(file_priv->head->device), 341 (long)old_encode_dev(file_priv->minor->device),
345 dev->open_count); 342 dev->open_count);
346 343
347 if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { 344 if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
348 if (drm_i_have_hw_lock(dev, file_priv)) { 345 if (drm_i_have_hw_lock(dev, file_priv)) {
349 dev->driver->reclaim_buffers_locked(dev, file_priv); 346 dev->driver->reclaim_buffers_locked(dev, file_priv);
350 } else { 347 } else {
351 unsigned long _end=jiffies + 3*DRM_HZ; 348 unsigned long endtime = jiffies + 3 * DRM_HZ;
352 int locked = 0; 349 int locked = 0;
353 350
354 drm_idlelock_take(&dev->lock); 351 drm_idlelock_take(&dev->lock);
@@ -366,7 +363,7 @@ int drm_release(struct inode *inode, struct file *filp)
366 if (locked) 363 if (locked)
367 break; 364 break;
368 schedule(); 365 schedule();
369 } while (!time_after_eq(jiffies, _end)); 366 } while (!time_after_eq(jiffies, endtime));
370 367
371 if (!locked) { 368 if (!locked) {
372 DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" 369 DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n"
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index 089c015c01d1..286f9d61e7d5 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -71,6 +71,117 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
71 return 0; 71 return 0;
72} 72}
73 73
74static void vblank_disable_fn(unsigned long arg)
75{
76 struct drm_device *dev = (struct drm_device *)arg;
77 unsigned long irqflags;
78 int i;
79
80 for (i = 0; i < dev->num_crtcs; i++) {
81 spin_lock_irqsave(&dev->vbl_lock, irqflags);
82 if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
83 dev->vblank_enabled[i]) {
84 dev->driver->disable_vblank(dev, i);
85 dev->vblank_enabled[i] = 0;
86 }
87 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
88 }
89}
90
91static void drm_vblank_cleanup(struct drm_device *dev)
92{
93 /* Bail if the driver didn't call drm_vblank_init() */
94 if (dev->num_crtcs == 0)
95 return;
96
97 del_timer(&dev->vblank_disable_timer);
98
99 vblank_disable_fn((unsigned long)dev);
100
101 drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
102 DRM_MEM_DRIVER);
103 drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
104 DRM_MEM_DRIVER);
105 drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
106 dev->num_crtcs, DRM_MEM_DRIVER);
107 drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
108 dev->num_crtcs, DRM_MEM_DRIVER);
109 drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
110 dev->num_crtcs, DRM_MEM_DRIVER);
111 drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
112 DRM_MEM_DRIVER);
113 drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) *
114 dev->num_crtcs, DRM_MEM_DRIVER);
115 drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs,
116 DRM_MEM_DRIVER);
117
118 dev->num_crtcs = 0;
119}
120
121int drm_vblank_init(struct drm_device *dev, int num_crtcs)
122{
123 int i, ret = -ENOMEM;
124
125 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
126 (unsigned long)dev);
127 spin_lock_init(&dev->vbl_lock);
128 atomic_set(&dev->vbl_signal_pending, 0);
129 dev->num_crtcs = num_crtcs;
130
131 dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
132 DRM_MEM_DRIVER);
133 if (!dev->vbl_queue)
134 goto err;
135
136 dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
137 DRM_MEM_DRIVER);
138 if (!dev->vbl_sigs)
139 goto err;
140
141 dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
142 DRM_MEM_DRIVER);
143 if (!dev->_vblank_count)
144 goto err;
145
146 dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
147 DRM_MEM_DRIVER);
148 if (!dev->vblank_refcount)
149 goto err;
150
151 dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
152 DRM_MEM_DRIVER);
153 if (!dev->vblank_enabled)
154 goto err;
155
156 dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
157 if (!dev->last_vblank)
158 goto err;
159
160 dev->vblank_premodeset = drm_calloc(num_crtcs, sizeof(u32),
161 DRM_MEM_DRIVER);
162 if (!dev->vblank_premodeset)
163 goto err;
164
165 dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
166 if (!dev->vblank_offset)
167 goto err;
168
169 /* Zero per-crtc vblank stuff */
170 for (i = 0; i < num_crtcs; i++) {
171 init_waitqueue_head(&dev->vbl_queue[i]);
172 INIT_LIST_HEAD(&dev->vbl_sigs[i]);
173 atomic_set(&dev->_vblank_count[i], 0);
174 atomic_set(&dev->vblank_refcount[i], 0);
175 }
176
177 return 0;
178
179err:
180 drm_vblank_cleanup(dev);
181 return ret;
182}
183EXPORT_SYMBOL(drm_vblank_init);
184
74/** 185/**
75 * Install IRQ handler. 186 * Install IRQ handler.
76 * 187 *
@@ -109,17 +220,6 @@ static int drm_irq_install(struct drm_device * dev)
109 220
110 DRM_DEBUG("irq=%d\n", dev->irq); 221 DRM_DEBUG("irq=%d\n", dev->irq);
111 222
112 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
113 init_waitqueue_head(&dev->vbl_queue);
114
115 spin_lock_init(&dev->vbl_lock);
116
117 INIT_LIST_HEAD(&dev->vbl_sigs);
118 INIT_LIST_HEAD(&dev->vbl_sigs2);
119
120 dev->vbl_pending = 0;
121 }
122
123 /* Before installing handler */ 223 /* Before installing handler */
124 dev->driver->irq_preinstall(dev); 224 dev->driver->irq_preinstall(dev);
125 225
@@ -137,9 +237,14 @@ static int drm_irq_install(struct drm_device * dev)
137 } 237 }
138 238
139 /* After installing handler */ 239 /* After installing handler */
140 dev->driver->irq_postinstall(dev); 240 ret = dev->driver->irq_postinstall(dev);
241 if (ret < 0) {
242 mutex_lock(&dev->struct_mutex);
243 dev->irq_enabled = 0;
244 mutex_unlock(&dev->struct_mutex);
245 }
141 246
142 return 0; 247 return ret;
143} 248}
144 249
145/** 250/**
@@ -170,6 +275,8 @@ int drm_irq_uninstall(struct drm_device * dev)
170 275
171 free_irq(dev->irq, dev); 276 free_irq(dev->irq, dev);
172 277
278 drm_vblank_cleanup(dev);
279
173 dev->locked_tasklet_func = NULL; 280 dev->locked_tasklet_func = NULL;
174 281
175 return 0; 282 return 0;
@@ -214,6 +321,148 @@ int drm_control(struct drm_device *dev, void *data,
214} 321}
215 322
216/** 323/**
324 * drm_vblank_count - retrieve "cooked" vblank counter value
325 * @dev: DRM device
326 * @crtc: which counter to retrieve
327 *
328 * Fetches the "cooked" vblank count value that represents the number of
329 * vblank events since the system was booted, including lost events due to
330 * modesetting activity.
331 */
332u32 drm_vblank_count(struct drm_device *dev, int crtc)
333{
334 return atomic_read(&dev->_vblank_count[crtc]) +
335 dev->vblank_offset[crtc];
336}
337EXPORT_SYMBOL(drm_vblank_count);
338
339/**
340 * drm_update_vblank_count - update the master vblank counter
341 * @dev: DRM device
342 * @crtc: counter to update
343 *
344 * Call back into the driver to update the appropriate vblank counter
345 * (specified by @crtc). Deal with wraparound, if it occurred, and
346 * update the last read value so we can deal with wraparound on the next
347 * call if necessary.
348 */
349void drm_update_vblank_count(struct drm_device *dev, int crtc)
350{
351 unsigned long irqflags;
352 u32 cur_vblank, diff;
353
354 /*
355 * Interrupts were disabled prior to this call, so deal with counter
356 * wrap if needed.
357 * NOTE! It's possible we lost a full dev->max_vblank_count events
358 * here if the register is small or we had vblank interrupts off for
359 * a long time.
360 */
361 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
362 spin_lock_irqsave(&dev->vbl_lock, irqflags);
363 if (cur_vblank < dev->last_vblank[crtc]) {
364 diff = dev->max_vblank_count -
365 dev->last_vblank[crtc];
366 diff += cur_vblank;
367 } else {
368 diff = cur_vblank - dev->last_vblank[crtc];
369 }
370 dev->last_vblank[crtc] = cur_vblank;
371 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
372
373 atomic_add(diff, &dev->_vblank_count[crtc]);
374}
375EXPORT_SYMBOL(drm_update_vblank_count);
376
377/**
378 * drm_vblank_get - get a reference count on vblank events
379 * @dev: DRM device
380 * @crtc: which CRTC to own
381 *
382 * Acquire a reference count on vblank events to avoid having them disabled
383 * while in use. Note callers will probably want to update the master counter
384 * using drm_update_vblank_count() above before calling this routine so that
385 * wakeups occur on the right vblank event.
386 *
387 * RETURNS
388 * Zero on success, nonzero on failure.
389 */
390int drm_vblank_get(struct drm_device *dev, int crtc)
391{
392 unsigned long irqflags;
393 int ret = 0;
394
395 spin_lock_irqsave(&dev->vbl_lock, irqflags);
396 /* Going from 0->1 means we have to enable interrupts again */
397 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
398 !dev->vblank_enabled[crtc]) {
399 ret = dev->driver->enable_vblank(dev, crtc);
400 if (ret)
401 atomic_dec(&dev->vblank_refcount[crtc]);
402 else
403 dev->vblank_enabled[crtc] = 1;
404 }
405 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
406
407 return ret;
408}
409EXPORT_SYMBOL(drm_vblank_get);
410
411/**
412 * drm_vblank_put - give up ownership of vblank events
413 * @dev: DRM device
414 * @crtc: which counter to give up
415 *
416 * Release ownership of a given vblank counter, turning off interrupts
417 * if possible.
418 */
419void drm_vblank_put(struct drm_device *dev, int crtc)
420{
421 /* Last user schedules interrupt disable */
422 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
423 mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
424}
425EXPORT_SYMBOL(drm_vblank_put);
426
427/**
428 * drm_modeset_ctl - handle vblank event counter changes across mode switch
429 * @DRM_IOCTL_ARGS: standard ioctl arguments
430 *
431 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
432 * ioctls around modesetting so that any lost vblank events are accounted for.
433 */
434int drm_modeset_ctl(struct drm_device *dev, void *data,
435 struct drm_file *file_priv)
436{
437 struct drm_modeset_ctl *modeset = data;
438 int crtc, ret = 0;
439 u32 new;
440
441 crtc = modeset->arg;
442 if (crtc >= dev->num_crtcs) {
443 ret = -EINVAL;
444 goto out;
445 }
446
447 switch (modeset->cmd) {
448 case _DRM_PRE_MODESET:
449 dev->vblank_premodeset[crtc] =
450 dev->driver->get_vblank_counter(dev, crtc);
451 break;
452 case _DRM_POST_MODESET:
453 new = dev->driver->get_vblank_counter(dev, crtc);
454 dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new;
455 break;
456 default:
457 ret = -EINVAL;
458 break;
459 }
460
461out:
462 return ret;
463}
464
465/**
217 * Wait for VBLANK. 466 * Wait for VBLANK.
218 * 467 *
219 * \param inode device inode. 468 * \param inode device inode.
@@ -232,12 +481,13 @@ int drm_control(struct drm_device *dev, void *data,
232 * 481 *
233 * If a signal is not requested, then calls vblank_wait(). 482 * If a signal is not requested, then calls vblank_wait().
234 */ 483 */
235int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) 484int drm_wait_vblank(struct drm_device *dev, void *data,
485 struct drm_file *file_priv)
236{ 486{
237 union drm_wait_vblank *vblwait = data; 487 union drm_wait_vblank *vblwait = data;
238 struct timeval now; 488 struct timeval now;
239 int ret = 0; 489 int ret = 0;
240 unsigned int flags, seq; 490 unsigned int flags, seq, crtc;
241 491
242 if ((!dev->irq) || (!dev->irq_enabled)) 492 if ((!dev->irq) || (!dev->irq_enabled))
243 return -EINVAL; 493 return -EINVAL;
@@ -251,13 +501,13 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
251 } 501 }
252 502
253 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 503 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
504 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
254 505
255 if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? 506 if (crtc >= dev->num_crtcs)
256 DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
257 return -EINVAL; 507 return -EINVAL;
258 508
259 seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 509 drm_update_vblank_count(dev, crtc);
260 : &dev->vbl_received); 510 seq = drm_vblank_count(dev, crtc);
261 511
262 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 512 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
263 case _DRM_VBLANK_RELATIVE: 513 case _DRM_VBLANK_RELATIVE:
@@ -276,8 +526,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
276 526
277 if (flags & _DRM_VBLANK_SIGNAL) { 527 if (flags & _DRM_VBLANK_SIGNAL) {
278 unsigned long irqflags; 528 unsigned long irqflags;
279 struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) 529 struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
280 ? &dev->vbl_sigs2 : &dev->vbl_sigs;
281 struct drm_vbl_sig *vbl_sig; 530 struct drm_vbl_sig *vbl_sig;
282 531
283 spin_lock_irqsave(&dev->vbl_lock, irqflags); 532 spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -298,22 +547,26 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
298 } 547 }
299 } 548 }
300 549
301 if (dev->vbl_pending >= 100) { 550 if (atomic_read(&dev->vbl_signal_pending) >= 100) {
302 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 551 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
303 return -EBUSY; 552 return -EBUSY;
304 } 553 }
305 554
306 dev->vbl_pending++;
307
308 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 555 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
309 556
310 if (! 557 vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
311 (vbl_sig = 558 DRM_MEM_DRIVER);
312 drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { 559 if (!vbl_sig)
313 return -ENOMEM; 560 return -ENOMEM;
561
562 ret = drm_vblank_get(dev, crtc);
563 if (ret) {
564 drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
565 DRM_MEM_DRIVER);
566 return ret;
314 } 567 }
315 568
316 memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); 569 atomic_inc(&dev->vbl_signal_pending);
317 570
318 vbl_sig->sequence = vblwait->request.sequence; 571 vbl_sig->sequence = vblwait->request.sequence;
319 vbl_sig->info.si_signo = vblwait->request.signal; 572 vbl_sig->info.si_signo = vblwait->request.signal;
@@ -327,17 +580,20 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
327 580
328 vblwait->reply.sequence = seq; 581 vblwait->reply.sequence = seq;
329 } else { 582 } else {
330 if (flags & _DRM_VBLANK_SECONDARY) { 583 unsigned long cur_vblank;
331 if (dev->driver->vblank_wait2) 584
332 ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); 585 ret = drm_vblank_get(dev, crtc);
333 } else if (dev->driver->vblank_wait) 586 if (ret)
334 ret = 587 return ret;
335 dev->driver->vblank_wait(dev, 588 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
336 &vblwait->request.sequence); 589 (((cur_vblank = drm_vblank_count(dev, crtc))
337 590 - vblwait->request.sequence) <= (1 << 23)));
591 drm_vblank_put(dev, crtc);
338 do_gettimeofday(&now); 592 do_gettimeofday(&now);
593
339 vblwait->reply.tval_sec = now.tv_sec; 594 vblwait->reply.tval_sec = now.tv_sec;
340 vblwait->reply.tval_usec = now.tv_usec; 595 vblwait->reply.tval_usec = now.tv_usec;
596 vblwait->reply.sequence = cur_vblank;
341 } 597 }
342 598
343 done: 599 done:
@@ -348,44 +604,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
348 * Send the VBLANK signals. 604 * Send the VBLANK signals.
349 * 605 *
350 * \param dev DRM device. 606 * \param dev DRM device.
607 * \param crtc CRTC where the vblank event occurred
351 * 608 *
352 * Sends a signal for each task in drm_device::vbl_sigs and empties the list. 609 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
353 * 610 *
354 * If a signal is not requested, then calls vblank_wait(). 611 * If a signal is not requested, then calls vblank_wait().
355 */ 612 */
356void drm_vbl_send_signals(struct drm_device * dev) 613static void drm_vbl_send_signals(struct drm_device * dev, int crtc)
357{ 614{
615 struct drm_vbl_sig *vbl_sig, *tmp;
616 struct list_head *vbl_sigs;
617 unsigned int vbl_seq;
358 unsigned long flags; 618 unsigned long flags;
359 int i;
360 619
361 spin_lock_irqsave(&dev->vbl_lock, flags); 620 spin_lock_irqsave(&dev->vbl_lock, flags);
362 621
363 for (i = 0; i < 2; i++) { 622 vbl_sigs = &dev->vbl_sigs[crtc];
364 struct drm_vbl_sig *vbl_sig, *tmp; 623 vbl_seq = drm_vblank_count(dev, crtc);
365 struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
366 unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
367 &dev->vbl_received);
368 624
369 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { 625 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
370 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { 626 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
371 vbl_sig->info.si_code = vbl_seq; 627 vbl_sig->info.si_code = vbl_seq;
372 send_sig_info(vbl_sig->info.si_signo, 628 send_sig_info(vbl_sig->info.si_signo,
373 &vbl_sig->info, vbl_sig->task); 629 &vbl_sig->info, vbl_sig->task);
374 630
375 list_del(&vbl_sig->head); 631 list_del(&vbl_sig->head);
376 632
377 drm_free(vbl_sig, sizeof(*vbl_sig), 633 drm_free(vbl_sig, sizeof(*vbl_sig),
378 DRM_MEM_DRIVER); 634 DRM_MEM_DRIVER);
379 635 atomic_dec(&dev->vbl_signal_pending);
380 dev->vbl_pending--; 636 drm_vblank_put(dev, crtc);
381 } 637 }
382 }
383 } 638 }
384 639
385 spin_unlock_irqrestore(&dev->vbl_lock, flags); 640 spin_unlock_irqrestore(&dev->vbl_lock, flags);
386} 641}
387 642
388EXPORT_SYMBOL(drm_vbl_send_signals); 643/**
644 * drm_handle_vblank - handle a vblank event
645 * @dev: DRM device
646 * @crtc: where this event occurred
647 *
648 * Drivers should call this routine in their vblank interrupt handlers to
649 * update the vblank counter and send any signals that may be pending.
650 */
651void drm_handle_vblank(struct drm_device *dev, int crtc)
652{
653 drm_update_vblank_count(dev, crtc);
654 DRM_WAKEUP(&dev->vbl_queue[crtc]);
655 drm_vbl_send_signals(dev, crtc);
656}
657EXPORT_SYMBOL(drm_handle_vblank);
389 658
390/** 659/**
391 * Tasklet wrapper function. 660 * Tasklet wrapper function.
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index d9b560fe9bbe..93b1e0475c93 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -87,34 +87,35 @@ static struct drm_proc_list {
87 * "/proc/dri/%minor%/", and each entry in proc_list as 87 * "/proc/dri/%minor%/", and each entry in proc_list as
88 * "/proc/dri/%minor%/%name%". 88 * "/proc/dri/%minor%/%name%".
89 */ 89 */
90int drm_proc_init(struct drm_device * dev, int minor, 90int drm_proc_init(struct drm_minor *minor, int minor_id,
91 struct proc_dir_entry *root, struct proc_dir_entry **dev_root) 91 struct proc_dir_entry *root)
92{ 92{
93 struct proc_dir_entry *ent; 93 struct proc_dir_entry *ent;
94 int i, j; 94 int i, j;
95 char name[64]; 95 char name[64];
96 96
97 sprintf(name, "%d", minor); 97 sprintf(name, "%d", minor_id);
98 *dev_root = proc_mkdir(name, root); 98 minor->dev_root = proc_mkdir(name, root);
99 if (!*dev_root) { 99 if (!minor->dev_root) {
100 DRM_ERROR("Cannot create /proc/dri/%s\n", name); 100 DRM_ERROR("Cannot create /proc/dri/%s\n", name);
101 return -1; 101 return -1;
102 } 102 }
103 103
104 for (i = 0; i < DRM_PROC_ENTRIES; i++) { 104 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
105 ent = create_proc_entry(drm_proc_list[i].name, 105 ent = create_proc_entry(drm_proc_list[i].name,
106 S_IFREG | S_IRUGO, *dev_root); 106 S_IFREG | S_IRUGO, minor->dev_root);
107 if (!ent) { 107 if (!ent) {
108 DRM_ERROR("Cannot create /proc/dri/%s/%s\n", 108 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
109 name, drm_proc_list[i].name); 109 name, drm_proc_list[i].name);
110 for (j = 0; j < i; j++) 110 for (j = 0; j < i; j++)
111 remove_proc_entry(drm_proc_list[i].name, 111 remove_proc_entry(drm_proc_list[i].name,
112 *dev_root); 112 minor->dev_root);
113 remove_proc_entry(name, root); 113 remove_proc_entry(name, root);
114 minor->dev_root = NULL;
114 return -1; 115 return -1;
115 } 116 }
116 ent->read_proc = drm_proc_list[i].f; 117 ent->read_proc = drm_proc_list[i].f;
117 ent->data = dev; 118 ent->data = minor;
118 } 119 }
119 120
120 return 0; 121 return 0;
@@ -130,18 +131,17 @@ int drm_proc_init(struct drm_device * dev, int minor,
130 * 131 *
131 * Remove all proc entries created by proc_init(). 132 * Remove all proc entries created by proc_init().
132 */ 133 */
133int drm_proc_cleanup(int minor, struct proc_dir_entry *root, 134int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
134 struct proc_dir_entry *dev_root)
135{ 135{
136 int i; 136 int i;
137 char name[64]; 137 char name[64];
138 138
139 if (!root || !dev_root) 139 if (!root || !minor->dev_root)
140 return 0; 140 return 0;
141 141
142 for (i = 0; i < DRM_PROC_ENTRIES; i++) 142 for (i = 0; i < DRM_PROC_ENTRIES; i++)
143 remove_proc_entry(drm_proc_list[i].name, dev_root); 143 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
144 sprintf(name, "%d", minor); 144 sprintf(name, "%d", minor->index);
145 remove_proc_entry(name, root); 145 remove_proc_entry(name, root);
146 146
147 return 0; 147 return 0;
@@ -163,7 +163,8 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
163static int drm_name_info(char *buf, char **start, off_t offset, int request, 163static int drm_name_info(char *buf, char **start, off_t offset, int request,
164 int *eof, void *data) 164 int *eof, void *data)
165{ 165{
166 struct drm_device *dev = (struct drm_device *) data; 166 struct drm_minor *minor = (struct drm_minor *) data;
167 struct drm_device *dev = minor->dev;
167 int len = 0; 168 int len = 0;
168 169
169 if (offset > DRM_PROC_LIMIT) { 170 if (offset > DRM_PROC_LIMIT) {
@@ -205,7 +206,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
205static int drm__vm_info(char *buf, char **start, off_t offset, int request, 206static int drm__vm_info(char *buf, char **start, off_t offset, int request,
206 int *eof, void *data) 207 int *eof, void *data)
207{ 208{
208 struct drm_device *dev = (struct drm_device *) data; 209 struct drm_minor *minor = (struct drm_minor *) data;
210 struct drm_device *dev = minor->dev;
209 int len = 0; 211 int len = 0;
210 struct drm_map *map; 212 struct drm_map *map;
211 struct drm_map_list *r_list; 213 struct drm_map_list *r_list;
@@ -261,7 +263,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
261static int drm_vm_info(char *buf, char **start, off_t offset, int request, 263static int drm_vm_info(char *buf, char **start, off_t offset, int request,
262 int *eof, void *data) 264 int *eof, void *data)
263{ 265{
264 struct drm_device *dev = (struct drm_device *) data; 266 struct drm_minor *minor = (struct drm_minor *) data;
267 struct drm_device *dev = minor->dev;
265 int ret; 268 int ret;
266 269
267 mutex_lock(&dev->struct_mutex); 270 mutex_lock(&dev->struct_mutex);
@@ -284,7 +287,8 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
284static int drm__queues_info(char *buf, char **start, off_t offset, 287static int drm__queues_info(char *buf, char **start, off_t offset,
285 int request, int *eof, void *data) 288 int request, int *eof, void *data)
286{ 289{
287 struct drm_device *dev = (struct drm_device *) data; 290 struct drm_minor *minor = (struct drm_minor *) data;
291 struct drm_device *dev = minor->dev;
288 int len = 0; 292 int len = 0;
289 int i; 293 int i;
290 struct drm_queue *q; 294 struct drm_queue *q;
@@ -334,7 +338,8 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
334static int drm_queues_info(char *buf, char **start, off_t offset, int request, 338static int drm_queues_info(char *buf, char **start, off_t offset, int request,
335 int *eof, void *data) 339 int *eof, void *data)
336{ 340{
337 struct drm_device *dev = (struct drm_device *) data; 341 struct drm_minor *minor = (struct drm_minor *) data;
342 struct drm_device *dev = minor->dev;
338 int ret; 343 int ret;
339 344
340 mutex_lock(&dev->struct_mutex); 345 mutex_lock(&dev->struct_mutex);
@@ -357,7 +362,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
357static int drm__bufs_info(char *buf, char **start, off_t offset, int request, 362static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
358 int *eof, void *data) 363 int *eof, void *data)
359{ 364{
360 struct drm_device *dev = (struct drm_device *) data; 365 struct drm_minor *minor = (struct drm_minor *) data;
366 struct drm_device *dev = minor->dev;
361 int len = 0; 367 int len = 0;
362 struct drm_device_dma *dma = dev->dma; 368 struct drm_device_dma *dma = dev->dma;
363 int i; 369 int i;
@@ -406,7 +412,8 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
406static int drm_bufs_info(char *buf, char **start, off_t offset, int request, 412static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
407 int *eof, void *data) 413 int *eof, void *data)
408{ 414{
409 struct drm_device *dev = (struct drm_device *) data; 415 struct drm_minor *minor = (struct drm_minor *) data;
416 struct drm_device *dev = minor->dev;
410 int ret; 417 int ret;
411 418
412 mutex_lock(&dev->struct_mutex); 419 mutex_lock(&dev->struct_mutex);
@@ -429,7 +436,8 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
429static int drm__clients_info(char *buf, char **start, off_t offset, 436static int drm__clients_info(char *buf, char **start, off_t offset,
430 int request, int *eof, void *data) 437 int request, int *eof, void *data)
431{ 438{
432 struct drm_device *dev = (struct drm_device *) data; 439 struct drm_minor *minor = (struct drm_minor *) data;
440 struct drm_device *dev = minor->dev;
433 int len = 0; 441 int len = 0;
434 struct drm_file *priv; 442 struct drm_file *priv;
435 443
@@ -445,7 +453,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
445 list_for_each_entry(priv, &dev->filelist, lhead) { 453 list_for_each_entry(priv, &dev->filelist, lhead) {
446 DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", 454 DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
447 priv->authenticated ? 'y' : 'n', 455 priv->authenticated ? 'y' : 'n',
448 priv->minor, 456 priv->minor->index,
449 priv->pid, 457 priv->pid,
450 priv->uid, priv->magic, priv->ioctl_count); 458 priv->uid, priv->magic, priv->ioctl_count);
451 } 459 }
@@ -462,7 +470,8 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
462static int drm_clients_info(char *buf, char **start, off_t offset, 470static int drm_clients_info(char *buf, char **start, off_t offset,
463 int request, int *eof, void *data) 471 int request, int *eof, void *data)
464{ 472{
465 struct drm_device *dev = (struct drm_device *) data; 473 struct drm_minor *minor = (struct drm_minor *) data;
474 struct drm_device *dev = minor->dev;
466 int ret; 475 int ret;
467 476
468 mutex_lock(&dev->struct_mutex); 477 mutex_lock(&dev->struct_mutex);
@@ -476,7 +485,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
476static int drm__vma_info(char *buf, char **start, off_t offset, int request, 485static int drm__vma_info(char *buf, char **start, off_t offset, int request,
477 int *eof, void *data) 486 int *eof, void *data)
478{ 487{
479 struct drm_device *dev = (struct drm_device *) data; 488 struct drm_minor *minor = (struct drm_minor *) data;
489 struct drm_device *dev = minor->dev;
480 int len = 0; 490 int len = 0;
481 struct drm_vma_entry *pt; 491 struct drm_vma_entry *pt;
482 struct vm_area_struct *vma; 492 struct vm_area_struct *vma;
@@ -535,7 +545,8 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
535static int drm_vma_info(char *buf, char **start, off_t offset, int request, 545static int drm_vma_info(char *buf, char **start, off_t offset, int request,
536 int *eof, void *data) 546 int *eof, void *data)
537{ 547{
538 struct drm_device *dev = (struct drm_device *) data; 548 struct drm_minor *minor = (struct drm_minor *) data;
549 struct drm_device *dev = minor->dev;
539 int ret; 550 int ret;
540 551
541 mutex_lock(&dev->struct_mutex); 552 mutex_lock(&dev->struct_mutex);
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index d93a217f856a..c2f584f3b46c 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -36,23 +36,49 @@
36#include "drmP.h" 36#include "drmP.h"
37#include "drm_core.h" 37#include "drm_core.h"
38 38
39unsigned int drm_cards_limit = 16; /* Enough for one machine */
40unsigned int drm_debug = 0; /* 1 to enable debug output */ 39unsigned int drm_debug = 0; /* 1 to enable debug output */
41EXPORT_SYMBOL(drm_debug); 40EXPORT_SYMBOL(drm_debug);
42 41
43MODULE_AUTHOR(CORE_AUTHOR); 42MODULE_AUTHOR(CORE_AUTHOR);
44MODULE_DESCRIPTION(CORE_DESC); 43MODULE_DESCRIPTION(CORE_DESC);
45MODULE_LICENSE("GPL and additional rights"); 44MODULE_LICENSE("GPL and additional rights");
46MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
47MODULE_PARM_DESC(debug, "Enable debug output"); 45MODULE_PARM_DESC(debug, "Enable debug output");
48 46
49module_param_named(cards_limit, drm_cards_limit, int, 0444);
50module_param_named(debug, drm_debug, int, 0600); 47module_param_named(debug, drm_debug, int, 0600);
51 48
52struct drm_head **drm_heads; 49struct idr drm_minors_idr;
50
53struct class *drm_class; 51struct class *drm_class;
54struct proc_dir_entry *drm_proc_root; 52struct proc_dir_entry *drm_proc_root;
55 53
54static int drm_minor_get_id(struct drm_device *dev, int type)
55{
56 int new_id;
57 int ret;
58 int base = 0, limit = 63;
59
60again:
61 if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
62 DRM_ERROR("Out of memory expanding drawable idr\n");
63 return -ENOMEM;
64 }
65 mutex_lock(&dev->struct_mutex);
66 ret = idr_get_new_above(&drm_minors_idr, NULL,
67 base, &new_id);
68 mutex_unlock(&dev->struct_mutex);
69 if (ret == -EAGAIN) {
70 goto again;
71 } else if (ret) {
72 return ret;
73 }
74
75 if (new_id >= limit) {
76 idr_remove(&drm_minors_idr, new_id);
77 return -EINVAL;
78 }
79 return new_id;
80}
81
56static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, 82static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
57 const struct pci_device_id *ent, 83 const struct pci_device_id *ent,
58 struct drm_driver *driver) 84 struct drm_driver *driver)
@@ -145,48 +171,60 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
145 * create the proc init entry via proc_init(). This routines assigns 171 * create the proc init entry via proc_init(). This routines assigns
146 * minor numbers to secondary heads of multi-headed cards 172 * minor numbers to secondary heads of multi-headed cards
147 */ 173 */
148static int drm_get_head(struct drm_device * dev, struct drm_head * head) 174static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
149{ 175{
150 struct drm_head **heads = drm_heads; 176 struct drm_minor *new_minor;
151 int ret; 177 int ret;
152 int minor; 178 int minor_id;
153 179
154 DRM_DEBUG("\n"); 180 DRM_DEBUG("\n");
155 181
156 for (minor = 0; minor < drm_cards_limit; minor++, heads++) { 182 minor_id = drm_minor_get_id(dev, type);
157 if (!*heads) { 183 if (minor_id < 0)
158 184 return minor_id;
159 *head = (struct drm_head) { 185
160 .dev = dev,.device = 186 new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL);
161 MKDEV(DRM_MAJOR, minor),.minor = minor,}; 187 if (!new_minor) {
162 188 ret = -ENOMEM;
163 if ((ret = 189 goto err_idr;
164 drm_proc_init(dev, minor, drm_proc_root, 190 }
165 &head->dev_root))) { 191
166 printk(KERN_ERR 192 new_minor->type = type;
167 "DRM: Failed to initialize /proc/dri.\n"); 193 new_minor->device = MKDEV(DRM_MAJOR, minor_id);
168 goto err_g1; 194 new_minor->dev = dev;
169 } 195 new_minor->index = minor_id;
170 196
171 ret = drm_sysfs_device_add(dev, head); 197 idr_replace(&drm_minors_idr, new_minor, minor_id);
172 if (ret) { 198
173 printk(KERN_ERR 199 if (type == DRM_MINOR_LEGACY) {
174 "DRM: Error sysfs_device_add.\n"); 200 ret = drm_proc_init(new_minor, minor_id, drm_proc_root);
175 goto err_g2; 201 if (ret) {
176 } 202 DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
177 *heads = head; 203 goto err_mem;
178
179 DRM_DEBUG("new minor assigned %d\n", minor);
180 return 0;
181 } 204 }
205 } else
206 new_minor->dev_root = NULL;
207
208 ret = drm_sysfs_device_add(new_minor);
209 if (ret) {
210 printk(KERN_ERR
211 "DRM: Error sysfs_device_add.\n");
212 goto err_g2;
182 } 213 }
183 DRM_ERROR("out of minors\n"); 214 *minor = new_minor;
184 return -ENOMEM; 215
185 err_g2: 216 DRM_DEBUG("new minor assigned %d\n", minor_id);
186 drm_proc_cleanup(minor, drm_proc_root, head->dev_root); 217 return 0;
187 err_g1: 218
188 *head = (struct drm_head) { 219
189 .dev = NULL}; 220err_g2:
221 if (new_minor->type == DRM_MINOR_LEGACY)
222 drm_proc_cleanup(new_minor, drm_proc_root);
223err_mem:
224 kfree(new_minor);
225err_idr:
226 idr_remove(&drm_minors_idr, minor_id);
227 *minor = NULL;
190 return ret; 228 return ret;
191} 229}
192 230
@@ -222,12 +260,12 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
222 printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); 260 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
223 goto err_g2; 261 goto err_g2;
224 } 262 }
225 if ((ret = drm_get_head(dev, &dev->primary))) 263 if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
226 goto err_g2; 264 goto err_g2;
227 265
228 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", 266 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
229 driver->name, driver->major, driver->minor, driver->patchlevel, 267 driver->name, driver->major, driver->minor, driver->patchlevel,
230 driver->date, dev->primary.minor); 268 driver->date, dev->primary->index);
231 269
232 return 0; 270 return 0;
233 271
@@ -276,18 +314,18 @@ int drm_put_dev(struct drm_device * dev)
276 * last minor released. 314 * last minor released.
277 * 315 *
278 */ 316 */
279int drm_put_head(struct drm_head * head) 317int drm_put_minor(struct drm_minor **minor_p)
280{ 318{
281 int minor = head->minor; 319 struct drm_minor *minor = *minor_p;
282 320 DRM_DEBUG("release secondary minor %d\n", minor->index);
283 DRM_DEBUG("release secondary minor %d\n", minor);
284
285 drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
286 drm_sysfs_device_remove(head->dev);
287 321
288 *head = (struct drm_head) {.dev = NULL}; 322 if (minor->type == DRM_MINOR_LEGACY)
323 drm_proc_cleanup(minor, drm_proc_root);
324 drm_sysfs_device_remove(minor);
289 325
290 drm_heads[minor] = NULL; 326 idr_remove(&drm_minors_idr, minor->index);
291 327
328 kfree(minor);
329 *minor_p = NULL;
292 return 0; 330 return 0;
293} 331}
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 05ed5043254f..7a1d9a782ddb 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -19,7 +19,7 @@
19#include "drm_core.h" 19#include "drm_core.h"
20#include "drmP.h" 20#include "drmP.h"
21 21
22#define to_drm_device(d) container_of(d, struct drm_device, dev) 22#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
23 23
24/** 24/**
25 * drm_sysfs_suspend - DRM class suspend hook 25 * drm_sysfs_suspend - DRM class suspend hook
@@ -31,7 +31,8 @@
31 */ 31 */
32static int drm_sysfs_suspend(struct device *dev, pm_message_t state) 32static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
33{ 33{
34 struct drm_device *drm_dev = to_drm_device(dev); 34 struct drm_minor *drm_minor = to_drm_minor(dev);
35 struct drm_device *drm_dev = drm_minor->dev;
35 36
36 printk(KERN_ERR "%s\n", __FUNCTION__); 37 printk(KERN_ERR "%s\n", __FUNCTION__);
37 38
@@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
50 */ 51 */
51static int drm_sysfs_resume(struct device *dev) 52static int drm_sysfs_resume(struct device *dev)
52{ 53{
53 struct drm_device *drm_dev = to_drm_device(dev); 54 struct drm_minor *drm_minor = to_drm_minor(dev);
55 struct drm_device *drm_dev = drm_minor->dev;
54 56
55 if (drm_dev->driver->resume) 57 if (drm_dev->driver->resume)
56 return drm_dev->driver->resume(drm_dev); 58 return drm_dev->driver->resume(drm_dev);
@@ -120,10 +122,11 @@ void drm_sysfs_destroy(void)
120static ssize_t show_dri(struct device *device, struct device_attribute *attr, 122static ssize_t show_dri(struct device *device, struct device_attribute *attr,
121 char *buf) 123 char *buf)
122{ 124{
123 struct drm_device *dev = to_drm_device(device); 125 struct drm_minor *drm_minor = to_drm_minor(device);
124 if (dev->driver->dri_library_name) 126 struct drm_device *drm_dev = drm_minor->dev;
125 return dev->driver->dri_library_name(dev, buf); 127 if (drm_dev->driver->dri_library_name)
126 return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); 128 return drm_dev->driver->dri_library_name(drm_dev, buf);
129 return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
127} 130}
128 131
129static struct device_attribute device_attrs[] = { 132static struct device_attribute device_attrs[] = {
@@ -152,25 +155,28 @@ static void drm_sysfs_device_release(struct device *dev)
152 * as the parent for the Linux device, and make sure it has a file containing 155 * as the parent for the Linux device, and make sure it has a file containing
153 * the driver we're using (for userspace compatibility). 156 * the driver we're using (for userspace compatibility).
154 */ 157 */
155int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) 158int drm_sysfs_device_add(struct drm_minor *minor)
156{ 159{
157 int err; 160 int err;
158 int i, j; 161 int i, j;
162 char *minor_str;
159 163
160 dev->dev.parent = &dev->pdev->dev; 164 minor->kdev.parent = &minor->dev->pdev->dev;
161 dev->dev.class = drm_class; 165 minor->kdev.class = drm_class;
162 dev->dev.release = drm_sysfs_device_release; 166 minor->kdev.release = drm_sysfs_device_release;
163 dev->dev.devt = head->device; 167 minor->kdev.devt = minor->device;
164 snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); 168 minor_str = "card%d";
165 169
166 err = device_register(&dev->dev); 170 snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index);
171
172 err = device_register(&minor->kdev);
167 if (err) { 173 if (err) {
168 DRM_ERROR("device add failed: %d\n", err); 174 DRM_ERROR("device add failed: %d\n", err);
169 goto err_out; 175 goto err_out;
170 } 176 }
171 177
172 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { 178 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
173 err = device_create_file(&dev->dev, &device_attrs[i]); 179 err = device_create_file(&minor->kdev, &device_attrs[i]);
174 if (err) 180 if (err)
175 goto err_out_files; 181 goto err_out_files;
176 } 182 }
@@ -180,8 +186,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head)
180err_out_files: 186err_out_files:
181 if (i > 0) 187 if (i > 0)
182 for (j = 0; j < i; j++) 188 for (j = 0; j < i; j++)
183 device_remove_file(&dev->dev, &device_attrs[i]); 189 device_remove_file(&minor->kdev, &device_attrs[i]);
184 device_unregister(&dev->dev); 190 device_unregister(&minor->kdev);
185err_out: 191err_out:
186 192
187 return err; 193 return err;
@@ -194,11 +200,11 @@ err_out:
194 * This call unregisters and cleans up a class device that was created with a 200 * This call unregisters and cleans up a class device that was created with a
195 * call to drm_sysfs_device_add() 201 * call to drm_sysfs_device_add()
196 */ 202 */
197void drm_sysfs_device_remove(struct drm_device *dev) 203void drm_sysfs_device_remove(struct drm_minor *minor)
198{ 204{
199 int i; 205 int i;
200 206
201 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) 207 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
202 device_remove_file(&dev->dev, &device_attrs[i]); 208 device_remove_file(&minor->kdev, &device_attrs[i]);
203 device_unregister(&dev->dev); 209 device_unregister(&minor->kdev);
204} 210}
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 945df72a51a9..c234c6f24a8d 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -90,7 +90,7 @@ static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
90static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 90static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
91{ 91{
92 struct drm_file *priv = vma->vm_file->private_data; 92 struct drm_file *priv = vma->vm_file->private_data;
93 struct drm_device *dev = priv->head->dev; 93 struct drm_device *dev = priv->minor->dev;
94 struct drm_map *map = NULL; 94 struct drm_map *map = NULL;
95 struct drm_map_list *r_list; 95 struct drm_map_list *r_list;
96 struct drm_hash_item *hash; 96 struct drm_hash_item *hash;
@@ -207,7 +207,7 @@ static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
207static void drm_vm_shm_close(struct vm_area_struct *vma) 207static void drm_vm_shm_close(struct vm_area_struct *vma)
208{ 208{
209 struct drm_file *priv = vma->vm_file->private_data; 209 struct drm_file *priv = vma->vm_file->private_data;
210 struct drm_device *dev = priv->head->dev; 210 struct drm_device *dev = priv->minor->dev;
211 struct drm_vma_entry *pt, *temp; 211 struct drm_vma_entry *pt, *temp;
212 struct drm_map *map; 212 struct drm_map *map;
213 struct drm_map_list *r_list; 213 struct drm_map_list *r_list;
@@ -286,7 +286,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
286static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 286static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
287{ 287{
288 struct drm_file *priv = vma->vm_file->private_data; 288 struct drm_file *priv = vma->vm_file->private_data;
289 struct drm_device *dev = priv->head->dev; 289 struct drm_device *dev = priv->minor->dev;
290 struct drm_device_dma *dma = dev->dma; 290 struct drm_device_dma *dma = dev->dma;
291 unsigned long offset; 291 unsigned long offset;
292 unsigned long page_nr; 292 unsigned long page_nr;
@@ -321,7 +321,7 @@ static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
321{ 321{
322 struct drm_map *map = (struct drm_map *) vma->vm_private_data; 322 struct drm_map *map = (struct drm_map *) vma->vm_private_data;
323 struct drm_file *priv = vma->vm_file->private_data; 323 struct drm_file *priv = vma->vm_file->private_data;
324 struct drm_device *dev = priv->head->dev; 324 struct drm_device *dev = priv->minor->dev;
325 struct drm_sg_mem *entry = dev->sg; 325 struct drm_sg_mem *entry = dev->sg;
326 unsigned long offset; 326 unsigned long offset;
327 unsigned long map_offset; 327 unsigned long map_offset;
@@ -402,7 +402,7 @@ static struct vm_operations_struct drm_vm_sg_ops = {
402static void drm_vm_open_locked(struct vm_area_struct *vma) 402static void drm_vm_open_locked(struct vm_area_struct *vma)
403{ 403{
404 struct drm_file *priv = vma->vm_file->private_data; 404 struct drm_file *priv = vma->vm_file->private_data;
405 struct drm_device *dev = priv->head->dev; 405 struct drm_device *dev = priv->minor->dev;
406 struct drm_vma_entry *vma_entry; 406 struct drm_vma_entry *vma_entry;
407 407
408 DRM_DEBUG("0x%08lx,0x%08lx\n", 408 DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -420,7 +420,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma)
420static void drm_vm_open(struct vm_area_struct *vma) 420static void drm_vm_open(struct vm_area_struct *vma)
421{ 421{
422 struct drm_file *priv = vma->vm_file->private_data; 422 struct drm_file *priv = vma->vm_file->private_data;
423 struct drm_device *dev = priv->head->dev; 423 struct drm_device *dev = priv->minor->dev;
424 424
425 mutex_lock(&dev->struct_mutex); 425 mutex_lock(&dev->struct_mutex);
426 drm_vm_open_locked(vma); 426 drm_vm_open_locked(vma);
@@ -438,7 +438,7 @@ static void drm_vm_open(struct vm_area_struct *vma)
438static void drm_vm_close(struct vm_area_struct *vma) 438static void drm_vm_close(struct vm_area_struct *vma)
439{ 439{
440 struct drm_file *priv = vma->vm_file->private_data; 440 struct drm_file *priv = vma->vm_file->private_data;
441 struct drm_device *dev = priv->head->dev; 441 struct drm_device *dev = priv->minor->dev;
442 struct drm_vma_entry *pt, *temp; 442 struct drm_vma_entry *pt, *temp;
443 443
444 DRM_DEBUG("0x%08lx,0x%08lx\n", 444 DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -473,7 +473,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
473 struct drm_device_dma *dma; 473 struct drm_device_dma *dma;
474 unsigned long length = vma->vm_end - vma->vm_start; 474 unsigned long length = vma->vm_end - vma->vm_start;
475 475
476 dev = priv->head->dev; 476 dev = priv->minor->dev;
477 dma = dev->dma; 477 dma = dev->dma;
478 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", 478 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
479 vma->vm_start, vma->vm_end, vma->vm_pgoff); 479 vma->vm_start, vma->vm_end, vma->vm_pgoff);
@@ -543,7 +543,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
543static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) 543static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
544{ 544{
545 struct drm_file *priv = filp->private_data; 545 struct drm_file *priv = filp->private_data;
546 struct drm_device *dev = priv->head->dev; 546 struct drm_device *dev = priv->minor->dev;
547 struct drm_map *map = NULL; 547 struct drm_map *map = NULL;
548 unsigned long offset = 0; 548 unsigned long offset = 0;
549 struct drm_hash_item *hash; 549 struct drm_hash_item *hash;
@@ -640,12 +640,12 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
640 /* Don't let this area swap. Change when 640 /* Don't let this area swap. Change when
641 DRM_KERNEL advisory is supported. */ 641 DRM_KERNEL advisory is supported. */
642 vma->vm_flags |= VM_RESERVED; 642 vma->vm_flags |= VM_RESERVED;
643 vma->vm_page_prot = drm_dma_prot(map->type, vma);
644 break; 643 break;
645 case _DRM_SCATTER_GATHER: 644 case _DRM_SCATTER_GATHER:
646 vma->vm_ops = &drm_vm_sg_ops; 645 vma->vm_ops = &drm_vm_sg_ops;
647 vma->vm_private_data = (void *)map; 646 vma->vm_private_data = (void *)map;
648 vma->vm_flags |= VM_RESERVED; 647 vma->vm_flags |= VM_RESERVED;
648 vma->vm_page_prot = drm_dma_prot(map->type, vma);
649 break; 649 break;
650 default: 650 default:
651 return -EINVAL; /* This should never happen. */ 651 return -EINVAL; /* This should never happen. */
@@ -661,7 +661,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
661int drm_mmap(struct file *filp, struct vm_area_struct *vma) 661int drm_mmap(struct file *filp, struct vm_area_struct *vma)
662{ 662{
663 struct drm_file *priv = filp->private_data; 663 struct drm_file *priv = filp->private_data;
664 struct drm_device *dev = priv->head->dev; 664 struct drm_device *dev = priv->minor->dev;
665 int ret; 665 int ret;
666 666
667 mutex_lock(&dev->struct_mutex); 667 mutex_lock(&dev->struct_mutex);
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 8d7ea81c4b66..e5de8ea41544 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -94,7 +94,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
94 drm_i810_buf_priv_t *buf_priv; 94 drm_i810_buf_priv_t *buf_priv;
95 95
96 lock_kernel(); 96 lock_kernel();
97 dev = priv->head->dev; 97 dev = priv->minor->dev;
98 dev_priv = dev->dev_private; 98 dev_priv = dev->dev_private;
99 buf = dev_priv->mmap_buffer; 99 buf = dev_priv->mmap_buffer;
100 buf_priv = buf->dev_private; 100 buf_priv = buf->dev_private;
@@ -122,7 +122,7 @@ static const struct file_operations i810_buffer_fops = {
122 122
123static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) 123static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
124{ 124{
125 struct drm_device *dev = file_priv->head->dev; 125 struct drm_device *dev = file_priv->minor->dev;
126 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 126 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
127 drm_i810_private_t *dev_priv = dev->dev_private; 127 drm_i810_private_t *dev_priv = dev->dev_private;
128 const struct file_operations *old_fops; 128 const struct file_operations *old_fops;
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 9df08105f4f3..60c9376be486 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -96,7 +96,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
96 drm_i830_buf_priv_t *buf_priv; 96 drm_i830_buf_priv_t *buf_priv;
97 97
98 lock_kernel(); 98 lock_kernel();
99 dev = priv->head->dev; 99 dev = priv->minor->dev;
100 dev_priv = dev->dev_private; 100 dev_priv = dev->dev_private;
101 buf = dev_priv->mmap_buffer; 101 buf = dev_priv->mmap_buffer;
102 buf_priv = buf->dev_private; 102 buf_priv = buf->dev_private;
@@ -124,7 +124,7 @@ static const struct file_operations i830_buffer_fops = {
124 124
125static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) 125static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
126{ 126{
127 struct drm_device *dev = file_priv->head->dev; 127 struct drm_device *dev = file_priv->minor->dev;
128 drm_i830_buf_priv_t *buf_priv = buf->dev_private; 128 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
129 drm_i830_private_t *dev_priv = dev->dev_private; 129 drm_i830_private_t *dev_priv = dev->dev_private;
130 const struct file_operations *old_fops; 130 const struct file_operations *old_fops;
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index a043bb12301a..ef7bf143a80c 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -415,10 +415,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
415 drm_i915_private_t *dev_priv = dev->dev_private; 415 drm_i915_private_t *dev_priv = dev->dev_private;
416 RING_LOCALS; 416 RING_LOCALS;
417 417
418 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; 418 if (++dev_priv->counter > BREADCRUMB_MASK) {
419 dev_priv->counter = 1;
420 DRM_DEBUG("Breadcrumb counter wrapped around\n");
421 }
419 422
420 if (dev_priv->counter > 0x7FFFFFFFUL) 423 if (dev_priv->sarea_priv)
421 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; 424 dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
422 425
423 BEGIN_LP_RING(4); 426 BEGIN_LP_RING(4);
424 OUT_RING(CMD_STORE_DWORD_IDX); 427 OUT_RING(CMD_STORE_DWORD_IDX);
@@ -428,6 +431,26 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
428 ADVANCE_LP_RING(); 431 ADVANCE_LP_RING();
429} 432}
430 433
434int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
435{
436 drm_i915_private_t *dev_priv = dev->dev_private;
437 uint32_t flush_cmd = CMD_MI_FLUSH;
438 RING_LOCALS;
439
440 flush_cmd |= flush;
441
442 i915_kernel_lost_context(dev);
443
444 BEGIN_LP_RING(4);
445 OUT_RING(flush_cmd);
446 OUT_RING(0);
447 OUT_RING(0);
448 OUT_RING(0);
449 ADVANCE_LP_RING();
450
451 return 0;
452}
453
431static int i915_dispatch_cmdbuffer(struct drm_device * dev, 454static int i915_dispatch_cmdbuffer(struct drm_device * dev,
432 drm_i915_cmdbuffer_t * cmd) 455 drm_i915_cmdbuffer_t * cmd)
433{ 456{
@@ -511,52 +534,74 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
511 return 0; 534 return 0;
512} 535}
513 536
514static int i915_dispatch_flip(struct drm_device * dev) 537static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
515{ 538{
516 drm_i915_private_t *dev_priv = dev->dev_private; 539 drm_i915_private_t *dev_priv = dev->dev_private;
540 u32 num_pages, current_page, next_page, dspbase;
541 int shift = 2 * plane, x, y;
517 RING_LOCALS; 542 RING_LOCALS;
518 543
519 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 544 /* Calculate display base offset */
520 __FUNCTION__, 545 num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
521 dev_priv->current_page, 546 current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
522 dev_priv->sarea_priv->pf_current_page); 547 next_page = (current_page + 1) % num_pages;
523 548
524 i915_kernel_lost_context(dev); 549 switch (next_page) {
525 550 default:
526 BEGIN_LP_RING(2); 551 case 0:
527 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 552 dspbase = dev_priv->sarea_priv->front_offset;
528 OUT_RING(0); 553 break;
529 ADVANCE_LP_RING(); 554 case 1:
555 dspbase = dev_priv->sarea_priv->back_offset;
556 break;
557 case 2:
558 dspbase = dev_priv->sarea_priv->third_offset;
559 break;
560 }
530 561
531 BEGIN_LP_RING(6); 562 if (plane == 0) {
532 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 563 x = dev_priv->sarea_priv->planeA_x;
533 OUT_RING(0); 564 y = dev_priv->sarea_priv->planeA_y;
534 if (dev_priv->current_page == 0) {
535 OUT_RING(dev_priv->back_offset);
536 dev_priv->current_page = 1;
537 } else { 565 } else {
538 OUT_RING(dev_priv->front_offset); 566 x = dev_priv->sarea_priv->planeB_x;
539 dev_priv->current_page = 0; 567 y = dev_priv->sarea_priv->planeB_y;
540 } 568 }
541 OUT_RING(0);
542 ADVANCE_LP_RING();
543 569
544 BEGIN_LP_RING(2); 570 dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
545 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
546 OUT_RING(0);
547 ADVANCE_LP_RING();
548 571
549 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 572 DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page,
573 dspbase);
550 574
551 BEGIN_LP_RING(4); 575 BEGIN_LP_RING(4);
552 OUT_RING(CMD_STORE_DWORD_IDX); 576 OUT_RING(sync ? 0 :
553 OUT_RING(20); 577 (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP :
554 OUT_RING(dev_priv->counter); 578 MI_WAIT_FOR_PLANE_A_FLIP)));
555 OUT_RING(0); 579 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
580 (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
581 OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
582 OUT_RING(dspbase);
556 ADVANCE_LP_RING(); 583 ADVANCE_LP_RING();
557 584
558 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 585 dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
559 return 0; 586 dev_priv->sarea_priv->pf_current_page |= next_page << shift;
587}
588
589void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
590{
591 drm_i915_private_t *dev_priv = dev->dev_private;
592 int i;
593
594 DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
595 planes, dev_priv->sarea_priv->pf_current_page);
596
597 i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
598
599 for (i = 0; i < 2; i++)
600 if (planes & (1 << i))
601 i915_do_dispatch_flip(dev, i, sync);
602
603 i915_emit_breadcrumb(dev);
604
560} 605}
561 606
562static int i915_quiescent(struct drm_device * dev) 607static int i915_quiescent(struct drm_device * dev)
@@ -579,7 +624,6 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
579 struct drm_file *file_priv) 624 struct drm_file *file_priv)
580{ 625{
581 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 626 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
582 u32 *hw_status = dev_priv->hw_status_page;
583 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 627 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
584 dev_priv->sarea_priv; 628 dev_priv->sarea_priv;
585 drm_i915_batchbuffer_t *batch = data; 629 drm_i915_batchbuffer_t *batch = data;
@@ -602,7 +646,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
602 646
603 ret = i915_dispatch_batchbuffer(dev, batch); 647 ret = i915_dispatch_batchbuffer(dev, batch);
604 648
605 sarea_priv->last_dispatch = (int)hw_status[5]; 649 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
606 return ret; 650 return ret;
607} 651}
608 652
@@ -610,7 +654,6 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
610 struct drm_file *file_priv) 654 struct drm_file *file_priv)
611{ 655{
612 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 656 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
613 u32 *hw_status = dev_priv->hw_status_page;
614 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 657 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
615 dev_priv->sarea_priv; 658 dev_priv->sarea_priv;
616 drm_i915_cmdbuffer_t *cmdbuf = data; 659 drm_i915_cmdbuffer_t *cmdbuf = data;
@@ -635,18 +678,51 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
635 return ret; 678 return ret;
636 } 679 }
637 680
638 sarea_priv->last_dispatch = (int)hw_status[5]; 681 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
682 return 0;
683}
684
685static int i915_do_cleanup_pageflip(struct drm_device * dev)
686{
687 drm_i915_private_t *dev_priv = dev->dev_private;
688 int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
689
690 DRM_DEBUG("\n");
691
692 for (i = 0, planes = 0; i < 2; i++)
693 if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
694 dev_priv->sarea_priv->pf_current_page =
695 (dev_priv->sarea_priv->pf_current_page &
696 ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
697
698 planes |= 1 << i;
699 }
700
701 if (planes)
702 i915_dispatch_flip(dev, planes, 0);
703
639 return 0; 704 return 0;
640} 705}
641 706
642static int i915_flip_bufs(struct drm_device *dev, void *data, 707static int i915_flip_bufs(struct drm_device *dev, void *data,
643 struct drm_file *file_priv) 708 struct drm_file *file_priv)
644{ 709{
645 DRM_DEBUG("%s\n", __FUNCTION__); 710 drm_i915_flip_t *param = data;
711
712 DRM_DEBUG("\n");
646 713
647 LOCK_TEST_WITH_RETURN(dev, file_priv); 714 LOCK_TEST_WITH_RETURN(dev, file_priv);
648 715
649 return i915_dispatch_flip(dev); 716 /* This is really planes */
717 if (param->pipes & ~0x3) {
718 DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n",
719 param->pipes);
720 return -EINVAL;
721 }
722
723 i915_dispatch_flip(dev, param->pipes, 0);
724
725 return 0;
650} 726}
651 727
652static int i915_getparam(struct drm_device *dev, void *data, 728static int i915_getparam(struct drm_device *dev, void *data,
@@ -807,6 +883,8 @@ void i915_driver_lastclose(struct drm_device * dev)
807 if (!dev_priv) 883 if (!dev_priv)
808 return; 884 return;
809 885
886 if (drm_getsarea(dev) && dev_priv->sarea_priv)
887 i915_do_cleanup_pageflip(dev);
810 if (dev_priv->agp_heap) 888 if (dev_priv->agp_heap)
811 i915_mem_takedown(&(dev_priv->agp_heap)); 889 i915_mem_takedown(&(dev_priv->agp_heap));
812 890
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 05c66cf03a9e..0431c00e2289 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -105,14 +105,29 @@ typedef struct _drm_i915_sarea {
105 unsigned int rotated_tiled; 105 unsigned int rotated_tiled;
106 unsigned int rotated2_tiled; 106 unsigned int rotated2_tiled;
107 107
108 int pipeA_x; 108 int planeA_x;
109 int pipeA_y; 109 int planeA_y;
110 int pipeA_w; 110 int planeA_w;
111 int pipeA_h; 111 int planeA_h;
112 int pipeB_x; 112 int planeB_x;
113 int pipeB_y; 113 int planeB_y;
114 int pipeB_w; 114 int planeB_w;
115 int pipeB_h; 115 int planeB_h;
116
117 /* Triple buffering */
118 drm_handle_t third_handle;
119 int third_offset;
120 int third_size;
121 unsigned int third_tiled;
122
123 /* buffer object handles for the static buffers. May change
124 * over the lifetime of the client, though it doesn't in our current
125 * implementation.
126 */
127 unsigned int front_bo_handle;
128 unsigned int back_bo_handle;
129 unsigned int third_bo_handle;
130 unsigned int depth_bo_handle;
116} drm_i915_sarea_t; 131} drm_i915_sarea_t;
117 132
118/* Flags for perf_boxes 133/* Flags for perf_boxes
@@ -146,7 +161,7 @@ typedef struct _drm_i915_sarea {
146 161
147#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 162#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
148#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) 163#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
149#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) 164#define DRM_IOCTL_I915_FLIP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FLIP, drm_i915_flip_t)
150#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) 165#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
151#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) 166#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
152#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) 167#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
@@ -161,6 +176,18 @@ typedef struct _drm_i915_sarea {
161#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) 176#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
162#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) 177#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
163 178
179/* Asynchronous page flipping:
180 */
181typedef struct drm_i915_flip {
182 /*
183 * This is really talking about planes, and we could rename it
184 * except for the fact that some of the duplicated i915_drm.h files
185 * out there check for HAVE_I915_FLIP and so might pick up this
186 * version.
187 */
188 int pipes;
189} drm_i915_flip_t;
190
164/* Allow drivers to submit batchbuffers directly to hardware, relying 191/* Allow drivers to submit batchbuffers directly to hardware, relying
165 * on the security mechanisms provided by hardware. 192 * on the security mechanisms provided by hardware.
166 */ 193 */
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index b2b451dc4460..bb8f1b2fb383 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -533,8 +533,7 @@ static struct drm_driver driver = {
533 */ 533 */
534 .driver_features = 534 .driver_features =
535 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ 535 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
536 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | 536 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
537 DRIVER_IRQ_VBL2,
538 .load = i915_driver_load, 537 .load = i915_driver_load,
539 .unload = i915_driver_unload, 538 .unload = i915_driver_unload,
540 .lastclose = i915_driver_lastclose, 539 .lastclose = i915_driver_lastclose,
@@ -542,8 +541,9 @@ static struct drm_driver driver = {
542 .suspend = i915_suspend, 541 .suspend = i915_suspend,
543 .resume = i915_resume, 542 .resume = i915_resume,
544 .device_is_agp = i915_driver_device_is_agp, 543 .device_is_agp = i915_driver_device_is_agp,
545 .vblank_wait = i915_driver_vblank_wait, 544 .get_vblank_counter = i915_get_vblank_counter,
546 .vblank_wait2 = i915_driver_vblank_wait2, 545 .enable_vblank = i915_enable_vblank,
546 .disable_vblank = i915_disable_vblank,
547 .irq_preinstall = i915_driver_irq_preinstall, 547 .irq_preinstall = i915_driver_irq_preinstall,
548 .irq_postinstall = i915_driver_irq_postinstall, 548 .irq_postinstall = i915_driver_irq_postinstall,
549 .irq_uninstall = i915_driver_irq_uninstall, 549 .irq_uninstall = i915_driver_irq_uninstall,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 675d88bda066..c614d78b3dfd 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -76,8 +76,9 @@ struct mem_block {
76typedef struct _drm_i915_vbl_swap { 76typedef struct _drm_i915_vbl_swap {
77 struct list_head head; 77 struct list_head head;
78 drm_drawable_t drw_id; 78 drm_drawable_t drw_id;
79 unsigned int pipe; 79 unsigned int plane;
80 unsigned int sequence; 80 unsigned int sequence;
81 int flip;
81} drm_i915_vbl_swap_t; 82} drm_i915_vbl_swap_t;
82 83
83typedef struct drm_i915_private { 84typedef struct drm_i915_private {
@@ -90,7 +91,7 @@ typedef struct drm_i915_private {
90 drm_dma_handle_t *status_page_dmah; 91 drm_dma_handle_t *status_page_dmah;
91 void *hw_status_page; 92 void *hw_status_page;
92 dma_addr_t dma_status_page; 93 dma_addr_t dma_status_page;
93 unsigned long counter; 94 uint32_t counter;
94 unsigned int status_gfx_addr; 95 unsigned int status_gfx_addr;
95 drm_local_map_t hws_map; 96 drm_local_map_t hws_map;
96 97
@@ -103,13 +104,18 @@ typedef struct drm_i915_private {
103 104
104 wait_queue_head_t irq_queue; 105 wait_queue_head_t irq_queue;
105 atomic_t irq_received; 106 atomic_t irq_received;
106 atomic_t irq_emitted; 107 atomic_t irq_emited;
107 108
108 int tex_lru_log_granularity; 109 int tex_lru_log_granularity;
109 int allow_batchbuffer; 110 int allow_batchbuffer;
110 struct mem_block *agp_heap; 111 struct mem_block *agp_heap;
111 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; 112 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
112 int vblank_pipe; 113 int vblank_pipe;
114 spinlock_t user_irq_lock;
115 int user_irq_refcount;
116 int fence_irq_on;
117 uint32_t irq_enable_reg;
118 int irq_enabled;
113 119
114 spinlock_t swaps_lock; 120 spinlock_t swaps_lock;
115 drm_i915_vbl_swap_t vbl_swaps; 121 drm_i915_vbl_swap_t vbl_swaps;
@@ -216,7 +222,7 @@ extern void i915_driver_preclose(struct drm_device *dev,
216extern int i915_driver_device_is_agp(struct drm_device * dev); 222extern int i915_driver_device_is_agp(struct drm_device * dev);
217extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, 223extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
218 unsigned long arg); 224 unsigned long arg);
219 225extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
220/* i915_irq.c */ 226/* i915_irq.c */
221extern int i915_irq_emit(struct drm_device *dev, void *data, 227extern int i915_irq_emit(struct drm_device *dev, void *data,
222 struct drm_file *file_priv); 228 struct drm_file *file_priv);
@@ -227,7 +233,7 @@ extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequenc
227extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); 233extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
228extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 234extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
229extern void i915_driver_irq_preinstall(struct drm_device * dev); 235extern void i915_driver_irq_preinstall(struct drm_device * dev);
230extern void i915_driver_irq_postinstall(struct drm_device * dev); 236extern int i915_driver_irq_postinstall(struct drm_device * dev);
231extern void i915_driver_irq_uninstall(struct drm_device * dev); 237extern void i915_driver_irq_uninstall(struct drm_device * dev);
232extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, 238extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
233 struct drm_file *file_priv); 239 struct drm_file *file_priv);
@@ -235,6 +241,9 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
235 struct drm_file *file_priv); 241 struct drm_file *file_priv);
236extern int i915_vblank_swap(struct drm_device *dev, void *data, 242extern int i915_vblank_swap(struct drm_device *dev, void *data,
237 struct drm_file *file_priv); 243 struct drm_file *file_priv);
244extern int i915_enable_vblank(struct drm_device *dev, int crtc);
245extern void i915_disable_vblank(struct drm_device *dev, int crtc);
246extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
238 247
239/* i915_mem.c */ 248/* i915_mem.c */
240extern int i915_mem_alloc(struct drm_device *dev, void *data, 249extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -379,21 +388,91 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
379 388
380/* Interrupt bits: 389/* Interrupt bits:
381 */ 390 */
382#define USER_INT_FLAG (1<<1) 391#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
383#define VSYNC_PIPEB_FLAG (1<<5) 392#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
384#define VSYNC_PIPEA_FLAG (1<<7) 393#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
385#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ 394#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
395#define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */
396#define I915_SYNC_STATUS_INTERRUPT (1<<12)
397#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
398#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
399#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
400#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
401#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
402#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
403#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
404#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
405#define I915_DEBUG_INTERRUPT (1<<2)
406#define I915_USER_INTERRUPT (1<<1)
407
386 408
387#define I915REG_HWSTAM 0x02098 409#define I915REG_HWSTAM 0x02098
388#define I915REG_INT_IDENTITY_R 0x020a4 410#define I915REG_INT_IDENTITY_R 0x020a4
389#define I915REG_INT_MASK_R 0x020a8 411#define I915REG_INT_MASK_R 0x020a8
390#define I915REG_INT_ENABLE_R 0x020a0 412#define I915REG_INT_ENABLE_R 0x020a0
413#define I915REG_INSTPM 0x020c0
414
415#define PIPEADSL 0x70000
416#define PIPEBDSL 0x71000
391 417
392#define I915REG_PIPEASTAT 0x70024 418#define I915REG_PIPEASTAT 0x70024
393#define I915REG_PIPEBSTAT 0x71024 419#define I915REG_PIPEBSTAT 0x71024
420/*
421 * The two pipe frame counter registers are not synchronized, so
422 * reading a stable value is somewhat tricky. The following code
423 * should work:
424 *
425 * do {
426 * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
427 * PIPE_FRAME_HIGH_SHIFT;
428 * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
429 * PIPE_FRAME_LOW_SHIFT);
430 * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
431 * PIPE_FRAME_HIGH_SHIFT);
432 * } while (high1 != high2);
433 * frame = (high1 << 8) | low1;
434 */
435#define PIPEAFRAMEHIGH 0x70040
436#define PIPEBFRAMEHIGH 0x71040
437#define PIPE_FRAME_HIGH_MASK 0x0000ffff
438#define PIPE_FRAME_HIGH_SHIFT 0
439#define PIPEAFRAMEPIXEL 0x70044
440#define PIPEBFRAMEPIXEL 0x71044
394 441
395#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) 442#define PIPE_FRAME_LOW_MASK 0xff000000
396#define I915_VBLANK_CLEAR (1UL<<1) 443#define PIPE_FRAME_LOW_SHIFT 24
444/*
445 * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
446 * and is 24 bits wide.
447 */
448#define PIPE_PIXEL_MASK 0x00ffffff
449#define PIPE_PIXEL_SHIFT 0
450
451#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
452#define I915_CRC_ERROR_ENABLE (1UL<<29)
453#define I915_CRC_DONE_ENABLE (1UL<<28)
454#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
455#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
456#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
457#define I915_DPST_EVENT_ENABLE (1UL<<23)
458#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
459#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
460#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
461#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
462#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
463#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
464#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
465#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
466#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
467#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
468#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
469#define I915_DPST_EVENT_STATUS (1UL<<7)
470#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
471#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
472#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
473#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
474#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
475#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
397 476
398#define SRX_INDEX 0x3c4 477#define SRX_INDEX 0x3c4
399#define SRX_DATA 0x3c5 478#define SRX_DATA 0x3c5
@@ -566,6 +645,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
566#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) 645#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
567#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) 646#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
568#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) 647#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
648#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
649#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
569 650
570#define MI_BATCH_BUFFER ((0x30<<23)|1) 651#define MI_BATCH_BUFFER ((0x30<<23)|1)
571#define MI_BATCH_BUFFER_START (0x31<<23) 652#define MI_BATCH_BUFFER_START (0x31<<23)
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 92653b38e64c..023ce66ef3ab 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -38,6 +38,109 @@
38#define MAX_NOPID ((u32)~0) 38#define MAX_NOPID ((u32)~0)
39 39
40/** 40/**
41 * i915_get_pipe - return the the pipe associated with a given plane
42 * @dev: DRM device
43 * @plane: plane to look for
44 *
45 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
46 * rather than a pipe number, since they may not always be equal. This routine
47 * maps the given @plane back to a pipe number.
48 */
49static int
50i915_get_pipe(struct drm_device *dev, int plane)
51{
52 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
53 u32 dspcntr;
54
55 dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
56
57 return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
58}
59
60/**
61 * i915_get_plane - return the the plane associated with a given pipe
62 * @dev: DRM device
63 * @pipe: pipe to look for
64 *
65 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
66 * rather than a plane number, since they may not always be equal. This routine
67 * maps the given @pipe back to a plane number.
68 */
69static int
70i915_get_plane(struct drm_device *dev, int pipe)
71{
72 if (i915_get_pipe(dev, 0) == pipe)
73 return 0;
74 return 1;
75}
76
77/**
78 * i915_pipe_enabled - check if a pipe is enabled
79 * @dev: DRM device
80 * @pipe: pipe to check
81 *
82 * Reading certain registers when the pipe is disabled can hang the chip.
83 * Use this routine to make sure the PLL is running and the pipe is active
84 * before reading such registers if unsure.
85 */
86static int
87i915_pipe_enabled(struct drm_device *dev, int pipe)
88{
89 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
90 unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
91
92 if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
93 return 1;
94
95 return 0;
96}
97
98/**
99 * Emit a synchronous flip.
100 *
101 * This function must be called with the drawable spinlock held.
102 */
103static void
104i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
105 int plane)
106{
107 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
108 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
109 u16 x1, y1, x2, y2;
110 int pf_planes = 1 << plane;
111
112 /* If the window is visible on the other plane, we have to flip on that
113 * plane as well.
114 */
115 if (plane == 1) {
116 x1 = sarea_priv->planeA_x;
117 y1 = sarea_priv->planeA_y;
118 x2 = x1 + sarea_priv->planeA_w;
119 y2 = y1 + sarea_priv->planeA_h;
120 } else {
121 x1 = sarea_priv->planeB_x;
122 y1 = sarea_priv->planeB_y;
123 x2 = x1 + sarea_priv->planeB_w;
124 y2 = y1 + sarea_priv->planeB_h;
125 }
126
127 if (x2 > 0 && y2 > 0) {
128 int i, num_rects = drw->num_rects;
129 struct drm_clip_rect *rect = drw->rects;
130
131 for (i = 0; i < num_rects; i++)
132 if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 ||
133 rect[i].x2 <= x1 || rect[i].y2 <= y1)) {
134 pf_planes = 0x3;
135
136 break;
137 }
138 }
139
140 i915_dispatch_flip(dev, pf_planes, 1);
141}
142
143/**
41 * Emit blits for scheduled buffer swaps. 144 * Emit blits for scheduled buffer swaps.
42 * 145 *
43 * This function will be called with the HW lock held. 146 * This function will be called with the HW lock held.
@@ -45,40 +148,59 @@
45static void i915_vblank_tasklet(struct drm_device *dev) 148static void i915_vblank_tasklet(struct drm_device *dev)
46{ 149{
47 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 150 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
48 unsigned long irqflags;
49 struct list_head *list, *tmp, hits, *hit; 151 struct list_head *list, *tmp, hits, *hit;
50 int nhits, nrects, slice[2], upper[2], lower[2], i; 152 int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
51 unsigned counter[2] = { atomic_read(&dev->vbl_received), 153 unsigned counter[2];
52 atomic_read(&dev->vbl_received2) };
53 struct drm_drawable_info *drw; 154 struct drm_drawable_info *drw;
54 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; 155 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
55 u32 cpp = dev_priv->cpp; 156 u32 cpp = dev_priv->cpp, offsets[3];
56 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | 157 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
57 XY_SRC_COPY_BLT_WRITE_ALPHA | 158 XY_SRC_COPY_BLT_WRITE_ALPHA |
58 XY_SRC_COPY_BLT_WRITE_RGB) 159 XY_SRC_COPY_BLT_WRITE_RGB)
59 : XY_SRC_COPY_BLT_CMD; 160 : XY_SRC_COPY_BLT_CMD;
60 u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | 161 u32 src_pitch = sarea_priv->pitch * cpp;
61 (cpp << 23) | (1 << 24); 162 u32 dst_pitch = sarea_priv->pitch * cpp;
163 /* COPY rop (0xcc), map cpp to magic color depth constants */
164 u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
62 RING_LOCALS; 165 RING_LOCALS;
63 166
167 if (sarea_priv->front_tiled) {
168 cmd |= XY_SRC_COPY_BLT_DST_TILED;
169 dst_pitch >>= 2;
170 }
171 if (sarea_priv->back_tiled) {
172 cmd |= XY_SRC_COPY_BLT_SRC_TILED;
173 src_pitch >>= 2;
174 }
175
176 counter[0] = drm_vblank_count(dev, 0);
177 counter[1] = drm_vblank_count(dev, 1);
178
64 DRM_DEBUG("\n"); 179 DRM_DEBUG("\n");
65 180
66 INIT_LIST_HEAD(&hits); 181 INIT_LIST_HEAD(&hits);
67 182
68 nhits = nrects = 0; 183 nhits = nrects = 0;
69 184
70 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 185 /* No irqsave/restore necessary. This tasklet may be run in an
186 * interrupt context or normal context, but we don't have to worry
187 * about getting interrupted by something acquiring the lock, because
188 * we are the interrupt context thing that acquires the lock.
189 */
190 spin_lock(&dev_priv->swaps_lock);
71 191
72 /* Find buffer swaps scheduled for this vertical blank */ 192 /* Find buffer swaps scheduled for this vertical blank */
73 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { 193 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
74 drm_i915_vbl_swap_t *vbl_swap = 194 drm_i915_vbl_swap_t *vbl_swap =
75 list_entry(list, drm_i915_vbl_swap_t, head); 195 list_entry(list, drm_i915_vbl_swap_t, head);
196 int pipe = i915_get_pipe(dev, vbl_swap->plane);
76 197
77 if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) 198 if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
78 continue; 199 continue;
79 200
80 list_del(list); 201 list_del(list);
81 dev_priv->swaps_pending--; 202 dev_priv->swaps_pending--;
203 drm_vblank_put(dev, pipe);
82 204
83 spin_unlock(&dev_priv->swaps_lock); 205 spin_unlock(&dev_priv->swaps_lock);
84 spin_lock(&dev->drw_lock); 206 spin_lock(&dev->drw_lock);
@@ -116,33 +238,23 @@ static void i915_vblank_tasklet(struct drm_device *dev)
116 spin_lock(&dev_priv->swaps_lock); 238 spin_lock(&dev_priv->swaps_lock);
117 } 239 }
118 240
119 if (nhits == 0) {
120 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
121 return;
122 }
123
124 spin_unlock(&dev_priv->swaps_lock); 241 spin_unlock(&dev_priv->swaps_lock);
125 242
126 i915_kernel_lost_context(dev); 243 if (nhits == 0)
127 244 return;
128 BEGIN_LP_RING(6);
129
130 OUT_RING(GFX_OP_DRAWRECT_INFO);
131 OUT_RING(0);
132 OUT_RING(0);
133 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
134 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
135 OUT_RING(0);
136
137 ADVANCE_LP_RING();
138 245
139 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; 246 i915_kernel_lost_context(dev);
140 247
141 upper[0] = upper[1] = 0; 248 upper[0] = upper[1] = 0;
142 slice[0] = max(sarea_priv->pipeA_h / nhits, 1); 249 slice[0] = max(sarea_priv->planeA_h / nhits, 1);
143 slice[1] = max(sarea_priv->pipeB_h / nhits, 1); 250 slice[1] = max(sarea_priv->planeB_h / nhits, 1);
144 lower[0] = sarea_priv->pipeA_y + slice[0]; 251 lower[0] = sarea_priv->planeA_y + slice[0];
145 lower[1] = sarea_priv->pipeB_y + slice[0]; 252 lower[1] = sarea_priv->planeB_y + slice[0];
253
254 offsets[0] = sarea_priv->front_offset;
255 offsets[1] = sarea_priv->back_offset;
256 offsets[2] = sarea_priv->third_offset;
257 num_pages = sarea_priv->third_handle ? 3 : 2;
146 258
147 spin_lock(&dev->drw_lock); 259 spin_lock(&dev->drw_lock);
148 260
@@ -154,6 +266,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
154 for (i = 0; i++ < nhits; 266 for (i = 0; i++ < nhits;
155 upper[0] = lower[0], lower[0] += slice[0], 267 upper[0] = lower[0], lower[0] += slice[0],
156 upper[1] = lower[1], lower[1] += slice[1]) { 268 upper[1] = lower[1], lower[1] += slice[1]) {
269 int init_drawrect = 1;
270
157 if (i == nhits) 271 if (i == nhits)
158 lower[0] = lower[1] = sarea_priv->height; 272 lower[0] = lower[1] = sarea_priv->height;
159 273
@@ -161,7 +275,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
161 drm_i915_vbl_swap_t *swap_hit = 275 drm_i915_vbl_swap_t *swap_hit =
162 list_entry(hit, drm_i915_vbl_swap_t, head); 276 list_entry(hit, drm_i915_vbl_swap_t, head);
163 struct drm_clip_rect *rect; 277 struct drm_clip_rect *rect;
164 int num_rects, pipe; 278 int num_rects, plane, front, back;
165 unsigned short top, bottom; 279 unsigned short top, bottom;
166 280
167 drw = drm_get_drawable_info(dev, swap_hit->drw_id); 281 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
@@ -169,10 +283,50 @@ static void i915_vblank_tasklet(struct drm_device *dev)
169 if (!drw) 283 if (!drw)
170 continue; 284 continue;
171 285
286 plane = swap_hit->plane;
287
288 if (swap_hit->flip) {
289 i915_dispatch_vsync_flip(dev, drw, plane);
290 continue;
291 }
292
293 if (init_drawrect) {
294 int width = sarea_priv->width;
295 int height = sarea_priv->height;
296 if (IS_I965G(dev)) {
297 BEGIN_LP_RING(4);
298
299 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
300 OUT_RING(0);
301 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
302 OUT_RING(0);
303
304 ADVANCE_LP_RING();
305 } else {
306 BEGIN_LP_RING(6);
307
308 OUT_RING(GFX_OP_DRAWRECT_INFO);
309 OUT_RING(0);
310 OUT_RING(0);
311 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
312 OUT_RING(0);
313 OUT_RING(0);
314
315 ADVANCE_LP_RING();
316 }
317
318 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
319
320 init_drawrect = 0;
321 }
322
172 rect = drw->rects; 323 rect = drw->rects;
173 pipe = swap_hit->pipe; 324 top = upper[plane];
174 top = upper[pipe]; 325 bottom = lower[plane];
175 bottom = lower[pipe]; 326
327 front = (dev_priv->sarea_priv->pf_current_page >>
328 (2 * plane)) & 0x3;
329 back = (front + 1) % num_pages;
176 330
177 for (num_rects = drw->num_rects; num_rects--; rect++) { 331 for (num_rects = drw->num_rects; num_rects--; rect++) {
178 int y1 = max(rect->y1, top); 332 int y1 = max(rect->y1, top);
@@ -184,20 +338,20 @@ static void i915_vblank_tasklet(struct drm_device *dev)
184 BEGIN_LP_RING(8); 338 BEGIN_LP_RING(8);
185 339
186 OUT_RING(cmd); 340 OUT_RING(cmd);
187 OUT_RING(pitchropcpp); 341 OUT_RING(ropcpp | dst_pitch);
188 OUT_RING((y1 << 16) | rect->x1); 342 OUT_RING((y1 << 16) | rect->x1);
189 OUT_RING((y2 << 16) | rect->x2); 343 OUT_RING((y2 << 16) | rect->x2);
190 OUT_RING(sarea_priv->front_offset); 344 OUT_RING(offsets[front]);
191 OUT_RING((y1 << 16) | rect->x1); 345 OUT_RING((y1 << 16) | rect->x1);
192 OUT_RING(pitchropcpp & 0xffff); 346 OUT_RING(src_pitch);
193 OUT_RING(sarea_priv->back_offset); 347 OUT_RING(offsets[back]);
194 348
195 ADVANCE_LP_RING(); 349 ADVANCE_LP_RING();
196 } 350 }
197 } 351 }
198 } 352 }
199 353
200 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 354 spin_unlock(&dev->drw_lock);
201 355
202 list_for_each_safe(hit, tmp, &hits) { 356 list_for_each_safe(hit, tmp, &hits) {
203 drm_i915_vbl_swap_t *swap_hit = 357 drm_i915_vbl_swap_t *swap_hit =
@@ -209,67 +363,112 @@ static void i915_vblank_tasklet(struct drm_device *dev)
209 } 363 }
210} 364}
211 365
366u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
367{
368 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
369 unsigned long high_frame;
370 unsigned long low_frame;
371 u32 high1, high2, low, count;
372 int pipe;
373
374 pipe = i915_get_pipe(dev, plane);
375 high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
376 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
377
378 if (!i915_pipe_enabled(dev, pipe)) {
379 printk(KERN_ERR "trying to get vblank count for disabled "
380 "pipe %d\n", pipe);
381 return 0;
382 }
383
384 /*
385 * High & low register fields aren't synchronized, so make sure
386 * we get a low value that's stable across two reads of the high
387 * register.
388 */
389 do {
390 high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
391 PIPE_FRAME_HIGH_SHIFT);
392 low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
393 PIPE_FRAME_LOW_SHIFT);
394 high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
395 PIPE_FRAME_HIGH_SHIFT);
396 } while (high1 != high2);
397
398 count = (high1 << 8) | low;
399
400 /* count may be reset by other driver(e.g. 2D driver),
401 we have no way to know if it is wrapped or resetted
402 when count is zero. do a rough guess.
403 */
404 if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
405 dev->last_vblank[pipe] = 0;
406
407 return count;
408}
409
212irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 410irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
213{ 411{
214 struct drm_device *dev = (struct drm_device *) arg; 412 struct drm_device *dev = (struct drm_device *) arg;
215 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 413 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
216 u16 temp; 414 u32 iir;
217 u32 pipea_stats, pipeb_stats; 415 u32 pipea_stats, pipeb_stats;
218 416 int vblank = 0;
219 pipea_stats = I915_READ(I915REG_PIPEASTAT); 417
220 pipeb_stats = I915_READ(I915REG_PIPEBSTAT); 418 iir = I915_READ(I915REG_INT_IDENTITY_R);
221 419 if (iir == 0) {
222 temp = I915_READ16(I915REG_INT_IDENTITY_R); 420 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
223 421 iir,
224 temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); 422 I915_READ(I915REG_INT_MASK_R),
225 423 I915_READ(I915REG_INT_ENABLE_R),
226 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); 424 I915_READ(I915REG_PIPEASTAT),
227 425 I915_READ(I915REG_PIPEBSTAT));
228 if (temp == 0)
229 return IRQ_NONE; 426 return IRQ_NONE;
427 }
230 428
231 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 429 /*
232 (void) I915_READ16(I915REG_INT_IDENTITY_R); 430 * Clear the PIPE(A|B)STAT regs before the IIR otherwise
233 DRM_READMEMORYBARRIER(); 431 * we may get extra interrupts.
234 432 */
235 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 433 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
434 pipea_stats = I915_READ(I915REG_PIPEASTAT);
435 if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
436 I915_VBLANK_INTERRUPT_STATUS))
437 {
438 vblank++;
439 drm_handle_vblank(dev, i915_get_plane(dev, 0));
440 }
441 I915_WRITE(I915REG_PIPEASTAT, pipea_stats);
442 }
443 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
444 pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
445 if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
446 I915_VBLANK_INTERRUPT_STATUS))
447 {
448 vblank++;
449 drm_handle_vblank(dev, i915_get_plane(dev, 1));
450 }
451 I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats);
452 }
236 453
237 if (temp & USER_INT_FLAG) 454 if (dev_priv->sarea_priv)
238 DRM_WAKEUP(&dev_priv->irq_queue); 455 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
239 456
240 if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { 457 I915_WRITE(I915REG_INT_IDENTITY_R, iir);
241 int vblank_pipe = dev_priv->vblank_pipe; 458 (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */
242
243 if ((vblank_pipe &
244 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
245 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
246 if (temp & VSYNC_PIPEA_FLAG)
247 atomic_inc(&dev->vbl_received);
248 if (temp & VSYNC_PIPEB_FLAG)
249 atomic_inc(&dev->vbl_received2);
250 } else if (((temp & VSYNC_PIPEA_FLAG) &&
251 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
252 ((temp & VSYNC_PIPEB_FLAG) &&
253 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
254 atomic_inc(&dev->vbl_received);
255
256 DRM_WAKEUP(&dev->vbl_queue);
257 drm_vbl_send_signals(dev);
258 459
460 if (iir & I915_USER_INTERRUPT) {
461 DRM_WAKEUP(&dev_priv->irq_queue);
462 }
463 if (vblank) {
259 if (dev_priv->swaps_pending > 0) 464 if (dev_priv->swaps_pending > 0)
260 drm_locked_tasklet(dev, i915_vblank_tasklet); 465 drm_locked_tasklet(dev, i915_vblank_tasklet);
261 I915_WRITE(I915REG_PIPEASTAT,
262 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
263 I915_VBLANK_CLEAR);
264 I915_WRITE(I915REG_PIPEBSTAT,
265 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
266 I915_VBLANK_CLEAR);
267 } 466 }
268 467
269 return IRQ_HANDLED; 468 return IRQ_HANDLED;
270} 469}
271 470
272static int i915_emit_irq(struct drm_device * dev) 471static int i915_emit_irq(struct drm_device *dev)
273{ 472{
274 drm_i915_private_t *dev_priv = dev->dev_private; 473 drm_i915_private_t *dev_priv = dev->dev_private;
275 RING_LOCALS; 474 RING_LOCALS;
@@ -316,42 +515,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
316 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); 515 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
317 } 516 }
318 517
319 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 518 if (dev_priv->sarea_priv)
320 return ret; 519 dev_priv->sarea_priv->last_dispatch =
321} 520 READ_BREADCRUMB(dev_priv);
322
323static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
324 atomic_t *counter)
325{
326 drm_i915_private_t *dev_priv = dev->dev_private;
327 unsigned int cur_vblank;
328 int ret = 0;
329
330 if (!dev_priv) {
331 DRM_ERROR("called with no initialization\n");
332 return -EINVAL;
333 }
334
335 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
336 (((cur_vblank = atomic_read(counter))
337 - *sequence) <= (1<<23)));
338
339 *sequence = cur_vblank;
340
341 return ret; 521 return ret;
342} 522}
343 523
344
345int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
346{
347 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
348}
349
350int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
351{
352 return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
353}
354
355/* Needs the lock as it touches the ring. 524/* Needs the lock as it touches the ring.
356 */ 525 */
357int i915_irq_emit(struct drm_device *dev, void *data, 526int i915_irq_emit(struct drm_device *dev, void *data,
@@ -394,18 +563,96 @@ int i915_irq_wait(struct drm_device *dev, void *data,
394 return i915_wait_irq(dev, irqwait->irq_seq); 563 return i915_wait_irq(dev, irqwait->irq_seq);
395} 564}
396 565
566int i915_enable_vblank(struct drm_device *dev, int plane)
567{
568 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
569 int pipe = i915_get_pipe(dev, plane);
570 u32 pipestat_reg = 0;
571 u32 pipestat;
572
573 switch (pipe) {
574 case 0:
575 pipestat_reg = I915REG_PIPEASTAT;
576 dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
577 break;
578 case 1:
579 pipestat_reg = I915REG_PIPEBSTAT;
580 dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
581 break;
582 default:
583 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
584 pipe);
585 break;
586 }
587
588 if (pipestat_reg)
589 {
590 pipestat = I915_READ (pipestat_reg);
591 /*
592 * Older chips didn't have the start vblank interrupt,
593 * but
594 */
595 if (IS_I965G (dev))
596 pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE;
597 else
598 pipestat |= I915_VBLANK_INTERRUPT_ENABLE;
599 /*
600 * Clear any pending status
601 */
602 pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
603 I915_VBLANK_INTERRUPT_STATUS);
604 I915_WRITE(pipestat_reg, pipestat);
605 }
606 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
607
608 return 0;
609}
610
611void i915_disable_vblank(struct drm_device *dev, int plane)
612{
613 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
614 int pipe = i915_get_pipe(dev, plane);
615 u32 pipestat_reg = 0;
616 u32 pipestat;
617
618 switch (pipe) {
619 case 0:
620 pipestat_reg = I915REG_PIPEASTAT;
621 dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
622 break;
623 case 1:
624 pipestat_reg = I915REG_PIPEBSTAT;
625 dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
626 break;
627 default:
628 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
629 pipe);
630 break;
631 }
632
633 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
634 if (pipestat_reg)
635 {
636 pipestat = I915_READ (pipestat_reg);
637 pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE |
638 I915_VBLANK_INTERRUPT_ENABLE);
639 /*
640 * Clear any pending status
641 */
642 pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
643 I915_VBLANK_INTERRUPT_STATUS);
644 I915_WRITE(pipestat_reg, pipestat);
645 }
646}
647
397static void i915_enable_interrupt (struct drm_device *dev) 648static void i915_enable_interrupt (struct drm_device *dev)
398{ 649{
399 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 650 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
400 u16 flag;
401 651
402 flag = 0; 652 dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
403 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
404 flag |= VSYNC_PIPEA_FLAG;
405 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
406 flag |= VSYNC_PIPEB_FLAG;
407 653
408 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); 654 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
655 dev_priv->irq_enabled = 1;
409} 656}
410 657
411/* Set the vblank monitor pipe 658/* Set the vblank monitor pipe
@@ -428,8 +675,6 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
428 675
429 dev_priv->vblank_pipe = pipe->pipe; 676 dev_priv->vblank_pipe = pipe->pipe;
430 677
431 i915_enable_interrupt (dev);
432
433 return 0; 678 return 0;
434} 679}
435 680
@@ -447,9 +692,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
447 692
448 flag = I915_READ(I915REG_INT_ENABLE_R); 693 flag = I915_READ(I915REG_INT_ENABLE_R);
449 pipe->pipe = 0; 694 pipe->pipe = 0;
450 if (flag & VSYNC_PIPEA_FLAG) 695 if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
451 pipe->pipe |= DRM_I915_VBLANK_PIPE_A; 696 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
452 if (flag & VSYNC_PIPEB_FLAG) 697 if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
453 pipe->pipe |= DRM_I915_VBLANK_PIPE_B; 698 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
454 699
455 return 0; 700 return 0;
@@ -464,27 +709,30 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
464 drm_i915_private_t *dev_priv = dev->dev_private; 709 drm_i915_private_t *dev_priv = dev->dev_private;
465 drm_i915_vblank_swap_t *swap = data; 710 drm_i915_vblank_swap_t *swap = data;
466 drm_i915_vbl_swap_t *vbl_swap; 711 drm_i915_vbl_swap_t *vbl_swap;
467 unsigned int pipe, seqtype, curseq; 712 unsigned int pipe, seqtype, curseq, plane;
468 unsigned long irqflags; 713 unsigned long irqflags;
469 struct list_head *list; 714 struct list_head *list;
715 int ret;
470 716
471 if (!dev_priv) { 717 if (!dev_priv) {
472 DRM_ERROR("%s called with no initialization\n", __func__); 718 DRM_ERROR("%s called with no initialization\n", __func__);
473 return -EINVAL; 719 return -EINVAL;
474 } 720 }
475 721
476 if (dev_priv->sarea_priv->rotation) { 722 if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) {
477 DRM_DEBUG("Rotation not supported\n"); 723 DRM_DEBUG("Rotation not supported\n");
478 return -EINVAL; 724 return -EINVAL;
479 } 725 }
480 726
481 if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | 727 if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
482 _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { 728 _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS |
729 _DRM_VBLANK_FLIP)) {
483 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); 730 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype);
484 return -EINVAL; 731 return -EINVAL;
485 } 732 }
486 733
487 pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; 734 plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
735 pipe = i915_get_pipe(dev, plane);
488 736
489 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); 737 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
490 738
@@ -495,6 +743,11 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
495 743
496 spin_lock_irqsave(&dev->drw_lock, irqflags); 744 spin_lock_irqsave(&dev->drw_lock, irqflags);
497 745
746 /* It makes no sense to schedule a swap for a drawable that doesn't have
747 * valid information at this point. E.g. this could mean that the X
748 * server is too old to push drawable information to the DRM, in which
749 * case all such swaps would become ineffective.
750 */
498 if (!drm_get_drawable_info(dev, swap->drawable)) { 751 if (!drm_get_drawable_info(dev, swap->drawable)) {
499 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 752 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
500 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); 753 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
@@ -503,7 +756,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
503 756
504 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 757 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
505 758
506 curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); 759 drm_update_vblank_count(dev, pipe);
760 curseq = drm_vblank_count(dev, pipe);
507 761
508 if (seqtype == _DRM_VBLANK_RELATIVE) 762 if (seqtype == _DRM_VBLANK_RELATIVE)
509 swap->sequence += curseq; 763 swap->sequence += curseq;
@@ -517,14 +771,43 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
517 } 771 }
518 } 772 }
519 773
774 if (swap->seqtype & _DRM_VBLANK_FLIP) {
775 swap->sequence--;
776
777 if ((curseq - swap->sequence) <= (1<<23)) {
778 struct drm_drawable_info *drw;
779
780 LOCK_TEST_WITH_RETURN(dev, file_priv);
781
782 spin_lock_irqsave(&dev->drw_lock, irqflags);
783
784 drw = drm_get_drawable_info(dev, swap->drawable);
785
786 if (!drw) {
787 spin_unlock_irqrestore(&dev->drw_lock,
788 irqflags);
789 DRM_DEBUG("Invalid drawable ID %d\n",
790 swap->drawable);
791 return -EINVAL;
792 }
793
794 i915_dispatch_vsync_flip(dev, drw, plane);
795
796 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
797
798 return 0;
799 }
800 }
801
520 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 802 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
521 803
522 list_for_each(list, &dev_priv->vbl_swaps.head) { 804 list_for_each(list, &dev_priv->vbl_swaps.head) {
523 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); 805 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
524 806
525 if (vbl_swap->drw_id == swap->drawable && 807 if (vbl_swap->drw_id == swap->drawable &&
526 vbl_swap->pipe == pipe && 808 vbl_swap->plane == plane &&
527 vbl_swap->sequence == swap->sequence) { 809 vbl_swap->sequence == swap->sequence) {
810 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
528 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); 811 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
529 DRM_DEBUG("Already scheduled\n"); 812 DRM_DEBUG("Already scheduled\n");
530 return 0; 813 return 0;
@@ -547,9 +830,19 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
547 830
548 DRM_DEBUG("\n"); 831 DRM_DEBUG("\n");
549 832
833 ret = drm_vblank_get(dev, pipe);
834 if (ret) {
835 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
836 return ret;
837 }
838
550 vbl_swap->drw_id = swap->drawable; 839 vbl_swap->drw_id = swap->drawable;
551 vbl_swap->pipe = pipe; 840 vbl_swap->plane = plane;
552 vbl_swap->sequence = swap->sequence; 841 vbl_swap->sequence = swap->sequence;
842 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
843
844 if (vbl_swap->flip)
845 swap->sequence++;
553 846
554 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); 847 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
555 848
@@ -567,37 +860,57 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
567{ 860{
568 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 861 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
569 862
570 I915_WRITE16(I915REG_HWSTAM, 0xfffe); 863 I915_WRITE16(I915REG_HWSTAM, 0xeffe);
571 I915_WRITE16(I915REG_INT_MASK_R, 0x0); 864 I915_WRITE16(I915REG_INT_MASK_R, 0x0);
572 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); 865 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
573} 866}
574 867
575void i915_driver_irq_postinstall(struct drm_device * dev) 868int i915_driver_irq_postinstall(struct drm_device * dev)
576{ 869{
577 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 870 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
871 int ret, num_pipes = 2;
578 872
579 spin_lock_init(&dev_priv->swaps_lock); 873 spin_lock_init(&dev_priv->swaps_lock);
580 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); 874 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
581 dev_priv->swaps_pending = 0; 875 dev_priv->swaps_pending = 0;
582 876
583 if (!dev_priv->vblank_pipe) 877 dev_priv->user_irq_refcount = 0;
584 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; 878 dev_priv->irq_enable_reg = 0;
879
880 ret = drm_vblank_init(dev, num_pipes);
881 if (ret)
882 return ret;
883
884 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
885
585 i915_enable_interrupt(dev); 886 i915_enable_interrupt(dev);
586 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 887 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
888
889 /*
890 * Initialize the hardware status page IRQ location.
891 */
892
893 I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
894 return 0;
587} 895}
588 896
589void i915_driver_irq_uninstall(struct drm_device * dev) 897void i915_driver_irq_uninstall(struct drm_device * dev)
590{ 898{
591 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 899 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
592 u16 temp; 900 u32 temp;
593 901
594 if (!dev_priv) 902 if (!dev_priv)
595 return; 903 return;
596 904
597 I915_WRITE16(I915REG_HWSTAM, 0xffff); 905 dev_priv->irq_enabled = 0;
598 I915_WRITE16(I915REG_INT_MASK_R, 0xffff); 906 I915_WRITE(I915REG_HWSTAM, 0xffffffff);
599 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); 907 I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
600 908 I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
601 temp = I915_READ16(I915REG_INT_IDENTITY_R); 909
602 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 910 temp = I915_READ(I915REG_PIPEASTAT);
911 I915_WRITE(I915REG_PIPEASTAT, temp);
912 temp = I915_READ(I915REG_PIPEBSTAT);
913 I915_WRITE(I915REG_PIPEBSTAT, temp);
914 temp = I915_READ(I915REG_INT_IDENTITY_R);
915 I915_WRITE(I915REG_INT_IDENTITY_R, temp);
603} 916}
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 5572939fc7d1..6b3790939e76 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -45,15 +45,16 @@ static struct pci_device_id pciidlist[] = {
45static struct drm_driver driver = { 45static struct drm_driver driver = {
46 .driver_features = 46 .driver_features =
47 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | 47 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
48 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 48 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
49 DRIVER_IRQ_VBL,
50 .dev_priv_size = sizeof(drm_mga_buf_priv_t), 49 .dev_priv_size = sizeof(drm_mga_buf_priv_t),
51 .load = mga_driver_load, 50 .load = mga_driver_load,
52 .unload = mga_driver_unload, 51 .unload = mga_driver_unload,
53 .lastclose = mga_driver_lastclose, 52 .lastclose = mga_driver_lastclose,
54 .dma_quiescent = mga_driver_dma_quiescent, 53 .dma_quiescent = mga_driver_dma_quiescent,
55 .device_is_agp = mga_driver_device_is_agp, 54 .device_is_agp = mga_driver_device_is_agp,
56 .vblank_wait = mga_driver_vblank_wait, 55 .get_vblank_counter = mga_get_vblank_counter,
56 .enable_vblank = mga_enable_vblank,
57 .disable_vblank = mga_disable_vblank,
57 .irq_preinstall = mga_driver_irq_preinstall, 58 .irq_preinstall = mga_driver_irq_preinstall,
58 .irq_postinstall = mga_driver_irq_postinstall, 59 .irq_postinstall = mga_driver_irq_postinstall,
59 .irq_uninstall = mga_driver_irq_uninstall, 60 .irq_uninstall = mga_driver_irq_uninstall,
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index f6ebd24bd587..8f7291f36363 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -120,6 +120,7 @@ typedef struct drm_mga_private {
120 u32 clear_cmd; 120 u32 clear_cmd;
121 u32 maccess; 121 u32 maccess;
122 122
123 atomic_t vbl_received; /**< Number of vblanks received. */
123 wait_queue_head_t fence_queue; 124 wait_queue_head_t fence_queue;
124 atomic_t last_fence_retired; 125 atomic_t last_fence_retired;
125 u32 next_fence_to_post; 126 u32 next_fence_to_post;
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
181extern int mga_warp_init(drm_mga_private_t * dev_priv); 182extern int mga_warp_init(drm_mga_private_t * dev_priv);
182 183
183 /* mga_irq.c */ 184 /* mga_irq.c */
185extern int mga_enable_vblank(struct drm_device *dev, int crtc);
186extern void mga_disable_vblank(struct drm_device *dev, int crtc);
187extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
184extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); 188extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
185extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 189extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
186extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); 190extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
187extern void mga_driver_irq_preinstall(struct drm_device * dev); 191extern void mga_driver_irq_preinstall(struct drm_device * dev);
188extern void mga_driver_irq_postinstall(struct drm_device * dev); 192extern int mga_driver_irq_postinstall(struct drm_device * dev);
189extern void mga_driver_irq_uninstall(struct drm_device * dev); 193extern void mga_driver_irq_uninstall(struct drm_device * dev);
190extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, 194extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
191 unsigned long arg); 195 unsigned long arg);
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
index 9302cb8f0f83..06852fb4b278 100644
--- a/drivers/char/drm/mga_irq.c
+++ b/drivers/char/drm/mga_irq.c
@@ -35,6 +35,20 @@
35#include "mga_drm.h" 35#include "mga_drm.h"
36#include "mga_drv.h" 36#include "mga_drv.h"
37 37
38u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_mga_private_t *const dev_priv =
41 (drm_mga_private_t *) dev->dev_private;
42
43 if (crtc != 0) {
44 return 0;
45 }
46
47
48 return atomic_read(&dev_priv->vbl_received);
49}
50
51
38irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) 52irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
39{ 53{
40 struct drm_device *dev = (struct drm_device *) arg; 54 struct drm_device *dev = (struct drm_device *) arg;
@@ -47,9 +61,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
47 /* VBLANK interrupt */ 61 /* VBLANK interrupt */
48 if (status & MGA_VLINEPEN) { 62 if (status & MGA_VLINEPEN) {
49 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); 63 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
50 atomic_inc(&dev->vbl_received); 64 atomic_inc(&dev_priv->vbl_received);
51 DRM_WAKEUP(&dev->vbl_queue); 65 drm_handle_vblank(dev, 0);
52 drm_vbl_send_signals(dev);
53 handled = 1; 66 handled = 1;
54 } 67 }
55 68
@@ -78,22 +91,34 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
78 return IRQ_NONE; 91 return IRQ_NONE;
79} 92}
80 93
81int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 94int mga_enable_vblank(struct drm_device *dev, int crtc)
82{ 95{
83 unsigned int cur_vblank; 96 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
84 int ret = 0;
85 97
86 /* Assume that the user has missed the current sequence number 98 if (crtc != 0) {
87 * by about a day rather than she wants to wait for years 99 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
88 * using vertical blanks... 100 crtc);
89 */ 101 return 0;
90 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 102 }
91 (((cur_vblank = atomic_read(&dev->vbl_received))
92 - *sequence) <= (1 << 23)));
93 103
94 *sequence = cur_vblank; 104 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
105 return 0;
106}
95 107
96 return ret; 108
109void mga_disable_vblank(struct drm_device *dev, int crtc)
110{
111 if (crtc != 0) {
112 DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
113 crtc);
114 }
115
116 /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
117 * a nice hardware counter that tracks the number of refreshes when
118 * the interrupt is disabled, and the kernel doesn't know the refresh
119 * rate to calculate an estimate.
120 */
121 /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
97} 122}
98 123
99int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) 124int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -125,14 +150,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
125 MGA_WRITE(MGA_ICLEAR, ~0); 150 MGA_WRITE(MGA_ICLEAR, ~0);
126} 151}
127 152
128void mga_driver_irq_postinstall(struct drm_device * dev) 153int mga_driver_irq_postinstall(struct drm_device * dev)
129{ 154{
130 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; 155 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
156 int ret;
157
158 ret = drm_vblank_init(dev, 1);
159 if (ret)
160 return ret;
131 161
132 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); 162 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
133 163
134 /* Turn on vertical blank interrupt and soft trap interrupt. */ 164 /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
135 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); 165 * in mga_enable_vblank.
166 */
167 MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
168 return 0;
136} 169}
137 170
138void mga_driver_irq_uninstall(struct drm_device * dev) 171void mga_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index 6108e7587e12..2888aa01ebc7 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = {
43static struct drm_driver driver = { 43static struct drm_driver driver = {
44 .driver_features = 44 .driver_features =
45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
47 DRIVER_IRQ_VBL,
48 .dev_priv_size = sizeof(drm_r128_buf_priv_t), 47 .dev_priv_size = sizeof(drm_r128_buf_priv_t),
49 .preclose = r128_driver_preclose, 48 .preclose = r128_driver_preclose,
50 .lastclose = r128_driver_lastclose, 49 .lastclose = r128_driver_lastclose,
51 .vblank_wait = r128_driver_vblank_wait, 50 .get_vblank_counter = r128_get_vblank_counter,
51 .enable_vblank = r128_enable_vblank,
52 .disable_vblank = r128_disable_vblank,
52 .irq_preinstall = r128_driver_irq_preinstall, 53 .irq_preinstall = r128_driver_irq_preinstall,
53 .irq_postinstall = r128_driver_irq_postinstall, 54 .irq_postinstall = r128_driver_irq_postinstall,
54 .irq_uninstall = r128_driver_irq_uninstall, 55 .irq_uninstall = r128_driver_irq_uninstall,
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 011105e51ac6..80af9e09e75d 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -97,6 +97,8 @@ typedef struct drm_r128_private {
97 u32 crtc_offset; 97 u32 crtc_offset;
98 u32 crtc_offset_cntl; 98 u32 crtc_offset_cntl;
99 99
100 atomic_t vbl_received;
101
100 u32 color_fmt; 102 u32 color_fmt;
101 unsigned int front_offset; 103 unsigned int front_offset;
102 unsigned int front_pitch; 104 unsigned int front_pitch;
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
149extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); 151extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
150extern int r128_do_cleanup_cce(struct drm_device * dev); 152extern int r128_do_cleanup_cce(struct drm_device * dev);
151 153
152extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 154extern int r128_enable_vblank(struct drm_device *dev, int crtc);
153 155extern void r128_disable_vblank(struct drm_device *dev, int crtc);
156extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
154extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); 157extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
155extern void r128_driver_irq_preinstall(struct drm_device * dev); 158extern void r128_driver_irq_preinstall(struct drm_device * dev);
156extern void r128_driver_irq_postinstall(struct drm_device * dev); 159extern int r128_driver_irq_postinstall(struct drm_device * dev);
157extern void r128_driver_irq_uninstall(struct drm_device * dev); 160extern void r128_driver_irq_uninstall(struct drm_device * dev);
158extern void r128_driver_lastclose(struct drm_device * dev); 161extern void r128_driver_lastclose(struct drm_device * dev);
159extern void r128_driver_preclose(struct drm_device * dev, 162extern void r128_driver_preclose(struct drm_device * dev,
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
index c76fdca7662d..5b95bd898f95 100644
--- a/drivers/char/drm/r128_irq.c
+++ b/drivers/char/drm/r128_irq.c
@@ -35,6 +35,16 @@
35#include "r128_drm.h" 35#include "r128_drm.h"
36#include "r128_drv.h" 36#include "r128_drv.h"
37 37
38u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_r128_private_t *dev_priv = dev->dev_private;
41
42 if (crtc != 0)
43 return 0;
44
45 return atomic_read(&dev_priv->vbl_received);
46}
47
38irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) 48irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
39{ 49{
40 struct drm_device *dev = (struct drm_device *) arg; 50 struct drm_device *dev = (struct drm_device *) arg;
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
46 /* VBLANK interrupt */ 56 /* VBLANK interrupt */
47 if (status & R128_CRTC_VBLANK_INT) { 57 if (status & R128_CRTC_VBLANK_INT) {
48 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); 58 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
49 atomic_inc(&dev->vbl_received); 59 atomic_inc(&dev_priv->vbl_received);
50 DRM_WAKEUP(&dev->vbl_queue); 60 drm_handle_vblank(dev, 0);
51 drm_vbl_send_signals(dev);
52 return IRQ_HANDLED; 61 return IRQ_HANDLED;
53 } 62 }
54 return IRQ_NONE; 63 return IRQ_NONE;
55} 64}
56 65
57int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 66int r128_enable_vblank(struct drm_device *dev, int crtc)
58{ 67{
59 unsigned int cur_vblank; 68 drm_r128_private_t *dev_priv = dev->dev_private;
60 int ret = 0;
61 69
62 /* Assume that the user has missed the current sequence number 70 if (crtc != 0) {
63 * by about a day rather than she wants to wait for years 71 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
64 * using vertical blanks... 72 return -EINVAL;
65 */ 73 }
66 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
67 (((cur_vblank = atomic_read(&dev->vbl_received))
68 - *sequence) <= (1 << 23)));
69 74
70 *sequence = cur_vblank; 75 R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
76 return 0;
77}
78
79void r128_disable_vblank(struct drm_device *dev, int crtc)
80{
81 if (crtc != 0)
82 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
71 83
72 return ret; 84 /*
85 * FIXME: implement proper interrupt disable by using the vblank
86 * counter register (if available)
87 *
88 * R128_WRITE(R128_GEN_INT_CNTL,
89 * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
90 */
73} 91}
74 92
75void r128_driver_irq_preinstall(struct drm_device * dev) 93void r128_driver_irq_preinstall(struct drm_device * dev)
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
82 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); 100 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
83} 101}
84 102
85void r128_driver_irq_postinstall(struct drm_device * dev) 103int r128_driver_irq_postinstall(struct drm_device * dev)
86{ 104{
87 drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; 105 return drm_vblank_init(dev, 1);
88
89 /* Turn on VBL interrupt */
90 R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
91} 106}
92 107
93void r128_driver_irq_uninstall(struct drm_device * dev) 108void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index 349ac3d3b848..a2610319624d 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -59,8 +59,7 @@ static struct pci_device_id pciidlist[] = {
59static struct drm_driver driver = { 59static struct drm_driver driver = {
60 .driver_features = 60 .driver_features =
61 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 61 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
62 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | 62 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
63 DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
64 .dev_priv_size = sizeof(drm_radeon_buf_priv_t), 63 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
65 .load = radeon_driver_load, 64 .load = radeon_driver_load,
66 .firstopen = radeon_driver_firstopen, 65 .firstopen = radeon_driver_firstopen,
@@ -69,8 +68,9 @@ static struct drm_driver driver = {
69 .postclose = radeon_driver_postclose, 68 .postclose = radeon_driver_postclose,
70 .lastclose = radeon_driver_lastclose, 69 .lastclose = radeon_driver_lastclose,
71 .unload = radeon_driver_unload, 70 .unload = radeon_driver_unload,
72 .vblank_wait = radeon_driver_vblank_wait, 71 .get_vblank_counter = radeon_get_vblank_counter,
73 .vblank_wait2 = radeon_driver_vblank_wait2, 72 .enable_vblank = radeon_enable_vblank,
73 .disable_vblank = radeon_disable_vblank,
74 .dri_library_name = dri_library_name, 74 .dri_library_name = dri_library_name,
75 .irq_preinstall = radeon_driver_irq_preinstall, 75 .irq_preinstall = radeon_driver_irq_preinstall,
76 .irq_postinstall = radeon_driver_irq_postinstall, 76 .irq_postinstall = radeon_driver_irq_postinstall,
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 173ae620223a..b791420bd3d9 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -304,6 +304,9 @@ typedef struct drm_radeon_private {
304 304
305 u32 scratch_ages[5]; 305 u32 scratch_ages[5];
306 306
307 unsigned int crtc_last_cnt;
308 unsigned int crtc2_last_cnt;
309
307 /* starting from here on, data is preserved accross an open */ 310 /* starting from here on, data is preserved accross an open */
308 uint32_t flags; /* see radeon_chip_flags */ 311 uint32_t flags; /* see radeon_chip_flags */
309 unsigned long fb_aper_offset; 312 unsigned long fb_aper_offset;
@@ -374,13 +377,13 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *
374extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); 377extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
375 378
376extern void radeon_do_release(struct drm_device * dev); 379extern void radeon_do_release(struct drm_device * dev);
377extern int radeon_driver_vblank_wait(struct drm_device * dev, 380extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
378 unsigned int *sequence); 381extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
379extern int radeon_driver_vblank_wait2(struct drm_device * dev, 382extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
380 unsigned int *sequence); 383extern void radeon_do_release(struct drm_device * dev);
381extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); 384extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
382extern void radeon_driver_irq_preinstall(struct drm_device * dev); 385extern void radeon_driver_irq_preinstall(struct drm_device * dev);
383extern void radeon_driver_irq_postinstall(struct drm_device * dev); 386extern int radeon_driver_irq_postinstall(struct drm_device * dev);
384extern void radeon_driver_irq_uninstall(struct drm_device * dev); 387extern void radeon_driver_irq_uninstall(struct drm_device * dev);
385extern int radeon_vblank_crtc_get(struct drm_device *dev); 388extern int radeon_vblank_crtc_get(struct drm_device *dev);
386extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); 389extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
@@ -558,6 +561,12 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
558 ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ 561 ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
559 : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) 562 : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
560 563
564#define RADEON_CRTC_CRNT_FRAME 0x0214
565#define RADEON_CRTC2_CRNT_FRAME 0x0314
566
567#define RADEON_CRTC_STATUS 0x005c
568#define RADEON_CRTC2_STATUS 0x03fc
569
561#define RADEON_GEN_INT_CNTL 0x0040 570#define RADEON_GEN_INT_CNTL 0x0040
562# define RADEON_CRTC_VBLANK_MASK (1 << 0) 571# define RADEON_CRTC_VBLANK_MASK (1 << 0)
563# define RADEON_CRTC2_VBLANK_MASK (1 << 9) 572# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 009af3814b6f..507d6b747a13 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -35,12 +35,61 @@
35#include "radeon_drm.h" 35#include "radeon_drm.h"
36#include "radeon_drv.h" 36#include "radeon_drv.h"
37 37
38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, 38static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
39 u32 mask)
40{ 39{
41 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; 40 drm_radeon_private_t *dev_priv = dev->dev_private;
41
42 if (state)
43 dev_priv->irq_enable_reg |= mask;
44 else
45 dev_priv->irq_enable_reg &= ~mask;
46
47 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
48}
49
50int radeon_enable_vblank(struct drm_device *dev, int crtc)
51{
52 switch (crtc) {
53 case 0:
54 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
55 break;
56 case 1:
57 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
58 break;
59 default:
60 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
61 crtc);
62 return EINVAL;
63 }
64
65 return 0;
66}
67
68void radeon_disable_vblank(struct drm_device *dev, int crtc)
69{
70 switch (crtc) {
71 case 0:
72 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
73 break;
74 case 1:
75 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
76 break;
77 default:
78 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
79 crtc);
80 break;
81 }
82}
83
84static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv)
85{
86 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
87 (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
88 RADEON_CRTC2_VBLANK_STAT);
89
42 if (irqs) 90 if (irqs)
43 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 91 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
92
44 return irqs; 93 return irqs;
45} 94}
46 95
@@ -72,39 +121,21 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
72 /* Only consider the bits we're interested in - others could be used 121 /* Only consider the bits we're interested in - others could be used
73 * outside the DRM 122 * outside the DRM
74 */ 123 */
75 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 124 stat = radeon_acknowledge_irqs(dev_priv);
76 RADEON_CRTC_VBLANK_STAT |
77 RADEON_CRTC2_VBLANK_STAT));
78 if (!stat) 125 if (!stat)
79 return IRQ_NONE; 126 return IRQ_NONE;
80 127
81 stat &= dev_priv->irq_enable_reg; 128 stat &= dev_priv->irq_enable_reg;
82 129
83 /* SW interrupt */ 130 /* SW interrupt */
84 if (stat & RADEON_SW_INT_TEST) { 131 if (stat & RADEON_SW_INT_TEST)
85 DRM_WAKEUP(&dev_priv->swi_queue); 132 DRM_WAKEUP(&dev_priv->swi_queue);
86 }
87 133
88 /* VBLANK interrupt */ 134 /* VBLANK interrupt */
89 if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { 135 if (stat & RADEON_CRTC_VBLANK_STAT)
90 int vblank_crtc = dev_priv->vblank_crtc; 136 drm_handle_vblank(dev, 0);
91 137 if (stat & RADEON_CRTC2_VBLANK_STAT)
92 if ((vblank_crtc & 138 drm_handle_vblank(dev, 1);
93 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
94 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
95 if (stat & RADEON_CRTC_VBLANK_STAT)
96 atomic_inc(&dev->vbl_received);
97 if (stat & RADEON_CRTC2_VBLANK_STAT)
98 atomic_inc(&dev->vbl_received2);
99 } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
100 (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
101 ((stat & RADEON_CRTC2_VBLANK_STAT) &&
102 (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
103 atomic_inc(&dev->vbl_received);
104
105 DRM_WAKEUP(&dev->vbl_queue);
106 drm_vbl_send_signals(dev);
107 }
108 139
109 return IRQ_HANDLED; 140 return IRQ_HANDLED;
110} 141}
@@ -144,54 +175,27 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
144 return ret; 175 return ret;
145} 176}
146 177
147static int radeon_driver_vblank_do_wait(struct drm_device * dev, 178u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
148 unsigned int *sequence, int crtc)
149{ 179{
150 drm_radeon_private_t *dev_priv = 180 drm_radeon_private_t *dev_priv = dev->dev_private;
151 (drm_radeon_private_t *) dev->dev_private; 181 u32 crtc_cnt_reg, crtc_status_reg;
152 unsigned int cur_vblank; 182
153 int ret = 0;
154 int ack = 0;
155 atomic_t *counter;
156 if (!dev_priv) { 183 if (!dev_priv) {
157 DRM_ERROR("called with no initialization\n"); 184 DRM_ERROR("called with no initialization\n");
158 return -EINVAL; 185 return -EINVAL;
159 } 186 }
160 187
161 if (crtc == DRM_RADEON_VBLANK_CRTC1) { 188 if (crtc == 0) {
162 counter = &dev->vbl_received; 189 crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
163 ack |= RADEON_CRTC_VBLANK_STAT; 190 crtc_status_reg = RADEON_CRTC_STATUS;
164 } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { 191 } else if (crtc == 1) {
165 counter = &dev->vbl_received2; 192 crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
166 ack |= RADEON_CRTC2_VBLANK_STAT; 193 crtc_status_reg = RADEON_CRTC2_STATUS;
167 } else 194 } else {
168 return -EINVAL; 195 return -EINVAL;
196 }
169 197
170 radeon_acknowledge_irqs(dev_priv, ack); 198 return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
171
172 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
173
174 /* Assume that the user has missed the current sequence number
175 * by about a day rather than she wants to wait for years
176 * using vertical blanks...
177 */
178 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
179 (((cur_vblank = atomic_read(counter))
180 - *sequence) <= (1 << 23)));
181
182 *sequence = cur_vblank;
183
184 return ret;
185}
186
187int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
188{
189 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
190}
191
192int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
193{
194 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
195} 199}
196 200
197/* Needs the lock as it touches the ring. 201/* Needs the lock as it touches the ring.
@@ -234,21 +238,6 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
234 return radeon_wait_irq(dev, irqwait->irq_seq); 238 return radeon_wait_irq(dev, irqwait->irq_seq);
235} 239}
236 240
237static void radeon_enable_interrupt(struct drm_device *dev)
238{
239 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
240
241 dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
242 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
243 dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
244
245 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
246 dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
247
248 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
249 dev_priv->irq_enabled = 1;
250}
251
252/* drm_dma.h hooks 241/* drm_dma.h hooks
253*/ 242*/
254void radeon_driver_irq_preinstall(struct drm_device * dev) 243void radeon_driver_irq_preinstall(struct drm_device * dev)
@@ -260,20 +249,27 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
260 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 249 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
261 250
262 /* Clear bits if they're already high */ 251 /* Clear bits if they're already high */
263 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 252 radeon_acknowledge_irqs(dev_priv);
264 RADEON_CRTC_VBLANK_STAT |
265 RADEON_CRTC2_VBLANK_STAT));
266} 253}
267 254
268void radeon_driver_irq_postinstall(struct drm_device * dev) 255int radeon_driver_irq_postinstall(struct drm_device * dev)
269{ 256{
270 drm_radeon_private_t *dev_priv = 257 drm_radeon_private_t *dev_priv =
271 (drm_radeon_private_t *) dev->dev_private; 258 (drm_radeon_private_t *) dev->dev_private;
259 int ret;
272 260
273 atomic_set(&dev_priv->swi_emitted, 0); 261 atomic_set(&dev_priv->swi_emitted, 0);
274 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 262 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
275 263
276 radeon_enable_interrupt(dev); 264 ret = drm_vblank_init(dev, 2);
265 if (ret)
266 return ret;
267
268 dev->max_vblank_count = 0x001fffff;
269
270 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
271
272 return 0;
277} 273}
278 274
279void radeon_driver_irq_uninstall(struct drm_device * dev) 275void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -315,6 +311,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
315 return -EINVAL; 311 return -EINVAL;
316 } 312 }
317 dev_priv->vblank_crtc = (unsigned int)value; 313 dev_priv->vblank_crtc = (unsigned int)value;
318 radeon_enable_interrupt(dev);
319 return 0; 314 return 0;
320} 315}
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 80c01cdfa37d..37870a4a3dc7 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -40,11 +40,13 @@ static struct pci_device_id pciidlist[] = {
40static struct drm_driver driver = { 40static struct drm_driver driver = {
41 .driver_features = 41 .driver_features =
42 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | 42 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
43 DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 43 DRIVER_IRQ_SHARED,
44 .load = via_driver_load, 44 .load = via_driver_load,
45 .unload = via_driver_unload, 45 .unload = via_driver_unload,
46 .context_dtor = via_final_context, 46 .context_dtor = via_final_context,
47 .vblank_wait = via_driver_vblank_wait, 47 .get_vblank_counter = via_get_vblank_counter,
48 .enable_vblank = via_enable_vblank,
49 .disable_vblank = via_disable_vblank,
48 .irq_preinstall = via_driver_irq_preinstall, 50 .irq_preinstall = via_driver_irq_preinstall,
49 .irq_postinstall = via_driver_irq_postinstall, 51 .irq_postinstall = via_driver_irq_postinstall,
50 .irq_uninstall = via_driver_irq_uninstall, 52 .irq_uninstall = via_driver_irq_uninstall,
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 2daae81874cd..fe67030e39ac 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -75,6 +75,7 @@ typedef struct drm_via_private {
75 struct timeval last_vblank; 75 struct timeval last_vblank;
76 int last_vblank_valid; 76 int last_vblank_valid;
77 unsigned usec_per_vblank; 77 unsigned usec_per_vblank;
78 atomic_t vbl_received;
78 drm_via_state_t hc_state; 79 drm_via_state_t hc_state;
79 char pci_buf[VIA_PCI_BUF_SIZE]; 80 char pci_buf[VIA_PCI_BUF_SIZE];
80 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; 81 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -130,11 +131,13 @@ extern int via_init_context(struct drm_device * dev, int context);
130extern int via_final_context(struct drm_device * dev, int context); 131extern int via_final_context(struct drm_device * dev, int context);
131 132
132extern int via_do_cleanup_map(struct drm_device * dev); 133extern int via_do_cleanup_map(struct drm_device * dev);
133extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); 134extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
135extern int via_enable_vblank(struct drm_device *dev, int crtc);
136extern void via_disable_vblank(struct drm_device *dev, int crtc);
134 137
135extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); 138extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
136extern void via_driver_irq_preinstall(struct drm_device * dev); 139extern void via_driver_irq_preinstall(struct drm_device * dev);
137extern void via_driver_irq_postinstall(struct drm_device * dev); 140extern int via_driver_irq_postinstall(struct drm_device * dev);
138extern void via_driver_irq_uninstall(struct drm_device * dev); 141extern void via_driver_irq_uninstall(struct drm_device * dev);
139 142
140extern int via_dma_cleanup(struct drm_device * dev); 143extern int via_dma_cleanup(struct drm_device * dev);
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index c6bb978a1106..f1ab6fc7c07e 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -92,8 +92,17 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
92static unsigned time_diff(struct timeval *now, struct timeval *then) 92static unsigned time_diff(struct timeval *now, struct timeval *then)
93{ 93{
94 return (now->tv_usec >= then->tv_usec) ? 94 return (now->tv_usec >= then->tv_usec) ?
95 now->tv_usec - then->tv_usec : 95 now->tv_usec - then->tv_usec :
96 1000000 - (then->tv_usec - now->tv_usec); 96 1000000 - (then->tv_usec - now->tv_usec);
97}
98
99u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
100{
101 drm_via_private_t *dev_priv = dev->dev_private;
102 if (crtc != 0)
103 return 0;
104
105 return atomic_read(&dev_priv->vbl_received);
97} 106}
98 107
99irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) 108irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
@@ -108,8 +117,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
108 117
109 status = VIA_READ(VIA_REG_INTERRUPT); 118 status = VIA_READ(VIA_REG_INTERRUPT);
110 if (status & VIA_IRQ_VBLANK_PENDING) { 119 if (status & VIA_IRQ_VBLANK_PENDING) {
111 atomic_inc(&dev->vbl_received); 120 atomic_inc(&dev_priv->vbl_received);
112 if (!(atomic_read(&dev->vbl_received) & 0x0F)) { 121 if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
113 do_gettimeofday(&cur_vblank); 122 do_gettimeofday(&cur_vblank);
114 if (dev_priv->last_vblank_valid) { 123 if (dev_priv->last_vblank_valid) {
115 dev_priv->usec_per_vblank = 124 dev_priv->usec_per_vblank =
@@ -119,12 +128,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
119 dev_priv->last_vblank = cur_vblank; 128 dev_priv->last_vblank = cur_vblank;
120 dev_priv->last_vblank_valid = 1; 129 dev_priv->last_vblank_valid = 1;
121 } 130 }
122 if (!(atomic_read(&dev->vbl_received) & 0xFF)) { 131 if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
123 DRM_DEBUG("US per vblank is: %u\n", 132 DRM_DEBUG("US per vblank is: %u\n",
124 dev_priv->usec_per_vblank); 133 dev_priv->usec_per_vblank);
125 } 134 }
126 DRM_WAKEUP(&dev->vbl_queue); 135 drm_handle_vblank(dev, 0);
127 drm_vbl_send_signals(dev);
128 handled = 1; 136 handled = 1;
129 } 137 }
130 138
@@ -163,31 +171,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
163 } 171 }
164} 172}
165 173
166int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) 174int via_enable_vblank(struct drm_device *dev, int crtc)
167{ 175{
168 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 176 drm_via_private_t *dev_priv = dev->dev_private;
169 unsigned int cur_vblank; 177 u32 status;
170 int ret = 0;
171 178
172 DRM_DEBUG("\n"); 179 if (crtc != 0) {
173 if (!dev_priv) { 180 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
174 DRM_ERROR("called with no initialization\n");
175 return -EINVAL; 181 return -EINVAL;
176 } 182 }
177 183
178 viadrv_acknowledge_irqs(dev_priv); 184 status = VIA_READ(VIA_REG_INTERRUPT);
185 VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
179 186
180 /* Assume that the user has missed the current sequence number 187 VIA_WRITE8(0x83d4, 0x11);
181 * by about a day rather than she wants to wait for years 188 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
182 * using vertical blanks...
183 */
184 189
185 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 190 return 0;
186 (((cur_vblank = atomic_read(&dev->vbl_received)) - 191}
187 *sequence) <= (1 << 23)));
188 192
189 *sequence = cur_vblank; 193void via_disable_vblank(struct drm_device *dev, int crtc)
190 return ret; 194{
195 drm_via_private_t *dev_priv = dev->dev_private;
196
197 VIA_WRITE8(0x83d4, 0x11);
198 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
199
200 if (crtc != 0)
201 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
191} 202}
192 203
193static int 204static int
@@ -292,23 +303,25 @@ void via_driver_irq_preinstall(struct drm_device * dev)
292 } 303 }
293} 304}
294 305
295void via_driver_irq_postinstall(struct drm_device * dev) 306int via_driver_irq_postinstall(struct drm_device * dev)
296{ 307{
297 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 308 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
298 u32 status; 309 u32 status;
299 310
300 DRM_DEBUG("\n"); 311 DRM_DEBUG("via_driver_irq_postinstall\n");
301 if (dev_priv) { 312 if (!dev_priv)
302 status = VIA_READ(VIA_REG_INTERRUPT); 313 return -EINVAL;
303 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
304 | dev_priv->irq_enable_mask);
305 314
306 /* Some magic, oh for some data sheets ! */ 315 drm_vblank_init(dev, 1);
316 status = VIA_READ(VIA_REG_INTERRUPT);
317 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
318 | dev_priv->irq_enable_mask);
307 319
308 VIA_WRITE8(0x83d4, 0x11); 320 /* Some magic, oh for some data sheets ! */
309 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); 321 VIA_WRITE8(0x83d4, 0x11);
322 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
310 323
311 } 324 return 0;
312} 325}
313 326
314void via_driver_irq_uninstall(struct drm_device * dev) 327void via_driver_irq_uninstall(struct drm_device * dev)
diff --git a/kernel/fork.c b/kernel/fork.c
index efb618fc8ffe..cb46befdd3a0 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1787,7 +1787,7 @@ bad_unshare_out:
1787int unshare_files(struct files_struct **displaced) 1787int unshare_files(struct files_struct **displaced)
1788{ 1788{
1789 struct task_struct *task = current; 1789 struct task_struct *task = current;
1790 struct files_struct *copy; 1790 struct files_struct *copy = NULL;
1791 int error; 1791 int error;
1792 1792
1793 error = unshare_fd(CLONE_FILES, &copy); 1793 error = unshare_fd(CLONE_FILES, &copy);