linux/drivers/macintosh/therm_pm72.c
<<
ptio.32/spa="v .32/form"v .32a ptio.3 href="../linux+v3.7.5/drivers/macintosh/therm_pm72.c">ptio.32img src="../.static/gfx/right.png" alt=">>">pt2/spa="vpt2spa= class="lxr_search">ptioptio.32input typ v2hidden" nam v2navtarget" > v2">ptio.32input typ v2text" nam v2search" idv2search">ptio.32butt typ v2submit">Searchptio.3Prefsv .32/a>pt2/spa="vio.3 32/div"vio.3 32form aclue=="ajax+*" method="post" onsubmit="return false;">pt2input typ v2hidden" nam v2ajax_lookup" idv2ajax_lookup" > v2">pio.3 32/form"vpio.3 32div class="headingbott m">v 2div idv2file_contents""
3 312/a>2spa= class="comment">/*2/spa="v3 322/a>2spa= class="comment"> * Device driver for the thermostats & fa= controller of  the2/spa="v3 332/a>2spa= class="comment"> * Apple G5 "PowerMac7,2" desktop machines.2/spa="v3 342/a>2spa= class="comment"> *2/spa="v3 352/a>2spa= class="comment"> * (c) Copyright IBM Corp. 2003-20042/spa="v3 362/a>2spa= class="comment"> *2/spa="v3 372/a>2spa= class="comment"> * Maintained by: Benjamin Herrenschmidt2/spa="v3 382/a>2spa= class="comment"> *                <benh@kernel.crashing.org>2/spa="v3 392/a>2spa= class="comment"> * 2/spa="v3 ion a>2spa= class="comment"> *2/spa="v3 112/a>2spa= class="comment"> * The algorithm used is the PID control algorithm, used the sam 2/spa="v3 122/a>2spa= class="comment"> * way the published Darwi= code does, using the sam   >
  s that2/spa="v3 132/a>2spa= class="comment"> * are present i= the Darwi= 7.0 snapshot property lists.2/spa="v3 142/a>2spa= class="comment"> *2/spa="v3 152/a>2spa= class="comment"> * As far as the CPUs control loops are concerned, I use the2/spa="v3 162/a>2spa= class="comment"> * calibra2"
	 & PID constants provided by the EEPROM,2/spa="v3 172/a>2spa= class="comment"> * I do _not_ embed any  >
   from the property lists, as the ones2/spa="v3 182/a>2spa= class="comment"> * provided by Darwi= 7.0 seem to always have an older vers"
	 that2/spa="v3 192/a>2spa= class="comment"> * what I've seen o= the aclual computers.2/spa="v3 2on a>2spa= class="comment"> * It would be i=teresting to verify that though. Darwi= has a2/spa="v3 212/a>2spa= class="comment"> * vers"
	 code of 1.0.0d11 for all control loops it seems, while2/spa="v3 222/a>2spa= class="comment"> * so far, the machines EEPROMs contain a dataset vers"
	ed 1.0.0f2/spa="v3 232/a>2spa= class="comment"> *2/spa="v3 242/a>2spa= class="comment"> * Darwi= doesn't provide source to all parts, som  missing2/spa="v3 252/a>2spa= class="comment"> * bits like the AppleFCU driver or the aclual scale of som 2/spa="v3 262/a>2spa= class="comment"> * of the  >
  s returned by sensors had to be "g  ssed" som 2/spa="v3 272/a>2spa= class="comment"> * way... or based 
	 what Open Firmware does.2/spa="v3 282/a>2spa= class="comment"> *2/spa="v3 292/a>2spa= class="comment"> * I didn't yet figure out how to get the slots power consumalue=2/spa="v3 3on a>2spa= class="comment"> * out of the FCU, so that part has not been implemented yet and2/spa="v3 312/a>2spa= class="comment"> * the slots fa= is set to a fixed 50% PWM, hoping this  >
   is2/spa="v3 322/a>2spa= class="comment"> * safe enough ...2/spa="v3 332/a>2spa= class="comment"> *2/spa="v3 342/a>2spa= class="comment"> * Note: I have observed strange oscilla2"
	s of the CPU control2/spa="v3 352/a>2spa= class="comment"> * loop 
	 a dual G5 here. When idle, the CPU exhaust fa= tend to2/spa="v3 362/a>2spa= class="comment"> * oscilla2 s slowly (over several minutes) between the minimum2/spa="v3 372/a>2spa= class="comment"> * of 300RPMs and approx. 1000 RPMs. I don't know what is causing2/spa="v3 382/a>2spa= class="comment"> * this, it could be som  incorrect constant or a= error i= the2/spa="v3 392/a>2spa= class="comment"> * way I ported the algorithm, or it could be just normal. I2/spa="v3 4on a>2spa= class="comment"> * don't have full understanding o= the way Apple tweaked the PID2/spa="v3 412/a>2spa= class="comment"> * algorithm for the CPU control, it is definitely not a standard2/spa="v3 422/a>2spa= class="comment"> * implementa2"
	...2/spa="v3 432/a>2spa= class="comment"> *2/spa="v3 442/a>2spa= class="comment"> * TODO:  - Check MPU struclure vers"
	/signalure2/spa="v3 452/a>2spa= class="comment"> *        - Add things like /sbin/overtemp for non-critical2/spa="v3 462/a>2spa= class="comment"> *          overtemp condi2"
	s so userland ca= take som  policy2/spa="v3 472/a>2spa= class="comment"> *          decis"
	s, like slowing down CPUs2/spa="v3 482/a>2spa= class="comment"> *        - Deal with fa= and i2c failures in a better way2/spa="v3 492/a>2spa= class="comment"> *        - Maybe do a generic PID based 
	 params used for2/spa="v3 5on a>2spa= class="comment"> *          U3 and Drives ? Definitely need to factor code a bit2/spa="v3 512/a>2spa= class="comment"> *          better... also make sensor deteclue= more robust using2/spa="v3 522/a>2spa= class="comment"> *          the device-tree to probe for them2/spa="v3 532/a>2spa= class="comment"> *        - Figure out how to get the slots consumalue= and set the2/spa="v3 542/a>2spa= class="comment"> *          slots fa= accordingly2/spa="v3 552/a>2spa= class="comment"> *2/spa="v3 562/a>2spa= class="comment"> * History:2/spa="v3 572/a>2spa= class="comment"> *2/spa="v3 582/a>2spa= class="comment"> *  Nov. 13, 2003 : optiospa="v3 592/a>2spa= class="comment"> *      - First release2/spa="v3 6on a>2spa= class="comment"> *2/spa="v3 612/a>2spa= class="comment"> *  Nov. 14, 2003 : op62/spa="v3 622/a>2spa= class="comment"> *      - Read fa= speed from FCU, low level fa= routines now deal2/spa="v3 632/a>2spa= class="comment"> *        with errors & check fa= sta2us, though higher level don't2/spa="v3 642/a>2spa= class="comment"> *        do much.2/spa="v3 652/a>2spa= class="comment"> *      - Move a bunch of definit"
	s to .h file2/spa="v3 662/a>2spa= class="comment"> *2/spa="v3 672/a>2spa= class="comment"> *  Nov. 18, 2003 : op72/spa="v3 682/a>2spa= class="comment"> *      - Fix build 
	 ppc64 kernel2/spa="v3 692/a>2spa= class="comment"> *      - Move back statics definit"
	s to .c file2/spa="v3 7on a>2spa= class="comment"> *      - Avoid calling schedule_timeout with a negative number2/spa="v3 712/a>2spa= class="comment"> *2/spa="v3 722/a>2spa= class="comment"> *  Dec. 18, 2003 : op82/spa="v3 732/a>2spa= class="comment"> *      - Fix typo when reading back fa= speed 
	 2 CPU machines2/spa="v3 742/a>2spa= class="comment"> *2/spa="v3 752/a>2spa= class="comment"> *  Mar. 11, 2004 : op92/spa="v3 762/a>2spa= class="comment"> *      - Rework code accessing the ADC chips, make it more robust and2/spa="v3 772/a>2spa= class="comment"> *        closer to the chip spec. Also make sure it is configured properly,2/spa="v3 782/a>2spa= class="comment"> *        I've seen yet unexplained cases where o= startup, I would have stale2/spa="v3 792/a>2spa= class="comment"> *         >
  s i= the configura2"
	 register2/spa="v3 8on a>2spa= class="comment"> *      - Switch back to use of target fa= speed for PID, thus lowering2/spa="v3 812/a>2spa= class="comment"> *        pressure 
	 i2c2/spa="v3 822/a>2spa= class="comment"> *2/spa="v3 832/a>2spa= class="comment"> *  Oct. 20, 2004 : optiospa="v3 842/a>2spa= class="comment"> *      - Add device-tree lookup for fa= IDs, should detecl liquid cooling2/spa="v3 852/a>2spa= class="comment"> *        pumps when present2/spa="v3 862/a>2spa= class="comment"> *      - Enable driver for PowerMac7,3 machines2/spa="v3 872/a>2spa= class="comment"> *      - Split the U3/Backside cooling 
	 U3 & U3H vers"
	s as Darwi= does2/spa="v3 882/a>2spa= class="comment"> *      - Add new CPU cooling algorithm for machines with liquid cooling2/spa="v3 892/a>2spa= class="comment"> *      - Workaround for som  PowerMac7,3 with empty "fa=" node i= the devtree2/spa="v3 9on a>2spa= class="comment"> *      - Fix a signed/unsigned compare issue i= som  PID loops2/spa="v3 912/a>2spa= class="comment"> *2/spa="v3 922/a>2spa= class="comment"> *  Mar. 10, 2005 : op22/spa="v3 932/a>2spa= class="comment"> *      - Add basic support for Xserve Gtiospa="v3 942/a>2spa= class="comment"> *      - Retrieve pumps min/max from EEPROM image i= device-tree (broken)iospa="v3 952/a>2spa= class="comment"> *      - Use min/max macros here or there2/spa="v3 962/a>2spa= class="comment"> *      - La2 st darwi= updated U3H min fa= speed to 20% PWM2/spa="v3 972/a>2spa= class="comment"> *2/spa="v3 982/a>2spa= class="comment"> *  July. 06, 2006 : op32/spa="v3 992/a>2spa= class="comment"> *      - Fix setting of RPM fa=s 
	 Xserve Gt (they were going too fast)iospa="v31002/a>2spa= class="comment"> *      - Add missing slots fa= control loop for Xserve Gtiospa="v31012/a>2spa= class="comment"> *      - Lower fixed slots fa= speed from 50% to 40% on desktop G5s. We2/spa="v31022/a>2spa= class="comment"> *        still can't properly implement the control loop for these, so let's2/spa="v31032/a>2spa= class="comment"> *        reduce the noise a little bit, it appears that 40% still gives us2/spa="v31042/a>2spa= class="comment"> *        a pretty good air flow2/spa="v31052/a>2spa= class="comment"> *      - Add code to "tickle" the FCU regulary so it doesn't think that2/spa="v31062/a>2spa= class="comment"> *        we are gone while in fact, the machine just didn't need any fa=2/spa="v31072/a>2spa= class="comment"> *        speed change la2 ly2/spa="v31082/a>2spa= class="comment"> *2/spa="v31092/a>2spa= class="comment"> */2/spa="v31ion a>v31112/a>#include <linux/typ s.h2/a>>v31122/a>#include <linux/module.h2/a>>v31132/a>#include <linux/errno.h2/a>>v31142/a>#include <linux/kernel.h2/a>>v31152/a>#include <linux/delay.h2/a>>v31162/a>#include <linux/sched.h2/a>>v31172/a>#include <linux/init.h2/a>>v31182/a>#include <linux/spinlock.h2/a>>v31192/a>#include <linux/wait.h2/a>>v312on a>#include <linux/reboot.h2/a>>v31212/a>#include <linux/kmod.h2/a>>v31222/a>#include <linux/i2c.h2/a>>v31232/a>#include <linux/kthread.h2/a>>v31242/a>#include <linux/mutex.h2/a>>v31252/a>#include <linux/of_device.h2/a>>v31262/a>#include <linux/of_pla2form.h2/a>>v31272/a>#include <asm/prom.h2/a>>v31282/a>#include <asm/machdep.h2/a>>v31292/a>#include <asm/io.h2/a>>v313on a>#include <asm/seclue=s.h2/a>>v31312/a>#include <asm/macio.h2/a>>v31322/a>v31332/a>#include "therm_pm72.h2/a>"v31342/a>v31352/a>#define32a href="+code=VERSION" class="sref">VERSION2/a> 2spa= class="string">"1.3"31362/a>v31372/a>#undef32a href="+code=DEBUG" class="sref">DEBUG2/a>v31382/a>v31392/a>#ifdef32a href="+code=DEBUG" class="sref">DEBUG2/a>v314on a>#define32a href="+code=DBG" class="sref">DBG2/a>(2a href="+code=args" class="sref">args2/a>...)    2a href="+code=printk" class="sref">printk2/a>(2a href="+code=args" class="sref">args2/a>)v31412/a>#elsev31422/a>#define32a href="+code=DBG" class="sref">DBG2/a>(2a href="+code=args" class="sref">args2/a>...)    do { } while(0)v31432/a>#endifv31442/a>v31452/a>v31462/a>2spa= class="comment">/*2/spa="v31472/a>2spa= class="comment"> * Driver statics2/spa="v31482/a>2spa= class="comment"> */2/spa="v31492/a>v315on a>static strucl 2a href="+code=pla2form_device" class="sref">pla2form_device2/a> *         2a href="+code=of_dev" class="sref">of_dev2/a>;v31512/a>static strucl 2a href="+code=i2c_adapter" class="sref">i2c_adapter2/a> *             2a href="+code=u3_0" class="sref">u3_02/a>;v31522/a>static strucl 2a href="+code=i2c_adapter" class="sref">i2c_adapter2/a> *             2a href="+code=u3_1" class="sref">u3_12/a>;v31532/a>static strucl 2a href="+code=i2c_adapter" class="sref">i2c_adapter2/a> *             2a href="+code=k2" class="sref">k22/a>;v31542/a>static strucl 2a href="+code=i2c_client" class="sref">i2c_client2/a> *              2a href="+code=fcu" class="sref">fcu2/a>;v31552/a>static strucl 2a href="+code=cpu_pid_state" class="sref">cpu_pid_state2/a>             2a href="+code=processor_state" class="sref">processor_state2/a>[2];v31562/a>static strucl 2a href="+code=basckside_pid_params" class="sref">basckside_pid_params2/a>      2a href="+code=backside_params" class="sref">backside_params2/a>;v31572/a>static strucl 2a href="+code=backside_pid_state" class="sref">backside_pid_state2/a>        2a href="+code=backside_state" class="sref">backside_state2/a>;v31582/a>static strucl 2a href="+code=drives_pid_state" class="sref">drives_pid_state2/a>          2a href="+code=drives_state" class="sref">drives_state2/a>;v31592/a>static strucl 2a href="+code=dimm_pid_state" class="sref">dimm_pid_state2/a>            2a href="+code=dimms_state" class="sref">dimms_state2/a>;v316on a>static strucl 2a href="+code=slots_pid_state" class="sref">slots_pid_state2/a>           2a href="+code=slots_state" class="sref">slots_state2/a>;v31612/a>static int                              2a href="+code=state" class="sref">state2/a>;v31622/a>static int                              2a href="+code=cpu_count" class="sref">cpu_count2/a>;v31632/a>static int                              2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a>;v31642/a>static strucl 2a href="+code=task_strucl" class="sref">task_strucl2/a>               *2a href="+code=ctrl_task" class="sref">ctrl_task2/a>;v31652/a>static strucl 2a href="+code=complelue=" class="sref">complelue=2/a>                2a href="+code=ctrl_complel " class="sref">ctrl_complel 2/a>;v31662/a>static int                              2a href="+code=critical_state" class="sref">critical_state2/a>;v31672/a>static int                              2a href="+code=rackmac" class="sref">rackmac2/a>;v31682/a>static 2a href="+code=s32" class="sref">s322/a>                              2a href="+code=dimm_output_clamp" class="sref">dimm_output_clamp2/a>;v31692/a>static int                              2a href="+code=fcu_rpm_shifl" class="sref">fcu_rpm_shifl2/a>;v31702/a>static int                              2a href="+code=fcu_tickle_ticks" class="sref">fcu_tickle_ticks2/a>;v31712/a>static 2a href="+code=DEFINE_MUTEX" class="sref">DEFINE_MUTEX2/a>(2a href="+code=driver_lock" class="sref">driver_lock2/a>);v31722/a>v31732/a>2spa= class="comment">/*2/spa="v31742/a>2spa= class="comment"> * We have 3 typ s of CPU PID control. One is "split" old style control2/spa="v31752/a>2spa= class="comment"> * for i=take & exhaust fa=s, the other is "combined" control for both2/spa="v31762/a>2spa= class="comment"> * CPUs that also deals with the pumps when present. To be "compatible"2/spa="v31772/a>2spa= class="comment"> * with OS X at this point, we only use "COMBINED" on the machines that2/spa="v31782/a>2spa= class="comment"> * are identified as having the pumps (though that identifica2"
	 is at2/spa="v31792/a>2spa= class="comment"> * least dodgy). Ultima2 ly, we could probably switch complel ly to this2/spa="v318on a>2spa= class="comment"> * algorithm provided we hack it to deal with the UP case2/spa="v31812/a>2spa= class="comment"> */2/spa="v31822/a>#define32a href="+code=CPU_PID_TYPE_SPLIT" class="sref">CPU_PID_TYPE_SPLIT2/a>      0v31832/a>#define32a href="+code=CPU_PID_TYPE_COMBINED" class="sref">CPU_PID_TYPE_COMBINED2/a>   1v31842/a>#define32a href="+code=CPU_PID_TYPE_RACKMAC" class="sref">CPU_PID_TYPE_RACKMAC2/a>    2v31852/a>v31862/a>2spa= class="comment">/*2/spa="v31872/a>2spa= class="comment"> * This table describes all fa=s i= the FCU. The "id" and "typ "  >
  s2/spa="v31882/a>2spa= class="comment"> * are defaults  >
