diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.h | 1 |
4 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index f7d4d2a10052..c4f5658b9e49 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -520,6 +520,7 @@ struct drm_nouveau_private { | |||
| 520 | 520 | ||
| 521 | struct workqueue_struct *wq; | 521 | struct workqueue_struct *wq; |
| 522 | struct work_struct irq_work; | 522 | struct work_struct irq_work; |
| 523 | struct work_struct hpd_work; | ||
| 523 | 524 | ||
| 524 | struct list_head vbl_waiting; | 525 | struct list_head vbl_waiting; |
| 525 | 526 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 2bd59a92fee5..13e73cee4c44 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
| @@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev) | |||
| 51 | 51 | ||
| 52 | if (dev_priv->card_type == NV_50) { | 52 | if (dev_priv->card_type == NV_50) { |
| 53 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); | 53 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); |
| 54 | INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); | ||
| 54 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); | 55 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); |
| 55 | } | 56 | } |
| 56 | } | 57 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index fd00f4000f14..649db4c1b690 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -887,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev) | |||
| 887 | nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); | 887 | nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); |
| 888 | } | 888 | } |
| 889 | 889 | ||
| 890 | static void | 890 | void |
| 891 | nv50_display_irq_hotplug(struct drm_device *dev) | 891 | nv50_display_irq_hotplug_bh(struct work_struct *work) |
| 892 | { | 892 | { |
| 893 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 893 | struct drm_nouveau_private *dev_priv = |
| 894 | container_of(work, struct drm_nouveau_private, hpd_work); | ||
| 895 | struct drm_device *dev = dev_priv->dev; | ||
| 894 | struct drm_connector *connector; | 896 | struct drm_connector *connector; |
| 895 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | 897 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; |
| 896 | uint32_t unplug_mask, plug_mask, change_mask; | 898 | uint32_t unplug_mask, plug_mask, change_mask; |
| @@ -951,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev) | |||
| 951 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 953 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 952 | uint32_t delayed = 0; | 954 | uint32_t delayed = 0; |
| 953 | 955 | ||
| 954 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) | 956 | if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { |
| 955 | nv50_display_irq_hotplug(dev); | 957 | if (!work_pending(&dev_priv->hpd_work)) |
| 958 | queue_work(dev_priv->wq, &dev_priv->hpd_work); | ||
| 959 | } | ||
| 956 | 960 | ||
| 957 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { | 961 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { |
| 958 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); | 962 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 3ae8d0725f63..581d405ac014 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | void nv50_display_irq_handler(struct drm_device *dev); | 38 | void nv50_display_irq_handler(struct drm_device *dev); |
| 39 | void nv50_display_irq_handler_bh(struct work_struct *work); | 39 | void nv50_display_irq_handler_bh(struct work_struct *work); |
| 40 | void nv50_display_irq_hotplug_bh(struct work_struct *work); | ||
| 40 | int nv50_display_init(struct drm_device *dev); | 41 | int nv50_display_init(struct drm_device *dev); |
| 41 | int nv50_display_create(struct drm_device *dev); | 42 | int nv50_display_create(struct drm_device *dev); |
| 42 | int nv50_display_destroy(struct drm_device *dev); | 43 | int nv50_display_destroy(struct drm_device *dev); |
