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

Commit 700cd930 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 spin lock for interrupt state"

parents c7559a5c ed79cec6
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
@@ -613,6 +613,7 @@ static void _sde_cp_crtc_enable_hist_irq(struct sde_crtc *sde_crtc)
	if (!node)
		return;

	spin_lock_irqsave(&node->state_lock, flags);
	if (node->state == IRQ_DISABLED) {
		ret = sde_core_irq_enable(kms, &irq_idx, 1);
		if (ret)
@@ -620,6 +621,7 @@ static void _sde_cp_crtc_enable_hist_irq(struct sde_crtc *sde_crtc)
		else
			node->state = IRQ_ENABLED;
	}
	spin_unlock_irqrestore(&node->state_lock, flags);
}

static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
@@ -1623,6 +1625,7 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,
	struct sde_crtc *crtc;
	int i;
	int irq_idx, ret;
	unsigned long flags;
	struct sde_cp_node prop_node;
	struct sde_crtc_irq_info *node = NULL;

@@ -1673,6 +1676,7 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,

	if (!en) {
		if (node) {
			spin_lock_irqsave(&node->state_lock, flags);
			if (node->state == IRQ_ENABLED) {
				ret = sde_core_irq_disable(kms, &irq_idx, 1);
				if (ret)
@@ -1683,6 +1687,7 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,
			} else {
				node->state = IRQ_NOINIT;
			}
			spin_unlock_irqrestore(&node->state_lock, flags);
		} else {
			DRM_ERROR("failed to get node from crtc event list\n");
		}
@@ -1701,6 +1706,7 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,

	if (node) {
		/* device resume or resume from IPC cases */
		spin_lock_irqsave(&node->state_lock, flags);
		if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
			ret = sde_core_irq_enable(kms, &irq_idx, 1);
			if (ret) {
@@ -1712,6 +1718,7 @@ int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,
				node->state = IRQ_ENABLED;
			}
		}
		spin_unlock_irqrestore(&node->state_lock, flags);
	} else {
		/* request from userspace to register the event
		 * in this case, node has not been added into the event list
@@ -1807,14 +1814,17 @@ static void sde_cp_hist_interrupt_cb(void *arg, int irq_idx)
		return;
	}

	spin_lock_irqsave(&node->state_lock, flags);
	if (node->state == IRQ_ENABLED) {
		if (sde_core_irq_disable_nolock(kms, irq_idx)) {
			DRM_ERROR("failed to disable irq %d, ret %d\n",
				irq_idx, ret);
			spin_unlock_irqrestore(&node->state_lock, flags);
			return;
		}
		node->state = IRQ_DISABLED;
	}
	spin_unlock_irqrestore(&node->state_lock, flags);

	/* lock histogram buffer */
	for (i = 0; i < crtc->num_mixers; i++) {
@@ -1886,6 +1896,7 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
	struct sde_crtc *crtc;
	struct sde_crtc_irq_info *node = NULL;
	int i, irq_idx, ret = 0;
	unsigned long flags;

	if (!crtc_drm || !hist_irq) {
		DRM_ERROR("invalid crtc %pK irq %pK\n", crtc_drm, hist_irq);
@@ -1928,6 +1939,7 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
	if (!en) {
		if (node) {
			/* device suspend case or suspend to IPC cases */
			spin_lock_irqsave(&node->state_lock, flags);
			if (node->state == IRQ_ENABLED) {
				ret = sde_core_irq_disable(kms, &irq_idx, 1);
				if (ret)
@@ -1938,6 +1950,7 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
			} else {
				node->state = IRQ_NOINIT;
			}
			spin_unlock_irqrestore(&node->state_lock, flags);
		} else {
			DRM_ERROR("failed to get node from crtc event list\n");
		}
@@ -1957,6 +1970,7 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,

	if (node) {
		/* device resume or resume from IPC cases */
		spin_lock_irqsave(&node->state_lock, flags);
		if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
			ret = sde_core_irq_enable(kms, &irq_idx, 1);
			if (ret) {
@@ -1968,6 +1982,7 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
				node->state = IRQ_ENABLED;
			}
		}
		spin_unlock_irqrestore(&node->state_lock, flags);
	} else {
		/* request from userspace to register the event
		 * in this case, node has not been added into the event list
+1 −0
Original line number Diff line number Diff line
@@ -6133,6 +6133,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;
			spin_lock_init(&node->state_lock);
			break;
		}
	}
+3 −1
Original line number Diff line number Diff line
@@ -445,7 +445,8 @@ enum sde_crtc_irq_state {
 * @event: event type of the interrupt
 * @func: function pointer to enable/disable the interrupt
 * @list: list of user customized event in crtc
 * @ref_count: reference count for the interrupt
 * @state: state of the interrupt
 * @state_lock: spin lock for interrupt state
 */
struct sde_crtc_irq_info {
	struct sde_irq_callback irq;
@@ -454,6 +455,7 @@ struct sde_crtc_irq_info {
			struct sde_irq_callback *irq);
	struct list_head list;
	enum sde_crtc_irq_state state;
	spinlock_t state_lock;
};

#define to_sde_crtc_state(x) \