linux/drivers/cpufreq/speedstep-ich.c
<<
on4w /spapio /formio a on4w href="../linux+v3.9.5/drivers/cpufreq/speedstep-ich.c">on4w img src="../.static/gfx/right.png" alt=">>">on /spapioon spap class="lxr_search">on4won4w input typluehidden" namluenavtarget" o value">on4w input typluetext" namluesearch" iduesearch">on4w buttptitypluesubmit">Searchon4w Prefso /a>on /spapio4w /divio4w form acon input typluehidden" namlueajax_lookup" idueajax_lookup" o value">o4w /formioo4w div class="headingbottpm">o div iduefile_contents"i
   1
/a>
spap class="comment">/*
/spapio   2
/a>
spap class="comment"> * (C) 2001  Dave Jones, Arjatio n de ven.
/spapio   3
/a>
spap class="comment"> * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
/spapio   4
/a>
spap class="comment"> *
/spapio   5
/a>
spap class="comment"> *  Licensed under the terms of the GNU GPL License versopti2.
/spapio   6
/a>
spap class="comment"> *  Based upptireverse engineered informa   7
/a>
spap class="comment"> *  for chipsets ICH2-M and ICH3-M.
/spapio   8
/a>
spap class="comment"> *
/spapio   9
/a>
spap class="comment"> *  Many thanks to Ducrot Bruno for finding and fixing the last
/spapio  .18.a>
spap class="comment"> *  "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler
/spapio  11
/a>
spap class="comment"> *  for extensive testing.
/spapio  12
/a>
spap class="comment"> *
/spapio  13
/a>
spap class="comment"> *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
/spapio  14
/a>
spap class="comment"> */
/spapio  15
/a>o  16
/a>o  17
/a>
spap class="comment">/*********************************************************************
/spapio  18
/a>
spap class="comment"> *                        SPEEDSTEP - DEFINITIONS                    *
/spapio  19
/a>
spap class="comment"> *********************************************************************/
/spapio  20
/a>o  21
/a>#include <linux/kernel.h
/a>>o  22
/a>#include <linux/module.h
/a>>o  23
/a>#include <linux/init.h
/a>>o  24
/a>#include <linux/cpufreq.h
/a>>o  25
/a>#include <linux/pci.h
/a>>o  26
/a>#include <linux/sched.h
/a>>o  27
/a>o  28
/a>#include <asm/cpu_device_id.h
/a>>o  29
/a>o  30
/a>#include "speedstep-lib.h
/a>"o  31
/a>o  32
/a>o  33
/a>
spap class="comment">/* speedstep_chipset:
/spapio  34
/a>
spap class="comment"> *   It is necessary to know which chipset is used. As accesses to
/spapio  35
/a>
spap class="comment"> * this device occur at various places in this module, we need a
/spapio  36
/a>
spap class="comment"> * static struct pci_dev * pointing to that device.
/spapio  37
/a>
spap class="comment"> */
/spapio  38
/a>static struct pci_dev
/a> *
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>;o  39
/a>o  40
/a>o  41
/a>
spap class="comment">/* speedstep_processor
/spapio  42
/a>
spap class="comment"> */
/spapio  43
/a>static enum speedstep_processor
/a> speedstep_processor
/a>;o  44
/a>o  45
/a>static u32
/a> pmbase
/a>;o  46
/a>o  47
/a>
spap class="comment">/*
/spapio  48
/a>
spap class="comment"> *   There are only two frequency states for each processor. V vals
/spapio  49
/a>
spap class="comment"> * are in kHz for the time being.
/spapio  518.a>
spap class="comment"> */
/spapio  51
/a>static struct cpufreq_frequency_table
/a> speedstep_freqs
/a>[] = {o  52
/a>        {SPEEDSTEP_HIGH
/a>,        0},o  53
/a>        {SPEEDSTEP_LOW
/a>,         0},o  54
/a>        {0,                     CPUFREQ_TABLE_END
/a>},o  55
/a>};o  56
/a>o  57
/a>o  58
/a>
spap class="comment">/**
/spapio  59
/a>
spap class="comment"> * speedstep_find_register - read the PMBASE address
/spapio  618.a>
spap class="comment"> *
/spapio  61
/a>
spap class="comment"> * Returns: -ENODEV if no register could be found
/spapio  62
/a>
spap class="comment"> */
/spapio  63
/a>static int speedstep_find_register
/a>(void)o  64
/a>{o  65
/a>        if (!
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>)o  66
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o  67
/a>o  68
/a>        
spap class="comment">/* get PMBASE */
/spapio  69
/a>        
a href="+code=pci_read_config_dword" class="sref">pci_read_config_dword
/a>(
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>, 0x40, &
a href="+code=pmbase" class="sref">pmbase
/a>);o  70
/a>        if (!(
a href="+code=pmbase" class="sref">pmbase
/a> & 0x01)) {o  71
/a>                
a href="+code=printk" class="sref">printk
/a>(
a href="+code=KERN_ERR" class="sref">KERN_ERR
/a> "speedstep-ich: could not find speedstep register\n"  72
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o  73
/a>        }o  74
/a>o  75
/a>        
a href="+code=pmbase" class="sref">pmbase
/a> &= 0xFFFFFFFE;o  76
/a>        if (!
a href="+code=pmbase" class="sref">pmbase
/a>) {o  77
/a>                
a href="+code=printk" class="sref">printk
/a>(
a href="+code=KERN_ERR" class="sref">KERN_ERR
/a> "speedstep-ich: could not find speedstep register\n"  78
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o  79
/a>        }o  80
/a>o  81
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"pmbase is 0x%x\n"pmbase
/a>);o  82
/a>        return 0;o  83
/a>}o  84
/a>o  85
/a>
spap class="comment">/**
/spapio  86
/a>
spap class="comment"> * speedstep_set_state - set the SpeedStep state
/spapio  87
/a>
spap class="comment"> * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
/spapio  88
/a>
spap class="comment"> *
/spapio  89
/a>
spap class="comment"> *   Tries to change the SpeedStep state.  Cap be called from
/spapio  918.a>
spap class="comment"> *   smp_call_func  91
/a>
spap class="comment"> */
/spapio  92
/a>static void speedstep_set_state
/a>(unsigned int state
/a>)o  93
/a>{o  94
/a>        
a href="+code=u8" class="sref">u8
/a> pm2_blk
/a>;o  95
/a>        
a href="+code=u8" class="sref">u8
/a> o val
/a>;o  96
/a>        unsigned long flags
/a>;o  97
/a>o  98
/a>        if (state
/a> > 0x1)o  99
/a>                return;o 100
/a>o 101
/a>        
spap class="comment">/* Disable IRQs */
/spapio 102
/a>        
a href="+code=local_irq_save" class="sref">local_irq_save
/a>(
a href="+code=flags" class="sref">flags
/a>);o 103
/a>o 104
/a>        
spap class="comment">/* read state */
/spapio 105
/a>        
a href="+code=o val" class="sref">o val
/a> = 
a href="+code=inb" class="sref">inb
/a>(
a href="+code=pmbase" class="sref">pmbase
/a> + 0x50);o 106
/a>o 107
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"read at pmbase 0x%x + 0x50 returned 0x%x\n"pmbase
/a>, 
a href="+code=o val" class="sref">o val
/a>);o 108
/a>o 109
/a>        
spap class="comment">/* write new state */
/spapio 110
/a>        
a href="+code=o val" class="sref">o val
/a> &= 0xFE;o 111
/a>        
a href="+code=o val" class="sref">o val
/a> |= 
a href="+code=state" class="sref">state
/a>;o 112
/a>o 113
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"writing 0x%x to pmbase 0x%x + 0x50\n"o val
/a>, 
a href="+code=pmbase" class="sref">pmbase
/a>);o 114
/a>o 115
/a>        
spap class="comment">/* Disable bus master arbitra 116
/a>        
a href="+code=pm2_blk" class="sref">pm2_blk
/a> = 
a href="+code=inb" class="sref">inb
/a>(
a href="+code=pmbase" class="sref">pmbase
/a> + 0x20);o 117
/a>        
a href="+code=pm2_blk" class="sref">pm2_blk
/a> |= 0x01;o 118
/a>        
a href="+code=outb" class="sref">outb
/a>(
a href="+code=pm2_blk" class="sref">pm2_blk
/a>, (pmbase
/a> + 0x20));o 119
/a>o 120
/a>        
spap class="comment">/* Actual transi 121
/a>        
a href="+code=outb" class="sref">outb
/a>(
a href="+code=o val" class="sref">o val
/a>, (
a href="+code=pmbase" class="sref">pmbase
/a> + 0x50));o 122
/a>o 123
/a>        
spap class="comment">/* Restore bus master arbitra 124
/a>        
a href="+code=pm2_blk" class="sref">pm2_blk
/a> &= 0xfe;o 125
/a>        
a href="+code=outb" class="sref">outb
/a>(
a href="+code=pm2_blk" class="sref">pm2_blk
/a>, (pmbase
/a> + 0x20));o 126
/a>o 127
/a>        
spap class="comment">/* check if transi 128
/a>        
a href="+code=o val" class="sref">o val
/a> = 
a href="+code=inb" class="sref">inb
/a>(
a href="+code=pmbase" class="sref">pmbase
/a> + 0x50);o 129
/a>o 130
/a>        
spap class="comment">/* Enable IRQs */
/spapio 131
/a>        
a href="+code=local_irq_restore" class="sref">local_irq_restore
/a>(
a href="+code=flags" class="sref">flags
/a>);o 132
/a>o 133
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"read at pmbase 0x%x + 0x50 returned 0x%x\n"pmbase
/a>, 
a href="+code=o val" class="sref">o val
/a>);o 134
/a>o 135
/a>        if (state
/a> == (o val
/a> & 0x1))o 136
/a>                
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"change to %u MHz succeeded\n" 137
/a>                        
a href="+code=speedstep_get_frequency" class="sref">speedstep_get_frequency
/a>(
a href="+code=speedstep_processor" class="sref">speedstep_processor
/a>) / 1000);o 138
/a>        elseo 139
/a>                
a href="+code=printk" class="sref">printk
/a>(
a href="+code=KERN_ERR" class="sref">KERN_ERR
/a> "cpufreq: change failed - I/O error\n" 140
/a>o 141
/a>        return;o 142
/a>}o 143
/a>o 144
/a>
spap class="comment">/* Wrapper for smp_call_func 145
/a>static void _speedstep_set_state
/a>(void *
a href="+code=_state" class="sref">_state
/a>)o 146
/a>{o 147
/a>        
a href="+code=speedstep_set_state" class="sref">speedstep_set_state
/a>(*(unsigned int *)
a href="+code=_state" class="sref">_state
/a>);o 148
/a>}o 149
/a>o 1518.a>
spap class="comment">/**
/spapio 151
/a>
spap class="comment"> * speedstep_ac 152
/a>
spap class="comment"> *
/spapio 153
/a>
spap class="comment"> *   Tries to ac 154
/a>
spap class="comment"> * Returns -EINVAL on ap unsupported chipset, and zero on success.
/spapio 155
/a>
spap class="comment"> */
/spapio 156
/a>static int speedstep_ac(void)o 157
/a>{o 158
/a>        
a href="+code=u16" class="sref">u16
/a> 
a href="+code=o val" class="sref">o val
/a> = 0;o 159
/a>o 160
/a>        if (!speedstep_chipset_dev
/a>)o 161
/a>                return -
a href="+code=EINVAL" class="sref">EINVAL
/a>;o 162
/a>o 163
/a>        
a href="+code=pci_read_config_word" class="sref">pci_read_config_word
/a>(
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>, 0x00A0, &
a href="+code=o val" class="sref">o val
/a>);o 164
/a>        if (!(o val
/a> & 0x08)) {o 165
/a>                
a href="+code=o val" class="sref">o val
/a> |= 0x08;o 166
/a>                
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"ac 167
/a>                
a href="+code=pci_write_config_word" class="sref">pci_write_config_word
/a>(
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>, 0x00A0, 
a href="+code=o val" class="sref">o val
/a>);o 168
/a>        }o 169
/a>o 170
/a>        return 0;o 171
/a>}o 172
/a>o 173
/a>o 174
/a>
spap class="comment">/**
/spapio 175
/a>
spap class="comment"> * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic
/spapio 176
/a>
spap class="comment"> *
/spapio 177
/a>
spap class="comment"> *   Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to
/spapio 178
/a>
spap class="comment"> * the LPC bridge / PM module which contains all power-management
/spapio 179
/a>
spap class="comment"> * func 1818.a>
spap class="comment"> * chipset, or zero on failure.
/spapio 181
/a>
spap class="comment"> */
/spapio 182
/a>static unsigned int speedstep_detect_chipset
/a>(void)o 183
/a>{o 184
/a>        
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a> = 
a href="+code=pci_get_subsys" class="sref">pci_get_subsys
/a>(
a href="+code=PCI_VENDOR_ID_INTEL" class="sref">PCI_VENDOR_ID_INTEL
/a>,o 185
/a>                              
a href="+code=PCI_DEVICE_ID_INTEL_82801DB_12" class="sref">PCI_DEVICE_ID_INTEL_82801DB_12
/a>,o 186
/a>                              
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>, 
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>,o 187
/a>                              
a href="+code=NULL" class="sref">NULL
/a>);o 188
/a>        if (speedstep_chipset_dev
/a>)o 189
/a>                return 4; 
spap class="comment">/* 4-M */
/spapio 190
/a>o 191
/a>        
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a> = 
a href="+code=pci_get_subsys" class="sref">pci_get_subsys
/a>(
a href="+code=PCI_VENDOR_ID_INTEL" class="sref">PCI_VENDOR_ID_INTEL
/a>,o 192
/a>                              
a href="+code=PCI_DEVICE_ID_INTEL_82801CA_12" class="sref">PCI_DEVICE_ID_INTEL_82801CA_12
/a>,o 193
/a>                              
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>, 
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>,o 194
/a>                              
a href="+code=NULL" class="sref">NULL
/a>);o 195
/a>        if (speedstep_chipset_dev
/a>)o 196
/a>                return 3; 
spap class="comment">/* 3-M */
/spapio 197
/a>o 198
/a>o 199
/a>        
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a> = 
a href="+code=pci_get_subsys" class="sref">pci_get_subsys
/a>(
a href="+code=PCI_VENDOR_ID_INTEL" class="sref">PCI_VENDOR_ID_INTEL
/a>,o 200
/a>                              
a href="+code=PCI_DEVICE_ID_INTEL_82801BA_10" class="sref">PCI_DEVICE_ID_INTEL_82801BA_10
/a>,o 201
/a>                              
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>, 
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>,o 202
/a>                              
a href="+code=NULL" class="sref">NULL
/a>);o 203
/a>        if (speedstep_chipset_dev
/a>) {o 204
/a>                
spap class="comment">/* speedstep.c causes lockups on Dell Inspirons 8000 and
/spapio 205
/a>
spap class="comment">                 * 8100 which use a pretty old revis/op of the 82815
/spapio 206
/a>
spap class="comment">                 * host bridge. Abort on these systems.
/spapio 207
/a>
spap class="comment">                 */
/spapio 208
/a>                static struct pci_dev
/a> *
a href="+code=hostbridge" class="sref">hostbridge
/a>;o 209
/a>o 210
/a>                
a href="+code=hostbridge" class="sref">hostbridge
/a>  = 
a href="+code=pci_get_subsys" class="sref">pci_get_subsys
/a>(
a href="+code=PCI_VENDOR_ID_INTEL" class="sref">PCI_VENDOR_ID_INTEL
/a>,o 211
/a>                              
a href="+code=PCI_DEVICE_ID_INTEL_82815_MC" class="sref">PCI_DEVICE_ID_INTEL_82815_MC
/a>,o 212
/a>                              
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>, 
a href="+code=PCI_ANY_ID" class="sref">PCI_ANY_ID
/a>,o 213
/a>                              
a href="+code=NULL" class="sref">NULL
/a>);o 214
/a>o 215
/a>                if (!hostbridge
/a>)o 216
/a>                        return 2; 
spap class="comment">/* 2-M */
/spapio 217
/a>o 218
/a>                if (hostbridge
/a>->revis/op
/a> < 5) {o 219
/a>                        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"hostbridge does not support speedstep\n" 220
/a>                        
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a> = 
a href="+code=NULL" class="sref">NULL
/a>;o 221
/a>                        pci_dev_put
/a>(
a href="+code=hostbridge" class="sref">hostbridge
/a>);o 222
/a>                        return 0;o 223
/a>                }o 224
/a>o 225
/a>                
a href="+code=pci_dev_put" class="sref">pci_dev_put
/a>(
a href="+code=hostbridge" class="sref">hostbridge
/a>);o 226
/a>                return 2; 
spap class="comment">/* 2-M */
/spapio 227
/a>        }o 228
/a>o 229
/a>        return 0;o 230
/a>}o 231
/a>o 232
/a>static void get_freq_data
/a>(void *
a href="+code=_speed" class="sref">_speed
/a>)o 233
/a>{o 234
/a>        unsigned int *
a href="+code=speed" class="sref">speed
/a> = 
a href="+code=_speed" class="sref">_speed
/a>;o 235
/a>o 236
/a>        *
a href="+code=speed" class="sref">speed
/a> = 
a href="+code=speedstep_get_frequency" class="sref">speedstep_get_frequency
/a>(
a href="+code=speedstep_processor" class="sref">speedstep_processor
/a>);o 237
/a>}o 238
/a>o 239
/a>static unsigned int speedstep_get
/a>(unsigned int cpu
/a>)o 240
/a>{o 241
/a>        unsigned int speed
/a>;o 242
/a>o 243
/a>        
spap class="comment">/* You're supposed to ensure CPU is online. */
/spapio 244
/a>        if (smp_call_func(
a href="+code=cpu" class="sref">cpu
/a>, 
a href="+code=get_freq_data" class="sref">get_freq_data
/a>, &
a href="+code=speed" class="sref">speed
/a>, 1) != 0)o 245
/a>                
a href="+code=BUG" class="sref">BUG
/a>();o 246
/a>o 247
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"detected %u kHz as current frequency\n"speed
/a>);o 248
/a>        return speed
/a>;o 249
/a>}o 250
/a>o 251
/a>
spap class="comment">/**
/spapio 252
/a>
spap class="comment"> * speedstep_target - set a new CPUFreq policy
/spapio 253
/a>
spap class="comment"> * @policy: new policy
/spapio 254
/a>
spap class="comment"> * @target_freq: the target frequency
/spapio 255
/a>
spap class="comment"> * @rela 256
/a>
spap class="comment"> *      (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
/spapio 257
/a>
spap class="comment"> *
/spapio 258
/a>
spap class="comment"> * Sets a new CPUFreq policy.
/spapio 259
/a>
spap class="comment"> */
/spapio 260
/a>static int speedstep_target
/a>(struct cpufreq_policy
/a> *
a href="+code=policy" class="sref">policy
/a>,o 261
/a>                             unsigned int target_freq
/a>,o 262
/a>                             unsigned int rela)o 263
/a>{o 264
/a>        unsigned int newstate
/a> = 0, 
a href="+code=policy_cpu" class="sref">policy_cpu
/a>;o 265
/a>        struct cpufreq_freqs
/a> freqs
/a>;o 266
/a>        int i
/a>;o 267
/a>o 268
/a>        if (cpufreq_frequency_table_target
/a>(
a href="+code=policy" class="sref">policy
/a>, &
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[0],o 269
/a>                                
a href="+code=target_freq" class="sref">target_freq
/a>, rela, &
a href="+code=newstate" class="sref">newstate
/a>))o 270
/a>                return -
a href="+code=EINVAL" class="sref">EINVAL
/a>;o 271
/a>o 272
/a>        
a href="+code=policy_cpu" class="sref">policy_cpu
/a> = 
a href="+code=cpumask_any_and" class="sref">cpumask_any_and
/a>(
a href="+code=policy" class="sref">policy
/a>->cpus
/a>, cpu_online_mask
/a>);o 273
/a>        
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=old" class="sref">old
/a> = 
a href="+code=speedstep_get" class="sref">speedstep_get
/a>(
a href="+code=policy_cpu" class="sref">policy_cpu
/a>);o 274
/a>        
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=new" class="sref">new
/a> = 
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[
a href="+code=newstate" class="sref">newstate
/a>].
a href="+code=frequency" class="sref">frequency
/a>;o 275
/a>        
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=cpu" class="sref">cpu
/a> = 
a href="+code=policy" class="sref">policy
/a>->cpu
/a>;o 276
/a>o 277
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"transifreqs
/a>.
a href="+code=old" class="sref">old
/a>, 
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=new" class="sref">new
/a>);o 278
/a>o 279
/a>        
spap class="comment">/* no transi 280
/a>        if (
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=old" class="sref">old
/a> == 
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=new" class="sref">new
/a>)o 281
/a>                return 0;o 282
/a>o 283
/a>        
a href="+code=for_each_cpu" class="sref">for_each_cpu
/a>(
a href="+code=i" class="sref">i
/a>, 
a href="+code=policy" class="sref">policy
/a>->cpus
/a>) {o 284
/a>                
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=cpu" class="sref">cpu
/a> = 
a href="+code=i" class="sref">i
/a>;o 285
/a>                cpufreq_notify_transi(&
a href="+code=freqs" class="sref">freqs
/a>, 
a href="+code=CPUFREQ_PRECHANGE" class="sref">CPUFREQ_PRECHANGE
/a>);o 286
/a>        }o 287
/a>o 288
/a>        
a href="+code=smp_call_funcsmp_call_func(
a href="+code=policy_cpu" class="sref">policy_cpu
/a>, 
a href="+code=_speedstep_set_state" class="sref">_speedstep_set_state
/a>, &
a href="+code=newstate" class="sref">newstate
/a>,o 289
/a>                                 
a href="+code=tral" class="sref">tral
/a>);o 290
/a>o 291
/a>        
a href="+code=for_each_cpu" class="sref">for_each_cpu
/a>(
a href="+code=i" class="sref">i
/a>, 
a href="+code=policy" class="sref">policy
/a>->cpus
/a>) {o 292
/a>                
a href="+code=freqs" class="sref">freqs
/a>.
a href="+code=cpu" class="sref">cpu
/a> = 
a href="+code=i" class="sref">i
/a>;o 293
/a>                cpufreq_notify_transi(&
a href="+code=freqs" class="sref">freqs
/a>, 
a href="+code=CPUFREQ_POSTCHANGE" class="sref">CPUFREQ_POSTCHANGE
/a>);o 294
/a>        }o 295
/a>o 296
/a>        return 0;o 297
/a>}o 298
/a>o 299
/a>o 3018.a>
spap class="comment">/**
/spapio 301
/a>
spap class="comment"> * speedstep_verify - verifies a new CPUFreq policy
/spapio 302
/a>
spap class="comment"> * @policy: new policy
/spapio 303
/a>
spap class="comment"> *
/spapio 304
/a>
spap class="comment"> * Limit must be within speedstep_low_freq and speedstep_high_freq, with
/spapio 305
/a>
spap class="comment"> * at least one border included.
/spapio 306
/a>
spap class="comment"> */
/spapio 307
/a>static int speedstep_verify
/a>(struct cpufreq_policy
/a> *
a href="+code=policy" class="sref">policy
/a>)o 308
/a>{o 309
/a>        return cpufreq_frequency_table_verify
/a>(
a href="+code=policy" class="sref">policy
/a>, &
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[0]);o 310
/a>}o 311
/a>o 312
/a>struct get_freqs
/a> {o 313
/a>        struct cpufreq_policy
/a> *
a href="+code=policy" class="sref">policy
/a>;o 314
/a>        int ret
/a>;o 315
/a>};o 316
/a>o 317
/a>static void get_freqs_on_cpu
/a>(void *
a href="+code=_get_freqs" class="sref">_get_freqs
/a>)o 318
/a>{o 319
/a>        struct get_freqs
/a> *
a href="+code=get_freqs" class="sref">get_freqs
/a> = 
a href="+code=_get_freqs" class="sref">_get_freqs
/a>;o 320
/a>o 321
/a>        
a href="+code=get_freqs" class="sref">get_freqs
/a>->ret
/a> =o 322
/a>                
a href="+code=speedstep_get_freqs" class="sref">speedstep_get_freqs
/a>(
a href="+code=speedstep_processor" class="sref">speedstep_processor
/a>,o 323
/a>                            &
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[
a href="+code=SPEEDSTEP_LOW" class="sref">SPEEDSTEP_LOW
/a>].
a href="+code=frequency" class="sref">frequency
/a>,o 324
/a>                            &
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[
a href="+code=SPEEDSTEP_HIGH" class="sref">SPEEDSTEP_HIGH
/a>].
a href="+code=frequency" class="sref">frequency
/a>,o 325
/a>                            &
a href="+code=get_freqs" class="sref">get_freqs
/a>->policy
/a>->cpuinfo
/a>.
a href="+code=transitransi,o 326
/a>                            &
a href="+code=speedstep_set_state" class="sref">speedstep_set_state
/a>);o 327
/a>}o 328
/a>o 329
/a>static int speedstep_cpu_init
/a>(struct cpufreq_policy
/a> *
a href="+code=policy" class="sref">policy
/a>)o 330
/a>{o 331
/a>        int result
/a>;o 332
/a>        unsigned int policy_cpu
/a>, 
a href="+code=speed" class="sref">speed
/a>;o 333
/a>        struct get_freqs
/a> gf
/a>;o 334
/a>o 335
/a>        
spap class="comment">/* only run on CPU to be set, or on its sibl/ng */
/spapio 336
/a>#ifdef 
a href="+code=CONFIG_SMP" class="sref">CONFIG_SMP
/a>o 337
/a>        
a href="+code=cpumask_copy" class="sref">cpumask_copy
/a>(
a href="+code=policy" class="sref">policy
/a>->cpus
/a>, cpu_sibl/ng_mask
/a>(
a href="+code=policy" class="sref">policy
/a>->cpu
/a>));o 338
/a>#endifo 339
/a>        
a href="+code=policy_cpu" class="sref">policy_cpu
/a> = 
a href="+code=cpumask_any_and" class="sref">cpumask_any_and
/a>(
a href="+code=policy" class="sref">policy
/a>->cpus
/a>, cpu_online_mask
/a>);o 340
/a>o 341
/a>        
spap class="comment">/* detect low and high frequency and transi 342
/a>        
a href="+code=gf" class="sref">gf
/a>.
a href="+code=policy" class="sref">policy
/a> = 
a href="+code=policy" class="sref">policy
/a>;o 343
/a>        
a href="+code=smp_call_funcsmp_call_func(
a href="+code=policy_cpu" class="sref">policy_cpu
/a>, 
a href="+code=get_freqs_on_cpu" class="sref">get_freqs_on_cpu
/a>, &
a href="+code=gf" class="sref">gf
/a>, 1);o 344
/a>        if (gf
/a>.
a href="+code=ret" class="sref">ret
/a>)o 345
/a>                return gf
/a>.
a href="+code=ret" class="sref">ret
/a>;o 346
/a>o 347
/a>        
spap class="comment">/* get current speed sett/ng */
/spapio 348
/a>        
a href="+code=speed" class="sref">speed
/a> = 
a href="+code=speedstep_get" class="sref">speedstep_get
/a>(
a href="+code=policy_cpu" class="sref">policy_cpu
/a>);o 349
/a>        if (!speed
/a>)o 350
/a>                return -
a href="+code=EIO" class="sref">EIO
/a>;o 351
/a>o 352
/a>        
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"currently at %s speed sett/ng - %i MHz\n" 353
/a>                (
a href="+code=speed" class="sref">speed
/a> == 
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>[
a href="+code=SPEEDSTEP_LOW" class="sref">SPEEDSTEP_LOW
/a>].
a href="+code=frequency" class="sref">frequency
/a>)o 354
/a>                ? 
spap class="string">"low""high" 355
/a>                (
a href="+code=speed" class="sref">speed
/a> / 1000));o 356
/a>o 357
/a>        
spap class="comment">/* cpuinfo and default policy values */
/spapio 358
/a>        
a href="+code=policy" class="sref">policy
/a>->cur
/a> = 
a href="+code=speed" class="sref">speed
/a>;o 359
/a>o 360
/a>        
a href="+code=result" class="sref">result
/a> = 
a href="+code=cpufreq_frequency_table_cpuinfo" class="sref">cpufreq_frequency_table_cpuinfo
/a>(
a href="+code=policy" class="sref">policy
/a>, 
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>);o 361
/a>        if (result
/a>)o 362
/a>                return result
/a>;o 363
/a>o 364
/a>        
a href="+code=cpufreq_frequency_table_get_attr" class="sref">cpufreq_frequency_table_get_attr
/a>(
a href="+code=speedstep_freqs" class="sref">speedstep_freqs
/a>, 
a href="+code=policy" class="sref">policy
/a>->cpu
/a>);o 365
/a>o 366
/a>        return 0;o 367
/a>}o 368
/a>o 369
/a>o 370
/a>static int speedstep_cpu_exit
/a>(struct cpufreq_policy
/a> *
a href="+code=policy" class="sref">policy
/a>)o 371
/a>{o 372
/a>        
a href="+code=cpufreq_frequency_table_put_attr" class="sref">cpufreq_frequency_table_put_attr
/a>(
a href="+code=policy" class="sref">policy
/a>->cpu
/a>);o 373
/a>        return 0;o 374
/a>}o 375
/a>o 376
/a>static struct freq_attr
/a> *
a href="+code=speedstep_attr" class="sref">speedstep_attr
/a>[] = {o 377
/a>        &
a href="+code=cpufreq_freq_attr_scal/ng_available_freqs" class="sref">cpufreq_freq_attr_scal/ng_available_freqs
/a>,o 378
/a>        
a href="+code=NULL" class="sref">NULL
/a>,o 379
/a>};o 380
/a>o 381
/a>o 382
/a>static struct cpufreq_driver
/a> speedstep_driver
/a> = {o 383
/a>        .
a href="+code=naml" class="sref">naml
/a>   = 
spap class="string">"speedstep-ich" 384
/a>        .
a href="+code=verify" class="sref">verify
/a> = 
a href="+code=speedstep_verify" class="sref">speedstep_verify
/a>,o 385
/a>        .
a href="+code=target" class="sref">target
/a> = 
a href="+code=speedstep_target" class="sref">speedstep_target
/a>,o 386
/a>        .
a href="+code=init" class="sref">init
/a>   = 
a href="+code=speedstep_cpu_init" class="sref">speedstep_cpu_init
/a>,o 387
/a>        .
a href="+code=exit" class="sref">exit
/a>   = 
a href="+code=speedstep_cpu_exit" class="sref">speedstep_cpu_exit
/a>,o 388
/a>        .
a href="+code=get" class="sref">get
/a>    = 
a href="+code=speedstep_get" class="sref">speedstep_get
/a>,o 389
/a>        .
a href="+code=owner" class="sref">owner
/a>  = 
a href="+code=THIS_MODULE" class="sref">THIS_MODULE
/a>,o 390
/a>        .
a href="+code=attr" class="sref">attr
/a>   = 
a href="+code=speedstep_attr" class="sref">speedstep_attr
/a>,o 391
/a>};o 392
/a>o 393
/a>static const struct x86_cpu_id
/a> ss_smi_ids
/a>[] = {o 394
/a>        { X86_VENDOR_INTEL
/a>, 6, 0xb, },o 395
/a>        { X86_VENDOR_INTEL
/a>, 6, 0x8, },o 396
/a>        { X86_VENDOR_INTEL
/a>, 15, 2 },o 397
/a>        {}o 398
/a>};o 399
/a>#if 0o 4018.a>
spap class="comment">/* Autoload or not? Do not for now. */
/spapio 401
/a>
a href="+code=MODULE_DEVICE_TABLE" class="sref">MODULE_DEVICE_TABLE
/a>(
a href="+code=x86cpu" class="sref">x86cpu
/a>, 
a href="+code=ss_smi_ids" class="sref">ss_smi_ids
/a>);o 402
/a>#endifo 403
/a>o 404
/a>
spap class="comment">/**
/spapio 405
/a>
spap class="comment"> * speedstep_init - initializes the SpeedStep CPUFreq driver
/spapio 406
/a>
spap class="comment"> *
/spapio 407
/a>
spap class="comment"> *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
/spapio 408
/a>
spap class="comment"> * devices, -EINVAL on problems during initiatiza 409
/a>
spap class="comment"> * success.
/spapio 4118.a>
spap class="comment"> */
/spapio 411
/a>static int __init
/a> 
a href="+code=speedstep_init" class="sref">speedstep_init
/a>(void)o 412
/a>{o 413
/a>        if (!x86_match_cpu
/a>(
a href="+code=ss_smi_ids" class="sref">ss_smi_ids
/a>))o 414
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o 415
/a>o 416
/a>        
spap class="comment">/* detect processor */
/spapio 417
/a>        
a href="+code=speedstep_processor" class="sref">speedstep_processor
/a> = 
a href="+code=speedstep_detect_processor" class="sref">speedstep_detect_processor
/a>();o 418
/a>        if (!speedstep_processor
/a>) {o 419
/a>                
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"Intel(R) SpeedStep(TM) capable processor " 420
/a>                                
spap class="string">"not found\n" 421
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o 422
/a>        }o 423
/a>o 424
/a>        
spap class="comment">/* detect chipset */
/spapio 425
/a>        if (!speedstep_detect_chipset
/a>()) {o 426
/a>                
a href="+code=pr_debug" class="sref">pr_debug
/a>(
spap class="string">"Intel(R) SpeedStep(TM) for this chipset not " 427
/a>                                
spap class="string">"(yet) available.\n" 428
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o 429
/a>        }o 430
/a>o 431
/a>        
spap class="comment">/* activate speedstep support */
/spapio 432
/a>        if (speedstep_activate
/a>()) {o 433
/a>                
a href="+code=pci_dev_put" class="sref">pci_dev_put
/a>(
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>);o 434
/a>                return -
a href="+code=EINVAL" class="sref">EINVAL
/a>;o 435
/a>        }o 436
/a>o 437
/a>        if (speedstep_find_register
/a>())o 438
/a>                return -
a href="+code=ENODEV" class="sref">ENODEV
/a>;o 439
/a>o 440
/a>        return cpufreq_register_driver
/a>(&
a href="+code=speedstep_driver" class="sref">speedstep_driver
/a>);o 441
/a>}o 442
/a>o 443
/a>o 444
/a>
spap class="comment">/**
/spapio 445
/a>
spap class="comment"> * speedstep_exit - unregisters SpeedStep support
/spapio 446
/a>
spap class="comment"> *
/spapio 447
/a>
spap class="comment"> *   Unregisters SpeedStep support.
/spapio 448
/a>
spap class="comment"> */
/spapio 449
/a>static void __exit
/a> 
a href="+code=speedstep_exit" class="sref">speedstep_exit
/a>(void)o 450
/a>{o 451
/a>        
a href="+code=pci_dev_put" class="sref">pci_dev_put
/a>(
a href="+code=speedstep_chipset_dev" class="sref">speedstep_chipset_dev
/a>);o 452
/a>        
a href="+code=cpufreq_unregister_driver" class="sref">cpufreq_unregister_driver
/a>(&
a href="+code=speedstep_driver" class="sref">speedstep_driver
/a>);o 453
/a>}o 454
/a>o 455
/a>o 456
/a>
a href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHOR
/a>(
spap class="string">"Dave Jones <davej@redhat.com>, " 457
/a>                
spap class="string">"Dominik Brodowski <linux@brodo.de>" 458
/a>
a href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTION
/a>(
spap class="string">"Speedstep driver for Intel mobile processors on chipsets " 459
/a>                
spap class="string">"with ICH-M southbridges." 460
/a>
a href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE
/a>(
spap class="string">"GPL" 461
/a>o 462
/a>
a href="+code=module_init" class="sref">module_init
/a>(
a href="+code=speedstep_init" class="sref">speedstep_init
/a>);o 463
/a>
a href="+code=module_exit" class="sref">module_exit
/a>(
a href="+code=speedstep_exit" class="sref">speedstep_exit
/a>);o 464
/a>
lxr.linux.no kindly hosted by Redpill Linpro AS /a>, provider of Linux consult/ng and opera