Browse Source

Merge branch 'acpi-assorted'

* acpi-assorted:
  ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan
  ACPI: Add CMOS RTC Operation Region handler support
  ACPI: Remove unused flags in acpi_device_flags
  ACPI: Remove useless initializers
  ACPI / battery: Make sure all spaces are in correct places
  ACPI: add _STA evaluation at do_acpi_find_child()
  ACPI / EC: access user space with get_user()/put_user()
Rafael J. Wysocki 12 years ago
parent
commit
bdc8f09685

+ 1 - 0
drivers/acpi/Makefile

@@ -44,6 +44,7 @@ acpi-y				+= acpi_platform.o
 acpi-y				+= power.o
 acpi-y				+= event.o
 acpi-y				+= sysfs.o
+acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o

+ 92 - 0
drivers/acpi/acpi_cmos_rtc.c

@@ -0,0 +1,92 @@
+/*
+ * ACPI support for CMOS RTC Address Space access
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Lan Tianyu <tianyu.lan@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm-generic/rtc.h>
+
+#include "internal.h"
+
+#define PREFIX "ACPI: "
+
+ACPI_MODULE_NAME("cmos rtc");
+
+static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
+	{ "PNP0B00" },
+	{ "PNP0B01" },
+	{ "PNP0B02" },
+	{}
+};
+
+static acpi_status
+acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
+		      u32 bits, u64 *value64,
+		      void *handler_context, void *region_context)
+{
+	int i;
+	u8 *value = (u8 *)&value64;
+
+	if (address > 0xff || !value64)
+		return AE_BAD_PARAMETER;
+
+	if (function != ACPI_WRITE && function != ACPI_READ)
+		return AE_BAD_PARAMETER;
+
+	spin_lock_irq(&rtc_lock);
+
+	for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
+		if (function == ACPI_READ)
+			*value = CMOS_READ(address);
+		else
+			CMOS_WRITE(*value, address);
+
+	spin_unlock_irq(&rtc_lock);
+
+	return AE_OK;
+}
+
+static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
+		const struct acpi_device_id *id)
+{
+	acpi_status status;
+
+	status = acpi_install_address_space_handler(adev->handle,
+			ACPI_ADR_SPACE_CMOS,
+			&acpi_cmos_rtc_space_handler,
+			NULL, NULL);
+	if (ACPI_FAILURE(status)) {
+		pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
+{
+	if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
+			ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
+		pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
+}
+
+static struct acpi_scan_handler cmos_rtc_handler = {
+	.ids = acpi_cmos_rtc_ids,
+	.attach = acpi_install_cmos_rtc_space_handler,
+	.detach = acpi_remove_cmos_rtc_space_handler,
+};
+
+void __init acpi_cmos_rtc_init(void)
+{
+	acpi_scan_add_handler(&cmos_rtc_handler);
+}

+ 9 - 9
drivers/acpi/battery.c

@@ -425,7 +425,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 {
 	int result = -EFAULT;
 	acpi_status status = 0;
-	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
+	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
 			"_BIX" : "_BIF";
 
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -661,11 +661,11 @@ static void find_battery(const struct dmi_header *dm, void *private)
 static void acpi_battery_quirks(struct acpi_battery *battery)
 {
 	if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
-		return ;
+		return;
 
-        if (battery->full_charge_capacity == 100 &&
-            battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
-            battery->capacity_now >=0 && battery->capacity_now <= 100) {
+	if (battery->full_charge_capacity == 100 &&
+		battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
+		battery->capacity_now >= 0 && battery->capacity_now <= 100) {
 		set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
 		battery->full_charge_capacity = battery->design_capacity;
 		battery->capacity_now = (battery->capacity_now *
@@ -673,7 +673,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
 	}
 
 	if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
-		return ;
+		return;
 
 	if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
 		const char *s;
@@ -761,7 +761,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 		goto end;
 
 	seq_printf(seq, "present:                 %s\n",
-		   acpi_battery_present(battery)?"yes":"no");
+		   acpi_battery_present(battery) ? "yes" : "no");
 	if (!acpi_battery_present(battery))
 		goto end;
 	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
@@ -817,12 +817,12 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 		goto end;
 
 	seq_printf(seq, "present:                 %s\n",
-		   acpi_battery_present(battery)?"yes":"no");
+		   acpi_battery_present(battery) ? "yes" : "no");
 	if (!acpi_battery_present(battery))
 		goto end;
 
 	seq_printf(seq, "capacity state:          %s\n",
-			(battery->state & 0x04)?"critical":"ok");
+			(battery->state & 0x04) ? "critical" : "ok");
 	if ((battery->state & 0x01) && (battery->state & 0x02))
 		seq_printf(seq,
 			   "charging state:          charging/discharging\n");

+ 8 - 9
drivers/acpi/bus.c

@@ -91,8 +91,7 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
 
 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
 {
-	acpi_status status = AE_OK;
-
+	acpi_status status;
 
 	if (!device)
 		return -EINVAL;
@@ -162,7 +161,7 @@ EXPORT_SYMBOL(acpi_bus_private_data_handler);
 
 int acpi_bus_get_private_data(acpi_handle handle, void **data)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 
 	if (!*data)
 		return -EINVAL;
@@ -361,7 +360,7 @@ extern int event_is_open;
 int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
 	struct acpi_bus_event *event;
-	unsigned long flags = 0;
+	unsigned long flags;
 
 	/* drop event on the floor if no one's listening */
 	if (!event_is_open)
