[Debian-eeepc-devel] [PATCH] eeepc-laptop: disable cpu speed control on EeePC 701

Corentin Chary corentin.chary at gmail.com
Fri Dec 11 06:33:24 UTC 2009


On Thu, Dec 10, 2009 at 11:30 PM, Alan Jenkins
<alan-jenkins at tuffmail.co.uk> wrote:
> The EeePC 4G ("701") implements CFVS, but it is not supported
> by the pre-installed OS, and the original option to change it
> in the BIOS setup screen was removed in later versions.
>
> Judging by the lack of "Super Hybrid Engine" on Asus product pages,
> this applies to all "701" models (4G/4G Surf/2G Surf).
>
>
> So Asus made a deliberate decision not to support it on this model.
> We have several reports that using it can cause the system to hang [1].
> That said, it does not happen all the time.  Some users do not
> experience it at all (and apparently wish to continue "right-clocking").
>
> Check for the EeePC 701 using DMI.  If met, then disable writes to the
> "cpufv" sysfs attribute and log an explanatory message.
>
>
> Add a "cpufv_disabled" attribute which allows users to override this
> policy.  Writing to this attribute will log a second message.
>
> The sysfs attribute is more useful than a module option, because it
> makes it easier for userspace scripts to provide consistent behaviour
> (according to user configuration), regardless of whether the kernel
> includes this change.
>
> [1] "EeePC 701 freezes with garbled screen while booting"
>   <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=559578>
>
> Signed-off-by: Alan Jenkins <alan-jenkins at tuffmail.co.uk>
> ---
> drivers/platform/x86/eeepc-laptop.c |   86
> +++++++++++++++++++++++++++++++++++
> 1 files changed, 86 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/platform/x86/eeepc-laptop.c
> b/drivers/platform/x86/eeepc-laptop.c
> index d07a4c0..70e5a30 100644
> --- a/drivers/platform/x86/eeepc-laptop.c
> +++ b/drivers/platform/x86/eeepc-laptop.c
> @@ -35,6 +35,7 @@
> #include <linux/pci.h>
> #include <linux/pci_hotplug.h>
> #include <linux/leds.h>
> +#include <linux/dmi.h>
>
> #define EEEPC_LAPTOP_VERSION    "0.1"
> #define EEEPC_LAPTOP_NAME       "Eee PC Hotkey Driver"
> @@ -159,6 +160,7 @@ struct eeepc_laptop {
>        acpi_handle handle;             /* the handle of the acpi device */
>        u32 cm_supported;               /* the control methods supported
>                                           by this BIOS */
> +       bool cpufv_disabled;
>        u16 event_count[128];           /* count for each event */
>
>        struct platform_device *platform_device;
> @@ -378,6 +380,8 @@ static ssize_t store_cpufv(struct device *dev,
>        struct eeepc_cpufv c;
>        int rv, value;
>
> +       if (eeepc->cpufv_disabled)
> +               return -EPERM;
>        if (get_cpufv(eeepc, &c))
>                return -ENODEV;
>        rv = parse_arg(buf, count, &value);
> @@ -389,6 +393,41 @@ static ssize_t store_cpufv(struct device *dev,
>        return rv;
> }
>
> +static ssize_t show_cpufv_disabled(struct device *dev,
> +                         struct device_attribute *attr,
> +                         char *buf)
> +{
> +       struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
> +
> +       return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
> +}
> +
> +static ssize_t store_cpufv_disabled(struct device *dev,
> +                          struct device_attribute *attr,
> +                          const char *buf, size_t count)
> +{
> +       struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
> +       int rv, value;
> +
> +       rv = parse_arg(buf, count, &value);
> +       if (rv < 0)
> +               return rv;
> +
> +       switch (value) {
> +       case 0:
> +               if (eeepc->cpufv_disabled)
> +                       pr_warning("cpufv enabled (not officially supported
> "
> +                               "on this model)\n");
> +               eeepc->cpufv_disabled = false;
> +               return rv;
> +       case 1:
> +               return -EPERM;

Why -EPERM if value 1 ? Can't we just do cpufv->disabled = true; return rv; ?

> +       default:
> +               return -EINVAL;
> +       }
> +}
> +
> +
> static struct device_attribute dev_attr_cpufv = {
>        .attr = {
>                .name = "cpufv",
> @@ -404,12 +443,22 @@ static struct device_attribute
> dev_attr_available_cpufv = {
>        .show   = show_available_cpufv
> };
>
> +static struct device_attribute dev_attr_cpufv_disabled = {
> +       .attr = {
> +               .name = "cpufv_disabled",
> +               .mode = 0644 },
> +       .show   = show_cpufv_disabled,
> +       .store  = store_cpufv_disabled
> +};
> +
> +
> static struct attribute *platform_attributes[] = {
>        &dev_attr_camera.attr,
>        &dev_attr_cardr.attr,
>        &dev_attr_disp.attr,
>        &dev_attr_cpufv.attr,
>        &dev_attr_available_cpufv.attr,
> +       &dev_attr_cpufv_disabled.attr,
>        NULL
> };
>
> @@ -1261,6 +1310,41 @@ static void eeepc_acpi_notify(struct acpi_device
> *device, u32 event)
>        }
> }
>
> +static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
> +{
> +       struct eeepc_cpufv c;
> +       const char *model;
> +
> +       /*
> +        * Blacklist for setting cpufv (cpu speed).
> +        *
> +        * EeePC 4G ("701") implements CFVS, but it is not supported
> +        * by the pre-installed OS, and the original option to change it
> +        * in the BIOS setup screen was removed in later versions.
> +        *
> +        * Judging by the lack of "Super Hybrid Engine" on Asus product
> pages,
> +        * this applies to all "701" models (4G/4G Surf/2G Surf).
> +        *
> +        * So Asus made a deliberate decision not to support it on this
> model.
> +        * We have several reports that using it can cause the system to
> hang
> +        *
> +        * The hang has also been reported on a "702" (Model name "8G"?).
> +        *
> +        * We avoid dmi_check_system() / dmi_match(), because they use
> +        * substring matching.  We don't want to affect the "701SD"
> +        * and "701SDX" models, because they do support S.H.E.
> +        */
> +
> +       model = dmi_get_system_info(DMI_PRODUCT_NAME);
> +
> +       if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
> +               eeepc->cpufv_disabled = true;
> +               pr_info("model %s does not officially support setting cpu "
> +                       "speed\n", model);
> +               pr_info("cpufv disabled to avoid instability\n");
> +       }
> +}
> +
> static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
> {
>        int dummy;
> @@ -1342,6 +1426,8 @@ static int __devinit eeepc_acpi_add(struct acpi_device
> *device)
>        strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
>        device->driver_data = eeepc;
>
> +       eeepc_dmi_check(eeepc);
> +
>        result = eeepc_acpi_init(eeepc, device);
>        if (result)
>                goto fail_platform;
> --
> 1.6.3.3
>
>
>
>



-- 
Corentin Chary
http://xf.iksaif.net



More information about the Debian-eeepc-devel mailing list