1/*	$NetBSD: drm_random.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $	*/
2
3// SPDX-License-Identifier: GPL-2.0
4#include <sys/cdefs.h>
5__KERNEL_RCSID(0, "$NetBSD: drm_random.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $");
6
7#include <linux/bitops.h>
8#include <linux/kernel.h>
9#include <linux/random.h>
10#include <linux/slab.h>
11#include <linux/types.h>
12
13#include "drm_random.h"
14
15static inline u32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
16{
17	return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
18}
19
20void drm_random_reorder(unsigned int *order, unsigned int count,
21			struct rnd_state *state)
22{
23	unsigned int i, j;
24
25	for (i = 0; i < count; ++i) {
26		BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
27		j = drm_prandom_u32_max_state(count, state);
28		swap(order[i], order[j]);
29	}
30}
31EXPORT_SYMBOL(drm_random_reorder);
32
33unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
34{
35	unsigned int *order, i;
36
37	order = kmalloc_array(count, sizeof(*order), GFP_KERNEL);
38	if (!order)
39		return order;
40
41	for (i = 0; i < count; i++)
42		order[i] = i;
43
44	drm_random_reorder(order, count, state);
45	return order;
46}
47EXPORT_SYMBOL(drm_random_order);
48