CHROMIUM: chromeos_acpi: Enable USB wake from S3
[cascardo/linux.git] / drivers / platform / x86 / chromeos_acpi.c
index aa4b9ca..37afad3 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 
+#include "../chromeos.h"
+
 #define CHNV_DEBUG_RESET_FLAG  0x40         /* flag for S3 reboot */
 #define CHNV_RECOVERY_FLAG     0x80         /* flag for recovery reboot */
 
@@ -188,7 +190,7 @@ int chromeos_legacy_set_need_recovery(void)
  *
  * retrun number of bytes copied, or -1 on any error.
  */
-int chromeos_platform_read_nvram(u8 *nvram_buffer, int buf_size)
+static ssize_t chromeos_vbc_nvram_read(void *buf, size_t count)
 {
 
        int base, size, i;
@@ -202,19 +204,19 @@ int chromeos_platform_read_nvram(u8 *nvram_buffer, int buf_size)
        base = chromeos_acpi_if_data.nv_base.cad_value;
        size = chromeos_acpi_if_data.nv_size.cad_value;
 
-       if (buf_size < size) {
-               pr_err("%s: not enough room to read nvram (%d < %d)\n",
-                      __func__, buf_size, size);
+       if (count < size) {
+               pr_err("%s: not enough room to read nvram (%zd < %d)\n",
+                      __func__, count, size);
                return -EINVAL;
        }
 
        for (i = 0; i < size; i++)
-               nvram_buffer[i] = nvram_read_byte(base++);
+               ((u8 *)buf)[i] = nvram_read_byte(base++);
 
        return size;
 }
 
-int chromeos_platform_write_nvram(u8 *nvram_buffer, int buf_size)
+static ssize_t chromeos_vbc_nvram_write(const void *buf, size_t count)
 {
        unsigned base, size, i;
 
@@ -227,9 +229,9 @@ int chromeos_platform_write_nvram(u8 *nvram_buffer, int buf_size)
        size = chromeos_acpi_if_data.nv_size.cad_value;
        base = chromeos_acpi_if_data.nv_base.cad_value;
 
-       if (buf_size != size) {
-               printk(MY_ERR "%s: wrong buffer size (%d != %d)!\n", __func__,
-                      buf_size, size);
+       if (count != size) {
+               printk(MY_ERR "%s: wrong buffer size (%zd != %d)!\n", __func__,
+                      count, size);
                return -EINVAL;
        }
 
@@ -237,11 +239,11 @@ int chromeos_platform_write_nvram(u8 *nvram_buffer, int buf_size)
                u8 c;
 
                c = nvram_read_byte(base + i);
-               if (c == nvram_buffer[i])
+               if (c == ((u8 *)buf)[i])
                        continue;
-               nvram_write_byte(nvram_buffer[i], base + i);
+               nvram_write_byte(((u8 *)buf)[i], base + i);
        }
-       return 0;
+       return size;
 }
 
 /*
@@ -440,7 +442,7 @@ static void handle_nested_acpi_package(union acpi_object *po, char *pm,
 
                case ACPI_TYPE_STRING:
                        copy_size = min(element->string.length,
-                                       sizeof(attr_value) - 1);
+                                       (u32)(sizeof(attr_value)) - 1);
                        memcpy(attr_value, element->string.pointer, copy_size);
                        attr_value[copy_size] = '\0';
                        paa = create_sysfs_attribute(attr_value, pm, count, i);
@@ -619,7 +621,7 @@ static void handle_acpi_package(union acpi_object *po, char *pm)
 
                case ACPI_TYPE_STRING:
                        copy_size = min(element->string.length,
-                                       sizeof(attr_value) - 1);
+                                       (u32)(sizeof(attr_value)) - 1);
                        memcpy(attr_value, element->string.pointer, copy_size);
                        attr_value[copy_size] = '\0';
                        add_sysfs_attribute(attr_value, pm, count, j);
@@ -752,13 +754,24 @@ static int chromeos_device_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+static struct chromeos_vbc chromeos_vbc_nvram = {
+       .name = "chromeos_vbc_nvram",
+       .read = chromeos_vbc_nvram_read,
+       .write = chromeos_vbc_nvram_write,
+};
+
 static int __init chromeos_acpi_init(void)
 {
        int ret = 0;
+       acpi_status status;
 
        if (acpi_disabled)
                return -ENODEV;
 
+       ret = chromeos_vbc_register(&chromeos_vbc_nvram);
+       if (ret)
+               return ret;
+
        chromeos_acpi.p_dev = platform_device_register_simple("chromeos_acpi",
                                                              -1, NULL, 0);
        if (IS_ERR(chromeos_acpi.p_dev)) {
@@ -775,6 +788,12 @@ static int __init chromeos_acpi_init(void)
        }
        printk(MY_INFO "installed%s\n",
               chromeos_on_legacy_firmware() ? " (legacy mode)" : "");
+
+       printk(MY_INFO "chromeos_acpi: enabling S3 USB wake\n");
+       status = acpi_evaluate_object(NULL, "\\S3UE", NULL, NULL);
+       if (!ACPI_SUCCESS(status))
+               printk(MY_INFO "chromeos_acpi: failed to enable S3 USB wake\n");
+
        return 0;
 }