废话不多说,直接贴上代码,在代码里面解释具体的步骤:
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <soc/imx8/sc/sci.h>
#define IMX8QXP_FUSE_UUID_WORD0 0x10
#define IMX8QXP_FUSE_UUID_WORD1 0x11
static uint32_t val = 0;
static struct kobject *k_obj = NULL;
static uint32_t imx8qxp_get__UID_from_fuse(int add)
{
uint32_t mu_id;
sc_ipc_t ipc_handle;
sc_err_t sc_err = SC_ERR_NONE;
uint32_t val = 0;
uint32_t word;
sc_err = sc_ipc_getMuID(&mu_id);
if (sc_err != SC_ERR_NONE) {
pr_err("FEC MAC fuse: Get MU ID failed\n");
return;
}
sc_err = sc_ipc_open(&ipc_handle, mu_id);
if (sc_err != SC_ERR_NONE) {
pr_err("FEC MAC fuse: Open MU channel failed\n");
return;
}
word = add;
sc_err = sc_misc_otp_fuse_read(ipc_handle, word, &val);//调用函数读取地址存的信息
if (sc_err != SC_ERR_NONE) {
pr_err("FEC UUID fuse %d read error: %d\n", word, sc_err);
sc_ipc_close(ipc_handle);
return;
}
return val;
}
static ssize_t sysfs_demo_show_node_one(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{
return sprintf(buf, "%s: %s\n", attr->attr.name, imx8qxp_get__UID_from_fuse(IMX8QXP_FUSE_UUID_WORD0));
}
static ssize_t sysfs_demo_show_node_two(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{
return sprintf(buf, "%s: %s\n", attr->attr.name,imx8qxp_get__UID_from_fuse(IMX8QXP_FUSE_UUID_WORD1));
}
static struct kobj_attribute node_one_attribute = //创建的文件的信息
__ATTR(HW_OCOTP_CFG0, S_IWUSR|S_IRUGO, sysfs_demo_show_node_one, NULL);
static struct kobj_attribute node_two_attribute =//创建的文件的信息
__ATTR(HW_OCOTP_CFG1, S_IWUSR|S_IRUGO, sysfs_demo_show_node_two, NULL);
static struct attribute *sysfs_demo_attributes[] = {
&node_one_attribute.attr,
&node_two_attribute.attr,
NULL
};
static const struct attribute_group sysfs_demo_attr_group = {
.attrs = sysfs_demo_attributes,
};
static int __init sysfs_demo_init(void)
{
if ((k_obj = kobject_create_and_add("fsl_otp", NULL)) == NULL ) {//创建fsl_otp目录
pr_err("fsl_otp sys node create error \n");
goto out;
}
if(sysfs_create_group(k_obj, &sysfs_demo_attr_group) ) {//在建好的目录下创建文件
pr_err("sysfs_create_group failed\n");
goto out2;
}
pr_info("enter.\n");
return 0;
out2:
kobject_put(k_obj);
out:
return -1;
}
module_init(sysfs_demo_init); //函数入口
static void __exit sysfs_demo_exit(void)
{
pr_info("enter.\n");
if (k_obj) {
sysfs_remove_group(k_obj, &sysfs_demo_attr_group);
kobject_put(k_obj);
}
}
module_exit(sysfs_demo_exit);
MODULE_LICENSE("GPL");