Ejemplo n.º 1
0
/* brief
 * arg0: command type as TEE_SMC_PLAFORM_OPERATION
 * arg1: set standby status mode.(clear or get or set)
 * arg2: standby reg physical address.
 * arg3: value to set when set.
 */
static u32 sunxi_sec_set_standby_status(u32 command_type, u32 setting_type, u32 addr, u32 val)
{
	u32 ret_val = 0;
	u32 phys_addr;

	phys_addr = (u32)addr > (u32)IO_ADDRESS(0) ? ((u32)addr - (u32)IO_ADDRESS(0)) : (u32)addr;
	switch(setting_type){
		case TE_SMC_STANDBY_STATUS_CLEAR:
			ret_val = sunxi_do_smc(TEE_SMC_PLAFORM_OPERATION, TE_SMC_READ_REG, phys_addr, 0);
			if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
				ret_val = sunxi_do_smc(TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_CLEAR, phys_addr, ret_val);
				hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
			}
			break;
		case TE_SMC_STANDBY_STATUS_SET:
			if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
				ret_val = sunxi_do_smc(TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_SET, phys_addr, val);
				hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
			}
			asm volatile ("dsb");
			asm volatile ("isb");

			break;
		case TE_SMC_STANDBY_STATUS_GET:
			if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
				ret_val = sunxi_do_smc(TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_GET, phys_addr, val);
				hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
			}
			break;
		default:
			break;
	}

	return ret_val;
}
Ejemplo n.º 2
0
void show_pm_secure_mem_status(void)
{
	int i = 1;
	int val = 0;
	
#ifndef CONFIG_SUNXI_TRUSTZONE
	while(i < STANDBY_STATUS_REG_NUM) {
		pm_secure_status_reg_tmp.bits.reg_sel = i;
		if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
			hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
		}
		val = pm_secure_status_reg_tmp.bits.data_rd;
		printk("addr %x, value = %x. \n", (i), val);
		i++;
	}
#else
	while(i < STANDBY_STATUS_REG_NUM){
		val = call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_GET, (u32)pm_secure_status_reg, i);
		printk("addr %x, value = %x. \n", (i), val);
		i++;
	}
#endif

}
static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
{
	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
	unsigned long flags;
	unsigned char gpiodir;

	if (offset >= gc->ngpio)
		return -EINVAL;

	spin_lock_irqsave(&chip->lock, flags);

	if (hwspin_lock_timeout(gpio_hwlock, LOCK_TIMEOUT)) {
		pr_err("%s: hwspinlock timeout!\n", __func__);
		spin_unlock_irqrestore(&chip->lock, flags);
		return -EBUSY;
	}

	gpiodir = readb(chip->base + GPIODIR);
	gpiodir &= ~(1 << offset);
	writeb(gpiodir, chip->base + GPIODIR);

	hwspin_unlock(gpio_hwlock);
	spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}
static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
		int value)
{
	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
	unsigned long flags;
	unsigned char gpiodir;

	if (offset >= gc->ngpio)
		return -EINVAL;

	spin_lock_irqsave(&chip->lock, flags);

	if (hwspin_lock_timeout(gpio_hwlock, LOCK_TIMEOUT)) {
		pr_err("%s: hwspinlock timeout!\n", __func__);
		spin_unlock_irqrestore(&chip->lock, flags);
		return -EBUSY;
	}

	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
	gpiodir = readb(chip->base + GPIODIR);
	gpiodir |= 1 << offset;
	writeb(gpiodir, chip->base + GPIODIR);

	/*
	 * gpio value is set again, because pl061 doesn't allow to set value of
	 * a gpio pin before configuring it in OUT mode.
	 */
	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
	hwspin_unlock(gpio_hwlock);
	spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}
