aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm_atmel.c125
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
162static int __devinit tpm_atml_init(struct pci_dev *pci_dev, 162static struct platform_device *pdev = NULL;
163 const struct pci_device_id *pci_id) 163
164static 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
173static 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
181static 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";
204out_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
209static 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
217static 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
231MODULE_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
233static 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
242static 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
247static void __exit cleanup_atmel(void) 241static 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
252module_init(init_atmel); 253module_init(init_atmel);