id for all earlier machines. Newer machines will2/spa="v31892/a>2spa= class="comment"> * eventually override the table content based 
	 the device-tree2/spa="v319on a>2spa= class="comment"> */2/spa="v31912/a>strucl 2a href="+code=fcu_fa=_table" class="sref">fcu_fa=_table2/a>v31922/a>{v31932/a>        char*   2a href="+code=loc" class="sref">loc2/a>;    2spa= class="comment">/* loca2"
	 code */2/spa="v31942/a>        int     2a href="+code=typ " class="sref">typ 2/a>;   2spa= class="comment">/* 0 = rpm, 1 = pwm, 2 = pump */2/spa="v31952/a>        int     2a href="+code=id" class="sref">id2/a>;     2spa= class="comment">/* id or -1 */2/spa="v31962/a>};v31972/a>v31982/a>#define32a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>             0v31992/a>#define32a href="+code=FCU_FAN_PWM" class="sref">FCU_FAN_PWM2/a>             1v320on a>v32012/a>#define32a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>       -1v32022/a>v32032/a>#define32a href="+code=FCU_FAN_COUNT" class="sref">FCU_FAN_COUNT2/a>           2a href="+code=ARRAY_SIZE" class="sref">ARRAY_SIZE2/a>(2a href="+code=fcu_fa=s" class="sref">fcu_fa=s2/a>)v32042/a>v32052/a>strucl 2a href="+code=fcu_fa=_table" class="sref">fcu_fa=_table2/a>    2a href="+code=fcu_fa=s" class="sref">fcu_fa=s2/a>[] = {v32062/a>        [2a href="+code=BACKSIDE_FAN_PWM_INDEX" class="sref">BACKSIDE_FAN_PWM_INDEX2/a>] = {v32072/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"BACKSIDE,SYS CTRLR FAN"2/spa=",v32082/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_PWM" class="sref">FCU_FAN_PWM2/a>,v32092/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=BACKSIDE_FAN_PWM_DEFAULT_ID" class="sref">BACKSIDE_FAN_PWM_DEFAULT_ID2/a>,v32ion a>        },v32112/a>        [2a href="+code=DRIVES_FAN_RPM_INDEX" class="sref">DRIVES_FAN_RPM_INDEX2/a>] = {v32122/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"DRIVE BAY"2/spa=",v32132/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32142/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=DRIVES_FAN_RPM_DEFAULT_ID" class="sref">DRIVES_FAN_RPM_DEFAULT_ID2/a>,v3215n a>        },v32162/a>        [2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>] = {v32172/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"SLOT,PCI FAN"2/spa=",v32182/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_PWM" class="sref">FCU_FAN_PWM2/a>,v32192/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=SLOTS_FAN_PWM_DEFAULT_ID" class="sref">SLOTS_FAN_PWM_DEFAULT_ID2/a>,v322on a>        },v32212/a>        [2a href="+code=CPUA_INTAKE_FAN_RPM_INDEX" class="sref">CPUA_INTAKE_FAN_RPM_INDEX2/a>] = {v32222/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A INTAKE"2/spa=",v32232/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32242/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=CPUA_INTAKE_FAN_RPM_DEFAULT_ID" class="sref">CPUA_INTAKE_FAN_RPM_DEFAULT_ID2/a>,v3225n a>        },v32262/a>        [2a href="+code=CPUA_EXHAUST_FAN_RPM_INDEX" class="sref">CPUA_EXHAUST_FAN_RPM_INDEX2/a>] = {v32272/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A EXHAUST"2/spa=",v32282/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32292/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=CPUA_EXHAUST_FAN_RPM_DEFAULT_ID" class="sref">CPUA_EXHAUST_FAN_RPM_DEFAULT_ID2/a>,v323on a>        },v32312/a>        [2a href="+code=CPUB_INTAKE_FAN_RPM_INDEX" class="sref">CPUB_INTAKE_FAN_RPM_INDEX2/a>] = {v32322/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B INTAKE"2/spa=",v32332/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32342/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=CPUB_INTAKE_FAN_RPM_DEFAULT_ID" class="sref">CPUB_INTAKE_FAN_RPM_DEFAULT_ID2/a>,v3235n a>        },v32362/a>        [2a href="+code=CPUB_EXHAUST_FAN_RPM_INDEX" class="sref">CPUB_EXHAUST_FAN_RPM_INDEX2/a>] = {v32372/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B EXHAUST"2/spa=",v32382/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32392/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=CPUB_EXHAUST_FAN_RPM_DEFAULT_ID" class="sref">CPUB_EXHAUST_FAN_RPM_DEFAULT_ID2/a>,v324on a>        },v32412/a>        2spa= class="comment">/* pumps aren't present by default, have to be looked up i= the2/spa="v32422/a>2spa= class="comment">         * device-tree2/spa="v32432/a>2spa= class="comment">         */2/spa="v32442/a>        [2a href="+code=CPUA_PUMP_RPM_INDEX" class="sref">CPUA_PUMP_RPM_INDEX2/a>] = {v32452/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A PUMP"2/spa=",v32462/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,          v32472/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3248n a>        },v32492/a>        [2a href="+code=CPUB_PUMP_RPM_INDEX" class="sref">CPUB_PUMP_RPM_INDEX2/a>] = {v32502/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B PUMP"2/spa=",v32512/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32522/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3253n a>        },v32542/a>        2spa= class="comment">/* Xserve fa=s */2/spa="v32552/a>        [2a href="+code=CPU_A1_FAN_RPM_INDEX" class="sref">CPU_A1_FAN_RPM_INDEX2/a>] = {v32562/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A 1"2/spa=",v32572/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32582/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3259n a>        },v32602/a>        [2a href="+code=CPU_A2_FAN_RPM_INDEX" class="sref">CPU_A2_FAN_RPM_INDEX2/a>] = {v32612/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A 2"2/spa=",v32622/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32632/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3264n a>        },v32652/a>        [2a href="+code=CPU_A3_FAN_RPM_INDEX" class="sref">CPU_A3_FAN_RPM_INDEX2/a>] = {v32662/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU A 3"2/spa=",v32672/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32682/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3269n a>        },v32702/a>        [2a href="+code=CPU_B1_FAN_RPM_INDEX" class="sref">CPU_B1_FAN_RPM_INDEX2/a>] = {v32712/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B 1"2/spa=",v32722/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32732/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3274n a>        },v32752/a>        [2a href="+code=CPU_B2_FAN_RPM_INDEX" class="sref">CPU_B2_FAN_RPM_INDEX2/a>] = {v32762/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B 2"2/spa=",v32772/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32782/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3279n a>        },v32802/a>        [2a href="+code=CPU_B3_FAN_RPM_INDEX" class="sref">CPU_B3_FAN_RPM_INDEX2/a>] = {v32812/a>                .2a href="+code=loc" class="sref">loc2/a>    = 2spa= class="string">"CPU B 3"2/spa=",v32822/a>                .2a href="+code=typ " class="sref">typ 2/a>   = 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>,v32832/a>                .2a href="+code=id" class="sref">id2/a>     = 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>,v3284n a>        },v32852/a>};v32862/a>v32872/a>static strucl 2a href="+code=i2c_driver" class="sref">i2c_drivern a> 2a href="+code=therm_pm72_driver" class="sref">therm_pm72_drivern a>;v32882/a>v32892/a>2spa= class="comment">/*2/spa="v329on a>2spa= class="comment"> * Utility funclue= to create a= i2c_client struclure a=d2/spa="v32912/a>2spa= class="comment"> * attach it to one of u3 adapters2/spa="v32922/a>2spa= class="comment"> */2/spa="v32932/a>static strucl 2a href="+code=i2c_client" class="sref">i2c_client2/a> *2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(int 2a href="+code=id" class="sref">id2/a>, const char *2a href="+code=nam " class="sref">nam 2/a>)v32942/a>{v32952/a>        strucl 2a href="+code=i2c_client" class="sref">i2c_client2/a> *2a href="+code=clt" class="sref">cll2/a>;v32962/a>        strucl 2a href="+code=i2c_adapter" class="sref">i2c_adapter2/a> *2a href="+code=adap" class="sref">adap2/a>;v32972/a>        strucl 2a href="+code=i2c_board_info" class="sref">i2c_board_infon a> 2a href="+code=info" class="sref">infon a>;v32982/a>v3299n a>        if (2a href="+code=id" class="sref">id2/a> & 0x200)v33002/a>                2a href="+code=adap" class="sref">adap2/a> = 2a href="+code=k2" class="sref">k22/a>;v33012/a>        else if (2a href="+code=id" class="sref">id2/a> & 0x100)v33022/a>                2a href="+code=adap" class="sref">adap2/a> = 2a href="+code=u3_1" class="sref">u3_12/a>;v33032/a>        elsev33042/a>                2a href="+code=adap" class="sref">adap2/a> = 2a href="+code=u3_0" class="sref">u3_02/a>;v3305n a>        if (2a href="+code=adap" class="sref">adap2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v33062/a>                relurn 2a href="+code=NULL" class="sref">NULL2/a>;v33072/a>v33082/a>        2a href="+code=memset" class="sref">memset2/a>(&2a href="+code=info" class="sref">infon a>, 0, sizeof(strucl 2a href="+code=i2c_board_info" class="sref">i2c_board_infon a>));v33092/a>        2a href="+code=info" class="sref">infon a>.2a href="+code=addr" class="sref">addr2/a> = (2a href="+code=id" class="sref">id2/a> >> 1) & 0x7f;v33ion a>        2a href="+code=strlcpy" class="sref">strlcpy2/a>(2a href="+code=info" class="sref">infon a>.2a href="+code=typ " class="sref">typ 2/a>, 2spa= class="string">"therm_pm72"2/spa=", 2a href="+code=I2C_NAME_SIZE" class="sref">I2C_NAME_SIZEn a>);v33112/a>        2a href="+code=clt" class="sref">cll2/a> = 2a href="+code=i2c_new_device" class="sref">i2c_new_device2/a>(2a href="+code=adap" class="sref">adap2/a>, &2a href="+code=info" class="sref">infon a>);v33122/a>        if (!2a href="+code=clt" class="sref">cll2/a>) {v33132/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Failed to attach to i2c ID 0x%x\n"2/spa=", 2a href="+code=id" class="sref">id2/a>);v33142/a>                relurn 2a href="+code=NULL" class="sref">NULL2/a>;v3315n a>        }v33162/a>v33172/a>        2spa= class="comment">/*2/spa="v33182/a>2spa= class="comment">         * Let i2c-core delel  that device 
	 driver removal.2/spa="v33192/a>2spa= class="comment">         * This is safe because i2c-core holds the core_lock mutex for us.2/spa="v332on a>2spa= class="comment">         */2/spa="v33212/a>        2a href="+code=list_add_tail" class="sref">list_add_tail2/a>(&2a href="+code=clt" class="sref">cll2/a>->2a href="+code=del cted" class="sref">del cted2/a>, &2a href="+code=therm_pm72_driver" class="sref">therm_pm72_drivern a>.2a href="+code=clients" class="sref">clients2/a>);v33222/a>        relurn 2a href="+code=clt" class="sref">cll2/a>;v33232/a>}v33242/a>v33252/a>2spa= class="comment">/*2/spa="v33262/a>2spa= class="comment"> * Here are the i2c chip access wrappers2/spa="v33272/a>2spa= class="comment"> */2/spa="v33282/a>v33292/a>static void 2a href="+code=initialize_adc" class="sref">initialize_adc2/a>(strucl 2a href="+code=cpu_pid_state" class="sref">cpu_pid_state2/a> *2a href="+code=state" class="sref">state2/a>)v333on a>{v33312/a>        int 2a href="+code=rc" class="sref">rc2/a>;v33322/a>        2a href="+code=u8" class="sref">u8n a> 2a href="+code=buf" class="sref">bufn a>[2];v33332/a>v33342/a>        2spa= class="comment">/* Read ADC the configura2"
	 register and cache it. We2/spa="v33352/a>2spa= class="comment">         * also make sure Config2 contains proper  >
  s, I've seen2/spa="v33362/a>2spa= class="comment">         * cases where we got stale grabage i= there, thus preventing2/spa="v33372/a>2spa= class="comment">         * proper reading of conv.  >
  s2/spa="v33382/a>2spa= class="comment">         */2/spa="v33392/a>v334on a>        2spa= class="comment">/* Clear Config2 */2/spa="v33412/a>        2a href="+code=buf" class="sref">bufn a>[0] = 5;v33422/a>        2a href="+code=buf" class="sref">bufn a>[1] = 0;v33432/a>        2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 2);v33442/a>v33452/a>        2spa= class="comment">/* Read & cache Config1 */2/spa="v33462/a>        2a href="+code=buf" class="sref">bufn a>[0] = 1;v33472/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 1);v3348n a>        if (2a href="+code=rc" class="sref">rc2/a> > 0) {v33492/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_recv" class="sref">i2c_master_recv2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 1);v33502/a>                if (2a href="+code=rc" class="sref">rc2/a> > 0) {v33512/a>                        2a href="+code=state" class="sref">state2/a>->2a href="+code=adc_config" class="sref">adc_config2/a> = 2a href="+code=buf" class="sref">bufn a>[0];v33522/a>                        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"ADC config reg: %02x\n"2/spa=", 2a href="+code=state" class="sref">state2/a>->2a href="+code=adc_config" class="sref">adc_config2/a>);v33532/a>                        2spa= class="comment">/* Disable shutdown mode */2/spa="v33542/a>                        2a href="+code=state" class="sref">state2/a>->2a href="+code=adc_config" class="sref">adc_config2/a> &= 0xfe;v33552/a>                        2a href="+code=buf" class="sref">bufn a>[0] = 1;v33562/a>                        2a href="+code=buf" class="sref">bufn a>[1] = 2a href="+code=state" class="sref">state2/a>->2a href="+code=adc_config" class="sref">adc_config2/a>;v33572/a>                        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 2);v33582/a>                }v3359n a>        }v33602/a>        if (2a href="+code=rc" class="sref">rc2/a> <= 0)v33612/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Error reading ADC config"2/spa="v33622/a>                       2spa= class="string">" register !\n"2/spa=");v33632/a>}v33642/a>v33652/a>static int 2a href="+code=read_smon_adc" class="sref">read_smon_adc2/a>(strucl 2a href="+code=cpu_pid_state" class="sref">cpu_pid_state2/a> *2a href="+code=state" class="sref">state2/a>, int 2a href="+code=chan" class="sref">chan2/a>)v33662/a>{v33672/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=data" class="sref">data2/a>, 2a href="+code=tries" class="sref">tries2/a> = 0;v33682/a>        2a href="+code=u8" class="sref">u8n a> 2a href="+code=buf" class="sref">bufn a>[2];v33692/a>v33702/a>        for (;;) {v33712/a>                2spa= class="comment">/* Set channel */2/spa="v33722/a>                2a href="+code=buf" class="sref">bufn a>[0] = 1;v33732/a>                2a href="+code=buf" class="sref">bufn a>[1] = (2a href="+code=state" class="sref">state2/a>->2a href="+code=adc_config" class="sref">adc_config2/a> & 0x1f) | (2a href="+code=chan" class="sref">chan2/a> << 5);v33742/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 2);v33752/a>                if (2a href="+code=rc" class="sref">rc2/a> <= 0)v33762/a>                        goto 2a href="+code=error" class="sref">error2/a>;v33772/a>                2spa= class="comment">/* Wait for convers"
	 */2/spa="v33782/a>                2a href="+code=msleep" class="sref">msleep2/a>(1);v33792/a>                2spa= class="comment">/* Switch to data register */2/spa="v33802/a>                2a href="+code=buf" class="sref">bufn a>[0] = 4;v33812/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 1);v33822/a>                if (2a href="+code=rc" class="sref">rc2/a> <= 0)v33832/a>                        goto 2a href="+code=error" class="sref">error2/a>;v33842/a>                2spa= class="comment">/* Read result */2/spa="v33852/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_recv" class="sref">i2c_master_recv2/a>(2a href="+code=state" class="sref">state2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=buf" class="sref">bufn a>, 2);v33862/a>                if (2a href="+code=rc" class="sref">rc2/a> < 0)v33872/a>                        goto 2a href="+code=error" class="sref">error2/a>;v33882/a>                2a href="+code=data" class="sref">data2/a> = ((2a href="+code=u16" class="sref">u162/a>)2a href="+code=buf" class="sref">bufn a>[0]) << 8 | (2a href="+code=u16" class="sref">u162/a>)2a href="+code=buf" class="sref">bufn a>[1];v33892/a>                relurn 2a href="+code=data" class="sref">data2/a> >> 6;v339on a>        2a href="+code=error" class="sref">error2/a>:v33912/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"Error reading ADC, relrying...\n"2/spa=");v33922/a>                if (++2a href="+code=tries" class="sref">tries2/a> > 10) {v33932/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Error reading ADC !\n"2/spa=");v33942/a>                        relurn -1;v33952/a>                }v33962/a>                2a href="+code=msleep" class="sref">msleep2/a>(10);v33972/a>        }v33982/a>}v33992/a>v34002/a>static int 2a href="+code=read_lm87_reg" class="sref">read_lm87_reg2/a>(strucl 2a href="+code=i2c_client" class="sref">i2c_client2/a> * 2a href="+code=chip" class="sref">chip2/a>, int 2a href="+code=reg" class="sref">reg2/a>)v34012/a>{v34022/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=tries" class="sref">tries2/a> = 0;v34032/a>        2a href="+code=u8" class="sref">u8n a> 2a href="+code=buf" class="sref">bufn a>;v34042/a>v3405n a>        for (;;) {v34062/a>                2spa= class="comment">/* Set address */2/spa="v34072/a>                2a href="+code=buf" class="sref">bufn a> = (2a href="+code=u8" class="sref">u8n a>)2a href="+code=reg" class="sref">reg2/a>;v34082/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=chip" class="sref">chip2/a>, &2a href="+code=buf" class="sref">bufn a>, 1);v34092/a>                if (2a href="+code=rc" class="sref">rc2/a> <= 0)v34102/a>                        goto 2a href="+code=error" class="sref">error2/a>;v34112/a>                2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=i2c_master_recv" class="sref">i2c_master_recv2/a>(2a href="+code=chip" class="sref">chip2/a>, &2a href="+code=buf" class="sref">bufn a>, 1);v34122/a>                if (2a href="+code=rc" class="sref">rc2/a> <= 0)v34132/a>                        goto 2a href="+code=error" class="sref">error2/a>;v34142/a>                relurn (int)2a href="+code=buf" class="sref">bufn a>;v3415n a>        2a href="+code=error" class="sref">error2/a>:v34162/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"Error reading LM87, relrying...\n"2/spa=");v34172/a>                if (++2a href="+code=tries" class="sref">tries2/a> > 10) {v34182/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Error reading LM87 !\n"2/spa=");v34192/a>                        relurn -1;v34202/a>                }v34212/a>                2a href="+code=msleep" class="sref">msleep2/a>(10);v34222/a>        }v34232/a>}v34242/a>v34252/a>static int 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(int 2a href="+code=reg" class="sref">reg2/a>, unsigned char *2a href="+code=buf" class="sref">bufn a>, int 2a href="+code=nb" class="sref">nb2/a>)v34262/a>{v34272/a>        int 2a href="+code=tries" class="sref">tries2/a>, 2a href="+code=nr" class="sref">nr2/a>, 2a href="+code=nw" class="sref">nwn a>;v34282/a>v34292/a>        2a href="+code=buf" class="sref">bufn a>[0] = 2a href="+code=reg" class="sref">reg2/a>;v343on a>        2a href="+code=tries" class="sref">tries2/a> = 0;v34312/a>        for (;;) {v34322/a>                2a href="+code=nw" class="sref">nwn a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=fcu" class="sref">fcu2/a>, 2a href="+code=buf" class="sref">bufn a>, 1);v34332/a>                if (2a href="+code=nw" class="sref">nwn a> > 0 || (2a href="+code=nw" class="sref">nwn a> < 0 && 2a href="+code=nw" class="sref">nwn a> != -2a href="+code=EIO" class="sref">EIO2/a>) || 2a href="+code=tries" class="sref">tries2/a> >= 100)v34342/a>                        break;v34352/a>                2a href="+code=msleep" class="sref">msleep2/a>(10);v34362/a>                ++2a href="+code=tries" class="sref">tries2/a>;v34372/a>        }v3438n a>        if (2a href="+code=nw" class="sref">nwn a> <= 0) {v34392/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"Failure writing address to FCU: %d"2/spa=", 2a href="+code=nw" class="sref">nwn a>);v34402/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v34412/a>        }v34422/a>        2a href="+code=tries" class="sref">tries2/a> = 0;v34432/a>        for (;;) {v34442/a>                2a href="+code=nr" class="sref">nr2/a> = 2a href="+code=i2c_master_recv" class="sref">i2c_master_recv2/a>(2a href="+code=fcu" class="sref">fcu2/a>, 2a href="+code=buf" class="sref">bufn a>, 2a href="+code=nb" class="sref">nb2/a>);v34452/a>                if (2a href="+code=nr" class="sref">nr2/a> > 0 || (2a href="+code=nr" class="sref">nr2/a> < 0 && 2a href="+code=nr" class="sref">nr2/a> != -2a href="+code=ENODEV" class="sref">ENODEV2/a>) || 2a href="+code=tries" class="sref">tries2/a> >= 100)v34462/a>                        break;v34472/a>                2a href="+code=msleep" class="sref">msleep2/a>(10);v34482/a>                ++2a href="+code=tries" class="sref">tries2/a>;v3449n a>        }v34502/a>        if (2a href="+code=nr" class="sref">nr2/a> <= 0)v34512/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"Failure reading data from FCU: %d"2/spa=", 2a href="+code=nw" class="sref">nwn a>);v34522/a>        relurn 2a href="+code=nr" class="sref">nr2/a>;v34532/a>}v34542/a>v34552/a>static int 2a href="+code=fan_write_reg" class="sref">fan_write_reg2/a>(int 2a href="+code=reg" class="sref">reg2/a>, const unsigned char *2a href="+code=ptr" class="sref">ptrn a>, int 2a href="+code=nb" class="sref">nb2/a>)v34562/a>{v34572/a>        int 2a href="+code=tries" class="sref">tries2/a>, 2a href="+code=nw" class="sref">nwn a>;v34582/a>        unsigned char 2a href="+code=buf" class="sref">bufn a>[16];v34592/a>v346on a>        2a href="+code=buf" class="sref">bufn a>[0] = 2a href="+code=reg" class="sref">reg2/a>;v34612/a>        2a href="+code=memcpy" class="sref">memcpy2/a>(2a href="+code=buf" class="sref">bufn a>+1, 2a href="+code=ptr" class="sref">ptrn a>, 2a href="+code=nb" class="sref">nb2/a>);v34622/a>        ++2a href="+code=nb" class="sref">nb2/a>;v34632/a>        2a href="+code=tries" class="sref">tries2/a> = 0;v34642/a>        for (;;) {v34652/a>                2a href="+code=nw" class="sref">nwn a> = 2a href="+code=i2c_master_send" class="sref">i2c_master_send2/a>(2a href="+code=fcu" class="sref">fcu2/a>, 2a href="+code=buf" class="sref">bufn a>, 2a href="+code=nb" class="sref">nb2/a>);v34662/a>                if (2a href="+code=nw" class="sref">nwn a> > 0 || (2a href="+code=nw" class="sref">nwn a> < 0 && 2a href="+code=nw" class="sref">nwn a> != -2a href="+code=EIO" class="sref">EIO2/a>) || 2a href="+code=tries" class="sref">tries2/a> >= 100)v34672/a>                        break;v34682/a>                2a href="+code=msleep" class="sref">msleep2/a>(10);v34692/a>                ++2a href="+code=tries" class="sref">tries2/a>;v34702/a>        }v34712/a>        if (2a href="+code=nw" class="sref">nwn a> < 0)v34722/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"Failure writing to FCU: %d"2/spa=", 2a href="+code=nw" class="sref">nwn a>);v34732/a>        relurn 2a href="+code=nw" class="sref">nwn a>;v34742/a>}v34752/a>v34762/a>static int 2a href="+code=start_fcu" class="sref">start_fcu2/a>(void)v34772/a>{v34782/a>        unsigned char 2a href="+code=buf" class="sref">bufn a> = 0xff;v34792/a>        int 2a href="+code=rc" class="sref">rc2/a>;v34802/a>v34812/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_write_reg" class="sref">fan_write_reg2/a>(0xe, &2a href="+code=buf" class="sref">bufn a>, 1);v34822/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0)v34832/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v34842/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_write_reg" class="sref">fan_write_reg2/a>(0x2e, &2a href="+code=buf" class="sref">bufn a>, 1);v34852/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0)v34862/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v34872/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0, &2a href="+code=buf" class="sref">bufn a>, 1);v3488n a>        if (2a href="+code=rc" class="sref">rc2/a> < 0)v34892/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v349on a>        2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a> = (2a href="+code=buf" class="sref">bufn a> == 1) ? 2 : 3;v34912/a>        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_DEBUG" class="sref">KERN_DEBUGn a> 2spa= class="string">"FCU Initialized, RPM fan shift is %d\n"2/spa=",v34922/a>               2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>);v34932/a>v34942/a>        relurn 0;v34952/a>}v34962/a>v34972/a>static int 2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(int 2a href="+code=fan_index" class="sref">fan_indexn a>, int 2a href="+code=rpm" class="sref">rpm2/a>)v34982/a>{v34992/a>        unsigned char 2a href="+code=buf" class="sref">bufn a>[2];v35002/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=id" class="sref">id2/a>, 2a href="+code=min" class="sref">min2/a>, 2a href="+code=max" class="sref">max2/a>;v35012/a>v35022/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=type" class="sref">typen a> != 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>)v35032/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35042/a>        2a href="+code=id" class="sref">id2/a> = 2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=id" class="sref">id2/a>; v35052/a>        if (2a href="+code=id" class="sref">id2/a> == 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>)v35062/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35072/a>v35082/a>        2a href="+code=min" class="sref">min2/a> = 2400 >> 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>;v35092/a>        2a href="+code=max" class="sref">max2/a> = 56000 >> 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>;v35102/a>v35112/a>        if (2a href="+code=rpm" class="sref">rpm2/a> < 2a href="+code=min" class="sref">min2/a>)v35122/a>                2a href="+code=rpm" class="sref">rpm2/a> = 2a href="+code=min" class="sref">min2/a>;v35132/a>        else if (2a href="+code=rpm" class="sref">rpm2/a> > 2a href="+code=max" class="sref">max2/a>)v35142/a>                2a href="+code=rpm" class="sref">rpm2/a> = 2a href="+code=max" class="sref">max2/a>;v3515n a>        2a href="+code=buf" class="sref">bufn a>[0] = 2a href="+code=rpm" class="sref">rpm2/a> >> (8 - 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>);v35162/a>        2a href="+code=buf" class="sref">bufn a>[1] = 2a href="+code=rpm" class="sref">rpm2/a> << 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>;v35172/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_write_reg" class="sref">fan_write_reg2/a>(0x10 + (2a href="+code=id" class="sref">id2/a> * 2), 2a href="+code=buf" class="sref">bufn a>, 2);v3518n a>        if (2a href="+code=rc" class="sref">rc2/a> < 0)v35192/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v35202/a>        relurn 0;v35212/a>}v35222/a>v35232/a>static int 2a href="+code=get_rpm_fan" class="sref">get_rpm_fan2/a>(int 2a href="+code=fan_index" class="sref">fan_indexn a>, int 2a href="+code=programmed" class="sref">programmed2/a>)v35242/a>{v3525n a>        unsigned char 2a href="+code=failure" class="sref">failure2/a>;v3526n a>        unsigned char 2a href="+code=active" class="sref">active2/a>;v35272/a>        unsigned char 2a href="+code=buf" class="sref">bufn a>[2];v3528n a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=id" class="sref">id2/a>, 2a href="+code=reg_base" class="sref">reg_base2/a>;v35292/a>v35302/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=type" class="sref">typen a> != 2a href="+code=FCU_FAN_RPM" class="sref">FCU_FAN_RPM2/a>)v35312/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35322/a>        2a href="+code=id" class="sref">id2/a> = 2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=id" class="sref">id2/a>; v35332/a>        if (2a href="+code=id" class="sref">id2/a> == 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>)v35342/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35352/a>v35362/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0xb, &2a href="+code=failure" class="sref">failure2/a>, 1);v35372/a>        if (2a href="+code=rc" class="sref">rc2/a> != 1)v35382/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v35392/a>        if ((2a href="+code=failure" class="sref">failure2/a> & (1 << 2a href="+code=id" class="sref">id2/a>)) != 0)v35402/a>                relurn -2a href="+code=EFAULT" class="sref">EFAULT2/a>;v35412/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0xd, &2a href="+code=active" class="sref">active2/a>, 1);v35422/a>        if (2a href="+code=rc" class="sref">rc2/a> != 1)v35432/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v35442/a>        if ((2a href="+code=active" class="sref">active2/a> & (1 << 2a href="+code=id" class="sref">id2/a>)) == 0)v35452/a>                relurn -2a href="+code=ENXIO" class="sref">ENXIO2/a>;v35462/a>v35472/a>        2spa= class="comment">/* Programmed value or real current speed */2/spa="v35482/a>        2a href="+code=reg_base" class="sref">reg_base2/a> = 2a href="+code=programmed" class="sref">programmed2/a> ? 0x10 : 0x11;v35492/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(2a href="+code=reg_base" class="sref">reg_base2/a> + (2a href="+code=id" class="sref">id2/a> * 2), 2a href="+code=buf" class="sref">bufn a>, 2);v35502/a>        if (2a href="+code=rc" class="sref">rc2/a> != 2)v35512/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v35522/a>v35532/a>        relurn (2a href="+code=buf" class="sref">bufn a>[0] << (8 - 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>)) | 2a href="+code=buf" class="sref">bufn a>[1] >> 2a href="+code=fcu_rpm_shift" class="sref">fcu_rpm_shift2/a>;v35542/a>}v35552/a>v35562/a>static int 2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(int 2a href="+code=fan_index" class="sref">fan_indexn a>, int 2a href="+code=pwm" class="sref">pwm2/a>)v35572/a>{v35582/a>        unsigned char 2a href="+code=buf" class="sref">bufn a>[2];v35592/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=id" class="sref">id2/a>;v35602/a>v35612/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=type" class="sref">typen a> != 2a href="+code=FCU_FAN_PWM" class="sref">FCU_FAN_PWM2/a>)v35622/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35632/a>        2a href="+code=id" class="sref">id2/a> = 2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=id" class="sref">id2/a>; v35642/a>        if (2a href="+code=id" class="sref">id2/a> == 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>)v35652/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35662/a>v35672/a>        if (2a href="+code=pwm" class="sref">pwm2/a> < 10)v35682/a>                2a href="+code=pwm" class="sref">pwm2/a> = 10;v35692/a>        else if (2a href="+code=pwm" class="sref">pwm2/a> > 100)v35702/a>                2a href="+code=pwm" class="sref">pwm2/a> = 100;v35712/a>        2a href="+code=pwm" class="sref">pwm2/a> = (2a href="+code=pwm" class="sref">pwm2/a> * 2559) / 1000;v35722/a>        2a href="+code=buf" class="sref">bufn a>[0] = 2a href="+code=pwm" class="sref">pwm2/a>;v35732/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_write_reg" class="sref">fan_write_reg2/a>(0x30 + (2a href="+code=id" class="sref">id2/a> * 2), 2a href="+code=buf" class="sref">bufn a>, 1);v35742/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0)v35752/a>                relurn 2a href="+code=rc" class="sref">rc2/a>;v35762/a>        relurn 0;v35772/a>}v35782/a>v35792/a>static int 2a href="+code=get_pwm_fan" class="sref">get_pwm_fan2/a>(int 2a href="+code=fan_index" class="sref">fan_indexn a>)v35802/a>{v35812/a>        unsigned char 2a href="+code=failure" class="sref">failure2/a>;v35822/a>        unsigned char 2a href="+code=active" class="sref">active2/a>;v35832/a>        unsigned char 2a href="+code=buf" class="sref">bufn a>[2];v35842/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=id" class="sref">id2/a>;v35852/a>v35862/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=type" class="sref">typen a> != 2a href="+code=FCU_FAN_PWM" class="sref">FCU_FAN_PWM2/a>)v35872/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35882/a>        2a href="+code=id" class="sref">id2/a> = 2a href="+code=fcu_fans" class="sref">fcu_fansn a>[2a href="+code=fan_index" class="sref">fan_indexn a>].2a href="+code=id" class="sref">id2/a>; v35892/a>        if (2a href="+code=id" class="sref">id2/a> == 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>)v35902/a>                relurn -2a href="+code=EINVAL" class="sref">EINVAL2/a>;v35912/a>v35922/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0x2b, &2a href="+code=failure" class="sref">failure2/a>, 1);v35932/a>        if (2a href="+code=rc" class="sref">rc2/a> != 1)v35942/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v35952/a>        if ((2a href="+code=failure" class="sref">failure2/a> & (1 << 2a href="+code=id" class="sref">id2/a>)) != 0)v35962/a>                relurn -2a href="+code=EFAULT" class="sref">EFAULT2/a>;v35972/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0x2d, &2a href="+code=active" class="sref">active2/a>, 1);v3598n a>        if (2a href="+code=rc" class="sref">rc2/a> != 1)v35992/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v36002/a>        if ((2a href="+code=active" class="sref">active2/a> & (1 << 2a href="+code=id" class="sref">id2/a>)) == 0)v36012/a>                relurn -2a href="+code=ENXIO" class="sref">ENXIO2/a>;v36022/a>v36032/a>        2spa= class="comment">/* Programmed value or real current speed */2/spa="v36042/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=fan_read_reg" class="sref">fan_read_reg2/a>(0x30 + (2a href="+code=id" class="sref">id2/a> * 2), 2a href="+code=buf" class="sref">bufn a>, 1);v36052/a>        if (2a href="+code=rc" class="sref">rc2/a> != 1)v36062/a>                relurn -2a href="+code=EIO" class="sref">EIO2/a>;v36072/a>v36082/a>        relurn (2a href="+code=buf" class="sref">bufn a>[0] * 1000) / 2559;v36092/a>}v36102/a>v36112/a>static void 2a href="+code=tickle_fcu" class="sref">tickle_fcu2/a>(void)v36122/a>{v36132/a>        int 2a href="+code=pwm" class="sref">pwm2/a>;v36142/a>v3615n a>        2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=get_pwm_fan" class="sref">get_pwm_fan2/a>(2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>);v36162/a>v36172/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"FCU Tickle, slots fan is: %d\n"2/spa=", 2a href="+code=pwm" class="sref">pwm2/a>);v3618n a>        if (2a href="+code=pwm" class="sref">pwm2/a> < 0)v36192/a>                2a href="+code=pwm" class="sref">pwm2/a> = 100;v36202/a>v36212/a>        if (!2a href="+code=rackmac" class="sref">rackmac2/a>) {v36222/a>                2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=SLOTS_FAN_DEFAULT_PWM" class="sref">SLOTS_FAN_DEFAULT_PWM2/a>;v36232/a>        } else if (2a href="+code=pwm" class="sref">pwm2/a> < 2a href="+code=SLOTS_PID_OUTPUT_MIN" class="sref">SLOTS_PID_OUTPUT_MIN2/a>)v36242/a>                2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=SLOTS_PID_OUTPUT_MIN" class="sref">SLOTS_PID_OUTPUT_MIN2/a>;v36252/a>v3626n a>        2spa= class="comment">/* That is hopefully enough to make the FCU happy */2/spa="v36272/a>        2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>, 2a href="+code=pwm" class="sref">pwm2/a>);v3628n a>}v36292/a>v36302/a>v36312/a>2spa= class="comment">/*2/spa="v36322/a>2spa= class="comment"> * Utility routine to read the CPU calibration EEPROM data2/spa="v36332/a>2spa= class="comment"> * from the device-tree2/spa="v36342/a>2spa= class="comment"> */2/spa="v36352/a>static int 2a href="+code=read_eeprom" class="sref">read_eeprom2/a>(int 2a href="+code=cpu" class="sref">cpu2/a>, struct 2a href="+code=mpu_data" class="sref">mpu_data2/a> *2a href="+code=out" class="sref">out2/a>)v36362/a>{v36372/a>        struct 2a href="+code=device_node" class="sref">device_node2/a> *2a href="+code=np" class="sref">np2/a>;v36382/a>        char 2a href="+code=nodenam " class="sref">nodenam n a>[64];v36392/a>        const 2a href="+code=u8" class="sref">u82/a> *2a href="+code=data" class="sref">data2/a>;v36402/a>        int 2a href="+code=len" class="sref">len2/a>;v36412/a>v36422/a>        2spa= class="comment">/* prom.c routine for finding a node by path is a bit brain dead2/spa="v36432/a>2spa= class="comment">         * and requires exact @xxx unit numbers. This is a bit ugly but2/spa="v36442/a>2spa= class="comment">         * will work for these machines2/spa="v36452/a>2spa= class="comment">         */2/spa="v36462/a>        2a href="+code=sprintf" class="sref">sprintf2/a>(2a href="+code=nodenam " class="sref">nodenam n a>, 2spa= class="string">"/u3@0,f8000000/i2c@f8001000/cpuid@a%d"2/spa=", 2a href="+code=cpu" class="sref">cpu2/a> ? 2 : 0);v36472/a>        2a href="+code=np" class="sref">np2/a> = 2a href="+code=of_find_node_by_path" class="sref">of_find_node_by_path2/a>(2a href="+code=nodenam " class="sref">nodenam n a>);v3648n a>        if (2a href="+code=np" class="sref">np2/a> == 2a href="+code=NULL" class="sref">NULL2/a>) {v36492/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Failed to retrieve cpuid node from device-tree\n"2/spa=");v36502/a>                relurn -2a href="+code=ENODEV" class="sref">ENODEV2/a>;v36512/a>        }v36522/a>        2a href="+code=data" class="sref">data2/a> = 2a href="+code=of_get_property" class="sref">of_get_property2/a>(2a href="+code=np" class="sref">np2/a>, 2spa= class="string">"cpuid"2/spa=", &2a href="+code=len" class="sref">len2/a>);v36532/a>        if (2a href="+code=data" class="sref">data2/a> == 2a href="+code=NULL" class="sref">NULL2/a>) {v36542/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERRn a> 2spa= class="string">"therm_pm72: Failed to retrieve cpuid property from device-tree\n"2/spa=");v36552/a>                2a href="+code=of_node_put" class="sref">of_node_put2/a>(2a href="+code=np" class="sref">np2/a>);v36562/a>                relurn -2a href="+code=ENODEV" class="sref">ENODEV2/a>;v36572/a>        }v36582/a>        2a href="+code=memcpy" class="sref">memcpy2/a>(2a href="+code=out" class="sref">out2/a>, 2a href="+code=data" class="sref">data2/a>, sizeof(struct 2a href="+code=mpu_data" class="sref">mpu_data2/a>));v36592/a>        2a href="+code=of_node_put" class="sref">of_node_put2/a>(2a href="+code=np" class="sref">np2/a>);v36602/a>        v36612/a>        relurn 0;v36622/a>}v36632/a>v36642/a>static void 2a href="+code=fetch_cpu_pumps_minmax" class="sref">fetch_cpu_pumps_minmax2/a>(void)v36652/a>{v36662/a>        struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat 0" class="sref">stat 02/a> = &2a href="+code=processor_stat " class="sref">processor_stat n a>[0];v36672/a>        struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat 1" class="sref">stat 12/a> = &2a href="+code=processor_stat " class="sref">processor_stat n a>[1];v36682/a>        2a href="+code=u16" class="sref">u162/a> 2a href="+code=pump_min" class="sref">pump_min2/a> = 0, 2a href="+code=pump_max" class="sref">pump_max2/a> = 0xffff;v36692/a>        2a href="+code=u16" class="sref">u162/a> 2a href="+code=tmp" class="sref">tmpn a>[4];v36702/a>v36712/a>        2spa= class="comment">/* Try to fetch pumps min/max infos from eeprom */2/spa="v36722/a>v36732/a>        2a href="+code=memcpy" class="sref">memcpy2/a>(&2a href="+code=tmp" class="sref">tmpn a>, &2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=processor_part_num" class="sref">processor_part_numn a>, 8);v36742/a>        if (2a href="+code=tmp" class="sref">tmpn a>[0] != 0xffff && 2a href="+code=tmp" class="sref">tmpn a>[1] != 0xffff) {v36752/a>                2a href="+code=pump_min" class="sref">pump_min2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=pump_min" class="sref">pump_min2/a>, 2a href="+code=tmp" class="sref">tmpn a>[0]);v36762/a>                2a href="+code=pump_max" class="sref">pump_max2/a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=pump_max" class="sref">pump_max2/a>, 2a href="+code=tmp" class="sref">tmpn a>[1]);v36772/a>        }v3678n a>        if (2a href="+code=tmp" class="sref">tmpn a>[2] != 0xffff && 2a href="+code=tmp" class="sref">tmpn a>[3] != 0xffff) {v36792/a>                2a href="+code=pump_min" class="sref">pump_min2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=pump_min" class="sref">pump_min2/a>, 2a href="+code=tmp" class="sref">tmpn a>[2]);v36802/a>                2a href="+code=pump_max" class="sref">pump_max2/a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=pump_max" class="sref">pump_max2/a>, 2a href="+code=tmp" class="sref">tmpn a>[3]);v36812/a>        }v36822/a>v36832/a>        2spa= class="comment">/* Double check the values, this _IS_ needed as the EEPROM on2/spa="v36842/a>2spa= class="comment">         * some dual 2.5Ghz G5s seem, at least, to have both min & max2/spa="v36852/a>2spa= class="comment">         * sam  to the sam  value ... (grrrr)2/spa="v36862/a>2spa= class="comment">         */2/spa="v36872/a>        if (2a href="+code=pump_min" class="sref">pump_min2/a> == 2a href="+code=pump_max" class="sref">pump_max2/a> || 2a href="+code=pump_min" class="sref">pump_min2/a> == 0 || 2a href="+code=pump_max" class="sref">pump_max2/a> == 0xffff) {v36882/a>                2a href="+code=pump_min" class="sref">pump_min2/a> = 2a href="+code=CPU_PUMP_OUTPUT_MIN" class="sref">CPU_PUMP_OUTPUT_MIN2/a>;v36892/a>                2a href="+code=pump_max" class="sref">pump_max2/a> = 2a href="+code=CPU_PUMP_OUTPUT_MAX" class="sref">CPU_PUMP_OUTPUT_MAX2/a>;v36902/a>        }v36912/a>v36922/a>        2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_min" class="sref">pump_min2/a> = 2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=pump_min" class="sref">pump_min2/a> = 2a href="+code=pump_min" class="sref">pump_min2/a>;v36932/a>        2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_max" class="sref">pump_max2/a> = 2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=pump_max" class="sref">pump_max2/a> = 2a href="+code=pump_max" class="sref">pump_max2/a>;v36942/a>}v36952/a>v36962/a>2spa= class="comment">/* 2/spa="v36972/a>2spa= class="comment"> * Now, unfortunat ly, sysfs doesn't give us a nice void * we could2/spa="v3698n a>2spa= class="comment"> * pass around to the attribute functions, so we don't really have2/spa="v36992/a>2spa= class="comment"> * choice but implement a bunch of them...2/spa="v37002/a>2spa= class="comment"> *2/spa="v37012/a>2spa= class="comment"> * That sucks a bit, we take the lock because FIX32TOPRINT evaluat s2/spa="v37022/a>2spa= class="comment"> * the input twice... I accept patches :)2/spa="v37032/a>2spa= class="comment"> */2/spa="v37042/a>#define 2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=nam " class="sref">nam n a>, 2a href="+code=data" class="sref">data2/a>)                         \v37052/a>static 2a href="+code=ssize_t" class="sref">ssize_t2/a> 2a href="+code=show_" class="sref">show_2/a>##nam (struct 2a href="+code=device" class="sref">device2/a> *2a href="+code=dev" class="sref">dev2/a>, struct 2a href="+code=device_attribute" class="sref">device_attribute2/a> *2a href="+code=attr" class="sref">attr2/a>, char *2a href="+code=buf" class="sref">bufn a>)        \v37062/a>{                                                               \v37072/a>        2a href="+code=ssize_t" class="sref">ssize_t2/a> 2a href="+code=r" class="sref">r2/a>;                                              \v37082/a>        2a href="+code=mutex_lock" class="sref">mutex_lock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);                                       \v37092/a>        2a href="+code=r" class="sref">r2/a> = 2a href="+code=sprintf" class="sref">sprintf2/a>(2a href="+code=buf" class="sref">bufn a>, 2spa= class="string">"%d.%03d"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=data" class="sref">data2/a>));        \v37102/a>        2a href="+code=mutex_unlock" class="sref">mutex_unlock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);                                     \v37112/a>        relurn 2a href="+code=r" class="sref">r2/a>;                                               \v37122/a>}v37132/a>#define 2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=nam " class="sref">nam n a>, 2a href="+code=data" class="sref">data2/a>)                         \v37142/a>static 2a href="+code=ssize_t" class="sref">ssize_t2/a> 2a href="+code=show_" class="sref">show_2/a>##nam (struct 2a href="+code=device" class="sref">device2/a> *2a href="+code=dev" class="sref">dev2/a>, struct 2a href="+code=device_attribute" class="sref">device_attribute2/a> *2a href="+code=attr" class="sref">attr2/a>, char *2a href="+code=buf" class="sref">bufn a>)        \v3715n a>{                                                               \v37162/a>        relurn 2a href="+code=sprintf" class="sref">sprintf2/a>(2a href="+code=buf" class="sref">bufn a>, 2spa= class="string">"%d"2/spa=", 2a href="+code=data" class="sref">data2/a>);                        \v37172/a>}v37182/a>v37192/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu0_temperature" class="sref">cpu0_temperaturen a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[0].2a href="+code=last_temp" class="sref">last_temp2/a>)v37202/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu0_voltage" class="sref">cpu0_voltagen a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[0].2a href="+code=voltage" class="sref">voltagen a>)v37212/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu0_current" class="sref">cpu0_currentn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[0].2a href="+code=current_a" class="sref">current_an a>)v37222/a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=cpu0_exhaust_fan_rpm" class="sref">cpu0_exhaust_fan_rpmn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[0].2a href="+code=rpm" class="sref">rpmn a>)v37232/a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=cpu0_intake_fan_rpm" class="sref">cpu0_intake_fan_rpmn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[0].2a href="+code=intake_rpm" class="sref">intake_rpmn a>)v37242/a>v37252/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu1_temperature" class="sref">cpu1_temperaturen a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[1].2a href="+code=last_temp" class="sref">last_temp2/a>)v3726n a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu1_voltage" class="sref">cpu1_voltagen a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[1].2a href="+code=voltage" class="sref">voltagen a>)v37272/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=cpu1_current" class="sref">cpu1_currentn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[1].2a href="+code=current_a" class="sref">current_an a>)v3728n a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=cpu1_exhaust_fan_rpm" class="sref">cpu1_exhaust_fan_rpmn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[1].2a href="+code=rpm" class="sref">rpmn a>)v37292/a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=cpu1_intake_fan_rpm" class="sref">cpu1_intake_fan_rpmn a>, 2a href="+code=processor_stat " class="sref">processor_stat n a>[1].2a href="+code=intake_rpm" class="sref">intake_rpmn a>)v37302/a>v37312/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=backside_temperature" class="sref">backside_temperaturen a>, 2a href="+code=backside_stat " class="sref">backside_stat n a>.2a href="+code=last_temp" class="sref">last_temp2/a>)v37322/a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=backside_fan_pwm" class="sref">backside_fan_pwmn a>, 2a href="+code=backside_stat " class="sref">backside_stat n a>.2a href="+code=pwm" class="sref">pwm2/a>)v37332/a>v37342/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=drives_temperature" class="sref">drives_temperaturen a>, 2a href="+code=drives_stat " class="sref">drives_stat n a>.2a href="+code=last_temp" class="sref">last_temp2/a>)v37352/a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=drives_fan_rpm" class="sref">drives_fan_rpmn a>, 2a href="+code=drives_stat " class="sref">drives_stat n a>.2a href="+code=rpm" class="sref">rpmn a>)v37362/a>v37372/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=slots_temperature" class="sref">slots_temperaturen a>, 2a href="+code=slots_stat " class="sref">slots_stat n a>.2a href="+code=last_temp" class="sref">last_temp2/a>)v3738n a>2a href="+code=BUILD_SHOW_FUNC_INT" class="sref">BUILD_SHOW_FUNC_INT2/a>(2a href="+code=slots_fan_pwm" class="sref">slots_fan_pwmn a>, 2a href="+code=slots_stat " class="sref">slots_stat n a>.2a href="+code=pwm" class="sref">pwm2/a>)v37392/a>v37402/a>2a href="+code=BUILD_SHOW_FUNC_FIX" class="sref">BUILD_SHOW_FUNC_FIX2/a>(2a href="+code=dimms_temperature" class="sref">dimms_temperaturen a>, 2a href="+code=dimms_stat " class="sref">dimms_stat n a>.2a href="+code=last_temp" class="sref">last_temp2/a>)v37412/a>v37422/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu0_temperature" class="sref">cpu0_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu0_temperature" class="sref">show_cpu0_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37432/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu0_voltage" class="sref">cpu0_voltagen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu0_voltage" class="sref">show_cpu0_voltagen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37442/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu0_current" class="sref">cpu0_currentn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu0_current" class="sref">show_cpu0_currentn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37452/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu0_exhaust_fan_rpm" class="sref">cpu0_exhaust_fan_rpmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu0_exhaust_fan_rpm" class="sref">show_cpu0_exhaust_fan_rpmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37462/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu0_intake_fan_rpm" class="sref">cpu0_intake_fan_rpmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu0_intake_fan_rpm" class="sref">show_cpu0_intake_fan_rpmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37472/a>v3748n a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu1_temperature" class="sref">cpu1_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu1_temperature" class="sref">show_cpu1_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37492/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu1_voltage" class="sref">cpu1_voltagen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu1_voltage" class="sref">show_cpu1_voltagen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37502/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu1_current" class="sref">cpu1_currentn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu1_current" class="sref">show_cpu1_currentn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37512/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu1_exhaust_fan_rpm" class="sref">cpu1_exhaust_fan_rpmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu1_exhaust_fan_rpm" class="sref">show_cpu1_exhaust_fan_rpmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37522/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=cpu1_intake_fan_rpm" class="sref">cpu1_intake_fan_rpmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_cpu1_intake_fan_rpm" class="sref">show_cpu1_intake_fan_rpmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37532/a>v37542/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=backside_temperature" class="sref">backside_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_backside_temperature" class="sref">show_backside_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37552/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=backside_fan_pwm" class="sref">backside_fan_pwmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_backside_fan_pwm" class="sref">show_backside_fan_pwmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37562/a>v37572/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=drives_temperature" class="sref">drives_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_drives_temperature" class="sref">show_drives_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v3758n a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=drives_fan_rpm" class="sref">drives_fan_rpmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_drives_fan_rpm" class="sref">show_drives_fan_rpmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37592/a>v37602/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=slots_temperature" class="sref">slots_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_slots_temperature" class="sref">show_slots_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37612/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=slots_fan_pwm" class="sref">slots_fan_pwmn a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_slots_fan_pwm" class="sref">show_slots_fan_pwmn a>,2a href="+code=NULL" class="sref">NULL2/a>);v37622/a>v37632/a>static 2a href="+code=DEVICE_ATTR" class="sref">DEVICE_ATTR2/a>(2a href="+code=dimms_temperature" class="sref">dimms_temperaturen a>,2a href="+code=S_IRUGO" class="sref">S_IRUGOn a>,2a href="+code=show_dimms_temperature" class="sref">show_dimms_temperaturen a>,2a href="+code=NULL" class="sref">NULL2/a>);v37642/a>v37652/a>2spa= class="comment">/*2/spa="v37662/a>2spa= class="comment"> * CPUs fans control loop2/spa="v37672/a>2spa= class="comment"> */2/spa="v37682/a>v37692/a>static int 2a href="+code=do_read_one_cpu_values" class="sref">do_read_one_cpu_values2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat 2/a>, 2a href="+code=s32" class="sref">s322/a> *2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=s32" class="sref">s322/a> *2a href="+code=power" class="sref">power2/a>)v37702/a>{v37712/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=ltemp" class="sref">ltemp2/a>, 2a href="+code=volts" class="sref">volts2/a>, 2a href="+code=amps" class="sref">amps2/a>;v37722/a>        int 2a href="+code=index" class="sref">index2/a>, 2a href="+code=rc" class="sref">rc2/a> = 0;v37732/a>v37742/a>        2spa= class="comment">/* Default (i= case of error) */2/spa="v37752/a>        *2a href="+code=temp" class="sref">temp2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a>;v37762/a>        *2a href="+code=power" class="sref">power2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a>;v37772/a>v3778n a>        if (2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> == 2a href="+code=CPU_PID_TYPE_RACKMAC" class="sref">CPU_PID_TYPE_RACKMAC2/a>)v37792/a>                2a href="+code=index" class="sref">index2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> == 0) ?v37802/a>                        2a href="+code=CPU_A1_FAN_RPM_INDEX" class="sref">CPU_A1_FAN_RPM_INDEX2/a> : 2a href="+code=CPU_B1_FAN_RPM_INDEX" class="sref">CPU_B1_FAN_RPM_INDEX2/a>;v37812/a>        elsev37822/a>                2a href="+code=index" class="sref">index2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> == 0) ?v37832/a>                        2a href="+code=CPUA_EXHAUST_FAN_RPM_INDEX" class="sref">CPUA_EXHAUST_FAN_RPM_INDEX2/a> : 2a href="+code=CPUB_EXHAUST_FAN_RPM_INDEX" class="sref">CPUB_EXHAUST_FAN_RPM_INDEX2/a>;v37842/a>v37852/a>        2spa= class="comment">/* Read current fan status */2/spa="v37862/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=get_rpm_fan" class="sref">get_rpm_fan2/a>(2a href="+code=index" class="sref">index2/a>, !2a href="+code=RPM_PID_USE_ACTUAL_SPEED" class="sref">RPM_PID_USE_ACTUAL_SPEED2/a>);v37872/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v37882/a>                2spa= class="comment">/* XXX What do we do now ? Nothing for now, keep old value, but2/spa="v37892/a>2spa= class="comment">                 * relurn error upstream2/spa="v37902/a>2spa= class="comment">                 */2/spa="v37912/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  cpu %d, fan reading error !\n"2/spa=", 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a>);v37922/a>        } else {v37932/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=rc" class="sref">rc2/a>;v37942/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  cpu %d, exhaust RPM: %d\n"2/spa=", 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v37952/a>        }v37962/a>v37972/a>        2spa= class="comment">/* Get some sensor readings and scale it */2/spa="v37982/a>        2a href="+code=ltemp" class="sref">ltemp2/a> = 2a href="+code=read_smon_adc" class="sref">read_smon_adc2/a>(2a href="+code=stat " class="sref">stat 2/a>, 1);v37992/a>        if (2a href="+code=ltemp" class="sref">ltemp2/a> == -1) {v38002/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v38012/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>++;v38022/a>                if (2a href="+code=rc" class="sref">rc2/a> == 0)v38032/a>                        2a href="+code=rc" class="sref">rc2/a> = -2a href="+code=EIO" class="sref">EIO2/a>;v38042/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  cpu %d, temp reading error !\n"2/spa=", 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a>);v38052/a>        } else {v38062/a>                2spa= class="comment">/* Fixup temperature according to diode calibration2/spa="v38072/a>2spa= class="comment">                 */2/spa="v38082/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  cpu %d, temp raw: %04x, m_diode: %04x, b_diode: %04x\n"2/spa=",v38092/a>                    2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a>,v38102/a>                    2a href="+code=ltemp" class="sref">ltemp2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=mdiode" class="sref">mdiode2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=bdiode" class="sref">bdiode2/a>);v38112/a>                *2a href="+code=temp" class="sref">temp2/a> = ((2a href="+code=s32" class="sref">s322/a>)2a href="+code=ltemp" class="sref">ltemp2/a> * (2a href="+code=s32" class="sref">s322/a>)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=mdiode" class="sref">mdiode2/a> + ((2a href="+code=s32" class="sref">s322/a>)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=bdiode" class="sref">bdiode2/a> << 12)) >> 2;v38122/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=last_temp" class="sref">last_temp2/a> = *2a href="+code=temp" class="sref">temp2/a>;v38132/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  temp: %d.%03d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>((*2a href="+code=temp" class="sref">temp2/a>)));v38142/a>        }v38152/a>v38162/a>        2spa= class="comment">/*2/spa="v38172/a>2spa= class="comment">         * Read voltage & current and calculat  power2/spa="v3818n a>2spa= class="comment">         */2/spa="v38192/a>        2a href="+code=volts" class="sref">volts2/a> = 2a href="+code=read_smon_adc" class="sref">read_smon_adc2/a>(2a href="+code=stat " class="sref">stat 2/a>, 3);v38202/a>        2a href="+code=amps" class="sref">amps2/a> = 2a href="+code=read_smon_adc" class="sref">read_smon_adc2/a>(2a href="+code=stat " class="sref">stat 2/a>, 4);v38212/a>v38222/a>        2spa= class="comment">/* Scale voltage and current raw sensor values according to fixed scales2/spa="v38232/a>2spa= class="comment">         * obtained in Darwin and calculat  power from I and V2/spa="v38242/a>2spa= class="comment">         */2/spa="v38252/a>        2a href="+code=volts" class="sref">volts2/a> *= 2a href="+code=ADC_CPU_VOLTAGE_SCALE" class="sref">ADC_CPU_VOLTAGE_SCALE2/a>;v38262/a>        2a href="+code=amps" class="sref">amps2/a> *= 2a href="+code=ADC_CPU_CURRENT_SCALE" class="sref">ADC_CPU_CURRENT_SCALE2/a>;v38272/a>        *2a href="+code=power" class="sref">power2/a> = (((2a href="+code=u64" class="sref">u642/a>)2a href="+code=volts" class="sref">volts2/a>) * ((2a href="+code=u64" class="sref">u642/a>)2a href="+code=amps" class="sref">amps2/a>)) >> 16;v38282/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=voltage" class="sref">voltagen a> = 2a href="+code=volts" class="sref">volts2/a>;v38292/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=current_a" class="sref">current_an a> = 2a href="+code=amps" class="sref">amps2/a>;v38302/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=last_power" class="sref">last_power2/a> = *2a href="+code=power" class="sref">power2/a>;v38312/a>v38322/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  cpu %d, current: %d.%03d, voltage: %d.%03d, power: %d.%03d W\n"2/spa=",v38332/a>            2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=current_a" class="sref">current_an a>),v38342/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=voltage" class="sref">voltagen a>), 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(*2a href="+code=power" class="sref">power2/a>));v38352/a>v38362/a>        relurn 0;v38372/a>}v38382/a>v38392/a>static void 2a href="+code=do_cpu_pid" class="sref">do_cpu_pid2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat 2/a>, 2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=s32" class="sref">s322/a> 2a href="+code=power" class="sref">power2/a>)v38402/a>{v38412/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=power_target" class="sref">power_target2/a>, 2a href="+code=integral" class="sref">integral2/a>, 2a href="+code=derivativ " class="sref">derivativ 2/a>, 2a href="+code=proportional" class="sref">proportional2/a>, 2a href="+code=adj_in_target" class="sref">adj_in_target2/a>, 2a href="+code=sval" class="sref">sval2/a>;v38422/a>        2a href="+code=s64" class="sref">s642/a> 2a href="+code=integ_p" class="sref">integ_p2/a>, 2a href="+code=deriv_p" class="sref">deriv_p2/a>, 2a href="+code=prop_p" class="sref">prop_p2/a>, 2a href="+code=sum" class="sref">sumn a>; v38432/a>        int 2a href="+code=i" class="sref">i2/a>;v38442/a>v38452/a>        2spa= class="comment">/* Calculat  power target value (could be done once for all)2/spa="v38462/a>2spa= class="comment">         * and convert to a 16.16 fp number2/spa="v38472/a>2spa= class="comment">         */2/spa="v38482/a>        2a href="+code=power_target" class="sref">power_target2/a> = ((2a href="+code=u32" class="sref">u322/a>)(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=pmaxh" class="sref">pmaxh2/a> - 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=padjmax" class="sref">padjmax2/a>)) << 16;v38492/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  power target: %d.%03d, error: %d.%03d\n"2/spa=",v38502/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=power_target" class="sref">power_target2/a>), 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=power_target" class="sref">power_target2/a> - 2a href="+code=power" class="sref">power2/a>));v38512/a>v38522/a>        2spa= class="comment">/* Store temperature and power in history array */2/spa="v38532/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a> + 1) % 2a href="+code=CPU_TEMP_HISTORY_SIZE" class="sref">CPU_TEMP_HISTORY_SIZE2/a>;v38542/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=temp_history" class="sref">temp_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v38552/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a> + 1) % 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_power2/a>;v38562/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=power_history" class="sref">power_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a>] = 2a href="+code=power" class="sref">power2/a>;v38572/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a>] = 2a href="+code=power_target" class="sref">power_target2/a> - 2a href="+code=power" class="sref">power2/a>;v38582/a>        v38592/a>        2spa= class="comment">/* If first loop, fill the history table */2/spa="v38602/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a>) {v38612/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_power2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v38622/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a> + 1) % 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_power2/a>;v38632/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=power_history" class="sref">power_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a>] = 2a href="+code=power" class="sref">power2/a>;v38642/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_power" class="sref">cur_power2/a>] = 2a href="+code=power_target" class="sref">power_target2/a> - 2a href="+code=power" class="sref">power2/a>;v38652/a>                }v38662/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=CPU_TEMP_HISTORY_SIZE" class="sref">CPU_TEMP_HISTORY_SIZE2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v38672/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a> + 1) % 2a href="+code=CPU_TEMP_HISTORY_SIZE" class="sref">CPU_TEMP_HISTORY_SIZE2/a>;v38682/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=temp_history" class="sref">temp_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a>] = 2a href="+code=temp" class="sref">temp2/a>;                    v38692/a>                }v38702/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 0;v38712/a>        }v38722/a>v38732/a>        2spa= class="comment">/* Calculat  the integral term normally based on the "power" values */2/spa="v38742/a>        2a href="+code=sum" class="sref">sumn a> = 0;v38752/a>        2a href="+code=integral" class="sref">integral2/a> = 0;v38762/a>        for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_power2/a>; 2a href="+code=i" class="sref">i2/a>++)v38772/a>                2a href="+code=integral" class="sref">integral2/a> += 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=i" class="sref">i2/a>];v38782/a>        2a href="+code=integral" class="sref">integral2/a> *= 2a href="+code=CPU_PID_INTERVAL" class="sref">CPU_PID_INTERVAL2/a>;v38792/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  integral: %08x\n"2/spa=", 2a href="+code=integral" class="sref">integral2/a>);v38802/a>v38812/a>        2spa= class="comment">/* Calculat  the adjusted input (sense value).2/spa="v38822/a>2spa= class="comment">         *   G_r is 12.202/spa="v38832/a>2spa= class="comment">         *   integ is 16.162/spa="v38842/a>2spa= class="comment">         *   so the result is 28.362/spa="v38852/a>2spa= class="comment">         *2/spa="v38862/a>2spa= class="comment">         * input target is mpu.ttarget, input max is mpu.tmax2/spa="v38872/a>2spa= class="comment">         */2/spa="v38882/a>        2a href="+code=integ_p" class="sref">integ_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=pid_gr" class="sref">pid_gr2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=integral" class="sref">integral2/a>;v38892/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   integ_p: %d\n"2/spa=", (int)(2a href="+code=integ_p" class="sref">integ_p2/a> >> 36));v38902/a>        2a href="+code=sval" class="sref">sval2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> << 16) - ((2a href="+code=integ_p" class="sref">integ_p2/a> >> 20) & 0xffffffff);v38912/a>        2a href="+code=adj_in_target" class="sref">adj_in_target2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=ttarget" class="sref">ttarget2/a> << 16);v38922/a>        if (2a href="+code=adj_in_target" class="sref">adj_in_target2/a> > 2a href="+code=sval" class="sref">sval2/a>)v38932/a>                2a href="+code=adj_in_target" class="sref">adj_in_target2/a> = 2a href="+code=sval" class="sref">sval2/a>;v38942/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   adj_in_target: %d.%03d, ttarget: %d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=adj_in_target" class="sref">adj_in_target2/a>),v38952/a>            2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=ttarget" class="sref">ttarget2/a>);v38962/a>v38972/a>        2spa= class="comment">/* Calculat  the derivativ  term */2/spa="v38982/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=temp_history" class="sref">temp_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a>] -v38992/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=temp_history" class="sref">temp_history2/a>[(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_temp" class="sref">cur_temp2/a> + 2a href="+code=CPU_TEMP_HISTORY_SIZE" class="sref">CPU_TEMP_HISTORY_SIZE2/a> - 1)v39002/a>                                    % 2a href="+code=CPU_TEMP_HISTORY_SIZE" class="sref">CPU_TEMP_HISTORY_SIZE2/a>];v39012/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> /= 2a href="+code=CPU_PID_INTERVAL" class="sref">CPU_PID_INTERVAL2/a>;v39022/a>        2a href="+code=deriv_p" class="sref">deriv_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=pid_gd" class="sref">pid_gd2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=derivativ " class="sref">derivativ 2/a>;v39032/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   deriv_p: %d\n"2/spa=", (int)(2a href="+code=deriv_p" class="sref">deriv_p2/a> >> 36));v39042/a>        2a href="+code=sum" class="sref">sumn a> += 2a href="+code=deriv_p" class="sref">deriv_p2/a>;v39052/a>v39062/a>        2spa= class="comment">/* Calculat  the proportional term */2/spa="v39072/a>        2a href="+code=proportional" class="sref">proportional2/a> = 2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=adj_in_target" class="sref">adj_in_target2/a>;v39082/a>        2a href="+code=prop_p" class="sref">prop_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=pid_gp" class="sref">pid_gp2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=proportional" class="sref">proportional2/a>;v39092/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   prop_p: %d\n"2/spa=", (int)(2a href="+code=prop_p" class="sref">prop_p2/a> >> 36));v39102/a>        2a href="+code=sum" class="sref">sumn a> += 2a href="+code=prop_p" class="sref">prop_p2/a>;v39112/a>v39122/a>        2spa= class="comment">/* Scale sum */2/spa="v39132/a>        2a href="+code=sum" class="sref">sumn a> >>= 36;v39142/a>v39152/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   sum: %d\n"2/spa=", (int)2a href="+code=sum" class="sref">sumn a>);v39162/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> += (2a href="+code=s32" class="sref">s322/a>)2a href="+code=sum" class="sref">sumn a>;v39172/a>}v39182/a>v39192/a>static void 2a href="+code=do_monitor_cpu_combined" class="sref">do_monitor_cpu_combined2/a>(void)v39202/a>{v39212/a>        struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat 0" class="sref">stat 02/a> = &2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0];v39222/a>        struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat 1" class="sref">stat 12/a> = &2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1];v39232/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp0" class="sref">temp02/a>, 2a href="+code=power0" class="sref">power02/a>, 2a href="+code=temp1" class="sref">temp12/a>, 2a href="+code=power1" class="sref">power1n a>;v39242/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp_combi" class="sref">temp_combi2/a>, 2a href="+code=power_combi" class="sref">power_combin a>;v39252/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=intak " class="sref">intak 2/a>, 2a href="+code=pump" class="sref">pumpn a>;v39262/a>v39272/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=do_read_one_cpu_values" class="sref">do_read_one_cpu_values2/a>(2a href="+code=stat 0" class="sref">stat 02/a>, &2a href="+code=temp0" class="sref">temp02/a>, &2a href="+code=power0" class="sref">power02/a>);v39282/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v39292/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v39302/a>        }v39312/a>        2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 0;v39322/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=do_read_one_cpu_values" class="sref">do_read_one_cpu_values2/a>(2a href="+code=stat 1" class="sref">stat 12/a>, &2a href="+code=temp1" class="sref">temp12/a>, &2a href="+code=power1" class="sref">power1n a>);v39332/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v39342/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v39352/a>        }v39362/a>        if (2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=overtemp" class="sref">overtemp2/a>)v39372/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a>++;v39382/a>v39392/a>        2a href="+code=temp_combi" class="sref">temp_combi2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=temp0" class="sref">temp02/a>, 2a href="+code=temp1" class="sref">temp12/a>);v39402/a>        2a href="+code=power_combi" class="sref">power_combin a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=power0" class="sref">power02/a>, 2a href="+code=power1" class="sref">power1n a>);v39412/a>v39422/a>        2spa= class="comment">/* Check tmax, increment overtemp if we ar  there. At tmax+8, we go2/spa="v39432/a>2spa= class="comment">         * full blown immediat ly and try to trigger a shutdown2/spa="v39442/a>2spa= class="comment">         */2/spa="v39452/a>        if (2a href="+code=temp_combi" class="sref">temp_combi2/a> >= ((2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> + 8) << 16)) {v39462/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Warning ! Temperature way above maximum (%d) !\n"2/spa=",v39472/a>                       2a href="+code=temp_combi" class="sref">temp_combi2/a> >> 16);v39482/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a> += 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a> / 4;v39492/a>        } else if (2a href="+code=temp_combi" class="sref">temp_combi2/a> > (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> << 16)) {v39502/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a>++;v39512/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Temperature %d above max %d. overtemp %d\n"2/spa=",v39522/a>                       2a href="+code=temp_combi" class="sref">temp_combi2/a> >> 16, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a>, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v39532/a>        } else {v39542/a>                if (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a>)v39552/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Temperature back down to %d\n"2/spa=",v39562/a>                               2a href="+code=temp_combi" class="sref">temp_combi2/a> >> 16);v39572/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 0;v39582/a>        }v39592/a>        if (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a> >= 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a>)v39602/a>                2a href="+code=critical_stat " class="sref">critical_stat 2/a> = 1;v39612/a>        if (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=overtemp" class="sref">overtemp2/a> > 0) {v39622/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_exhaust_fan" class="sref">rmaxn_exhaust_fann a>;v39632/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>;v39642/a>                2a href="+code=pump" class="sref">pumpn a> = 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_max" class="sref">pump_maxn a>;v39652/a>                goto 2a href="+code=do_set_fans" class="sref">do_set_fansn a>;v39662/a>        }v39672/a>v39682/a>        2spa= class="comment">/* Do the PID */2/spa="v39692/a>        2a href="+code=do_cpu_pid" class="sref">do_cpu_pid2/a>(2a href="+code=stat 0" class="sref">stat 02/a>, 2a href="+code=temp_combi" class="sref">temp_combi2/a>, 2a href="+code=power_combi" class="sref">power_combin a>);v39702/a>v39712/a>        2spa= class="comment">/* Range check */2/spa="v39722/a>        2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_exhaust_fan" class="sref">rminn_exhaust_fann a>);v39732/a>        2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_exhaust_fan" class="sref">rmaxn_exhaust_fann a>);v39742/a>v39752/a>        2spa= class="comment">/* Calculat  intak  fan speed */2/spa="v39762/a>        2a href="+code=intak " class="sref">intak 2/a> = (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a> * 2a href="+code=CPU_INTAKE_SCALE" class="sref">CPU_INTAKE_SCALEn a>) >> 16;v39772/a>        2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=intak " class="sref">intak 2/a>, (int)2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_intak _fan" class="sref">rminn_intak _fann a>);v39782/a>        2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=intak " class="sref">intak 2/a>, (int)2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>);v39792/a>        2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=intak " class="sref">intak 2/a>;v39802/a>v39812/a>        2spa= class="comment">/* Calculat  pump speed */2/spa="v39822/a>        2a href="+code=pump" class="sref">pumpn a> = (2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a> * 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_max" class="sref">pump_maxn a>) /v39832/a>                2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_exhaust_fan" class="sref">rmaxn_exhaust_fann a>;v39842/a>        2a href="+code=pump" class="sref">pumpn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=pump" class="sref">pumpn a>, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_max" class="sref">pump_maxn a>);v39852/a>        2a href="+code=pump" class="sref">pumpn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=pump" class="sref">pumpn a>, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=pump_min" class="sref">pump_minn a>);v39862/a>        v39872/a> 2a href="+code=do_set_fans" class="sref">do_set_fansn a>:v39882/a>        2spa= class="comment">/* We copy values from stat  0 to stat  1 for /sysfs */2/spa="v39892/a>        2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a>;v39902/a>        2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a>;v39912/a>v39922/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** CPU %d RPM: %d Ex, %d, Pump: %d, In, overtemp: %d\n"2/spa=",v39932/a>            2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=index" class="sref">index2/a>, (int)2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=rpm" class="sref">rpmn a>, 2a href="+code=intak " class="sref">intak 2/a>, 2a href="+code=pump" class="sref">pumpn a>, 2a href="+code=stat 1" class="sref">stat 12/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v39942/a>v39952/a>        2spa= class="comment">/* We should check for errors, shouldn't we ? But then, what2/spa="v39962/a>2spa= class="comment">         * do we do onc  the error occurs ? For FCU notified fann spa="v39972/a>2spa= class="comment">         * failures (-EFAULT) we probably want to notify userlandn spa="v39982/a>2spa= class="comment">         * some way...2/spa="v39992/a>2spa= class="comment">         */2/spa="v10002/a>        2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUA_INTAKE_FAN_RPM_INDEX" class="sref">CPUA_INTAKE_FAN_RPM_INDEXn a>, 2a href="+code=intak " class="sref">intak 2/a>);v
