Lines Matching +full:fault +full:- +full:log +full:- +full:enable

1 // SPDX-License-Identifier: GPL-2.0
51 /* Fault injection data and count registers */
70 #define EDAC_DEVICE "ZynqMP-OCM"
73 * struct ecc_error_info - ECC error log information
74 * @addr: Fault generated at this address
75 * @fault_lo: Generated fault data (lower 32-bit)
76 * @fault_hi: Generated fault data (upper 32-bit)
85 * struct ecc_status - ECC status information to report
88 * @ceinfo: Correctable error log information
89 * @ueinfo: Uncorrectable error log information
99 * struct edac_priv - OCM private instance data
108 * @fault_injection_cnt: Fault Injection Counter value
125 * get_error_info - Get the current ECC error info
136 p->ce_cnt++; in get_error_info()
137 p->ceinfo.fault_lo = readl(base + CE_FFD0_OFST); in get_error_info()
138 p->ceinfo.fault_hi = readl(base + CE_FFD1_OFST); in get_error_info()
139 p->ceinfo.addr = (OCM_BASEVAL | readl(base + CE_FFA_OFST)); in get_error_info()
142 p->ue_cnt++; in get_error_info()
143 p->ueinfo.fault_lo = readl(base + UE_FFD0_OFST); in get_error_info()
144 p->ueinfo.fault_hi = readl(base + UE_FFD1_OFST); in get_error_info()
145 p->ueinfo.addr = (OCM_BASEVAL | readl(base + UE_FFA_OFST)); in get_error_info()
151 * handle_error - Handle error types CE and UE
159 struct edac_priv *priv = dci->pvt_info; in handle_error()
162 if (p->ce_cnt) { in handle_error()
163 pinf = &p->ceinfo; in handle_error()
164 snprintf(priv->message, ZYNQMP_OCM_EDAC_MSG_SIZE, in handle_error()
166 "CE", pinf->addr, pinf->fault_hi, pinf->fault_lo); in handle_error()
167 edac_device_handle_ce(dci, 0, 0, priv->message); in handle_error()
170 if (p->ue_cnt) { in handle_error()
171 pinf = &p->ueinfo; in handle_error()
172 snprintf(priv->message, ZYNQMP_OCM_EDAC_MSG_SIZE, in handle_error()
174 "UE", pinf->addr, pinf->fault_hi, pinf->fault_lo); in handle_error()
175 edac_device_handle_ue(dci, 0, 0, priv->message); in handle_error()
182 * intr_handler - ISR routine
191 struct edac_priv *priv = dci->pvt_info; in intr_handler()
194 regval = readl(priv->baseaddr + OCM_ISR_OFST); in intr_handler()
200 get_error_info(priv->baseaddr, &priv->stat, regval); in intr_handler()
202 priv->ce_cnt += priv->stat.ce_cnt; in intr_handler()
203 priv->ue_cnt += priv->stat.ue_cnt; in intr_handler()
204 handle_error(dci, &priv->stat); in intr_handler()
210 * get_eccstate - Return the ECC status
213 * Get the ECC enable/disable status
224 * write_fault_count - write fault injection count
227 * Update the fault injection count register, once the counter reaches
232 u32 ficount = priv->fault_injection_cnt; in write_fault_count()
237 "Fault injection count value truncated to %d\n", ficount); in write_fault_count()
240 writel(ficount, priv->baseaddr + OCM_FIC_OFST); in write_fault_count()
245 * - Setup the optional Fault Injection Count:
247 * - Write the Correctable Error bit position value:
253 struct edac_device_ctl_info *edac_dev = file->private_data; in inject_ce_write()
254 struct edac_priv *priv = edac_dev->pvt_info; in inject_ce_write()
258 return -EFAULT; in inject_ce_write()
260 ret = kstrtou8_from_user(data, count, 0, &priv->ce_bitpos); in inject_ce_write()
264 if (priv->ce_bitpos > UE_MAX_BITPOS_UPPER) in inject_ce_write()
265 return -EINVAL; in inject_ce_write()
267 if (priv->ce_bitpos <= UE_MAX_BITPOS_LOWER) { in inject_ce_write()
268 writel(BIT(priv->ce_bitpos), priv->baseaddr + OCM_FID0_OFST); in inject_ce_write()
269 writel(0, priv->baseaddr + OCM_FID1_OFST); in inject_ce_write()
271 writel(BIT(priv->ce_bitpos - UE_MIN_BITPOS_UPPER), in inject_ce_write()
272 priv->baseaddr + OCM_FID1_OFST); in inject_ce_write()
273 writel(0, priv->baseaddr + OCM_FID0_OFST); in inject_ce_write()
289 * - Setup the optional Fault Injection Count:
291 * - Write the Uncorrectable Error bit position values:
297 struct edac_device_ctl_info *edac_dev = file->private_data; in inject_ue_write()
298 struct edac_priv *priv = edac_dev->pvt_info; in inject_ue_write()
305 return -EFAULT; in inject_ue_write()
309 return -EFAULT; in inject_ue_write()
316 ret = kstrtou8(token[0], 0, &priv->ue_bitpos[0]); in inject_ue_write()
320 ret = kstrtou8(token[1], 0, &priv->ue_bitpos[1]); in inject_ue_write()
324 if (priv->ue_bitpos[0] > UE_MAX_BITPOS_UPPER || in inject_ue_write()
325 priv->ue_bitpos[1] > UE_MAX_BITPOS_UPPER) in inject_ue_write()
326 return -EINVAL; in inject_ue_write()
328 if (priv->ue_bitpos[0] == priv->ue_bitpos[1]) { in inject_ue_write()
330 return -EINVAL; in inject_ue_write()
333 ue_bitpos = BIT(priv->ue_bitpos[0]) | BIT(priv->ue_bitpos[1]); in inject_ue_write()
335 writel((u32)ue_bitpos, priv->baseaddr + OCM_FID0_OFST); in inject_ue_write()
336 writel((u32)(ue_bitpos >> 32), priv->baseaddr + OCM_FID1_OFST); in inject_ue_write()
351 struct edac_priv *priv = edac_dev->pvt_info; in setup_debugfs()
353 priv->debugfs_dir = edac_debugfs_create_dir("ocm"); in setup_debugfs()
354 if (!priv->debugfs_dir) in setup_debugfs()
357 edac_debugfs_create_x32("inject_fault_count", 0644, priv->debugfs_dir, in setup_debugfs()
358 &priv->fault_injection_cnt); in setup_debugfs()
359 edac_debugfs_create_file("inject_ue_bitpos", 0644, priv->debugfs_dir, in setup_debugfs()
361 edac_debugfs_create_file("inject_ce_bitpos", 0644, priv->debugfs_dir, in setup_debugfs()
380 return -ENXIO; in edac_probe()
387 return -ENOMEM; in edac_probe()
389 priv = dci->pvt_info; in edac_probe()
391 dci->dev = &pdev->dev; in edac_probe()
392 priv->baseaddr = baseaddr; in edac_probe()
393 dci->mod_name = pdev->dev.driver->name; in edac_probe()
394 dci->ctl_name = ZYNQMP_OCM_EDAC_STRING; in edac_probe()
395 dci->dev_name = dev_name(&pdev->dev); in edac_probe()
403 ret = devm_request_irq(&pdev->dev, irq, intr_handler, 0, in edac_probe()
404 dev_name(&pdev->dev), dci); in edac_probe()
410 /* Enable UE, CE interrupts */ in edac_probe()
411 writel((OCM_CEINTR_MASK | OCM_UEINTR_MASK), priv->baseaddr + OCM_IEN_OFST); in edac_probe()
432 struct edac_priv *priv = dci->pvt_info; in edac_remove()
435 writel((OCM_CEINTR_MASK | OCM_UEINTR_MASK), priv->baseaddr + OCM_IDS_OFST); in edac_remove()
438 debugfs_remove_recursive(priv->debugfs_dir); in edac_remove()
441 edac_device_del_device(&pdev->dev); in edac_remove()
446 { .compatible = "xlnx,zynqmp-ocmc-1.0"},
454 .name = "zynqmp-ocm-edac",