Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #23 from Fede2782/exynos-hwrng-update
Browse files Browse the repository at this point in the history
hwrng: exysdw-rng: Update from P615XXS7FWK1
  • Loading branch information
Royna2544 authored May 12, 2024
2 parents 117bb59 + 7b11ccc commit 9ccaf89
Showing 1 changed file with 41 additions and 44 deletions.
85 changes: 41 additions & 44 deletions drivers/char/hw_random/exyswd-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ static int hwrng_disabled;
#endif
static int start_up_test;

atomic_t hwrng_suspend_flag;
atomic_t hwrng_running_flag;

/* Protects exyswd read functions */
static DEFINE_SPINLOCK(rng_running_lock);

#ifdef CONFIG_EXYRNG_DEBUG
#define exyrng_debug(args...) printk(KERN_INFO args)
#else
Expand Down Expand Up @@ -165,13 +171,25 @@ static int exynos_swd_read(struct hwrng *rng, void *data, size_t max, bool wait)
uint32_t *read_buf = data;
uint32_t read_size = max;
unsigned long flag;
unsigned long running_flag;
uint32_t retry_cnt;
int ret = HWRNG_RET_OK;

#if defined(CONFIG_EXYRNG_FAIL_POLICY_DISABLE)
if (hwrng_disabled)
return -EPERM;
#endif
spin_lock_irqsave(&rng_running_lock, running_flag);
if (atomic_read(&hwrng_suspend_flag) == 1) {
atomic_set(&hwrng_running_flag, 0);
spin_unlock_irqrestore(&rng_running_lock, running_flag);
printk("[ExyRNG] exynos_swd_read is failed because of suspend flag\n");
return -EFAULT;
}

atomic_set(&hwrng_running_flag, 1);
spin_unlock_irqrestore(&rng_running_lock, running_flag);

retry_cnt = 0;
do {
spin_lock_irqsave(&hwrandom_lock, flag);
Expand Down Expand Up @@ -204,7 +222,8 @@ static int exynos_swd_read(struct hwrng *rng, void *data, size_t max, bool wait)
} while (ret == HWRNG_RET_RETRY_ERROR);
if (ret != HWRNG_RET_OK) {
msleep(1);
return -EFAULT;
ret = -EFAULT;
goto err;
}

if (start_up_test) {
Expand Down Expand Up @@ -283,6 +302,11 @@ static int exynos_swd_read(struct hwrng *rng, void *data, size_t max, bool wait)
usleep_range(50, 100);
} while(1);

err:
spin_lock_irqsave(&rng_running_lock, running_flag);
atomic_set(&hwrng_running_flag, 0);
spin_unlock_irqrestore(&rng_running_lock, running_flag);

return ret;
}

Expand All @@ -299,6 +323,9 @@ static int exyswd_rng_probe(struct platform_device *pdev)
start_up_test = 1;
#endif

atomic_set(&hwrng_suspend_flag, 0);
atomic_set(&hwrng_running_flag, 0);

ret = hwrng_register(&rng);
if (ret)
return ret;
Expand All @@ -318,62 +345,32 @@ static int exyswd_rng_remove(struct platform_device *pdev)
#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
static int exyswd_rng_suspend(struct device *dev)
{
uint64_t reg0;
uint64_t reg1;
uint64_t reg2;
uint64_t reg3;
unsigned long flag;
int ret = HWRNG_RET_OK;

spin_lock_irqsave(&hwrandom_lock, flag);
if (hwrng_read_flag) {
reg0 = SMC_CMD_RANDOM;
reg1 = HWRNG_EXIT;
reg2 = 0;
reg3 = 0;

ret = exynos_cm_smc(&reg0, &reg1, &reg2, &reg3);
if (ret != HWRNG_RET_OK)
printk("[ExyRNG] failed to enter suspend with %d\n", ret);
spin_lock_irqsave(&rng_running_lock, flag);
if (atomic_read(&hwrng_running_flag) == 1) {
printk("[ExyRNG] exyswd_rng_suspend: hwrng_running_flag is 1.\n");
ret = -EFAULT;
goto out;
}
spin_unlock_irqrestore(&hwrandom_lock, flag);

atomic_set(&hwrng_suspend_flag, 1);
out:
spin_unlock_irqrestore(&rng_running_lock, flag);

return ret;
}

static int exyswd_rng_resume(struct device *dev)
{
uint64_t reg0;
uint64_t reg1;
uint64_t reg2;
uint64_t reg3;
unsigned long flag;
int ret = HWRNG_RET_OK;

spin_lock_irqsave(&hwrandom_lock, flag);
#if defined(CONFIG_EXYRNG_FIPS_COMPLIANCE)
reg0 = SMC_CMD_RANDOM;
reg1 = HWRNG_RESUME;
reg2 = 0;
reg3 = 0;

ret = exynos_cm_smc(&reg0, &reg1, &reg2, &reg3);
if (ret != HWRNG_RET_OK)
printk("[ExyRNG] failed to resume with %d\n", ret);
#endif
if (hwrng_read_flag) {
reg0 = SMC_CMD_RANDOM;
reg1 = HWRNG_INIT;
reg2 = 0;
reg3 = 0;

ret = exynos_cm_smc(&reg0, &reg1, &reg2, &reg3);
if (ret != HWRNG_RET_OK)
printk("[ExyRNG] failed to resume with %d\n", ret);
}
spin_unlock_irqrestore(&hwrandom_lock, flag);
spin_lock_irqsave(&rng_running_lock, flag);
atomic_set(&hwrng_suspend_flag, 0);
spin_unlock_irqrestore(&rng_running_lock, flag);

return ret;
return HWRNG_RET_OK;
}
#endif

Expand Down

0 comments on commit 9ccaf89

Please sign in to comment.