10012/a>        2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUA_EXHAUST_FAN_RPM_INDEX" class="sref">CPUA_EXHAUST_FAN_RPM_INDEXn a>, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a>);v10022/a>        2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUB_INTAKE_FAN_RPM_INDEX" class="sref">CPUB_INTAKE_FAN_RPM_INDEXn a>, 2a href="+code=intak " class="sref">intak 2/a>);v10032/a>        2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUB_EXHAUST_FAN_RPM_INDEX" class="sref">CPUB_EXHAUST_FAN_RPM_INDEXn a>, 2a href="+code=stat 0" class="sref">stat 02/a>->2a href="+code=rpm" class="sref">rpmn a>);v10042/a>v10052/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fans2/a>[2a href="+code=CPUA_PUMP_RPM_INDEX" class="sref">CPUA_PUMP_RPM_INDEX2/a>].2a href="+code=id" class="sref">id2/a> != 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_IDn a>)v10062/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUA_PUMP_RPM_INDEX" class="sref">CPUA_PUMP_RPM_INDEX2/a>, 2a href="+code=pump" class="sref">pumpn a>);v10072/a>        if (2a href="+code=fcu_fans" class="sref">fcu_fans2/a>[2a href="+code=CPUB_PUMP_RPM_INDEX" class="sref">CPUB_PUMP_RPM_INDEX2/a>].2a href="+code=id" class="sref">id2/a> != 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_IDn a>)v10082/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUB_PUMP_RPM_INDEX" class="sref">CPUB_PUMP_RPM_INDEX2/a>, 2a href="+code=pump" class="sref">pumpn a>);v10092/a>}v10102/a>v10112/a>static void 2a href="+code=do_monitor_cpu_split" class="sref">do_monitor_cpu_split2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v10122/a>{v10132/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=power" class="sref">power2/a>;v10142/a>        int 2a href="+code=rc" class="sref">rc2/a>, 2a href="+code=intak " class="sref">intak 2/a>;v10152/a>v10162/a>        2spa= class="comment">/* Read current fan status */2/spa="v10172/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=do_read_one_cpu_values" class="sref">do_read_one_cpu_values2/a>(2a href="+code=stat " class="sref">stat n a>, &2a href="+code=temp" class="sref">temp2/a>, &2a href="+code=power" class="sref">power2/a>);v10182/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v10192/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v10202/a>        }v10212/a>v10222/a>        2spa= class="comment">/* Check tmax, increment overtemp if we ar  there. At tmax+8, we go2/spa="v10232/a>2spa= class="comment">         * full blown immediat ly and try to trigger a shutdown2/spa="v10242/a>2spa= class="comment">         */2/spa="v10252/a>        if (2a href="+code=temp" class="sref">temp2/a> >= ((2a href="+code=stat " class="sref">stat n a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> + 8) << 16)) {v10262/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Warning ! CPU %d temperature way above maximum"2/spa="v10272/a>                       2spa= class="string">" (%d) !\n"2/spa=",v10282/a>                       2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16);v10292/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> += 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a> / 4;v10302/a>        } else if (2a href="+code=temp" class="sref">temp2/a> > (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> << 16)) {v10312/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>++;v10322/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"CPU %d temperature %d above max %d. overtemp %d\n"2/spa=",v10332/a>                       2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v10342/a>        } else {v10352/a>                if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>)v10362/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"CPU %d temperature back down to %d\n"2/spa=",v10372/a>                               2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16);v10382/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 0;v10392/a>        }v10402/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> >= 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a>)v10412/a>                2a href="+code=critical_stat " class="sref">critical_stat 2/a> = 1;v10422/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> > 0) {v10432/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_exhaust_fan" class="sref">rmaxn_exhaust_fann a>;v10442/a>                2a href="+code=stat " class="sref">stat n a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>;v10452/a>                goto 2a href="+code=do_set_fans" class="sref">do_set_fansn a>;v10462/a>        }v10472/a>v10482/a>        2spa= class="comment">/* Do the PID */2/spa="v10492/a>        2a href="+code=do_cpu_pid" class="sref">do_cpu_pid2/a>(2a href="+code=stat " class="sref">stat n a>, 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=power" class="sref">power2/a>);v10502/a>v10512/a>        2spa= class="comment">/* Range check */2/spa="v10522/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_exhaust_fan" class="sref">rminn_exhaust_fann a>);v10532/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_exhaust_fan" class="sref">rmaxn_exhaust_fann a>);v10542/a>v10552/a>        2spa= class="comment">/* Calculat  intak  fan */2/spa="v10562/a>        2a href="+code=intak " class="sref">intak 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> * 2a href="+code=CPU_INTAKE_SCALE" class="sref">CPU_INTAKE_SCALEn a>) >> 16;v10572/a>        2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=intak " class="sref">intak 2/a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_intak _fan" class="sref">rminn_intak _fann a>);v10582/a>        2a href="+code=intak " class="sref">intak 2/a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=intak " class="sref">intak 2/a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>);v10592/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=intak " class="sref">intak 2/a>;v10602/a>v10612/a> 2a href="+code=do_set_fans" class="sref">do_set_fansn a>:v10622/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** CPU %d RPM: %d Ex, %d In, overtemp: %d\n"2/spa=",v10632/a>            2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, 2a href="+code=intak " class="sref">intak 2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v10642/a>v10652/a>        2spa= class="comment">/* We should check for errors, shouldn't we ? But then, what2/spa="v10662/a>2spa= class="comment">         * do we do onc  the error occurs ? For FCU notified fann spa="v10672/a>2spa= class="comment">         * failures (-EFAULT) we probably want to notify userlandn spa="v10682/a>2spa= class="comment">         * some way...2/spa="v10692/a>2spa= class="comment">         */2/spa="v10702/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> == 0) {v10712/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUA_INTAKE_FAN_RPM_INDEX" class="sref">CPUA_INTAKE_FAN_RPM_INDEXn a>, 2a href="+code=intak " class="sref">intak 2/a>);v10722/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUA_EXHAUST_FAN_RPM_INDEX" class="sref">CPUA_EXHAUST_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v10732/a>        } else {v10742/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUB_INTAKE_FAN_RPM_INDEX" class="sref">CPUB_INTAKE_FAN_RPM_INDEXn a>, 2a href="+code=intak " class="sref">intak 2/a>);v10752/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPUB_EXHAUST_FAN_RPM_INDEX" class="sref">CPUB_EXHAUST_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v10762/a>        }v10772/a>}v10782/a>v10792/a>static void 2a href="+code=do_monitor_cpu_rack" class="sref">do_monitor_cpu_rack2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v1080n a>{v10812/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=power" class="sref">power2/a>, 2a href="+code=fan_min" class="sref">fan_min2/a>;v10822/a>        int 2a href="+code=rc" class="sref">rc2/a>;v10832/a>v10842/a>        2spa= class="comment">/* Read current fan status */2/spa="v10852/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=do_read_one_cpu_values" class="sref">do_read_one_cpu_values2/a>(2a href="+code=stat " class="sref">stat n a>, &2a href="+code=temp" class="sref">temp2/a>, &2a href="+code=power" class="sref">power2/a>);v10862/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v10872/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v10882/a>        }v10892/a>v10902/a>        2spa= class="comment">/* Check tmax, increment overtemp if we ar  there. At tmax+8, we go2/spa="v10912/a>2spa= class="comment">         * full blown immediat ly and try to trigger a shutdown2/spa="v10922/a>2spa= class="comment">         */2/spa="v10932/a>        if (2a href="+code=temp" class="sref">temp2/a> >= ((2a href="+code=stat " class="sref">stat n a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> + 8) << 16)) {v10942/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Warning ! CPU %d temperature way above maximum"2/spa="v10952/a>                       2spa= class="string">" (%d) !\n"2/spa=",v10962/a>                       2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16);v10972/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a> / 4;v10982/a>        } else if (2a href="+code=temp" class="sref">temp2/a> > (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a> << 16)) {v10992/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>++;v11002/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"CPU %d temperature %d above max %d. overtemp %d\n"2/spa=",v11012/a>                       2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tmax" class="sref">tmax2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v11022/a>        } else {v11032/a>                if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>)v11042/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"CPU %d temperature back down to %d\n"2/spa=",v11052/a>                               2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, 2a href="+code=temp" class="sref">temp2/a> >> 16);v11062/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 0;v11072/a>        }v11082/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> >= 2a href="+code=CPU_MAX_OVERTEMP" class="sref">CPU_MAX_OVERTEMP2/a>)v11092/a>                2a href="+code=critical_stat " class="sref">critical_stat 2/a> = 1;v11102/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a> > 0) {v11112/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>;v11122/a>                goto 2a href="+code=do_set_fans" class="sref">do_set_fansn a>;v11132/a>        }v11142/a>v11152/a>        2spa= class="comment">/* Do the PID */2/spa="v11162/a>        2a href="+code=do_cpu_pid" class="sref">do_cpu_pid2/a>(2a href="+code=stat " class="sref">stat n a>, 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=power" class="sref">power2/a>);v11172/a>v11182/a>        2spa= class="comment">/* Check clamp from dimms */2/spa="v11192/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = 2a href="+code=dimm_output_clamp" class="sref">dimm_output_clampn a>;v11202/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=fan_min" class="sref">fan_min2/a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_intak _fan" class="sref">rminn_intak _fann a>);v11212/a>v11222/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">" CPU min mpu = %d, min dimm = %d\n"2/spa=",v11232/a>            2a href="+code=stat " class="sref">stat n a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rminn_intak _fan" class="sref">rminn_intak _fann a>, 2a href="+code=dimm_output_clamp" class="sref">dimm_output_clampn a>);v11242/a>v11252/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=fan_min" class="sref">fan_min2/a>);v11262/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=rmaxn_intak _fan" class="sref">rmaxn_intak _fann a>);v11272/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=intak _rpm" class="sref">intak _rpmn a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>;v11282/a>v11292/a> 2a href="+code=do_set_fans" class="sref">do_set_fansn a>:v11302/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** CPU %d RPM: %d overtemp: %d\n"2/spa=",v11312/a>            2a href="+code=stat " class="sref">stat n a>->2a href="+code=index" class="sref">index2/a>, (int)2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=overtemp" class="sref">overtemp2/a>);v11322/a>v11332/a>        2spa= class="comment">/* We should check for errors, shouldn't we ? But then, what2/spa="v11342/a>2spa= class="comment">         * do we do onc  the error occurs ? For FCU notified fann spa="v11352/a>2spa= class="comment">         * failures (-EFAULT) we probably want to notify userlandn spa="v11362/a>2spa= class="comment">         * some way...2/spa="v11372/a>2spa= class="comment">         */2/spa="v11382/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> == 0) {v11392/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_A1_FAN_RPM_INDEX" class="sref">CPU_A1_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11402/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_A2_FAN_RPM_INDEX" class="sref">CPU_A2_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11412/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_A3_FAN_RPM_INDEX" class="sref">CPU_A3_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11422/a>        } else {v11432/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_B1_FAN_RPM_INDEX" class="sref">CPU_B1_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11442/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_B2_FAN_RPM_INDEX" class="sref">CPU_B2_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11452/a>                2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=CPU_B3_FAN_RPM_INDEX" class="sref">CPU_B3_FAN_RPM_INDEXn a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>);v11462/a>        }v11472/a>}v11482/a>v11492/a>2spa= class="comment">/*2/spa="v11502/a>2spa= class="comment"> * Initializ  the stat  structure for one CPU control loop2/spa="v11512/a>2spa= class="comment"> */2/spa="v11522/a>static int 2a href="+code=init_processor_stat " class="sref">init_processor_stat 2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>, int 2a href="+code=index" class="sref">index2/a>)v11532/a>{v11542/a>        int 2a href="+code=err" class="sref">errn a>;v11552/a>v11562/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> = 2a href="+code=index" class="sref">index2/a>;v11572/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 1;v11582/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = (2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> == 2a href="+code=CPU_PID_TYPE_RACKMAC" class="sref">CPU_PID_TYPE_RACKMAC2/a>) ? 4000 : 1000;v11592/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=overtemp" class="sref">overtemp2/a> = 0;v11602/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=adc_config" class="sref">adc_config2/a> = 0x00;v11612/a>v11622/a>v11632/a>        if (2a href="+code=index" class="sref">index2/a> == 0)v11642/a>                2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=SUPPLY_MONITOR_ID" class="sref">SUPPLY_MONITOR_IDn a>, 2spa= class="string">"CPU0_monitor"2/spa=");v11652/a>        else if (2a href="+code=index" class="sref">index2/a> == 1)v11662/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=SUPPLY_MONITORB_ID" class="sref">SUPPLY_MONITORB_IDn a>, 2spa= class="string">"CPU1_monitor"2/spa=");v11672/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v11682/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v11692/a>v11702/a>        if (2a href="+code=read_eeprom" class="sref">read_eeprom2/a>(2a href="+code=index" class="sref">index2/a>, &2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>))v11712/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v11722/a>v11732/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_powern a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=mpu" class="sref">mpu2/a>.2a href="+code=tguardband" class="sref">tguardband2/a>;v11742/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_powern a> > 2a href="+code=CPU_POWER_HISTORY_SIZE" class="sref">CPU_POWER_HISTORY_SIZE2/a>) {v11752/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Warning ! too many power history slots\n"2/spa=");v11762/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_powern a> = 2a href="+code=CPU_POWER_HISTORY_SIZE" class="sref">CPU_POWER_HISTORY_SIZE2/a>;v11772/a>        }v11782/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"CPU %d Using %d power history entries\n"2/spa=", 2a href="+code=index" class="sref">index2/a>, 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=count_power" class="sref">count_powern a>);v11792/a>v11802/a>        if (2a href="+code=index" class="sref">index2/a> == 0) {v11812/a>                2a href="+code=err" class="sref">errn a> = 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_temperature" class="sref">dev_attr_cpu0_temperaturen a>);v11822/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_voltage" class="sref">dev_attr_cpu0_voltagen a>);v11832/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_current" class="sref">dev_attr_cpu0_currentn a>);v11842/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_exhaust_fan_rpm" class="sref">dev_attr_cpu0_exhaust_fan_rpmn a>);v11852/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_intak _fan_rpm" class="sref">dev_attr_cpu0_intak _fan_rpmn a>);v11862/a>        } else {v11872/a>                2a href="+code=err" class="sref">errn a> = 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_temperature" class="sref">dev_attr_cpu1_temperaturen a>);v11882/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_voltage" class="sref">dev_attr_cpu1_voltagen a>);v11892/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_current" class="sref">dev_attr_cpu1_currentn a>);v11902/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_exhaust_fan_rpm" class="sref">dev_attr_cpu1_exhaust_fan_rpmn a>);v11912/a>                2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_create_fil " class="sref">device_create_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_intak _fan_rpm" class="sref">dev_attr_cpu1_intak _fan_rpmn a>);v11922/a>        }v11932/a>        if (2a href="+code=err" class="sref">errn a>)v11942/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Fail d to create some of the attribute"2/spa="v11952/a>                        2spa= class="string">"fil s for CPU %d\n"2/spa=", 2a href="+code=index" class="sref">index2/a>);v11962/a>v11972/a>        return 0;v11982/a> 2a href="+code=fail" class="sref">fail2/a>:v11992/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v12002/a>        v12012/a>        return -2a href="+code=ENODEV" class="sref">ENODEV2/a>;v12022/a>}v12032/a>v12042/a>2spa= class="comment">/*2/spa="v12052/a>2spa= class="comment"> * Dispose of the stat  data for one CPU control loop2/spa="v12062/a>2spa= class="comment"> */2/spa="v12072/a>static void 2a href="+code=dispose_processor_stat " class="sref">dispose_processor_stat 2/a>(struct 2a href="+code=cpu_pid_stat " class="sref">cpu_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v12082/a>{v12092/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v12102/a>                return;v12112/a>v12122/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=index" class="sref">index2/a> == 0) {v12132/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_temperature" class="sref">dev_attr_cpu0_temperaturen a>);v12142/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_voltage" class="sref">dev_attr_cpu0_voltagen a>);v12152/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_current" class="sref">dev_attr_cpu0_currentn a>);v12162/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_exhaust_fan_rpm" class="sref">dev_attr_cpu0_exhaust_fan_rpmn a>);v12172/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu0_intak _fan_rpm" class="sref">dev_attr_cpu0_intak _fan_rpmn a>);v12182/a>        } else {v12192/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_temperature" class="sref">dev_attr_cpu1_temperaturen a>);v12202/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_voltage" class="sref">dev_attr_cpu1_voltagen a>);v12212/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_current" class="sref">dev_attr_cpu1_currentn a>);v12222/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_exhaust_fan_rpm" class="sref">dev_attr_cpu1_exhaust_fan_rpmn a>);v12232/a>                2a href="+code=device_remove_fil " class="sref">device_remove_fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_cpu1_intak _fan_rpm" class="sref">dev_attr_cpu1_intak _fan_rpmn a>);v12242/a>        }v12252/a>v12262/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v12272/a>}v12282/a>v12292/a>2spa= class="comment">/*2/spa="v12302/a>2spa= class="comment"> * Motherboard backside & U3 heatsink fan control loop2/spa="v12312/a>2spa= class="comment"> */2/spa="v12322/a>static void 2a href="+code=do_monitor_backside" class="sref">do_monitor_backside2/a>(struct 2a href="+code=backside_pid_stat " class="sref">backside_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v12332/a>{v12342/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=integral" class="sref">integral2/a>, 2a href="+code=derivativ " class="sref">derivativ 2/a>, 2a href="+code=fan_min" class="sref">fan_min2/a>;v12352/a>        2a href="+code=s64" class="sref">s642/a> 2a href="+code=integ_p" class="sref">integ_p2/a>, 2a href="+code=deriv_p" class="sref">deriv_p2/a>, 2a href="+code=prop_p" class="sref">prop_p2/a>, 2a href="+code=sum" class="sref">sum2/a>; v12362/a>        int 2a href="+code=i" class="sref">i2/a>, 2a href="+code=rc" class="sref">rc2/a>;v12372/a>v12382/a>        if (--2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> != 0)v12392/a>                return;v12402/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=ticks" class="sref">ticks2/a> = 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a>;v12412/a>v12422/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"backside:\n"2/spa=");v12432/a>v12442/a>        2spa= class="comment">/* Check fan status */2/spa="v12452/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=get_pwm_fan" class="sref">get_pwm_fan2/a>(2a href="+code=BACKSIDE_FAN_PWM_INDEX" class="sref">BACKSIDE_FAN_PWM_INDEXn a>);v12462/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v12472/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Error %d reading backside fan !\n"2/spa=", 2a href="+code=rc" class="sref">rc2/a>);v12482/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v12492/a>        } elsev12502/a>                2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a> = 2a href="+code=rc" class="sref">rc2/a>;v12512/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  current pwm: %d\n"2/spa=", 2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a>);v12522/a>v12532/a>        2spa= class="comment">/* Get some sensor readings */2/spa="v12542/a>        2a href="+code=temp" class="sref">temp2/a> = 2a href="+code=i2c_smbus_read_byte_data" class="sref">i2c_smbus_read_byte_data2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=MAX6690_EXT_TEMP" class="sref">MAX6690_EXT_TEMPn a>) << 16;v12552/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=last_temp" class="sref">last_temp2/a> = 2a href="+code=temp" class="sref">temp2/a>;v12562/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  temp: %d.%03d, target: %d.%03d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=temp" class="sref">temp2/a>),v12572/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a>));v12582/a>v12592/a>        2spa= class="comment">/* Store temperature and error in history array */2/spa="v12602/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) % 2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a>;v12612/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v12622/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a>;v12632/a>        v12642/a>        2spa= class="comment">/* If first loop, fill the history table */2/spa="v12652/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a>) {v12662/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v12672/a>                        2a href="+code=stat " class="sref">stat n a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) %v12682/a>                                2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a>;v12692/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v12702/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] =v12712/a>                                2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a>;v12722/a>                }v12732/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 0;v12742/a>        }v12752/a>v12762/a>        2spa= class="comment">/* Calculat  the integral term */2/spa="v12772/a>        2a href="+code=sum" class="sref">sum2/a> = 0;v12782/a>        2a href="+code=integral" class="sref">integral2/a> = 0;v12792/a>        for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < 2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a>; 2a href="+code=i" class="sref">i2/a>++)v12802/a>                2a href="+code=integral" class="sref">integral2/a> += 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=i" class="sref">i2/a>];v12812/a>        2a href="+code=integral" class="sref">integral2/a> *= 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a>;v12822/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  integral: %08x\n"2/spa=", 2a href="+code=integral" class="sref">integral2/a>);v12832/a>        2a href="+code=integ_p" class="sref">integ_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_r" class="sref">G_r2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=integral" class="sref">integral2/a>;v12842/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   integ_p: %d\n"2/spa=", (int)(2a href="+code=integ_p" class="sref">integ_p2/a> >> 36));v12852/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=integ_p" class="sref">integ_p2/a>;v12862/a>v12872/a>        2spa= class="comment">/* Calculat  the derivativ  term */2/spa="v12882/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] -v12892/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a> - 1)v12902/a>                                    % 2a href="+code=BACKSIDE_PID_HISTORY_SIZE" class="sref">BACKSIDE_PID_HISTORY_SIZE2/a>];v12912/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> /= 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a>;v12922/a>        2a href="+code=deriv_p" class="sref">deriv_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_d" class="sref">G_d2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=derivativ " class="sref">derivativ 2/a>;v12932/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   deriv_p: %d\n"2/spa=", (int)(2a href="+code=deriv_p" class="sref">deriv_p2/a> >> 36));v12942/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=deriv_p" class="sref">deriv_p2/a>;v12952/a>v12962/a>        2spa= class="comment">/* Calculat  the proportional term */2/spa="v12972/a>        2a href="+code=prop_p" class="sref">prop_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_p" class="sref">G_p2/a>) * (2a href="+code=s64" class="sref">s642/a>)(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>]);v12982/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   prop_p: %d\n"2/spa=", (int)(2a href="+code=prop_p" class="sref">prop_p2/a> >> 36));v12992/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=prop_p" class="sref">prop_p2/a>;v13002/a>v13012/a>        2spa= class="comment">/* Scale sum */2/spa="v13022/a>        2a href="+code=sum" class="sref">sum2/a> >>= 36;v13032/a>v13042/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   sum: %d\n"2/spa=", (int)2a href="+code=sum" class="sref">sum2/a>);v13052/a>        if (2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=additiv " class="sref">additiv 2/a>)v13062/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwmn a> += (2a href="+code=s32" class="sref">s322/a>)2a href="+code=sum" class="sref">sum2/a>;v13072/a>        elsev13082/a>                2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a> = 2a href="+code=sum" class="sref">sum2/a>;v13092/a>v13102/a>        2spa= class="comment">/* Check for clamp */2/spa="v13112/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = (2a href="+code=dimm_output_clamp" class="sref">dimm_output_clamp2/a> * 100) / 14000;v13122/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=fan_min" class="sref">fan_min2/a>, 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_min" class="sref">output_min2/a>);v13132/a>v13142/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a>, 2a href="+code=fan_min" class="sref">fan_min2/a>);v13152/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a>, 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_max" class="sref">output_max2/a>);v13162/a>v13172/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** BACKSIDE PWM: %d\n"2/spa=", (int)2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a>);v13182/a>        2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(2a href="+code=BACKSIDE_FAN_PWM_INDEX" class="sref">BACKSIDE_FAN_PWM_INDEXn a>, 2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a>);v13192/a>}v13202/a>v13212/a>2spa= class="comment">/*2/spa="v13222/a>2spa= class="comment"> * Initialize the stat  structure for the backside fan control loop2/spa="v13232/a>2spa= class="comment"> */2/spa="v13242/a>static int 2a href="+code=init_backside_stat " class="sref">init_backside_stat 2/a>(struct 2a href="+code=backside_pid_stat " class="sref">backside_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v13252/a>{v13262/a>        struct 2a href="+code=device_node" class="sref">device_node2/a> *2a href="+code=u3" class="sref">u32/a>;v13272/a>        int 2a href="+code=u3h" class="sref">u3hn a> = 1; 2spa= class="comment">/* conservativ  by default */2/spa="v13282/a>        int 2a href="+code=err" class="sref">errn a>;v13292/a>v13302/a>        2spa= class="comment">/*2/spa="v13312/a>2spa= class="comment">         * There are different PID params for machines with U3 and machines2/spa="v13322/a>2spa= class="comment">         * with U3H, pick the right ones now2/spa="v13332/a>2spa= class="comment">         */2/spa="v13342/a>        2a href="+code=u3" class="sref">u32/a> = 2a href="+code=of_find_node_by_path" class="sref">of_find_node_by_path2/a>(2spa= class="string">"/u3@0,f8000000"2/spa=");v13352/a>        if (2a href="+code=u3" class="sref">u32/a> != 2a href="+code=NULL" class="sref">NULL2/a>) {v13362/a>                const 2a href="+code=u32" class="sref">u322/a> *2a href="+code=vers" class="sref">vers2/a> = 2a href="+code=of_get_property" class="sref">of_get_property2/a>(2a href="+code=u3" class="sref">u32/a>, 2spa= class="string">"device-rev"2/spa=", 2a href="+code=NULL" class="sref">NULL2/a>);v13372/a>                if (2a href="+code=vers" class="sref">vers2/a>)v13382/a>                        if (((*2a href="+code=vers" class="sref">vers2/a>) & 0x3f) < 0x34)v13392/a>                                2a href="+code=u3h" class="sref">u3hn a> = 0;v13402/a>                2a href="+code=of_node_put" class="sref">of_node_put2/a>(2a href="+code=u3" class="sref">u32/a>);v13412/a>        }v13422/a>v13432/a>        if (2a href="+code=rackmac" class="sref">rackmac2/a>) {v13442/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_d" class="sref">G_d2/a> = 2a href="+code=BACKSIDE_PID_RACK_G_d" class="sref">BACKSIDE_PID_RACK_G_dn a>;v13452/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a> = 2a href="+code=BACKSIDE_PID_RACK_INPUT_TARGET" class="sref">BACKSIDE_PID_RACK_INPUT_TARGETn a>;v13462/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_min" class="sref">output_min2/a> = 2a href="+code=BACKSIDE_PID_U3H_OUTPUT_MIN" class="sref">BACKSIDE_PID_U3H_OUTPUT_MINn a>;v13472/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a> = 2a href="+code=BACKSIDE_PID_RACK_INTERVAL" class="sref">BACKSIDE_PID_RACK_INTERVALn a>;v13482/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_p" class="sref">G_p2/a> = 2a href="+code=BACKSIDE_PID_RACK_G_p" class="sref">BACKSIDE_PID_RACK_G_pn a>;v13492/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_r" class="sref">G_r2/a> = 2a href="+code=BACKSIDE_PID_G_r" class="sref">BACKSIDE_PID_G_rn a>;v13502/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_max" class="sref">output_max2/a> = 2a href="+code=BACKSIDE_PID_OUTPUT_MAX" class="sref">BACKSIDE_PID_OUTPUT_MAXn a>;v13512/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=additiv " class="sref">additiv 2/a> = 0;v13522/a>        } else if (2a href="+code=u3h" class="sref">u3hn a>) {v13532/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_d" class="sref">G_d2/a> = 2a href="+code=BACKSIDE_PID_U3H_G_d" class="sref">BACKSIDE_PID_U3H_G_dn a>;v13542/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a> = 2a href="+code=BACKSIDE_PID_U3H_INPUT_TARGET" class="sref">BACKSIDE_PID_U3H_INPUT_TARGETn a>;v13552/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_min" class="sref">output_min2/a> = 2a href="+code=BACKSIDE_PID_U3H_OUTPUT_MIN" class="sref">BACKSIDE_PID_U3H_OUTPUT_MINn a>;v13562/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a> = 2a href="+code=BACKSIDE_PID_INTERVAL" class="sref">BACKSIDE_PID_INTERVALn a>;v13572/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_p" class="sref">G_p2/a> = 2a href="+code=BACKSIDE_PID_G_p" class="sref">BACKSIDE_PID_G_pn a>;v13582/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_r" class="sref">G_r2/a> = 2a href="+code=BACKSIDE_PID_G_r" class="sref">BACKSIDE_PID_G_rn a>;v13592/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_max" class="sref">output_max2/a> = 2a href="+code=BACKSIDE_PID_OUTPUT_MAX" class="sref">BACKSIDE_PID_OUTPUT_MAXn a>;v13602/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=additiv " class="sref">additiv 2/a> = 1;v13612/a>        } else {v13622/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_d" class="sref">G_d2/a> = 2a href="+code=BACKSIDE_PID_U3_G_d" class="sref">BACKSIDE_PID_U3_G_dn a>;v13632/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=input_target" class="sref">input_target2/a> = 2a href="+code=BACKSIDE_PID_U3_INPUT_TARGET" class="sref">BACKSIDE_PID_U3_INPUT_TARGETn a>;v13642/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_min" class="sref">output_min2/a> = 2a href="+code=BACKSIDE_PID_U3_OUTPUT_MIN" class="sref">BACKSIDE_PID_U3_OUTPUT_MINn a>;v13652/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=interval" class="sref">interval2/a> = 2a href="+code=BACKSIDE_PID_INTERVAL" class="sref">BACKSIDE_PID_INTERVALn a>;v13662/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_p" class="sref">G_p2/a> = 2a href="+code=BACKSIDE_PID_G_p" class="sref">BACKSIDE_PID_G_pn a>;v13672/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=G_r" class="sref">G_r2/a> = 2a href="+code=BACKSIDE_PID_G_r" class="sref">BACKSIDE_PID_G_rn a>;v13682/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_max" class="sref">output_max2/a> = 2a href="+code=BACKSIDE_PID_OUTPUT_MAX" class="sref">BACKSIDE_PID_OUTPUT_MAXn a>;v13692/a>                2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=additiv " class="sref">additiv 2/a> = 1;v13702/a>        }v13712/a>v13722/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> = 1;v13732/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 1;v13742/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwmn a> = 50;v13752/a>v13762/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=BACKSIDE_MAX_ID" class="sref">BACKSIDE_MAX_ID2/a>, 2spa= class="string">"backside_temp"2/spa=");v13772/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v13782/a>                return -2a href="+code=ENODEV" class="sref">ENODEVn a>;v13792/a>v13802/a>        2a href="+code=err" class="sref">errn a> = 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_backside_temperature" class="sref">dev_attr_backside_temperature2/a>);v13812/a>        2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_backside_fan_pwm" class="sref">dev_attr_backside_fan_pwm2/a>);v13822/a>        if (2a href="+code=err" class="sref">errn a>)v13832/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Fail d to creat  attribut  fil (s)"2/spa="v13842/a>                        2spa= class="string">" for backside fan\n"2/spa=");v13852/a>v13862/a>        return 0;v13872/a>}v13882/a>v13892/a>2spa= class="comment">/*2/spa="v13902/a>2spa= class="comment"> * Dispose of the stat  data for the backside control loop2/spa="v13912/a>2spa= class="comment"> */2/spa="v13922/a>static void 2a href="+code=dispose_backside_stat " class="sref">dispose_backside_stat 2/a>(struct 2a href="+code=backside_pid_stat " class="sref">backside_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v13932/a>{v13942/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v13952/a>                return;v13962/a>v13972/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_backside_temperature" class="sref">dev_attr_backside_temperature2/a>);v13982/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_backside_fan_pwm" class="sref">dev_attr_backside_fan_pwm2/a>);v13992/a>v14002/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v14012/a>}v14022/a> v14032/a>2spa= class="comment">/*2/spa="v14042/a>2spa= class="comment"> * Drives bay fan control loop2/spa="v14052/a>2spa= class="comment"> */2/spa="v14062/a>static void 2a href="+code=do_monitor_drives" class="sref">do_monitor_drives2/a>(struct 2a href="+code=drives_pid_stat " class="sref">drives_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v14072/a>{v14082/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=integral" class="sref">integral2/a>, 2a href="+code=derivativ " class="sref">derivativ 2/a>;v14092/a>        2a href="+code=s64" class="sref">s642/a> 2a href="+code=integ_p" class="sref">integ_p2/a>, 2a href="+code=deriv_p" class="sref">deriv_p2/a>, 2a href="+code=prop_p" class="sref">prop_p2/a>, 2a href="+code=sum" class="sref">sum2/a>; v14102/a>        int 2a href="+code=i" class="sref">i2/a>, 2a href="+code=rc" class="sref">rc2/a>;v14112/a>v14122/a>        if (--2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> != 0)v14132/a>                return;v14142/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=ticks" class="sref">ticks2/a> = 2a href="+code=DRIVES_PID_INTERVAL" class="sref">DRIVES_PID_INTERVAL2/a>;v14152/a>v14162/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"drives:\n"2/spa=");v14172/a>v14182/a>        2spa= class="comment">/* Check fa= status */2/spa="v14192/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=get_rpm_fan" class="sref">get_rpm_fan2/a>(2a href="+code=DRIVES_FAN_RPM_INDEX" class="sref">DRIVES_FAN_RPM_INDEX2/a>, !2a href="+code=RPM_PID_USE_ACTUAL_SPEED" class="sref">RPM_PID_USE_ACTUAL_SPEED2/a>);v14202/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v14212/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Error %d reading drives fa= !\n"2/spa=", 2a href="+code=rc" class="sref">rc2/a>);v14222/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v14232/a>        } elsev14242/a>                2a href="+code=stat " class="sref">stat n a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=rc" class="sref">rc2/a>;v14252/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  current rpm: %d\n"2/spa=", 2a href="+code=stat " class="sref">stat n a>->2a href="+code=rpm" class="sref">rpmn a>);v14262/a>v14272/a>        2spa= class="comment">/* Get some sensor readings */2/spa="v14282/a>        2a href="+code=temp" class="sref">temp2/a> = 2a href="+code=le16_to_cpu" class="sref">le16_to_cpu2/a>(2a href="+code=i2c_smbus_read_word_data" class="sref">i2c_smbus_read_word_data2/a>(2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a>,v14292/a>                                                    2a href="+code=DS1775_TEMP" class="sref">DS1775_TEMPn a>)) << 8;v14302/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=last_temp" class="sref">last_temp2/a> = 2a href="+code=temp" class="sref">temp2/a>;v14312/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  temp: %d.%03d, target: %d.%03d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=temp" class="sref">temp2/a>),v14322/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=DRIVES_PID_INPUT_TARGET" class="sref">DRIVES_PID_INPUT_TARGETn a>));v14332/a>v14342/a>        2spa= class="comment">/* Store temperature and error in history array */2/spa="v14352/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) % 2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a>;v14362/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v14372/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=DRIVES_PID_INPUT_TARGET" class="sref">DRIVES_PID_INPUT_TARGETn a>;v14382/a>        v14392/a>        2spa= class="comment">/* If first loop, fill the history table */2/spa="v14402/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a>) {v14412/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v14422/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) %v14432/a>                                2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a>;v14442/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v14452/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] =v14462/a>                                2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=DRIVES_PID_INPUT_TARGET" class="sref">DRIVES_PID_INPUT_TARGETn a>;v14472/a>                }v14482/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 0;v14492/a>        }v14502/a>v14512/a>        2spa= class="comment">/* Calculat  the integral term */2/spa="v14522/a>        2a href="+code=sum" class="sref">sum2/a> = 0;v14532/a>        2a href="+code=integral" class="sref">integral2/a> = 0;v14542/a>        for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < 2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a>; 2a href="+code=i" class="sref">i2/a>++)v14552/a>                2a href="+code=integral" class="sref">integral2/a> += 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=i" class="sref">i2/a>];v14562/a>        2a href="+code=integral" class="sref">integral2/a> *= 2a href="+code=DRIVES_PID_INTERVAL" class="sref">DRIVES_PID_INTERVAL2/a>;v14572/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  integral: %08x\n"2/spa=", 2a href="+code=integral" class="sref">integral2/a>);v14582/a>        2a href="+code=integ_p" class="sref">integ_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DRIVES_PID_G_r" class="sref">DRIVES_PID_G_r2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=integral" class="sref">integral2/a>;v14592/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   integ_p: %d\n"2/spa=", (int)(2a href="+code=integ_p" class="sref">integ_p2/a> >> 36));v14602/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=integ_p" class="sref">integ_p2/a>;v14612/a>v14622/a>        2spa= class="comment">/* Calculat  the derivativ  term */2/spa="v14632/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] -v14642/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a> - 1)v14652/a>                                    % 2a href="+code=DRIVES_PID_HISTORY_SIZE" class="sref">DRIVES_PID_HISTORY_SIZE2/a>];v14662/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> /= 2a href="+code=DRIVES_PID_INTERVAL" class="sref">DRIVES_PID_INTERVAL2/a>;v14672/a>        2a href="+code=deriv_p" class="sref">deriv_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DRIVES_PID_G_d" class="sref">DRIVES_PID_G_d2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=derivativ " class="sref">derivativ 2/a>;v14682/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   deriv_p: %d\n"2/spa=", (int)(2a href="+code=deriv_p" class="sref">deriv_p2/a> >> 36));v14692/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=deriv_p" class="sref">deriv_p2/a>;v14702/a>v14712/a>        2spa= class="comment">/* Calculat  the proportional term */2/spa="v14722/a>        2a href="+code=prop_p" class="sref">prop_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DRIVES_PID_G_p" class="sref">DRIVES_PID_G_p2/a>) * (2a href="+code=s64" class="sref">s642/a>)(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>]);v14732/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   prop_p: %d\n"2/spa=", (int)(2a href="+code=prop_p" class="sref">prop_p2/a> >> 36));v14742/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=prop_p" class="sref">prop_p2/a>;v14752/a>v14762/a>        2spa= class="comment">/* Scale sum */2/spa="v14772/a>        2a href="+code=sum" class="sref">sum2/a> >>= 36;v14782/a>v14792/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   sum: %d\n"2/spa=", (int)2a href="+code=sum" class="sref">sum2/a>);v14802/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=rpm" class="sref">rpmn a> += (2a href="+code=s32" class="sref">s322/a>)2a href="+code=sum" class="sref">sum2/a>;v14812/a>v14822/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, 2a href="+code=DRIVES_PID_OUTPUT_MIN" class="sref">DRIVES_PID_OUTPUT_MIN2/a>);v14832/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a>, 2a href="+code=DRIVES_PID_OUTPUT_MAX" class="sref">DRIVES_PID_OUTPUT_MAX2/a>);v14842/a>v14852/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** DRIVES RPM: %d\n"2/spa=", (int)2a href="+code=stat " class="sref">stat n a>->2a href="+code=rpm" class="sref">rpmn a>);v14862/a>        2a href="+code=set_rpm_fan" class="sref">set_rpm_fan2/a>(2a href="+code=DRIVES_FAN_RPM_INDEX" class="sref">DRIVES_FAN_RPM_INDEX2/a>, 2a href="+code=stat " class="sref">stat n a>->2a href="+code=rpm" class="sref">rpmn a>);v14872/a>}v14882/a>v14892/a>2spa= class="comment">/*2/spa="v14902/a>2spa= class="comment"> * Initialize the stat  structure for the drives bay fan control loop2/spa="v14912/a>2spa= class="comment"> */2/spa="v14922/a>static int 2a href="+code=init_drives_stat " class="sref">init_drives_stat 2/a>(struct 2a href="+code=drives_pid_stat " class="sref">drives_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v14932/a>{v14942/a>        int 2a href="+code=err" class="sref">errn a>;v14952/a>v14962/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> = 1;v14972/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 1;v14982/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=rpm" class="sref">rpmn a> = 1000;v14992/a>v15002/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=DRIVES_DALLAS_ID" class="sref">DRIVES_DALLAS_ID2/a>, 2spa= class="string">"drives_temp"2/spa=");v15012/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v15022/a>                return -2a href="+code=ENODEV" class="sref">ENODEVn a>;v15032/a>v15042/a>        2a href="+code=err" class="sref">errn a> = 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_drives_temperature" class="sref">dev_attr_drives_temperaturen a>);v15052/a>        2a href="+code=err" class="sref">errn a> |= 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_drives_fan_rpm" class="sref">dev_attr_drives_fan_rpmn a>);v15062/a>        if (2a href="+code=err" class="sref">errn a>)v15072/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Fail d to creat  attribut  fil (s)"2/spa="v15082/a>                        2spa= class="string">" for drives bay fan\n"2/spa=");v15092/a>v15102/a>        return 0;v15112/a>}v15122/a>v15132/a>2spa= class="comment">/*2/spa="v15142/a>2spa= class="comment"> * Dispose of the stat  data for the drives control loop2/spa="v15152/a>2spa= class="comment"> */2/spa="v15162/a>static void 2a href="+code=dispose_drives_stat " class="sref">dispose_drives_stat 2/a>(struct 2a href="+code=drives_pid_stat " class="sref">drives_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v15172/a>{v15182/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v15192/a>                return;v15202/a>v15212/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_drives_temperature" class="sref">dev_attr_drives_temperaturen a>);v15222/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_drives_fan_rpm" class="sref">dev_attr_drives_fan_rpmn a>);v15232/a>v15242/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v15252/a>}v15262/a>v15272/a>2spa= class="comment">/*2/spa="v15282/a>2spa= class="comment"> * DIMMs temp control loop2/spa="v15292/a>2spa= class="comment"> */2/spa="v15302/a>static void 2a href="+code=do_monitor_dimms" class="sref">do_monitor_dimms2/a>(struct 2a href="+code=dimm_pid_stat " class="sref">dimm_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v15312/a>{v15322/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=integral" class="sref">integral2/a>, 2a href="+code=derivativ " class="sref">derivativ 2/a>, 2a href="+code=fan_min" class="sref">fan_min2/a>;v15332/a>        2a href="+code=s64" class="sref">s642/a> 2a href="+code=integ_p" class="sref">integ_p2/a>, 2a href="+code=deriv_p" class="sref">deriv_p2/a>, 2a href="+code=prop_p" class="sref">prop_p2/a>, 2a href="+code=sum" class="sref">sum2/a>;v15342/a>        int 2a href="+code=i" class="sref">i2/a>;v15352/a>v15362/a>        if (--2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> != 0)v15372/a>                return;v15382/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> = 2a href="+code=DIMM_PID_INTERVAL" class="sref">DIMM_PID_INTERVAL2/a>;v15392/a>v15402/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"DIMM:\n"2/spa=");v15412/a>v15422/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  current value: %d\n"2/spa=", 2a href="+code=stat " class="sref">stat n a>->2a href="+code=output" class="sref">outputn a>);v15432/a>v15442/a>        2a href="+code=temp" class="sref">temp2/a> = 2a href="+code=read_lm87_reg" class="sref">read_lm87_reg2/a>(2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a>, 2a href="+code=LM87_INT_TEMP" class="sref">LM87_INT_TEMPn a>);v15452/a>        if (2a href="+code=temp" class="sref">temp2/a> < 0)v15462/a>                return;v15472/a>        2a href="+code=temp" class="sref">temp2/a> <<= 16;v15482/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=last_temp" class="sref">last_temp2/a> = 2a href="+code=temp" class="sref">temp2/a>;v15492/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  temp: %d.%03d, target: %d.%03d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=temp" class="sref">temp2/a>),v15502/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=DIMM_PID_INPUT_TARGET" class="sref">DIMM_PID_INPUT_TARGET2/a>));v15512/a>v15522/a>        2spa= class="comment">/* Store temperature and error in history array */2/spa="v15532/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) % 2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a>;v15542/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v15552/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=DIMM_PID_INPUT_TARGET" class="sref">DIMM_PID_INPUT_TARGET2/a>;v15562/a>v15572/a>        2spa= class="comment">/* If first loop, fill the history table */2/spa="v15582/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a>) {v15592/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v15602/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) %v15612/a>                                2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a>;v15622/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v15632/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] =v15642/a>                                2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=DIMM_PID_INPUT_TARGET" class="sref">DIMM_PID_INPUT_TARGET2/a>;v15652/a>                }v15662/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 0;v15672/a>        }v15682/a>v15692/a>        2spa= class="comment">/* Calculat  the integral term */2/spa="v15702/a>        2a href="+code=sum" class="sref">sum2/a> = 0;v15712/a>        2a href="+code=integral" class="sref">integral2/a> = 0;v15722/a>        for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < 2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a>; 2a href="+code=i" class="sref">i2/a>++)v15732/a>                2a href="+code=integral" class="sref">integral2/a> += 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=i" class="sref">i2/a>];v15742/a>        2a href="+code=integral" class="sref">integral2/a> *= 2a href="+code=DIMM_PID_INTERVAL" class="sref">DIMM_PID_INTERVAL2/a>;v15752/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  integral: %08x\n"2/spa=", 2a href="+code=integral" class="sref">integral2/a>);v15762/a>        2a href="+code=integ_p" class="sref">integ_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DIMM_PID_G_r" class="sref">DIMM_PID_G_r2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=integral" class="sref">integral2/a>;v15772/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   integ_p: %d\n"2/spa=", (int)(2a href="+code=integ_p" class="sref">integ_p2/a> >> 36));v15782/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=integ_p" class="sref">integ_p2/a>;v15792/a>v15802/a>        2spa= class="comment">/* Calculat  the derivativ  term */2/spa="v15812/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] -v15822/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a> - 1)v15832/a>                                    % 2a href="+code=DIMM_PID_HISTORY_SIZE" class="sref">DIMM_PID_HISTORY_SIZE2/a>];v15842/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> /= 2a href="+code=DIMM_PID_INTERVAL" class="sref">DIMM_PID_INTERVAL2/a>;v15852/a>        2a href="+code=deriv_p" class="sref">deriv_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DIMM_PID_G_d" class="sref">DIMM_PID_G_d2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=derivativ " class="sref">derivativ 2/a>;v15862/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   deriv_p: %d\n"2/spa=", (int)(2a href="+code=deriv_p" class="sref">deriv_p2/a> >> 36));v15872/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=deriv_p" class="sref">deriv_p2/a>;v15882/a>v15892/a>        2spa= class="comment">/* Calculat  the proportional term */2/spa="v15902/a>        2a href="+code=prop_p" class="sref">prop_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=DIMM_PID_G_p" class="sref">DIMM_PID_G_p2/a>) * (2a href="+code=s64" class="sref">s642/a>)(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>]);v15912/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   prop_p: %d\n"2/spa=", (int)(2a href="+code=prop_p" class="sref">prop_p2/a> >> 36));v15922/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=prop_p" class="sref">prop_p2/a>;v15932/a>v15942/a>        2spa= class="comment">/* Scale sum */2/spa="v15952/a>        2a href="+code=sum" class="sref">sum2/a> >>= 36;v15962/a>v15972/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   sum: %d\n"2/spa=", (int)2a href="+code=sum" class="sref">sum2/a>);v15982/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=output" class="sref">outputn a> = (2a href="+code=s32" class="sref">s322/a>)2a href="+code=sum" class="sref">sum2/a>;v15992/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=output" class="sref">outputn a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=output" class="sref">outputn a>, 2a href="+code=DIMM_PID_OUTPUT_MIN" class="sref">DIMM_PID_OUTPUT_MIN2/a>);v16002/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=output" class="sref">outputn a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=output" class="sref">outputn a>, 2a href="+code=DIMM_PID_OUTPUT_MAX" class="sref">DIMM_PID_OUTPUT_MAX2/a>);v16012/a>        2a href="+code=dimm_output_clamp" class="sref">dimm_output_clamp2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=output" class="sref">outputn a>;v16022/a>v16032/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** DIMM clamp value: %d\n"2/spa=", (int)2a href="+code=stat " class="sref">stat n a>->2a href="+code=output" class="sref">outputn a>);v16042/a>v16052/a>        2spa= class="comment">/* Backside PID is only every 5 seconds, force backside fa= clamping now */2/spa="v16062/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = (2a href="+code=dimm_output_clamp" class="sref">dimm_output_clamp2/a> * 100) / 14000;v16072/a>        2a href="+code=fan_min" class="sref">fan_min2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=fan_min" class="sref">fan_min2/a>, 2a href="+code=backside_params" class="sref">backside_params2/a>.2a href="+code=output_min" class="sref">output_minn a>);v16082/a>        if (2a href="+code=backside_stat " class="sref">backside_stat 2/a>.2a href="+code=pwm" class="sref">pwm2/a> < 2a href="+code=fan_min" class="sref">fan_min2/a>) {v16092/a>                2a href="+code=backside_stat " class="sref">backside_stat 2/a>.2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=fan_min" class="sref">fan_min2/a>;v16102/a>                2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">" -> applying clamp to backside fa= now: %d  !\n"2/spa=", 2a href="+code=fan_min" class="sref">fan_min2/a>);v16112/a>                2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(2a href="+code=BACKSIDE_FAN_PWM_INDEX" class="sref">BACKSIDE_FAN_PWM_INDEX2/a>, 2a href="+code=fan_min" class="sref">fan_min2/a>);v16122/a>        }v16132/a>}v16142/a>v16152/a>2spa= class="comment">/*2/spa="v16162/a>2spa= class="comment"> * Initialize the stat  structure for the DIMM temp control loop2/spa="v16172/a>2spa= class="comment"> */2/spa="v16182/a>static int 2a href="+code=init_dimms_stat " class="sref">init_dimms_stat 2/a>(struct 2a href="+code=dimm_pid_stat " class="sref">dimm_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v16192/a>{v16202/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=ticks" class="sref">ticks2/a> = 1;v16212/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 1;v16222/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=output" class="sref">outputn a> = 4000;v16232/a>v16242/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=XSERVE_DIMMS_LM87" class="sref">XSERVE_DIMMS_LM872/a>, 2spa= class="string">"dimms_temp"2/spa=");v16252/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v16262/a>                return -2a href="+code=ENODEV" class="sref">ENODEVn a>;v16272/a>v16282/a>        if (2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_dimms_temperature" class="sref">dev_attr_dimms_temperature2/a>))v16292/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Fail d to creat  attribut  fil "2/spa="v16302/a>                        2spa= class="string">" for DIMM temperature\n"2/spa=");v16312/a>v16322/a>        return 0;v16332/a>}v16342/a>v16352/a>2spa= class="comment">/*2/spa="v16362/a>2spa= class="comment"> * Dispose of the stat  data for the DIMM control loop2/spa="v16372/a>2spa= class="comment"> */2/spa="v16382/a>static void 2a href="+code=dispose_dimms_stat " class="sref">dispose_dimms_stat 2/a>(struct 2a href="+code=dimm_pid_stat " class="sref">dimm_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v16392/a>{v16402/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v16412/a>                return;v16422/a>v16432/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_dimms_temperature" class="sref">dev_attr_dimms_temperature2/a>);v16442/a>v16452/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v16462/a>}v16472/a>v16482/a>2spa= class="comment">/*2/spa="v16492/a>2spa= class="comment"> * Slots fan control loop2/spa="v16502/a>2spa= class="comment"> */2/spa="v16512/a>static void 2a href="+code=do_monitor_slots" class="sref">do_monitor_slots2/a>(struct 2a href="+code=slots_pid_stat " class="sref">slots_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v16522/a>{v16532/a>        2a href="+code=s32" class="sref">s322/a> 2a href="+code=temp" class="sref">temp2/a>, 2a href="+code=integral" class="sref">integral2/a>, 2a href="+code=derivativ " class="sref">derivativ 2/a>;v16542/a>        2a href="+code=s64" class="sref">s642/a> 2a href="+code=integ_p" class="sref">integ_p2/a>, 2a href="+code=deriv_p" class="sref">deriv_p2/a>, 2a href="+code=prop_p" class="sref">prop_p2/a>, 2a href="+code=sum" class="sref">sum2/a>;v16552/a>        int 2a href="+code=i" class="sref">i2/a>, 2a href="+code=rc" class="sref">rc2/a>;v16562/a>v16572/a>        if (--2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> != 0)v16582/a>                return;v16592/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> = 2a href="+code=SLOTS_PID_INTERVAL" class="sref">SLOTS_PID_INTERVAL2/a>;v16602/a>v16612/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"slots:\n"2/spa=");v16622/a>v16632/a>        2spa= class="comment">/* Check fan status */2/spa="v16642/a>        2a href="+code=rc" class="sref">rc2/a> = 2a href="+code=get_pwm_fan" class="sref">get_pwm_fan2/a>(2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>);v16652/a>        if (2a href="+code=rc" class="sref">rc2/a> < 0) {v16662/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Error %d reading slots fan !\n"2/spa=", 2a href="+code=rc" class="sref">rc2/a>);v16672/a>                2spa= class="comment">/* XXX What do we do now ? */2/spa="v16682/a>        } elsev16692/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=rc" class="sref">rc2/a>;v16702/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  current pwm: %d\n"2/spa=", 2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwm2/a>);v16712/a>v16722/a>        2spa= class="comment">/* Get some sensor readings */2/spa="v16732/a>        2a href="+code=temp" class="sref">temp2/a> = 2a href="+code=le16_to_cpu" class="sref">le16_to_cpu2/a>(2a href="+code=i2c_smbus_read_word_data" class="sref">i2c_smbus_read_word_data2/a>(2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a>,v16742/a>                                                    2a href="+code=DS1775_TEMP" class="sref">DS1775_TEMP2/a>)) << 8;v16752/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=last_temp" class="sref">last_temp2/a> = 2a href="+code=temp" class="sref">temp2/a>;v16762/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  temp: %d.%03d, target: %d.%03d\n"2/spa=", 2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=temp" class="sref">temp2/a>),v16772/a>            2a href="+code=FIX32TOPRINT" class="sref">FIX32TOPRINT2/a>(2a href="+code=SLOTS_PID_INPUT_TARGET" class="sref">SLOTS_PID_INPUT_TARGET2/a>));v16782/a>v16792/a>        2spa= class="comment">/* Store temperature and error in history array */2/spa="v16802/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) % 2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a>;v16812/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v16822/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=SLOTS_PID_INPUT_TARGET" class="sref">SLOTS_PID_INPUT_TARGET2/a>;v16832/a>v16842/a>        2spa= class="comment">/* If first loop, fill the history table */2/spa="v16852/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a>) {v16862/a>                for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < (2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a> - 1); 2a href="+code=i" class="sref">i2/a>++) {v16872/a>                        2a href="+code=stat " class="sref">stat n a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> = (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 1) %v16882/a>                                2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a>;v16892/a>                        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=sampl _history" class="sref">sampl _history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] = 2a href="+code=temp" class="sref">temp2/a>;v16902/a>                        2a href="+code=stat " class="sref">stat n a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] =v16912/a>                                2a href="+code=temp" class="sref">temp2/a> - 2a href="+code=SLOTS_PID_INPUT_TARGET" class="sref">SLOTS_PID_INPUT_TARGET2/a>;v16922/a>                }v16932/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=first" class="sref">first2/a> = 0;v16942/a>        }v16952/a>v16962/a>        2spa= class="comment">/* Calculat  the integral term */2/spa="v16972/a>        2a href="+code=sum" class="sref">sum2/a> = 0;v16982/a>        2a href="+code=integral" class="sref">integral2/a> = 0;v16992/a>        for (2a href="+code=i" class="sref">i2/a> = 0; 2a href="+code=i" class="sref">i2/a> < 2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a>; 2a href="+code=i" class="sref">i2/a>++)v17002/a>                2a href="+code=integral" class="sref">integral2/a> += 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=i" class="sref">i2/a>];v17012/a>        2a href="+code=integral" class="sref">integral2/a> *= 2a href="+code=SLOTS_PID_INTERVAL" class="sref">SLOTS_PID_INTERVAL2/a>;v17022/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"  integral: %08x\n"2/spa=", 2a href="+code=integral" class="sref">integral2/a>);v17032/a>        2a href="+code=integ_p" class="sref">integ_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=SLOTS_PID_G_r" class="sref">SLOTS_PID_G_r2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=integral" class="sref">integral2/a>;v17042/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   integ_p: %d\n"2/spa=", (int)(2a href="+code=integ_p" class="sref">integ_p2/a> >> 36));v17052/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=integ_p" class="sref">integ_p2/a>;v17062/a>v17072/a>        2spa= class="comment">/* Calculat  the derivativ  term */2/spa="v17082/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> = 2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>] -v17092/a>                2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a> + 2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a> - 1)v17102/a>                                    % 2a href="+code=SLOTS_PID_HISTORY_SIZE" class="sref">SLOTS_PID_HISTORY_SIZE2/a>];v17112/a>        2a href="+code=derivativ " class="sref">derivativ 2/a> /= 2a href="+code=SLOTS_PID_INTERVAL" class="sref">SLOTS_PID_INTERVAL2/a>;v17122/a>        2a href="+code=deriv_p" class="sref">deriv_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=SLOTS_PID_G_d" class="sref">SLOTS_PID_G_d2/a>) * (2a href="+code=s64" class="sref">s642/a>)2a href="+code=derivativ " class="sref">derivativ 2/a>;v17132/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   deriv_p: %d\n"2/spa=", (int)(2a href="+code=deriv_p" class="sref">deriv_p2/a> >> 36));v17142/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=deriv_p" class="sref">deriv_p2/a>;v17152/a>v17162/a>        2spa= class="comment">/* Calculat  the proportional term */2/spa="v17172/a>        2a href="+code=prop_p" class="sref">prop_p2/a> = ((2a href="+code=s64" class="sref">s642/a>)2a href="+code=SLOTS_PID_G_p" class="sref">SLOTS_PID_G_p2/a>) * (2a href="+code=s64" class="sref">s642/a>)(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=error_history" class="sref">error_history2/a>[2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=cur_sampl " class="sref">cur_sampl 2/a>]);v17182/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   prop_p: %d\n"2/spa=", (int)(2a href="+code=prop_p" class="sref">prop_p2/a> >> 36));v17192/a>        2a href="+code=sum" class="sref">sum2/a> += 2a href="+code=prop_p" class="sref">prop_p2/a>;v17202/a>v17212/a>        2spa= class="comment">/* Scale sum */2/spa="v17222/a>        2a href="+code=sum" class="sref">sum2/a> >>= 36;v17232/a>v17242/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"   sum: %d\n"2/spa=", (int)2a href="+code=sum" class="sref">sum2/a>);v17252/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a> = (2a href="+code=s32" class="sref">s322/a>)2a href="+code=sum" class="sref">sum2/a>;v17262/a>v17272/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=max" class="sref">max2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a>, 2a href="+code=SLOTS_PID_OUTPUT_MIN" class="sref">SLOTS_PID_OUTPUT_MIN2/a>);v17282/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a> = 2a href="+code=min" class="sref">min2/a>(2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a>, 2a href="+code=SLOTS_PID_OUTPUT_MAX" class="sref">SLOTS_PID_OUTPUT_MAX2/a>);v17292/a>v17302/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"** DRIVES PWM: %d\n"2/spa=", (int)2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwm2/a>);v17312/a>        2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>, 2a href="+code=stat " class="sref">stat n a>->2a href="+code=pwm" class="sref">pwm2/a>);v17322/a>}v17332/a>v17342/a>2spa= class="comment">/*2/spa="v17352/a>2spa= class="comment"> * Initialize the stat  structure for the slots bay fan control loop2/spa="v17362/a>2spa= class="comment"> */2/spa="v17372/a>static int 2a href="+code=init_slots_stat " class="sref">init_slots_stat 2/a>(struct 2a href="+code=slots_pid_stat " class="sref">slots_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v17382/a>{v17392/a>        int 2a href="+code=err" class="sref">err2/a>;v17402/a>v17412/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=ticks" class="sref">ticks2/a> = 1;v17422/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=first" class="sref">first2/a> = 1;v17432/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=pwm" class="sref">pwm2/a> = 50;v17442/a>v17452/a>        2a href="+code=stat " class="sref">stat n a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=XSERVE_SLOTS_LM75" class="sref">XSERVE_SLOTS_LM752/a>, 2spa= class="string">"slots_temp"2/spa=");v17462/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v17472/a>                return -2a href="+code=ENODEV" class="sref">ENODEVn a>;v17482/a>v17492/a>        2a href="+code=err" class="sref">err2/a> = 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_slots_temperature" class="sref">dev_attr_slots_temperature2/a>);v17502/a>        2a href="+code=err" class="sref">err2/a> |= 2a href="+code=device_creat _fil " class="sref">device_creat _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_slots_fan_pwm" class="sref">dev_attr_slots_fan_pwm2/a>);v17512/a>        if (2a href="+code=err" class="sref">err2/a>)v17522/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Fail d to creat  attribut  fil (s)"2/spa="v17532/a>                        2spa= class="string">" for slots bay fan\n"2/spa=");v17542/a>v17552/a>        return 0;v17562/a>}v17572/a>v17582/a>2spa= class="comment">/*2/spa="v17592/a>2spa= class="comment"> * Dispose of the stat  data for the slots control loop2/spa="v17602/a>2spa= class="comment"> */2/spa="v17612/a>static void 2a href="+code=dispose_slots_stat " class="sref">dispose_slots_stat 2/a>(struct 2a href="+code=slots_pid_stat " class="sref">slots_pid_stat 2/a> *2a href="+code=stat " class="sref">stat n a>)v17622/a>{v17632/a>        if (2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v17642/a>                return;v17652/a>v17662/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_slots_temperature" class="sref">dev_attr_slots_temperature2/a>);v17672/a>        2a href="+code=device_remov _fil " class="sref">device_remov _fil 2/a>(&2a href="+code=of_dev" class="sref">of_dev2/a>->2a href="+code=dev" class="sref">dev2/a>, &2a href="+code=dev_attr_slots_fan_pwm" class="sref">dev_attr_slots_fan_pwm2/a>);v17682/a>v17692/a>        2a href="+code=stat " class="sref">stat 2/a>->2a href="+code=monitor" class="sref">monitor2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v17702/a>}v17712/a>v17722/a>v17732/a>static int 2a href="+code=call_critical_ov rtemp" class="sref">call_critical_ov rtemp2/a>(void)v17742/a>{v17752/a>        char *2a href="+code=argv" class="sref">argv2/a>[] = { 2a href="+code=critical_ov rtemp_path" class="sref">critical_ov rtemp_path2/a>, 2a href="+code=NULL" class="sref">NULL2/a> };v17762/a>        static char *2a href="+code=envp" class="sref">envp2/a>[] = { 2spa= class="string">"HOME=/"2/spa=",v17772/a>                                2spa= class="string">"TERM=linux"2/spa=",v17782/a>                                2spa= class="string">"PATH=/sbin:/usr/sbin:/bin:/usr/bin"2/spa=",v17792/a>                                2a href="+code=NULL" class="sref">NULL2/a> };v17802/a>v17812/a>        return 2a href="+code=call_usermodehelper" class="sref">call_usermodehelper2/a>(2a href="+code=critical_ov rtemp_path" class="sref">critical_ov rtemp_path2/a>,v17822/a>                                   2a href="+code=argv" class="sref">argv2/a>, 2a href="+code=envp" class="sref">envp2/a>, 2a href="+code=UMH_WAIT_EXEC" class="sref">UMH_WAIT_EXEC2/a>);v17832/a>}v17842/a>v17852/a>v17862/a>2spa= class="comment">/*2/spa="v17872/a>2spa= class="comment"> * Here's the kernel thread that calls the various control loops2/spa="v17882/a>2spa= class="comment"> */2/spa="v17892/a>static int 2a href="+code=main_control_loop" class="sref">main_control_loop2/a>(void *2a href="+code=x" class="sref">x2/a>)v17902/a>{v17912/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"main_control_loop started\n"2/spa=");v17922/a>v17932/a>        2a href="+code=mutex_lock" class="sref">mutex_lock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);v17942/a>v17952/a>        if (2a href="+code=start_fcu" class="sref">start_fcu2/a>() < 0) {v17962/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_ERR" class="sref">KERN_ERR2/a> 2spa= class="string">"kfand: fail d to start FCU\n"2/spa=");v17972/a>                2a href="+code=mutex_unlock" class="sref">mutex_unlock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);v17982/a>                goto 2a href="+code=out" class="sref">out2/a>;v17992/a>        }v18002/a>v18012/a>        2spa= class="comment">/* Set the PCI fan once for now on non-RackMac */2/spa="v18022/a>        if (!2a href="+code=rackmac" class="sref">rackmac2/a>)v18032/a>                2a href="+code=set_pwm_fan" class="sref">set_pwm_fan2/a>(2a href="+code=SLOTS_FAN_PWM_INDEX" class="sref">SLOTS_FAN_PWM_INDEX2/a>, 2a href="+code=SLOTS_FAN_DEFAULT_PWM" class="sref">SLOTS_FAN_DEFAULT_PWM2/a>);v18042/a>v18052/a>        2spa= class="comment">/* Initialize ADCs */2/spa="v18062/a>        2a href="+code=initialize_adc" class="sref">initialize_adc2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0]);v18072/a>        if (2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1].2a href="+code=monitor" class="sref">monitor2/a> != 2a href="+code=NULL" class="sref">NULL2/a>)v18082/a>                2a href="+code=initialize_adc" class="sref">initialize_adc2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1]);v18092/a>v18102/a>        2a href="+code=fcu_tickle_ticks" class="sref">fcu_tickle_ticks2/a> = 2a href="+code=FCU_TICKLE_TICKS" class="sref">FCU_TICKLE_TICKS2/a>;v18112/a>v18122/a>        2a href="+code=mutex_unlock" class="sref">mutex_unlock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);v18132/a>v18142/a>        whil  (2a href="+code=stat " class="sref">stat 2/a> == 2a href="+code=stat _attached" class="sref">stat _attached2/a>) {v18152/a>                unsign d long 2a href="+code=elapsed" class="sref">elapsed2/a>, 2a href="+code=start" class="sref">start2/a>;v18162/a>v18172/a>                2a href="+code=start" class="sref">start2/a> = 2a href="+code=jiffies" class="sref">jiffies2/a>;v18182/a>v18192/a>                2a href="+code=mutex_lock" class="sref">mutex_lock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);v18202/a>v18212/a>                2spa= class="comment">/* Tickle the FCU just in case */2/spa="v18222/a>                if (--2a href="+code=fcu_tickle_ticks" class="sref">fcu_tickle_ticks2/a> < 0) {v18232/a>                        2a href="+code=fcu_tickle_ticks" class="sref">fcu_tickle_ticks2/a> = 2a href="+code=FCU_TICKLE_TICKS" class="sref">FCU_TICKLE_TICKS2/a>;v18242/a>                        2a href="+code=tickle_fcu" class="sref">tickle_fcu2/a>();v18252/a>                }v18262/a>v18272/a>                2spa= class="comment">/* First, we always calculat  the new DIMMs stat  on a= Xserve */2/spa="v18282/a>                if (2a href="+code=rackmac" class="sref">rackmac2/a>)v18292/a>                        2a href="+code=do_monitor_dimms" class="sref">do_monitor_dimms2/a>(&2a href="+code=dimms_stat " class="sref">dimms_stat 2/a>);v18302/a>v18312/a>                2spa= class="comment">/* Then, the CPUs */2/spa="v18322/a>                if (2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> == 2a href="+code=CPU_PID_TYPE_COMBINED" class="sref">CPU_PID_TYPE_COMBINED2/a>)v18332/a>                        2a href="+code=do_monitor_cpu_combined" class="sref">do_monitor_cpu_combined2/a>();v18342/a>                else if (2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> == 2a href="+code=CPU_PID_TYPE_RACKMAC" class="sref">CPU_PID_TYPE_RACKMAC2/a>) {v18352/a>                        2a href="+code=do_monitor_cpu_rack" class="sref">do_monitor_cpu_rack2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0]);v18362/a>                        if (2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1].2a href="+code=monitor" class="sref">monitor2/a> != 2a href="+code=NULL" class="sref">NULL2/a>)v18372/a>                                2a href="+code=do_monitor_cpu_rack" class="sref">do_monitor_cpu_rack2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1]);v18382/a>                        2spa= class="comment">// better deal with UP2/spa="v18392/a>                } else {v18402/a>                        2a href="+code=do_monitor_cpu_split" class="sref">do_monitor_cpu_split2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0]);v18412/a>                        if (2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1].2a href="+code=monitor" class="sref">monitor2/a> != 2a href="+code=NULL" class="sref">NULL2/a>)v18422/a>                                2a href="+code=do_monitor_cpu_split" class="sref">do_monitor_cpu_split2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1]);v18432/a>                        2spa= class="comment">// better deal with UP2/spa="v18442/a>                }v18452/a>                2spa= class="comment">/* Then, the rest */2/spa="v18462/a>                2a href="+code=do_monitor_backsid " class="sref">do_monitor_backsid 2/a>(&2a href="+code=backsid _stat " class="sref">backsid _stat 2/a>);v18472/a>                if (2a href="+code=rackmac" class="sref">rackmac2/a>)v18482/a>                        2a href="+code=do_monitor_slots" class="sref">do_monitor_slots2/a>(&2a href="+code=slots_stat " class="sref">slots_stat 2/a>);v18492/a>                elsev18502/a>                        2a href="+code=do_monitor_drives" class="sref">do_monitor_drives2/a>(&2a href="+code=drives_stat " class="sref">drives_stat 2/a>);v18512/a>                2a href="+code=mutex_unlock" class="sref">mutex_unlock2/a>(&2a href="+code=driver_lock" class="sref">driver_lock2/a>);v18522/a>v18532/a>                if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> == 1) {v18542/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Temperature control detected a critical condition\n"2/spa=");v18552/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Attempting to shut down...\n"2/spa=");v18562/a>                        if (2a href="+code=call_critical_ov rtemp" class="sref">call_critical_ov rtemp2/a>()) {v18572/a>                                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Can't call %s, power off now!\n"2/spa=",v18582/a>                                       2a href="+code=critical_ov rtemp_path" class="sref">critical_ov rtemp_path2/a>);v18592/a>                                2a href="+code=machine_power_off" class="sref">machine_power_off2/a>();v18602/a>                        }v18612/a>                }v18622/a>                if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> > 0)v18632/a>                        2a href="+code=critical_stat " class="sref">critical_stat 2/a>++;v18642/a>                if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> > 2a href="+code=MAX_CRITICAL_STATE" class="sref">MAX_CRITICAL_STATE2/a>) {v18652/a>                        2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_WARNING" class="sref">KERN_WARNING2/a> 2spa= class="string">"Shutdown timed out, power off now !\n"2/spa=");v18662/a>                        2a href="+code=machine_power_off" class="sref">machine_power_off2/a>();v18672/a>                }v18682/a>v18692/a>                2spa= class="comment">// FIXME: Deal with signals2/spa="v18702/a>                2a href="+code=elapsed" class="sref">elapsed2/a> = 2a href="+code=jiffies" class="sref">jiffies2/a> - 2a href="+code=start" class="sref">start2/a>;v18712/a>                if (2a href="+code=elapsed" class="sref">elapsed2/a> < 2a href="+code=HZ" class="sref">HZ2/a>)v18722/a>                        2a href="+code=schedule_timeout_interruptibl " class="sref">schedule_timeout_interruptibl 2/a>(2a href="+code=HZ" class="sref">HZ2/a> - 2a href="+code=elapsed" class="sref">elapsed2/a>);v18732/a>        }v18742/a>v18752/a> 2a href="+code=out" class="sref">out2/a>:v18762/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"main_control_loop ended\n"2/spa=");v18772/a>v18782/a>        2a href="+code=ctrl_task" class="sref">ctrl_task2/a> = 0;v18792/a>        2a href="+code=complet _and_exit" class="sref">complet _and_exit2/a>(&2a href="+code=ctrl_complet " class="sref">ctrl_complet 2/a>, 0);v18802/a>}v18812/a>v18822/a>2spa= class="comment">/*2/spa="v18832/a>2spa= class="comment"> * Dispose the control loops when tearing down2/spa="v18842/a>2spa= class="comment"> */2/spa="v18852/a>static void 2a href="+code=dispose_control_loops" class="sref">dispose_control_loops2/a>(void)v18862/a>{v18872/a>        2a href="+code=dispose_processor_stat " class="sref">dispose_processor_stat 2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0]);v18882/a>        2a href="+code=dispose_processor_stat " class="sref">dispose_processor_stat 2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1]);v18892/a>        2a href="+code=dispose_backsid _stat " class="sref">dispose_backsid _stat 2/a>(&2a href="+code=backsid _stat " class="sref">backsid _stat 2/a>);v18902/a>        2a href="+code=dispose_drives_stat " class="sref">dispose_drives_stat 2/a>(&2a href="+code=drives_stat " class="sref">drives_stat 2/a>);v18912/a>        2a href="+code=dispose_slots_stat " class="sref">dispose_slots_stat 2/a>(&2a href="+code=slots_stat " class="sref">slots_stat 2/a>);v18922/a>        2a href="+code=dispose_dimms_stat " class="sref">dispose_dimms_stat 2/a>(&2a href="+code=dimms_stat " class="sref">dimms_stat 2/a>);v18932/a>}v18942/a>v18952/a>2spa= class="comment">/*2/spa="v18962/a>2spa= class="comment"> * Creat  the control loops. U3-0 i2c bus is up, so we can now2/spa="v18972/a>2spa= class="comment"> * get to the various sensors2/spa="v18982/a>2spa= class="comment"> */2/spa="v18992/a>static int 2a href="+code=creat _control_loops" class="sref">creat _control_loops2/a>(void)v19002/a>{v19012/a>        struct 2a href="+code=device_nod " class="sref">device_nod 2/a> *2a href="+code=np" class="sref">np2/a>;v19022/a>v19032/a>        2spa= class="comment">/* Count CPUs from the device-tree, we don't care how many are2/spa="v19042/a>2spa= class="comment">         * actually used by Linux2/spa="v19052/a>2spa= class="comment">         */2/spa="v19062/a>        2a href="+code=cpu_count" class="sref">cpu_count2/a> = 0;v19072/a>        for (2a href="+code=np" class="sref">np2/a> = 2a href="+code=NULL" class="sref">NULL2/a>; 2a href="+code=NULL" class="sref">NULL2/a> != (2a href="+code=np" class="sref">np2/a> = 2a href="+code=of_find_nod _by_typ " class="sref">of_find_nod _by_typ 2/a>(2a href="+code=np" class="sref">np2/a>, 2spa= class="string">"cpu"2/spa="));)v19082/a>                2a href="+code=cpu_count" class="sref">cpu_count2/a>++;v19092/a>v19102/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"counted %d CPUs in the device-tree\n"2/spa=", 2a href="+code=cpu_count" class="sref">cpu_count2/a>);v19112/a>v19122/a>        2spa= class="comment">/* Decid  the typ  of PID algorithm to use based on the presenc  of2/spa="v19132/a>2spa= class="comment">         * the pumps, though that may not b  the best way, that is good enough2/spa="v19142/a>2spa= class="comment">         * for now2/spa="v19152/a>2spa= class="comment">         */2/spa="v19162/a>        if (2a href="+code=rackmac" class="sref">rackmac2/a>)v19172/a>                2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> = 2a href="+code=CPU_PID_TYPE_RACKMAC" class="sref">CPU_PID_TYPE_RACKMAC2/a>;v19182/a>        else if (2a href="+code=of_machine_is_compatibl " class="sref">of_machine_is_compatibl 2/a>(2spa= class="string">"PowerMac7,3"2/spa=")v19192/a>            && (2a href="+code=cpu_count" class="sref">cpu_count2/a> > 1)v19202/a>            && 2a href="+code=fcu_fans" class="sref">fcu_fans2/a>[2a href="+code=CPUA_PUMP_RPM_INDEX" class="sref">CPUA_PUMP_RPM_INDEX2/a>].2a href="+code=id" class="sref">id2/a> != 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>v19212/a>            && 2a href="+code=fcu_fans" class="sref">fcu_fans2/a>[2a href="+code=CPUB_PUMP_RPM_INDEX" class="sref">CPUB_PUMP_RPM_INDEX2/a>].2a href="+code=id" class="sref">id2/a> != 2a href="+code=FCU_FAN_ABSENT_ID" class="sref">FCU_FAN_ABSENT_ID2/a>) {v19222/a>                2a href="+code=printk" class="sref">printk2/a>(2a href="+code=KERN_INFO" class="sref">KERN_INFO2/a> 2spa= class="string">"Liquid cooling pumps detected, using new algorithm !\n"2/spa=");v19232/a>                2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> = 2a href="+code=CPU_PID_TYPE_COMBINED" class="sref">CPU_PID_TYPE_COMBINED2/a>;v19242/a>        } elsev19252/a>                2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> = 2a href="+code=CPU_PID_TYPE_SPLIT" class="sref">CPU_PID_TYPE_SPLIT2/a>;v19262/a>v19272/a>        2spa= class="comment">/* Creat  control loops for everything. If any fail, everything2/spa="v19282/a>2spa= class="comment">         * fails2/spa="v19292/a>2spa= class="comment">         */2/spa="v19302/a>        if (2a href="+code=init_processor_stat " class="sref">init_processor_stat 2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[0], 0))v19312/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19322/a>        if (2a href="+code=cpu_pid_typ " class="sref">cpu_pid_typ 2/a> == 2a href="+code=CPU_PID_TYPE_COMBINED" class="sref">CPU_PID_TYPE_COMBINED2/a>)v19332/a>                2a href="+code=fetch_cpu_pumps_minmax" class="sref">fetch_cpu_pumps_minmax2/a>();v19342/a>v19352/a>        if (2a href="+code=cpu_count" class="sref">cpu_count2/a> > 1 && 2a href="+code=init_processor_stat " class="sref">init_processor_stat 2/a>(&2a href="+code=processor_stat " class="sref">processor_stat 2/a>[1], 1))v19362/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19372/a>        if (2a href="+code=init_backsid _stat " class="sref">init_backsid _stat 2/a>(&2a href="+code=backsid _stat " class="sref">backsid _stat 2/a>))v19382/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19392/a>        if (2a href="+code=rackmac" class="sref">rackmac2/a> && 2a href="+code=init_dimms_stat " class="sref">init_dimms_stat 2/a>(&2a href="+code=dimms_stat " class="sref">dimms_stat 2/a>))v19402/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19412/a>        if (2a href="+code=rackmac" class="sref">rackmac2/a> && 2a href="+code=init_slots_stat " class="sref">init_slots_stat 2/a>(&2a href="+code=slots_stat " class="sref">slots_stat 2/a>))v19422/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19432/a>        if (!2a href="+code=rackmac" class="sref">rackmac2/a> && 2a href="+code=init_drives_stat " class="sref">init_drives_stat 2/a>(&2a href="+code=drives_stat " class="sref">drives_stat 2/a>))v19442/a>                goto 2a href="+code=fail" class="sref">fail2/a>;v19452/a>v19462/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"all control loops up !\n"2/spa=");v19472/a>v19482/a>        return 0;v19492/a>        v19502/a> 2a href="+code=fail" class="sref">fail2/a>:v19512/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"failure creating control loops, disposing\n"2/spa=");v19522/a>v19532/a>        2a href="+code=dispose_control_loops" class="sref">dispose_control_loops2/a>();v19542/a>v19552/a>        return -2a href="+code=ENODEV" class="sref">ENODEV2/a>;v19562/a>}v19572/a>v19582/a>2spa= class="comment">/*2/spa="v19592/a>2spa= class="comment"> * Start the control loops after everything is up, that is creat 2/spa="v19602/a>2spa= class="comment"> * the thread that will mak  them run2/spa="v19612/a>2spa= class="comment"> */2/spa="v19622/a>static void 2a href="+code=start_control_loops" class="sref">start_control_loops2/a>(void)v19632/a>{v19642/a>        2a href="+code=init_completion" class="sref">init_completion2/a>(&2a href="+code=ctrl_complet " class="sref">ctrl_complet 2/a>);v19652/a>v19662/a>        2a href="+code=ctrl_task" class="sref">ctrl_task2/a> = 2a href="+code=kthread_run" class="sref">kthread_run2/a>(2a href="+code=main_control_loop" class="sref">main_control_loop2/a>, 2a href="+code=NULL" class="sref">NULL2/a>, 2spa= class="string">"kfand"2/spa=");v19672/a>}v19682/a>v19692/a>2spa= class="comment">/*2/spa="v19702/a>2spa= class="comment"> * Stop the control loops when tearing down2/spa="v19712/a>2spa= class="comment"> */2/spa="v19722/a>static void 2a href="+code=stop_control_loops" class="sref">stop_control_loops2/a>(void)v19732/a>{v19742/a>        if (2a href="+code=ctrl_task" class="sref">ctrl_task2/a>)v19752/a>                2a href="+code=wait_for_completion" class="sref">wait_for_completion2/a>(&2a href="+code=ctrl_complet " class="sref">ctrl_complet 2/a>);v19762/a>}v19772/a>v19782/a>2spa= class="comment">/*2/spa="v19792/a>2spa= class="comment"> * Attach to the i2c FCU after detecting U3-1 bus2/spa="v19802/a>2spa= class="comment"> */2/spa="v19812/a>static int 2a href="+code=attach_fcu" class="sref">attach_fcu2/a>(void)v19822/a>{v19832/a>        2a href="+code=fcu" class="sref">fcu2/a> = 2a href="+code=attach_i2c_chip" class="sref">attach_i2c_chip2/a>(2a href="+code=FAN_CTRLER_ID" class="sref">FAN_CTRLER_ID2/a>, 2spa= class="string">"fcu"2/spa=");v19842/a>        if (2a href="+code=fcu" class="sref">fcu2/a> == 2a href="+code=NULL" class="sref">NULL2/a>)v19852/a>                return -2a href="+code=ENODEV" class="sref">ENODEV2/a>;v19862/a>v19872/a>        2a href="+code=DBG" class="sref">DBG2/a>(2spa= class="string">"FCU attached\n"2/spa=");v19882/a>v19892/a>        return 0;v19902/a>}v19912/a>v19922/a>2spa= class="comment">/*2/spa="v19932/a>2spa= class="comment"> * Detach from the i2c FCU when tearing down2/spa="v19942/a>2spa= class="comment"> */2/spa="v19952/a>static void 2a href="+code=detach_fcu" class="sref">detach_fcu2/a>(void)v19962/a>{v19972/a>        2a href="+code=fcu" class="sref">fcu2/a> = 2a href="+code=NULL" class="sref">NULL2/a>;v19982/a>}v19992/a>v20002/a>2spa= class="comment">/*2/spa="v
/*2/spa="v
jiffss="sref">CPU_PID_TYPE_SPLIT2/a>;v19872/a> nam v2L1860">18602/a> }v985" class="line" nam v2L19s="E5cksid _sta> 2a href="+code=DBG" class="sref">DBG2/ax2L1990" idv2L1990" classe92/a> 2a hre" idv842/a> if (2a12L1887">18872/a> 2a href="+code=dispose_. Wne" o"commenclass="sass=s4" clantosh/therm_pm72.c#L1997" idv2L1997" class="line" 2" classe92994" class="line" nam ve9299 9942/a>2spa= class="comment oclass="comment">/ cints andcu2ild2/a>2spa= cl="coass="#L199a hntosh/therm_pm72.c#L1997" idv2L1997" class="line" 3" classe921995" class="line" nam e9219 19952/a>static void 2a href="+runspa= tref"kickoass="#L199ass="sreidv2Lacintntosh/therm_pm72.c#L1997" idv2L1997" class="line" 4" classe92996" class="line" nam ve9299 9962/a>{v 2a hrefe9219 cu" class="sef">fcu2/a> = 2a hr" class="l_lass="2L2000">20002/a" class="l_lass="a>;v 2spa= class=" cladapss= 2a href= cladapss=2L200ee, we don'tadapss= 2a hrefadapss=2L20ef="drivers/macintosh/therm_pm72.c#L1998" i 6" classe92s="line" nam v2L1998">1e92s= 1e92s= a href="drivers/macintosh/th href= if (2a href=code=critical_stat " class="sref">critical_stat 2/a> == 1) {v19912/a>v1911s""li>s""lintosh/therm_pm72.c#L1986" idv2 if (!2a href="tected a cri2.c#L1986" idv2 _ef">NUs="line" nam v2L1 _ef">NUs=2L20ef="drivers/macintosh/therm_pm72.c#L1998" i 10" classe91913" class="line" nam ve9191>s""L1853" class="line" nam v2L1853">185 if (!2a href="tected a ci2.c#L1986" idv2 _lass="0" iline" nam v2L1 _lass="0" a= class="comment">/*2/spa="v
s""u_pumps_minmax" class="sref">fet       if (!2a href="tected a  class="string">&q     _lass="0" iline" nam v2L1     _lass="0" a= cm !\n"2/spa=");vcritical_stat 2/a> == 1) {v19162/a> e9" n>s""="sref">DBG2/a>(2spa=>2spa= class="comment">/*2/spa="vs""" class="sref/*2/spa="v
s""19882/a>vs""8_pumps_minmax" class="sref">fetu3_0al_stat 2/a> ==u3_0am v2L1986">19862/a>vfail2/ a> css="string">"a> css"sref">NULL2/a>)vNULL2/a>)vfetu3_0al_stat 2/a> ==u3_0am v2Lcode=fcu" class="dapss= 2a hrefadapss=2L20lass="comment">/*2/spa="vvs"T_a href="+code=start" ass="sref">fet>19532/a> 2a href="+code=dispose_control_loops"oundc= clne" nam v2L1990">19902/a>}v) {vschedule_timeout_interruptibl 2/ak2532/a> 2ku_pump||/ "drivers/macintosh/therm_pm72.c#L1918" idv2L1918" class="line" nam v2L1918">s"T2" classe9.c#L1923" idv2L1923" clae9.c#>s"Tam v2L1873">18732/a> }ss="sref">printk2/a>(od " class="sref">device_nod 2/a> *2a href="+code=np" clas72.c#L1946" idv2L1946" class="line" nam v2L1s"T3" classe9 } elsevfetu3_0al_stat 2/a> ==u3_0am v2Lcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
;vfetu3_1al_stat 2/a> ==u3_1am v2L1986">19862/a>vfail2/                a> css="string">"a> css"sref">NULL2/a>)vNULL2/a>)vs"T_pm72.c#L1977" idv2L1977" class="linu3_1al_stat 2/a> ==u3_1am v2Lcode=fcu" class="dapss=        2a hrefadapss=2L20lass="comment">/*2/spa="vs"Tde=rackmac" class="sref">rackmac2/a>>19532/a>        2a href="+code=dispose_control_loops"oundc= c1, lass="0" ass=ne" nam v2L1990">19902/a>}vs"T " class="sref">slots_stat 2/a>);v72.c#L1946" idv2L1946" class="line" nam v2L1s"T8" classe9nam v2L1930">19302/a>   e9nam>s"Ts/macintosh/therm_pm72.c#L1850" idv2L1850" cu3_1al_stat 2/a> ==u3_1am v2Lcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
proce9sta>s"T9herm_pm72.c#L1926"ax" class="sref">fetk2532/a>        2ku_pumpL1986">19862/a>vfail2/                a> css="string">"a> css"sref">NULL2/a>)vNULL2/a>)v                gs"931>s"93e=rackmac" class="sref">rackmac2/a>k2532/a>        2ku_pumpLcode=fcu" class="dapss=        2a hrefadapss=2L20lass="comment">/*2/spa="vs"9L1853" class="line" nam v2L1853">185 href="drivers/macintosh/therm_pm72.c#L1990" idv2L1990oundcK2ne" nam v2L1990">19902/a>}v ==u3_0am v2ref">fail2/a>;vs"33" classe9lass="line" nam v2L1935"e9las>s"9e=MAX_CRITICAL_STATE" class="ss="sref">printk2/a>(od " class="sref">device_nod 2/a> *2a href="+code=np" clas72.c#L1946" idv2L1946" class="line" nam v2L1s"34" classe9(&2a href="+code=proe9(&a>s"9lass="line" nam v2L1855">1855lass="sref">rackmac2/a>k2532/a>        2ku_pumpLcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
s"9" class="sref/*2/spa="v
s"9fail" class="sref">fail2/a>;v ==u3_0am v2 class="string">&q href="drivers/macintosh/thsref">fail2/0" idv2L1850" cu3_1al_stat 2/a> ==u3_1am v2 class="string">&q href="drivers/macintosh/thsref">fail2/interruptibl 2/ak2532/a> 2ku_pump||/ "drivers/macintosh/therm_pm72.c#L1t !\n"2/spa=");vs"9" class="sref">DBG2/a>(2spa= class=" href="drivers/macintosh/therm_pm72.c#L1990" idv2L199/a>2spa= cl"> */&">dispose_controlne" nam v2L1990">19902/a>}vs"92a href="+code=start" ass="sref">fet if (!2a href="tected a ci2.c#L1986" idv2 _lass="s="line" nam v2L1 _lass="s=a= class="comment">/*2/spa="v
s"loa href="+code=start" ass="sref">fet   lass="sref">init_completion2/a>(&2a href="+code=ctr">19902/a>}vs"l1 class="sref/*2/spa="v
if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> == 1) {vv2spa= class="comment">/*2/spa="v/*2/spa="vvs"l7u" class="sef">fcu2/a> = 2a hr" class="l_" o"c2L2000">20002/a" class="l_" o"ca>;v 2spa= class=" clclie362/a> " clclie362L200ee, we don'tclie362/a> clie362L20,/a>v:v 2spa= class=" clom the ref">KERN_INFO2/a> clom the re2L200ee, we don'tref">KERN_INFO2/a> 2spa2.c#L1946" idv2L1946" class="line" nam v2L1s"49" classe9ref="+code=DBG" class="se9ref>s"l9a href="drivers/macintosh/therm_pm72.c#L1999" i 5="drivers"sing\n"2/spa=");vs"si href="driverclass="line" nam v2L1929Always succe;vs"s1ass="line" n>2spa= class="comment">/*2/spa="v19542/a>ve9" n>s"s2nt">/*2/spa="v19552/a> e9" n>s"s39882/a>v{v */2/spa="v 2a href=* C" ied"sref" */2_pmsh/="commes" cich pamp"cip a= c href=rmaclasnageme362L/2/spa="vs"sL1898" idv2L1898" class="line"/spa=">diaway.2L/2/spa="vs"sint 2a href="+code=creat _conintosh/therm_pm72.c#L1997" idv2L1997" class="line" 58" classe9m_pm72.c#L1960" idv2L196e9m_p>s"s8u" class="sef">fcu2/a> = 2a hr" class="l_removc2L2000">20002/a" class="l_removca>;v 2spa= class=" clclie362/a> " clclie362L200ee, we don'tclie362/a> clie362L202.c#L1946" idv2L1946" class="line" nam v2L1s"59" classe9a="vs"s9a href="drivers/macintosh/therm_pm72.c#L1999" i 6="drivers"class="line" nam v2L1962s"cla>s"class="line" na> 2spa= class=" cladapss= 2a href= cladapss=2L200ee, we don'tadapss= 2a hrefadapss=2L20 ci2.c#L1986" idv2clie362/a> clie362L20-ref=">NULL2/a>)v/*2/spa="vs"c2/spa="v19642e9lin>s"c4" idv2L1894" class="line" n32/a> if (2a href=code=critical_stat " class="sref">critical_stat 2/a> == 1) {vs"c39882/a>vs"ccintosh/therm_pm72.c#L1986" idv2 if (!2a href="tected a class="string">&q _ef">NUs="line" nam v2L1 _ef">NUs=2L20ef="drivers/macintosh/therm_pm72.c#L1998" i 65" classe9ss="sref">main_control_le9ss=>s"c_pm72.c#L1977" idv2L1977" class="lin if (!2a href="tected a ci2.c#L1986" idv2 _ef">NU0" iline" nam v2L1 _ef">NU0" 2L20lass="comment">/*2/spa="v"kfand"2/e9ing>s"c19882/a>vs"c9" idv2L1929" class="line" nam v2L1929ode=scontrol_loops"i */2nintosh/therm_pm72.c#L1997" idv2L1997" class="line" 68" classe9 control loops when teare9 co>s"cose_backsid _stat " class="s href="drivers/macintosh/therm_pm72.c#L1990" idv2L199="drp">dispose_controlne" nam v2L1990">19902/a>}vs"cves_stat " class="sref">disp32/a> if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> == 1) {vs"19es_stat " class="sref">dispass="sref">ctrl_task2/a>)vs"13" class="line" nam v2L1953"32/a> if (2a href=code=critical_stat " class="sref">critical_stat 2/a> == 1) {v19742/ae9ne">s"1drivers/macintosh/therm_pm72.c#L1955" idv2L1955s"13" classe9a> 2a hree9a> >s"1v2L1944">19442/a>">fail2/a>;v ==u3_0am v2 class="string">&q href="drivers/macintosh/thsref">fail2/ a> css="string">"a> css"sref">NULL2/a>)vNULL2/a>)v(ispose_controlne" nam v2L1990">19902/a>}vENODEV2/a>;vs"1de=rackmac" class="sref">rackmac2/a>u3_0al_stat 2/a> ==u3_0am v2Lcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
s"19" idv2L1929"/*2/spa="v
s"1ose_backsid _*2/spa="vs"140">19402/a> gotou3_1al_stat 2/a> ==u3_1am v2 class="string">&q href="drivers/macintosh/thsref">fail2/ a> css="string">"a> css"sref">NULL2/a>)v
NULL2/a>)vs"98ass="line" nam v2L18stat " class="s href="drivers/macintosh/therm_pm72.c#L1990" idv2L199lostc= c1, ef">NU0" ass=ne" nam v2L1990">19902/a>}v 2a href=e9198>s"9L1853" class="line" nam v2L1853">185ef="+code=NULL" class="sref">NULL2/a>;v<">19902/a>}vFAN_CTRLER_ID2/a>, 2se9f">>s"9 nam v2L1923">19232/a> u3_1al_stat 2/a> ==u3_1am v2Lcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
s"93" idv2L1929"/*2/spa="v
ENODEV2/a>;v
E>s"9cintosh/therm_pm72.c#L1986" idv2u3_0al_stat 2/a> ==u3_0am v2L1986">19862/a>vfail2/> u3_1al_stat 2/a> ==u3_1am v2L1986">19862/a>v 2a href="e9987>s"9_pm72.c#L1977" idv2L1977" class="lin if (!2a href="tected a ci2.c#L1986" idv2 _ef">NUs="line" nam v2L1 _ef">NUs=2L20lass="comment">/*2/spa="v
s"919882/a>vs"9a href="drivers/macintosh/th href=               if (2a href="+code=critical_stat " class="sref">critical_stat 2/a> == 1) {vs"91991">19912/a>vs"91992">19922/a>2spa= class="comment">/*2/spa="vs"m_nt">/*2/spa="v
s"m2/spa="vs"m9942/a>2spa= class="comment"> */2/spa="vs"m19952/a>static void 2a href="+> clo#L199aa> ass=to lass="a href="hostc+code=dispose_ */2/spa="vs"m9962/a>{v19972/a> 2a hrefe9>19>s"m2a href="+code=NULL" class="sref">NULL2/a>, 2sps"m6" classe9ss="line" nam v2L1998">1e9ss=>s"m6u" class="s2a st/a> 2spa= class=" clom the ref">KERN_INFO2/a> clom the re2L200fcu2/a> = 2a hr" class="l_ref">KERN_INFO2/a" class="l_re2L20[] ci!\n"2/spa=");v1e9ss=>s"m9" idv2L1929" class="line" nam v2L192ntosh/therm_pm72.c#L1997" idv2L1997" class="line" 98" classe9bo/3e12ab42a href="+codle9bo/>s"m2a href="+code=init_processor_stat " cFss="om thef="+c,ref=rmaclasnageme36"/spclae=by s/a>2alntosh/therm_pm72.c#L1997" idv2L1997" class="line" 99" classe9 2a href="+code=jiffies"e9 2a>s"mt 2/a>[0], 0))v19871/a> nam v2L1860">18602/a>vers/macinsth/sppomac.2L/2/spa="v 2a hre" idv841/a> 1 if (2a12L1887">18872/a> ers/macinintosh/therm_pm72.c#L1997" idv2L1997" class="line" 1 2" classe12994" class="line" nam ve1299 10 nam v2L1923"{v2L1985" class="line" nam v2" class="l" nam v2L1990, 0 },/a>v/*2/spa="v 2a hrefe1219 102a href="+code=NULL" class="sref">NULL2/a>, 2sps1 6" classe12s="line" nam v2L1998">1e12s= 106u" class="sa> 2spa= class=" cloULL" f">KERN_INFO2/a> cloULL" 2L200fcu2/a> = 2a hr" class="l_oULL" f">KERN_INFO2/a" class="l_oULL" ed a ci!\n"2/spa=");v1e12s= 1 a href="driveN_INFO" class="soULL" f">KERN_INFO2/aoULL" ed a ci!\n"2/spa=");vv1911s1"li>s1"lintosh/thermN_INFO" class="s" classadapss= 2a hrefa classadapss=ed a ci2.c#L1986" idv2" class="l_lass="2L2000">20002/a" class="l_lass="a>;v,/a>vs1"L1853" class=N_INFO" class="s" o"c2L2000">20002/a" o"ca>;v/therm_pm7ci2.c#L1986" idv2" class="l_" o"c2L2000">20002/a" class="l_" o"ca>;v,/a>vs1"u_pumps_minmaN_INFO" class="sremovc2L2000">20002/aremovca>;vtherm_pm7ci2.c#L1986" idv2" class="l_removc2L2000">20002/a" class="l_removca>;v,/a>v20002/aef="ablc if (ci2.c#L1986" idv2" class="l_ref">KERN_INFO2/a" class="l_re2L20,/a>v19162/a> e1" n>s119962/}lass="comment">/*2/spa="vs112a href="+code=NULL" class="sref">NULL2/a>, 2sps1"6" classe1PID_TYPE_RACKMAC" class=e1PID>s116u" class="sef">fcu2/a> = 2a hrfan_check20002/afan_check20002/aa h5" idvef">fcu2/a> = 2a hrfan2L2000">20002/afanh/therm_pm72.c#L1987" idv2L1987" class="line" ns1"7" classe1 else if (2a href="+coe1 >s1"9" id!\n"2/spa=");vs1"8_pumps_minmachar0 vers/macintosh/thtss="string">"tss"sre[64]lass="comment">/*2/spa="v20002/ae2L20lass="comment">/*2/spa="v
v/*2/spa="v
) {v"a> lcpy"sref">NULL2/a>)v"tss"sre="drivers/macintofcu_fan2/a>;v = 2a hrfan2L2000">20002/afanh/th]N_INFO" class="sa h2L2000">20002/aa h5" idv64drivers/macintosh/therm_pm72.c#L1854" idv2L1s1T2" classe1.c#L1923" idv2L1923" clae1.c#>s12drivers/macintosh/therm_pm72.c#L1955" idv2L1955s1T3" classe1     } elsev198c2/a>           c5" i(ci2.c#L1986" idv2"ss="string">"tss"srerivers/macintosh/therm_pm72.c#L1854" idv2L1s1T4" classe12/a>;vs1T_pm72.c#L1977" idv2L1977" class="linc2L2000">20002/ae2L20 ci2.c#L1986" idv2  rch=        2a href  rch="sref">NULL2/a>)v           c5" idv2L1985" class="line" n#39;,n#39;v2L1990">19902/a>}vs1Tde=rackmac" class="sr_pm72.c#L1986" idv2c2L2000">20002/ae2L20erm_pm72.c#L1987" idv2L1987" class="line" ns1T7" classe1ivers/macintosh/therm_pme1ive>s1T " class="sref">slotsssssssssee, we don'tc2L2000">20002/ae2L20 ciclass="comment">/*2/spa="v19302/a>   e1nam>s1Ts/macintosh/therm_pm7_pm72.c#L1986" idv2   css="string">"a> css"sref">NULL2/a>)v20002/aa h5" idv">NULL2/a>)v           c5" i)2L190erm_pm72.c#L1987" idv2L1987" class="line" ns1T9" classe1stat " class="sref">proce1sta>s122a href="+code=start""""""""">2spa= 1lass="comment">/*2/spa="v                gs1931>s193e=rackmac" class="sr_pm72.c#L1986" idv2c2L2000">20002/ae2L202L1986">19862/a>vs19L1853" class="line" nnnnnnnnnbreaklass="comment">/*2/spa="v198c2/a>           c5" i(ci2.c#L1986" idv2c2L2000">20002/ae2L202+ 1lass="comment">/*2/spa="vs133" idv2L1929"/*2/spa="v
2spa= class="comment">/*2/spa="vs135nt">/*2/spa="vs137u" class="sref">fcu2/a> = 2a hrfcu_lookup_fan2/a>;v 2spa= class=om the cintNULL" class="sref the cintass="ee, we don'tfcu_cintNULL" class="srfcu_cinth/therm_pm72.c#L1987" idv2L1987" class="line" ns138" classe1imms_stat " class="sref"e1imm>s19" cla!\n"2/spa=");vs192a href="+coda> 2spa= class=om the cintNULL" class="sref the cintass="ee, we don'tns="string">"npam v2Lcode=fcu" class=am v2L2000">20002/a>2spa= class="comment">/*2/spa="v
s1loa href="+codef">fcu2/a> = 2a hri2L2000">20002/aea= class="comment">/*2/spa="v
s142/spa="vNU0"es" "thout="comment">/ in="cmash/ts. Wnesca2/a>(void)v/ andcorivrid= trose valuesls"th wloo/a>2"/s/a>(void)vs141 bus2/spa="v:v/...ne" nam v2L1990">19902/a>}vjiffss="sref">CPU_PID_TYPE_SPLIT2/a>;vs1si href="drivewhilc"(72.c#L1986" idv2ns="string">"npam v2Lcode=fcu" class=of_get_nextlasslef">KERN_INFO2/aof_get_nextlassle"sref">NULL2/a>)vNULL2/a>)v"npam v))2 class="string">&q href="drivers/macintosh/tht !\n"2/spa=");vs15"sref">schedule_timeouf">fcu2/a> = 2a hr"ypc2L2000">20002/a"ypcam v2Lc-1lass="comment">/*2/spa="v19542/a>ve1" n>s15rivers/macintosh/ther2a st/char0ee, we don'ta h2L2000">20002/aa h5" ilass="comment">/*2/spa="v19552/a> e1" n>s15e=MAX_CRITICAL_STATE"2a st/e, we don'tu          2/a> ==u32ass="ee, we don'tre iline" nam v2L1re 5" ilass="comment">/*2/spa="v/*2/spa="vNULL2/a>)v"npam v-ref=">NULL2/a>)vNULL2/a>)v"npam v-ref=">NULL2/a>)v20002/a"ypcam v">19902/a>}vs1519882/a>vs15 " class="sref">slots class="line" nam v2L1929Dref">ispose_co"ypcseintosh/therm_pm72.c#L1997" idv2L1997" class="line" 158" classe1m_pm72.c#L1960" idv2L196e1m_p>s15s/macintosh/therm_pm7_pm7                a> css="string">"a> css"sref">NULL2/a>)v"npam v-ref=">NULL2/a>)v20002/a"ypcam vdv2L1985" class="line" nam v2Lan-rpm-spose_c" nam v2L1990" ||herm_pm72.c#L1997" idv2L1997" class="line" 159" classe1a="vs152a href="+code=start"""""                a> css="string">"a> css"sref">NULL2/a>)v"npam v-ref=">NULL2/a>)v20002/a"ypcam vdv2L1985" class="line" nam v2Lan-rpmers/macintosh/therm_pm72.c#L1997" idv2L1997" class="line" 16="drivers1class="line" nam v2L1962s1cla>s163e=rackmac" class="sr" idv2L1977" class="lin"ypc2L2000">20002/a"ypcam v2Lc977" class="linss=_m_pmRPM2L2000">20002/ass=_m_pmRPM5" ilass="comment">/*2/spa="vs16"sref">schedule_timeout_i                a> css="string">"a> css"sref">NULL2/a>)v"npam v-ref=">NULL2/a>)v20002/a"ypcam vdv2L1985" class="line" nam v2Lan-pwm-spose_c" nam v2L1990" ||herm_pm72.c#L1997" idv2L1997" class="line" 1c2" classe1line" nam v2L1964">19642e1lin>s16rivers/macintosh/ther""""                a> css="string">"a> css"sref">NULL2/a>)v"npam v-ref=">NULL2/a>)v20002/a"ypcam vdv2L1985" class="line" nam v2Lan-pwmers/macintosh/therm_pm72.c#L1997" idv2L1997" class="line" 163" classe1s/macintosh/therm_pm72.ce1s/m>s16e=MAX_CRITICAL_STATE" class="977" class="lin"ypc2L2000">20002/a"ypcam v2Lc977" class="linss=_m_pmPWM2L2000">20002/ass=_m_pmPWM5" ilass="comment">/*2/spa="vs16lass="line" nam v2L18sclass="line" nam v2L1929Only cent"about=fan2l="conowseintosh/therm_pm72.c#L1997" idv2L1997" class="line" 165" classe1ss="sref">main_control_le1ss=>s1c_pm72.c#L1977" idv2L1_pm72.c#L1986" idv2"ypc2L2000">20002/a"ypcam v2LLc-1therm_pm72.c#L1997" idv2L1997" class="line" 166" classe1ing">"kfand"2/e1ing>s16de=rackmac" class="srrrrrrrrrsposinuelass="comment">/*2/spa="vs161 bus2/spa="vs16" class="sref">DBG2/a>class="line" nam v2L1929Lookupl="coa mat="= cla hash/tseintosh/therm_pm72.c#L1997" idv2L1997" class="line" 169" classe1971" class="line" nam v2e1971>s162a href="+code=start" ass="sref">feta h2L2000">20002/aa h5" i2Lcode=fcu" class=of_get_property="string">"of_get_property"sref">NULL2/a>)v"npam vdv2L1985" class="line" nam v2a hash/t" nam v2L1990dv">NULL2/a>)v/*2/spa="vs178ass="line" nam v2L18stat " class="sre iline" nam v2L1re 5" i2Lcode=fcu" class=of_get_property="string">"of_get_property"sref">NULL2/a>)v"npam vdv2L1985" class="line" nam v2re " nam v2L1990dv">NULL2/a>)v/*2/spa="vs17"sref">schedule_timeout_interruptibl 2/aa h2L2000">20002/aa h5" i2L1986">19862/a>v19862/a>v19742/ae1ne">s17am v2L1873">18732/a>        }sposinuelass="comment">/*2/spa="v                2a hree1a> >s17e=MAX_CRITICAL_STATE"977" class="lin href="drivers/macintosh/therm_pm72.c#L1990" idv2L199"mat="= cla hash/t: %s, re : 0x%08xne" nam v2L1990dv">NULL2/a>)v20002/aa h5" idvee, we don'tre iline" nam v2L1re 5" itlass="comment">/*2/spa="v/*2/spa="v20002/aea= c cicl>fcu2/a> = 2a hri2L2000">20002/aea= c <l>fcu2/a> = 2a hrss=_m_pmCOUNT2L2000">20002/ass=_m_pmCOUNT5" il>fcu2/a> = 2a hri2L2000">20002/aea= c++t !\n"2/spa=");vs11de=rackmac" class="srle_timeouf">fcu2/a> = 2a hrfan_ref">KERN_INFO2/afan_re5" ilass="comment">/*2/spa="vs171 bus2/spa="vs17s/macintosh/therm_pm72.c#L185ut_i                fan_check20002/afan_checkNULL2/a>)v20002/aa h5" idv">NULL2/a>)v20002/aea= c/therm_pm72.c#L1997" idv2L1997" class="line" 179" classe1 idv2L1981" class="line"e1 id>s172a href="+code=start"""""""""       }sposinuelass="comment">/*2/spa="vs198ass="line" nam v2L18L_STATE"977" class="lin href="drivers/macintosh/therm_pm72.c#L1990" idv2L199"a hash/tsmat="dvefdex: %dne" nam v2L1990dv">NULL2/a>)v20002/aea= c/lass="comment">/*2/spa="v        2a href=e1198>s19L1853" class="line" nL_STATE"977" class="linfcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="sref">KERN_INFO2/a> 2spa2Lc977" class="linss=_m_pmABSENT_ID2L2000">20002/ass=_m_pmABSENT_ID5" ilass="comment">/*2/spa="vFAN_CTRLER_ID2/a>, 2se1f">>s19 nam v2L1923">19232/a2.c#L185ut_i2.c#L1986" idv2"ypc2L2000">20002/a"ypcam v2 class="string">&qfcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="s"ypc2L2000">20002/a"ypcam v" !\n"2/spa=");vs18e=MAX_CRITICAL_STATE" class="L_STATE"977" class="linp90"tcal_stat 2/a> ==p90"tc=crit">NULL2/a>)vENODEV2/a>;vE>s18lass="line" nam v2L18_STATE" class="L_STATE"9L1985" class="line" nam v2 c="comment">/1="co%sne" nam v2L1990dv">NULL2/a>)v"npam v-ref=">NULL2/a>)v/*2/spa="v        2a href="e1987>s19_pm72.c#L1977" idv2L11111111111111111breaklass="comment">/*2/spa="vs18de=rackmac" class="srle_timeo/*2/spa="v
s18 " class="sref">slotsssssssss_pm72.c#L1986" idv2"ypc2L2000">20002/a"ypcam v2LLc977" class="linss=_m_pmRPM2L2000">20002/ass=_m_pmRPM5" itherm_pm72.c#L1997" idv2L1997" class="line" 188" classe1" idv2L1991" class="linee1" i>s18s/macintosh/therm_pm72.c#L1855555ATE"9cu2/a> = 2a hrfan_ref">KERN_INFO2/afan_re5" i2Lc((ee, we don'tre iline" nam v2L1re 5" it - 0x10) / 2lass="comment">/*2/spa="vs182a href="+code=start"""""""""926"ass="comment">/*2/spa="vs198ass="line" nam v2L18L_STATE"5555ATE"9cu2/a> = 2a hrfan_ref">KERN_INFO2/afan_re5" i2Lc((ee, we don'tre iline" nam v2L1re 5" it - 0x30) / 2lass="comment">/*2/spa="vs19L1853" class="line" nL_STATE"_pm72.c#L1986" idv2fan_ref">KERN_INFO2/afan_re5" i2ref= 7" !\n"2/spa=");vs19 nam v2L1923">19232/a2.c#L1855555ATE"9cu2/a> = 2a hrp90"tcal_stat 2/a> ==p90"tc=crit">NULL2/a>)vs19e=MAX_CRITICAL_STATE" class="L_STATE"555ATE"9L1985" class="line" nam v2Lan ID c="comment">/1="co%sne" nam v2L1990dv">NULL2/a>)v"npam v-ref=">NULL2/a>)v/*2/spa="vs19lass="line" nam v2L18_STATE" class="Lbreaklass="comment">/*2/spa="v19972/a> 2a hrefe1>19>s19_pm72.c#L1977" idv2L111111111/*2/spa="v1e1ss=>s19de=rackmac" class="srle_timeo977" class="lin href="drivers/macintosh/therm_pm72.c#L1990" idv2L199"Lan id -ref= %d, "ypc -ref= %dne" nam v2L1990dv">NULL2/a>)vKERN_INFO2/afan_re5" idv">NULL2/a>)v20002/a"ypcam v">19902/a>}v1e1ss=>s19 " class="sref">slotsssssssss977" class="linfcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="sref">KERN_INFO2/a> 2spa2Lc977" class="linfan_ref">KERN_INFO2/afan_re5" ilass="comment">/*2/spa="vs19ves_stat " cl}*2/spa="v198720_a hrass="comment">/*2/spa="v
        2a hre" idv842/a>  203" class="lineclass="line" nam v2L1929Now dumpltss=arra/2nintosh/therm_pm72.c#L1997" idv2L1997" class="line" 2 2" classe22994" class="line" nam ve2299  204" idv2L1894" class="line" np90"tcal_stat 2/a> ==p90"tc=crit">NULL2/a>)ved"Lan e=dispoa:ne" nam v2L1990">19902/a>}v20002/aea= c cicl>fcu2/a> = 2a hri2L2000">20002/aea= c <l>fcu2/a> = 2a hrss=_m_pmCOUNT2L2000">20002/ass=_m_pmCOUNT5" il>fcu2/a> = 2a hri2L2000">20002/aea= c++t !\n"2/spa=");v;v = 2a hri2L2000">20002/aea= c]N_INFO" class="sref">KERN_INFO2/a> 2spa2LLc977" class="linss=_m_pmABSENT_ID2L2000">20002/ass=_m_pmABSENT_ID5" itherm_pm72.c#L1997" idv2L1997" class="line" 2 5" classe2219972/a>        2a hrefe2219  20_pm72.c#L1977" idv2L111111111sposinuelass="comment">/*2/spa="v1e22s=  20de=rackmac" class="sref">rackmac2/a>p90"tcal_stat 2/a> ==p90"tc=crit">NULL2/a>)vNULL2/a>)v20002/aea= c,/a>v1e22s=  20 " class="sref">slotssssssssass="string">&qfcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="s"ypc2L2000">20002/a"ypcam v2LLc977" class="linss=_m_pmRPM2L2000">20002/ass=_m_pmRPM5" i ?_2L1985" class="line" nam v2RPM" nam v2L1990 :_2L1985" class="line" nam v2PWM" nam v2L1990,/a>v&qfcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="sref">KERN_INFO2/a> 2spa="drivers/macintofcu_fan2/a>;v = 2a hri2L2000">20002/aea= c]N_INFO" class="sa h2L2000">20002/aa h5" i">19902/a>}v1911s2"li>s21_nt">/*2/spa="v
s212/spa="vs2"u_pumlass="sef">fcu2/a> = 2a hrfcu_of_" o"c2L2000">20002/afcu_of_" o"c=crita> 2spa= class=plat="cm_"commeal_stat 2/a> ==plat="cm_"comme=cri* 2spa= class=om al_stat 2/a> ==om 5" itherm_pm72.c#L1997" idv2L1997" class="line" 213" classe2 href="drivers/macintoshe2 hr>s2" !\n"2/spa=");v19162/a> e2" n>s21lass="line" n 2spa= class= if (!2a href="tected a ci2.c#L1986" idv2 _ef">NUs="line" nam v2L1 _ef">NUs=2L20lass="comment">/*2/spa="v
s215ass="line" n   2spa= class=of_om al_stat 2/a> ==of_om ed a ci2.c#L1986" idv2om al_stat 2/a> ==om 5" ilass="comment">/*2/spa="v
s2119882/a>vNULL2/a>)v ==VERSION5" i">19902/a>}vs211991">19912/a>v/1nintosh/therm_pm72.c#L1997" idv2L1997" class="line" 22="drivers2T_ID2/a>vdispfcu_lookup_fan2/a>;v19902/a>}v) {vs224" idv2L1894" class="line" nam v2L1929Addlass"o="dri nintosh/therm_pm72.c#L1997" idv2L1997" class="line" 223" classe2     } elsev2spa= fcu2/a> = 2a hri claddloULL" f">KERN_INFO2/a> claddloULL" =critical_stat " class="s" class="l_oULL" f">KERN_INFO2/a" class="l_oULL" 5" i">19902/a>}v;vs222a href="+code=NULL" class="sref">NULL2/a>, 2sps226" classe2" class="line" nam v2L19e2" c>s226u" class="sef">fcu2/a> = 2a hrfcu_of_removc2L2000">20002/afcu_of_removc=crita>        2spa= class=plat="cm_"commeal_stat 2/a> ==plat="cm_"comme=cri*    2spa= class=om al_stat 2/a> ==om 5" itherm_pm72.c#L1997" idv2L1997" class="line" 2T7" classe2ivers/macintosh/therm_pme2ive>s229" id!\n"2/spa=");v19302/a>   e2nam>s22ose_backsid _stat " class="s> clomlloULL" f">KERN_INFO2/a> clomlloULL" =critical_stat " class="s" class="l_oULL" f">KERN_INFO2/a" class="l_oULL" 5" i">19902/a>}vproce2sta>s22ref">jiffss="sref">CPU_PID_TYPE_SPLIT2/a>;v2spa= class="comment">/*2/spa="vs29L1853/*2/spa="v
s233" idlass="s2a st/a> 2spa= class=of_om the ref">KERN_INFO2/aof_om the re=MAX_2cu2/a> = 2a hrfcu_mat="2L2000">20002/afcu_mat=""sre[] cirs/macintosh/therm_pm72.c#L1955" idv2L1955s234" classe2(&2a href="+code=proe2(&a>s23lass=!\n"2/spa=");vs235ass="line" n!\n"2/spa=");v20002/a"ypcam v22222222222=v2L1985" class="line" nam v2fcu" nam v2L1990,/a>vs239" idv2L1929"/,/a>vs23ose_backsid _{/,/a>vs292a hr}lass="comment">/*2/spa="vs2loa hr_INFO" class="sMODULE_DEVICE_TABLE2L2000">20002/aMODULE_DEVICE_TABLE"srefstat " class="soff">KERN_INFO2/aof2spa="drivers/macintofcu_mat="2L2000">20002/afcu_mat=""sre">19902/a>}vs242/spa="v 2spa= class=plat="cm_"ULL" f">KERN_INFO2/aplat="cm_"ULL" =MAX_2cu2/a> = 2a hrfcu_of_"lat="cm_"ULL" f">KERN_INFO2/afcu_of_"lat="cm_"ULL" ed a ci="vKERN_INFO2/a"ULL" ed a ci!\n"2/spa=");vvKERN_INFO2/aown" ed a ci2.c#L1986" idv2THIS_MODULEf">KERN_INFO2/aTHIS_MODULEa= c,/a>vs24 " class="sref">slotsN_INFO" class="sof_mat="="ablc2L2000">20002/aof_mat="="ablc2spa2Lc977" class="linfcu_mat="2L2000">20002/afcu_mat=""sre,/a>v:v20002/a" o"ca>;v/therm_pm7ci2.c#L1986" idv2fcu_of_" o"c2L2000">20002/afcu_of_" o"c=cri,/a>v20002/aremovca>;vtherm_pm7ci2.c#L1986" idv2fcu_of_removc2L2000">20002/afcu_of_removc=cri/a>vs25"sref}lass="comment">/*2/spa="v19542/a>ve2" n>s25drivers/macintosh/therm_pm72.c#L1955" idv2L1955s253" classe2" nam v2L1955">19552/a> e2" n>s2519952/a>static void 2a href92ntosh/therm_pm72.c#L1997" idv2L1997" class="line" 254" classe2vNU0"e "ypc, lass="a hr+code=dispose_ */2/spa="vs256u" class="sef">fcu2/a> = 2a hr__init2L2000">20002/a__init=MAX_2cu2/a> = 2a hr" class="l_init2L2000">20002/a" class="l_init"srefref"therm_pm72.c#L1997" idv2L1997" class="line" 2s7" classe2e control loops after eve2e c>s259" id!\n"2/spa=");vs25ose_backsid _stat " class="srack20002/arack20002/aof_maNU0"e_is_ 2pss=blc"srefsL1985" class="line" nam v2RackMac3,1" nam v2L1990">19902/a>}vjiffss="sref">CPU_PID_TYPE_SPLIT2/a>;vs263e=rackmac" cut_i of_maNU0"e_is_ 2pss=blc2L2000">20002/aof_maNU0"e_is_ 2pss=blc"srefsL1985" class="line" nam v2PowerMac7,l" nam v2L1990)sref">fail2jiffss="sref">CPU_PID_TYPE_SPLIT2/a>;vs26"sref">schedule_t of_maNU0"e_is_ 2pss=blc2L2000">20002/aof_maNU0"e_is_ 2pss=blc"srefsL1985" class="line" nam v2PowerMac7,3" nam v2L1990)sref">fail2jiffss="sref">CPU_PID_TYPE_SPLIT2/a>;v19642e2lin>s26rivers/macintosh/ rack20002/aracks26e=MAX_CRITICAL_STATE">2spa= - ENODEV2L2000">20002/aENODEV5" ilass="comment">/*2/spa="v
s269962/ass="comment">/*2/spa="vmain_control_le2ss=>s2c_pm72.c#L1977>2spa= fcu2/a> = 2a hr"lat="cm_"ULL" _regisss=        2a href"lat="cm_"ULL" _regisss==critical_stat " class="sfcu_of_"lat="cm_"ULL" f">KERN_INFO2/afcu_of_"lat="cm_"ULL" ed a">19902/a>}v"kfand"2/e2ing>s26de=ra/*2/spa="v
s261 bus2/spa="vs26" clalass="sref">fcu2/a> = 2a hr__exit2L2000">20002/a__exit=MAX_2cu2/a> = 2a hr" class="l_exit2L2000">20002/a" class="l_exit"srefref"therm_pm72.c#L1997" idv2L1997" class="line" 269" classe2971" class="line" nam v2e2971>s262a hr!\n"2/spa=");vs279es_stat " class="sref">disp"lat="cm_"ULL" _unregisss= 2a href"lat="cm_"ULL" _unregisss==critical_stat " class="sfcu_of_"lat="cm_"ULL" f">KERN_INFO2/afcu_of_"lat="cm_"ULL" ed a">19902/a>}vs27L1853/*2/spa="v19742/ae2ne">s27drivers/macintosh/therm_pm72.c#L1955" idv2L1955s213" classe2a> 2a hree2a> >s27e=MAXstat " class="smodule_init2L2000">20002/amodule_init"srefstat " class="s" class="l_init2L2000">20002/a" class="l_init"sre">19902/a>}v20002/amodule_exit"srefstat " class="s" class="l_exit2L2000">20002/a" class="l_exit"sre">19902/a>}vNULL2/a>, 2sps216" classe2m_pm72.c#L1979" idv2L197e2m_p>s21de=ra_INFO" class="sMODULE_AUTHOR2L2000">20002/aMODULE_AUTHOR"srefsL1985" class="line" nam v2Benjamin Herrenschmidt <lbenh@kernel.cras"= c.orgref=" nam v2L1990">19902/a>}vs271 bus_INFO" class="sMODULE_DESCRIPTIONal_stat 2/a> ==MODULE_DESCRIPTION"srefsL1985" class="line" nam v2D="dri ="coApple's PowerMac G59trtrmaclspose_c" nam v2L1990">19902/a>}vs27s/mac_INFO" class="sMODULE_LICENSE2L2000">20002/aMODULE_LICENSE"srefsL1985" class="line" nam v2GPL" nam v2L1990">19902/a>}vs27ref">jiffss="sref">CPU_PID_TYPE_SPLIT2/a>;vs298ass=
Tss=originaclLXR softwent"bylass"iffss="srhttp://source="cge.net/projects/lx= >LXR 2aunity2spa="this experia hracl>CPUh/tsbyliffss="srmailto:lx=@"liux.no">lx=@"liux.no5" iN
lx=."liux.no kindly hosted"by iffss="srhttp://www.redpill-"lipro.no">Redpill Llipro AS2spa="providri of Lliuxs2a sult= clandcopera h/ts ser thes since 1995.