diff options
Diffstat (limited to 'drivers/char/drm/i830_irq.c')
-rw-r--r-- | drivers/char/drm/i830_irq.c | 137 |
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 | 36 | irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS) | |
37 | irqreturn_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 | ||
57 | static int i830_emit_irq(drm_device_t *dev) | 56 | static 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 | 73 | static int i830_wait_irq(drm_device_t * dev, int irq_nr) | |
75 | static 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 | */ |
121 | int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, | 117 | int 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 | */ |
153 | int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, | 149 | int 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 | */ |
176 | void i830_driver_irq_preinstall( drm_device_t *dev ) { | 171 | void 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 | ||
188 | void i830_driver_irq_postinstall( drm_device_t *dev ) { | 183 | void 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 | ||
195 | void i830_driver_irq_uninstall( drm_device_t *dev ) { | 190 | void 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 | } |