diff options
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 75 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis_core.c | 16 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis_core.h | 13 |
3 files changed, 56 insertions, 48 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index e2d1055fb814..923f8f2cbaca 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -134,33 +134,24 @@ static int check_acpi_tpm2(struct device *dev) | |||
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | #ifdef CONFIG_X86 | 136 | #ifdef CONFIG_X86 |
137 | #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | 137 | #define LPC_CNTRL_OFFSET 0x84 |
138 | #define ILB_REMAP_SIZE 0x100 | 138 | #define LPC_CLKRUN_EN (1 << 2) |
139 | #define LPC_CNTRL_REG_OFFSET 0x84 | ||
140 | #define LPC_CLKRUN_EN (1 << 2) | ||
141 | |||
142 | static void __iomem *ilb_base_addr; | ||
143 | |||
144 | static inline bool is_bsw(void) | ||
145 | { | ||
146 | return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
147 | } | ||
148 | 139 | ||
149 | /** | 140 | /** |
150 | * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running | 141 | * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running |
151 | */ | 142 | */ |
152 | static void tpm_platform_begin_xfer(void) | 143 | static void tpm_platform_begin_xfer(struct tpm_tis_data *data) |
153 | { | 144 | { |
154 | u32 clkrun_val; | 145 | u32 clkrun_val; |
155 | 146 | ||
156 | if (!is_bsw()) | 147 | if (!is_bsw()) |
157 | return; | 148 | return; |
158 | 149 | ||
159 | clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | 150 | clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); |
160 | 151 | ||
161 | /* Disable LPC CLKRUN# */ | 152 | /* Disable LPC CLKRUN# */ |
162 | clkrun_val &= ~LPC_CLKRUN_EN; | 153 | clkrun_val &= ~LPC_CLKRUN_EN; |
163 | iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | 154 | iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); |
164 | 155 | ||
165 | /* | 156 | /* |
166 | * Write any random value on port 0x80 which is on LPC, to make | 157 | * Write any random value on port 0x80 which is on LPC, to make |
@@ -173,18 +164,18 @@ static void tpm_platform_begin_xfer(void) | |||
173 | /** | 164 | /** |
174 | * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off | 165 | * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off |
175 | */ | 166 | */ |
176 | static void tpm_platform_end_xfer(void) | 167 | static void tpm_platform_end_xfer(struct tpm_tis_data *data) |
177 | { | 168 | { |
178 | u32 clkrun_val; | 169 | u32 clkrun_val; |
179 | 170 | ||
180 | if (!is_bsw()) | 171 | if (!is_bsw()) |
181 | return; | 172 | return; |
182 | 173 | ||
183 | clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | 174 | clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); |
184 | 175 | ||
185 | /* Enable LPC CLKRUN# */ | 176 | /* Enable LPC CLKRUN# */ |
186 | clkrun_val |= LPC_CLKRUN_EN; | 177 | clkrun_val |= LPC_CLKRUN_EN; |
187 | iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | 178 | iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); |
188 | 179 | ||
189 | /* | 180 | /* |
190 | * Write any random value on port 0x80 which is on LPC, to make | 181 | * Write any random value on port 0x80 which is on LPC, to make |
@@ -194,16 +185,11 @@ static void tpm_platform_end_xfer(void) | |||
194 | 185 | ||
195 | } | 186 | } |
196 | #else | 187 | #else |
197 | static inline bool is_bsw(void) | 188 | static void tpm_platform_begin_xfer(struct tpm_tis_data *data) |
198 | { | ||
199 | return false; | ||
200 | } | ||
201 | |||
202 | static void tpm_platform_begin_xfer(void) | ||
203 | { | 189 | { |
204 | } | 190 | } |
205 | 191 | ||
206 | static void tpm_platform_end_xfer(void) | 192 | static void tpm_platform_end_xfer(struct tpm_tis_data *data) |
207 | { | 193 | { |
208 | } | 194 | } |
209 | #endif | 195 | #endif |
@@ -213,12 +199,12 @@ static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | |||
213 | { | 199 | { |
214 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 200 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
215 | 201 | ||
216 | tpm_platform_begin_xfer(); | 202 | tpm_platform_begin_xfer(data); |
217 | 203 | ||
218 | while (len--) | 204 | while (len--) |
219 | *result++ = ioread8(phy->iobase + addr); | 205 | *result++ = ioread8(phy->iobase + addr); |
220 | 206 | ||
221 | tpm_platform_end_xfer(); | 207 | tpm_platform_end_xfer(data); |
222 | 208 | ||
223 | return 0; | 209 | return 0; |
224 | } | 210 | } |
@@ -228,12 +214,12 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | |||
228 | { | 214 | { |
229 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 215 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
230 | 216 | ||
231 | tpm_platform_begin_xfer(); | 217 | tpm_platform_begin_xfer(data); |
232 | 218 | ||
233 | while (len--) | 219 | while (len--) |
234 | iowrite8(*value++, phy->iobase + addr); | 220 | iowrite8(*value++, phy->iobase + addr); |
235 | 221 | ||
236 | tpm_platform_end_xfer(); | 222 | tpm_platform_end_xfer(data); |
237 | 223 | ||
238 | return 0; | 224 | return 0; |
239 | } | 225 | } |
@@ -242,11 +228,11 @@ static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) | |||
242 | { | 228 | { |
243 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 229 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
244 | 230 | ||
245 | tpm_platform_begin_xfer(); | 231 | tpm_platform_begin_xfer(data); |
246 | 232 | ||
247 | *result = ioread16(phy->iobase + addr); | 233 | *result = ioread16(phy->iobase + addr); |
248 | 234 | ||
249 | tpm_platform_end_xfer(); | 235 | tpm_platform_end_xfer(data); |
250 | 236 | ||
251 | return 0; | 237 | return 0; |
252 | } | 238 | } |
@@ -255,11 +241,11 @@ static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) | |||
255 | { | 241 | { |
256 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 242 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
257 | 243 | ||
258 | tpm_platform_begin_xfer(); | 244 | tpm_platform_begin_xfer(data); |
259 | 245 | ||
260 | *result = ioread32(phy->iobase + addr); | 246 | *result = ioread32(phy->iobase + addr); |
261 | 247 | ||
262 | tpm_platform_end_xfer(); | 248 | tpm_platform_end_xfer(data); |
263 | 249 | ||
264 | return 0; | 250 | return 0; |
265 | } | 251 | } |
@@ -268,11 +254,11 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) | |||
268 | { | 254 | { |
269 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 255 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
270 | 256 | ||
271 | tpm_platform_begin_xfer(); | 257 | tpm_platform_begin_xfer(data); |
272 | 258 | ||
273 | iowrite32(value, phy->iobase + addr); | 259 | iowrite32(value, phy->iobase + addr); |
274 | 260 | ||
275 | tpm_platform_end_xfer(); | 261 | tpm_platform_end_xfer(data); |
276 | 262 | ||
277 | return 0; | 263 | return 0; |
278 | } | 264 | } |
@@ -351,9 +337,13 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | |||
351 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) | 337 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) |
352 | { | 338 | { |
353 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 339 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
340 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | ||
354 | 341 | ||
355 | tpm_chip_unregister(chip); | 342 | tpm_chip_unregister(chip); |
356 | tpm_tis_remove(chip); | 343 | tpm_tis_remove(chip); |
344 | if (is_bsw()) | ||
345 | iounmap(priv->ilb_base_addr); | ||
346 | |||
357 | } | 347 | } |
358 | 348 | ||
359 | static struct pnp_driver tis_pnp_driver = { | 349 | static struct pnp_driver tis_pnp_driver = { |
@@ -400,10 +390,14 @@ static int tpm_tis_plat_probe(struct platform_device *pdev) | |||
400 | static int tpm_tis_plat_remove(struct platform_device *pdev) | 390 | static int tpm_tis_plat_remove(struct platform_device *pdev) |
401 | { | 391 | { |
402 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); | 392 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); |
393 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | ||
403 | 394 | ||
404 | tpm_chip_unregister(chip); | 395 | tpm_chip_unregister(chip); |
405 | tpm_tis_remove(chip); | 396 | tpm_tis_remove(chip); |
406 | 397 | ||
398 | if (is_bsw()) | ||
399 | iounmap(priv->ilb_base_addr); | ||
400 | |||
407 | return 0; | 401 | return 0; |
408 | } | 402 | } |
409 | 403 | ||
@@ -461,11 +455,6 @@ static int __init init_tis(void) | |||
461 | if (rc) | 455 | if (rc) |
462 | goto err_force; | 456 | goto err_force; |
463 | 457 | ||
464 | #ifdef CONFIG_X86 | ||
465 | if (is_bsw()) | ||
466 | ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
467 | ILB_REMAP_SIZE); | ||
468 | #endif | ||
469 | rc = platform_driver_register(&tis_drv); | 458 | rc = platform_driver_register(&tis_drv); |
470 | if (rc) | 459 | if (rc) |
471 | goto err_platform; | 460 | goto err_platform; |
@@ -484,10 +473,6 @@ err_pnp: | |||
484 | err_platform: | 473 | err_platform: |
485 | if (force_pdev) | 474 | if (force_pdev) |
486 | platform_device_unregister(force_pdev); | 475 | platform_device_unregister(force_pdev); |
487 | #ifdef CONFIG_X86 | ||
488 | if (is_bsw()) | ||
489 | iounmap(ilb_base_addr); | ||
490 | #endif | ||
491 | err_force: | 476 | err_force: |
492 | return rc; | 477 | return rc; |
493 | } | 478 | } |
@@ -497,10 +482,6 @@ static void __exit cleanup_tis(void) | |||
497 | pnp_unregister_driver(&tis_pnp_driver); | 482 | pnp_unregister_driver(&tis_pnp_driver); |
498 | platform_driver_unregister(&tis_drv); | 483 | platform_driver_unregister(&tis_drv); |
499 | 484 | ||
500 | #ifdef CONFIG_X86 | ||
501 | if (is_bsw()) | ||
502 | iounmap(ilb_base_addr); | ||
503 | #endif | ||
504 | if (force_pdev) | 485 | if (force_pdev) |
505 | platform_device_unregister(force_pdev); | 486 | platform_device_unregister(force_pdev); |
506 | } | 487 | } |
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index ca6b2b527d52..aff567840e50 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c | |||
@@ -766,6 +766,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | |||
766 | priv->phy_ops = phy_ops; | 766 | priv->phy_ops = phy_ops; |
767 | dev_set_drvdata(&chip->dev, priv); | 767 | dev_set_drvdata(&chip->dev, priv); |
768 | 768 | ||
769 | if (is_bsw()) { | ||
770 | priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
771 | ILB_REMAP_SIZE); | ||
772 | if (!priv->ilb_base_addr) | ||
773 | return -ENOMEM; | ||
774 | } | ||
775 | |||
769 | if (wait_startup(chip, 0) != 0) { | 776 | if (wait_startup(chip, 0) != 0) { |
770 | rc = -ENODEV; | 777 | rc = -ENODEV; |
771 | goto out_err; | 778 | goto out_err; |
@@ -856,9 +863,16 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | |||
856 | } | 863 | } |
857 | } | 864 | } |
858 | 865 | ||
859 | return tpm_chip_register(chip); | 866 | rc = tpm_chip_register(chip); |
867 | if (rc && is_bsw()) | ||
868 | iounmap(priv->ilb_base_addr); | ||
869 | |||
870 | return rc; | ||
860 | out_err: | 871 | out_err: |
861 | tpm_tis_remove(chip); | 872 | tpm_tis_remove(chip); |
873 | if (is_bsw()) | ||
874 | iounmap(priv->ilb_base_addr); | ||
875 | |||
862 | return rc; | 876 | return rc; |
863 | } | 877 | } |
864 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); | 878 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); |
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 6bbac319ff3b..458847f72758 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h | |||
@@ -79,6 +79,9 @@ enum tis_defaults { | |||
79 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) | 79 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) |
80 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) | 80 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) |
81 | 81 | ||
82 | #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | ||
83 | #define ILB_REMAP_SIZE 0x100 | ||
84 | |||
82 | enum tpm_tis_flags { | 85 | enum tpm_tis_flags { |
83 | TPM_TIS_ITPM_WORKAROUND = BIT(0), | 86 | TPM_TIS_ITPM_WORKAROUND = BIT(0), |
84 | }; | 87 | }; |
@@ -89,6 +92,7 @@ struct tpm_tis_data { | |||
89 | int irq; | 92 | int irq; |
90 | bool irq_tested; | 93 | bool irq_tested; |
91 | unsigned int flags; | 94 | unsigned int flags; |
95 | void __iomem *ilb_base_addr; | ||
92 | wait_queue_head_t int_queue; | 96 | wait_queue_head_t int_queue; |
93 | wait_queue_head_t read_queue; | 97 | wait_queue_head_t read_queue; |
94 | const struct tpm_tis_phy_ops *phy_ops; | 98 | const struct tpm_tis_phy_ops *phy_ops; |
@@ -144,6 +148,15 @@ static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr, | |||
144 | return data->phy_ops->write32(data, addr, value); | 148 | return data->phy_ops->write32(data, addr, value); |
145 | } | 149 | } |
146 | 150 | ||
151 | static inline bool is_bsw(void) | ||
152 | { | ||
153 | #ifdef CONFIG_X86 | ||
154 | return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
155 | #else | ||
156 | return false; | ||
157 | #endif | ||
158 | } | ||
159 | |||
147 | void tpm_tis_remove(struct tpm_chip *chip); | 160 | void tpm_tis_remove(struct tpm_chip *chip); |
148 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | 161 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
149 | const struct tpm_tis_phy_ops *phy_ops, | 162 | const struct tpm_tis_phy_ops *phy_ops, |