Merge "msm: kgsl: refcount irq to avoid racing against idle check"

This commit is contained in:
Linux Build Service Account 2017-02-01 19:23:48 -08:00 committed by Gerrit - the friendly Code Review server
commit 664d80e845
2 changed files with 23 additions and 3 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -592,6 +592,9 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
unsigned int status = 0, tmp, int_bit; unsigned int status = 0, tmp, int_bit;
int i; int i;
atomic_inc(&adreno_dev->pending_irq_refcnt);
smp_mb__after_atomic();
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status);
/* /*
@ -630,6 +633,10 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD,
int_bit); int_bit);
smp_mb__before_atomic();
atomic_dec(&adreno_dev->pending_irq_refcnt);
smp_mb__after_atomic();
return ret; return ret;
} }
@ -2030,7 +2037,18 @@ inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev)
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status);
return (status & gpudev->irq->mask) ? 1 : 0; /*
* IRQ handler clears the RBBM INT0 status register immediately
* entering the ISR before actually serving the interrupt because
* of this we can't rely only on RBBM INT0 status only.
* Use pending_irq_refcnt along with RBBM INT0 to correctly
* determine whether any IRQ is pending or not.
*/
if ((status & gpudev->irq->mask) ||
atomic_read(&adreno_dev->pending_irq_refcnt))
return 1;
else
return 0;
} }

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -351,6 +351,7 @@ struct adreno_gpu_core {
* @ram_cycles_lo: Number of DDR clock cycles for the monitor session * @ram_cycles_lo: Number of DDR clock cycles for the monitor session
* @perfctr_pwr_lo: Number of cycles VBIF is stalled by DDR * @perfctr_pwr_lo: Number of cycles VBIF is stalled by DDR
* @halt: Atomic variable to check whether the GPU is currently halted * @halt: Atomic variable to check whether the GPU is currently halted
* @pending_irq_refcnt: Atomic variable to keep track of running IRQ handlers
* @ctx_d_debugfs: Context debugfs node * @ctx_d_debugfs: Context debugfs node
* @pwrctrl_flag: Flag to hold adreno specific power attributes * @pwrctrl_flag: Flag to hold adreno specific power attributes
* @profile_buffer: Memdesc holding the drawobj profiling buffer * @profile_buffer: Memdesc holding the drawobj profiling buffer
@ -408,6 +409,7 @@ struct adreno_device {
unsigned int starved_ram_lo; unsigned int starved_ram_lo;
unsigned int perfctr_pwr_lo; unsigned int perfctr_pwr_lo;
atomic_t halt; atomic_t halt;
atomic_t pending_irq_refcnt;
struct dentry *ctx_d_debugfs; struct dentry *ctx_d_debugfs;
unsigned long pwrctrl_flag; unsigned long pwrctrl_flag;