/*hwspin_trylock()
* Returns 0 if we successfully locked the hwspinlock, -EBUSY if
* the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
* hwspin_lock_timeout()
* Returns 0 when the @hwlock was successfully taken, and an appropriate
* error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
* busy after @timeout msecs). The function will never sleep.
*/
static int debugfs_hwspinlock_trylock_timeout(int id, int timeout, int unlock)
{
	struct hwspinlock_hisi *hwlockinfo, *hwunlockinfo;
	int ret = 0;
	int val0, val1 = 0;

	if (0 == timeout)
		ret = hwspin_trylock(hwlock);
	else if (timeout > 0) {
		ret = hwspin_lock_timeout(hwlock, timeout);
		if (ret) {
			pr_err("%s: hwspinlock timeout!\n", __func__);
			goto _timout;
		}
	}
	hwlockinfo = (struct hwspinlock_hisi *)(hwlock->priv);
	val0 = readl(hwlockinfo->address + RESOURCE_LOCK_STAT_OFFSET);
	locked = 1;
	if (unlock) {
		hwspin_unlock(hwlock);
		hwunlockinfo = (struct hwspinlock_hisi *)(hwlock->priv);
		val1 = readl(hwunlockinfo->address + RESOURCE_LOCK_STAT_OFFSET);
		locked = 0;
	} else
		val1 = readl(hwlockinfo->address + RESOURCE_LOCK_STAT_OFFSET);
	pr_info("[debug]the ResourceLock %d locked val= 0x%x,unlock val=0x%x\n", id, val0, val1);

_timout:
	return ret;
}
Ejemplo n.º 6
0
static void sci_glb_lock(unsigned long *flags, unsigned long *hw_flags)
{
	spin_lock_irqsave(&glb_lock, *flags);
	*hw_flags = hw_local_irq_save();
	if (arch_get_hwlock(HWLOCK_GLB))
		WARN_ON(IS_ERR_VALUE(hwspin_lock_timeout(arch_get_hwlock(HWLOCK_GLB), -1)));
	else
		arch_hwlock_fast(HWLOCK_GLB);
}
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
	struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
	int offset = irqd_to_hwirq(d);
	unsigned long flags;
	u8 gpiois, gpioibe, gpioiev;

	if (offset < 0 || offset >= PL061_GPIO_NR)
		return -EINVAL;

	spin_lock_irqsave(&chip->lock, flags);

	if (hwspin_lock_timeout(gpio_hwlock, LOCK_TIMEOUT)) {
		pr_err("%s: hwspinlock timeout!\n", __func__);
		spin_unlock_irqrestore(&chip->lock, flags);
		return -EBUSY;
	}

	gpioiev = readb(chip->base + GPIOIEV);

	gpiois = readb(chip->base + GPIOIS);
	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
		gpiois |= 1 << offset;
		if (trigger & IRQ_TYPE_LEVEL_HIGH)
			gpioiev |= 1 << offset;
		else
			gpioiev &= ~(1 << offset);
	} else
		gpiois &= ~(1 << offset);
	writeb(gpiois, chip->base + GPIOIS);

	gpioibe = readb(chip->base + GPIOIBE);
	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
		gpioibe |= 1 << offset;
	else {
		gpioibe &= ~(1 << offset);
		if (trigger & IRQ_TYPE_EDGE_RISING)
			gpioiev |= 1 << offset;
		else if (trigger & IRQ_TYPE_EDGE_FALLING)
			gpioiev &= ~(1 << offset);
	}
	writeb(gpioibe, chip->base + GPIOIBE);

	writeb(gpioiev, chip->base + GPIOIEV);

	hwspin_unlock(gpio_hwlock);
	spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}
Ejemplo n.º 8
0
__u32 get_pm_secure_mem_status(void)
{
	int val = 0;

#ifndef CONFIG_SUNXI_TRUSTZONE
	pm_secure_status_reg_tmp.bits.reg_sel = 1;
	if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
		hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
	}

	val = pm_secure_status_reg_tmp.bits.data_rd;
	return (val);
#else
	val = call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_GET, (u32)pm_secure_status_reg, 1);
	return (val);
#endif
}
static void pl061_irq_unmask(struct irq_data *d)
{
	struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
	u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
	u8 gpioie;
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);

	if (hwspin_lock_timeout(gpio_hwlock, LOCK_TIMEOUT)) {
		pr_err("%s: hwspinlock timeout!\n!", __func__);
		spin_unlock_irqrestore(&chip->lock, flags);
		return ;
	}

	gpioie = readb(chip->base + GPIOIE) | mask;
	writeb(gpioie, chip->base + GPIOIE);

	hwspin_unlock(gpio_hwlock);
	spin_unlock_irqrestore(&chip->lock, flags);
}
Ejemplo n.º 10
0
void save_pm_secure_mem_status(volatile __u32 val)
{
#ifndef CONFIG_SUNXI_TRUSTZONE
	if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		pm_secure_status_reg_tmp.bits.reg_sel = 1;
		pm_secure_status_reg_tmp.bits.data_wr = val;
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		pm_secure_status_reg_tmp.bits.wr_pulse = 0;
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		pm_secure_status_reg_tmp.bits.wr_pulse = 1;
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		pm_secure_status_reg_tmp.bits.wr_pulse = 0;
		(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
		hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
	}
	asm volatile ("dsb");
	asm volatile ("isb");
	return;
#else
	call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_SET, (u32)pm_secure_status_reg, val);
	return;
#endif
}
Ejemplo n.º 11
0
void pm_secure_mem_status_clear(void)
{
#ifndef CONFIG_SUNXI_TRUSTZONE
	int i = 1;
	pm_secure_status_reg_tmp.dwval = (*pm_secure_status_reg).dwval;
	if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
		while(i < STANDBY_STATUS_REG_NUM){
			pm_secure_status_reg_tmp.bits.reg_sel = i;
			pm_secure_status_reg_tmp.bits.data_wr = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 1;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			pm_secure_status_reg_tmp.bits.wr_pulse = 0;
			(*pm_secure_status_reg).dwval = pm_secure_status_reg_tmp.dwval;
			i++;
	    	}
		hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
	}
#else
	call_firmware_op(set_standby_status,TEE_SMC_PLAFORM_OPERATION, TE_SMC_STANDBY_STATUS_CLEAR, (u32)pm_secure_status_reg, 0);
#endif
}