aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm_atmel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm/tpm_atmel.c')
-rw-r--r--drivers/char/tpm/tpm_atmel.c125
1 files changed, 48 insertions, 77 deletions
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 32e01450c425..ff3654964fe3 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -19,14 +19,8 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/platform_device.h>
23#include "tpm.h" 22#include "tpm.h"
24 23#include "tpm_atmel.h"
25/* Atmel definitions */
26enum tpm_atmel_addr {
27 TPM_ATMEL_BASE_ADDR_LO = 0x08,
28 TPM_ATMEL_BASE_ADDR_HI = 0x09
29};
30 24
31/* write status bits */ 25/* write status bits */
32enum tpm_atmel_write_status { 26enum tpm_atmel_write_status {
@@ -53,13 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
53 return -EIO; 47 return -EIO;
54 48
55 for (i = 0; i < 6; i++) { 49 for (i = 0; i < 6; i++) {
56 status = inb(chip->vendor->base + 1); 50 status = ioread8(chip->vendor->iobase + 1);
57 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 51 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
58 dev_err(chip->dev, 52 dev_err(chip->dev, "error reading header\n");
59 "error reading header\n");
60 return -EIO; 53 return -EIO;
61 } 54 }
62 *buf++ = inb(chip->vendor->base); 55 *buf++ = ioread8(chip->vendor->iobase);
63 } 56 }
64 57
65 /* size of the data received */ 58 /* size of the data received */
@@ -70,10 +63,9 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
70 dev_err(chip->dev, 63 dev_err(chip->dev,
71 "Recv size(%d) less than available space\n", size); 64 "Recv size(%d) less than available space\n", size);
72 for (; i < size; i++) { /* clear the waiting data anyway */ 65 for (; i < size; i++) { /* clear the waiting data anyway */
73 status = inb(chip->vendor->base + 1); 66 status = ioread8(chip->vendor->iobase + 1);
74 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 67 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
75 dev_err(chip->dev, 68 dev_err(chip->dev, "error reading data\n");
76 "error reading data\n");
77 return -EIO; 69 return -EIO;
78 } 70 }
79 } 71 }
@@ -82,17 +74,17 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
82 74
83 /* read all the data available */ 75 /* read all the data available */
84 for (; i < size; i++) { 76 for (; i < size; i++) {
85 status = inb(chip->vendor->base + 1); 77 status = ioread8(chip->vendor->iobase + 1);
86 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 78 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
87 dev_err(chip->dev, 79 dev_err(chip->dev, "error reading data\n");
88 "error reading data\n");
89 return -EIO; 80 return -EIO;
90 } 81 }
91 *buf++ = inb(chip->vendor->base); 82 *buf++ = ioread8(chip->vendor->iobase);
92 } 83 }
93 84
94 /* make sure data available is gone */ 85 /* make sure data available is gone */
95 status = inb(chip->vendor->base + 1); 86 status = ioread8(chip->vendor->iobase + 1);
87
96 if (status & ATML_STATUS_DATA_AVAIL) { 88 if (status & ATML_STATUS_DATA_AVAIL) {
97 dev_err(chip->dev, "data available is stuck\n"); 89 dev_err(chip->dev, "data available is stuck\n");
98 return -EIO; 90 return -EIO;
@@ -108,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
108 dev_dbg(chip->dev, "tpm_atml_send:\n"); 100 dev_dbg(chip->dev, "tpm_atml_send:\n");
109 for (i = 0; i < count; i++) { 101 for (i = 0; i < count; i++) {
110 dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); 102 dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
111 outb(buf[i], chip->vendor->base); 103 iowrite8(buf[i], chip->vendor->iobase);
112 } 104 }
113 105
114 return count; 106 return count;
@@ -116,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
116 108
117static void tpm_atml_cancel(struct tpm_chip *chip) 109static void tpm_atml_cancel(struct tpm_chip *chip)
118{ 110{
119 outb(ATML_STATUS_ABORT, chip->vendor->base + 1); 111 iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
120} 112}
121 113
122static u8 tpm_atml_status(struct tpm_chip *chip) 114static u8 tpm_atml_status(struct tpm_chip *chip)
123{ 115{
124 return inb(chip->vendor->base + 1); 116 return ioread8(chip->vendor->iobase + 1);
125} 117}
126 118
127static struct file_operations atmel_ops = { 119static struct file_operations atmel_ops = {
@@ -162,12 +154,17 @@ static struct tpm_vendor_specific tpm_atmel = {
162 154
163static struct platform_device *pdev; 155static struct platform_device *pdev;
164 156
165static void __devexit tpm_atml_remove(struct device *dev) 157static void atml_plat_remove(void)
166{ 158{
167 struct tpm_chip *chip = dev_get_drvdata(dev); 159 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
160
168 if (chip) { 161 if (chip) {
169 release_region(chip->vendor->base, 2); 162 if (chip->vendor->have_region)
163 atmel_release_region(chip->vendor->base,
164 chip->vendor->region_size);
165 atmel_put_base_addr(chip->vendor);
170 tpm_remove_hardware(chip->dev); 166 tpm_remove_hardware(chip->dev);
167 platform_device_unregister(pdev);
171 } 168 }
172} 169}
173 170
@@ -182,72 +179,46 @@ static struct device_driver atml_drv = {
182static int __init init_atmel(void) 179static int __init init_atmel(void)
183{ 180{
184 int rc = 0; 181 int rc = 0;
185 int lo, hi;
186 182
187 driver_register(&atml_drv); 183 driver_register(&atml_drv);
188 184
189 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); 185 if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
190 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); 186 rc = -ENODEV;
191 187 goto err_unreg_drv;
192 tpm_atmel.base = (hi<<8)|lo;
193
194 /* verify that it is an Atmel part */
195 if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
196 || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
197 return -ENODEV;
198 } 188 }
199 189
200 /* verify chip version number is 1.1 */ 190 tpm_atmel.have_region =
201 if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || 191 (atmel_request_region
202 (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) 192 (tpm_atmel.base, tpm_atmel.region_size,
203 return -ENODEV; 193 "tpm_atmel0") == NULL) ? 0 : 1;
204
205 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
206 if ( !pdev )
207 return -ENOMEM;
208
209 pdev->name = "tpm_atmel0";
210 pdev->id = -1;
211 pdev->num_resources = 0;
212 pdev->dev.release = tpm_atml_remove;
213 pdev->dev.driver = &atml_drv;
214
215 if ((rc = platform_device_register(pdev)) < 0) {
216 kfree(pdev);
217 pdev = NULL;
218 return rc;
219 }
220 194
221 if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { 195 if (IS_ERR
222 platform_device_unregister(pdev); 196 (pdev =
223 kfree(pdev); 197 platform_device_register_simple("tpm_atmel", -1, NULL, 0))) {
224 pdev = NULL; 198 rc = PTR_ERR(pdev);
225 return -EBUSY; 199 goto err_rel_reg;
226 } 200 }
227 201
228 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { 202 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
229 release_region(tpm_atmel.base, 2); 203 goto err_unreg_dev;
230 platform_device_unregister(pdev);
231 kfree(pdev);
232 pdev = NULL;
233 return rc;
234 }
235
236 dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
237 tpm_atmel.base);
238 return 0; 204 return 0;
205
206err_unreg_dev:
207 platform_device_unregister(pdev);
208err_rel_reg:
209 atmel_put_base_addr(&tpm_atmel);
210 if (tpm_atmel.have_region)
211 atmel_release_region(tpm_atmel.base,
212 tpm_atmel.region_size);
213err_unreg_drv:
214 driver_unregister(&atml_drv);
215 return rc;
239} 216}
240 217
241static void __exit cleanup_atmel(void) 218static void __exit cleanup_atmel(void)
242{ 219{
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); 220 driver_unregister(&atml_drv);
221 atml_plat_remove();
251} 222}
252 223
253module_init(init_atmel); 224module_init(init_atmel);