aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2018-11-04 14:18:46 -0500
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2019-02-13 02:48:33 -0500
commit719b7d81f2048477f89f7303e2b4ddec8197e6e3 (patch)
treeda5983336e23c58d3dba2a85326983baf54a07ce
parent2f257402ee981720d65080b1e3ce19f693f5c9c3 (diff)
tpm: introduce tpm_chip_start() and tpm_chip_stop()
Encapsulate power gating and locality functionality to tpm_chip_start() and tpm_chip_stop() in order to clean up the branching mess in tpm_transmit(). Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com> Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>
-rw-r--r--drivers/char/tpm/tpm-chip.c111
-rw-r--r--drivers/char/tpm/tpm-interface.c84
-rw-r--r--drivers/char/tpm/tpm.h2
3 files changed, 116 insertions, 81 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 157505b0f755..ed673c7216a0 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -37,6 +37,117 @@ struct class *tpm_class;
37struct class *tpmrm_class; 37struct class *tpmrm_class;
38dev_t tpm_devt; 38dev_t tpm_devt;
39 39
40static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
41{
42 int rc;
43
44 if (flags & TPM_TRANSMIT_NESTED)
45 return 0;
46
47 if (!chip->ops->request_locality)
48 return 0;
49
50 rc = chip->ops->request_locality(chip, 0);
51 if (rc < 0)
52 return rc;
53
54 chip->locality = rc;
55 return 0;
56}
57
58static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)
59{
60 int rc;
61
62 if (flags & TPM_TRANSMIT_NESTED)
63 return;
64
65 if (!chip->ops->relinquish_locality)
66 return;
67
68 rc = chip->ops->relinquish_locality(chip, chip->locality);
69 if (rc)
70 dev_err(&chip->dev, "%s: : error %d\n", __func__, rc);
71
72 chip->locality = -1;
73}
74
75static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)
76{
77 if (flags & TPM_TRANSMIT_NESTED)
78 return 0;
79
80 if (!chip->ops->cmd_ready)
81 return 0;
82
83 return chip->ops->cmd_ready(chip);
84}
85
86static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
87{
88 if (flags & TPM_TRANSMIT_NESTED)
89 return 0;
90
91 if (!chip->ops->go_idle)
92 return 0;
93
94 return chip->ops->go_idle(chip);
95}
96
97/**
98 * tpm_chip_start() - power on the TPM
99 * @chip: a TPM chip to use
100 * @flags: TPM transmit flags
101 *
102 * Return:
103 * * The response length - OK
104 * * -errno - A system error
105 */
106int tpm_chip_start(struct tpm_chip *chip, unsigned int flags)
107{
108 int ret;
109
110 if (chip->ops->clk_enable)
111 chip->ops->clk_enable(chip, true);
112
113 if (chip->locality == -1) {
114 ret = tpm_request_locality(chip, flags);
115 if (ret) {
116 chip->ops->clk_enable(chip, false);
117 return ret;
118 }
119 }
120
121 ret = tpm_cmd_ready(chip, flags);
122 if (ret) {
123 tpm_relinquish_locality(chip, flags);
124 if (chip->ops->clk_enable)
125 chip->ops->clk_enable(chip, false);
126 return ret;
127 }
128
129 return 0;
130}
131EXPORT_SYMBOL_GPL(tpm_chip_start);
132
133/**
134 * tpm_chip_stop() - power off the TPM
135 * @chip: a TPM chip to use
136 * @flags: TPM transmit flags
137 *
138 * Return:
139 * * The response length - OK
140 * * -errno - A system error
141 */
142void tpm_chip_stop(struct tpm_chip *chip, unsigned int flags)
143{
144 tpm_go_idle(chip, flags);
145 tpm_relinquish_locality(chip, flags);
146 if (chip->ops->clk_enable)
147 chip->ops->clk_enable(chip, false);
148}
149EXPORT_SYMBOL_GPL(tpm_chip_stop);
150
40/** 151/**
41 * tpm_try_get_ops() - Get a ref to the tpm_chip 152 * tpm_try_get_ops() - Get a ref to the tpm_chip
42 * @chip: Chip to ref 153 * @chip: Chip to ref
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 54a15f59e175..038a4767d9d6 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -62,64 +62,6 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
62} 62}
63EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); 63EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
64 64
65static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
66{
67 int rc;
68
69 if (flags & TPM_TRANSMIT_NESTED)
70 return 0;
71
72 if (!chip->ops->request_locality)
73 return 0;
74
75 rc = chip->ops->request_locality(chip, 0);
76 if (rc < 0)
77 return rc;
78
79 chip->locality = rc;
80
81 return 0;
82}
83
84static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)
85{
86 int rc;
87
88 if (flags & TPM_TRANSMIT_NESTED)
89 return;
90
91 if (!chip->ops->relinquish_locality)
92 return;
93
94 rc = chip->ops->relinquish_locality(chip, chip->locality);
95 if (rc)
96 dev_err(&chip->dev, "%s: : error %d\n", __func__, rc);
97
98 chip->locality = -1;
99}
100
101static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)
102{
103 if (flags & TPM_TRANSMIT_NESTED)
104 return 0;
105
106 if (!chip->ops->cmd_ready)
107 return 0;
108
109 return chip->ops->cmd_ready(chip);
110}
111
112static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
113{
114 if (flags & TPM_TRANSMIT_NESTED)
115 return 0;
116
117 if (!chip->ops->go_idle)
118 return 0;
119
120 return chip->ops->go_idle(chip);
121}
122
123static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz, 65static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz,
124 unsigned int flags) 66 unsigned int flags)
125{ 67{
@@ -221,7 +163,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
221 /* space for header and handles */ 163 /* space for header and handles */
222 u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)]; 164 u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)];
223 unsigned int delay_msec = TPM2_DURATION_SHORT; 165 unsigned int delay_msec = TPM2_DURATION_SHORT;
224 bool has_locality = false;
225 u32 rc = 0; 166 u32 rc = 0;
226 ssize_t ret; 167 ssize_t ret;
227 const size_t save_size = min(sizeof(save), bufsiz); 168 const size_t save_size = min(sizeof(save), bufsiz);
@@ -236,32 +177,13 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
236 memcpy(save, buf, save_size); 177 memcpy(save, buf, save_size);
237 178
238 for (;;) { 179 for (;;) {
239 if (chip->ops->clk_enable != NULL) 180 ret = tpm_chip_start(chip, flags);
240 chip->ops->clk_enable(chip, true);
241
242 if (chip->locality == -1) {
243 ret = tpm_request_locality(chip, flags);
244 if (ret)
245 goto out_locality;
246 has_locality = true;
247 }
248
249 ret = tpm_cmd_ready(chip, flags);
250 if (ret) 181 if (ret)
251 goto out_locality; 182 return ret;
252 183
253 ret = tpm_try_transmit(chip, buf, bufsiz, flags); 184 ret = tpm_try_transmit(chip, buf, bufsiz, flags);
254 185
255 /* This may fail but do not override ret. */ 186 tpm_chip_stop(chip, flags);
256 tpm_go_idle(chip, flags);
257
258out_locality:
259 if (has_locality)
260 tpm_relinquish_locality(chip, flags);
261
262 if (chip->ops->clk_enable != NULL)
263 chip->ops->clk_enable(chip, false);
264
265 if (ret < 0) 187 if (ret < 0)
266 break; 188 break;
267 rc = be32_to_cpu(header->return_code); 189 rc = be32_to_cpu(header->return_code);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 18ef432a3fde..2d6d934f1c8b 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -523,6 +523,8 @@ static inline void tpm_msleep(unsigned int delay_msec)
523 delay_msec * 1000); 523 delay_msec * 1000);
524}; 524};
525 525
526int tpm_chip_start(struct tpm_chip *chip, unsigned int flags);
527void tpm_chip_stop(struct tpm_chip *chip, unsigned int flags);
526struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip); 528struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
527__must_check int tpm_try_get_ops(struct tpm_chip *chip); 529__must_check int tpm_try_get_ops(struct tpm_chip *chip);
528void tpm_put_ops(struct tpm_chip *chip); 530void tpm_put_ops(struct tpm_chip *chip);