--- /tmp/linux-2.6.22.3/drivers/hwmon/coretemp.c 2007-08-15 12:25:39.000000000 -0400 +++ drivers/hwmon/coretemp.c 2007-08-21 20:50:38.000000000 -0400 @@ -36,6 +36,71 @@ #include #include +/* + Following part ripped from the msr.c. It should be merged with generic MSR + infrastructure (once ready) +*/ + +static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) +{ + int err; + + err = rdmsr_safe(reg, eax, edx); + if (err) + err = -EIO; + return err; +} + +#ifdef CONFIG_SMP + +struct msr_command { + int cpu; + int err; + u32 reg; + u32 data[2]; +}; + +static void msr_smp_rdmsr(void *cmd_block) +{ + struct msr_command *cmd = (struct msr_command *)cmd_block; + + if (cmd->cpu == smp_processor_id()) + cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); +} + +static inline int msr_read(int cpu, u32 reg, u32 * eax, u32 * edx) +{ + struct msr_command cmd; + int ret; + + preempt_disable(); + if (cpu == smp_processor_id()) { + ret = rdmsr_eio(reg, eax, edx); + } else { + cmd.cpu = cpu; + cmd.reg = reg; + + smp_call_function(msr_smp_rdmsr, &cmd, 1, 1); + + *eax = cmd.data[0]; + *edx = cmd.data[1]; + + ret = cmd.err; + } + preempt_enable(); + return ret; +} + +#else /* ! CONFIG_SMP */ + +static inline int msr_read(int cpu, u32 reg, u32 *eax, u32 *edx) +{ + return rdmsr_eio(reg, eax, edx); +} + +#endif /* ! CONFIG_SMP */ + + #define DRVNAME "coretemp" typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; @@ -132,7 +197,7 @@ u32 eax, edx; data->valid = 0; - rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); + msr_read(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); data->alarm = (eax >> 5) & 1; /* update only if data has been valid */ if (eax & 0x80000000) { @@ -169,7 +234,7 @@ data->tjmax = 100000; /* test if we can access the THERM_STATUS MSR */ - err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); + err = msr_read(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); if (err) { dev_err(&pdev->dev, "Unable to access THERM_STATUS MSR, giving up\n"); @@ -183,7 +248,7 @@ if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) { /* check for microcode update */ - rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx); + msr_read(data->id, MSR_IA32_UCODE_REV, &eax, &edx); if (edx < 0x39) { err = -ENODEV; dev_err(&pdev->dev, @@ -200,7 +265,7 @@ if (((c->x86_model == 0xf) && (c->x86_mask > 3)) || (c->x86_model == 0xe)) { - err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx); + err = msr_read(data->id, 0xee, &eax, &edx); if (err) { dev_warn(&pdev->dev, "Unable to access MSR 0xEE, Tjmax left at %d " @@ -216,7 +281,7 @@ bit 50 of MSR_IA32_PLATFORM_ID should be 0. */ - rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx); + msr_read(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx); if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) { dev_warn(&pdev->dev, "Using undocumented features, absolute " @@ -339,11 +404,9 @@ switch (action) { case CPU_ONLINE: - case CPU_ONLINE_FROZEN: coretemp_device_add(cpu); break; case CPU_DEAD: - case CPU_DEAD_FROZEN: coretemp_device_remove(cpu); break; }