1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/device.h>
7 #include <linux/gunyah.h>
8 #include <linux/module.h>
9 #include <linux/rwsem.h>
10 
11 #include "rsc_mgr.h"
12 
13 static const struct gunyah_rm_platform_ops *rm_platform_ops;
14 static DECLARE_RWSEM(rm_platform_ops_lock);
15 
gunyah_rm_platform_pre_mem_share(struct gunyah_rm * rm,struct gunyah_rm_mem_parcel * mem_parcel)16 int gunyah_rm_platform_pre_mem_share(struct gunyah_rm *rm,
17 				     struct gunyah_rm_mem_parcel *mem_parcel)
18 {
19 	int ret = 0;
20 
21 	down_read(&rm_platform_ops_lock);
22 	if (rm_platform_ops && rm_platform_ops->pre_mem_share)
23 		ret = rm_platform_ops->pre_mem_share(rm, mem_parcel);
24 	up_read(&rm_platform_ops_lock);
25 	return ret;
26 }
27 EXPORT_SYMBOL_GPL(gunyah_rm_platform_pre_mem_share);
28 
gunyah_rm_platform_post_mem_reclaim(struct gunyah_rm * rm,struct gunyah_rm_mem_parcel * mem_parcel)29 int gunyah_rm_platform_post_mem_reclaim(struct gunyah_rm *rm,
30 					struct gunyah_rm_mem_parcel *mem_parcel)
31 {
32 	int ret = 0;
33 
34 	down_read(&rm_platform_ops_lock);
35 	if (rm_platform_ops && rm_platform_ops->post_mem_reclaim)
36 		ret = rm_platform_ops->post_mem_reclaim(rm, mem_parcel);
37 	up_read(&rm_platform_ops_lock);
38 	return ret;
39 }
40 EXPORT_SYMBOL_GPL(gunyah_rm_platform_post_mem_reclaim);
41 
gunyah_rm_platform_pre_demand_page(struct gunyah_rm * rm,u16 vmid,enum gunyah_pagetable_access access,struct folio * folio)42 int gunyah_rm_platform_pre_demand_page(struct gunyah_rm *rm, u16 vmid,
43 				       enum gunyah_pagetable_access access,
44 				       struct folio *folio)
45 {
46 	int ret = 0;
47 
48 	down_read(&rm_platform_ops_lock);
49 	if (rm_platform_ops && rm_platform_ops->pre_demand_page)
50 		ret = rm_platform_ops->pre_demand_page(rm, vmid, access, folio);
51 	up_read(&rm_platform_ops_lock);
52 	return ret;
53 }
54 EXPORT_SYMBOL_GPL(gunyah_rm_platform_pre_demand_page);
55 
gunyah_rm_platform_reclaim_demand_page(struct gunyah_rm * rm,u16 vmid,enum gunyah_pagetable_access access,struct folio * folio)56 int gunyah_rm_platform_reclaim_demand_page(struct gunyah_rm *rm, u16 vmid,
57 					   enum gunyah_pagetable_access access,
58 					   struct folio *folio)
59 {
60 	int ret = 0;
61 
62 	down_read(&rm_platform_ops_lock);
63 	if (rm_platform_ops && rm_platform_ops->pre_demand_page)
64 		ret = rm_platform_ops->release_demand_page(rm, vmid, access,
65 							   folio);
66 	up_read(&rm_platform_ops_lock);
67 	return ret;
68 }
69 EXPORT_SYMBOL_GPL(gunyah_rm_platform_reclaim_demand_page);
70 
gunyah_rm_register_platform_ops(const struct gunyah_rm_platform_ops * platform_ops)71 int gunyah_rm_register_platform_ops(
72 	const struct gunyah_rm_platform_ops *platform_ops)
73 {
74 	int ret = 0;
75 
76 	down_write(&rm_platform_ops_lock);
77 	if (!rm_platform_ops)
78 		rm_platform_ops = platform_ops;
79 	else
80 		ret = -EEXIST;
81 	up_write(&rm_platform_ops_lock);
82 	return ret;
83 }
84 EXPORT_SYMBOL_GPL(gunyah_rm_register_platform_ops);
85 
gunyah_rm_unregister_platform_ops(const struct gunyah_rm_platform_ops * platform_ops)86 void gunyah_rm_unregister_platform_ops(
87 	const struct gunyah_rm_platform_ops *platform_ops)
88 {
89 	down_write(&rm_platform_ops_lock);
90 	if (rm_platform_ops == platform_ops)
91 		rm_platform_ops = NULL;
92 	up_write(&rm_platform_ops_lock);
93 }
94 EXPORT_SYMBOL_GPL(gunyah_rm_unregister_platform_ops);
95 
_devm_gunyah_rm_unregister_platform_ops(void * data)96 static void _devm_gunyah_rm_unregister_platform_ops(void *data)
97 {
98 	gunyah_rm_unregister_platform_ops(
99 		(const struct gunyah_rm_platform_ops *)data);
100 }
101 
devm_gunyah_rm_register_platform_ops(struct device * dev,const struct gunyah_rm_platform_ops * ops)102 int devm_gunyah_rm_register_platform_ops(
103 	struct device *dev, const struct gunyah_rm_platform_ops *ops)
104 {
105 	int ret;
106 
107 	ret = gunyah_rm_register_platform_ops(ops);
108 	if (ret)
109 		return ret;
110 
111 	return devm_add_action(dev, _devm_gunyah_rm_unregister_platform_ops,
112 			       (void *)ops);
113 }
114 EXPORT_SYMBOL_GPL(devm_gunyah_rm_register_platform_ops);
115 
116 MODULE_LICENSE("GPL");
117 MODULE_DESCRIPTION("Gunyah Platform Hooks");
118