/* * Copyright (c) 2020 Samsung Electronics Co., Ltd. * http://www.samsung.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char *soc_ap_id; static const char * __init chip_id_to_name(void) { const char *soc_name; soc_name = of_flat_dt_get_machine_name(); return soc_name; } #define UNIQUE_ID_LEN 16 static char uniqueid_str[UNIQUE_ID_LEN+1]; static char nf_str[10] = "not found"; static char *uniqueid_get(void) { char *src_ptr = strstr(saved_command_line, "uniqueno="); if (src_ptr == NULL) return nf_str; strncpy(uniqueid_str, src_ptr + strlen("uniqueno="), UNIQUE_ID_LEN); uniqueid_str[UNIQUE_ID_LEN] = '\0'; return uniqueid_str; } static struct bus_type chipid_subsys = { .name = "chip-id", .dev_name = "chip-id", }; static ssize_t chipid_ap_id_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return snprintf(buf, 15, "%s\n", soc_ap_id); } static ssize_t chipid_unique_id_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return snprintf(buf, 20, "%s\n", uniqueid_get()); } static struct kobj_attribute chipid_ap_id_attr = __ATTR(ap_id, 0644, chipid_ap_id_show, NULL); static struct kobj_attribute chipid_unique_id_attr = __ATTR(unique_id, 0644, chipid_unique_id_show, NULL); static struct attribute *chipid_sysfs_attrs[] = { &chipid_ap_id_attr.attr, &chipid_unique_id_attr.attr, NULL, }; static struct attribute_group chipid_sysfs_group = { .attrs = chipid_sysfs_attrs, }; static const struct attribute_group *chipid_sysfs_groups[] = { &chipid_sysfs_group, NULL, }; static ssize_t svc_ap_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return snprintf(buf, 20, "%s\n", uniqueid_get()); } static struct kobj_attribute svc_ap_attr = __ATTR(SVC_AP, 0644, svc_ap_show, NULL); extern struct kset *devices_kset; void sysfs_create_svc_ap(void) { struct kernfs_node *svc_sd; struct kobject *data; struct kobject *ap; /* To find svc kobject */ svc_sd = sysfs_get_dirent(devices_kset->kobj.sd, "svc"); if (IS_ERR_OR_NULL(svc_sd)) { /* try to create svc kobject */ data = kobject_create_and_add("svc", &devices_kset->kobj); if (IS_ERR_OR_NULL(data)) pr_info("Existing path sys/devices/svc : 0x%pK\n", data); else pr_info("Created sys/devices/svc svc : 0x%pK\n", data); } else { data = (struct kobject *)svc_sd->priv; pr_info("Found svc_sd : 0x%pK svc : 0x%pK\n", svc_sd, data); } ap = kobject_create_and_add("AP", data); if (IS_ERR_OR_NULL(ap)) pr_info("Failed to create sys/devices/svc/AP : 0x%pK\n", ap); else pr_info("Success to create sys/devices/svc/AP : 0x%pK\n", ap); if (sysfs_create_file(ap, &svc_ap_attr.attr) < 0) { pr_err("failed to create sys/devices/svc/AP/SVC_AP, %s\n", svc_ap_attr.attr.name); } } static int __init chipid_sysfs_init(void) { int ret = 0; ret = subsys_system_register(&chipid_subsys, chipid_sysfs_groups); if (ret) pr_err("%s: fail to register chip id subsys\n", __func__); sysfs_create_svc_ap(); #ifdef CONFIG_SEC_MISC soc_ap_id = chip_id_to_name(); #endif return ret; } late_initcall(chipid_sysfs_init);