diff options
| -rw-r--r-- | drivers/char/hw_random/geode-rng.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index e7a245942029..e1d421a36a13 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c | |||
| @@ -31,6 +31,9 @@ | |||
| 31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
| 32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
| 33 | 33 | ||
| 34 | |||
| 35 | #define PFX KBUILD_MODNAME ": " | ||
| 36 | |||
| 34 | #define GEODE_RNG_DATA_REG 0x50 | 37 | #define GEODE_RNG_DATA_REG 0x50 |
| 35 | #define GEODE_RNG_STATUS_REG 0x54 | 38 | #define GEODE_RNG_STATUS_REG 0x54 |
| 36 | 39 | ||
| @@ -82,6 +85,7 @@ static struct hwrng geode_rng = { | |||
| 82 | 85 | ||
| 83 | static int __init mod_init(void) | 86 | static int __init mod_init(void) |
| 84 | { | 87 | { |
| 88 | int err = -ENODEV; | ||
| 85 | struct pci_dev *pdev = NULL; | 89 | struct pci_dev *pdev = NULL; |
| 86 | const struct pci_device_id *ent; | 90 | const struct pci_device_id *ent; |
| 87 | void __iomem *mem; | 91 | void __iomem *mem; |
| @@ -89,27 +93,43 @@ static int __init mod_init(void) | |||
| 89 | 93 | ||
| 90 | for_each_pci_dev(pdev) { | 94 | for_each_pci_dev(pdev) { |
| 91 | ent = pci_match_id(pci_tbl, pdev); | 95 | ent = pci_match_id(pci_tbl, pdev); |
| 92 | if (ent) { | 96 | if (ent) |
| 93 | rng_base = pci_resource_start(pdev, 0); | 97 | goto found; |
| 94 | if (rng_base == 0) | ||
| 95 | return -ENODEV; | ||
| 96 | |||
| 97 | mem = devm_ioremap(&pdev->dev, rng_base, 0x58); | ||
| 98 | if (!mem) | ||
| 99 | return -ENOMEM; | ||
| 100 | geode_rng.priv = (unsigned long)mem; | ||
| 101 | |||
| 102 | pr_info("AMD Geode RNG detected\n"); | ||
| 103 | return devm_hwrng_register(&pdev->dev, &geode_rng); | ||
| 104 | } | ||
| 105 | } | 98 | } |
| 106 | |||
| 107 | /* Device not found. */ | 99 | /* Device not found. */ |
| 108 | return -ENODEV; | 100 | goto out; |
| 101 | |||
| 102 | found: | ||
| 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 | } | ||
| 119 | out: | ||
| 120 | return err; | ||
| 121 | |||
| 122 | err_unmap: | ||
| 123 | iounmap(mem); | ||
| 124 | goto out; | ||
| 109 | } | 125 | } |
| 110 | 126 | ||
| 111 | static void __exit mod_exit(void) | 127 | static void __exit mod_exit(void) |
| 112 | { | 128 | { |
| 129 | void __iomem *mem = (void __iomem *)geode_rng.priv; | ||
| 130 | |||
| 131 | hwrng_unregister(&geode_rng); | ||
| 132 | iounmap(mem); | ||
| 113 | } | 133 | } |
| 114 | 134 | ||
| 115 | module_init(mod_init); | 135 | module_init(mod_init); |
