master
cocci 133 lines 3.91 KB
Raw
1 // Convert device code using three-phase reset to add a ResetType
2 // argument to implementations of ResettableHoldPhase and
3 // ResettableEnterPhase methods.
4 //
5 // Copyright Linaro Ltd 2024
6 // SPDX-License-Identifier: GPL-2.0-or-later
7 //
8 // for dir in include hw target; do \
9 // spatch --macro-file scripts/cocci-macro-file.h \
10 // --sp-file scripts/coccinelle/reset-type.cocci \
11 // --keep-comments --smpl-spacing --in-place --include-headers \
12 // --dir $dir; done
13 //
14 // This coccinelle script aims to produce a complete change that needs
15 // no human interaction, so as well as the generic "update device
16 // implementations of the hold and exit phase methods" it includes
17 // the special-case transformations needed for the core code and for
18 // one device model that does something a bit nonstandard. Those
19 // special cases are at the end of the file.
20
21 // Look for where we use a function as a ResettableHoldPhase method,
22 // either by directly assigning it to phases.hold or by calling
23 // resettable_class_set_parent_phases, and remember the function name.
24 @ holdfn_assigned @
25 identifier enterfn, holdfn, exitfn;
26 identifier rc;
27 expression e;
28 @@
29 ResettableClass *rc;
30 ...
31 (
32 rc->phases.hold = holdfn;
33 |
34 resettable_class_set_parent_phases(rc, enterfn, holdfn, exitfn, e);
35 )
36
37 // Look for the definition of the function we found in holdfn_assigned,
38 // and add the new argument. If the function calls a hold function
39 // itself (probably chaining to the parent class reset) then add the
40 // new argument there too.
41 @ holdfn_defined @
42 identifier holdfn_assigned.holdfn;
43 typedef Object;
44 identifier obj;
45 expression parent;
46 @@
47 -holdfn(Object *obj)
48 +holdfn(Object *obj, ResetType type)
49 {
50 <...
51 - parent.hold(obj)
52 + parent.hold(obj, type)
53 ...>
54 }
55
56 // Similarly for ResettableExitPhase.
57 @ exitfn_assigned @
58 identifier enterfn, holdfn, exitfn;
59 identifier rc;
60 expression e;
61 @@
62 ResettableClass *rc;
63 ...
64 (
65 rc->phases.exit = exitfn;
66 |
67 resettable_class_set_parent_phases(rc, enterfn, holdfn, exitfn, e);
68 )
69 @ exitfn_defined @
70 identifier exitfn_assigned.exitfn;
71 typedef Object;
72 identifier obj;
73 expression parent;
74 @@
75 -exitfn(Object *obj)
76 +exitfn(Object *obj, ResetType type)
77 {
78 <...
79 - parent.exit(obj)
80 + parent.exit(obj, type)
81 ...>
82 }
83
84 // SPECIAL CASES ONLY BELOW HERE
85 // We use a python scripted constraint on the position of the match
86 // to ensure that they only match in a particular function. See
87 // https://public-inbox.org/git/alpine.DEB.2.21.1808240652370.2344@hadrien/
88 // which recommends this as the way to do "match only in this function".
89
90 // Special case: isl_pmbus_vr.c has some reset methods calling others directly
91 @ isl_pmbus_vr @
92 identifier obj;
93 @@
94 - isl_pmbus_vr_exit_reset(obj);
95 + isl_pmbus_vr_exit_reset(obj, type);
96
97 // Special case: device_phases_reset() needs to pass RESET_TYPE_COLD
98 @ device_phases_reset_hold @
99 expression obj;
100 identifier rc;
101 identifier phase;
102 position p : script:python() { p[0].current_element == "device_phases_reset" };
103 @@
104 - rc->phases.phase(obj)@p
105 + rc->phases.phase(obj, RESET_TYPE_COLD)
106
107 // Special case: in resettable_phase_hold() and resettable_phase_exit()
108 // we need to pass through the ResetType argument to the method being called
109 @ resettable_phase_hold @
110 expression obj;
111 identifier rc;
112 position p : script:python() { p[0].current_element == "resettable_phase_hold" };
113 @@
114 - rc->phases.hold(obj)@p
115 + rc->phases.hold(obj, type)
116 @ resettable_phase_exit @
117 expression obj;
118 identifier rc;
119 position p : script:python() { p[0].current_element == "resettable_phase_exit" };
120 @@
121 - rc->phases.exit(obj)@p
122 + rc->phases.exit(obj, type)
123 // Special case: the typedefs for the methods need to declare the new argument
124 @ phase_typedef_hold @
125 identifier obj;
126 @@
127 - typedef void (*ResettableHoldPhase)(Object *obj);
128 + typedef void (*ResettableHoldPhase)(Object *obj, ResetType type);
129 @ phase_typedef_exit @
130 identifier obj;
131 @@
132 - typedef void (*ResettableExitPhase)(Object *obj);
133 + typedef void (*ResettableExitPhase)(Object *obj, ResetType type);