1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Xilinx TMR Inject IP.
5 * Copyright (C) 2022 Advanced Micro Devices, Inc.
8 * This driver is developed for TMR Inject IP,The Triple Modular Redundancy(TMR)
9 * Inject provides fault injection.
12 #include <asm/xilinx_mb_manager.h>
13 #include <linux/module.h>
15 #include <linux/debugfs.h>
16 #include <linux/platform_device.h>
17 #include <linux/fault-inject.h>
19 /* TMR Inject Register offsets */
20 #define XTMR_INJECT_CR_OFFSET 0x0
21 #define XTMR_INJECT_AIR_OFFSET 0x4
22 #define XTMR_INJECT_IIR_OFFSET 0xC
23 #define XTMR_INJECT_EAIR_OFFSET 0x10
24 #define XTMR_INJECT_ERR_OFFSET 0x204
26 /* Register Bitmasks/shifts */
27 #define XTMR_INJECT_CR_CPUID_SHIFT 8
28 #define XTMR_INJECT_CR_IE_SHIFT 10
29 #define XTMR_INJECT_IIR_ADDR_MASK GENMASK(31, 16)
31 #define XTMR_INJECT_MAGIC_MAX_VAL 255
34 * struct xtmr_inject_dev - Driver data for TMR Inject
35 * @regs: device physical base address
36 * @magic: Magic hardware configuration value
38 struct xtmr_inject_dev
{
43 static DECLARE_FAULT_ATTR(inject_fault
);
44 static char *inject_request
;
45 module_param(inject_request
, charp
, 0);
46 MODULE_PARM_DESC(inject_request
, "default fault injection attributes");
47 static struct dentry
*dbgfs_root
;
50 static inline void xtmr_inject_write(struct xtmr_inject_dev
*xtmr_inject
,
53 iowrite32(value
, xtmr_inject
->regs
+ addr
);
56 static inline u32
xtmr_inject_read(struct xtmr_inject_dev
*xtmr_inject
,
59 return ioread32(xtmr_inject
->regs
+ addr
);
62 static int xtmr_inject_set(void *data
, u64 val
)
70 DEFINE_DEBUGFS_ATTRIBUTE(xtmr_inject_fops
, NULL
, xtmr_inject_set
, "%llu\n");
72 static void xtmr_init_debugfs(struct xtmr_inject_dev
*xtmr_inject
)
76 dbgfs_root
= debugfs_create_dir("xtmr_inject", NULL
);
77 dir
= fault_create_debugfs_attr("inject_fault", dbgfs_root
,
79 debugfs_create_file("inject_fault", 0200, dir
, NULL
,
83 static void xtmr_inject_init(struct xtmr_inject_dev
*xtmr_inject
)
88 setup_fault_attr(&inject_fault
, inject_request
);
89 /* Allow fault injection */
90 cr_val
= xtmr_inject
->magic
|
91 (1 << XTMR_INJECT_CR_IE_SHIFT
) |
92 (1 << XTMR_INJECT_CR_CPUID_SHIFT
);
93 xtmr_inject_write(xtmr_inject
, XTMR_INJECT_CR_OFFSET
,
95 /* Initialize the address inject and instruction inject registers */
96 xtmr_inject_write(xtmr_inject
, XTMR_INJECT_AIR_OFFSET
,
97 XMB_INJECT_ERR_OFFSET
);
98 xtmr_inject_write(xtmr_inject
, XTMR_INJECT_IIR_OFFSET
,
99 XMB_INJECT_ERR_OFFSET
& XTMR_INJECT_IIR_ADDR_MASK
);
103 * xtmr_inject_probe - Driver probe function
104 * @pdev: Pointer to the platform_device structure
106 * This is the driver probe routine. It does all the memory
107 * allocation for the device.
109 * Return: 0 on success and failure value on error
111 static int xtmr_inject_probe(struct platform_device
*pdev
)
113 struct xtmr_inject_dev
*xtmr_inject
;
116 xtmr_inject
= devm_kzalloc(&pdev
->dev
, sizeof(*xtmr_inject
),
121 xtmr_inject
->regs
= devm_platform_ioremap_resource(pdev
, 0);
122 if (IS_ERR(xtmr_inject
->regs
))
123 return PTR_ERR(xtmr_inject
->regs
);
125 err
= of_property_read_u32(pdev
->dev
.of_node
, "xlnx,magic",
126 &xtmr_inject
->magic
);
128 dev_err(&pdev
->dev
, "unable to read xlnx,magic property");
132 if (xtmr_inject
->magic
> XTMR_INJECT_MAGIC_MAX_VAL
) {
133 dev_err(&pdev
->dev
, "invalid xlnx,magic property value");
137 /* Initialize TMR Inject */
138 xtmr_inject_init(xtmr_inject
);
140 xtmr_init_debugfs(xtmr_inject
);
142 platform_set_drvdata(pdev
, xtmr_inject
);
147 static void xtmr_inject_remove(struct platform_device
*pdev
)
149 debugfs_remove_recursive(dbgfs_root
);
153 static const struct of_device_id xtmr_inject_of_match
[] = {
155 .compatible
= "xlnx,tmr-inject-1.0",
157 { /* end of table */ }
159 MODULE_DEVICE_TABLE(of
, xtmr_inject_of_match
);
161 static struct platform_driver xtmr_inject_driver
= {
163 .name
= "xilinx-tmr_inject",
164 .of_match_table
= xtmr_inject_of_match
,
166 .probe
= xtmr_inject_probe
,
167 .remove
= xtmr_inject_remove
,
169 module_platform_driver(xtmr_inject_driver
);
170 MODULE_AUTHOR("Advanced Micro Devices, Inc");
171 MODULE_DESCRIPTION("Xilinx TMR Inject Driver");
172 MODULE_LICENSE("GPL");