xref: /linux/drivers/platform/x86/amd/pmf/acpi.c (revision c7decec2f2d2ab0366567f9e30c0e1418cece43f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * AMD Platform Management Framework Driver
4  *
5  * Copyright (c) 2022, Advanced Micro Devices, Inc.
6  * All Rights Reserved.
7  *
8  * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
9  */
10 
11 #include <linux/acpi.h>
12 #include <linux/array_size.h>
13 #include <linux/cleanup.h>
14 #include <linux/dev_printk.h>
15 #include "pmf.h"
16 
17 #define APMF_CQL_NOTIFICATION  2
18 #define APMF_AMT_NOTIFICATION  3
19 
20 static union acpi_object *apmf_if_call(struct amd_pmf_dev *pdev, int fn, struct acpi_buffer *param)
21 {
22 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
23 	acpi_handle ahandle = ACPI_HANDLE(pdev->dev);
24 	struct acpi_object_list apmf_if_arg_list;
25 	union acpi_object apmf_if_args[2];
26 	acpi_status status;
27 
28 	apmf_if_arg_list.count = 2;
29 	apmf_if_arg_list.pointer = &apmf_if_args[0];
30 
31 	apmf_if_args[0].type = ACPI_TYPE_INTEGER;
32 	apmf_if_args[0].integer.value = fn;
33 
34 	if (param) {
35 		apmf_if_args[1].type = ACPI_TYPE_BUFFER;
36 		apmf_if_args[1].buffer.length = param->length;
37 		apmf_if_args[1].buffer.pointer = param->pointer;
38 	} else {
39 		apmf_if_args[1].type = ACPI_TYPE_INTEGER;
40 		apmf_if_args[1].integer.value = 0;
41 	}
42 
43 	status = acpi_evaluate_object(ahandle, "APMF", &apmf_if_arg_list, &buffer);
44 	if (ACPI_FAILURE(status)) {
45 		dev_err(pdev->dev, "APMF method:%d call failed\n", fn);
46 		kfree(buffer.pointer);
47 		return NULL;
48 	}
49 
50 	return buffer.pointer;
51 }
52 
53 static int apmf_if_call_store_buffer(struct amd_pmf_dev *pdev, int fn, void *dest, size_t out_sz)
54 {
55 	union acpi_object *info;
56 	size_t size;
57 	int err = 0;
58 
59 	info = apmf_if_call(pdev, fn, NULL);
60 	if (!info)
61 		return -EIO;
62 
63 	if (info->type != ACPI_TYPE_BUFFER) {
64 		dev_err(pdev->dev, "object is not a buffer\n");
65 		err = -EINVAL;
66 		goto out;
67 	}
68 
69 	if (info->buffer.length < 2) {
70 		dev_err(pdev->dev, "buffer too small\n");
71 		err = -EINVAL;
72 		goto out;
73 	}
74 
75 	size = *(u16 *)info->buffer.pointer;
76 	if (info->buffer.length < size) {
77 		dev_err(pdev->dev, "buffer smaller then headersize %u < %zu\n",
78 			info->buffer.length, size);
79 		err = -EINVAL;
80 		goto out;
81 	}
82 
83 	if (size < out_sz) {
84 		dev_err(pdev->dev, "buffer too small %zu\n", size);
85 		err = -EINVAL;
86 		goto out;
87 	}
88 
89 	memcpy(dest, info->buffer.pointer, out_sz);
90 
91 out:
92 	kfree(info);
93 	return err;
94 }
95 
96 static union acpi_object *apts_if_call(struct amd_pmf_dev *pdev, u32 state_index)
97 {
98 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
99 	acpi_handle ahandle = ACPI_HANDLE(pdev->dev);
100 	struct acpi_object_list apts_if_arg_list;
101 	union acpi_object apts_if_args[3];
102 	acpi_status status;
103 
104 	apts_if_arg_list.count = 3;
105 	apts_if_arg_list.pointer = &apts_if_args[0];
106 
107 	apts_if_args[0].type = ACPI_TYPE_INTEGER;
108 	apts_if_args[0].integer.value = 1;
109 	apts_if_args[1].type = ACPI_TYPE_INTEGER;
110 	apts_if_args[1].integer.value = state_index;
111 	apts_if_args[2].type = ACPI_TYPE_INTEGER;
112 	apts_if_args[2].integer.value = 0;
113 
114 	status = acpi_evaluate_object(ahandle, "APTS", &apts_if_arg_list, &buffer);
115 	if (ACPI_FAILURE(status)) {
116 		dev_err(pdev->dev, "APTS state_idx:%u call failed\n", state_index);
117 		kfree(buffer.pointer);
118 		return NULL;
119 	}
120 
121 	return buffer.pointer;
122 }
123 
124 static int apts_if_call_store_buffer(struct amd_pmf_dev *pdev,
125 				     u32 index, void *data, size_t out_sz)
126 {
127 	union acpi_object *info;
128 	size_t size;
129 	int err = 0;
130 
131 	info = apts_if_call(pdev, index);
132 	if (!info)
133 		return -EIO;
134 
135 	if (info->type != ACPI_TYPE_BUFFER) {
136 		dev_err(pdev->dev, "object is not a buffer\n");
137 		err = -EINVAL;
138 		goto out;
139 	}
140 
141 	size = *(u16 *)info->buffer.pointer;
142 	if (info->buffer.length < size) {
143 		dev_err(pdev->dev, "buffer smaller than header size %u < %zu\n",
144 			info->buffer.length, size);
145 		err = -EINVAL;
146 		goto out;
147 	}
148 
149 	if (size < out_sz) {
150 		dev_err(pdev->dev, "buffer too small %zu\n", size);
151 		err = -EINVAL;
152 		goto out;
153 	}
154 
155 	memcpy(data, info->buffer.pointer, out_sz);
156 out:
157 	kfree(info);
158 	return err;
159 }
160 
161 int is_apmf_func_supported(struct amd_pmf_dev *pdev, unsigned long index)
162 {
163 	/* If bit-n is set, that indicates function n+1 is supported */
164 	return !!(pdev->supported_func & BIT(index - 1));
165 }
166 
167 int is_apmf_bios_input_notifications_supported(struct amd_pmf_dev *pdev)
168 {
169 	return !!(pdev->notifications & CUSTOM_BIOS_INPUT_BITS);
170 }
171 
172 int apts_get_static_slider_granular_v2(struct amd_pmf_dev *pdev,
173 				       struct amd_pmf_apts_granular_output *data, u32 apts_idx)
174 {
175 	if (!is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR))
176 		return -EINVAL;
177 
178 	return apts_if_call_store_buffer(pdev, apts_idx, data, sizeof(*data));
179 }
180 
181 int apmf_get_static_slider_granular_v2(struct amd_pmf_dev *pdev,
182 				       struct apmf_static_slider_granular_output_v2 *data)
183 {
184 	if (!is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR))
185 		return -EINVAL;
186 
187 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR,
188 					 data, sizeof(*data));
189 }
190 
191 int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev,
192 				    struct apmf_static_slider_granular_output *data)
193 {
194 	if (!is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR))
195 		return -EINVAL;
196 
197 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR,
198 									 data, sizeof(*data));
199 }
200 
201 int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event)
202 {
203 	struct os_power_slider args;
204 	struct acpi_buffer params;
205 	union acpi_object *info;
206 
207 	args.size = sizeof(args);
208 	args.slider_event = event;
209 
210 	params.length = sizeof(args);
211 	params.pointer = (void *)&args;
212 
213 	info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, &params);
214 	if (!info)
215 		return -EIO;
216 
217 	kfree(info);
218 	return 0;
219 }
220 
221 static void apmf_sbios_heartbeat_notify(struct work_struct *work)
222 {
223 	struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work);
224 	union acpi_object *info;
225 
226 	dev_dbg(dev->dev, "Sending heartbeat to SBIOS\n");
227 	info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT, NULL);
228 	if (!info)
229 		return;
230 
231 	schedule_delayed_work(&dev->heart_beat, secs_to_jiffies(dev->hb_interval));
232 	kfree(info);
233 }
234 
235 int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag)
236 {
237 	struct sbios_hb_event_v2 args = { };
238 	struct acpi_buffer params;
239 	union acpi_object *info;
240 
241 	args.size = sizeof(args);
242 
243 	switch (flag) {
244 	case ON_LOAD:
245 		args.load = 1;
246 		break;
247 	case ON_UNLOAD:
248 		args.unload = 1;
249 		break;
250 	case ON_SUSPEND:
251 		args.suspend = 1;
252 		break;
253 	case ON_RESUME:
254 		args.resume = 1;
255 		break;
256 	default:
257 		dev_dbg(dev->dev, "Failed to send v2 heartbeat event, flag:0x%x\n", flag);
258 		return -EINVAL;
259 	}
260 
261 	params.length = sizeof(args);
262 	params.pointer = &args;
263 
264 	info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2, &params);
265 	if (!info)
266 		return -EIO;
267 
268 	kfree(info);
269 	return 0;
270 }
271 
272 int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx)
273 {
274 	union acpi_object *info;
275 	struct apmf_fan_idx args;
276 	struct acpi_buffer params;
277 
278 	args.size = sizeof(args);
279 	args.fan_ctl_mode = manual;
280 	args.fan_ctl_idx = idx;
281 
282 	params.length = sizeof(args);
283 	params.pointer = (void *)&args;
284 
285 	info = apmf_if_call(pdev, APMF_FUNC_SET_FAN_IDX, &params);
286 	if (!info)
287 		return -EIO;
288 
289 	kfree(info);
290 	return 0;
291 }
292 
293 static int apmf_notify_smart_pc_update(struct amd_pmf_dev *pdev, u32 val, u32 preq, u32 index)
294 {
295 	struct amd_pmf_notify_smart_pc_update args;
296 	struct acpi_buffer params;
297 	union acpi_object *info;
298 
299 	args.size = sizeof(args);
300 	args.pending_req = preq;
301 	args.custom_bios[index] = val;
302 
303 	params.length = sizeof(args);
304 	params.pointer = &args;
305 
306 	info = apmf_if_call(pdev, APMF_FUNC_NOTIFY_SMART_PC_UPDATES, &params);
307 	if (!info)
308 		return -EIO;
309 
310 	kfree(info);
311 	dev_dbg(pdev->dev, "Notify smart pc update, val: %u\n", val);
312 
313 	return 0;
314 }
315 
316 int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data)
317 {
318 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_AUTO_MODE, data, sizeof(*data));
319 }
320 
321 int apmf_get_sbios_requests_v2(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v2 *req)
322 {
323 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, req, sizeof(*req));
324 }
325 
326 int apmf_get_sbios_requests_v1(struct amd_pmf_dev *pdev, struct apmf_sbios_req_v1 *req)
327 {
328 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS, req, sizeof(*req));
329 }
330 
331 int apmf_get_sbios_requests(struct amd_pmf_dev *pdev, struct apmf_sbios_req *req)
332 {
333 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_SBIOS_REQUESTS,
334 									 req, sizeof(*req));
335 }
336 
337 /* Store custom BIOS inputs data in ring buffer */
338 static void amd_pmf_custom_bios_inputs_rb(struct amd_pmf_dev *pmf_dev)
339 {
340 	struct pmf_cbi_ring_buffer *rb = &pmf_dev->cbi_buf;
341 	int i;
342 
343 	guard(mutex)(&pmf_dev->cbi_mutex);
344 
345 	switch (pmf_dev->cpu_id) {
346 	case AMD_CPU_ID_PS:
347 		for (i = 0; i < ARRAY_SIZE(custom_bios_inputs_v1); i++)
348 			rb->data[rb->head].val[i] = pmf_dev->req1.custom_policy[i];
349 		rb->data[rb->head].preq = pmf_dev->req1.pending_req;
350 		break;
351 	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
352 	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
353 		for (i = 0; i < ARRAY_SIZE(custom_bios_inputs); i++)
354 			rb->data[rb->head].val[i] = pmf_dev->req.custom_policy[i];
355 		rb->data[rb->head].preq = pmf_dev->req.pending_req;
356 		break;
357 	default:
358 		return;
359 	}
360 
361 	if (CIRC_SPACE(rb->head, rb->tail, CUSTOM_BIOS_INPUT_RING_ENTRIES) == 0) {
362 		/* Rare case: ensures the newest BIOS input value is kept */
363 		dev_warn(pmf_dev->dev, "Overwriting BIOS input value, data may be lost\n");
364 		rb->tail = (rb->tail + 1) & (CUSTOM_BIOS_INPUT_RING_ENTRIES - 1);
365 	}
366 
367 	rb->head = (rb->head + 1) & (CUSTOM_BIOS_INPUT_RING_ENTRIES - 1);
368 }
369 
370 static void amd_pmf_handle_early_preq(struct amd_pmf_dev *pdev)
371 {
372 	if (!pdev->cb_flag)
373 		return;
374 
375 	amd_pmf_invoke_cmd_enact(pdev);
376 	pdev->cb_flag = false;
377 }
378 
379 static void apmf_event_handler_v2(acpi_handle handle, u32 event, void *data)
380 {
381 	struct amd_pmf_dev *pmf_dev = data;
382 	int ret;
383 
384 	guard(mutex)(&pmf_dev->cb_mutex);
385 
386 	ret = apmf_get_sbios_requests_v2(pmf_dev, &pmf_dev->req);
387 	if (ret) {
388 		dev_err(pmf_dev->dev, "Failed to get v2 SBIOS requests: %d\n", ret);
389 		return;
390 	}
391 
392 	dev_dbg(pmf_dev->dev, "Pending request (preq): 0x%x\n", pmf_dev->req.pending_req);
393 
394 	amd_pmf_handle_early_preq(pmf_dev);
395 
396 	amd_pmf_custom_bios_inputs_rb(pmf_dev);
397 }
398 
399 static void apmf_event_handler_v1(acpi_handle handle, u32 event, void *data)
400 {
401 	struct amd_pmf_dev *pmf_dev = data;
402 	int ret;
403 
404 	guard(mutex)(&pmf_dev->cb_mutex);
405 
406 	ret = apmf_get_sbios_requests_v1(pmf_dev, &pmf_dev->req1);
407 	if (ret) {
408 		dev_err(pmf_dev->dev, "Failed to get v1 SBIOS requests: %d\n", ret);
409 		return;
410 	}
411 
412 	dev_dbg(pmf_dev->dev, "Pending request (preq1): 0x%x\n", pmf_dev->req1.pending_req);
413 
414 	amd_pmf_handle_early_preq(pmf_dev);
415 
416 	amd_pmf_custom_bios_inputs_rb(pmf_dev);
417 }
418 
419 static void apmf_event_handler(acpi_handle handle, u32 event, void *data)
420 {
421 	struct amd_pmf_dev *pmf_dev = data;
422 	struct apmf_sbios_req req;
423 	int ret;
424 
425 	guard(mutex)(&pmf_dev->update_mutex);
426 	ret = apmf_get_sbios_requests(pmf_dev, &req);
427 	if (ret) {
428 		dev_err(pmf_dev->dev, "Failed to get SBIOS requests:%d\n", ret);
429 		return;
430 	}
431 
432 	if (req.pending_req & BIT(APMF_AMT_NOTIFICATION)) {
433 		dev_dbg(pmf_dev->dev, "AMT is supported and notifications %s\n",
434 			req.amt_event ? "Enabled" : "Disabled");
435 		pmf_dev->amt_enabled = !!req.amt_event;
436 
437 		if (pmf_dev->amt_enabled)
438 			amd_pmf_handle_amt(pmf_dev);
439 		else
440 			amd_pmf_reset_amt(pmf_dev);
441 	}
442 
443 	if (req.pending_req & BIT(APMF_CQL_NOTIFICATION)) {
444 		dev_dbg(pmf_dev->dev, "CQL is supported and notifications %s\n",
445 			req.cql_event ? "Enabled" : "Disabled");
446 
447 		/* update the target mode information */
448 		if (pmf_dev->amt_enabled)
449 			amd_pmf_update_2_cql(pmf_dev, req.cql_event);
450 	}
451 }
452 
453 static int apmf_if_verify_interface(struct amd_pmf_dev *pdev)
454 {
455 	struct apmf_verify_interface output;
456 	int err;
457 
458 	err = apmf_if_call_store_buffer(pdev, APMF_FUNC_VERIFY_INTERFACE, &output, sizeof(output));
459 	if (err)
460 		return err;
461 
462 	/* only set if not already set by a quirk */
463 	if (!pdev->supported_func)
464 		pdev->supported_func = output.supported_functions;
465 
466 	dev_dbg(pdev->dev, "supported functions:0x%x notifications:0x%x version:%u\n",
467 		output.supported_functions, output.notification_mask, output.version);
468 
469 	pdev->pmf_if_version = output.version;
470 
471 	pdev->notifications =  output.notification_mask;
472 	return 0;
473 }
474 
475 static int apmf_get_system_params(struct amd_pmf_dev *dev)
476 {
477 	struct apmf_system_params params;
478 	int err;
479 
480 	if (!is_apmf_func_supported(dev, APMF_FUNC_GET_SYS_PARAMS))
481 		return -EINVAL;
482 
483 	err = apmf_if_call_store_buffer(dev, APMF_FUNC_GET_SYS_PARAMS, &params, sizeof(params));
484 	if (err)
485 		return err;
486 
487 	dev_dbg(dev->dev, "system params mask:0x%x flags:0x%x cmd_code:0x%x heartbeat:%d\n",
488 		params.valid_mask,
489 		params.flags,
490 		params.command_code,
491 		params.heartbeat_int);
492 	params.flags = params.flags & params.valid_mask;
493 	dev->hb_interval = params.heartbeat_int;
494 
495 	return 0;
496 }
497 
498 int apmf_get_dyn_slider_def_ac(struct amd_pmf_dev *pdev, struct apmf_dyn_slider_output *data)
499 {
500 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_DYN_SLIDER_AC, data, sizeof(*data));
501 }
502 
503 int apmf_get_dyn_slider_def_dc(struct amd_pmf_dev *pdev, struct apmf_dyn_slider_output *data)
504 {
505 	return apmf_if_call_store_buffer(pdev, APMF_FUNC_DYN_SLIDER_DC, data, sizeof(*data));
506 }
507 
508 static apmf_event_handler_t apmf_event_handlers[] = {
509 	[PMF_IF_V1] = apmf_event_handler_v1,
510 	[PMF_IF_V2] = apmf_event_handler_v2,
511 };
512 
513 int apmf_install_handler(struct amd_pmf_dev *pmf_dev)
514 {
515 	acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev);
516 	acpi_status status;
517 
518 	/* Install the APMF Notify handler */
519 	if (is_apmf_func_supported(pmf_dev, APMF_FUNC_AUTO_MODE) &&
520 	    is_apmf_func_supported(pmf_dev, APMF_FUNC_SBIOS_REQUESTS)) {
521 		status = acpi_install_notify_handler(ahandle, ACPI_ALL_NOTIFY,
522 						     apmf_event_handler, pmf_dev);
523 		if (ACPI_FAILURE(status)) {
524 			dev_err(pmf_dev->dev, "failed to install notify handler\n");
525 			return -ENODEV;
526 		}
527 
528 		/* Call the handler once manually to catch up with possibly missed notifies. */
529 		apmf_event_handler(ahandle, 0, pmf_dev);
530 	}
531 
532 	if (!pmf_dev->smart_pc_enabled)
533 		return -EINVAL;
534 
535 	switch (pmf_dev->pmf_if_version) {
536 	case PMF_IF_V1:
537 		if (!is_apmf_bios_input_notifications_supported(pmf_dev))
538 			break;
539 		fallthrough;
540 	case PMF_IF_V2:
541 		status = acpi_install_notify_handler(ahandle, ACPI_ALL_NOTIFY,
542 				apmf_event_handlers[pmf_dev->pmf_if_version], pmf_dev);
543 		if (ACPI_FAILURE(status)) {
544 			dev_err(pmf_dev->dev,
545 				"failed to install notify handler v%d for custom BIOS inputs\n",
546 				pmf_dev->pmf_if_version);
547 			return -ENODEV;
548 		}
549 		break;
550 	default:
551 		break;
552 	}
553 
554 	return 0;
555 }
556 
557 int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev)
558 {
559 	struct platform_device *pdev = to_platform_device(pmf_dev->dev);
560 
561 	pmf_dev->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
562 	if (!pmf_dev->res) {
563 		dev_dbg(pmf_dev->dev, "Failed to get I/O memory resource\n");
564 		return -EINVAL;
565 	}
566 
567 	pmf_dev->policy_addr = pmf_dev->res->start;
568 	/*
569 	 * We cannot use resource_size() here because it adds an extra byte to round off the size.
570 	 * In the case of PMF ResourceTemplate(), this rounding is already handled within the _CRS.
571 	 * Using resource_size() would increase the resource size by 1, causing a mismatch with the
572 	 * length field and leading to issues. Therefore, simply use end-start of the ACPI resource
573 	 * to obtain the actual length.
574 	 */
575 	pmf_dev->policy_sz = pmf_dev->res->end - pmf_dev->res->start;
576 
577 	if (!pmf_dev->policy_addr || pmf_dev->policy_sz > POLICY_BUF_MAX_SZ ||
578 	    pmf_dev->policy_sz == 0) {
579 		dev_err(pmf_dev->dev, "Incorrect policy params, possibly a SBIOS bug\n");
580 		return -EINVAL;
581 	}
582 
583 	return 0;
584 }
585 
586 int amd_pmf_smartpc_apply_bios_output(struct amd_pmf_dev *dev, u32 val, u32 preq, u32 idx)
587 {
588 	if (!is_apmf_func_supported(dev, APMF_FUNC_NOTIFY_SMART_PC_UPDATES))
589 		return -EINVAL;
590 
591 	return apmf_notify_smart_pc_update(dev, val, preq, idx);
592 }
593 
594 void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev)
595 {
596 	acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev);
597 
598 	if (pmf_dev->hb_interval && pmf_dev->pmf_if_version == PMF_IF_V1)
599 		cancel_delayed_work_sync(&pmf_dev->heart_beat);
600 
601 	if (is_apmf_func_supported(pmf_dev, APMF_FUNC_AUTO_MODE) &&
602 	    is_apmf_func_supported(pmf_dev, APMF_FUNC_SBIOS_REQUESTS))
603 		acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY, apmf_event_handler);
604 
605 	if (!pmf_dev->smart_pc_enabled)
606 		return;
607 
608 	switch (pmf_dev->pmf_if_version) {
609 	case PMF_IF_V1:
610 		if (!is_apmf_bios_input_notifications_supported(pmf_dev))
611 			break;
612 		fallthrough;
613 	case PMF_IF_V2:
614 		acpi_remove_notify_handler(ahandle, ACPI_ALL_NOTIFY,
615 					   apmf_event_handlers[pmf_dev->pmf_if_version]);
616 		break;
617 	default:
618 		break;
619 	}
620 }
621 
622 int apmf_acpi_init(struct amd_pmf_dev *pmf_dev)
623 {
624 	int ret;
625 
626 	ret = apmf_if_verify_interface(pmf_dev);
627 	if (ret) {
628 		dev_err(pmf_dev->dev, "APMF verify interface failed :%d\n", ret);
629 		goto out;
630 	}
631 
632 	ret = apmf_get_system_params(pmf_dev);
633 	if (ret) {
634 		dev_dbg(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret);
635 		goto out;
636 	}
637 
638 	if (pmf_dev->hb_interval && pmf_dev->pmf_if_version == PMF_IF_V1) {
639 		/* send heartbeats only if the interval is not zero */
640 		INIT_DELAYED_WORK(&pmf_dev->heart_beat, apmf_sbios_heartbeat_notify);
641 		schedule_delayed_work(&pmf_dev->heart_beat, 0);
642 	}
643 
644 out:
645 	return ret;
646 }
647