Loading arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +65 −40 Original line number Original line Diff line number Diff line Loading @@ -79,8 +79,9 @@ #include <linux/smp.h> #include <linux/smp.h> #include <linux/cpufreq.h> #include <linux/cpufreq.h> #include <linux/pci.h> #include <linux/pci.h> #include <linux/errno.h> #include <asm/processor-cyrix.h> #include <asm/processor-cyrix.h> #include <asm/errno.h> /* PCI config registers, all at F0 */ /* PCI config registers, all at F0 */ #define PCI_PMER1 0x80 /* power management enable register 1 */ #define PCI_PMER1 0x80 /* power management enable register 1 */ Loading Loading @@ -122,7 +123,7 @@ static struct gxfreq_params *gx_params; static int stock_freq; static int stock_freq; /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ static int pci_busclk = 0; static int pci_busclk; module_param(pci_busclk, int, 0444); module_param(pci_busclk, int, 0444); /* maximum duration for which the cpu may be suspended /* maximum duration for which the cpu may be suspended Loading @@ -140,7 +141,8 @@ module_param (max_duration, int, 0444); #define POLICY_MIN_DIV 20 #define POLICY_MIN_DIV 20 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ "gx-suspmod", msg) /** /** * we can detect a core multipiler from dir0_lsb * we can detect a core multipiler from dir0_lsb Loading @@ -166,12 +168,20 @@ static int gx_freq_mult[16] = { * Low Level chipset interface * * Low Level chipset interface * ****************************************************************/ ****************************************************************/ static struct pci_device_id gx_chipset_tbl[] __initdata = { static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, { 0, }, { 0, }, }; }; static void gx_write_byte(int reg, int value) { pci_write_config_byte(gx_params->cs55x0, reg, value); } /** /** * gx_detect_chipset: * gx_detect_chipset: * * Loading Loading @@ -200,7 +210,8 @@ static __init struct pci_dev *gx_detect_chipset(void) /** /** * gx_get_cpuspeed: * gx_get_cpuspeed: * * * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi * Geode CPU runs. */ */ static unsigned int gx_get_cpuspeed(unsigned int cpu) static unsigned int gx_get_cpuspeed(unsigned int cpu) { { Loading @@ -217,7 +228,8 @@ static unsigned int gx_get_cpuspeed(unsigned int cpu) * * **/ **/ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) { { unsigned int i; unsigned int i; u8 tmp_on, tmp_off; u8 tmp_on, tmp_off; Loading Loading @@ -259,25 +271,33 @@ static void gx_set_cpuspeed(unsigned int khz) freqs.cpu = 0; freqs.cpu = 0; freqs.old = gx_get_cpuspeed(0); freqs.old = gx_get_cpuspeed(0); new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); freqs.new = new_khz; freqs.new = new_khz; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); local_irq_save(flags); local_irq_save(flags); if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ switch (gx_params->cs55x0->device) { switch (gx_params->cs55x0->device) { case PCI_DEVICE_ID_CYRIX_5530_LEGACY: case PCI_DEVICE_ID_CYRIX_5530_LEGACY: pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; /* FIXME: need to test other values -- Zwane,Miura */ /* FIXME: need to test other values -- Zwane,Miura */ pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */ /* typical 2 to 4ms */ pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */ gx_write_byte(PCI_IRQTC, 4); pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1); /* typical 50 to 100ms */ gx_write_byte(PCI_VIDTC, 100); if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */ gx_write_byte(PCI_PMER1, pmer1); if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */ suscfg = gx_params->pci_suscfg|SUSMOD; suscfg = gx_params->pci_suscfg|SUSMOD; } else { /* CS5530A,B.. */ } else { /* CS5530A,B.. */ suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; } } break; break; Loading @@ -294,13 +314,13 @@ static void gx_set_cpuspeed(unsigned int khz) suscfg = gx_params->pci_suscfg & ~(SUSMOD); suscfg = gx_params->pci_suscfg & ~(SUSMOD); gx_params->off_duration = 0; gx_params->off_duration = 0; gx_params->on_duration = 0; gx_params->on_duration = 0; dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n"); dprintk("suspend modulation disabled: cpu runs 100%% speed.\n"); } } pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); gx_write_byte(PCI_MODOFF, gx_params->off_duration); pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); gx_write_byte(PCI_MODON, gx_params->on_duration); pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); gx_write_byte(PCI_SUSCFG, suscfg); pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); local_irq_restore(flags); local_irq_restore(flags); Loading Loading @@ -334,7 +354,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) return -EINVAL; return -EINVAL; policy->cpu = 0; policy->cpu = 0; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); /* it needs to be assured that at least one supported frequency is /* it needs to be assured that at least one supported frequency is * within policy->min and policy->max. If it is not, policy->max * within policy->min and policy->max. If it is not, policy->max Loading @@ -354,7 +375,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) policy->max = tmp_freq; policy->max = tmp_freq; if (policy->max < policy->min) if (policy->max < policy->min) policy->max = policy->min; policy->max = policy->min; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); return 0; return 0; } } Loading Loading @@ -398,13 +420,13 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) return -ENODEV; return -ENODEV; /* determine maximum frequency */ /* determine maximum frequency */ if (pci_busclk) { if (pci_busclk) maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; } else if (cpu_khz) { else if (cpu_khz) maxfreq = cpu_khz; maxfreq = cpu_khz; } else { else maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; } stock_freq = maxfreq; stock_freq = maxfreq; curfreq = gx_get_cpuspeed(0); curfreq = gx_get_cpuspeed(0); Loading Loading @@ -447,7 +469,8 @@ static int __init cpufreq_gx_init(void) struct pci_dev *gx_pci; struct pci_dev *gx_pci; /* Test if we have the right hardware */ /* Test if we have the right hardware */ if ((gx_pci = gx_detect_chipset()) == NULL) gx_pci = gx_detect_chipset(); if (gx_pci == NULL) return -ENODEV; return -ENODEV; /* check whether module parameters are sane */ /* check whether module parameters are sane */ Loading @@ -468,9 +491,11 @@ static int __init cpufreq_gx_init(void) pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { ret = cpufreq_register_driver(&gx_suspmod_driver); if (ret) { kfree(params); kfree(params); return ret; /* register error! */ return ret; /* register error! */ } } Loading Loading
arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +65 −40 Original line number Original line Diff line number Diff line Loading @@ -79,8 +79,9 @@ #include <linux/smp.h> #include <linux/smp.h> #include <linux/cpufreq.h> #include <linux/cpufreq.h> #include <linux/pci.h> #include <linux/pci.h> #include <linux/errno.h> #include <asm/processor-cyrix.h> #include <asm/processor-cyrix.h> #include <asm/errno.h> /* PCI config registers, all at F0 */ /* PCI config registers, all at F0 */ #define PCI_PMER1 0x80 /* power management enable register 1 */ #define PCI_PMER1 0x80 /* power management enable register 1 */ Loading Loading @@ -122,7 +123,7 @@ static struct gxfreq_params *gx_params; static int stock_freq; static int stock_freq; /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ static int pci_busclk = 0; static int pci_busclk; module_param(pci_busclk, int, 0444); module_param(pci_busclk, int, 0444); /* maximum duration for which the cpu may be suspended /* maximum duration for which the cpu may be suspended Loading @@ -140,7 +141,8 @@ module_param (max_duration, int, 0444); #define POLICY_MIN_DIV 20 #define POLICY_MIN_DIV 20 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ "gx-suspmod", msg) /** /** * we can detect a core multipiler from dir0_lsb * we can detect a core multipiler from dir0_lsb Loading @@ -166,12 +168,20 @@ static int gx_freq_mult[16] = { * Low Level chipset interface * * Low Level chipset interface * ****************************************************************/ ****************************************************************/ static struct pci_device_id gx_chipset_tbl[] __initdata = { static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, { 0, }, { 0, }, }; }; static void gx_write_byte(int reg, int value) { pci_write_config_byte(gx_params->cs55x0, reg, value); } /** /** * gx_detect_chipset: * gx_detect_chipset: * * Loading Loading @@ -200,7 +210,8 @@ static __init struct pci_dev *gx_detect_chipset(void) /** /** * gx_get_cpuspeed: * gx_get_cpuspeed: * * * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi * Geode CPU runs. */ */ static unsigned int gx_get_cpuspeed(unsigned int cpu) static unsigned int gx_get_cpuspeed(unsigned int cpu) { { Loading @@ -217,7 +228,8 @@ static unsigned int gx_get_cpuspeed(unsigned int cpu) * * **/ **/ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) { { unsigned int i; unsigned int i; u8 tmp_on, tmp_off; u8 tmp_on, tmp_off; Loading Loading @@ -259,25 +271,33 @@ static void gx_set_cpuspeed(unsigned int khz) freqs.cpu = 0; freqs.cpu = 0; freqs.old = gx_get_cpuspeed(0); freqs.old = gx_get_cpuspeed(0); new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration); freqs.new = new_khz; freqs.new = new_khz; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); local_irq_save(flags); local_irq_save(flags); if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */ switch (gx_params->cs55x0->device) { switch (gx_params->cs55x0->device) { case PCI_DEVICE_ID_CYRIX_5530_LEGACY: case PCI_DEVICE_ID_CYRIX_5530_LEGACY: pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; /* FIXME: need to test other values -- Zwane,Miura */ /* FIXME: need to test other values -- Zwane,Miura */ pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */ /* typical 2 to 4ms */ pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */ gx_write_byte(PCI_IRQTC, 4); pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1); /* typical 50 to 100ms */ gx_write_byte(PCI_VIDTC, 100); if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */ gx_write_byte(PCI_PMER1, pmer1); if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */ suscfg = gx_params->pci_suscfg|SUSMOD; suscfg = gx_params->pci_suscfg|SUSMOD; } else { /* CS5530A,B.. */ } else { /* CS5530A,B.. */ suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; } } break; break; Loading @@ -294,13 +314,13 @@ static void gx_set_cpuspeed(unsigned int khz) suscfg = gx_params->pci_suscfg & ~(SUSMOD); suscfg = gx_params->pci_suscfg & ~(SUSMOD); gx_params->off_duration = 0; gx_params->off_duration = 0; gx_params->on_duration = 0; gx_params->on_duration = 0; dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n"); dprintk("suspend modulation disabled: cpu runs 100%% speed.\n"); } } pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); gx_write_byte(PCI_MODOFF, gx_params->off_duration); pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); gx_write_byte(PCI_MODON, gx_params->on_duration); pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); gx_write_byte(PCI_SUSCFG, suscfg); pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); local_irq_restore(flags); local_irq_restore(flags); Loading Loading @@ -334,7 +354,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) return -EINVAL; return -EINVAL; policy->cpu = 0; policy->cpu = 0; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); /* it needs to be assured that at least one supported frequency is /* it needs to be assured that at least one supported frequency is * within policy->min and policy->max. If it is not, policy->max * within policy->min and policy->max. If it is not, policy->max Loading @@ -354,7 +375,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) policy->max = tmp_freq; policy->max = tmp_freq; if (policy->max < policy->min) if (policy->max < policy->min) policy->max = policy->min; policy->max = policy->min; cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); return 0; return 0; } } Loading Loading @@ -398,13 +420,13 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) return -ENODEV; return -ENODEV; /* determine maximum frequency */ /* determine maximum frequency */ if (pci_busclk) { if (pci_busclk) maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; } else if (cpu_khz) { else if (cpu_khz) maxfreq = cpu_khz; maxfreq = cpu_khz; } else { else maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; } stock_freq = maxfreq; stock_freq = maxfreq; curfreq = gx_get_cpuspeed(0); curfreq = gx_get_cpuspeed(0); Loading Loading @@ -447,7 +469,8 @@ static int __init cpufreq_gx_init(void) struct pci_dev *gx_pci; struct pci_dev *gx_pci; /* Test if we have the right hardware */ /* Test if we have the right hardware */ if ((gx_pci = gx_detect_chipset()) == NULL) gx_pci = gx_detect_chipset(); if (gx_pci == NULL) return -ENODEV; return -ENODEV; /* check whether module parameters are sane */ /* check whether module parameters are sane */ Loading @@ -468,9 +491,11 @@ static int __init cpufreq_gx_init(void) pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration)); if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { ret = cpufreq_register_driver(&gx_suspmod_driver); if (ret) { kfree(params); kfree(params); return ret; /* register error! */ return ret; /* register error! */ } } Loading