aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/i830_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/i830_irq.c')
-rw-r--r--drivers/char/drm/i830_irq.c137
1 files changed, 66 insertions, 71 deletions
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
index a5923e5d0a77..5841f7674956 100644
--- a/drivers/char/drm/i830_irq.c
+++ b/drivers/char/drm/i830_irq.c
@@ -9,11 +9,11 @@
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the 10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions: 11 * Software is furnished to do so, subject to the following conditions:
12 * 12 *
13 * The above copyright notice and this permission notice (including the next 13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the 14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software. 15 * Software.
16 * 16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -33,28 +33,27 @@
33#include <linux/interrupt.h> /* For task queue support */ 33#include <linux/interrupt.h> /* For task queue support */
34#include <linux/delay.h> 34#include <linux/delay.h>
35 35
36 36irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
37irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS )
38{ 37{
39 drm_device_t *dev = (drm_device_t *)arg; 38 drm_device_t *dev = (drm_device_t *) arg;
40 drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; 39 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
41 u16 temp; 40 u16 temp;
42 41
43 temp = I830_READ16(I830REG_INT_IDENTITY_R); 42 temp = I830_READ16(I830REG_INT_IDENTITY_R);
44 DRM_DEBUG("%x\n", temp); 43 DRM_DEBUG("%x\n", temp);
45 44
46 if ( !( temp & 2 ) ) 45 if (!(temp & 2))
47 return IRQ_NONE; 46 return IRQ_NONE;
48 47
49 I830_WRITE16(I830REG_INT_IDENTITY_R, temp); 48 I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
50 49
51 atomic_inc(&dev_priv->irq_received); 50 atomic_inc(&dev_priv->irq_received);
52 wake_up_interruptible(&dev_priv->irq_queue); 51 wake_up_interruptible(&dev_priv->irq_queue);
53 52
54 return IRQ_HANDLED; 53 return IRQ_HANDLED;
55} 54}
56 55
57static int i830_emit_irq(drm_device_t *dev) 56static int i830_emit_irq(drm_device_t * dev)
58{ 57{
59 drm_i830_private_t *dev_priv = dev->dev_private; 58 drm_i830_private_t *dev_priv = dev->dev_private;
60 RING_LOCALS; 59 RING_LOCALS;
@@ -63,27 +62,25 @@ static int i830_emit_irq(drm_device_t *dev)
63 62
64 atomic_inc(&dev_priv->irq_emitted); 63 atomic_inc(&dev_priv->irq_emitted);
65 64
66 BEGIN_LP_RING(2); 65 BEGIN_LP_RING(2);
67 OUT_RING( 0 ); 66 OUT_RING(0);
68 OUT_RING( GFX_OP_USER_INTERRUPT ); 67 OUT_RING(GFX_OP_USER_INTERRUPT);
69 ADVANCE_LP_RING(); 68 ADVANCE_LP_RING();
70 69
71 return atomic_read(&dev_priv->irq_emitted); 70 return atomic_read(&dev_priv->irq_emitted);
72} 71}
73 72
74 73static int i830_wait_irq(drm_device_t * dev, int irq_nr)
75static int i830_wait_irq(drm_device_t *dev, int irq_nr)
76{ 74{
77 drm_i830_private_t *dev_priv = 75 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
78 (drm_i830_private_t *)dev->dev_private;
79 DECLARE_WAITQUEUE(entry, current); 76 DECLARE_WAITQUEUE(entry, current);
80 unsigned long end = jiffies + HZ*3; 77 unsigned long end = jiffies + HZ * 3;
81 int ret = 0; 78 int ret = 0;
82 79
83 DRM_DEBUG("%s\n", __FUNCTION__); 80 DRM_DEBUG("%s\n", __FUNCTION__);
84 81
85 if (atomic_read(&dev_priv->irq_received) >= irq_nr) 82 if (atomic_read(&dev_priv->irq_received) >= irq_nr)
86 return 0; 83 return 0;
87 84
88 dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; 85 dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
89 86
@@ -91,21 +88,21 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
91 88
92 for (;;) { 89 for (;;) {
93 __set_current_state(TASK_INTERRUPTIBLE); 90 __set_current_state(TASK_INTERRUPTIBLE);
94 if (atomic_read(&dev_priv->irq_received) >= irq_nr) 91 if (atomic_read(&dev_priv->irq_received) >= irq_nr)
95 break; 92 break;
96 if((signed)(end - jiffies) <= 0) { 93 if ((signed)(end - jiffies) <= 0) {
97 DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", 94 DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
98 I830_READ16( I830REG_INT_IDENTITY_R ), 95 I830_READ16(I830REG_INT_IDENTITY_R),
99 I830_READ16( I830REG_INT_MASK_R ), 96 I830_READ16(I830REG_INT_MASK_R),
100 I830_READ16( I830REG_INT_ENABLE_R ), 97 I830_READ16(I830REG_INT_ENABLE_R),
101 I830_READ16( I830REG_HWSTAM )); 98 I830_READ16(I830REG_HWSTAM));
102 99
103 ret = -EBUSY; /* Lockup? Missed irq? */ 100 ret = -EBUSY; /* Lockup? Missed irq? */
104 break; 101 break;
105 } 102 }
106 schedule_timeout(HZ*3); 103 schedule_timeout(HZ * 3);
107 if (signal_pending(current)) { 104 if (signal_pending(current)) {
108 ret = -EINTR; 105 ret = -EINTR;
109 break; 106 break;
110 } 107 }
111 } 108 }
@@ -115,89 +112,87 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
115 return ret; 112 return ret;
116} 113}
117 114
118
119/* Needs the lock as it touches the ring. 115/* Needs the lock as it touches the ring.
120 */ 116 */
121int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, 117int i830_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd,
122 unsigned long arg ) 118 unsigned long arg)
123{ 119{
124 drm_file_t *priv = filp->private_data; 120 drm_file_t *priv = filp->private_data;
125 drm_device_t *dev = priv->head->dev; 121 drm_device_t *dev = priv->head->dev;
126 drm_i830_private_t *dev_priv = dev->dev_private; 122 drm_i830_private_t *dev_priv = dev->dev_private;
127 drm_i830_irq_emit_t emit; 123 drm_i830_irq_emit_t emit;
128 int result; 124 int result;
129 125
130 LOCK_TEST_WITH_RETURN(dev, filp); 126 LOCK_TEST_WITH_RETURN(dev, filp);
131 127
132 if ( !dev_priv ) { 128 if (!dev_priv) {
133 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 129 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
134 return -EINVAL; 130 return -EINVAL;
135 } 131 }
136 132
137 if (copy_from_user( &emit, (drm_i830_irq_emit_t __user *)arg, sizeof(emit) )) 133 if (copy_from_user
134 (&emit, (drm_i830_irq_emit_t __user *) arg, sizeof(emit)))
138 return -EFAULT; 135 return -EFAULT;
139 136
140 result = i830_emit_irq( dev ); 137 result = i830_emit_irq(dev);
141 138
142 if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { 139 if (copy_to_user(emit.irq_seq, &result, sizeof(int))) {
143 DRM_ERROR( "copy_to_user\n" ); 140 DRM_ERROR("copy_to_user\n");
144 return -EFAULT; 141 return -EFAULT;
145 } 142 }
146 143
147 return 0; 144 return 0;
148} 145}
149 146
150
151/* Doesn't need the hardware lock. 147/* Doesn't need the hardware lock.
152 */ 148 */
153int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, 149int i830_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd,
154 unsigned long arg ) 150 unsigned long arg)
155{ 151{
156 drm_file_t *priv = filp->private_data; 152 drm_file_t *priv = filp->private_data;
157 drm_device_t *dev = priv->head->dev; 153 drm_device_t *dev = priv->head->dev;
158 drm_i830_private_t *dev_priv = dev->dev_private; 154 drm_i830_private_t *dev_priv = dev->dev_private;
159 drm_i830_irq_wait_t irqwait; 155 drm_i830_irq_wait_t irqwait;
160 156
161 if ( !dev_priv ) { 157 if (!dev_priv) {
162 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 158 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
163 return -EINVAL; 159 return -EINVAL;
164 } 160 }
165 161
166 if (copy_from_user( &irqwait, (drm_i830_irq_wait_t __user *)arg, 162 if (copy_from_user(&irqwait, (drm_i830_irq_wait_t __user *) arg,
167 sizeof(irqwait) )) 163 sizeof(irqwait)))
168 return -EFAULT; 164 return -EFAULT;
169 165
170 return i830_wait_irq( dev, irqwait.irq_seq ); 166 return i830_wait_irq(dev, irqwait.irq_seq);
171} 167}
172 168
173
174/* drm_dma.h hooks 169/* drm_dma.h hooks
175*/ 170*/
176void i830_driver_irq_preinstall( drm_device_t *dev ) { 171void i830_driver_irq_preinstall(drm_device_t * dev)
177 drm_i830_private_t *dev_priv = 172{
178 (drm_i830_private_t *)dev->dev_private; 173 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
179 174
180 I830_WRITE16( I830REG_HWSTAM, 0xffff ); 175 I830_WRITE16(I830REG_HWSTAM, 0xffff);
181 I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); 176 I830_WRITE16(I830REG_INT_MASK_R, 0x0);
182 I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); 177 I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
183 atomic_set(&dev_priv->irq_received, 0); 178 atomic_set(&dev_priv->irq_received, 0);
184 atomic_set(&dev_priv->irq_emitted, 0); 179 atomic_set(&dev_priv->irq_emitted, 0);
185 init_waitqueue_head(&dev_priv->irq_queue); 180 init_waitqueue_head(&dev_priv->irq_queue);
186} 181}
187 182
188void i830_driver_irq_postinstall( drm_device_t *dev ) { 183void i830_driver_irq_postinstall(drm_device_t * dev)
189 drm_i830_private_t *dev_priv = 184{
190 (drm_i830_private_t *)dev->dev_private; 185 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
191 186
192 I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); 187 I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
193} 188}
194 189
195void i830_driver_irq_uninstall( drm_device_t *dev ) { 190void i830_driver_irq_uninstall(drm_device_t * dev)
196 drm_i830_private_t *dev_priv = 191{
197 (drm_i830_private_t *)dev->dev_private; 192 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
198 if (!dev_priv) 193 if (!dev_priv)
199 return; 194 return;
200 195
201 I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); 196 I830_WRITE16(I830REG_INT_MASK_R, 0xffff);
202 I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); 197 I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
203} 198}