| .. | .. |
|---|
| 51 | 51 | }; |
|---|
| 52 | 52 | MODULE_DEVICE_TABLE(pci, pci_tbl); |
|---|
| 53 | 53 | |
|---|
| 54 | +struct amd_geode_priv { |
|---|
| 55 | + struct pci_dev *pcidev; |
|---|
| 56 | + void __iomem *membase; |
|---|
| 57 | +}; |
|---|
| 54 | 58 | |
|---|
| 55 | 59 | static int geode_rng_data_read(struct hwrng *rng, u32 *data) |
|---|
| 56 | 60 | { |
|---|
| .. | .. |
|---|
| 90 | 94 | const struct pci_device_id *ent; |
|---|
| 91 | 95 | void __iomem *mem; |
|---|
| 92 | 96 | unsigned long rng_base; |
|---|
| 97 | + struct amd_geode_priv *priv; |
|---|
| 93 | 98 | |
|---|
| 94 | 99 | for_each_pci_dev(pdev) { |
|---|
| 95 | 100 | ent = pci_match_id(pci_tbl, pdev); |
|---|
| .. | .. |
|---|
| 97 | 102 | goto found; |
|---|
| 98 | 103 | } |
|---|
| 99 | 104 | /* Device not found. */ |
|---|
| 100 | | - goto out; |
|---|
| 105 | + return err; |
|---|
| 101 | 106 | |
|---|
| 102 | 107 | found: |
|---|
| 108 | + priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
|---|
| 109 | + if (!priv) { |
|---|
| 110 | + err = -ENOMEM; |
|---|
| 111 | + goto put_dev; |
|---|
| 112 | + } |
|---|
| 113 | + |
|---|
| 103 | 114 | rng_base = pci_resource_start(pdev, 0); |
|---|
| 104 | 115 | if (rng_base == 0) |
|---|
| 105 | | - goto out; |
|---|
| 116 | + goto free_priv; |
|---|
| 106 | 117 | err = -ENOMEM; |
|---|
| 107 | 118 | mem = ioremap(rng_base, 0x58); |
|---|
| 108 | 119 | if (!mem) |
|---|
| 109 | | - goto out; |
|---|
| 110 | | - geode_rng.priv = (unsigned long)mem; |
|---|
| 120 | + goto free_priv; |
|---|
| 121 | + |
|---|
| 122 | + geode_rng.priv = (unsigned long)priv; |
|---|
| 123 | + priv->membase = mem; |
|---|
| 124 | + priv->pcidev = pdev; |
|---|
| 111 | 125 | |
|---|
| 112 | 126 | pr_info("AMD Geode RNG detected\n"); |
|---|
| 113 | 127 | err = hwrng_register(&geode_rng); |
|---|
| .. | .. |
|---|
| 116 | 130 | err); |
|---|
| 117 | 131 | goto err_unmap; |
|---|
| 118 | 132 | } |
|---|
| 119 | | -out: |
|---|
| 120 | 133 | return err; |
|---|
| 121 | 134 | |
|---|
| 122 | 135 | err_unmap: |
|---|
| 123 | 136 | iounmap(mem); |
|---|
| 124 | | - goto out; |
|---|
| 137 | +free_priv: |
|---|
| 138 | + kfree(priv); |
|---|
| 139 | +put_dev: |
|---|
| 140 | + pci_dev_put(pdev); |
|---|
| 141 | + return err; |
|---|
| 125 | 142 | } |
|---|
| 126 | 143 | |
|---|
| 127 | 144 | static void __exit mod_exit(void) |
|---|
| 128 | 145 | { |
|---|
| 129 | | - void __iomem *mem = (void __iomem *)geode_rng.priv; |
|---|
| 146 | + struct amd_geode_priv *priv; |
|---|
| 130 | 147 | |
|---|
| 148 | + priv = (struct amd_geode_priv *)geode_rng.priv; |
|---|
| 131 | 149 | hwrng_unregister(&geode_rng); |
|---|
| 132 | | - iounmap(mem); |
|---|
| 150 | + iounmap(priv->membase); |
|---|
| 151 | + pci_dev_put(priv->pcidev); |
|---|
| 152 | + kfree(priv); |
|---|
| 133 | 153 | } |
|---|
| 134 | 154 | |
|---|
| 135 | 155 | module_init(mod_init); |
|---|