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 @ 25identifier enterfn, holdfn, exitfn; 26identifier rc; 27expression e; 28@@ 29ResettableClass *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 @ 42identifier holdfn_assigned.holdfn; 43typedef Object; 44identifier obj; 45expression 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 @ 58identifier enterfn, holdfn, exitfn; 59identifier rc; 60expression e; 61@@ 62ResettableClass *rc; 63... 64( 65 rc->phases.exit = exitfn; 66| 67 resettable_class_set_parent_phases(rc, enterfn, holdfn, exitfn, e); 68) 69@ exitfn_defined @ 70identifier exitfn_assigned.exitfn; 71typedef Object; 72identifier obj; 73expression 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 @ 92identifier 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 @ 99expression obj; 100identifier rc; 101identifier phase; 102position 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 @ 110expression obj; 111identifier rc; 112position 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 @ 117expression obj; 118identifier rc; 119position 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 @ 125identifier obj; 126@@ 127- typedef void (*ResettableHoldPhase)(Object *obj); 128+ typedef void (*ResettableHoldPhase)(Object *obj, ResetType type); 129@ phase_typedef_exit @ 130identifier obj; 131@@ 132- typedef void (*ResettableExitPhase)(Object *obj); 133+ typedef void (*ResettableExitPhase)(Object *obj, ResetType type); 134