From nobody Sun Jun 14 14:32:47 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4ED8A3D561; Fri, 3 Apr 2026 05:40:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194860; cv=none; b=Q8XM/OY6pFzM8rM8YOanuFLpfvyZJXw+zp4A5U+nhF04QiZIQ/dl6iclR9t3X4AE8dPmYvH+sIFm9mZmDac2pXLasLeWegQwnjXrqGnZZ8zITbv15VKbuC51Xs+sr+nocoNrl2MtqWhfNKYm9YJw+NkwA2gTpzVqmwbJxoKurmY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194860; c=relaxed/simple; bh=RkpOupTJJ1qPgLpeNk4LFXOI14dn4d3ncD9K3G9P7Vs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LoafvY0KaG1nz/L7BFm+Yr0Pf78xx61EWRnmNYu4A5MAL3+aUG3nSGNyddsRg1e4CoWHUFK/2L8dzHQ7Jad6JSdW/UTC/Xr78XvTippP49W8q6SkzasSF/R8WQuvtL3/qz03qRQI6bVBEWnaMNdhdsQJtUmd0CBme7+n4eeALps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=PlUECgy8; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="PlUECgy8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1775194860; x=1806730860; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RkpOupTJJ1qPgLpeNk4LFXOI14dn4d3ncD9K3G9P7Vs=; b=PlUECgy8vZ3q1yjdDg/M2RbKw8D0hhM8cNrwYwucChpZmBLszlkFZPnV 4UkuRUc2ZxR39HX2SIeFECZQZVN/SpaTtTvTYIRYCBqFTF96joJm4tpEP v3XOYNyaoJFBj1o0pMt5A5MSxQLw0izrHpDRwxhrWVsDl2FVVEarYA0Qq Cacn5mGCMNYrZgjWfGGXGOnJAGbR/NKV7d8B0i32Iapq+KnlbSxjFdBhD XHkJQ0e/aW/PSnMYhxv5P9kcCTCzMo4ULWj8E0eNAdLl7s0VvZd4XOJS6 CAaKCHzVZRb3XUytx0Krt3DHjh3RLBpBVb2rGiqH/jvoRk6MClkJj0yTo w==; X-CSE-ConnectionGUID: J3Cd4yV4QDqIHsbpJodPVQ== X-CSE-MsgGUID: k0bbE7a+QliNv8RGyGerPw== X-IronPort-AV: E=McAfee;i="6800,10657,11747"; a="93843318" X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="93843318" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:40:59 -0700 X-CSE-ConnectionGUID: V62PVMdcSjKaIMiypUI1Ww== X-CSE-MsgGUID: 752fkozRQouNSwSs+I7bhQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="232107099" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:40:57 -0700 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] EDAC/igen6: Fix call trace due to missing release() Date: Fri, 3 Apr 2026 13:40:27 +0800 Message-ID: <20260403054029.3950383-2-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> References: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When unloading the igen6_edac driver, there is a call trace: Device '(null)' does not have a release() function, it is broken and must= be fixed. See Documentation/core-api/kobject.rst. WARNING: drivers/base/core.c:2567 at device_release+0x84/0x90, CPU#5: rmm= od/127209 ... RIP: 0010:device_release+0x84/0x90 Call Trace: kobject_put+0x8c/0x220 put_device+0x17/0x30 igen6_unregister_mcis+0xa2/0xe0 [igen6_edac] igen6_remove+0x82/0xb0 [igen6_edac] ... Fix the call trace by providing empty release() functions for the memory controller devices. Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs usi= ng IBECC") Signed-off-by: Qiuxu Zhuo --- drivers/edac/igen6_edac.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index fcb8ab44cba5..0bf9cf349d0b 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -1296,6 +1296,11 @@ static bool igen6_imc_absent(void __iomem *window) return readl(window + MAD_INTER_CHANNEL_OFFSET) =3D=3D ~0; } =20 +static void imc_release(struct device *dev) +{ + /* Nothing to do, the 'imc' owns the 'dev' and will also release it. */ +} + static int igen6_register_mci(int mc, void __iomem *window, struct pci_dev= *pdev) { struct edac_mc_layer layers[2]; @@ -1334,6 +1339,7 @@ static int igen6_register_mci(int mc, void __iomem *w= indow, struct pci_dev *pdev mci->pvt_info =3D &igen6_pvt->imc[mc]; =20 imc =3D mci->pvt_info; + imc->dev.release =3D imc_release; device_initialize(&imc->dev); /* * EDAC core uses mci->pdev(pointer of structure device) as --=20 2.43.0 From nobody Sun Jun 14 14:32:47 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70EA73D561; Fri, 3 Apr 2026 05:41:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194867; cv=none; b=db0DgTNFytyM3/b4kPBZVdKS7E4hGozx3COUUifsIaytcljuTRMctVjQvkb2hge1ZQMqZpqtx8dE0tDko7uu49vZuE0mJAx7c/Rw7ksjhn9iH7WfLYbVjU4DMZ2u2BY2Qk03U4UNKWjbmF/8Ooc8dXjDUxH8TyUz/mrT6jL+1g0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194867; c=relaxed/simple; bh=a64LgDiyjlraAvMSu64wkN5R6MQly+Qu9YsnY4HZEc4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ABEQGipZX4yBeJITNllHCbFnOrJELu18dCZf+daErvr3ou140CXorfX4B1wuvJjLoiSwYZ7jA1WuNxg2Iq6rpuazQm344RTjnS6GSXJ9PBAdSfiGG3aBYVO9fJPWMxVERV/7Fe0KVDYZ08P+Zg4XGG5acLK/2iF+PlSsbcT3zhw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=HTNwoWvT; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="HTNwoWvT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1775194866; x=1806730866; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=a64LgDiyjlraAvMSu64wkN5R6MQly+Qu9YsnY4HZEc4=; b=HTNwoWvT8ysBwKuMzLl8EmJTeyCZzDLGhZKn+OdBEYFR9xa/XPWdIbc3 PlRJ1bilCsL3MRoRsYwoe7YqwT7ZDQHeiLNhQWUaqdw0up+tWOcS4pzsB q7DEvhiUx6MyJiLe+IjFwaSKVQ77nMkgHW2ukGL/Ly2EnPe/ooq3BB9jy aWB9WIin3M/UTuBLs3B83gn2uqWLxc/+TSdn7JJ+Uyg+JeOwW+M7KEIZ7 UvyGrtwBAnSUpTW039FFOUwr2vbNggwEnx6YMewj7ogAR0dF/1SwZN8FX NC5XoOeCLiTzUY57fHLzx8kcr7cATxdOB2y48/Pn17J/TfLQ06FnSPpQo Q==; X-CSE-ConnectionGUID: i6EFLbJAQcK/ujLt1hv6PQ== X-CSE-MsgGUID: qfbgOEWOS7Kq16rqfE942w== X-IronPort-AV: E=McAfee;i="6800,10657,11747"; a="93843319" X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="93843319" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:41:05 -0700 X-CSE-ConnectionGUID: XD7y7RK4T2qH3mycxRsaHw== X-CSE-MsgGUID: cNc9MQvbRGyCpMgDAfz8RQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="232107127" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:41:03 -0700 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] EDAC/igen6: Fix memory topology parsing for Panther Lake-H SoCs Date: Fri, 3 Apr 2026 13:40:28 +0800 Message-ID: <20260403054029.3950383-3-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> References: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Panther Lake-H SoC memory controller registers for memory topology have been updated, but the current igen6_edac driver still uses old generation ones to incorrectly parse memory topology. Fix the issue by adding memory topology parsing function pointers to the 'struct res_config' and creating a new configuration structure for Panther Lake-H SoCs to enable igen6_edac to parse memory correctly. Fixes: 0be9f1af3902 ("EDAC/igen6: Add Intel Panther Lake-H SoCs support") Fixes: 4c36e6106997 ("EDAC/igen6: Add more Intel Panther Lake-H SoCs suppor= t") Signed-off-by: Qiuxu Zhuo --- drivers/edac/igen6_edac.c | 375 +++++++++++++++++++++++++++++++------- include/linux/edac.h | 3 + 2 files changed, 308 insertions(+), 70 deletions(-) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index 0bf9cf349d0b..f849e3299593 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -122,6 +122,20 @@ #define MEM_SLICE_HASH_MASK(v) (GET_BITFIELD(v, 6, 19) << 6) #define MEM_SLICE_HASH_LSB_MASK_BIT(v) GET_BITFIELD(v, 24, 26) =20 +struct igen6_imc { + int mc; + struct mem_ctl_info *mci; + struct pci_dev *pdev; + struct device dev; + void __iomem *window; + u64 size; + u64 ch_s_size; + int ch_l_map; + u64 dimm_s_size[NUM_CHANNELS]; + u64 dimm_l_size[NUM_CHANNELS]; + int dimm_l_map[NUM_CHANNELS]; +}; + static struct res_config { bool machine_check; /* The number of present memory controllers. */ @@ -134,12 +148,29 @@ static struct res_config { u64 reg_touud_mask; /* IBECC error log */ u64 reg_eccerrlog_addr_mask; + /* MEMSS_PMA_CR registers. */ + u32 reg_mem_config_offset; + u32 reg_mem_config_ddr_type_mask; + /* Memory controller registers. */ + u32 reg_mad_inter_size_mask[NUM_CHANNELS]; + u64 reg_mad_inter_size_granularity; + u32 reg_mad_intra_rank_mask[NUM_DIMMS]; + u32 reg_mad_intra_width_mask[NUM_DIMMS]; + u32 reg_mad_intra_density_mask[NUM_DIMMS]; u32 imc_base; u32 cmf_base; u32 cmf_size; u32 ms_hash_offset; u32 ibecc_base; u32 ibecc_error_log_offset; + /* Get memory type. */ + enum mem_type (*get_mem_type)(struct igen6_imc *imc); + /* Get DRAM chip type. */ + enum dev_type (*get_dev_type)(struct igen6_imc *imc, int chan, int dimm_l= ); + /* Set imc->ch_{s_size,l_map}. */ + void (*set_chan_params)(struct igen6_imc *imc); + /* Set imc->dimm_{l_size,s_size,l_map}[chan]. */ + void (*set_dimm_params)(struct igen6_imc *imc, int chan); bool (*ibecc_available)(struct pci_dev *pdev); /* Extract error address logged in IBECC */ u64 (*err_addr)(u64 ecclog); @@ -149,22 +180,9 @@ static struct res_config { u64 (*err_addr_to_imc_addr)(u64 eaddr, int mc); } *res_cfg; =20 -struct igen6_imc { - int mc; - struct mem_ctl_info *mci; - struct pci_dev *pdev; - struct device dev; - void __iomem *window; - u64 size; - u64 ch_s_size; - int ch_l_map; - u64 dimm_s_size[NUM_CHANNELS]; - u64 dimm_l_size[NUM_CHANNELS]; - int dimm_l_map[NUM_CHANNELS]; -}; - static struct igen6_pvt { struct igen6_imc imc[NUM_IMC]; + void __iomem *memss_pma_cr; u64 ms_hash; u64 ms_s_size; int ms_l_map; @@ -500,6 +518,119 @@ static u64 rpl_p_err_addr(u64 ecclog) return field_get(res_cfg->reg_eccerrlog_addr_mask, ecclog); } =20 +static enum mem_type ptl_h_get_mem_type(struct igen6_imc *imc) +{ + u32 mtype, val; + + val =3D readl(igen6_pvt->memss_pma_cr + res_cfg->reg_mem_config_offset); + mtype =3D field_get(res_cfg->reg_mem_config_ddr_type_mask, val); + + edac_dbg(2, "mtype %u (reg 0x%x)\n", mtype, val); + + switch (mtype) { + case 1: + return MEM_DDR5; + case 2: + return MEM_LPDDR5; + case 3: + return MEM_LPDDR4; + default: + return MEM_UNKNOWN; + } +} + +static enum dev_type ptl_h_get_dev_type(struct igen6_imc *imc, int chan, i= nt dimm) +{ + u32 width, val; + + val =3D readl(imc->window + MAD_INTRA_CH0_OFFSET + chan * 4); + width =3D field_get(res_cfg->reg_mad_intra_width_mask[dimm], val); + + switch (width) { + case 1: + return DEV_X8; + default: + return DEV_X16; + } +} + +static u64 ptl_h_get_chan_size(struct igen6_imc *imc, int chan) +{ + u32 val =3D readl(imc->window + MAD_INTER_CHANNEL_OFFSET); + + return field_get(res_cfg->reg_mad_inter_size_mask[chan], val) * + res_cfg->reg_mad_inter_size_granularity; +} + +static u64 ptl_h_get_dimm_size(struct igen6_imc *imc, int chan, int dimm) +{ + u32 val =3D readl(imc->window + MAD_INTRA_CH0_OFFSET + chan * 4); + u32 ranks =3D 1 << field_get(res_cfg->reg_mad_intra_rank_mask[dimm], val); + /* DRAM device density in Gb */ + u64 density =3D field_get(res_cfg->reg_mad_intra_density_mask[dimm], val)= * 4; + + enum mem_type mtype =3D ptl_h_get_mem_type(imc); + enum dev_type dtype =3D ptl_h_get_dev_type(imc, chan, dimm); + u64 sub_ch_width, dev_num; + + switch (mtype) { + case MEM_DDR5: + sub_ch_width =3D 32; + break; + case MEM_LPDDR5: + case MEM_LPDDR4: + sub_ch_width =3D 16; + break; + default: + sub_ch_width =3D 0; + } + + switch (dtype) { + case DEV_X8: + dev_num =3D sub_ch_width / 8; + break; + case DEV_X16: + dev_num =3D sub_ch_width / 16; + break; + default: + dev_num =3D 0; + } + + edac_dbg(2, "ranks %d, density %lluGb, sub_ch_width %llu, dev_num %llu (r= eg 0x%x)\n", ranks, density, sub_ch_width, dev_num, val); + + return ((dev_num * density / 8) * ranks) << 30; +} + +static void ptl_h_set_chan_params(struct igen6_imc *imc) +{ + u64 ch0_size =3D ptl_h_get_chan_size(imc, 0); + u64 ch1_size =3D ptl_h_get_chan_size(imc, 1); + + if (ch0_size <=3D ch1_size) { + imc->ch_s_size =3D ch0_size; + imc->ch_l_map =3D 1; + } else { + imc->ch_s_size =3D ch1_size; + imc->ch_l_map =3D 0; + } +} + +static void ptl_h_set_dimm_params(struct igen6_imc *imc, int chan) +{ + u64 dimm0_size =3D ptl_h_get_dimm_size(imc, chan, 0); + u64 dimm1_size =3D ptl_h_get_dimm_size(imc, chan, 1); + + if (dimm0_size <=3D dimm1_size) { + imc->dimm_s_size[chan] =3D dimm0_size; + imc->dimm_l_size[chan] =3D dimm1_size; + imc->dimm_l_map[chan] =3D 1; + } else { + imc->dimm_s_size[chan] =3D dimm1_size; + imc->dimm_l_size[chan] =3D dimm0_size; + imc->dimm_l_map[chan] =3D 0; + } +} + static struct res_config ehl_cfg =3D { .num_imc =3D 1, .reg_mchbar_mask =3D GENMASK_ULL(38, 16), @@ -622,6 +753,36 @@ static struct res_config mtl_p_cfg =3D { .err_addr_to_imc_addr =3D adl_err_addr_to_imc_addr, }; =20 +static struct res_config ptl_h_cfg =3D { + .machine_check =3D true, + .num_imc =3D 2, + .reg_mchbar_mask =3D GENMASK_ULL(41, 17), + .reg_tom_mask =3D GENMASK_ULL(41, 20), + .reg_touud_mask =3D GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask =3D GENMASK_ULL(38, 5), + .reg_mem_config_offset =3D 0x13d04, + .reg_mem_config_ddr_type_mask =3D GENMASK(8, 6), + .reg_mad_inter_size_mask[0] =3D GENMASK(15, 8), + .reg_mad_inter_size_mask[1] =3D GENMASK(23, 16), + .reg_mad_inter_size_granularity =3D BIT_ULL(29), + .reg_mad_intra_rank_mask[0] =3D BIT(7), + .reg_mad_intra_rank_mask[1] =3D BIT(15), + .reg_mad_intra_width_mask[0] =3D BIT(6), + .reg_mad_intra_width_mask[1] =3D BIT(14), + .reg_mad_intra_density_mask[0] =3D GENMASK(3, 0), + .reg_mad_intra_density_mask[1] =3D GENMASK(11, 8), + .imc_base =3D 0xd800, + .ibecc_base =3D 0xd400, + .ibecc_error_log_offset =3D 0x170, + .get_mem_type =3D ptl_h_get_mem_type, + .get_dev_type =3D ptl_h_get_dev_type, + .set_chan_params =3D ptl_h_set_chan_params, + .set_dimm_params =3D ptl_h_set_dimm_params, + .ibecc_available =3D mtl_p_ibecc_available, + .err_addr_to_sys_addr =3D adl_err_addr_to_sys_addr, + .err_addr_to_imc_addr =3D adl_err_addr_to_imc_addr, +}; + static struct res_config wcl_cfg =3D { .machine_check =3D true, .num_imc =3D 1, @@ -689,46 +850,34 @@ static struct pci_device_id igen6_pci_tbl[] =3D { { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU1), (kernel_ulong_t)&mtl_p_cfg }, { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU2), (kernel_ulong_t)&mtl_p_cfg }, { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU3), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU4), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU5), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU6), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU7), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU8), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU9), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU10), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU11), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU12), (kernel_ulong_t)&mtl_p_cfg }, - { PCI_VDEVICE(INTEL, DID_PTL_H_SKU13), (kernel_ulong_t)&mtl_p_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU4), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU5), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU6), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU7), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU8), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU9), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU10), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU11), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU12), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU13), (kernel_ulong_t)&ptl_h_cfg }, { PCI_VDEVICE(INTEL, DID_WCL_SKU1), (kernel_ulong_t)&wcl_cfg }, { }, }; MODULE_DEVICE_TABLE(pci, igen6_pci_tbl); =20 -static enum dev_type get_width(int dimm_l, u32 mad_dimm) +static enum mem_type get_mem_type(struct igen6_imc *imc) { - u32 w =3D dimm_l ? MAD_DIMM_CH_DLW(mad_dimm) : - MAD_DIMM_CH_DSW(mad_dimm); + u32 val; =20 - switch (w) { - case 0: - return DEV_X8; - case 1: - return DEV_X16; - case 2: - return DEV_X32; - default: - return DEV_UNKNOWN; - } -} + if (res_cfg->get_mem_type) + return res_cfg->get_mem_type(imc); =20 -static enum mem_type get_memory_type(u32 mad_inter) -{ - u32 t =3D MAD_INTER_CHANNEL_DDR_TYPE(mad_inter); + val =3D readl(imc->window + MAD_INTER_CHANNEL_OFFSET); =20 - switch (t) { + switch (MAD_INTER_CHANNEL_DDR_TYPE(val)) { case 0: return MEM_DDR4; case 1: @@ -744,6 +893,73 @@ static enum mem_type get_memory_type(u32 mad_inter) } } =20 +static bool large_dimm(struct igen6_imc *imc, int chan, int dimm) +{ + return dimm =3D=3D imc->dimm_l_map[chan]; +} + +static enum dev_type get_dev_type(struct igen6_imc *imc, int chan, int dim= m) +{ + u32 width, val; + + if (res_cfg->get_dev_type) + return res_cfg->get_dev_type(imc, chan, dimm); + + val =3D readl(imc->window + MAD_DIMM_CH0_OFFSET + chan * 4); + width =3D large_dimm(imc, chan, dimm) ? MAD_DIMM_CH_DLW(val) : + MAD_DIMM_CH_DSW(val); + + switch (width) { + case 0: + return DEV_X8; + case 1: + return DEV_X16; + case 2: + return DEV_X32; + default: + return DEV_UNKNOWN; + } +} + +static u64 get_dimm_size(struct igen6_imc *imc, int chan, int dimm) +{ + if (large_dimm(imc, chan, dimm)) + return imc->dimm_l_size[chan]; + + return imc->dimm_s_size[chan]; +} + +static void set_chan_params(struct igen6_imc *imc) +{ + u32 val; + + if (res_cfg->set_chan_params) { + res_cfg->set_chan_params(imc); + return; + } + + val =3D readl(imc->window + MAD_INTER_CHANNEL_OFFSET); + imc->ch_s_size =3D MAD_INTER_CHANNEL_CH_S_SIZE(val); + imc->ch_l_map =3D MAD_INTER_CHANNEL_CH_L_MAP(val); +} + +static void set_dimm_params(struct igen6_imc *imc, int chan) +{ + u32 val; + + if (res_cfg->set_dimm_params) { + res_cfg->set_dimm_params(imc, chan); + return; + } + + val =3D readl(imc->window + MAD_INTRA_CH0_OFFSET + chan * 4); + imc->dimm_l_map[chan] =3D MAD_INTRA_CH_DIMM_L_MAP(val); + + val =3D readl(imc->window + MAD_DIMM_CH0_OFFSET + chan * 4); + imc->dimm_l_size[chan] =3D MAD_DIMM_CH_DIMM_L_SIZE(val); + imc->dimm_s_size[chan] =3D MAD_DIMM_CH_DIMM_S_SIZE(val); +} + static int decode_chan_idx(u64 addr, u64 mask, int intlv_bit) { u64 hash_addr =3D addr & mask, hash =3D 0; @@ -1084,7 +1300,6 @@ static bool igen6_check_ecc(struct igen6_imc *imc) static int igen6_get_dimm_config(struct mem_ctl_info *mci) { struct igen6_imc *imc =3D mci->pvt_info; - u32 mad_inter, mad_intra, mad_dimm; int i, j, ndimms, mc =3D imc->mc; struct dimm_info *dimm; enum mem_type mtype; @@ -1094,33 +1309,20 @@ static int igen6_get_dimm_config(struct mem_ctl_inf= o *mci) =20 edac_dbg(2, "\n"); =20 - mad_inter =3D readl(imc->window + MAD_INTER_CHANNEL_OFFSET); - mtype =3D get_memory_type(mad_inter); + mtype =3D get_mem_type(imc); ecc =3D igen6_check_ecc(imc); - imc->ch_s_size =3D MAD_INTER_CHANNEL_CH_S_SIZE(mad_inter); - imc->ch_l_map =3D MAD_INTER_CHANNEL_CH_L_MAP(mad_inter); + set_chan_params(imc); =20 for (i =3D 0; i < NUM_CHANNELS; i++) { - mad_intra =3D readl(imc->window + MAD_INTRA_CH0_OFFSET + i * 4); - mad_dimm =3D readl(imc->window + MAD_DIMM_CH0_OFFSET + i * 4); - - imc->dimm_l_size[i] =3D MAD_DIMM_CH_DIMM_L_SIZE(mad_dimm); - imc->dimm_s_size[i] =3D MAD_DIMM_CH_DIMM_S_SIZE(mad_dimm); - imc->dimm_l_map[i] =3D MAD_INTRA_CH_DIMM_L_MAP(mad_intra); + set_dimm_params(imc, i); imc->size +=3D imc->dimm_s_size[i]; imc->size +=3D imc->dimm_l_size[i]; ndimms =3D 0; =20 for (j =3D 0; j < NUM_DIMMS; j++) { dimm =3D edac_get_dimm(mci, i, j, 0); - - if (j ^ imc->dimm_l_map[i]) { - dtype =3D get_width(0, mad_dimm); - dsize =3D imc->dimm_s_size[i]; - } else { - dtype =3D get_width(1, mad_dimm); - dsize =3D imc->dimm_l_size[i]; - } + dtype =3D get_dev_type(imc, i, j); + dsize =3D get_dimm_size(imc, i, j); =20 if (!dsize) continue; @@ -1223,6 +1425,39 @@ static void igen6_debug_setup(void) {} static void igen6_debug_teardown(void) {} #endif =20 +static struct igen6_pvt *igen6_pvt_setup(struct pci_dev *pdev) +{ + void __iomem *memss_pma_cr; + struct igen6_pvt *pvt; + u64 mchbar; + int rc; + + pvt =3D kzalloc_obj(*igen6_pvt); + if (!pvt) + return NULL; + + rc =3D get_mchbar(pdev, &mchbar); + if (rc) { + kfree(pvt); + return NULL; + } + + memss_pma_cr =3D ioremap(mchbar, MCHBAR_SIZE * 2); + if (!memss_pma_cr) { + kfree(pvt); + return NULL; + } + pvt->memss_pma_cr =3D memss_pma_cr; + + return pvt; +} + +static void igen6_pvt_release(struct igen6_pvt *pvt) +{ + iounmap(pvt->memss_pma_cr); + kfree(pvt); +} + static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) { union { @@ -1555,12 +1790,12 @@ static int igen6_probe(struct pci_dev *pdev, const = struct pci_device_id *ent) =20 edac_dbg(2, "\n"); =20 - igen6_pvt =3D kzalloc_obj(*igen6_pvt); - if (!igen6_pvt) - return -ENOMEM; - res_cfg =3D (struct res_config *)ent->driver_data; =20 + igen6_pvt =3D igen6_pvt_setup(pdev); + if (!igen6_pvt) + return -ENOMEM; + rc =3D igen6_pci_setup(pdev, &mchbar); if (rc) goto fail; @@ -1609,7 +1844,7 @@ static int igen6_probe(struct pci_dev *pdev, const st= ruct pci_device_id *ent) fail2: igen6_unregister_mcis(); fail: - kfree(igen6_pvt); + igen6_pvt_release(igen6_pvt); return rc; } =20 @@ -1624,7 +1859,7 @@ static void igen6_remove(struct pci_dev *pdev) flush_work(&ecclog_work); gen_pool_destroy(ecclog_pool); igen6_unregister_mcis(); - kfree(igen6_pvt); + igen6_pvt_release(igen6_pvt); } =20 static struct pci_driver igen6_driver =3D { diff --git a/include/linux/edac.h b/include/linux/edac.h index fa32f2aca22f..2a3511b0ad1c 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -184,6 +184,7 @@ static inline char *mc_event_error_type(const unsigned = int err_type) * @MEM_DDR5: Unbuffered DDR5 RAM * @MEM_RDDR5: Registered DDR5 RAM * @MEM_LRDDR5: Load-Reduced DDR5 memory. + * @MEM_LPDDR5: Low-Power DDR5 memory. * @MEM_NVDIMM: Non-volatile RAM * @MEM_WIO2: Wide I/O 2. * @MEM_HBM2: High bandwidth Memory Gen 2. @@ -216,6 +217,7 @@ enum mem_type { MEM_DDR5, MEM_RDDR5, MEM_LRDDR5, + MEM_LPDDR5, MEM_NVDIMM, MEM_WIO2, MEM_HBM2, @@ -247,6 +249,7 @@ enum mem_type { #define MEM_FLAG_DDR5 BIT(MEM_DDR5) #define MEM_FLAG_RDDR5 BIT(MEM_RDDR5) #define MEM_FLAG_LRDDR5 BIT(MEM_LRDDR5) +#define MEM_FLAG_LPDDR5 BIT(MEM_LPDDR5) #define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM) #define MEM_FLAG_WIO2 BIT(MEM_WIO2) #define MEM_FLAG_HBM2 BIT(MEM_HBM2) --=20 2.43.0 From nobody Sun Jun 14 14:32:47 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35D763590C3; Fri, 3 Apr 2026 05:41:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194870; cv=none; b=HAmwYbhTq4s7/iNh3vM3DFTrMR+orjhHwt0sJ9nWMzlUH3Oa43hqHiCpV4LYTr0UWd06uZfj1aAm8AIWiyJ62EPYEGuMVP29Yn907XXffMCkr4botbV43DztQGNdcIRchxJtOZXKQzZL9PJQSyqgZoxVEXmFHNN9ru7o1qTfZsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775194870; c=relaxed/simple; bh=MB8LpTgltQ79fr6/u/BNsW/xHPCWfLL30JTUJDWadWc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ReKP9rHb+ydXvODTfLUOwRUf2qpgpQOVLRDt56jJCTdl8OrxZSAo9i+rJOdhPLBbjwzMmgyc4KK8I/87IgtPFkYjCwfsZsT/KuNSPSidNaZKCxldaxPD/CbDdkl0i6mo7BF41mYXyijum+6JDhfaPxO8pQHmwxlyAZUKzZIrdEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=YwDDO8oQ; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="YwDDO8oQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1775194869; x=1806730869; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MB8LpTgltQ79fr6/u/BNsW/xHPCWfLL30JTUJDWadWc=; b=YwDDO8oQ7nkFmD8bOLo1FTKydEfwK+2ZOf5ENKHb2bsTrumKlJLQmLbh FNOtTFbnCKGm4cGKfh4z8S3h61paeGJX/dpDNe23YrUIDrOdXJ7+t0aZj 4Yo7vVdQhG9K3uZlMmtZbFr1LYM9gh16SI4M1YdtaWmPQjv4u08WQ4OSH x7k6y5kU1o3ANiaRC02y843mIlosAEpR+SZP1OP7Yw+v7Fj63Jw2r+bQ4 2y7suTrGIZpNxXYmclItu3UsRBd/s0KFbnumdnLQjQkyIGJk94RCZcRb3 Ko5CP6+D8vrIy96COSpR6YHW4d+eoq1L4rzPeRdMRyRFXNLZnOIPGmOvW A==; X-CSE-ConnectionGUID: Mm/C80EXShW8C9bbrCJanA== X-CSE-MsgGUID: pYaJtmWvSmeVCP9m22wHXQ== X-IronPort-AV: E=McAfee;i="6800,10657,11747"; a="93843322" X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="93843322" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:41:09 -0700 X-CSE-ConnectionGUID: n2i5q1sYTIuIahm3pEZ4GQ== X-CSE-MsgGUID: nD5XEq7+SvWpZXD8tvmprg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,157,1770624000"; d="scan'208";a="232107130" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Apr 2026 22:41:08 -0700 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] EDAC/igen6: Add one Intel Panther Lake-H SoC support Date: Fri, 3 Apr 2026 13:40:29 +0800 Message-ID: <20260403054029.3950383-4-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> References: <20260403054029.3950383-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add one Intel Panther Lake-H SoC compute die ID for EDAC support. Signed-off-by: Qiuxu Zhuo --- drivers/edac/igen6_edac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index f849e3299593..f3e53d63eb54 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -309,6 +309,7 @@ static struct work_struct ecclog_work; #define DID_PTL_H_SKU11 0xb028 #define DID_PTL_H_SKU12 0xb029 #define DID_PTL_H_SKU13 0xb02a +#define DID_PTL_H_SKU14 0xb00a =20 /* Compute die IDs for Wildcat Lake with IBECC */ #define DID_WCL_SKU1 0xfd00 @@ -863,6 +864,7 @@ static struct pci_device_id igen6_pci_tbl[] =3D { { PCI_VDEVICE(INTEL, DID_PTL_H_SKU11), (kernel_ulong_t)&ptl_h_cfg }, { PCI_VDEVICE(INTEL, DID_PTL_H_SKU12), (kernel_ulong_t)&ptl_h_cfg }, { PCI_VDEVICE(INTEL, DID_PTL_H_SKU13), (kernel_ulong_t)&ptl_h_cfg }, + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU14), (kernel_ulong_t)&ptl_h_cfg }, { PCI_VDEVICE(INTEL, DID_WCL_SKU1), (kernel_ulong_t)&wcl_cfg }, { }, }; --=20 2.43.0