[PATCH 19/72] gpu: ipu-v3: Protect more CM reg access with IPU lock
Philipp Zabel
p.zabel at pengutronix.de
Tue Nov 4 09:51:50 PST 2014
Hi Steve,
Am Freitag, den 31.10.2014, 15:54 -0700 schrieb Steve Longerbeam:
> Some cm_reg accesses were not being protected by the IPU spin lock.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam at mentor.com>
> ---
> drivers/gpu/ipu-v3/ipu-common.c | 22 ++++++++++++++++++++--
> 1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
> index f707d25..d3af206 100644
> --- a/drivers/gpu/ipu-v3/ipu-common.c
> +++ b/drivers/gpu/ipu-v3/ipu-common.c
> @@ -46,11 +46,16 @@ static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
>
> void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
> {
> + unsigned long flags;
> u32 val;
>
> + spin_lock_irqsave(&ipu->lock, flags);
> +
> val = ipu_cm_read(ipu, IPU_SRM_PRI2);
> val |= 0x8;
> ipu_cm_write(ipu, val, IPU_SRM_PRI2);
> +
> + spin_unlock_irqrestore(&ipu->lock, flags);
> }
> EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update);
This is the only place this register touched, only bit 3 is ever enabled
by software. This lock is not needed.
> @@ -451,8 +456,17 @@ int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel)
> {
> struct ipu_soc *ipu = channel->ipu;
> unsigned int chno = channel->num;
> + unsigned long flags;
> + int ret;
> +
> + spin_lock_irqsave(&ipu->lock, flags);
>
> - return (ipu_cm_read(ipu, IPU_CHA_CUR_BUF(chno)) & idma_mask(chno)) ? 1 : 0;
> + ret = (ipu_cm_read(ipu, IPU_CHA_CUR_BUF(chno)) & idma_mask(chno)) ?
> + 1 : 0;
> +
> + spin_unlock_irqrestore(&ipu->lock, flags);
> +
> + return ret;
Dito. This register isn't written partially multiple times under the
spinlock anywhere, so there is no gain from this lock around a register
read.
> }
> EXPORT_SYMBOL_GPL(ipu_idmac_get_current_buffer);
>
> @@ -569,10 +583,14 @@ EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
>
> int ipu_wait_interrupt(struct ipu_soc *ipu, int irq, int ms)
> {
> - unsigned long timeout;
> + unsigned long flags, timeout;
>
> timeout = jiffies + msecs_to_jiffies(ms);
> +
> + spin_lock_irqsave(&ipu->lock, flags);
> ipu_cm_write(ipu, BIT(irq % 32), IPU_INT_STAT(irq / 32));
> + spin_unlock_irqrestore(&ipu->lock, flags);
> +
> while (!(ipu_cm_read(ipu, IPU_INT_STAT(irq / 32) & BIT(irq % 32)))) {
> if (time_after(jiffies, timeout))
> return -ETIMEDOUT;
This is a write to clear register, the only other place it is accessed
is by the regmap irq handler. Can you think of a scenario where this
lock would protect anything?
regards
Philipp
More information about the dri-devel
mailing list