Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0aaa0849 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: add interrupt enabling state to fix deadlock"

parents 2f3e38e3 a4abbc98
Loading
Loading
Loading
Loading
+23 −15
Original line number Diff line number Diff line
@@ -1862,24 +1862,29 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,

	node = container_of(ad_irq, struct sde_crtc_irq_info, irq);

	/* deregister AD irq */
	if (!en) {
		spin_lock_irqsave(&node->state_lock, flags);
		if (node->state == IRQ_ENABLED) {
			node->state = IRQ_DISABLING;
			spin_unlock_irqrestore(&node->state_lock, flags);
			ret = sde_core_irq_disable(kms, &irq_idx, 1);
			if (ret)
			spin_lock_irqsave(&node->state_lock, flags);
			if (ret) {
				DRM_ERROR("disable irq %d error %d\n",
					irq_idx, ret);
			else
				node->state = IRQ_NOINIT;
				node->state = IRQ_ENABLED;
			} else {
			node->state = IRQ_NOINIT;
				node->state = IRQ_DISABLED;
			}
		}
		spin_unlock_irqrestore(&node->state_lock, flags);

		sde_core_irq_unregister_callback(kms, irq_idx, ad_irq);
		ret = 0;
		goto exit;
	}

	/* register AD irq */
	ad_irq->arg = crtc;
	ad_irq->func = sde_cp_ad_interrupt_cb;
	ret = sde_core_irq_register_callback(kms, irq_idx, ad_irq);
@@ -1889,11 +1894,15 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,
	}

	spin_lock_irqsave(&node->state_lock, flags);
	if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
	if (node->state == IRQ_DISABLED) {
		node->state = IRQ_ENABLING;
		spin_unlock_irqrestore(&node->state_lock, flags);
		ret = sde_core_irq_enable(kms, &irq_idx, 1);
		spin_lock_irqsave(&node->state_lock, flags);
		if (ret) {
			DRM_ERROR("enable irq %d error %d\n", irq_idx, ret);
			sde_core_irq_unregister_callback(kms, irq_idx, ad_irq);
			node->state = IRQ_DISABLED;
		} else {
			node->state = IRQ_ENABLED;
		}
@@ -2138,15 +2147,10 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
					irq_idx, ret);
				node->state = IRQ_ENABLED;
			} else {
				node->state = IRQ_NOINIT;
				node->state = IRQ_DISABLED;
			}
			spin_unlock_irqrestore(&node->state_lock, flags);
		} else if (node->state == IRQ_DISABLED) {
			node->state = IRQ_NOINIT;
			spin_unlock_irqrestore(&node->state_lock, flags);
		} else {
			spin_unlock_irqrestore(&node->state_lock, flags);
		}
		spin_unlock_irqrestore(&node->state_lock, flags);

		sde_core_irq_unregister_callback(kms, irq_idx, hist_irq);
		goto exit;
@@ -2162,12 +2166,16 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
	}

	spin_lock_irqsave(&node->state_lock, flags);
	if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
	if (node->state == IRQ_DISABLED) {
		node->state = IRQ_ENABLING;
		spin_unlock_irqrestore(&node->state_lock, flags);
		ret = sde_core_irq_enable(kms, &irq_idx, 1);
		spin_lock_irqsave(&node->state_lock, flags);
		if (ret) {
			DRM_ERROR("enable irq %d error %d\n", irq_idx, ret);
			sde_core_irq_unregister_callback(kms,
				irq_idx, hist_irq);
			node->state = IRQ_DISABLED;
		} else {
			node->state = IRQ_ENABLED;
		}
+1 −1
Original line number Diff line number Diff line
@@ -6216,7 +6216,7 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
			INIT_LIST_HEAD(&node->list);
			node->func = custom_events[i].func;
			node->event = event;
			node->state = IRQ_NOINIT;
			node->state = IRQ_DISABLED;
			spin_lock_init(&node->state_lock);
			break;
		}
+1 −1
Original line number Diff line number Diff line
@@ -430,7 +430,7 @@ struct sde_crtc_state {
};

enum sde_crtc_irq_state {
	IRQ_NOINIT,
	IRQ_ENABLING,
	IRQ_ENABLED,
	IRQ_DISABLING,
	IRQ_DISABLED,