static int __init sun4v_wdt_init(void) { struct mdesc_handle *handle; u64 node; const u64 *value; int err = 0; unsigned long major = 1, minor = 1; /* * There are 2 properties that can be set from the control * domain for the watchdog. * watchdog-resolution * watchdog-max-timeout * * We can expect a handle to be returned otherwise something * serious is wrong. Correct to return -ENODEV here. */ handle = mdesc_grab(); if (!handle) return -ENODEV; node = mdesc_node_by_name(handle, MDESC_NODE_NULL, "platform"); err = -ENODEV; if (node == MDESC_NODE_NULL) goto out_release; /* * This is a safe way to validate if we are on the right * platform. */ if (sun4v_hvapi_register(HV_GRP_CORE, major, &minor)) goto out_hv_unreg; /* Allow value of watchdog-resolution up to 1s (default) */ value = mdesc_get_property(handle, node, "watchdog-resolution", NULL); err = -EINVAL; if (value) { if (*value == 0 || *value > WDT_DEFAULT_RESOLUTION_MS) goto out_hv_unreg; } value = mdesc_get_property(handle, node, "watchdog-max-timeout", NULL); if (value) { /* * If the property value (in ms) is smaller than * min_timeout, return -EINVAL. */ if (*value < wdd.min_timeout * 1000) goto out_hv_unreg; /* * If the property value is smaller than * default max_timeout then set watchdog max_timeout to * the value of the property in seconds. */ if (*value < wdd.max_timeout * 1000) wdd.max_timeout = *value / 1000; } watchdog_init_timeout(&wdd, timeout, NULL); watchdog_set_nowayout(&wdd, nowayout); err = watchdog_register_device(&wdd); if (err) goto out_hv_unreg; pr_info("initialized (timeout=%ds, nowayout=%d)\n", wdd.timeout, nowayout); mdesc_release(handle); return 0; out_hv_unreg: sun4v_hvapi_unregister(HV_GRP_CORE); out_release: mdesc_release(handle); return err; }
static void __init unregister_perf_hsvc(void) { if (tlb_type != hypervisor) return; sun4v_hvapi_unregister(perf_hsvc_group); }
static void __exit sun4v_wdt_exit(void) { sun4v_hvapi_unregister(HV_GRP_CORE); watchdog_unregister_device(&wdd); }