0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "tpm.h"
0018 #include "tpm_atmel.h"
0019
0020
0021 enum tpm_atmel_write_status {
0022 ATML_STATUS_ABORT = 0x01,
0023 ATML_STATUS_LASTBYTE = 0x04
0024 };
0025
0026 enum tpm_atmel_read_status {
0027 ATML_STATUS_BUSY = 0x01,
0028 ATML_STATUS_DATA_AVAIL = 0x02,
0029 ATML_STATUS_REWRITE = 0x04,
0030 ATML_STATUS_READY = 0x08
0031 };
0032
0033 static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
0034 {
0035 struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
0036 u8 status, *hdr = buf;
0037 u32 size;
0038 int i;
0039 __be32 *native_size;
0040
0041
0042 if (count < 6)
0043 return -EIO;
0044
0045 for (i = 0; i < 6; i++) {
0046 status = ioread8(priv->iobase + 1);
0047 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
0048 dev_err(&chip->dev, "error reading header\n");
0049 return -EIO;
0050 }
0051 *buf++ = ioread8(priv->iobase);
0052 }
0053
0054
0055 native_size = (__force __be32 *) (hdr + 2);
0056 size = be32_to_cpu(*native_size);
0057
0058 if (count < size) {
0059 dev_err(&chip->dev,
0060 "Recv size(%d) less than available space\n", size);
0061 for (; i < size; i++) {
0062 status = ioread8(priv->iobase + 1);
0063 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
0064 dev_err(&chip->dev, "error reading data\n");
0065 return -EIO;
0066 }
0067 }
0068 return -EIO;
0069 }
0070
0071
0072 for (; i < size; i++) {
0073 status = ioread8(priv->iobase + 1);
0074 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
0075 dev_err(&chip->dev, "error reading data\n");
0076 return -EIO;
0077 }
0078 *buf++ = ioread8(priv->iobase);
0079 }
0080
0081
0082 status = ioread8(priv->iobase + 1);
0083
0084 if (status & ATML_STATUS_DATA_AVAIL) {
0085 dev_err(&chip->dev, "data available is stuck\n");
0086 return -EIO;
0087 }
0088
0089 return size;
0090 }
0091
0092 static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
0093 {
0094 struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
0095 int i;
0096
0097 dev_dbg(&chip->dev, "tpm_atml_send:\n");
0098 for (i = 0; i < count; i++) {
0099 dev_dbg(&chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
0100 iowrite8(buf[i], priv->iobase);
0101 }
0102
0103 return 0;
0104 }
0105
0106 static void tpm_atml_cancel(struct tpm_chip *chip)
0107 {
0108 struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
0109
0110 iowrite8(ATML_STATUS_ABORT, priv->iobase + 1);
0111 }
0112
0113 static u8 tpm_atml_status(struct tpm_chip *chip)
0114 {
0115 struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
0116
0117 return ioread8(priv->iobase + 1);
0118 }
0119
0120 static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status)
0121 {
0122 return (status == ATML_STATUS_READY);
0123 }
0124
0125 static const struct tpm_class_ops tpm_atmel = {
0126 .recv = tpm_atml_recv,
0127 .send = tpm_atml_send,
0128 .cancel = tpm_atml_cancel,
0129 .status = tpm_atml_status,
0130 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
0131 .req_complete_val = ATML_STATUS_DATA_AVAIL,
0132 .req_canceled = tpm_atml_req_canceled,
0133 };
0134
0135 static struct platform_device *pdev;
0136
0137 static void atml_plat_remove(void)
0138 {
0139 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
0140 struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
0141
0142 tpm_chip_unregister(chip);
0143 if (priv->have_region)
0144 atmel_release_region(priv->base, priv->region_size);
0145 atmel_put_base_addr(priv->iobase);
0146 platform_device_unregister(pdev);
0147 }
0148
0149 static SIMPLE_DEV_PM_OPS(tpm_atml_pm, tpm_pm_suspend, tpm_pm_resume);
0150
0151 static struct platform_driver atml_drv = {
0152 .driver = {
0153 .name = "tpm_atmel",
0154 .pm = &tpm_atml_pm,
0155 },
0156 };
0157
0158 static int __init init_atmel(void)
0159 {
0160 int rc = 0;
0161 void __iomem *iobase = NULL;
0162 int have_region, region_size;
0163 unsigned long base;
0164 struct tpm_chip *chip;
0165 struct tpm_atmel_priv *priv;
0166
0167 rc = platform_driver_register(&atml_drv);
0168 if (rc)
0169 return rc;
0170
0171 if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) {
0172 rc = -ENODEV;
0173 goto err_unreg_drv;
0174 }
0175
0176 have_region =
0177 (atmel_request_region
0178 (base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
0179
0180 pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0);
0181 if (IS_ERR(pdev)) {
0182 rc = PTR_ERR(pdev);
0183 goto err_rel_reg;
0184 }
0185
0186 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0187 if (!priv) {
0188 rc = -ENOMEM;
0189 goto err_unreg_dev;
0190 }
0191
0192 priv->iobase = iobase;
0193 priv->base = base;
0194 priv->have_region = have_region;
0195 priv->region_size = region_size;
0196
0197 chip = tpmm_chip_alloc(&pdev->dev, &tpm_atmel);
0198 if (IS_ERR(chip)) {
0199 rc = PTR_ERR(chip);
0200 goto err_unreg_dev;
0201 }
0202
0203 dev_set_drvdata(&chip->dev, priv);
0204
0205 rc = tpm_chip_register(chip);
0206 if (rc)
0207 goto err_unreg_dev;
0208
0209 return 0;
0210
0211 err_unreg_dev:
0212 platform_device_unregister(pdev);
0213 err_rel_reg:
0214 atmel_put_base_addr(iobase);
0215 if (have_region)
0216 atmel_release_region(base,
0217 region_size);
0218 err_unreg_drv:
0219 platform_driver_unregister(&atml_drv);
0220 return rc;
0221 }
0222
0223 static void __exit cleanup_atmel(void)
0224 {
0225 platform_driver_unregister(&atml_drv);
0226 atml_plat_remove();
0227 }
0228
0229 module_init(init_atmel);
0230 module_exit(cleanup_atmel);
0231
0232 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
0233 MODULE_DESCRIPTION("TPM Driver");
0234 MODULE_VERSION("2.0");
0235 MODULE_LICENSE("GPL");