@@ -469,37 +469,16 @@ static void nfit_mem_find_spa_bdw(struct acpi_nfit_desc *acpi_desc,
469
469
nfit_mem -> bdw = NULL ;
470
470
}
471
471
472
- static int nfit_mem_add (struct acpi_nfit_desc * acpi_desc ,
472
+ static void nfit_mem_init_bdw (struct acpi_nfit_desc * acpi_desc ,
473
473
struct nfit_mem * nfit_mem , struct acpi_nfit_system_address * spa )
474
474
{
475
475
u16 dcr = __to_nfit_memdev (nfit_mem )-> region_index ;
476
476
struct nfit_memdev * nfit_memdev ;
477
477
struct nfit_flush * nfit_flush ;
478
- struct nfit_dcr * nfit_dcr ;
479
478
struct nfit_bdw * nfit_bdw ;
480
479
struct nfit_idt * nfit_idt ;
481
480
u16 idt_idx , range_index ;
482
481
483
- list_for_each_entry (nfit_dcr , & acpi_desc -> dcrs , list ) {
484
- if (nfit_dcr -> dcr -> region_index != dcr )
485
- continue ;
486
- nfit_mem -> dcr = nfit_dcr -> dcr ;
487
- break ;
488
- }
489
-
490
- if (!nfit_mem -> dcr ) {
491
- dev_dbg (acpi_desc -> dev , "SPA %d missing:%s%s\n" ,
492
- spa -> range_index , __to_nfit_memdev (nfit_mem )
493
- ? "" : " MEMDEV" , nfit_mem -> dcr ? "" : " DCR" );
494
- return - ENODEV ;
495
- }
496
-
497
- /*
498
- * We've found enough to create an nvdimm, optionally
499
- * find an associated BDW
500
- */
501
- list_add (& nfit_mem -> list , & acpi_desc -> dimms );
502
-
503
482
list_for_each_entry (nfit_bdw , & acpi_desc -> bdws , list ) {
504
483
if (nfit_bdw -> bdw -> region_index != dcr )
505
484
continue ;
@@ -508,12 +487,12 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
508
487
}
509
488
510
489
if (!nfit_mem -> bdw )
511
- return 0 ;
490
+ return ;
512
491
513
492
nfit_mem_find_spa_bdw (acpi_desc , nfit_mem );
514
493
515
494
if (!nfit_mem -> spa_bdw )
516
- return 0 ;
495
+ return ;
517
496
518
497
range_index = nfit_mem -> spa_bdw -> range_index ;
519
498
list_for_each_entry (nfit_memdev , & acpi_desc -> memdevs , list ) {
@@ -538,8 +517,6 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
538
517
}
539
518
break ;
540
519
}
541
-
542
- return 0 ;
543
520
}
544
521
545
522
static int nfit_mem_dcr_init (struct acpi_nfit_desc * acpi_desc ,
@@ -548,7 +525,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
548
525
struct nfit_mem * nfit_mem , * found ;
549
526
struct nfit_memdev * nfit_memdev ;
550
527
int type = nfit_spa_type (spa );
551
- u16 dcr ;
552
528
553
529
switch (type ) {
554
530
case NFIT_SPA_DCR :
@@ -559,14 +535,18 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
559
535
}
560
536
561
537
list_for_each_entry (nfit_memdev , & acpi_desc -> memdevs , list ) {
562
- int rc ;
538
+ struct nfit_dcr * nfit_dcr ;
539
+ u32 device_handle ;
540
+ u16 dcr ;
563
541
564
542
if (nfit_memdev -> memdev -> range_index != spa -> range_index )
565
543
continue ;
566
544
found = NULL ;
567
545
dcr = nfit_memdev -> memdev -> region_index ;
546
+ device_handle = nfit_memdev -> memdev -> device_handle ;
568
547
list_for_each_entry (nfit_mem , & acpi_desc -> dimms , list )
569
- if (__to_nfit_memdev (nfit_mem )-> region_index == dcr ) {
548
+ if (__to_nfit_memdev (nfit_mem )-> device_handle
549
+ == device_handle ) {
570
550
found = nfit_mem ;
571
551
break ;
572
552
}
@@ -579,6 +559,31 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
579
559
if (!nfit_mem )
580
560
return - ENOMEM ;
581
561
INIT_LIST_HEAD (& nfit_mem -> list );
562
+ list_add (& nfit_mem -> list , & acpi_desc -> dimms );
563
+ }
564
+
565
+ list_for_each_entry (nfit_dcr , & acpi_desc -> dcrs , list ) {
566
+ if (nfit_dcr -> dcr -> region_index != dcr )
567
+ continue ;
568
+ /*
569
+ * Record the control region for the dimm. For
570
+ * the ACPI 6.1 case, where there are separate
571
+ * control regions for the pmem vs blk
572
+ * interfaces, be sure to record the extended
573
+ * blk details.
574
+ */
575
+ if (!nfit_mem -> dcr )
576
+ nfit_mem -> dcr = nfit_dcr -> dcr ;
577
+ else if (nfit_mem -> dcr -> windows == 0
578
+ && nfit_dcr -> dcr -> windows )
579
+ nfit_mem -> dcr = nfit_dcr -> dcr ;
580
+ break ;
581
+ }
582
+
583
+ if (dcr && !nfit_mem -> dcr ) {
584
+ dev_err (acpi_desc -> dev , "SPA %d missing DCR %d\n" ,
585
+ spa -> range_index , dcr );
586
+ return - ENODEV ;
582
587
}
583
588
584
589
if (type == NFIT_SPA_DCR ) {
@@ -595,6 +600,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
595
600
nfit_mem -> idt_dcr = nfit_idt -> idt ;
596
601
break ;
597
602
}
603
+ nfit_mem_init_bdw (acpi_desc , nfit_mem , spa );
598
604
} else {
599
605
/*
600
606
* A single dimm may belong to multiple SPA-PM
@@ -603,13 +609,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
603
609
*/
604
610
nfit_mem -> memdev_pmem = nfit_memdev -> memdev ;
605
611
}
606
-
607
- if (found )
608
- continue ;
609
-
610
- rc = nfit_mem_add (acpi_desc , nfit_mem , spa );
611
- if (rc )
612
- return rc ;
613
612
}
614
613
615
614
return 0 ;
0 commit comments