diff options
-rw-r--r-- | drivers/char/tpm/tpm.c | 90 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 16 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 22 |
4 files changed, 22 insertions, 108 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c6d985b04b6d..726d1b5b33b0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -35,25 +35,6 @@ enum tpm_const { | |||
35 | TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) | 35 | TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) |
36 | }; | 36 | }; |
37 | 37 | ||
38 | /* PCI configuration addresses */ | ||
39 | enum tpm_pci_config_addr { | ||
40 | PCI_GEN_PMCON_1 = 0xA0, | ||
41 | PCI_GEN1_DEC = 0xE4, | ||
42 | PCI_LPC_EN = 0xE6, | ||
43 | PCI_GEN2_DEC = 0xEC | ||
44 | }; | ||
45 | |||
46 | enum tpm_config { | ||
47 | TPM_LOCK_REG = 0x0D, | ||
48 | TPM_INTERUPT_REG = 0x0A, | ||
49 | TPM_BASE_ADDR_LO = 0x08, | ||
50 | TPM_BASE_ADDR_HI = 0x09, | ||
51 | TPM_UNLOCK_VALUE = 0x55, | ||
52 | TPM_LOCK_VALUE = 0xAA, | ||
53 | TPM_DISABLE_INTERUPT_VALUE = 0x00 | ||
54 | }; | ||
55 | |||
56 | |||
57 | static LIST_HEAD(tpm_chip_list); | 38 | static LIST_HEAD(tpm_chip_list); |
58 | static DEFINE_SPINLOCK(driver_lock); | 39 | static DEFINE_SPINLOCK(driver_lock); |
59 | static int dev_mask[TPM_NUM_MASK_ENTRIES]; | 40 | static int dev_mask[TPM_NUM_MASK_ENTRIES]; |
@@ -69,73 +50,6 @@ static void user_reader_timeout(unsigned long ptr) | |||
69 | } | 50 | } |
70 | 51 | ||
71 | /* | 52 | /* |
72 | * Initialize the LPC bus and enable the TPM ports | ||
73 | */ | ||
74 | int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base) | ||
75 | { | ||
76 | u32 lpcenable, tmp; | ||
77 | int is_lpcm = 0; | ||
78 | |||
79 | switch (pci_dev->vendor) { | ||
80 | case PCI_VENDOR_ID_INTEL: | ||
81 | switch (pci_dev->device) { | ||
82 | case PCI_DEVICE_ID_INTEL_82801CA_12: | ||
83 | case PCI_DEVICE_ID_INTEL_82801DB_12: | ||
84 | is_lpcm = 1; | ||
85 | break; | ||
86 | } | ||
87 | /* init ICH (enable LPC) */ | ||
88 | pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable); | ||
89 | lpcenable |= 0x20000000; | ||
90 | pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable); | ||
91 | |||
92 | if (is_lpcm) { | ||
93 | pci_read_config_dword(pci_dev, PCI_GEN1_DEC, | ||
94 | &lpcenable); | ||
95 | if ((lpcenable & 0x20000000) == 0) { | ||
96 | dev_err(&pci_dev->dev, | ||
97 | "cannot enable LPC\n"); | ||
98 | return -ENODEV; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /* initialize TPM registers */ | ||
103 | pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp); | ||
104 | |||
105 | if (!is_lpcm) | ||
106 | tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0); | ||
107 | else | ||
108 | tmp = | ||
109 | (tmp & 0xFFFF0000) | (base & 0xFFF0) | | ||
110 | 0x00000001; | ||
111 | |||
112 | pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp); | ||
113 | |||
114 | if (is_lpcm) { | ||
115 | pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1, | ||
116 | &tmp); | ||
117 | tmp |= 0x00000004; /* enable CLKRUN */ | ||
118 | pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1, | ||
119 | tmp); | ||
120 | } | ||
121 | break; | ||
122 | case PCI_VENDOR_ID_AMD: | ||
123 | /* nothing yet */ | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | tpm_write_index(TPM_LOCK_REG, TPM_UNLOCK_VALUE); | ||
128 | tpm_write_index(TPM_INTERUPT_REG, TPM_DISABLE_INTERUPT_VALUE); | ||
129 | tpm_write_index(TPM_BASE_ADDR_LO, base); | ||
130 | tpm_write_index(TPM_BASE_ADDR_HI, (base & 0xFF00) >> 8); | ||
131 | tpm_write_index(TPM_LOCK_REG, TPM_LOCK_VALUE); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | EXPORT_SYMBOL_GPL(tpm_lpc_bus_init); | ||
137 | |||
138 | /* | ||
139 | * Internal kernel interface to transmit TPM commands | 53 | * Internal kernel interface to transmit TPM commands |
140 | */ | 54 | */ |
141 | static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | 55 | static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, |
@@ -586,10 +500,6 @@ int tpm_pm_resume(struct pci_dev *pci_dev) | |||
586 | if (chip == NULL) | 500 | if (chip == NULL) |
587 | return -ENODEV; | 501 | return -ENODEV; |
588 | 502 | ||
589 | spin_lock(&driver_lock); | ||
590 | tpm_lpc_bus_init(pci_dev, chip->vendor->base); | ||
591 | spin_unlock(&driver_lock); | ||
592 | |||
593 | return 0; | 503 | return 0; |
594 | } | 504 | } |
595 | 505 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 714cb16b32cb..10cb450191a6 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -91,8 +91,6 @@ static inline void tpm_write_index(int index, int value) | |||
91 | outb(value & 0xFF, TPM_DATA); | 91 | outb(value & 0xFF, TPM_DATA); |
92 | } | 92 | } |
93 | 93 | ||
94 | extern int tpm_lpc_bus_init(struct pci_dev *, u16); | ||
95 | |||
96 | extern int tpm_register_hardware(struct pci_dev *, | 94 | extern int tpm_register_hardware(struct pci_dev *, |
97 | struct tpm_vendor_specific *); | 95 | struct tpm_vendor_specific *); |
98 | extern int tpm_open(struct inode *, struct file *); | 96 | extern int tpm_open(struct inode *, struct file *); |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 13248400b9c3..61fe14a77124 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -22,8 +22,9 @@ | |||
22 | #include "tpm.h" | 22 | #include "tpm.h" |
23 | 23 | ||
24 | /* Atmel definitions */ | 24 | /* Atmel definitions */ |
25 | enum tpm_atmel_addr{ | 25 | enum tpm_atmel_addr { |
26 | TPM_ATML_BASE = 0x400 | 26 | TPM_ATMEL_BASE_ADDR_LO = 0x08, |
27 | TPM_ATMEL_BASE_ADDR_HI = 0x09 | ||
27 | }; | 28 | }; |
28 | 29 | ||
29 | /* write status bits */ | 30 | /* write status bits */ |
@@ -148,7 +149,6 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
148 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, | 149 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, |
149 | .req_complete_val = ATML_STATUS_DATA_AVAIL, | 150 | .req_complete_val = ATML_STATUS_DATA_AVAIL, |
150 | .req_canceled = ATML_STATUS_READY, | 151 | .req_canceled = ATML_STATUS_READY, |
151 | .base = TPM_ATML_BASE, | ||
152 | .attr_group = &atmel_attr_grp, | 152 | .attr_group = &atmel_attr_grp, |
153 | .miscdev = { .fops = &atmel_ops, }, | 153 | .miscdev = { .fops = &atmel_ops, }, |
154 | }; | 154 | }; |
@@ -158,14 +158,16 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev, | |||
158 | { | 158 | { |
159 | u8 version[4]; | 159 | u8 version[4]; |
160 | int rc = 0; | 160 | int rc = 0; |
161 | int lo, hi; | ||
161 | 162 | ||
162 | if (pci_enable_device(pci_dev)) | 163 | if (pci_enable_device(pci_dev)) |
163 | return -EIO; | 164 | return -EIO; |
164 | 165 | ||
165 | if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) { | 166 | lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO ); |
166 | rc = -ENODEV; | 167 | hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI ); |
167 | goto out_err; | 168 | |
168 | } | 169 | tpm_atmel.base = (hi<<8)|lo; |
170 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); | ||
169 | 171 | ||
170 | /* verify that it is an Atmel part */ | 172 | /* verify that it is an Atmel part */ |
171 | if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' | 173 | if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 37bea14f9310..1a45e7dfc13b 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -22,9 +22,13 @@ | |||
22 | #include "tpm.h" | 22 | #include "tpm.h" |
23 | 23 | ||
24 | /* National definitions */ | 24 | /* National definitions */ |
25 | enum tpm_nsc_addr { | 25 | enum tpm_nsc_addr{ |
26 | TPM_NSC_BASE = 0x360, | 26 | TPM_NSC_BASE = 0x360, |
27 | TPM_NSC_IRQ = 0x07 | 27 | TPM_NSC_IRQ = 0x07, |
28 | TPM_NSC_BASE0_HI = 0x60, | ||
29 | TPM_NSC_BASE0_LO = 0x61, | ||
30 | TPM_NSC_BASE1_HI = 0x62, | ||
31 | TPM_NSC_BASE1_LO = 0x63 | ||
28 | }; | 32 | }; |
29 | 33 | ||
30 | enum tpm_nsc_index { | 34 | enum tpm_nsc_index { |
@@ -44,7 +48,7 @@ enum tpm_nsc_status_loc { | |||
44 | }; | 48 | }; |
45 | 49 | ||
46 | /* status bits */ | 50 | /* status bits */ |
47 | enum tpm_nsc_status{ | 51 | enum tpm_nsc_status { |
48 | NSC_STATUS_OBF = 0x01, /* output buffer full */ | 52 | NSC_STATUS_OBF = 0x01, /* output buffer full */ |
49 | NSC_STATUS_IBF = 0x02, /* input buffer full */ | 53 | NSC_STATUS_IBF = 0x02, /* input buffer full */ |
50 | NSC_STATUS_F0 = 0x04, /* F0 */ | 54 | NSC_STATUS_F0 = 0x04, /* F0 */ |
@@ -246,7 +250,6 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
246 | .req_complete_mask = NSC_STATUS_OBF, | 250 | .req_complete_mask = NSC_STATUS_OBF, |
247 | .req_complete_val = NSC_STATUS_OBF, | 251 | .req_complete_val = NSC_STATUS_OBF, |
248 | .req_canceled = NSC_STATUS_RDY, | 252 | .req_canceled = NSC_STATUS_RDY, |
249 | .base = TPM_NSC_BASE, | ||
250 | .attr_group = &nsc_attr_grp, | 253 | .attr_group = &nsc_attr_grp, |
251 | .miscdev = { .fops = &nsc_ops, }, | 254 | .miscdev = { .fops = &nsc_ops, }, |
252 | }; | 255 | }; |
@@ -255,15 +258,16 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
255 | const struct pci_device_id *pci_id) | 258 | const struct pci_device_id *pci_id) |
256 | { | 259 | { |
257 | int rc = 0; | 260 | int rc = 0; |
261 | int lo, hi; | ||
262 | |||
263 | hi = tpm_read_index(TPM_NSC_BASE0_HI); | ||
264 | lo = tpm_read_index(TPM_NSC_BASE0_LO); | ||
265 | |||
266 | tpm_nsc.base = (hi<<8) | lo; | ||
258 | 267 | ||
259 | if (pci_enable_device(pci_dev)) | 268 | if (pci_enable_device(pci_dev)) |
260 | return -EIO; | 269 | return -EIO; |
261 | 270 | ||
262 | if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) { | ||
263 | rc = -ENODEV; | ||
264 | goto out_err; | ||
265 | } | ||
266 | |||
267 | /* verify that it is a National part (SID) */ | 271 | /* verify that it is a National part (SID) */ |
268 | if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { | 272 | if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { |
269 | rc = -ENODEV; | 273 | rc = -ENODEV; |