127127
128128static const struct res_config {
129129 bool machine_check ;
130+ /* The number of present memory controllers. */
130131 int num_imc ;
131132 u32 imc_base ;
132133 u32 cmf_base ;
@@ -1201,23 +1202,21 @@ static void igen6_check(struct mem_ctl_info *mci)
12011202 irq_work_queue (& ecclog_irq_work );
12021203}
12031204
1204- static int igen6_register_mci (int mc , u64 mchbar , struct pci_dev * pdev )
1205+ /* Check whether the memory controller is absent. */
1206+ static bool igen6_imc_absent (void __iomem * window )
1207+ {
1208+ return readl (window + MAD_INTER_CHANNEL_OFFSET ) == ~0 ;
1209+ }
1210+
1211+ static int igen6_register_mci (int mc , void __iomem * window , struct pci_dev * pdev )
12051212{
12061213 struct edac_mc_layer layers [2 ];
12071214 struct mem_ctl_info * mci ;
12081215 struct igen6_imc * imc ;
1209- void __iomem * window ;
12101216 int rc ;
12111217
12121218 edac_dbg (2 , "\n" );
12131219
1214- mchbar += mc * MCHBAR_SIZE ;
1215- window = ioremap (mchbar , MCHBAR_SIZE );
1216- if (!window ) {
1217- igen6_printk (KERN_ERR , "Failed to ioremap 0x%llx\n" , mchbar );
1218- return - ENODEV ;
1219- }
1220-
12211220 layers [0 ].type = EDAC_MC_LAYER_CHANNEL ;
12221221 layers [0 ].size = NUM_CHANNELS ;
12231222 layers [0 ].is_virt_csrow = false;
@@ -1283,7 +1282,6 @@ static int igen6_register_mci(int mc, u64 mchbar, struct pci_dev *pdev)
12831282fail2 :
12841283 edac_mc_free (mci );
12851284fail :
1286- iounmap (window );
12871285 return rc ;
12881286}
12891287
@@ -1309,6 +1307,56 @@ static void igen6_unregister_mcis(void)
13091307 }
13101308}
13111309
1310+ static int igen6_register_mcis (struct pci_dev * pdev , u64 mchbar )
1311+ {
1312+ void __iomem * window ;
1313+ int lmc , pmc , rc ;
1314+ u64 base ;
1315+
1316+ for (lmc = 0 , pmc = 0 ; pmc < NUM_IMC ; pmc ++ ) {
1317+ base = mchbar + pmc * MCHBAR_SIZE ;
1318+ window = ioremap (base , MCHBAR_SIZE );
1319+ if (!window ) {
1320+ igen6_printk (KERN_ERR , "Failed to ioremap 0x%llx for mc%d\n" , base , pmc );
1321+ rc = - ENOMEM ;
1322+ goto out_unregister_mcis ;
1323+ }
1324+
1325+ if (igen6_imc_absent (window )) {
1326+ iounmap (window );
1327+ edac_dbg (2 , "Skip absent mc%d\n" , pmc );
1328+ continue ;
1329+ }
1330+
1331+ rc = igen6_register_mci (lmc , window , pdev );
1332+ if (rc )
1333+ goto out_iounmap ;
1334+
1335+ /* Done, if all present MCs are detected and registered. */
1336+ if (++ lmc >= res_cfg -> num_imc )
1337+ break ;
1338+ }
1339+
1340+ if (!lmc ) {
1341+ igen6_printk (KERN_ERR , "No mc found.\n" );
1342+ return - ENODEV ;
1343+ }
1344+
1345+ if (lmc < res_cfg -> num_imc )
1346+ igen6_printk (KERN_WARNING , "Expected %d mcs, but only %d detected." ,
1347+ res_cfg -> num_imc , lmc );
1348+
1349+ return 0 ;
1350+
1351+ out_iounmap :
1352+ iounmap (window );
1353+
1354+ out_unregister_mcis :
1355+ igen6_unregister_mcis ();
1356+
1357+ return rc ;
1358+ }
1359+
13121360static int igen6_mem_slice_setup (u64 mchbar )
13131361{
13141362 struct igen6_imc * imc = & igen6_pvt -> imc [0 ];
@@ -1405,7 +1453,7 @@ static void opstate_set(const struct res_config *cfg, const struct pci_device_id
14051453static int igen6_probe (struct pci_dev * pdev , const struct pci_device_id * ent )
14061454{
14071455 u64 mchbar ;
1408- int i , rc ;
1456+ int rc ;
14091457
14101458 edac_dbg (2 , "\n" );
14111459
@@ -1421,11 +1469,9 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14211469
14221470 opstate_set (res_cfg , ent );
14231471
1424- for (i = 0 ; i < res_cfg -> num_imc ; i ++ ) {
1425- rc = igen6_register_mci (i , mchbar , pdev );
1426- if (rc )
1427- goto fail2 ;
1428- }
1472+ rc = igen6_register_mcis (pdev , mchbar );
1473+ if (rc )
1474+ goto fail ;
14291475
14301476 if (res_cfg -> num_imc > 1 ) {
14311477 rc = igen6_mem_slice_setup (mchbar );
0 commit comments