18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Ultravisor high level interfaces 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2019, IBM Corporation. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/printk.h> 108c2ecf20Sopenharmony_ci#include <linux/of_fdt.h> 118c2ecf20Sopenharmony_ci#include <linux/of.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <asm/ultravisor.h> 148c2ecf20Sopenharmony_ci#include <asm/firmware.h> 158c2ecf20Sopenharmony_ci#include <asm/machdep.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "powernv.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic struct kobject *ultravisor_kobj; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ciint __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname, 228c2ecf20Sopenharmony_ci int depth, void *data) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci if (!of_flat_dt_is_compatible(node, "ibm,ultravisor")) 258c2ecf20Sopenharmony_ci return 0; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR; 288c2ecf20Sopenharmony_ci pr_debug("Ultravisor detected!\n"); 298c2ecf20Sopenharmony_ci return 1; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic struct memcons *uv_memcons; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic ssize_t uv_msglog_read(struct file *file, struct kobject *kobj, 358c2ecf20Sopenharmony_ci struct bin_attribute *bin_attr, char *to, 368c2ecf20Sopenharmony_ci loff_t pos, size_t count) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci return memcons_copy(uv_memcons, to, pos, count); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic struct bin_attribute uv_msglog_attr = { 428c2ecf20Sopenharmony_ci .attr = {.name = "msglog", .mode = 0400}, 438c2ecf20Sopenharmony_ci .read = uv_msglog_read 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic int __init uv_init(void) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci struct device_node *node; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR)) 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci node = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware"); 548c2ecf20Sopenharmony_ci if (!node) 558c2ecf20Sopenharmony_ci return -ENODEV; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci uv_memcons = memcons_init(node, "memcons"); 588c2ecf20Sopenharmony_ci of_node_put(node); 598c2ecf20Sopenharmony_ci if (!uv_memcons) 608c2ecf20Sopenharmony_ci return -ENOENT; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci uv_msglog_attr.size = memcons_get_size(uv_memcons); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci ultravisor_kobj = kobject_create_and_add("ultravisor", firmware_kobj); 658c2ecf20Sopenharmony_ci if (!ultravisor_kobj) 668c2ecf20Sopenharmony_ci return -ENOMEM; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return sysfs_create_bin_file(ultravisor_kobj, &uv_msglog_attr); 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_cimachine_subsys_initcall(powernv, uv_init); 71