diff options
author | Kylene Jo Hall <kjhall@us.ibm.com> | 2005-11-13 16:07:41 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-13 18:14:17 -0800 |
commit | ad5ea3cc5f745aef243ade0dafc8cf6f7f0bfea7 (patch) | |
tree | f4d2e4b39df27db5120bef6187d344d2edc05d37 /drivers/char/tpm/tpm_atmel.c | |
parent | c0131c143204ee0ba00592c016f20ce6fc67827d (diff) | |
download | op-kernel-dev-ad5ea3cc5f745aef243ade0dafc8cf6f7f0bfea7.zip op-kernel-dev-ad5ea3cc5f745aef243ade0dafc8cf6f7f0bfea7.tar.gz |
[PATCH] tpm: updates for new hardware
This is the patch to support TPMs on power ppc hardware. It has been
reworked as requested to remove the need for messing with the io page mask
by just using ioremap.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/tpm/tpm_atmel.c')
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 108 |
1 files changed, 37 insertions, 71 deletions
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 32e0145..deb4b5c 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -19,14 +19,8 @@ * */ -#include <linux/platform_device.h> #include "tpm.h" - -/* Atmel definitions */ -enum tpm_atmel_addr { - TPM_ATMEL_BASE_ADDR_LO = 0x08, - TPM_ATMEL_BASE_ADDR_HI = 0x09 -}; +#include "tpm_atmel.h" /* write status bits */ enum tpm_atmel_write_status { @@ -53,13 +47,13 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) return -EIO; for (i = 0; i < 6; i++) { - status = inb(chip->vendor->base + 1); + status = atmel_getb(chip, 1); if ((status & ATML_STATUS_DATA_AVAIL) == 0) { dev_err(chip->dev, "error reading header\n"); return -EIO; } - *buf++ = inb(chip->vendor->base); + *buf++ = atmel_getb(chip, 0); } /* size of the data received */ @@ -70,7 +64,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) dev_err(chip->dev, "Recv size(%d) less than available space\n", size); for (; i < size; i++) { /* clear the waiting data anyway */ - status = inb(chip->vendor->base + 1); + status = atmel_getb(chip, 1); if ((status & ATML_STATUS_DATA_AVAIL) == 0) { dev_err(chip->dev, "error reading data\n"); @@ -82,17 +76,17 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) /* read all the data available */ for (; i < size; i++) { - status = inb(chip->vendor->base + 1); + status = atmel_getb(chip, 1); if ((status & ATML_STATUS_DATA_AVAIL) == 0) { dev_err(chip->dev, "error reading data\n"); return -EIO; } - *buf++ = inb(chip->vendor->base); + *buf++ = atmel_getb(chip, 0); } /* make sure data available is gone */ - status = inb(chip->vendor->base + 1); + status = atmel_getb(chip, 1); if (status & ATML_STATUS_DATA_AVAIL) { dev_err(chip->dev, "data available is stuck\n"); return -EIO; @@ -108,7 +102,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) dev_dbg(chip->dev, "tpm_atml_send:\n"); for (i = 0; i < count; i++) { dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); - outb(buf[i], chip->vendor->base); + atmel_putb(buf[i], chip, 0); } return count; @@ -116,12 +110,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) static void tpm_atml_cancel(struct tpm_chip *chip) { - outb(ATML_STATUS_ABORT, chip->vendor->base + 1); + atmel_putb(ATML_STATUS_ABORT, chip, 1); } static u8 tpm_atml_status(struct tpm_chip *chip) { - return inb(chip->vendor->base + 1); + return atmel_getb(chip, 1); } static struct file_operations atmel_ops = { @@ -162,12 +156,16 @@ static struct tpm_vendor_specific tpm_atmel = { static struct platform_device *pdev; -static void __devexit tpm_atml_remove(struct device *dev) +static void atml_plat_remove(void) { - struct tpm_chip *chip = dev_get_drvdata(dev); + struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); + if (chip) { - release_region(chip->vendor->base, 2); + if (chip->vendor->have_region) + atmel_release_region(chip->vendor->base, chip->vendor->region_size); + atmel_put_base_addr(chip->vendor); tpm_remove_hardware(chip->dev); + platform_device_unregister(pdev); } } @@ -182,72 +180,40 @@ static struct device_driver atml_drv = { static int __init init_atmel(void) { int rc = 0; - int lo, hi; driver_register(&atml_drv); - lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); - hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); - - tpm_atmel.base = (hi<<8)|lo; - - /* verify that it is an Atmel part */ - if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' - || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { - return -ENODEV; - } - - /* verify chip version number is 1.1 */ - if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || - (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) - return -ENODEV; - - pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); - if ( !pdev ) - return -ENOMEM; - - pdev->name = "tpm_atmel0"; - pdev->id = -1; - pdev->num_resources = 0; - pdev->dev.release = tpm_atml_remove; - pdev->dev.driver = &atml_drv; - - if ((rc = platform_device_register(pdev)) < 0) { - kfree(pdev); - pdev = NULL; - return rc; + if (atmel_get_base_addr(&tpm_atmel) != 0) { + rc = -ENODEV; + goto err_unreg_drv; } - if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { - platform_device_unregister(pdev); - kfree(pdev); - pdev = NULL; - return -EBUSY; - } + tpm_atmel.have_region = (atmel_request_region( tpm_atmel.base, tpm_atmel.region_size, "tpm_atmel0") == NULL) ? 0 : 1; - if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { - release_region(tpm_atmel.base, 2); - platform_device_unregister(pdev); - kfree(pdev); - pdev = NULL; - return rc; + if (IS_ERR(pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0 ))) { + rc = PTR_ERR(pdev); + goto err_rel_reg; } - dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n", - tpm_atmel.base); + if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) + goto err_unreg_dev; return 0; + +err_unreg_dev: + platform_device_unregister(pdev); +err_rel_reg: + if (tpm_atmel.have_region) + atmel_release_region(tpm_atmel.base, tpm_atmel.region_size); + atmel_put_base_addr(&tpm_atmel); +err_unreg_drv: + driver_unregister(&atml_drv); + return rc; } static void __exit cleanup_atmel(void) { - if (pdev) { - tpm_atml_remove(&pdev->dev); - platform_device_unregister(pdev); - kfree(pdev); - pdev = NULL; - } - driver_unregister(&atml_drv); + atml_plat_remove(); } module_init(init_atmel); |