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