Fichiers
android_kernel_samsung_sm86…/msm/sde/sde_irq.c
Yahui Wang 5c291599a5 disp: msm: sde: set NOAUTOEN for sde irq to match with power event
If display cont-splash is enabled, then sde irq will be enabled
after registration, but sde power event assumes irq to be disabled
by default and will still try to enable irq with first power event
call, then could cause unbalanced irq enable warning on boot up.

Change-Id: Ic5482dd06501721664994f77cd5764140afb7a62
Signed-off-by: Yahui Wang <quic_yahuiw@quicinc.com>
2022-02-22 17:44:05 -08:00

136 lignes
2.7 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/kthread.h>
#include "sde_irq.h"
#include "sde_core_irq.h"
uint32_t g_sde_irq_status;
void sde_irq_update(struct msm_kms *msm_kms, bool enable)
{
struct sde_kms *sde_kms = to_sde_kms(msm_kms);
if (!msm_kms || !sde_kms) {
SDE_ERROR("invalid kms arguments\n");
return;
}
sde_kms->irq_enabled = enable;
if (enable)
enable_irq(sde_kms->irq_num);
else
disable_irq(sde_kms->irq_num);
}
irqreturn_t sde_irq(struct msm_kms *kms)
{
struct sde_kms *sde_kms = to_sde_kms(kms);
u32 interrupts;
sde_kms->hw_intr->ops.get_interrupt_sources(sde_kms->hw_intr,
&interrupts);
/* store irq status in case of irq-storm debugging */
g_sde_irq_status = interrupts;
/*
* Taking care of MDP interrupt
*/
if (interrupts & IRQ_SOURCE_MDP) {
interrupts &= ~IRQ_SOURCE_MDP;
sde_core_irq(sde_kms);
}
/*
* Routing all other interrupts to external drivers
*/
while (interrupts) {
irq_hw_number_t hwirq = fls(interrupts) - 1;
unsigned int mapping;
int rc;
mapping = irq_find_mapping(sde_kms->irq_controller.domain,
hwirq);
if (mapping == 0) {
SDE_EVT32(hwirq, SDE_EVTLOG_ERROR);
goto error;
}
rc = generic_handle_irq(mapping);
if (rc < 0) {
SDE_EVT32(hwirq, mapping, rc, SDE_EVTLOG_ERROR);
goto error;
}
interrupts &= ~(1 << hwirq);
}
return IRQ_HANDLED;
error:
/* bad situation, inform irq system, it may disable overall MDSS irq */
return IRQ_NONE;
}
void sde_irq_preinstall(struct msm_kms *kms)
{
struct sde_kms *sde_kms = to_sde_kms(kms);
if (!sde_kms->dev || !sde_kms->dev->dev) {
pr_err("invalid device handles\n");
return;
}
sde_core_irq_preinstall(sde_kms);
sde_kms->irq_num = platform_get_irq(
to_platform_device(sde_kms->dev->dev),
0);
if (sde_kms->irq_num < 0) {
SDE_ERROR("invalid irq number %d\n", sde_kms->irq_num);
return;
}
/* disable irq until power event enables it */
if (!sde_kms->irq_enabled)
irq_set_status_flags(sde_kms->irq_num, IRQ_NOAUTOEN);
}
int sde_irq_postinstall(struct msm_kms *kms)
{
struct sde_kms *sde_kms = to_sde_kms(kms);
int rc;
if (!kms) {
SDE_ERROR("invalid parameters\n");
return -EINVAL;
}
rc = sde_core_irq_postinstall(sde_kms);
return rc;
}
void sde_irq_uninstall(struct msm_kms *kms)
{
struct sde_kms *sde_kms = to_sde_kms(kms);
if (!kms) {
SDE_ERROR("invalid parameters\n");
return;
}
sde_core_irq_uninstall(sde_kms);
sde_core_irq_domain_fini(sde_kms);
}