Linux Audio

Check our new training course

Loading...
v6.8
  1/*
  2 * RNG driver for AMD Geode RNGs
  3 *
  4 * Copyright 2005 (c) MontaVista Software, Inc.
  5 *
  6 * with the majority of the code coming from:
  7 *
  8 * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
  9 * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
 10 *
 11 * derived from
 12 *
 13 * Hardware driver for the AMD 768 Random Number Generator (RNG)
 14 * (c) Copyright 2001 Red Hat Inc
 15 *
 16 * derived from
 17 *
 18 * Hardware driver for Intel i810 Random Number Generator (RNG)
 19 * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
 20 * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
 21 *
 22 * This file is licensed under  the terms of the GNU General Public
 23 * License version 2. This program is licensed "as is" without any
 24 * warranty of any kind, whether express or implied.
 25 */
 26
 27#include <linux/delay.h>
 28#include <linux/hw_random.h>
 29#include <linux/io.h>
 30#include <linux/kernel.h>
 31#include <linux/module.h>
 
 32#include <linux/pci.h>
 
 
 
 33
 34
 35#define PFX	KBUILD_MODNAME ": "
 36
 37#define GEODE_RNG_DATA_REG   0x50
 38#define GEODE_RNG_STATUS_REG 0x54
 39
 40/*
 41 * Data for PCI driver interface
 42 *
 43 * This data only exists for exporting the supported
 44 * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
 45 * register a pci_driver, because someone else might one day
 46 * want to register another driver on the same PCI id.
 47 */
 48static const struct pci_device_id pci_tbl[] = {
 49	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_LX_AES), 0, },
 50	{ 0, },	/* terminate list */
 51};
 52MODULE_DEVICE_TABLE(pci, pci_tbl);
 53
 54struct amd_geode_priv {
 55	struct pci_dev *pcidev;
 56	void __iomem *membase;
 57};
 58
 59static int geode_rng_data_read(struct hwrng *rng, u32 *data)
 60{
 61	struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv;
 62	void __iomem *mem = priv->membase;
 63
 64	*data = readl(mem + GEODE_RNG_DATA_REG);
 65
 66	return 4;
 67}
 68
 69static int geode_rng_data_present(struct hwrng *rng, int wait)
 70{
 71	struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv;
 72	void __iomem *mem = priv->membase;
 73	int data, i;
 74
 75	for (i = 0; i < 20; i++) {
 76		data = !!(readl(mem + GEODE_RNG_STATUS_REG));
 77		if (data || !wait)
 78			break;
 79		udelay(10);
 80	}
 81	return data;
 82}
 83
 84
 85static struct hwrng geode_rng = {
 86	.name		= "geode",
 87	.data_present	= geode_rng_data_present,
 88	.data_read	= geode_rng_data_read,
 89};
 90
 91
 92static int __init geode_rng_init(void)
 93{
 94	int err = -ENODEV;
 95	struct pci_dev *pdev = NULL;
 96	const struct pci_device_id *ent;
 97	void __iomem *mem;
 98	unsigned long rng_base;
 99	struct amd_geode_priv *priv;
100
101	for_each_pci_dev(pdev) {
102		ent = pci_match_id(pci_tbl, pdev);
103		if (ent)
104			goto found;
105	}
106	/* Device not found. */
107	return err;
108
109found:
110	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
111	if (!priv) {
112		err = -ENOMEM;
113		goto put_dev;
114	}
115
116	rng_base = pci_resource_start(pdev, 0);
117	if (rng_base == 0)
118		goto free_priv;
119	err = -ENOMEM;
120	mem = ioremap(rng_base, 0x58);
121	if (!mem)
122		goto free_priv;
123
124	geode_rng.priv = (unsigned long)priv;
125	priv->membase = mem;
126	priv->pcidev = pdev;
127
128	pr_info("AMD Geode RNG detected\n");
129	err = hwrng_register(&geode_rng);
130	if (err) {
131		pr_err(PFX "RNG registering failed (%d)\n",
132		       err);
133		goto err_unmap;
134	}
 
135	return err;
136
137err_unmap:
138	iounmap(mem);
139free_priv:
140	kfree(priv);
141put_dev:
142	pci_dev_put(pdev);
143	return err;
144}
145
146static void __exit geode_rng_exit(void)
147{
148	struct amd_geode_priv *priv;
149
150	priv = (struct amd_geode_priv *)geode_rng.priv;
151	hwrng_unregister(&geode_rng);
152	iounmap(priv->membase);
153	pci_dev_put(priv->pcidev);
154	kfree(priv);
155}
156
157module_init(geode_rng_init);
158module_exit(geode_rng_exit);
159
160MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs");
161MODULE_LICENSE("GPL");
v4.6
  1/*
  2 * RNG driver for AMD Geode RNGs
  3 *
  4 * Copyright 2005 (c) MontaVista Software, Inc.
  5 *
  6 * with the majority of the code coming from:
  7 *
  8 * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
  9 * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
 10 *
 11 * derived from
 12 *
 13 * Hardware driver for the AMD 768 Random Number Generator (RNG)
 14 * (c) Copyright 2001 Red Hat Inc
 15 *
 16 * derived from
 17 *
 18 * Hardware driver for Intel i810 Random Number Generator (RNG)
 19 * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
 20 * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
 21 *
 22 * This file is licensed under  the terms of the GNU General Public
 23 * License version 2. This program is licensed "as is" without any
 24 * warranty of any kind, whether express or implied.
 25 */
 26
 
 
 
 
 27#include <linux/module.h>
 28#include <linux/kernel.h>
 29#include <linux/pci.h>
 30#include <linux/hw_random.h>
 31#include <linux/delay.h>
 32#include <asm/io.h>
 33
 34
 35#define PFX	KBUILD_MODNAME ": "
 36
 37#define GEODE_RNG_DATA_REG   0x50
 38#define GEODE_RNG_STATUS_REG 0x54
 39
 40/*
 41 * Data for PCI driver interface
 42 *
 43 * This data only exists for exporting the supported
 44 * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
 45 * register a pci_driver, because someone else might one day
 46 * want to register another driver on the same PCI id.
 47 */
 48static const struct pci_device_id pci_tbl[] = {
 49	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_LX_AES), 0, },
 50	{ 0, },	/* terminate list */
 51};
 52MODULE_DEVICE_TABLE(pci, pci_tbl);
 53
 
 
 
 
 54
 55static int geode_rng_data_read(struct hwrng *rng, u32 *data)
 56{
 57	void __iomem *mem = (void __iomem *)rng->priv;
 
 58
 59	*data = readl(mem + GEODE_RNG_DATA_REG);
 60
 61	return 4;
 62}
 63
 64static int geode_rng_data_present(struct hwrng *rng, int wait)
 65{
 66	void __iomem *mem = (void __iomem *)rng->priv;
 
 67	int data, i;
 68
 69	for (i = 0; i < 20; i++) {
 70		data = !!(readl(mem + GEODE_RNG_STATUS_REG));
 71		if (data || !wait)
 72			break;
 73		udelay(10);
 74	}
 75	return data;
 76}
 77
 78
 79static struct hwrng geode_rng = {
 80	.name		= "geode",
 81	.data_present	= geode_rng_data_present,
 82	.data_read	= geode_rng_data_read,
 83};
 84
 85
 86static int __init mod_init(void)
 87{
 88	int err = -ENODEV;
 89	struct pci_dev *pdev = NULL;
 90	const struct pci_device_id *ent;
 91	void __iomem *mem;
 92	unsigned long rng_base;
 
 93
 94	for_each_pci_dev(pdev) {
 95		ent = pci_match_id(pci_tbl, pdev);
 96		if (ent)
 97			goto found;
 98	}
 99	/* Device not found. */
100	goto out;
101
102found:
 
 
 
 
 
 
103	rng_base = pci_resource_start(pdev, 0);
104	if (rng_base == 0)
105		goto out;
106	err = -ENOMEM;
107	mem = ioremap(rng_base, 0x58);
108	if (!mem)
109		goto out;
110	geode_rng.priv = (unsigned long)mem;
 
 
 
111
112	pr_info("AMD Geode RNG detected\n");
113	err = hwrng_register(&geode_rng);
114	if (err) {
115		pr_err(PFX "RNG registering failed (%d)\n",
116		       err);
117		goto err_unmap;
118	}
119out:
120	return err;
121
122err_unmap:
123	iounmap(mem);
124	goto out;
 
 
 
 
125}
126
127static void __exit mod_exit(void)
128{
129	void __iomem *mem = (void __iomem *)geode_rng.priv;
130
 
131	hwrng_unregister(&geode_rng);
132	iounmap(mem);
 
 
133}
134
135module_init(mod_init);
136module_exit(mod_exit);
137
138MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs");
139MODULE_LICENSE("GPL");