162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/bitops.h>
362306a36Sopenharmony_ci#include <linux/kernel.h>
462306a36Sopenharmony_ci#include <linux/random.h>
562306a36Sopenharmony_ci#include <linux/slab.h>
662306a36Sopenharmony_ci#include <linux/types.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "drm_random.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciu32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
1362306a36Sopenharmony_ci}
1462306a36Sopenharmony_ciEXPORT_SYMBOL(drm_prandom_u32_max_state);
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_civoid drm_random_reorder(unsigned int *order, unsigned int count,
1762306a36Sopenharmony_ci			struct rnd_state *state)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	unsigned int i, j;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	for (i = 0; i < count; ++i) {
2262306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
2362306a36Sopenharmony_ci		j = drm_prandom_u32_max_state(count, state);
2462306a36Sopenharmony_ci		swap(order[i], order[j]);
2562306a36Sopenharmony_ci	}
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ciEXPORT_SYMBOL(drm_random_reorder);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciunsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	unsigned int *order, i;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	order = kmalloc_array(count, sizeof(*order), GFP_KERNEL);
3462306a36Sopenharmony_ci	if (!order)
3562306a36Sopenharmony_ci		return order;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	for (i = 0; i < count; i++)
3862306a36Sopenharmony_ci		order[i] = i;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	drm_random_reorder(order, count, state);
4162306a36Sopenharmony_ci	return order;
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ciEXPORT_SYMBOL(drm_random_order);
44