@@ -400,7 +399,7 @@ EXPORT_SYMBOL(acpi_bus_generate_proc_event);
 
 int acpi_bus_receive_event(struct acpi_bus_event *event)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	struct acpi_bus_event *entry = NULL;
 
 	DECLARE_WAITQUEUE(wait, current);
@@ -593,7 +592,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 
 static int __init acpi_bus_init_irq(void)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 	union acpi_object arg = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg };
 	char *message = NULL;
@@ -640,7 +639,7 @@ u8 acpi_gbl_permanent_mmap;
 
 void __init acpi_early_init(void)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 
 	if (acpi_disabled)
 		return;
@@ -714,8 +713,8 @@ void __init acpi_early_init(void)
 
 static int __init acpi_bus_init(void)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
+	int result;
+	acpi_status status;
 	extern acpi_status acpi_os_initialize1(void);
 
 	acpi_os_initialize1();

+ 4 - 0
drivers/acpi/ec.c

@@ -983,6 +983,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
 	ec_enlarge_storm_threshold, "CLEVO hardware", {
 	DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
 	DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
+	{
+	ec_skip_dsdt_scan, "HP Folio 13", {
+	DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
 	{},
 };
 

+ 14 - 4
drivers/acpi/ec_sys.c

@@ -12,6 +12,7 @@
 #include <linux/acpi.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
 	 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
 	 */
 	unsigned int size = EC_SPACE_SIZE;
-	u8 *data = (u8 *) buf;
 	loff_t init_off = *off;
 	int err = 0;
 
@@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
 		size = count;
 
 	while (size) {
-		err = ec_read(*off, &data[*off - init_off]);
+		u8 byte_read;
+		err = ec_read(*off, &byte_read);
 		if (err)
 			return err;
+		if (put_user(byte_read, buf + *off - init_off)) {
+			if (*off - init_off)
+				return *off - init_off; /* partial read */
+			return -EFAULT;
+		}
 		*off += 1;
 		size--;
 	}
@@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
 
 	unsigned int size = count;
 	loff_t init_off = *off;
-	u8 *data = (u8 *) buf;
 	int err = 0;
 
 	if (*off >= EC_SPACE_SIZE)
@@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
 	}
 
 	while (size) {
-		u8 byte_write = data[*off - init_off];
+		u8 byte_write;
+		if (get_user(byte_write, buf + *off - init_off)) {
+			if (*off - init_off)
+				return *off - init_off; /* partial write */
+			return -EFAULT;
+		}
 		err = ec_write(*off, byte_write);
 		if (err)
 			return err;

+ 4 - 2
drivers/acpi/glue.c

@@ -81,13 +81,15 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
 static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
 				      void *addr_p, void **ret_p)
 {
-	unsigned long long addr;
+	unsigned long long addr, sta;
 	acpi_status status;
 
 	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
 	if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
 		*ret_p = handle;
-		return AE_CTRL_TERMINATE;
+		status = acpi_bus_get_status_handle(handle, &sta);
+		if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED))
+			return AE_CTRL_TERMINATE;
 	}
 	return AE_OK;
 }

+ 5 - 0
drivers/acpi/internal.h

@@ -51,6 +51,11 @@ void acpi_memory_hotplug_init(void);
 #else
 static inline void acpi_memory_hotplug_init(void) {}
 #endif
+#ifdef CONFIG_X86
+void acpi_cmos_rtc_init(void);
+#else
+static inline void acpi_cmos_rtc_init(void) {}
+#endif
 
 extern bool acpi_force_hot_remove;
 

+ 1 - 0
drivers/acpi/scan.c

@@ -2132,6 +2132,7 @@ int __init acpi_scan_init(void)
 	acpi_processor_init();
 	acpi_platform_init();
 	acpi_lpss_init();
+	acpi_cmos_rtc_init();
 	acpi_container_init();
 	acpi_memory_hotplug_init();
 	acpi_dock_init();

+ 1 - 3
include/acpi/acpi_bus.h

@@ -156,12 +156,10 @@ struct acpi_device_flags {
 	u32 dynamic_status:1;
 	u32 removable:1;
 	u32 ejectable:1;
-	u32 suprise_removal_ok:1;
 	u32 power_manageable:1;
-	u32 performance_manageable:1;
 	u32 eject_pending:1;
 	u32 match_driver:1;
-	u32 reserved:24;
+	u32 reserved:26;
 };
 
 /* File System */