aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm_tis.c75
-rw-r--r--drivers/char/tpm/tpm_tis_core.c16
-rw-r--r--drivers/char/tpm/tpm_tis_core.h13
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
142static void __iomem *ilb_base_addr;
143
144static 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 */
152static void tpm_platform_begin_xfer(void) 143static 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 */
176static void tpm_platform_end_xfer(void) 167static 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
197static inline bool is_bsw(void) 188static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
198{
199 return false;
200}
201
202static void tpm_platform_begin_xfer(void)
203{ 189{
204} 190}
205 191
206static void tpm_platform_end_xfer(void) 192static 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);
351static void tpm_tis_pnp_remove(struct pnp_dev *dev) 337static 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
359static struct pnp_driver tis_pnp_driver = { 349static struct pnp_driver tis_pnp_driver = {
@@ -400,10 +390,14 @@ static int tpm_tis_plat_probe(struct platform_device *pdev)
400static int tpm_tis_plat_remove(struct platform_device *pdev) 390static 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:
484err_platform: 473err_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
491err_force: 476err_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;
860out_err: 871out_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}
864EXPORT_SYMBOL_GPL(tpm_tis_core_init); 878EXPORT_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
82enum tpm_tis_flags { 85enum 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
151static 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
147void tpm_tis_remove(struct tpm_chip *chip); 160void tpm_tis_remove(struct tpm_chip *chip);
148int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, 161int 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,