Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/armada: move IRQ handling into CRTC

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

+45 -63
+34 -2
drivers/gpu/drm/armada/armada_crtc.c
··· 349 349 return true; 350 350 } 351 351 352 - void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) 352 + static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) 353 353 { 354 354 struct armada_vbl_event *e, *n; 355 355 void __iomem *base = dcrtc->base; ··· 408 408 409 409 wake_up(&dcrtc->frame_wait); 410 410 } 411 + } 412 + 413 + static irqreturn_t armada_drm_irq(int irq, void *arg) 414 + { 415 + struct armada_crtc *dcrtc = arg; 416 + u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); 417 + 418 + /* 419 + * This is rediculous - rather than writing bits to clear, we 420 + * have to set the actual status register value. This is racy. 421 + */ 422 + writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); 423 + 424 + /* Mask out those interrupts we haven't enabled */ 425 + v = stat & dcrtc->irq_ena; 426 + 427 + if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) { 428 + armada_drm_crtc_irq(dcrtc, stat); 429 + return IRQ_HANDLED; 430 + } 431 + return IRQ_NONE; 411 432 } 412 433 413 434 /* These are locked by dev->vbl_lock */ ··· 909 888 if (!IS_ERR(dcrtc->clk)) 910 889 clk_disable_unprepare(dcrtc->clk); 911 890 891 + writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA); 892 + 912 893 kfree(dcrtc); 913 894 } 914 895 ··· 1051 1028 } 1052 1029 1053 1030 int armada_drm_crtc_create(struct drm_device *dev, unsigned num, 1054 - struct resource *res) 1031 + struct resource *res, int irq) 1055 1032 { 1056 1033 struct armada_private *priv = dev->dev_private; 1057 1034 struct armada_crtc *dcrtc; ··· 1097 1074 CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); 1098 1075 writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); 1099 1076 writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN); 1077 + writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); 1078 + writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); 1079 + 1080 + ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", 1081 + dcrtc); 1082 + if (ret < 0) { 1083 + kfree(dcrtc); 1084 + return ret; 1085 + } 1100 1086 1101 1087 if (priv->variant->crtc_init) { 1102 1088 ret = priv->variant->crtc_init(dcrtc);
+2 -2
drivers/gpu/drm/armada/armada_crtc.h
··· 72 72 }; 73 73 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc) 74 74 75 - int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *); 75 + int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *, 76 + int); 76 77 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int); 77 78 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int); 78 - void armada_drm_crtc_irq(struct armada_crtc *, u32); 79 79 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32); 80 80 void armada_drm_crtc_enable_irq(struct armada_crtc *, u32); 81 81 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
+9 -59
drivers/gpu/drm/armada/armada_drv.c
··· 155 155 156 156 /* Create all LCD controllers */ 157 157 for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) { 158 + int irq; 159 + 158 160 if (!res[n]) 159 161 break; 160 162 161 - ret = armada_drm_crtc_create(dev, n, res[n]); 163 + irq = platform_get_irq(dev->platformdev, n); 164 + if (irq < 0) 165 + goto err_kms; 166 + 167 + ret = armada_drm_crtc_create(dev, n, res[n], irq); 162 168 if (ret) 163 169 goto err_kms; 164 170 } ··· 179 173 if (ret) 180 174 goto err_kms; 181 175 182 - ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0)); 183 - if (ret) 184 - goto err_kms; 185 - 186 176 dev->vblank_disable_allowed = 1; 187 177 188 178 ret = armada_fbdev_init(dev); 189 179 if (ret) 190 - goto err_irq; 180 + goto err_kms; 191 181 192 182 drm_kms_helper_poll_init(dev); 193 183 194 184 return 0; 195 185 196 - err_irq: 197 - drm_irq_uninstall(dev); 198 186 err_kms: 199 187 drm_mode_config_cleanup(dev); 200 188 drm_mm_takedown(&priv->linear); ··· 203 203 204 204 drm_kms_helper_poll_fini(dev); 205 205 armada_fbdev_fini(dev); 206 - drm_irq_uninstall(dev); 207 206 drm_mode_config_cleanup(dev); 208 207 drm_mm_takedown(&priv->linear); 209 208 flush_work(&priv->fb_unref_work); ··· 258 259 armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA); 259 260 } 260 261 261 - static irqreturn_t armada_drm_irq_handler(int irq, void *arg) 262 - { 263 - struct drm_device *dev = arg; 264 - struct armada_private *priv = dev->dev_private; 265 - struct armada_crtc *dcrtc = priv->dcrtc[0]; 266 - uint32_t v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); 267 - irqreturn_t handled = IRQ_NONE; 268 - 269 - /* 270 - * This is rediculous - rather than writing bits to clear, we 271 - * have to set the actual status register value. This is racy. 272 - */ 273 - writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); 274 - 275 - /* Mask out those interrupts we haven't enabled */ 276 - v = stat & dcrtc->irq_ena; 277 - 278 - if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) { 279 - armada_drm_crtc_irq(dcrtc, stat); 280 - handled = IRQ_HANDLED; 281 - } 282 - 283 - return handled; 284 - } 285 - 286 - static int armada_drm_irq_postinstall(struct drm_device *dev) 287 - { 288 - struct armada_private *priv = dev->dev_private; 289 - struct armada_crtc *dcrtc = priv->dcrtc[0]; 290 - 291 - spin_lock_irq(&dev->vbl_lock); 292 - writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); 293 - writel(0, dcrtc->base + LCD_SPU_IRQ_ISR); 294 - spin_unlock_irq(&dev->vbl_lock); 295 - 296 - return 0; 297 - } 298 - 299 - static void armada_drm_irq_uninstall(struct drm_device *dev) 300 - { 301 - struct armada_private *priv = dev->dev_private; 302 - struct armada_crtc *dcrtc = priv->dcrtc[0]; 303 - 304 - writel(0, dcrtc->base + LCD_SPU_IRQ_ENA); 305 - } 306 - 307 262 static struct drm_ioctl_desc armada_ioctls[] = { 308 263 DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl, 309 264 DRM_UNLOCKED), ··· 293 340 .get_vblank_counter = drm_vblank_count, 294 341 .enable_vblank = armada_drm_enable_vblank, 295 342 .disable_vblank = armada_drm_disable_vblank, 296 - .irq_handler = armada_drm_irq_handler, 297 - .irq_postinstall = armada_drm_irq_postinstall, 298 - .irq_uninstall = armada_drm_irq_uninstall, 299 343 #ifdef CONFIG_DEBUG_FS 300 344 .debugfs_init = armada_drm_debugfs_init, 301 345 .debugfs_cleanup = armada_drm_debugfs_cleanup, ··· 312 362 .desc = "Armada SoC DRM", 313 363 .date = "20120730", 314 364 .driver_features = DRIVER_GEM | DRIVER_MODESET | 315 - DRIVER_HAVE_IRQ | DRIVER_PRIME, 365 + DRIVER_PRIME, 316 366 .ioctls = armada_ioctls, 317 367 .fops = &armada_drm_fops, 318 368 };