cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pl080.c (1814B)


      1/*
      2 * arch/arm/plat-spear/pl080.c
      3 *
      4 * DMAC pl080 definitions for SPEAr platform
      5 *
      6 * Copyright (C) 2012 ST Microelectronics
      7 * Viresh Kumar <vireshk@kernel.org>
      8 *
      9 * This file is licensed under the terms of the GNU General Public
     10 * License version 2. This program is licensed "as is" without any
     11 * warranty of any kind, whether express or implied.
     12 */
     13
     14#include <linux/amba/pl08x.h>
     15#include <linux/amba/bus.h>
     16#include <linux/bug.h>
     17#include <linux/err.h>
     18#include <linux/io.h>
     19#include <linux/spinlock_types.h>
     20#include "spear.h"
     21#include "misc_regs.h"
     22
     23static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x);
     24
     25struct {
     26	unsigned char busy;
     27	unsigned char val;
     28} signals[16] = {{0, 0}, };
     29
     30int pl080_get_signal(const struct pl08x_channel_data *cd)
     31{
     32	unsigned int signal = cd->min_signal, val;
     33	unsigned long flags;
     34
     35	spin_lock_irqsave(&lock, flags);
     36
     37	/* Return if signal is already acquired by somebody else */
     38	if (signals[signal].busy &&
     39			(signals[signal].val != cd->muxval)) {
     40		spin_unlock_irqrestore(&lock, flags);
     41		return -EBUSY;
     42	}
     43
     44	/* If acquiring for the first time, configure it */
     45	if (!signals[signal].busy) {
     46		val = readl(DMA_CHN_CFG);
     47
     48		/*
     49		 * Each request line has two bits in DMA_CHN_CFG register. To
     50		 * goto the bits of current request line, do left shift of
     51		 * value by 2 * signal number.
     52		 */
     53		val &= ~(0x3 << (signal * 2));
     54		val |= cd->muxval << (signal * 2);
     55		writel(val, DMA_CHN_CFG);
     56	}
     57
     58	signals[signal].busy++;
     59	signals[signal].val = cd->muxval;
     60	spin_unlock_irqrestore(&lock, flags);
     61
     62	return signal;
     63}
     64
     65void pl080_put_signal(const struct pl08x_channel_data *cd, int signal)
     66{
     67	unsigned long flags;
     68
     69	spin_lock_irqsave(&lock, flags);
     70
     71	/* if signal is not used */
     72	if (!signals[signal].busy)
     73		BUG();
     74
     75	signals[signal].busy--;
     76
     77	spin_unlock_irqrestore(&lock, flags);
     78}