@@ -77,6 +77,8 @@ enum crb_flags {
77
77
78
78
struct crb_priv {
79
79
unsigned int flags ;
80
+ struct resource res ;
81
+ void __iomem * iobase ;
80
82
struct crb_control_area __iomem * cca ;
81
83
u8 __iomem * cmd ;
82
84
u8 __iomem * rsp ;
@@ -196,41 +198,125 @@ static const struct tpm_class_ops tpm_crb = {
196
198
.req_complete_val = CRB_STS_COMPLETE ,
197
199
};
198
200
199
- static int crb_acpi_add (struct acpi_device * device )
201
+ static int crb_init (struct acpi_device * device , struct crb_priv * priv )
200
202
{
201
203
struct tpm_chip * chip ;
204
+ int rc ;
205
+
206
+ chip = tpmm_chip_alloc (& device -> dev , & tpm_crb );
207
+ if (IS_ERR (chip ))
208
+ return PTR_ERR (chip );
209
+
210
+ chip -> vendor .priv = priv ;
211
+ chip -> acpi_dev_handle = device -> handle ;
212
+ chip -> flags = TPM_CHIP_FLAG_TPM2 ;
213
+
214
+ rc = tpm_get_timeouts (chip );
215
+ if (rc )
216
+ return rc ;
217
+
218
+ rc = tpm2_do_selftest (chip );
219
+ if (rc )
220
+ return rc ;
221
+
222
+ return tpm_chip_register (chip );
223
+ }
224
+
225
+ static int crb_check_resource (struct acpi_resource * ares , void * data )
226
+ {
227
+ struct crb_priv * priv = data ;
228
+ struct resource res ;
229
+
230
+ if (acpi_dev_resource_memory (ares , & res ))
231
+ priv -> res = res ;
232
+
233
+ return 1 ;
234
+ }
235
+
236
+ static void __iomem * crb_map_res (struct device * dev , struct crb_priv * priv ,
237
+ u64 start , u32 size )
238
+ {
239
+ struct resource new_res = {
240
+ .start = start ,
241
+ .end = start + size - 1 ,
242
+ .flags = IORESOURCE_MEM ,
243
+ };
244
+
245
+ /* Detect a 64 bit address on a 32 bit system */
246
+ if (start != new_res .start )
247
+ return ERR_PTR (- EINVAL );
248
+
249
+ if (!resource_contains (& priv -> res , & new_res ))
250
+ return devm_ioremap_resource (dev , & new_res );
251
+
252
+ return priv -> iobase + (new_res .start - priv -> res .start );
253
+ }
254
+
255
+ static int crb_map_io (struct acpi_device * device , struct crb_priv * priv ,
256
+ struct acpi_table_tpm2 * buf )
257
+ {
258
+ struct list_head resources ;
259
+ struct device * dev = & device -> dev ;
260
+ u64 pa ;
261
+ int ret ;
262
+
263
+ INIT_LIST_HEAD (& resources );
264
+ ret = acpi_dev_get_resources (device , & resources , crb_check_resource ,
265
+ priv );
266
+ if (ret < 0 )
267
+ return ret ;
268
+ acpi_dev_free_resource_list (& resources );
269
+
270
+ if (resource_type (& priv -> res ) != IORESOURCE_MEM ) {
271
+ dev_err (dev ,
272
+ FW_BUG "TPM2 ACPI table does not define a memory resource\n" );
273
+ return - EINVAL ;
274
+ }
275
+
276
+ priv -> iobase = devm_ioremap_resource (dev , & priv -> res );
277
+ if (IS_ERR (priv -> iobase ))
278
+ return PTR_ERR (priv -> iobase );
279
+
280
+ priv -> cca = crb_map_res (dev , priv , buf -> control_address , 0x1000 );
281
+ if (IS_ERR (priv -> cca ))
282
+ return PTR_ERR (priv -> cca );
283
+
284
+ pa = ((u64 ) ioread32 (& priv -> cca -> cmd_pa_high ) << 32 ) |
285
+ (u64 ) ioread32 (& priv -> cca -> cmd_pa_low );
286
+ priv -> cmd = crb_map_res (dev , priv , pa , ioread32 (& priv -> cca -> cmd_size ));
287
+ if (IS_ERR (priv -> cmd ))
288
+ return PTR_ERR (priv -> cmd );
289
+
290
+ memcpy_fromio (& pa , & priv -> cca -> rsp_pa , 8 );
291
+ pa = le64_to_cpu (pa );
292
+ priv -> rsp = crb_map_res (dev , priv , pa , ioread32 (& priv -> cca -> rsp_size ));
293
+ return PTR_ERR_OR_ZERO (priv -> rsp );
294
+ }
295
+
296
+ static int crb_acpi_add (struct acpi_device * device )
297
+ {
202
298
struct acpi_table_tpm2 * buf ;
203
299
struct crb_priv * priv ;
204
300
struct device * dev = & device -> dev ;
205
301
acpi_status status ;
206
302
u32 sm ;
207
- u64 pa ;
208
303
int rc ;
209
304
210
305
status = acpi_get_table (ACPI_SIG_TPM2 , 1 ,
211
306
(struct acpi_table_header * * ) & buf );
212
307
if (ACPI_FAILURE (status ) || buf -> header .length < sizeof (* buf )) {
213
308
dev_err (dev , FW_BUG "failed to get TPM2 ACPI table\n" );
214
- return - ENODEV ;
309
+ return - EINVAL ;
215
310
}
216
311
217
312
/* Should the FIFO driver handle this? */
218
313
sm = buf -> start_method ;
219
314
if (sm == ACPI_TPM2_MEMORY_MAPPED )
220
315
return - ENODEV ;
221
316
222
- chip = tpmm_chip_alloc (dev , & tpm_crb );
223
- if (IS_ERR (chip ))
224
- return PTR_ERR (chip );
225
-
226
- chip -> flags = TPM_CHIP_FLAG_TPM2 ;
227
-
228
- priv = (struct crb_priv * ) devm_kzalloc (dev , sizeof (struct crb_priv ),
229
- GFP_KERNEL );
230
- if (!priv ) {
231
- dev_err (dev , "failed to devm_kzalloc for private data\n" );
317
+ priv = devm_kzalloc (dev , sizeof (struct crb_priv ), GFP_KERNEL );
318
+ if (!priv )
232
319
return - ENOMEM ;
233
- }
234
320
235
321
/* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
236
322
* report only ACPI start but in practice seems to require both
@@ -244,44 +330,11 @@ static int crb_acpi_add(struct acpi_device *device)
244
330
sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD )
245
331
priv -> flags |= CRB_FL_ACPI_START ;
246
332
247
- priv -> cca = (struct crb_control_area __iomem * )
248
- devm_ioremap_nocache (dev , buf -> control_address , 0x1000 );
249
- if (!priv -> cca ) {
250
- dev_err (dev , "ioremap of the control area failed\n" );
251
- return - ENOMEM ;
252
- }
253
-
254
- pa = ((u64 )ioread32 (& priv -> cca -> cmd_pa_high ) << 32 ) |
255
- (u64 )ioread32 (& priv -> cca -> cmd_pa_low );
256
- priv -> cmd =
257
- devm_ioremap_nocache (dev , pa , ioread32 (& priv -> cca -> cmd_size ));
258
- if (!priv -> cmd ) {
259
- dev_err (dev , "ioremap of the command buffer failed\n" );
260
- return - ENOMEM ;
261
- }
262
-
263
- memcpy_fromio (& pa , & priv -> cca -> rsp_pa , 8 );
264
- pa = le64_to_cpu (pa );
265
- priv -> rsp =
266
- devm_ioremap_nocache (dev , pa , ioread32 (& priv -> cca -> rsp_size ));
267
- if (!priv -> rsp ) {
268
- dev_err (dev , "ioremap of the response buffer failed\n" );
269
- return - ENOMEM ;
270
- }
271
-
272
- chip -> vendor .priv = priv ;
273
-
274
- rc = tpm_get_timeouts (chip );
333
+ rc = crb_map_io (device , priv , buf );
275
334
if (rc )
276
335
return rc ;
277
336
278
- chip -> acpi_dev_handle = device -> handle ;
279
-
280
- rc = tpm2_do_selftest (chip );
281
- if (rc )
282
- return rc ;
283
-
284
- return tpm_chip_register (chip );
337
+ return crb_init (device , priv );
285
338
}
286
339
287
340
static int crb_acpi_remove (struct acpi_device * device )
0 commit comments