diff options
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 125 |
1 files changed, 63 insertions, 62 deletions
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 44b08ba6fc9d..a9100ad3d030 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -159,94 +159,95 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
159 | .miscdev = { .fops = &atmel_ops, }, | 159 | .miscdev = { .fops = &atmel_ops, }, |
160 | }; | 160 | }; |
161 | 161 | ||
162 | static int __devinit tpm_atml_init(struct pci_dev *pci_dev, | 162 | static struct platform_device *pdev = NULL; |
163 | const struct pci_device_id *pci_id) | 163 | |
164 | static void __devexit tpm_atml_remove(struct device *dev) | ||
165 | { | ||
166 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
167 | if ( chip ) { | ||
168 | release_region(chip->vendor->base, 2); | ||
169 | tpm_remove_hardware(chip->dev); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static struct device_driver atml_drv = { | ||
174 | .name = "tpm_atmel", | ||
175 | .bus = &platform_bus_type, | ||
176 | .owner = THIS_MODULE, | ||
177 | .suspend = tpm_pm_suspend, | ||
178 | .resume = tpm_pm_resume, | ||
179 | }; | ||
180 | |||
181 | static int __init init_atmel(void) | ||
164 | { | 182 | { |
165 | u8 version[4]; | ||
166 | int rc = 0; | 183 | int rc = 0; |
167 | int lo, hi; | 184 | int lo, hi; |
168 | 185 | ||
169 | if (pci_enable_device(pci_dev)) | 186 | driver_register(&atml_drv); |
170 | return -EIO; | ||
171 | 187 | ||
172 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | 188 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); |
173 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | 189 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); |
174 | 190 | ||
175 | tpm_atmel.base = (hi<<8)|lo; | 191 | tpm_atmel.base = (hi<<8)|lo; |
176 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); | ||
177 | 192 | ||
178 | /* verify that it is an Atmel part */ | 193 | /* verify that it is an Atmel part */ |
179 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' | 194 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' |
180 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { | 195 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { |
181 | rc = -ENODEV; | 196 | return -ENODEV; |
182 | goto out_err; | ||
183 | } | 197 | } |
184 | 198 | ||
185 | /* query chip for its version number */ | 199 | /* verify chip version number is 1.1 */ |
186 | if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) { | 200 | if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || |
187 | version[1] = tpm_read_index(TPM_ADDR, 0x01); | 201 | (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) |
188 | version[2] = tpm_read_index(TPM_ADDR, 0x02); | 202 | return -ENODEV; |
189 | version[3] = tpm_read_index(TPM_ADDR, 0x03); | ||
190 | } else { | ||
191 | dev_info(&pci_dev->dev, "version query failed\n"); | ||
192 | rc = -ENODEV; | ||
193 | goto out_err; | ||
194 | } | ||
195 | 203 | ||
196 | if ((rc = tpm_register_hardware(&pci_dev->dev, &tpm_atmel)) < 0) | 204 | pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); |
197 | goto out_err; | 205 | if ( !pdev ) |
206 | return -ENOMEM; | ||
198 | 207 | ||
199 | dev_info(&pci_dev->dev, | 208 | memset(pdev, 0, sizeof(struct platform_device)); |
200 | "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1], | ||
201 | version[2], version[3]); | ||
202 | 209 | ||
203 | return 0; | 210 | pdev->name = "tpm_atmel0"; |
204 | out_err: | 211 | pdev->id = -1; |
205 | pci_disable_device(pci_dev); | 212 | pdev->num_resources = 0; |
206 | return rc; | 213 | pdev->dev.release = tpm_atml_remove; |
207 | } | 214 | pdev->dev.driver = &atml_drv; |
208 | 215 | ||
209 | static void __devexit tpm_atml_remove(struct pci_dev *pci_dev) | 216 | if ((rc=platform_device_register(pdev)) < 0) { |
210 | { | 217 | kfree(pdev); |
211 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 218 | pdev = NULL; |
212 | 219 | return rc; | |
213 | if ( chip ) | 220 | } |
214 | tpm_remove_hardware(chip->dev); | ||
215 | } | ||
216 | |||
217 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
218 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
219 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
220 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
221 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
222 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
223 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
224 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
225 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
226 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
227 | {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)}, | ||
228 | {0,} | ||
229 | }; | ||
230 | 221 | ||
231 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | 222 | if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { |
223 | platform_device_unregister(pdev); | ||
224 | kfree(pdev); | ||
225 | pdev = NULL; | ||
226 | return -EBUSY; | ||
227 | } | ||
232 | 228 | ||
233 | static struct pci_driver atmel_pci_driver = { | 229 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { |
234 | .name = "tpm_atmel", | 230 | release_region(tpm_atmel.base, 2); |
235 | .id_table = tpm_pci_tbl, | 231 | platform_device_unregister(pdev); |
236 | .probe = tpm_atml_init, | 232 | kfree(pdev); |
237 | .remove = __devexit_p(tpm_atml_remove), | 233 | pdev = NULL; |
238 | .suspend = tpm_pm_suspend, | 234 | return rc; |
239 | .resume = tpm_pm_resume, | 235 | } |
240 | }; | ||
241 | 236 | ||
242 | static int __init init_atmel(void) | 237 | dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n", tpm_atmel.base); |
243 | { | 238 | return 0; |
244 | return pci_register_driver(&atmel_pci_driver); | ||
245 | } | 239 | } |
246 | 240 | ||
247 | static void __exit cleanup_atmel(void) | 241 | static void __exit cleanup_atmel(void) |
248 | { | 242 | { |
249 | pci_unregister_driver(&atmel_pci_driver); | 243 | if (pdev) { |
244 | tpm_atml_remove(&pdev->dev); | ||
245 | platform_device_unregister(pdev); | ||
246 | kfree(pdev); | ||
247 | pdev = NULL; | ||
248 | } | ||
249 | |||
250 | driver_unregister(&atml_drv); | ||
250 | } | 251 | } |
251 | 252 | ||
252 | module_init(init_atmel); | 253 | module_init(init_atmel); |