diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-10-31 05:06:46 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-10-31 05:06:46 -0500 |
commit | 1f04c0a24b2f3cfe89c802a24396263623e3512d (patch) | |
tree | d7e2216b6e65b833c0c2b79b478d13ce17dbf296 /drivers/char/tpm/tpm_nsc.c | |
parent | 07b188ab773e183871e57b33ae37bf635c9f12ba (diff) | |
parent | e2f2e58e7968f8446b1078a20a18bf8ea12b4fbc (diff) |
Merge branch 'master' of /usr/src/ntfs-2.6/
Diffstat (limited to 'drivers/char/tpm/tpm_nsc.c')
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 164 |
1 files changed, 94 insertions, 70 deletions
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index b4127348c063..253871b5b1e2 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -111,7 +111,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
111 | } | 111 | } |
112 | while (time_before(jiffies, stop)); | 112 | while (time_before(jiffies, stop)); |
113 | 113 | ||
114 | dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); | 114 | dev_info(chip->dev, "wait for ready failed\n"); |
115 | return -EBUSY; | 115 | return -EBUSY; |
116 | } | 116 | } |
117 | 117 | ||
@@ -127,12 +127,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
127 | return -EIO; | 127 | return -EIO; |
128 | 128 | ||
129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { | 129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { |
130 | dev_err(&chip->pci_dev->dev, "F0 timeout\n"); | 130 | dev_err(chip->dev, "F0 timeout\n"); |
131 | return -EIO; | 131 | return -EIO; |
132 | } | 132 | } |
133 | if ((data = | 133 | if ((data = |
134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { | 134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { |
135 | dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n", | 135 | dev_err(chip->dev, "not in normal mode (0x%x)\n", |
136 | data); | 136 | data); |
137 | return -EIO; | 137 | return -EIO; |
138 | } | 138 | } |
@@ -141,7 +141,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
141 | for (p = buffer; p < &buffer[count]; p++) { | 141 | for (p = buffer; p < &buffer[count]; p++) { |
142 | if (wait_for_stat | 142 | if (wait_for_stat |
143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { | 143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { |
144 | dev_err(&chip->pci_dev->dev, | 144 | dev_err(chip->dev, |
145 | "OBF timeout (while reading data)\n"); | 145 | "OBF timeout (while reading data)\n"); |
146 | return -EIO; | 146 | return -EIO; |
147 | } | 147 | } |
@@ -152,11 +152,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
152 | 152 | ||
153 | if ((data & NSC_STATUS_F0) == 0 && | 153 | if ((data & NSC_STATUS_F0) == 0 && |
154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { | 154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { |
155 | dev_err(&chip->pci_dev->dev, "F0 not set\n"); | 155 | dev_err(chip->dev, "F0 not set\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { | 158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { |
159 | dev_err(&chip->pci_dev->dev, | 159 | dev_err(chip->dev, |
160 | "expected end of command(0x%x)\n", data); | 160 | "expected end of command(0x%x)\n", data); |
161 | return -EIO; | 161 | return -EIO; |
162 | } | 162 | } |
@@ -187,19 +187,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
187 | return -EIO; | 187 | return -EIO; |
188 | 188 | ||
189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
190 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 190 | dev_err(chip->dev, "IBF timeout\n"); |
191 | return -EIO; | 191 | return -EIO; |
192 | } | 192 | } |
193 | 193 | ||
194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); | 194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); |
195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { | 195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { |
196 | dev_err(&chip->pci_dev->dev, "IBR timeout\n"); | 196 | dev_err(chip->dev, "IBR timeout\n"); |
197 | return -EIO; | 197 | return -EIO; |
198 | } | 198 | } |
199 | 199 | ||
200 | for (i = 0; i < count; i++) { | 200 | for (i = 0; i < count; i++) { |
201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
202 | dev_err(&chip->pci_dev->dev, | 202 | dev_err(chip->dev, |
203 | "IBF timeout (while writing data)\n"); | 203 | "IBF timeout (while writing data)\n"); |
204 | return -EIO; | 204 | return -EIO; |
205 | } | 205 | } |
@@ -207,7 +207,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
210 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 210 | dev_err(chip->dev, "IBF timeout\n"); |
211 | return -EIO; | 211 | return -EIO; |
212 | } | 212 | } |
213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); | 213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); |
@@ -220,6 +220,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip) | |||
220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); | 220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); |
221 | } | 221 | } |
222 | 222 | ||
223 | static u8 tpm_nsc_status(struct tpm_chip *chip) | ||
224 | { | ||
225 | return inb(chip->vendor->base + NSC_STATUS); | ||
226 | } | ||
227 | |||
223 | static struct file_operations nsc_ops = { | 228 | static struct file_operations nsc_ops = { |
224 | .owner = THIS_MODULE, | 229 | .owner = THIS_MODULE, |
225 | .llseek = no_llseek, | 230 | .llseek = no_llseek, |
@@ -239,7 +244,7 @@ static struct attribute * nsc_attrs[] = { | |||
239 | &dev_attr_pcrs.attr, | 244 | &dev_attr_pcrs.attr, |
240 | &dev_attr_caps.attr, | 245 | &dev_attr_caps.attr, |
241 | &dev_attr_cancel.attr, | 246 | &dev_attr_cancel.attr, |
242 | 0, | 247 | NULL, |
243 | }; | 248 | }; |
244 | 249 | ||
245 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; | 250 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; |
@@ -248,6 +253,7 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
248 | .recv = tpm_nsc_recv, | 253 | .recv = tpm_nsc_recv, |
249 | .send = tpm_nsc_send, | 254 | .send = tpm_nsc_send, |
250 | .cancel = tpm_nsc_cancel, | 255 | .cancel = tpm_nsc_cancel, |
256 | .status = tpm_nsc_status, | ||
251 | .req_complete_mask = NSC_STATUS_OBF, | 257 | .req_complete_mask = NSC_STATUS_OBF, |
252 | .req_complete_val = NSC_STATUS_OBF, | 258 | .req_complete_val = NSC_STATUS_OBF, |
253 | .req_canceled = NSC_STATUS_RDY, | 259 | .req_canceled = NSC_STATUS_RDY, |
@@ -255,16 +261,32 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
255 | .miscdev = { .fops = &nsc_ops, }, | 261 | .miscdev = { .fops = &nsc_ops, }, |
256 | }; | 262 | }; |
257 | 263 | ||
258 | static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | 264 | static struct platform_device *pdev = NULL; |
259 | const struct pci_device_id *pci_id) | 265 | |
266 | static void __devexit tpm_nsc_remove(struct device *dev) | ||
267 | { | ||
268 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
269 | if ( chip ) { | ||
270 | release_region(chip->vendor->base, 2); | ||
271 | tpm_remove_hardware(chip->dev); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | static struct device_driver nsc_drv = { | ||
276 | .name = "tpm_nsc", | ||
277 | .bus = &platform_bus_type, | ||
278 | .owner = THIS_MODULE, | ||
279 | .suspend = tpm_pm_suspend, | ||
280 | .resume = tpm_pm_resume, | ||
281 | }; | ||
282 | |||
283 | static int __init init_nsc(void) | ||
260 | { | 284 | { |
261 | int rc = 0; | 285 | int rc = 0; |
262 | int lo, hi; | 286 | int lo, hi; |
263 | int nscAddrBase = TPM_ADDR; | 287 | int nscAddrBase = TPM_ADDR; |
264 | 288 | ||
265 | 289 | driver_register(&nsc_drv); | |
266 | if (pci_enable_device(pci_dev)) | ||
267 | return -EIO; | ||
268 | 290 | ||
269 | /* select PM channel 1 */ | 291 | /* select PM channel 1 */ |
270 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); | 292 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); |
@@ -273,37 +295,71 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
273 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { | 295 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { |
274 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| | 296 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| |
275 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); | 297 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); |
276 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) { | 298 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) |
277 | rc = -ENODEV; | 299 | return -ENODEV; |
278 | goto out_err; | ||
279 | } | ||
280 | } | 300 | } |
281 | 301 | ||
282 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | 302 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); |
283 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | 303 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); |
284 | tpm_nsc.base = (hi<<8) | lo; | 304 | tpm_nsc.base = (hi<<8) | lo; |
285 | 305 | ||
286 | dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); | 306 | /* enable the DPM module */ |
287 | dev_dbg(&pci_dev->dev, | 307 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); |
308 | |||
309 | pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
310 | if ( !pdev ) | ||
311 | return -ENOMEM; | ||
312 | |||
313 | memset(pdev, 0, sizeof(struct platform_device)); | ||
314 | |||
315 | pdev->name = "tpm_nscl0"; | ||
316 | pdev->id = -1; | ||
317 | pdev->num_resources = 0; | ||
318 | pdev->dev.release = tpm_nsc_remove; | ||
319 | pdev->dev.driver = &nsc_drv; | ||
320 | |||
321 | if ((rc=platform_device_register(pdev)) < 0) { | ||
322 | kfree(pdev); | ||
323 | pdev = NULL; | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { | ||
328 | platform_device_unregister(pdev); | ||
329 | kfree(pdev); | ||
330 | pdev = NULL; | ||
331 | return -EBUSY; | ||
332 | } | ||
333 | |||
334 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) { | ||
335 | release_region(tpm_nsc.base, 2); | ||
336 | platform_device_unregister(pdev); | ||
337 | kfree(pdev); | ||
338 | pdev = NULL; | ||
339 | return rc; | ||
340 | } | ||
341 | |||
342 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); | ||
343 | dev_dbg(&pdev->dev, | ||
288 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", | 344 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", |
289 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), | 345 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), |
290 | tpm_read_index(nscAddrBase,0x27)); | 346 | tpm_read_index(nscAddrBase,0x27)); |
291 | dev_dbg(&pci_dev->dev, | 347 | dev_dbg(&pdev->dev, |
292 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", | 348 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", |
293 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), | 349 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), |
294 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); | 350 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); |
295 | dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", | 351 | dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n", |
296 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); | 352 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); |
297 | dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", | 353 | dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n", |
298 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); | 354 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); |
299 | dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", | 355 | dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n", |
300 | tpm_read_index(nscAddrBase,0x70)); | 356 | tpm_read_index(nscAddrBase,0x70)); |
301 | dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", | 357 | dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n", |
302 | tpm_read_index(nscAddrBase,0x71)); | 358 | tpm_read_index(nscAddrBase,0x71)); |
303 | dev_dbg(&pci_dev->dev, | 359 | dev_dbg(&pdev->dev, |
304 | "NSC DMA channel select0 0x%x, select1 0x%x\n", | 360 | "NSC DMA channel select0 0x%x, select1 0x%x\n", |
305 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); | 361 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); |
306 | dev_dbg(&pci_dev->dev, | 362 | dev_dbg(&pdev->dev, |
307 | "NSC Config " | 363 | "NSC Config " |
308 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 364 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
309 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), | 365 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), |
@@ -312,55 +368,23 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
312 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), | 368 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), |
313 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); | 369 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); |
314 | 370 | ||
315 | dev_info(&pci_dev->dev, | 371 | dev_info(&pdev->dev, |
316 | "NSC TPM revision %d\n", | 372 | "NSC TPM revision %d\n", |
317 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); | 373 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); |
318 | 374 | ||
319 | /* enable the DPM module */ | ||
320 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); | ||
321 | |||
322 | if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) | ||
323 | goto out_err; | ||
324 | |||
325 | return 0; | 375 | return 0; |
326 | |||
327 | out_err: | ||
328 | pci_disable_device(pci_dev); | ||
329 | return rc; | ||
330 | } | ||
331 | |||
332 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
333 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
334 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
335 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
336 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
337 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
338 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
339 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
340 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
341 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
342 | {0,} | ||
343 | }; | ||
344 | |||
345 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | ||
346 | |||
347 | static struct pci_driver nsc_pci_driver = { | ||
348 | .name = "tpm_nsc", | ||
349 | .id_table = tpm_pci_tbl, | ||
350 | .probe = tpm_nsc_init, | ||
351 | .remove = __devexit_p(tpm_remove), | ||
352 | .suspend = tpm_pm_suspend, | ||
353 | .resume = tpm_pm_resume, | ||
354 | }; | ||
355 | |||
356 | static int __init init_nsc(void) | ||
357 | { | ||
358 | return pci_register_driver(&nsc_pci_driver); | ||
359 | } | 376 | } |
360 | 377 | ||
361 | static void __exit cleanup_nsc(void) | 378 | static void __exit cleanup_nsc(void) |
362 | { | 379 | { |
363 | pci_unregister_driver(&nsc_pci_driver); | 380 | if (pdev) { |
381 | tpm_nsc_remove(&pdev->dev); | ||
382 | platform_device_unregister(pdev); | ||
383 | kfree(pdev); | ||
384 | pdev = NULL; | ||
385 | } | ||
386 | |||
387 | driver_unregister(&nsc_drv); | ||
364 | } | 388 | } |
365 | 389 | ||
366 | module_init(init_nsc); | 390 | module_init(init_nsc); |