summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-31 16:06:50 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-31 16:06:50 -0800
commitf6ea76c0dc98f2a9219ee5327a2d3a00dfb7e89b (patch)
treec7c6360b40213958ee55fff48cc16c506357ce5d /drivers
parent54356933c64d5f26e15c040d6bb81e8d2d616555 (diff)
parent63b61eadc2c4fd8ef6932e3a31370927b2e4951f (diff)
Merge bk://kernel.bkbits.net/davem/net-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig20
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c18
-rw-r--r--drivers/acpi/acpi_memhotplug.c542
-rw-r--r--drivers/acpi/battery.c2
-rw-r--r--drivers/acpi/button.c4
-rw-r--r--drivers/acpi/container.c15
-rw-r--r--drivers/acpi/debug.c4
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c11
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c8
-rw-r--r--drivers/acpi/dispatcher/dsutils.c166
-rw-r--r--drivers/acpi/dispatcher/dswexec.c61
-rw-r--r--drivers/acpi/ec.c2
-rw-r--r--drivers/acpi/events/evxface.c4
-rw-r--r--drivers/acpi/executer/exmisc.c5
-rw-r--r--drivers/acpi/executer/exoparg2.c6
-rw-r--r--drivers/acpi/executer/exresolv.c6
-rw-r--r--drivers/acpi/executer/exstoren.c7
-rw-r--r--drivers/acpi/executer/exstorob.c27
-rw-r--r--drivers/acpi/fan.c33
-rw-r--r--drivers/acpi/ibm_acpi.c4
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c10
-rw-r--r--drivers/acpi/parser/psopcode.c2
-rw-r--r--drivers/acpi/parser/psparse.c42
-rw-r--r--drivers/acpi/parser/pswalk.c254
-rw-r--r--drivers/acpi/pci_irq.c38
-rw-r--r--drivers/acpi/pci_link.c14
-rw-r--r--drivers/acpi/pci_root.c4
-rw-r--r--drivers/acpi/power.c10
-rw-r--r--drivers/acpi/processor_core.c6
-rw-r--r--drivers/acpi/processor_thermal.c2
-rw-r--r--drivers/acpi/processor_throttling.c2
-rw-r--r--drivers/acpi/resources/rsaddr.c146
-rw-r--r--drivers/acpi/resources/rscalc.c14
-rw-r--r--drivers/acpi/resources/rsdump.c23
-rw-r--r--drivers/acpi/resources/rslist.c1
-rw-r--r--drivers/acpi/scan.c47
-rw-r--r--drivers/acpi/thermal.c2
-rw-r--r--drivers/acpi/toshiba_acpi.c2
-rw-r--r--drivers/acpi/utilities/utcopy.c19
-rw-r--r--drivers/acpi/utilities/utdelete.c18
-rw-r--r--drivers/acpi/utilities/utglobal.c10
-rw-r--r--drivers/acpi/utilities/utmisc.c44
-rw-r--r--drivers/acpi/video.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-ite.c13
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c44
-rw-r--r--drivers/i2c/algos/i2c-algo-sibyte.c13
-rw-r--r--drivers/i2c/busses/Kconfig38
-rw-r--r--drivers/i2c/busses/i2c-elektor.c9
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c4
-rw-r--r--drivers/i2c/busses/i2c-ite.c7
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c2
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c15
-rw-r--r--drivers/i2c/busses/i2c-viapro.c17
-rw-r--r--drivers/i2c/chips/Kconfig25
-rw-r--r--drivers/i2c/chips/Makefile2
-rw-r--r--drivers/i2c/chips/adm1021.c14
-rw-r--r--drivers/i2c/chips/ds1337.c402
-rw-r--r--drivers/i2c/chips/eeprom.c3
-rw-r--r--drivers/i2c/chips/it87.c10
-rw-r--r--drivers/i2c/chips/lm85.c104
-rw-r--r--drivers/i2c/chips/lm87.c20
-rw-r--r--drivers/i2c/chips/lm90.c44
-rw-r--r--drivers/i2c/chips/lm92.c423
-rw-r--r--drivers/i2c/chips/m41t00.c1
-rw-r--r--drivers/i2c/chips/w83627hf.c5
-rw-r--r--drivers/i2c/chips/w83781d.c100
-rw-r--r--drivers/i2c/i2c-core.c10
-rw-r--r--drivers/pci/msi.c4
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c9
71 files changed, 2286 insertions, 712 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 894128bffc..0400a52d50 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -331,6 +331,26 @@ config ACPI_CONTAINER
This is the ACPI generic container driver which supports
ACPI0004, PNP0A05 and PNP0A06 devices
+config ACPI_HOTPLUG_MEMORY
+ tristate "Memory Hotplug"
+ depends on ACPI
+ depends on MEMORY_HOTPLUG
+ default n
+ help
+ This driver adds supports for ACPI Memory Hotplug. This driver
+ provides support for fielding notifications on ACPI memory
+ devices (PNP0C80) which represent memory ranges that may be
+ onlined or offlined during runtime.
+
+ Enabling this driver assumes that your platform hardware
+ and firmware have support for hot-plugging physical memory. If
+ your system does not support physically adding or ripping out
+ memory DIMMs at some platfrom defined granularity (individually
+ or as a bank) at runtime, then you need not enable this driver.
+
+ If one selects "m," this driver can be loaded using the following
+ command:
+ $>modprobe acpi_memhotplug
endif # ACPI
endmenu
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 1ae0d89c2d..65c92e2056 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_ACPI_BUS) += scan.o motherboard.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index e0f498c7b3..23ab761dd7 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -51,8 +51,8 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
MODULE_LICENSE("GPL");
-int acpi_ac_add (struct acpi_device *device);
-int acpi_ac_remove (struct acpi_device *device, int type);
+static int acpi_ac_add (struct acpi_device *device);
+static int acpi_ac_remove (struct acpi_device *device, int type);
static int acpi_ac_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_ac_driver = {
@@ -108,9 +108,9 @@ acpi_ac_get_state (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_ac_dir;
+static struct proc_dir_entry *acpi_ac_dir;
-int acpi_ac_seq_show(struct seq_file *seq, void *offset)
+static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_ac *ac = (struct acpi_ac *) seq->private;
@@ -200,7 +200,7 @@ acpi_ac_remove_fs (
Driver Model
-------------------------------------------------------------------------- */
-void
+static void
acpi_ac_notify (
acpi_handle handle,
u32 event,
@@ -232,7 +232,7 @@ acpi_ac_notify (
}
-int
+static int
acpi_ac_add (
struct acpi_device *device)
{
@@ -286,7 +286,7 @@ end:
}
-int
+static int
acpi_ac_remove (
struct acpi_device *device,
int type)
@@ -315,7 +315,7 @@ acpi_ac_remove (
}
-int __init
+static int __init
acpi_ac_init (void)
{
int result = 0;
@@ -337,7 +337,7 @@ acpi_ac_init (void)
}
-void __exit
+static void __exit
acpi_ac_exit (void)
{
ACPI_FUNCTION_TRACE("acpi_ac_exit");
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
new file mode 100644
index 0000000000..77285ffe41
--- /dev/null
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2004 Intel Corporation <naveen.b.s@intel.com>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * ACPI based HotPlug driver that supports Memory Hotplug
+ * This driver fields notifications from firmare for memory add
+ * and remove operations and alerts the VM of the affected memory
+ * ranges.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/memory_hotplug.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL
+#define ACPI_MEMORY_DEVICE_CLASS "memory"
+#define ACPI_MEMORY_DEVICE_HID "PNP0C80"
+#define ACPI_MEMORY_DEVICE_DRIVER_NAME "Hotplug Mem Driver"
+#define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device"
+
+#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT
+
+ACPI_MODULE_NAME ("acpi_memory")
+MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+/* ACPI _STA method values */
+#define ACPI_MEMORY_STA_PRESENT (0x00000001UL)
+#define ACPI_MEMORY_STA_ENABLED (0x00000002UL)
+#define ACPI_MEMORY_STA_FUNCTIONAL (0x00000008UL)
+
+/* Memory Device States */
+#define MEMORY_INVALID_STATE 0
+#define MEMORY_POWER_ON_STATE 1
+#define MEMORY_POWER_OFF_STATE 2
+
+static int acpi_memory_device_add (struct acpi_device *device);
+static int acpi_memory_device_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_memory_device_driver = {
+ .name = ACPI_MEMORY_DEVICE_DRIVER_NAME,
+ .class = ACPI_MEMORY_DEVICE_CLASS,
+ .ids = ACPI_MEMORY_DEVICE_HID,
+ .ops = {
+ .add = acpi_memory_device_add,
+ .remove = acpi_memory_device_remove,
+ },
+};
+
+struct acpi_memory_device {
+ acpi_handle handle;
+ unsigned int state; /* State of the memory device */
+ unsigned short cache_attribute; /* memory cache attribute */
+ unsigned short read_write_attribute;/* memory read/write attribute */
+ u64 start_addr; /* Memory Range start physical addr */
+ u64 end_addr; /* Memory Range end physical addr */
+};
+
+
+static int
+acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
+{
+ acpi_status status;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_resource *resource = NULL;
+ struct acpi_resource_address64 address64;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources");
+
+ /* Get the range from the _CRS */
+ status = acpi_get_current_resources(mem_device->handle, &buffer);
+ if (ACPI_FAILURE(status))
+ return_VALUE(-EINVAL);
+
+ resource = (struct acpi_resource *) buffer.pointer;
+ status = acpi_resource_to_address64(resource, &address64);
+ if (ACPI_SUCCESS(status)) {
+ if (address64.resource_type == ACPI_MEMORY_RANGE) {
+ /* Populate the structure */
+ mem_device->cache_attribute =
+ address64.attribute.memory.cache_attribute;
+ mem_device->read_write_attribute =
+ address64.attribute.memory.read_write_attribute;
+ mem_device->start_addr = address64.min_address_range;
+ mem_device->end_addr = address64.max_address_range;
+ }
+ }
+
+ acpi_os_free(buffer.pointer);
+ return_VALUE(0);
+}
+
+static int
+acpi_memory_get_device(acpi_handle handle,
+ struct acpi_memory_device **mem_device)
+{
+ acpi_status status;
+ acpi_handle phandle;
+ struct acpi_device *device = NULL;
+ struct acpi_device *pdevice = NULL;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_get_device");
+
+ if (!acpi_bus_get_device(handle, &device) && device)
+ goto end;
+
+ status = acpi_get_parent(handle, &phandle);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in acpi_get_parent\n"));
+ return_VALUE(-EINVAL);
+ }
+
+ /* Get the parent device */
+ status = acpi_bus_get_device(phandle, &pdevice);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in acpi_bus_get_device\n"));
+ return_VALUE(-EINVAL);
+ }
+
+ /*
+ * Now add the notified device. This creates the acpi_device
+ * and invokes .add function
+ */
+ status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in acpi_bus_add\n"));
+ return_VALUE(-EINVAL);
+ }
+
+end:
+ *mem_device = acpi_driver_data(device);
+ if (!(*mem_device)) {
+ printk(KERN_ERR "\n driver data not found" );
+ return_VALUE(-ENODEV);
+ }
+
+ return_VALUE(0);
+}
+
+static int
+acpi_memory_check_device(struct acpi_memory_device *mem_device)
+{
+ unsigned long current_status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_check_device");
+
+ /* Get device present/absent information from the _STA */
+ if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA",
+ NULL, &current_status)))
+ return_VALUE(-ENODEV);
+ /*
+ * Check for device status. Device should be
+ * present/enabled/functioning.
+ */
+ if (!((current_status & ACPI_MEMORY_STA_PRESENT)
+ && (current_status & ACPI_MEMORY_STA_ENABLED)
+ && (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
+ return_VALUE(-ENODEV);
+
+ return_VALUE(0);
+}
+
+static int
+acpi_memory_enable_device(struct acpi_memory_device *mem_device)
+{
+ int result;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_enable_device");
+
+ /* Get the range from the _CRS */
+ result = acpi_memory_get_device_resources(mem_device);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "\nget_device_resources failed\n"));
+ mem_device->state = MEMORY_INVALID_STATE;
+ return result;
+ }
+
+ /*
+ * Tell the VM there is more memory here...
+ * Note: Assume that this function returns zero on success
+ */
+ result = add_memory(mem_device->start_addr,
+ (mem_device->end_addr - mem_device->start_addr) + 1,
+ mem_device->read_write_attribute);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "\nadd_memory failed\n"));
+ mem_device->state = MEMORY_INVALID_STATE;
+ return result;
+ }
+
+ return result;
+}
+
+static int
+acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+{
+ acpi_status status;
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+ unsigned long current_status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_powerdown_device");
+
+ /* Issue the _EJ0 command */
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = 1;
+ status = acpi_evaluate_object(mem_device->handle,
+ "_EJ0", &arg_list, NULL);
+ /* Return on _EJ0 failure */
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"_EJ0 failed.\n"));
+ return_VALUE(-ENODEV);
+ }
+
+ /* Evalute _STA to check if the device is disabled */
+ status = acpi_evaluate_integer(mem_device->handle, "_STA",
+ NULL, &current_status);
+ if (ACPI_FAILURE(status))
+ return_VALUE(-ENODEV);
+
+ /* Check for device status. Device should be disabled */
+ if (current_status & ACPI_MEMORY_STA_ENABLED)
+ return_VALUE(-EINVAL);
+
+ return_VALUE(0);
+}
+
+static int
+acpi_memory_disable_device(struct acpi_memory_device *mem_device)
+{
+ int result;
+ u64 start = mem_device->start_addr;
+ u64 len = mem_device->end_addr - start + 1;
+ unsigned long attr = mem_device->read_write_attribute;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_disable_device");
+
+ /*
+ * Ask the VM to offline this memory range.
+ * Note: Assume that this function returns zero on success
+ */
+ result = remove_memory(start, len, attr);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
+ return_VALUE(result);
+ }
+
+ /* Power-off and eject the device */
+ result = acpi_memory_powerdown_device(mem_device);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Device Power Down failed.\n"));
+ /* Set the status of the device to invalid */
+ mem_device->state = MEMORY_INVALID_STATE;
+ return result;
+ }
+
+ mem_device->state = MEMORY_POWER_OFF_STATE;
+ return result;
+}
+
+static void
+acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_memory_device *mem_device;
+ struct acpi_device *device;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_device_notify");
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "\nReceived BUS CHECK notification for device\n"));
+ /* Fall Through */
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ if (event == ACPI_NOTIFY_DEVICE_CHECK)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "\nReceived DEVICE CHECK notification for device\n"));
+ if (acpi_memory_get_device(handle, &mem_device)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in finding driver data\n"));
+ return_VOID;
+ }
+
+ if (!acpi_memory_check_device(mem_device)) {
+ if (acpi_memory_enable_device(mem_device))
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in acpi_memory_enable_device\n"));
+ }
+ break;
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "\nReceived EJECT REQUEST notification for device\n"));
+
+ if (acpi_bus_get_device(handle, &device)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Device doesn't exist\n"));
+ break;
+ }
+ mem_device = acpi_driver_data(device);
+ if (!mem_device) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Driver Data is NULL\n"));
+ break;
+ }
+
+ /*
+ * Currently disabling memory device from kernel mode
+ * TBD: Can also be disabled from user mode scripts
+ * TBD: Can also be disabled by Callback registration
+ * with generic sysfs driver
+ */
+ if (acpi_memory_disable_device(mem_device))
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error in acpi_memory_disable_device\n"));
+ /*
+ * TBD: Invoke acpi_bus_remove to cleanup data structures
+ */
+ break;
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
+ break;
+ }
+
+ return_VOID;
+}
+
+static int
+acpi_memory_device_add(struct acpi_device *device)
+{
+ int result;
+ struct acpi_memory_device *mem_device = NULL;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_device_add");
+
+ if (!device)
+ return_VALUE(-EINVAL);
+
+ mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
+ if (!mem_device)
+ return_VALUE(-ENOMEM);
+ memset(mem_device, 0, sizeof(struct acpi_memory_device));
+
+ mem_device->handle = device->handle;
+ sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
+ sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
+ acpi_driver_data(device) = mem_device;
+
+ /* Get the range from the _CRS */
+ result = acpi_memory_get_device_resources(mem_device);
+ if (result) {
+ kfree(mem_device);
+ return_VALUE(result);
+ }
+
+ /* Set the device state */
+ mem_device->state = MEMORY_POWER_ON_STATE;
+
+ printk(KERN_INFO "%s \n", acpi_device_name(device));
+
+ return_VALUE(result);
+}
+
+static int
+acpi_memory_device_remove (struct acpi_device *device, int type)
+{
+ struct acpi_memory_device *mem_device = NULL;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_device_remove");
+
+ if (!device || !acpi_driver_data(device))
+ return_VALUE(-EINVAL);
+
+ mem_device = (struct acpi_memory_device *) acpi_driver_data(device);
+ kfree(mem_device);
+
+ return_VALUE(0);
+}
+
+/*
+ * Helper function to check for memory device
+ */
+static acpi_status
+is_memory_device(acpi_handle handle)
+{
+ char *hardware_id;
+ acpi_status status;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_device_info *info;
+
+ ACPI_FUNCTION_TRACE("is_memory_device");
+
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(AE_ERROR);
+
+ info = buffer.pointer;
+ if (!(info->valid & ACPI_VALID_HID)) {
+ acpi_os_free(buffer.pointer);
+ return_ACPI_STATUS(AE_ERROR);
+ }
+
+ hardware_id = info->hardware_id.value;
+ if ((hardware_id == NULL) ||
+ (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
+ status = AE_ERROR;
+
+ acpi_os_free(buffer.pointer);
+ return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_register_notify_handler (acpi_handle handle,
+ u32 level, void *ctxt, void **retv)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_register_notify_handler");
+
+ status = is_memory_device(handle);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(AE_OK); /* continue */
+
+ status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+ acpi_memory_device_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error installing notify handler\n"));
+ return_ACPI_STATUS(AE_OK); /* continue */
+ }
+
+ return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_deregister_notify_handler (acpi_handle handle,
+ u32 level, void *ctxt, void **retv)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_deregister_notify_handler");
+
+ status = is_memory_device(handle);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(AE_OK); /* continue */
+
+ status = acpi_remove_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error removing notify handler\n"));
+ return_ACPI_STATUS(AE_OK); /* continue */
+ }
+
+ return_ACPI_STATUS(status);
+}
+
+static int __init
+acpi_memory_device_init (void)
+{
+ int result;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_device_init");
+
+ result = acpi_bus_register_driver(&acpi_memory_device_driver);
+
+ if (result < 0)
+ return_VALUE(-ENODEV);
+
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ acpi_memory_register_notify_handler,
+ NULL, NULL);
+
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+ acpi_bus_unregister_driver(&acpi_memory_device_driver);
+ return_VALUE(-ENODEV);
+ }
+
+ return_VALUE(0);
+}
+
+static void __exit
+acpi_memory_device_exit (void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("acpi_memory_device_exit");
+
+ /*
+ * Adding this to un-install notification handlers for all the device
+ * handles.
+ */
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ acpi_memory_deregister_notify_handler,
+ NULL, NULL);
+
+ if (ACPI_FAILURE (status))
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+
+ acpi_bus_unregister_driver(&acpi_memory_device_driver);
+
+ return_VOID;
+}
+
+module_init(acpi_memory_device_init);
+module_exit(acpi_memory_device_exit);
+
+
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index a10de067db..c55feca9b7 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -341,7 +341,7 @@ acpi_battery_check (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_battery_dir;
+static struct proc_dir_entry *acpi_battery_dir;
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
{
int result = 0;
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 31aded126c..ec4430e305 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -275,7 +275,7 @@ acpi_button_remove_fs (
Driver Interface
-------------------------------------------------------------------------- */
-void
+static void
acpi_button_notify (
acpi_handle handle,
u32 event,
@@ -302,7 +302,7 @@ acpi_button_notify (
}
-acpi_status
+static acpi_status
acpi_button_notify_fixed (
void *data)
{
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 060251b5e4..5a0adbf8bc 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -177,13 +177,18 @@ container_notify_cb(acpi_handle handle, u32 type, void *context)
printk("Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK)?
"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+ status = acpi_bus_get_device(handle, &device);
if (present) {
- status = acpi_bus_get_device(handle, &device);
if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle);
if (!result)
- kobject_hotplug(&device->kobj, KOBJ_ONLINE);
- } else {
+ kobject_hotplug(&device->kobj,
+ KOBJ_ONLINE);
+ else
+ printk("Failed to add container\n");
+ }
+ } else {
+ if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
}
@@ -255,7 +260,7 @@ end:
}
-int __init
+static int __init
acpi_container_init(void)
{
int result = 0;
@@ -276,7 +281,7 @@ acpi_container_init(void)
return(0);
}
-void __exit
+static void __exit
acpi_container_exit(void)
{
int action = UNINSTALL_NOTIFY_HANDLER;
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index d947e2a0a4..2c0dac559f 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -35,7 +35,7 @@ struct acpi_dlevel {
};
#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
-const struct acpi_dlayer acpi_debug_layers[] =
+static const struct acpi_dlayer acpi_debug_layers[] =
{
ACPI_DEBUG_INIT(ACPI_UTILITIES),
ACPI_DEBUG_INIT(ACPI_HARDWARE),
@@ -53,7 +53,7 @@ const struct acpi_dlayer acpi_debug_layers[] =
ACPI_DEBUG_INIT(ACPI_TOOLS),
};
-const struct acpi_dlevel acpi_debug_levels[] =
+static const struct acpi_dlevel acpi_debug_levels[] =
{
ACPI_DEBUG_INIT(ACPI_LV_ERROR),
ACPI_DEBUG_INIT(ACPI_LV_WARN),
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index fac39ba4a7..9f0456cb9b 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -448,7 +448,16 @@ acpi_ds_restart_control_method (
*/
walk_state->return_desc = return_desc;
}
- else {
+
+ /*
+ * The following code is the
+ * optional support for a so-called "implicit return". Some AML code
+ * assumes that the last value of the method is "implicitly" returned
+ * to the caller. Just save the last result as the return value.
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
+ */
+ else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) {
/*
* Delete the return value if it will not be used by the
* calling method
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 66fc7549c6..5c987a0e7b 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -1010,6 +1010,10 @@ acpi_ds_exec_end_control_op (
* has been bubbled up the tree
*/
if (op->common.value.arg) {
+ /* Since we have a real Return(), delete any implicit return */
+
+ acpi_ds_clear_implicit_return (walk_state);
+
/* Return statement has an immediate operand */
status = acpi_ds_create_operands (walk_state, op->common.value.arg);
@@ -1036,6 +1040,10 @@ acpi_ds_exec_end_control_op (
}
else if ((walk_state->results) &&
(walk_state->results->results.num_results > 0)) {
+ /* Since we have a real Return(), delete any implicit return */
+
+ acpi_ds_clear_implicit_return (walk_state);
+
/*
* The return value has come from a previous calculation.
*
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index df6b001867..462c5d83e7 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -54,10 +54,120 @@
ACPI_MODULE_NAME ("dsutils")
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_clear_implicit_return
+ *
+ * PARAMETERS: walk_state - Current State
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
+ * to delete "stale" return values (if enabled, the return value
+ * from every operator is saved at least momentarily, in case the
+ * parent method exits.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_clear_implicit_return (
+ struct acpi_walk_state *walk_state)
+{
+ ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
+
+
+ /*
+ * Slack must be enabled for this feature
+ */
+ if (!acpi_gbl_enable_interpreter_slack) {
+ return;
+ }
+
+ if (walk_state->implicit_return_obj) {
+ /*
+ * Delete any "stale" implicit return. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Removing reference on stale implicit return obj %p\n",
+ walk_state->implicit_return_obj));
+
+ acpi_ut_remove_reference (walk_state->implicit_return_obj);
+ walk_state->implicit_return_obj = NULL;
+ }
+}
+
+
#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
*
+ * FUNCTION: acpi_ds_do_implicit_return
+ *
+ * PARAMETERS: return_desc - The return value
+ * walk_state - Current State
+ * add_reference - True if a reference should be added to the
+ * return object
+ *
+ * RETURN: TRUE if implicit return enabled, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the optional "implicit return". We save the result
+ * of every ASL operator and control method invocation in case the
+ * parent method exit. Before storing a new return value, we
+ * delete the previous return value.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ds_do_implicit_return (
+ union acpi_operand_object *return_desc,
+ struct acpi_walk_state *walk_state,
+ u8 add_reference)
+{
+ ACPI_FUNCTION_NAME ("ds_do_implicit_return");
+
+
+ /*
+ * Slack must be enabled for this feature, and we must
+ * have a valid return object
+ */
+ if ((!acpi_gbl_enable_interpreter_slack) ||
+ (!return_desc)) {
+ return (FALSE);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result %p will be implicitly returned; Prev=%p\n",
+ return_desc,
+ walk_state->implicit_return_obj));
+
+ /*
+ * Delete any "stale" implicit return value first. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels, so we don't clear the value if it
+ * is the same as the return_desc.
+ */
+ if (walk_state->implicit_return_obj) {
+ if (walk_state->implicit_return_obj == return_desc) {
+ return (TRUE);
+ }
+ acpi_ds_clear_implicit_return (walk_state);
+ }
+
+ /* Save the implicit return value, add a reference if requested */
+
+ walk_state->implicit_return_obj = return_desc;
+ if (add_reference) {
+ acpi_ut_add_reference (return_desc);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ds_is_result_used
*
* PARAMETERS: Op - Current Op
@@ -76,7 +186,6 @@ acpi_ds_is_result_used (
{
const struct acpi_opcode_info *parent_info;
-
ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
@@ -88,6 +197,19 @@ acpi_ds_is_result_used (
}
/*
+ * We know that this operator is not a
+ * Return() operator (would not come here.) The following code is the
+ * optional support for a so-called "implicit return". Some AML code
+ * assumes that the last value of the method is "implicitly" returned
+ * to the caller. Just save the last result as the return value.
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
+ */
+ acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+
+ /*
+ * Now determine if the parent will use the result
+ *
* If there is no parent, or the parent is a scope_op, we are executing
* at the method level. An executing method typically has no parent,
* since each method is parsed separately. A method invoked externally
@@ -95,29 +217,10 @@ acpi_ds_is_result_used (
*/
if ((!op->common.parent) ||
(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
- /*
- * If this is the last statement in the method, we know it is not a
- * Return() operator (would not come here.) The following code is the
- * optional support for a so-called "implicit return". Some AML code
- * assumes that the last value of the method is "implicitly" returned
- * to the caller. Just save the last result as the return value.
- * NOTE: this is optional because the ASL language does not actually
- * support this behavior.
- */
- if ((acpi_gbl_enable_interpreter_slack) &&
- (walk_state->parser_state.aml >= walk_state->parser_state.aml_end)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Result of [%s] will be implicitly returned\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode)));
-
- /* Use the top of the result stack as the implicit return value */
-
- walk_state->return_desc = walk_state->results->results.obj_desc[0];
- return_VALUE (TRUE);
- }
-
/* No parent, the return value cannot possibly be used */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
+ acpi_ps_get_opcode_name (op->common.aml_opcode)));
return_VALUE (FALSE);
}
@@ -262,9 +365,8 @@ acpi_ds_delete_result_if_not_used (
}
if (!acpi_ds_is_result_used (op, walk_state)) {
- /*
- * Must pop the result stack (obj_desc should be equal to result_obj)
- */
+ /* Must pop the result stack (obj_desc should be equal to result_obj) */
+
status = acpi_ds_result_pop (&obj_desc, walk_state);
if (ACPI_SUCCESS (status)) {
acpi_ut_remove_reference (result_obj);
@@ -338,9 +440,8 @@ acpi_ds_clear_operands (
ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
- /*
- * Remove a reference on each operand on the stack
- */
+ /* Remove a reference on each operand on the stack */
+
for (i = 0; i < walk_state->num_operands; i++) {
/*
* Remove a reference to all operands, including both
@@ -407,11 +508,7 @@ acpi_ds_create_operand (
return_ACPI_STATUS (status);
}
- /*
- * All prefixes have been handled, and the name is
- * in name_string
- */
-
+ /* All prefixes have been handled, and the name is in name_string */
/*
* Special handling for buffer_field declarations. This is a deferred
@@ -586,7 +683,8 @@ acpi_ds_create_operand (
*
* FUNCTION: acpi_ds_create_operands
*
- * PARAMETERS: first_arg - First argument of a parser argument tree
+ * PARAMETERS: walk_state - Current state
+ * first_arg - First argument of a parser argument tree
*
* RETURN: Status
*
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b02322e213..2071a0d2bb 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -91,6 +91,7 @@ acpi_ds_get_predicate_value (
union acpi_operand_object *result_obj) {
acpi_status status = AE_OK;
union acpi_operand_object *obj_desc;
+ union acpi_operand_object *local_obj_desc = NULL;
ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
@@ -130,12 +131,17 @@ acpi_ds_get_predicate_value (
}
/*
- * Result of predicate evaluation currently must
- * be a number
+ * Result of predicate evaluation must be an Integer
+ * object. Implicitly convert the argument if necessary.
*/
- if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
+ status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
+ if (ACPI_FAILURE (status)) {
+ goto cleanup;
+ }
+
+ if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Bad predicate (not a number) obj_desc=%p State=%p Type=%X\n",
+ "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
status = AE_AML_OPERAND_TYPE;
@@ -144,13 +150,13 @@ acpi_ds_get_predicate_value (
/* Truncate the predicate to 32-bits if necessary */
- acpi_ex_truncate_for32bit_table (obj_desc);
+ acpi_ex_truncate_for32bit_table (local_obj_desc);
/*
* Save the result of the predicate evaluation on
* the control stack
*/
- if (obj_desc->integer.value) {
+ if (local_obj_desc->integer.value) {
walk_state->control_state->common.value = TRUE;
}
else {
@@ -170,12 +176,15 @@ cleanup:
/* Break to debugger to display result */
- ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state));
+ ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
/*
* Delete the predicate result object (we know that
* we don't need it anymore)
*/
+ if (local_obj_desc != obj_desc) {
+ acpi_ut_remove_reference (local_obj_desc);
+ }
acpi_ut_remove_reference (obj_desc);
walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
@@ -306,9 +315,10 @@ acpi_ds_exec_begin_op (
case AML_CLASS_EXECUTE:
case AML_CLASS_CREATE:
- /* most operators with arguments */
- /* Start a new result/operand state */
-
+ /*
+ * Most operators with arguments.
+ * Start a new result/operand state
+ */
status = acpi_ds_result_stack_push (walk_state);
break;
@@ -471,20 +481,41 @@ acpi_ds_exec_end_op (
/* 1 Operand, 0 external_result, 0 internal_result */
status = acpi_ds_exec_end_control_op (walk_state, op);
- if (ACPI_FAILURE (status)) {
- break;
- }
- status = acpi_ds_result_stack_pop (walk_state);
+ /* Make sure to properly pop the result stack */
+
+ if (ACPI_SUCCESS (status)) {
+ status = acpi_ds_result_stack_pop (walk_state);
+ }
+ else if (status == AE_CTRL_PENDING) {
+ status = acpi_ds_result_stack_pop (walk_state);
+ if (ACPI_SUCCESS (status)) {
+ status = AE_CTRL_PENDING;
+ }
+ }
break;
case AML_TYPE_METHOD_CALL:
+ /*
+ * If the method is referenced from within a package
+ * declaration, it is not a invocation of the method, just
+ * a reference to it.
+ */
+ if ((op->asl.parent) &&
+ ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
+ (op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
+ op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
+ acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
+ return_ACPI_STATUS (AE_OK);
+ }
+
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
/*
- * (AML_METHODCALL) Op->Value->Arg->Node contains
+ * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
* the method Node pointer
*/
/* next_op points to the op that holds the method name */
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8d4219388c..fdf143b405 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -514,7 +514,7 @@ out:
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_ec_dir;
+static struct proc_dir_entry *acpi_ec_dir;
static int
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index a48820152c..0bfec10a5f 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -149,7 +149,9 @@ acpi_install_fixed_event_handler (
acpi_gbl_fixed_event_handlers[event].handler = handler;
acpi_gbl_fixed_event_handlers[event].context = context;
- status = acpi_enable_event (event, 0);
+ status = acpi_clear_event (event);
+ if (ACPI_SUCCESS(status))
+ status = acpi_enable_event (event, 0);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index fc54d4d0cc..b542dcd58c 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -95,6 +95,7 @@ acpi_ex_get_object_reference (
switch (obj_desc->reference.opcode) {
case AML_LOCAL_OP:
case AML_ARG_OP:
+ case AML_DEBUG_OP:
/* The referenced object is the pseudo-node for the local/arg */
@@ -103,7 +104,7 @@ acpi_ex_get_object_reference (
default:
- ACPI_REPORT_ERROR (("Unknown Reference subtype in get ref %X\n",
+ ACPI_REPORT_ERROR (("Unknown Reference opcode in get_reference %X\n",
obj_desc->reference.opcode));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -121,7 +122,7 @@ acpi_ex_get_object_reference (
default:
- ACPI_REPORT_ERROR (("Invalid descriptor type in get ref: %X\n",
+ ACPI_REPORT_ERROR (("Invalid descriptor type in get_reference: %X\n",
ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
return_ACPI_STATUS (AE_TYPE);
}
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 23964e70a8..8be4d80cee 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -442,6 +442,12 @@ acpi_ex_opcode_2A_1T_1R (
return_desc->reference.object = operand[0];
}
+ /*
+ * Add a reference to the target package/buffer/string for the life
+ * of the index.
+ */
+ acpi_ut_add_reference (operand[0]);
+
/* Complete the Index reference object */
return_desc->reference.opcode = AML_INDEX_OP;
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 9cccf8299d..7be6049111 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -422,6 +422,12 @@ acpi_ex_resolve_multiple (
* This could of course in turn be another reference object.
*/
obj_desc = *(obj_desc->reference.where);
+ if (!obj_desc) {
+ /* NULL package elements are allowed */
+
+ type = 0; /* Uninitialized */
+ goto exit;
+ }
break;
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index e663a48f8a..d3677feb07 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -206,7 +206,6 @@ acpi_ex_store_object_to_object (
{
union acpi_operand_object *actual_src_desc;
acpi_status status = AE_OK;
- acpi_object_type original_src_type;
ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
@@ -223,8 +222,7 @@ acpi_ex_store_object_to_object (
return_ACPI_STATUS (status);
}
- original_src_type = ACPI_GET_OBJECT_TYPE (source_desc);
- if (original_src_type != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -275,8 +273,7 @@ acpi_ex_store_object_to_object (
* Note: There is different store behavior depending on the original
* source type
*/
- status = acpi_ex_store_buffer_to_buffer (original_src_type, actual_src_desc,
- dest_desc);
+ status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
break;
case ACPI_TYPE_PACKAGE:
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 4e2b442ee5..05e1ecae8d 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -66,7 +66,6 @@
acpi_status
acpi_ex_store_buffer_to_buffer (
- acpi_object_type original_src_type,
union acpi_operand_object *source_desc,
union acpi_operand_object *target_desc)
{
@@ -77,9 +76,8 @@ acpi_ex_store_buffer_to_buffer (
ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);
- /*
- * We know that source_desc is a buffer by now
- */
+ /* We know that source_desc is a buffer by now */
+
buffer = (u8 *) source_desc->buffer.pointer;
length = source_desc->buffer.length;
@@ -105,7 +103,17 @@ acpi_ex_store_buffer_to_buffer (
ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
+#ifdef ACPI_OBSOLETE_BEHAVIOR
+ /*
+ * NOTE: ACPI versions up to 3.0 specified that the buffer must be
+ * truncated if the string is smaller than the buffer. However, "other"
+ * implementations of ACPI never did this and thus became the defacto
+ * standard. ACPi 3.0_a changes this behavior such that the buffer
+ * is no longer truncated.
+ */
+
/*
+ * OBSOLETE BEHAVIOR:
* If the original source was a string, we must truncate the buffer,
* according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
* copy must not truncate the original buffer.
@@ -115,6 +123,7 @@ acpi_ex_store_buffer_to_buffer (
target_desc->buffer.length = length;
}
+#endif
}
else {
/* Truncate the source, copy only what will fit */
@@ -159,9 +168,8 @@ acpi_ex_store_string_to_string (
ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);
- /*
- * We know that source_desc is a string by now.
- */
+ /* We know that source_desc is a string by now */
+
buffer = (u8 *) source_desc->string.pointer;
length = source_desc->string.length;
@@ -185,9 +193,8 @@ acpi_ex_store_string_to_string (
*/
if (target_desc->string.pointer &&
(!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
- /*
- * Only free if not a pointer into the DSDT
- */
+ /* Only free if not a pointer into the DSDT */
+
ACPI_MEM_FREE (target_desc->string.pointer);
}
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 2c5422dfec..14192ee55f 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -50,8 +50,8 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
MODULE_LICENSE("GPL");
-int acpi_fan_add (struct acpi_device *device);
-int acpi_fan_remove (struct acpi_device *device, int type);
+static int acpi_fan_add (struct acpi_device *device);
+static int acpi_fan_remove (struct acpi_device *device, int type);
static struct acpi_driver acpi_fan_driver = {
.name = ACPI_FAN_DRIVER_NAME,
@@ -72,27 +72,24 @@ struct acpi_fan {
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_fan_dir;
+static struct proc_dir_entry *acpi_fan_dir;
static int
acpi_fan_read_state (struct seq_file *seq, void *offset)
{
- struct acpi_fan *fan = (struct acpi_fan *) seq->private;
+ struct acpi_fan *fan = seq->private;
int state = 0;
ACPI_FUNCTION_TRACE("acpi_fan_read_state");
- if (!fan)
- goto end;
-
- if (acpi_bus_get_power(fan->handle, &state))
- goto end;
-
- seq_printf(seq, "status: %s\n",
- !state?"on":"off");
-
-end:
+ if (fan) {
+ if (acpi_bus_get_power(fan->handle, &state))
+ seq_printf(seq, "status: ERROR\n");
+ else
+ seq_printf(seq, "status: %s\n",
+ !state?"on":"off");
+ }
return_VALUE(0);
}
@@ -197,7 +194,7 @@ acpi_fan_remove_fs (
Driver Interface
-------------------------------------------------------------------------- */
-int
+static int
acpi_fan_add (
struct acpi_device *device)
{
@@ -243,7 +240,7 @@ end:
}
-int
+static int
acpi_fan_remove (
struct acpi_device *device,
int type)
@@ -265,7 +262,7 @@ acpi_fan_remove (
}
-int __init
+static int __init
acpi_fan_init (void)
{
int result = 0;
@@ -287,7 +284,7 @@ acpi_fan_init (void)
}
-void __exit
+static void __exit
acpi_fan_exit (void)
{
ACPI_FUNCTION_TRACE("acpi_fan_exit");
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 94a76e520e..0fb731a470 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -155,7 +155,7 @@ struct ibm_struct {
int experimental;
};
-struct proc_dir_entry *proc_dir = NULL;
+static struct proc_dir_entry *proc_dir = NULL;
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -856,7 +856,7 @@ static int beep_write(struct ibm_struct *ibm, char *buf)
return 0;
}
-struct ibm_struct ibms[] = {
+static struct ibm_struct ibms[] = {
{
.name = "driver",
.init = driver_init,
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 9bfce46cd4..a82834b327 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -170,7 +170,7 @@ acpi_table_parse_srat (
int __init
-acpi_numa_init()
+acpi_numa_init(void)
{
int result;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 94a511315c..5a9128de62 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -563,7 +563,7 @@ acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integ
}
/* TODO: Change code to take advantage of driver model more */
-void
+static void
acpi_os_derive_pci_id_2 (
acpi_handle rhandle, /* upper bound */
acpi_handle chandle, /* current node */
@@ -1071,7 +1071,7 @@ acpi_os_signal (
}
EXPORT_SYMBOL(acpi_os_signal);
-int __init
+static int __init
acpi_os_name_setup(char *str)
{
char *p = acpi_os_name;
@@ -1101,7 +1101,7 @@ __setup("acpi_os_name=", acpi_os_name_setup);
* empty string disables _OSI
* TBD additional string adds to _OSI
*/
-int __init
+static int __init
acpi_osi_setup(char *str)
{
if (str == NULL || *str == '\0') {
@@ -1119,7 +1119,7 @@ acpi_osi_setup(char *str)
__setup("acpi_osi=", acpi_osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
-int __init
+static int __init
acpi_serialize_setup(char *str)
{
printk(KERN_INFO PREFIX "serialize enabled\n");
@@ -1140,7 +1140,7 @@ __setup("acpi_serialize", acpi_serialize_setup);
* Run-time events on the same GPE this flag is available
* to tell Linux to keep the wake-time GPEs enabled at run-time.
*/
-int __init
+static int __init
acpi_wake_gpes_always_on_setup(char *str)
{
printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index c1360fc23c..03e33fedc1 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -522,7 +522,7 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
/* 2E */ ACPI_OP ("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
/* 2F */ ACPI_OP ("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R),
/* 30 */ ACPI_OP ("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
-/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 31 */ ACPI_OP ("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R, AML_FLAGS_EXEC_2A_1T_1R),
/* 32 */ ACPI_OP ("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
/* 33 */ ACPI_OP ("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
/* 34 */ ACPI_OP ("CreateWordField", ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index fd2751f512..e79edb53cb 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -1187,8 +1187,8 @@ acpi_ps_parse_aml (
previous_walk_state = walk_state;
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, State=%p\n",
- walk_state->return_desc, walk_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n",
+ walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
/* Check if we have restarted a preempted walk */
@@ -1200,8 +1200,20 @@ acpi_ps_parse_aml (
* If the method return value is not used by the parent,
* The object is deleted
*/
- status = acpi_ds_restart_control_method (walk_state,
- previous_walk_state->return_desc);
+ if (!previous_walk_state->return_desc) {
+ status = acpi_ds_restart_control_method (walk_state,
+ previous_walk_state->implicit_return_obj);
+ }
+ else {
+ /*
+ * We have a valid return value, delete any implicit
+ * return value.
+ */
+ acpi_ds_clear_implicit_return (previous_walk_state);
+
+ status = acpi_ds_restart_control_method (walk_state,
+ previous_walk_state->return_desc);
+ }
if (ACPI_SUCCESS (status)) {
walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;
}
@@ -1218,12 +1230,26 @@ acpi_ps_parse_aml (
* value (if any)
*/
else if (previous_walk_state->caller_return_desc) {
- *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */
+ if (previous_walk_state->implicit_return_obj) {
+ *(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj;
+ }
+ else {
+ /* NULL if no return value */
+
+ *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc;
+ }
}
- else if (previous_walk_state->return_desc) {
- /* Caller doesn't want it, must delete it */
+ else {
+ if (previous_walk_state->return_desc) {
+ /* Caller doesn't want it, must delete it */
- acpi_ut_remove_reference (previous_walk_state->return_desc);
+ acpi_ut_remove_reference (previous_walk_state->return_desc);
+ }
+ if (previous_walk_state->implicit_return_obj) {
+ /* Caller doesn't want it, must delete it */
+
+ acpi_ut_remove_reference (previous_walk_state->implicit_return_obj);
+ }
}
acpi_ds_delete_walk_state (previous_walk_state);
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index e04b1b7360..110d2ce917 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -44,7 +44,6 @@
#include <acpi/acpi.h>
#include <acpi/acparser.h>
-#include <acpi/acdispat.h>
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("pswalk")
@@ -52,256 +51,65 @@
/*******************************************************************************
*
- * FUNCTION: acpi_ps_get_next_walk_op
+ * FUNCTION: acpi_ps_delete_parse_tree
*
- * PARAMETERS: walk_state - Current state of the walk
- * Op - Current Op to be walked
- * ascending_callback - Procedure called when Op is complete
+ * PARAMETERS: subtree_root - Root of tree (or subtree) to delete
*
- * RETURN: Status
+ * RETURN: None
*
- * DESCRIPTION: Get the next Op in a walk of the parse tree.
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
*
******************************************************************************/
-acpi_status
-acpi_ps_get_next_walk_op (
- struct acpi_walk_state *walk_state,
- union acpi_parse_object *op,
- acpi_parse_upwards ascending_callback)
+void
+acpi_ps_delete_parse_tree (
+ union acpi_parse_object *subtree_root)
{
- union acpi_parse_object *next;
- union acpi_parse_object *parent;
- union acpi_parse_object *grand_parent;
- acpi_status status;
+ union acpi_parse_object *op = subtree_root;
+ union acpi_parse_object *next = NULL;
+ union acpi_parse_object *parent = NULL;
- ACPI_FUNCTION_TRACE_PTR ("ps_get_next_walk_op", op);
+ ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
- /* Check for a argument only if we are descending in the tree */
+ /* Visit all nodes in the subtree */
- if (walk_state->next_op_info != ACPI_NEXT_OP_UPWARD) {
- /* Look for an argument or child of the current op */
+ while (op) {
+ /* Check if we are not ascending */
- next = acpi_ps_get_arg (op, 0);
- if (next) {
- /* Still going downward in tree (Op is not completed yet) */
+ if (op != parent) {
+ /* Look for an argument or child of the current op */
- walk_state->prev_op = op;
- walk_state->next_op = next;
- walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
+ next = acpi_ps_get_arg (op, 0);
+ if (next) {
+ /* Still going downward in tree (Op is not completed yet) */
- return_ACPI_STATUS (AE_OK);
+ op = next;
+ continue;
+ }
}
/*
- * No more children, this Op is complete. Save Next and Parent
- * in case the Op object gets deleted by the callback routine
+ * No more children, this Op is complete.
*/
- next = op->common.next;
- parent = op->common.parent;
-
- walk_state->op = op;
- walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
- walk_state->opcode = op->common.aml_opcode;
+ next = op->common.next;
+ parent = op->common.parent;
- status = ascending_callback (walk_state);
+ acpi_ps_free_op (op);
/*
* If we are back to the starting point, the walk is complete.
*/
- if (op == walk_state->origin) {
- /* Reached the point of origin, the walk is complete */
-
- walk_state->prev_op = op;
- walk_state->next_op = NULL;
-
- return_ACPI_STATUS (status);
+ if (op == subtree_root) {
+ return_VOID;
}
-
- /*
- * Check for a sibling to the current op. A sibling means
- * we are still going "downward" in the tree.
- */
if (next) {
- /* There is a sibling, it will be next */
-
- walk_state->prev_op = op;
- walk_state->next_op = next;
- walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
- /* Continue downward */
-
- return_ACPI_STATUS (status);
+ op = next;
}
-
- /*
- * Drop into the loop below because we are moving upwards in
- * the tree
- */
- }
- else {
- /*
- * We are resuming a walk, and we were (are) going upward in the tree.
- * So, we want to drop into the parent loop below.
- */
- parent = op;
- }
-
- /*
- * Look for a sibling of the current Op's parent
- * Continue moving up the tree until we find a node that has not been
- * visited, or we get back to where we started.
- */
- while (parent) {
- /* We are moving up the tree, therefore this parent Op is complete */
-
- grand_parent = parent->common.parent;
- next = parent->common.next;
-
- walk_state->op = parent;
- walk_state->op_info = acpi_ps_get_opcode_info (parent->common.aml_opcode);
- walk_state->opcode = parent->common.aml_opcode;
-
- status = ascending_callback (walk_state);
-
- /*
- * If we are back to the starting point, the walk is complete.
- */
- if (parent == walk_state->origin) {
- /* Reached the point of origin, the walk is complete */
-
- walk_state->prev_op = parent;
- walk_state->next_op = NULL;
-
- return_ACPI_STATUS (status);
- }
-
- /*
- * If there is a sibling to this parent (it is not the starting point
- * Op), then we will visit it.
- */
- if (next) {
- /* found sibling of parent */
-
- walk_state->prev_op = parent;
- walk_state->next_op = next;
- walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
- return_ACPI_STATUS (status);
+ else {
+ op = parent;
}
-
- /* No siblings, no errors, just move up one more level in the tree */
-
- op = parent;
- parent = grand_parent;
- walk_state->prev_op = op;
}
-
-
- /*
- * Got all the way to the top of the tree, we must be done!
- * However, the code should have terminated in the loop above
- */
- walk_state->next_op = NULL;
-
- return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ps_delete_completed_op
- *
- * PARAMETERS: State - Walk state
- * Op - Completed op
- *
- * RETURN: AE_OK
- *
- * DESCRIPTION: Callback function for acpi_ps_get_next_walk_op(). Used during
- * acpi_ps_delete_parse tree to delete Op objects when all sub-objects
- * have been visited (and deleted.)
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ps_delete_completed_op (
- struct acpi_walk_state *walk_state)
-{
-
- acpi_ps_free_op (walk_state->op);
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ps_delete_parse_tree
- *
- * PARAMETERS: subtree_root - Root of tree (or subtree) to delete
- *
- * RETURN: None
- *
- * DESCRIPTION: Delete a portion of or an entire parse tree.
- *
- ******************************************************************************/
-
-void
-acpi_ps_delete_parse_tree (
- union acpi_parse_object *subtree_root)
-{
- struct acpi_walk_state *walk_state;
- struct acpi_thread_state *thread;
- acpi_status status;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
-
-
- if (!subtree_root) {
- return_VOID;
- }
-
- /* Create and initialize a new walk list */
-
- thread = acpi_ut_create_thread_state ();
- if (!thread) {
- return_VOID;
- }
-
- walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
- if (!walk_state) {
- return_VOID;
- }
-
- walk_state->parse_flags = 0;
- walk_state->descending_callback = NULL;
- walk_state->ascending_callback = NULL;
-
- walk_state->origin = subtree_root;
- walk_state->next_op = subtree_root;
-
- /* Head downward in the tree */
-
- walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
- /* Visit all nodes in the subtree */
-
- while (walk_state->next_op) {
- status = acpi_ps_get_next_walk_op (walk_state, walk_state->next_op,
- acpi_ps_delete_completed_op);
- if (ACPI_FAILURE (status)) {
- break;
- }
- }
-
- /* We are done with this walk */
-
- acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));
- acpi_ds_delete_walk_state (walk_state);
-
return_VOID;
}
-
-
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index a4750192a3..12b0eea634 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -42,8 +42,8 @@
#define _COMPONENT ACPI_PCI_COMPONENT
ACPI_MODULE_NAME ("pci_irq")
-struct acpi_prt_list acpi_prt;
-DEFINE_SPINLOCK(acpi_prt_lock);
+static struct acpi_prt_list acpi_prt;
+static DEFINE_SPINLOCK(acpi_prt_lock);
/* --------------------------------------------------------------------------
PCI IRQ Routing Table (PRT) Support
@@ -281,7 +281,8 @@ acpi_pci_irq_lookup (
int device,
int pin,
int *edge_level,
- int *active_high_low)
+ int *active_high_low,
+ char **link)
{
struct acpi_prt_entry *entry = NULL;
int segment = pci_domain_nr(bus);
@@ -301,7 +302,8 @@ acpi_pci_irq_lookup (
}
if (entry->link.handle) {
- irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low);
+ irq = acpi_pci_link_get_irq(entry->link.handle,
+ entry->link.index, edge_level, active_high_low, link);
if (irq < 0) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
return_VALUE(-1);
@@ -327,7 +329,8 @@ acpi_pci_irq_derive (
struct pci_dev *dev,
int pin,
int *edge_level,
- int *active_high_low)
+ int *active_high_low,
+ char **link)
{
struct pci_dev *bridge = dev;
int irq = -1;
@@ -360,7 +363,7 @@ acpi_pci_irq_derive (
}
irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
- pin, edge_level, active_high_low);
+ pin, edge_level, active_high_low, link);
}
if (irq < 0) {
@@ -389,6 +392,7 @@ acpi_pci_irq_enable (
int edge_level = ACPI_LEVEL_SENSITIVE;
int active_high_low = ACPI_ACTIVE_LOW;
extern int via_interrupt_line_quirk;
+ char *link = NULL;
ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
@@ -411,21 +415,23 @@ acpi_pci_irq_enable (
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assigned IRQs set during boot.
*/
- irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low);
+ irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+ &edge_level, &active_high_low, &link);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if (irq < 0)
- irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low);
+ irq = acpi_pci_irq_derive(dev, pin, &edge_level,
+ &active_high_low, &link);
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
* driver reported one, then use it. Exit in any case.
*/
if (irq < 0) {
- printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
+ printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
pci_name(dev), ('A' + pin));
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq >= 0 && (dev->irq <= 0xF)) {
@@ -443,9 +449,13 @@ acpi_pci_irq_enable (
dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
- printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
- "(%s, %s) -> IRQ %d\n",
- pci_name(dev), 'A' + pin, irq,
+ printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
+ pci_name(dev), 'A' + pin);
+
+ if (link)
+ printk("Link [%s] -> ", link);
+
+ printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
(edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
(active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
dev->irq);
@@ -482,14 +492,14 @@ acpi_pci_irq_disable (
* First we check the PCI IRQ routing table (PRT) for an IRQ.
*/
gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
- &edge_level, &active_high_low);
+ &edge_level, &active_high_low, NULL);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if (gsi < 0)
gsi = acpi_pci_irq_derive(dev, pin,
- &edge_level, &active_high_low);
+ &edge_level, &active_high_low, NULL);
if (gsi < 0)
return_VOID;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 3191b5ff10..520b28ad07 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -522,9 +522,11 @@ acpi_irq_penalty_init(void)
static int acpi_irq_balance; /* 0: static, 1: balance */
-static int acpi_pci_link_allocate(struct acpi_pci_link* link) {
- int irq;
- int i;
+static int acpi_pci_link_allocate(
+ struct acpi_pci_link *link)
+{
+ int irq;
+ int i;
ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
@@ -597,8 +599,9 @@ int
acpi_pci_link_get_irq (
acpi_handle handle,
int index,
- int* edge_level,
- int* active_high_low)
+ int *edge_level,
+ int *active_high_low,
+ char **name)
{
int result = 0;
struct acpi_device *device = NULL;
@@ -634,6 +637,7 @@ acpi_pci_link_get_irq (
if (edge_level) *edge_level = link->irq.edge_level;
if (active_high_low) *active_high_low = link->irq.active_high_low;
+ if (name) *name = acpi_device_bid(link->device);
return_VALUE(link->irq.active);
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 2adaba68b8..7e6b8e3b2e 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -258,7 +258,7 @@ acpi_pci_root_add (
/* TBD: Locking */
list_add_tail(&root->node, &acpi_pci_roots);
- printk(KERN_INFO PREFIX "%s [%s] (%02x:%02x)\n",
+ printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
acpi_device_name(device), acpi_device_bid(device),
root->id.segment, root->id.bus);
@@ -272,7 +272,7 @@ acpi_pci_root_add (
root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
if (!root->bus) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Bus %02x:%02x not present in PCI namespace\n",
+ "Bus %04x:%02x not present in PCI namespace\n",
root->id.segment, root->id.bus));
result = -ENODEV;
goto end;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 419b371d95..373a3a95bb 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -58,8 +58,8 @@ ACPI_MODULE_NAME ("acpi_power")
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-int acpi_power_add (struct acpi_device *device);
-int acpi_power_remove (struct acpi_device *device, int type);
+static int acpi_power_add (struct acpi_device *device);
+static int acpi_power_remove (struct acpi_device *device, int type);
static int acpi_power_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_power_driver = {
@@ -479,7 +479,7 @@ end:
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_power_dir;
+static struct proc_dir_entry *acpi_power_dir;
static int acpi_power_seq_show(struct seq_file *seq, void *offset)
{
@@ -576,7 +576,7 @@ acpi_power_remove_fs (
Driver Interface
-------------------------------------------------------------------------- */
-int
+static int
acpi_power_add (
struct acpi_device *device)
{
@@ -642,7 +642,7 @@ end:
}
-int
+static int
acpi_power_remove (
struct acpi_device *device,
int type)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e517a11dc9..f4778747e8 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -105,7 +105,7 @@ static struct acpi_driver acpi_processor_driver = {
#define UNINSTALL_NOTIFY_HANDLER 2
-struct file_operations acpi_processor_info_fops = {
+static struct file_operations acpi_processor_info_fops = {
.open = acpi_processor_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -121,7 +121,7 @@ struct acpi_processor_errata errata;
Errata Handling
-------------------------------------------------------------------------- */
-int
+static int
acpi_processor_errata_piix4 (
struct pci_dev *dev)
{
@@ -259,7 +259,7 @@ acpi_processor_errata (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_processor_dir = NULL;
+static struct proc_dir_entry *acpi_processor_dir = NULL;
static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
{
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 8711236d28..12bd980a12 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -345,7 +345,7 @@ end:
return_VALUE(0);
}
-int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
+static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_limit_seq_show,
PDE(inode)->data);
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index db0b31d2b3..be9f569d39 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -308,7 +308,7 @@ end:
return_VALUE(0);
}
-int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
+static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_throttling_seq_show,
PDE(inode)->data);
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index ec4ae9a15c..4788c07973 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -110,13 +110,13 @@ acpi_rs_address16_resource (
buffer += 2;
temp8 = *buffer;
- /* Values 0-2 are valid */
+ /* Values 0-2 and 0xC0-0xFF are valid */
- if (temp8 > 2) {
+ if ((temp8 > 2) && (temp8 < 0xC0)) {
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
}
- output_struct->data.address16.resource_type = temp8 & 0x03;
+ output_struct->data.address16.resource_type = temp8;
/*
* Get the General Flags (Byte4)
@@ -496,12 +496,13 @@ acpi_rs_address32_resource (
buffer += 2;
temp8 = *buffer;
- /* Values 0-2 are valid */
- if(temp8 > 2) {
+ /* Values 0-2 and 0xC0-0xFF are valid */
+
+ if ((temp8 > 2) && (temp8 < 0xC0)) {
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
}
- output_struct->data.address32.resource_type = temp8 & 0x03;
+ output_struct->data.address32.resource_type = temp8;
/*
* Get the General Flags (Byte4)
@@ -850,6 +851,7 @@ acpi_rs_address64_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16;
u8 temp8;
+ u8 resource_type;
u8 *temp_ptr;
acpi_size struct_size;
u32 index;
@@ -860,6 +862,7 @@ acpi_rs_address64_resource (
buffer = byte_stream_buffer;
struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+ resource_type = *buffer;
/*
* Point past the Descriptor to get the number of bytes consumed
@@ -882,13 +885,13 @@ acpi_rs_address64_resource (
buffer += 2;
temp8 = *buffer;
- /* Values 0-2 are valid */
+ /* Values 0-2 and 0xC0-0xFF are valid */
- if(temp8 > 2) {
+ if ((temp8 > 2) && (temp8 < 0xC0)) {
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
}
- output_struct->data.address64.resource_type = temp8 & 0x03;
+ output_struct->data.address64.resource_type = temp8;
/*
* Get the General Flags (Byte4)
@@ -942,98 +945,113 @@ acpi_rs_address64_resource (
}
}
+ if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+ /* Move past revision_id and Reserved byte */
+
+ buffer += 2;
+ }
+
/*
- * Get Granularity (Bytes 6-13)
+ * Get Granularity (Bytes 6-13) or (Bytes 8-15)
*/
buffer += 1;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
/*
- * Get min_address_range (Bytes 14-21)
+ * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
*/
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
/*
- * Get max_address_range (Bytes 22-29)
+ * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
*/
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
/*
- * Get address_translation_offset (Bytes 30-37)
+ * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
*/
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
/*
- * Get address_length (Bytes 38-45)
+ * Get address_length (Bytes 38-45) or (Bytes 40-47)
*/
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
- /*
- * Resource Source Index (if present)
- */
- buffer += 8;
+ output_struct->data.address64.resource_source.index = 0x00;
+ output_struct->data.address64.resource_source.string_length = 0;
+ output_struct->data.address64.resource_source.string_ptr = NULL;
- /*
- * This will leave us pointing to the Resource Source Index
- * If it is present, then save it off and calculate the
- * pointer to where the null terminated string goes:
- * Each Interrupt takes 32-bits + the 5 bytes of the
- * stream that are default.
- *
- * Note: Some resource descriptors will have an additional null, so
- * we add 1 to the length.
- */
- if (*bytes_consumed > (46 + 1)) {
- /* Dereference the Index */
+ if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+ /* Get type_specific_attribute (Bytes 48-55) */
- temp8 = *buffer;
- output_struct->data.address64.resource_source.index =
- (u32) temp8;
+ buffer += 8;
+ ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer);
+ }
+ else {
+ output_struct->data.address64.type_specific_attributes = 0;
- /* Point to the String */
+ /*
+ * Resource Source Index (if present)
+ */
+ buffer += 8;
- buffer += 1;
+ /*
+ * This will leave us pointing to the Resource Source Index
+ * If it is present, then save it off and calculate the
+ * pointer to where the null terminated string goes:
+ * Each Interrupt takes 32-bits + the 5 bytes of the
+ * stream that are default.
+ *
+ * Note: Some resource descriptors will have an additional null, so
+ * we add 1 to the length.
+ */
+ if (*bytes_consumed > (46 + 1)) {
+ /* Dereference the Index */
- /* Point the String pointer to the end of this structure */
+ temp8 = *buffer;
+ output_struct->data.address64.resource_source.index =
+ (u32) temp8;
- output_struct->data.address64.resource_source.string_ptr =
- (char *)((u8 *)output_struct + struct_size);
+ /* Point to the String */
- temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
+ buffer += 1;
- /* Copy the string into the buffer */
+ /* Point the String pointer to the end of this structure */
- index = 0;
- while (0x00 != *buffer) {
- *temp_ptr = *buffer;
+ output_struct->data.address64.resource_source.string_ptr =
+ (char *)((u8 *)output_struct + struct_size);
- temp_ptr += 1;
- buffer += 1;
- index += 1;
- }
+ temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
- /*
- * Add the terminating null
- */
- *temp_ptr = 0x00;
- output_struct->data.address64.resource_source.string_length = index + 1;
+ /* Copy the string into the buffer */
- /*
- * In order for the struct_size to fall on a 32-bit boundary,
- * calculate the length of the string and expand the
- * struct_size to the next 32-bit boundary.
- */
- temp8 = (u8) (index + 1);
- struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
- }
- else {
- output_struct->data.address64.resource_source.index = 0x00;
- output_struct->data.address64.resource_source.string_length = 0;
- output_struct->data.address64.resource_source.string_ptr = NULL;
+ index = 0;
+ while (0x00 != *buffer) {
+ *temp_ptr = *buffer;
+
+ temp_ptr += 1;
+ buffer += 1;
+ index += 1;
+ }
+
+ /*
+ * Add the terminating null
+ */
+ *temp_ptr = 0x00;
+ output_struct->data.address64.resource_source.string_length = index + 1;
+
+ /*
+ * In order for the struct_size to fall on a 32-bit boundary,
+ * calculate the length of the string and expand the
+ * struct_size to the next 32-bit boundary.
+ */
+ temp8 = (u8) (index + 1);
+ struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+ }
}
/*
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 1113af7469..8a5f0a5237 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -376,6 +376,20 @@ acpi_rs_get_list_length (
break;
+ case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
+ /*
+ * 64-Bit Address Resource
+ */
+ buffer = byte_stream_buffer;
+
+ ++buffer;
+ ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+ bytes_consumed = temp16 + 3;
+ structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+ break;
+
+
case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
/*
* 64-Bit Address Resource
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index a869980f7f..eef1b1f2c6 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -571,7 +571,7 @@ acpi_rs_dump_address16 (
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
+ acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
address16_data->attribute.io.translation_attribute ?
"Sparse" : "Dense");
@@ -584,8 +584,8 @@ acpi_rs_dump_address16 (
default:
- acpi_os_printf ("Invalid resource type. Exiting.\n");
- return;
+ acpi_os_printf ("0x%2.2X\n", address16_data->resource_type);
+ break;
}
acpi_os_printf (" Resource %s\n",
@@ -718,7 +718,7 @@ acpi_rs_dump_address32 (
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
+ acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
address32_data->attribute.io.translation_attribute ?
"Sparse" : "Dense");
@@ -731,8 +731,8 @@ acpi_rs_dump_address32 (
default:
- acpi_os_printf (" Invalid Resource Type..exiting.\n");
- return;
+ acpi_os_printf (" Resource Type: 0x%2.2X\n", address32_data->resource_type);
+ break;
}
acpi_os_printf (" Resource %s\n",
@@ -865,7 +865,7 @@ acpi_rs_dump_address64 (
break;
}
- acpi_os_printf (" Type Specific: %s Translation\n",
+ acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
address64_data->attribute.io.translation_attribute ?
"Sparse" : "Dense");
@@ -878,8 +878,8 @@ acpi_rs_dump_address64 (
default:
- acpi_os_printf (" Invalid Resource Type..exiting.\n");
- return;
+ acpi_os_printf (" Resource Type: 0x%2.2X\n", address64_data->resource_type);
+ break;
}
acpi_os_printf (" Resource %s\n",
@@ -913,7 +913,10 @@ acpi_rs_dump_address64 (
acpi_os_printf (" Address Length: %8.8X%8.8X\n",
ACPI_FORMAT_UINT64 (address64_data->address_length));
- if(0xFF != address64_data->resource_source.index) {
+ acpi_os_printf (" Type Specific Attributes: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+
+ if (0xFF != address64_data->resource_source.index) {
acpi_os_printf (" Resource Source Index: %X\n",
address64_data->resource_source.index);
acpi_os_printf (" Resource Source: %s\n",
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index 1297589d79..e49c1e030f 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -178,6 +178,7 @@ acpi_rs_byte_stream_to_list (
case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
+ case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
/*
* 64-Bit Address Resource
*/
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f20d88d3c5..e7ca066265 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -27,6 +27,10 @@ static LIST_HEAD(acpi_device_list);
DEFINE_SPINLOCK(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
+static int
+acpi_bus_trim(struct acpi_device *start,
+ int rmdevice);
+
static void acpi_device_release(struct kobject * kobj)
{
struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
@@ -81,12 +85,37 @@ static struct kobj_type ktype_acpi_ns = {
.release = acpi_device_release,
};
+static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
+ char **envp, int num_envp, char *buffer,
+ int buffer_size)
+{
+ struct acpi_device *dev = to_acpi_device(kobj);
+ int i = 0;
+ int len = 0;
+
+ if (!dev->driver)
+ return 0;
+
+ if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+ "PHYSDEVDRIVER=%s", dev->driver->name))
+ return -ENOMEM;
+
+ envp[i] = NULL;
+
+ return 0;
+}
+
+static struct kset_hotplug_ops namespace_hotplug_ops = {
+ .hotplug = &namespace_hotplug,
+};
+
static struct kset acpi_namespace_kset = {
.kobj = {
.name = "namespace",
},
.subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns,
+ .hotplug_ops = &namespace_hotplug_ops,
};
@@ -358,7 +387,15 @@ setup_sys_fs_device_files (
struct acpi_device *dev,
acpi_device_sysfs_files *func)
{
- if (dev->flags.ejectable == 1)
+ acpi_status status;
+ acpi_handle temp = NULL;
+
+ /*
+ * If device has _EJ0, 'eject' file is created that is used to trigger
+ * hot-removal function from userland.
+ */
+ status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+ if (ACPI_SUCCESS(status))
(*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
}
@@ -857,7 +894,7 @@ static void acpi_device_set_id(struct acpi_device * device, struct acpi_device *
acpi_os_free(buffer.pointer);
}
-int acpi_device_set_context(struct acpi_device * device, int type)
+static int acpi_device_set_context(struct acpi_device * device, int type)
{
acpi_status status = AE_OK;
int result = 0;
@@ -882,7 +919,7 @@ int acpi_device_set_context(struct acpi_device * device, int type)
return result;
}
-void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
+static void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
{
#ifdef CONFIG_ACPI_DEBUG_OUTPUT
char *type_string = NULL;
@@ -925,7 +962,7 @@ void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle,
}
-int
+static int
acpi_bus_remove (
struct acpi_device *dev,
int rmdevice)
@@ -1223,7 +1260,7 @@ int acpi_bus_scan (struct acpi_device *start)
EXPORT_SYMBOL(acpi_bus_scan);
-int
+static int
acpi_bus_trim(struct acpi_device *start,
int rmdevice)
{
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index be97f28695..79c3a686bc 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -774,7 +774,7 @@ acpi_thermal_check (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_thermal_dir;
+static struct proc_dir_entry *acpi_thermal_dir;
static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
{
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index c0c9ea1084..c84997c9f9 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -481,7 +481,7 @@ read_version(char* p)
#define PROC_TOSHIBA "toshiba"
-ProcItem proc_items[] =
+static ProcItem proc_items[] =
{
{ "lcd" , read_lcd , write_lcd },
{ "video" , read_video , write_video },
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 0b366d3b48..0fcd98bde0 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -659,15 +659,17 @@ acpi_ut_copy_simple_object (
/* Create an actual buffer only if length > 0 */
if (source_desc->buffer.length) {
- dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+ dest_desc->buffer.pointer =
+ ACPI_MEM_ALLOCATE (source_desc->buffer.length);
if (!dest_desc->buffer.pointer) {
return (AE_NO_MEMORY);
}
/* Copy the actual buffer data */
- ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
- source_desc->buffer.length);
+ ACPI_MEMCPY (dest_desc->buffer.pointer,
+ source_desc->buffer.pointer,
+ source_desc->buffer.length);
}
}
break;
@@ -682,7 +684,8 @@ acpi_ut_copy_simple_object (
*/
if ((source_desc->string.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
- dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
+ dest_desc->string.pointer =
+ ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
if (!dest_desc->string.pointer) {
return (AE_NO_MEMORY);
}
@@ -692,6 +695,14 @@ acpi_ut_copy_simple_object (
}
break;
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ /*
+ * We copied the reference object, so we now must add a reference
+ * to the object pointed to by the reference
+ */
+ acpi_ut_add_reference (source_desc->reference.object);
+ break;
+
default:
/* Nothing to do for other simple objects */
break;
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index e8ee13280b..9a52ad52a2 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -46,6 +46,7 @@
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
+#include <acpi/amlcode.h>
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utdelete")
@@ -562,8 +563,23 @@ acpi_ut_update_object_reference (
break;
- case ACPI_TYPE_REGION:
case ACPI_TYPE_LOCAL_REFERENCE:
+
+ /*
+ * The target of an Index (a package, string, or buffer) must track
+ * changes to the ref count of the index.
+ */
+ if (object->reference.opcode == AML_INDEX_OP) {
+ status = acpi_ut_create_update_state_and_push (
+ object->reference.object, action, &state_list);
+ if (ACPI_FAILURE (status)) {
+ goto error_exit;
+ }
+ }
+ break;
+
+
+ case ACPI_TYPE_REGION:
default:
/* No subobjects */
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index d3eb4db38f..25b0f8ae1b 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -194,6 +194,8 @@ const char *acpi_gbl_highest_dstate_names[4] =
*/
const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
{
+ /* Operating System Vendor Strings */
+
"Linux",
"Windows 2000",
"Windows 2001",
@@ -202,7 +204,11 @@ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STR
"Windows 2001 SP1",
"Windows 2001 SP2",
"Windows 2001 SP3",
- "Windows 2001 SP4"
+ "Windows 2001 SP4",
+
+ /* Feature Group Strings */
+
+ "Extended Address Space Descriptor"
};
@@ -355,6 +361,7 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]
/* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS},
/* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS},
/* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS},
+ /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS},
/* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE},
/* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
@@ -362,6 +369,7 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]
/* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
/* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE},
/* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
+ /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
/* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE},
/* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD},
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 4d32f6d18f..f659854738 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -372,7 +372,7 @@ acpi_ut_strtoul64 (
u32 base,
acpi_integer *ret_integer)
{
- u32 this_digit;
+ u32 this_digit = 0;
acpi_integer return_value = 0;
acpi_integer quotient;
@@ -380,6 +380,10 @@ acpi_ut_strtoul64 (
ACPI_FUNCTION_TRACE ("ut_stroul64");
+ if ((!string) || !(*string)) {
+ goto error_exit;
+ }
+
switch (base) {
case ACPI_ANY_BASE:
case 10:
@@ -394,7 +398,7 @@ acpi_ut_strtoul64 (
/* Skip over any white space in the buffer */
while (ACPI_IS_SPACE (*string) || *string == '\t') {
- ++string;
+ string++;
}
/*
@@ -403,9 +407,9 @@ acpi_ut_strtoul64 (
*/
if (base == 0) {
if ((*string == '0') &&
- (ACPI_TOLOWER (*(++string)) == 'x')) {
+ (ACPI_TOLOWER (*(string + 1)) == 'x')) {
base = 16;
- ++string;
+ string += 2;
}
else {
base = 10;
@@ -416,10 +420,10 @@ acpi_ut_strtoul64 (
* For hexadecimal base, skip over the leading
* 0 or 0x, if they are present.
*/
- if (base == 16 &&
- *string == '0' &&
- ACPI_TOLOWER (*(++string)) == 'x') {
- string++;
+ if ((base == 16) &&
+ (*string == '0') &&
+ (ACPI_TOLOWER (*(string + 1)) == 'x')) {
+ string += 2;
}
/* Any string left? */
@@ -437,23 +441,27 @@ acpi_ut_strtoul64 (
this_digit = ((u8) *string) - '0';
}
else {
+ if (base == 10) {
+ /* Digit is out of range */
+
+ goto error_exit;
+ }
+
this_digit = (u8) ACPI_TOUPPER (*string);
- if (ACPI_IS_UPPER ((char) this_digit)) {
+ if (ACPI_IS_XDIGIT ((char) this_digit)) {
/* Convert ASCII Hex char to value */
this_digit = this_digit - 'A' + 10;
}
else {
- goto error_exit;
+ /*
+ * We allow non-hex chars, just stop now, same as end-of-string.
+ * See ACPI spec, string-to-integer conversion.
+ */
+ break;
}
}
- /* Check to see if digit is out of range */
-
- if (this_digit >= base) {
- goto error_exit;
- }
-
/* Divide the digit into the correct position */
(void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
@@ -464,9 +472,11 @@ acpi_ut_strtoul64 (
return_value *= base;
return_value += this_digit;
- ++string;
+ string++;
}
+ /* All done, normal exit */
+
*ret_integer = return_value;
return_ACPI_STATUS (AE_OK);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bd311c2076..71fa101171 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -683,7 +683,7 @@ acpi_video_bus_check (
FS Interface (/proc)
-------------------------------------------------------------------------- */
-struct proc_dir_entry *acpi_video_dir;
+static struct proc_dir_entry *acpi_video_dir;
/* video devices */
diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
index ffd87404b0..68e9e6832c 100644
--- a/drivers/i2c/algos/i2c-algo-ite.c
+++ b/drivers/i2c/algos/i2c-algo-ite.c
@@ -713,14 +713,11 @@ static u32 iic_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm iic_algo = {
- "ITE IIC algorithm",
- I2C_ALGO_IIC,
- iic_xfer, /* master_xfer */
- NULL, /* smbus_xfer */
- NULL, /* slave_xmit */
- NULL, /* slave_recv */
- algo_control, /* ioctl */
- iic_func, /* functionality */
+ .name = "ITE IIC algorithm",
+ .id = I2C_ALGO_IIC,
+ .master_xfer = iic_xfer,
+ .algo_control = algo_control, /* ioctl */
+ .functionality = iic_func,
};
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index 66e681cb33..8d087dac32 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -78,7 +78,6 @@ static void i2c_stop(struct i2c_algo_pcf_data *adap)
set_pcf(adap, 1, I2C_PCF_STOP);
}
-
static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
int timeout = DEF_TIMEOUT;
@@ -109,6 +108,26 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
adap->waitforpin();
*status = get_pcf(adap, 1);
}
+ if (*status & I2C_PCF_LAB) {
+ DEB2(printk(KERN_INFO
+ "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
+ *status));
+ /* Cleanup from LAB-- reset and enable ESO.
+ * This resets the PCF8584; since we've lost the bus, no
+ * further attempts should be made by callers to clean up
+ * (no i2c_stop() etc.)
+ */
+ set_pcf(adap, 1, I2C_PCF_PIN);
+ set_pcf(adap, 1, I2C_PCF_ESO);
+ /* TODO: we should pause for a time period sufficient for any
+ * running I2C transaction to complete-- the arbitration
+ * logic won't work properly until the next START is seen.
+ */
+ DEB2(printk(KERN_INFO
+ "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
+ get_pcf(adap,1)));
+ return(-EINTR);
+ }
#endif
if (timeout <= 0)
return(-1);
@@ -188,16 +207,22 @@ static inline int try_address(struct i2c_algo_pcf_data *adap,
unsigned char addr, int retries)
{
int i, status, ret = -1;
+ int wfp;
for (i=0;i<retries;i++) {
i2c_outb(adap, addr);
i2c_start(adap);
status = get_pcf(adap, 1);
- if (wait_for_pin(adap, &status) >= 0) {
+ if ((wfp = wait_for_pin(adap, &status)) >= 0) {
if ((status & I2C_PCF_LRB) == 0) {
i2c_stop(adap);
break; /* success! */
}
}
+ if (wfp == -EINTR) {
+ /* arbitration lost */
+ udelay(adap->udelay);
+ return -EINTR;
+ }
i2c_stop(adap);
udelay(adap->udelay);
}
@@ -219,6 +244,10 @@ static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
i2c_outb(adap, buf[wrcount]);
timeout = wait_for_pin(adap, &status);
if (timeout) {
+ if (timeout == -EINTR) {
+ /* arbitration lost */
+ return -EINTR;
+ }
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
return -EREMOTEIO; /* got a better one ?? */
@@ -247,11 +276,16 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
{
int i, status;
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
+ int wfp;
/* increment number of bytes to read by one -- read dummy byte */
for (i = 0; i <= count; i++) {
- if (wait_for_pin(adap, &status)) {
+ if ((wfp = wait_for_pin(adap, &status))) {
+ if (wfp == -EINTR) {
+ /* arbitration lost */
+ return -EINTR;
+ }
i2c_stop(adap);
dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
return (-1);
@@ -366,6 +400,10 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
/* Wait for PIN (pending interrupt NOT) */
timeout = wait_for_pin(adap, &status);
if (timeout) {
+ if (timeout == -EINTR) {
+ /* arbitration lost */
+ return (-EINTR);
+ }
i2c_stop(adap);
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
"for PIN(1) in pcf_xfer\n");)
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
index ea1a9047a3..35789bb712 100644
--- a/drivers/i2c/algos/i2c-algo-sibyte.c
+++ b/drivers/i2c/algos/i2c-algo-sibyte.c
@@ -136,14 +136,11 @@ static u32 bit_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm i2c_sibyte_algo = {
- "SiByte algorithm",
- I2C_ALGO_SIBYTE,
- NULL, /* master_xfer */
- smbus_xfer, /* smbus_xfer */
- NULL, /* slave_xmit */
- NULL, /* slave_recv */
- algo_control, /* ioctl */
- bit_func, /* functionality */
+ .name = "SiByte algorithm",
+ .id = I2C_ALGO_SIBYTE,
+ .smbus_xfer = smbus_xfer,
+ .algo_control = algo_control, /* ioctl */
+ .functionality = bit_func,
};
/*
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 34ff2ecad2..edf8051da3 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -108,7 +108,7 @@ config I2C_HYDRA
will be called i2c-hydra.
config I2C_I801
- tristate "Intel 801"
+ tristate "Intel 82801 (ICH)"
depends on I2C && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the Intel
@@ -119,7 +119,7 @@ config I2C_I801
82801BA
82801CA/CAM
82801DB
- 82801EB
+ 82801EB/ER (ICH5/ICH5R)
6300ESB
ICH6
ICH7
@@ -143,6 +143,23 @@ config I2C_I810
This driver can also be built as a module. If so, the module
will be called i2c-i810.
+config I2C_PIIX4
+ tristate "Intel PIIX4"
+ depends on I2C && PCI
+ help
+ If you say yes to this option, support will be included for the Intel
+ PIIX4 family of mainboard I2C interfaces. Specifically, the following
+ versions of the chipset are supported:
+ Intel PIIX4
+ Intel 440MX
+ Serverworks OSB4
+ Serverworks CSB5
+ Serverworks CSB6
+ SMSC Victory66
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-piix4.
+
config I2C_IBM_IIC
tristate "IBM PPC 4xx on-chip I2C interface"
depends on IBM_OCP && I2C
@@ -285,23 +302,6 @@ config I2C_PARPORT_LIGHT
This support is also available as a module. If so, the module
will be called i2c-parport-light.
-config I2C_PIIX4
- tristate "Intel PIIX4"
- depends on I2C && PCI && EXPERIMENTAL
- help
- If you say yes to this option, support will be included for the Intel
- PIIX4 family of mainboard I2C interfaces. Specifically, the following
- versions of the chipset are supported:
- Intel PIIX4
- Intel 440MX
- Serverworks OSB4
- Serverworks CSB5
- Serverworks CSB6
- SMSC Victory66
-
- This driver can also be built as a module. If so, the module
- will be called i2c-piix4.
-
config I2C_PROSAVAGE
tristate "S3/VIA (Pro)Savage"
depends on I2C && PCI && EXPERIMENTAL
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 96fc7d7290..0a7720000a 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -110,22 +110,23 @@ static int pcf_isa_getclock(void *data)
}
static void pcf_isa_waitforpin(void) {
-
+ DEFINE_WAIT(wait);
int timeout = 2;
- long flags;
+ unsigned long flags;
if (irq > 0) {
spin_lock_irqsave(&lock, flags);
if (pcf_pending == 0) {
spin_unlock_irqrestore(&lock, flags);
- if (interruptible_sleep_on_timeout(&pcf_wait,
- timeout*HZ)) {
+ prepare_to_wait(&pcf_wait, &wait, TASK_INTERRUPTIBLE);
+ if (schedule_timeout(timeout*HZ)) {
spin_lock_irqsave(&lock, flags);
if (pcf_pending == 1) {
pcf_pending = 0;
}
spin_unlock_irqrestore(&lock, flags);
}
+ finish_wait(&pcf_wait, &wait);
} else {
pcf_pending = 0;
spin_unlock_irqrestore(&lock, flags);
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 17326cdd68..bb885215c0 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -630,10 +630,6 @@ static struct i2c_algorithm iic_algo = {
.name = "IBM IIC algorithm",
.id = I2C_ALGO_OCP,
.master_xfer = iic_xfer,
- .smbus_xfer = NULL,
- .slave_send = NULL,
- .slave_recv = NULL,
- .algo_control = NULL,
.functionality = iic_func
};
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
index 62638115cf..702e3def1b 100644
--- a/drivers/i2c/busses/i2c-ite.c
+++ b/drivers/i2c/busses/i2c-ite.c
@@ -40,6 +40,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/wait.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -107,7 +108,7 @@ static int iic_ite_getclock(void *data)
* IIC controller interrupts.
*/
static void iic_ite_waitforpin(void) {
-
+ DEFINE_WAIT(wait);
int timeout = 2;
long flags;
@@ -121,13 +122,15 @@ static void iic_ite_waitforpin(void) {
spin_lock_irqsave(&lock, flags);
if (iic_pending == 0) {
spin_unlock_irqrestore(&lock, flags);
- if (interruptible_sleep_on_timeout(&iic_wait, timeout*HZ)) {
+ prepare_to_wait(&iic_wait, &wait, TASK_INTERRUPTIBLE);
+ if (schedule_timeout(timeout*HZ)) {
spin_lock_irqsave(&lock, flags);
if (iic_pending == 1) {
iic_pending = 0;
}
spin_unlock_irqrestore(&lock, flags);
}
+ finish_wait(&iic_wait, &wait);
} else {
iic_pending = 0;
spin_unlock_irqrestore(&lock, flags);
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index db88a12439..5b852782d2 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -525,6 +525,8 @@ mv64xxx_i2c_probe(struct device *dev)
drv_data->irq = platform_get_irq(pd, 0);
drv_data->adapter.id = I2C_ALGO_MV64XXX | I2C_HW_MV64XXX;
drv_data->adapter.algo = &mv64xxx_i2c_algo;
+ drv_data->adapter.owner = THIS_MODULE;
+ drv_data->adapter.class = I2C_CLASS_HWMON;
drv_data->adapter.timeout = pdata->timeout;
drv_data->adapter.retries = pdata->retries;
dev_set_drvdata(dev, drv_data);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 0ac72c935e..fcfa51c143 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -1,6 +1,6 @@
/* linux/drivers/i2c/busses/i2c-s3c2410.c
*
- * Copyright (C) 2004 Simtec Electronics
+ * Copyright (C) 2004,2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 I2C Controller
@@ -188,6 +188,9 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
} else
stat |= S3C2410_IICSTAT_MASTER_TX;
+ if (msg->flags & I2C_M_REV_DIR_ADDR)
+ addr ^= 1;
+
// todo - check for wether ack wanted or not
s3c24xx_i2c_enable_ack(i2c);
@@ -287,7 +290,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */
- dev_err(i2c->dev, "ack was not received\n" );
+ dev_dbg(i2c->dev, "ack was not received\n");
s3c24xx_i2c_stop(i2c, -EREMOTEIO);
goto out_ack;
}
@@ -555,11 +558,18 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
return -EREMOTEIO;
}
+/* declare our i2c functionality */
+static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
+}
+
/* i2c bus registration info */
static struct i2c_algorithm s3c24xx_i2c_algorithm = {
.name = "S3C2410-I2C-Algorithm",
.master_xfer = s3c24xx_i2c_xfer,
+ .functionality = s3c24xx_i2c_func,
};
static struct s3c24xx_i2c s3c24xx_i2c = {
@@ -567,6 +577,7 @@ static struct s3c24xx_i2c s3c24xx_i2c = {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
.adap = {
.name = "s3c2410-i2c",
+ .owner = THIS_MODULE,
.algo = &s3c24xx_i2c_algorithm,
.retries = 2,
.class = I2C_CLASS_HWMON,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c872c2849a..0bb60a636e 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -121,12 +121,12 @@ static int vt596_transaction(void)
inb_p(SMBHSTDAT1));
/* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
"Resetting...\n", temp);
outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp);
return -1;
@@ -168,13 +168,14 @@ static int vt596_transaction(void)
dev_dbg(&vt596_adapter.dev, "Error: no response!\n");
}
- if (inb_p(SMBHSTSTS) != 0x00)
- outb_p(inb(SMBHSTSTS), SMBHSTSTS);
-
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
- dev_dbg(&vt596_adapter.dev, "Failed reset at end of "
- "transaction (%02x)\n", temp);
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ outb_p(temp, SMBHSTSTS);
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ dev_warn(&vt596_adapter.dev, "Failed reset at end "
+ "of transaction (%02x)\n", temp);
+ }
}
+
dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 824c62d3a6..74d23cfce2 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -233,9 +233,23 @@ config SENSORS_LM90
LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
MAX6658 sensor chips.
+ The Analog Devices ADT7461 sensor chip is also supported, but only
+ if found in ADM1032 compatibility mode.
+
This driver can also be built as a module. If so, the module
will be called lm90.
+config SENSORS_LM92
+ tristate "National Semiconductor LM92 and compatibles"
+ depends on I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM92
+ and Maxim MAX6635 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm92.
+
config SENSORS_MAX1619
tristate "Maxim MAX1619 sensor chip"
depends on I2C && EXPERIMENTAL
@@ -351,6 +365,17 @@ endmenu
menu "Other I2C Chip support"
depends on I2C
+config SENSORS_DS1337
+ tristate "Dallas Semiconductor DS1337 Real Time Clock"
+ depends on I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Dallas Semiconductor
+ DS1337 real-time clock chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called ds1337.
+
config SENSORS_EEPROM
tristate "EEPROM reader"
depends on I2C && EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index a6db6f3947..65599161a1 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
+obj-$(CONFIG_SENSORS_DS1337) += ds1337.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_SENSORS_LM83) += lm83.o
obj-$(CONFIG_SENSORS_LM85) += lm85.o
obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
+obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
diff --git a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
index 5dd7f64fdd..b4e3ee5682 100644
--- a/drivers/i2c/chips/adm1021.c
+++ b/drivers/i2c/chips/adm1021.c
@@ -28,18 +28,6 @@
#include <linux/i2c-sensor.h>
-/* Registers */
-#define ADM1021_SYSCTL_TEMP 1200
-#define ADM1021_SYSCTL_REMOTE_TEMP 1201
-#define ADM1021_SYSCTL_DIE_CODE 1202
-#define ADM1021_SYSCTL_ALARMS 1203
-
-#define ADM1021_ALARM_TEMP_HIGH 0x40
-#define ADM1021_ALARM_TEMP_LOW 0x20
-#define ADM1021_ALARM_RTEMP_HIGH 0x10
-#define ADM1021_ALARM_RTEMP_LOW 0x08
-#define ADM1021_ALARM_RTEMP_NA 0x04
-
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b,
@@ -380,7 +368,7 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP);
data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R);
data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R);
- data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0xec;
+ data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c;
if (data->type == adm1021)
data->die_code = adm1021_read_value(client, ADM1021_REG_DIE_CODE);
if (data->type == adm1023) {
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
new file mode 100644
index 0000000000..07f16c3fb0
--- /dev/null
+++ b/drivers/i2c/chips/ds1337.c
@@ -0,0 +1,402 @@
+/*
+ * linux/drivers/i2c/chips/ds1337.c
+ *
+ * Copyright (C) 2005 James Chapman <jchapman@katalix.com>
+ *
+ * based on linux/drivers/acron/char/pcf8583.c
+ * Copyright (C) 2000 Russell King
+ *
+ * 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.
+ *
+ * Driver for Dallas Semiconductor DS1337 real time clock chip
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/string.h>
+#include <linux/rtc.h> /* get the user-level API */
+#include <linux/bcd.h>
+#include <linux/list.h>
+
+/* Device registers */
+#define DS1337_REG_HOUR 2
+#define DS1337_REG_DAY 3
+#define DS1337_REG_DATE 4
+#define DS1337_REG_MONTH 5
+#define DS1337_REG_CONTROL 14
+#define DS1337_REG_STATUS 15
+
+/* FIXME - how do we export these interface constants? */
+#define DS1337_GET_DATE 0
+#define DS1337_SET_DATE 1
+
+/*
+ * Functions declaration
+ */
+static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+SENSORS_INSMOD_1(ds1337);
+
+static int ds1337_attach_adapter(struct i2c_adapter *adapter);
+static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind);
+static void ds1337_init_client(struct i2c_client *client);
+static int ds1337_detach_client(struct i2c_client *client);
+static int ds1337_command(struct i2c_client *client, unsigned int cmd,
+ void *arg);
+
+/*
+ * Driver data (common to all clients)
+ */
+static struct i2c_driver ds1337_driver = {
+ .owner = THIS_MODULE,
+ .name = "ds1337",
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = ds1337_attach_adapter,
+ .detach_client = ds1337_detach_client,
+ .command = ds1337_command,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+struct ds1337_data {
+ struct i2c_client client;
+ struct list_head list;
+ int id;
+};
+
+/*
+ * Internal variables
+ */
+static int ds1337_id;
+static LIST_HEAD(ds1337_clients);
+
+static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
+{
+ s32 tmp = i2c_smbus_read_byte_data(client, reg);
+
+ if (tmp < 0)
+ return -EIO;
+
+ *value = tmp;
+
+ return 0;
+}
+
+/*
+ * Chip access functions
+ */
+static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
+{
+ struct ds1337_data *data = i2c_get_clientdata(client);
+ int result;
+ u8 buf[7];
+ u8 val;
+ struct i2c_msg msg[2];
+ u8 offs = 0;
+
+ if (!dt) {
+ dev_dbg(&client->adapter->dev, "%s: EINVAL: dt=NULL\n",
+ __FUNCTION__);
+
+ return -EINVAL;
+ }
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &offs;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = sizeof(buf);
+ msg[1].buf = &buf[0];
+
+ result = client->adapter->algo->master_xfer(client->adapter,
+ &msg[0], 2);
+
+ dev_dbg(&client->adapter->dev,
+ "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
+ __FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6]);
+
+ if (result >= 0) {
+ dt->tm_sec = BCD_TO_BIN(buf[0]);
+ dt->tm_min = BCD_TO_BIN(buf[1]);
+ val = buf[2] & 0x3f;
+ dt->tm_hour = BCD_TO_BIN(val);
+ dt->tm_wday = BCD_TO_BIN(buf[3]) - 1;
+ dt->tm_mday = BCD_TO_BIN(buf[4]);
+ val = buf[5] & 0x7f;
+ dt->tm_mon = BCD_TO_BIN(val);
+ dt->tm_year = 1900 + BCD_TO_BIN(buf[6]);
+ if (buf[5] & 0x80)
+ dt->tm_year += 100;
+
+ dev_dbg(&client->adapter->dev, "%s: secs=%d, mins=%d, "
+ "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+ __FUNCTION__, dt->tm_sec, dt->tm_min,
+ dt->tm_hour, dt->tm_mday,
+ dt->tm_mon, dt->tm_year, dt->tm_wday);
+ } else {
+ dev_err(&client->adapter->dev, "ds1337[%d]: error reading "
+ "data! %d\n", data->id, result);
+ result = -EIO;
+ }
+
+ return result;
+}
+
+static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
+{
+ struct ds1337_data *data = i2c_get_clientdata(client);
+ int result;
+ u8 buf[8];
+ u8 val;
+ struct i2c_msg msg[1];
+
+ if (!dt) {
+ dev_dbg(&client->adapter->dev, "%s: EINVAL: dt=NULL\n",
+ __FUNCTION__);
+
+ return -EINVAL;
+ }
+
+ dev_dbg(&client->adapter->dev, "%s: secs=%d, mins=%d, hours=%d, "
+ "mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__,
+ dt->tm_sec, dt->tm_min, dt->tm_hour,
+ dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday);
+
+ buf[0] = 0; /* reg offset */
+ buf[1] = BIN_TO_BCD(dt->tm_sec);
+ buf[2] = BIN_TO_BCD(dt->tm_min);
+ buf[3] = BIN_TO_BCD(dt->tm_hour) | (1 << 6);
+ buf[4] = BIN_TO_BCD(dt->tm_wday) + 1;
+ buf[5] = BIN_TO_BCD(dt->tm_mday);
+ buf[6] = BIN_TO_BCD(dt->tm_mon);
+ if (dt->tm_year >= 2000) {
+ val = dt->tm_year - 2000;
+ buf[6] |= (1 << 7);
+ } else {
+ val = dt->tm_year - 1900;
+ }
+ buf[7] = BIN_TO_BCD(val);
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = sizeof(buf);
+ msg[0].buf = &buf[0];
+
+ result = client->adapter->algo->master_xfer(client->adapter,
+ &msg[0], 1);
+ if (result < 0) {
+ dev_err(&client->adapter->dev, "ds1337[%d]: error "
+ "writing data! %d\n", data->id, result);
+ result = -EIO;
+ } else {
+ result = 0;
+ }
+
+ return result;
+}
+
+static int ds1337_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ dev_dbg(&client->adapter->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
+
+ switch (cmd) {
+ case DS1337_GET_DATE:
+ return ds1337_get_datetime(client, arg);
+
+ case DS1337_SET_DATE:
+ return ds1337_set_datetime(client, arg);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Public API for access to specific device. Useful for low-level
+ * RTC access from kernel code.
+ */
+int ds1337_do_command(int id, int cmd, void *arg)
+{
+ struct list_head *walk;
+ struct list_head *tmp;
+ struct ds1337_data *data;
+
+ list_for_each_safe(walk, tmp, &ds1337_clients) {
+ data = list_entry(walk, struct ds1337_data, list);
+ if (data->id == id)
+ return ds1337_command(&data->client, cmd, arg);
+ }
+
+ return -ENODEV;
+}
+
+static int ds1337_attach_adapter(struct i2c_adapter *adapter)
+{
+ return i2c_detect(adapter, &addr_data, ds1337_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *new_client;
+ struct ds1337_data *data;
+ int err = 0;
+ const char *name = "";
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_I2C))
+ goto exit;
+
+ if (!(data = kmalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ memset(data, 0, sizeof(struct ds1337_data));
+ INIT_LIST_HEAD(&data->list);
+
+ /* The common I2C client data is placed right before the
+ * DS1337-specific data.
+ */
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &ds1337_driver;
+ new_client->flags = 0;
+
+ /*
+ * Now we do the remaining detection. A negative kind means that
+ * the driver was loaded with no force parameter (default), so we
+ * must both detect and identify the chip. A zero kind means that
+ * the driver was loaded with the force parameter, the detection
+ * step shall be skipped. A positive kind means that the driver
+ * was loaded with the force parameter and a given kind of chip is
+ * requested, so both the detection and the identification steps
+ * are skipped.
+ *
+ * For detection, we read registers that are most likely to cause
+ * detection failure, i.e. those that have more bits with fixed
+ * or reserved values.
+ */
+
+ /* Default to an DS1337 if forced */
+ if (kind == 0)
+ kind = ds1337;
+
+ if (kind < 0) { /* detection and identification */
+ u8 data;
+
+ /* Check that status register bits 6-2 are zero */
+ if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) ||
+ (data & 0x7c))
+ goto exit_free;
+
+ /* Check for a valid day register value */
+ if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) ||
+ (data == 0) || (data & 0xf8))
+ goto exit_free;
+
+ /* Check for a valid date register value */
+ if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) ||
+ (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) ||
+ (data >= 0x32))
+ goto exit_free;
+
+ /* Check for a valid month register value */
+ if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) ||
+ (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) ||
+ ((data >= 0x13) && (data <= 0x19)))
+ goto exit_free;
+
+ /* Check that control register bits 6-5 are zero */
+ if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) ||
+ (data & 0x60))
+ goto exit_free;
+
+ kind = ds1337;
+ }
+
+ if (kind == ds1337)
+ name = "ds1337";
+
+ /* We can fill in the remaining client fields */
+ strlcpy(new_client->name, name, I2C_NAME_SIZE);
+
+ /* Tell the I2C layer a new client has arrived */
+ if ((err = i2c_attach_client(new_client)))
+ goto exit_free;
+
+ /* Initialize the DS1337 chip */
+ ds1337_init_client(new_client);
+
+ /* Add client to local list */
+ data->id = ds1337_id++;
+ list_add(&data->list, &ds1337_clients);
+
+ return 0;
+
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void ds1337_init_client(struct i2c_client *client)
+{
+ s32 val;
+
+ /* Ensure that device is set in 24-hour mode */
+ val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
+ if ((val >= 0) && (val & (1 << 6)) == 0)
+ i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
+ val | (1 << 6));
+}
+
+static int ds1337_detach_client(struct i2c_client *client)
+{
+ int err;
+ struct ds1337_data *data = i2c_get_clientdata(client);
+
+ if ((err = i2c_detach_client(client))) {
+ dev_err(&client->dev, "Client deregistration failed, "
+ "client not detached.\n");
+ return err;
+ }
+
+ list_del(&data->list);
+ kfree(data);
+ return 0;
+}
+
+static int __init ds1337_init(void)
+{
+ return i2c_add_driver(&ds1337_driver);
+}
+
+static void __exit ds1337_exit(void)
+{
+ i2c_del_driver(&ds1337_driver);
+}
+
+MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("DS1337 RTC driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds1337_init);
+module_exit(ds1337_exit);
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index f126d011cf..cbdfa2db6f 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -210,10 +210,11 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
&& i2c_smbus_read_byte(new_client) == 'C'
&& i2c_smbus_read_byte(new_client) == 'G'
- && i2c_smbus_read_byte(new_client) == '-')
+ && i2c_smbus_read_byte(new_client) == '-') {
dev_info(&new_client->dev, "Vaio EEPROM detected, "
"enabling password protection\n");
data->nature = VAIO;
+ }
}
/* create the sysfs eeprom file */
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
index e62c2e3900..bf02ba555a 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/i2c/chips/it87.c
@@ -734,10 +734,9 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
goto ERROR0;
/* Probe whether there is anything available on this address. Already
- done for SMBus clients */
+ done for SMBus and Super-I/O clients */
if (kind < 0) {
- if (is_isa) {
-
+ if (is_isa && !chip_type) {
#define REALLY_SLOW_IO
/* We need the timeouts for at least some IT87-like chips. But only
if we read 'undefined' registers. */
@@ -890,9 +889,9 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
}
if (data->type == it8712) {
+ data->vrm = i2c_which_vrm();
device_create_file_vrm(new_client);
device_create_file_vid(new_client);
- data->vrm = i2c_which_vrm();
}
return 0;
@@ -1123,9 +1122,6 @@ static struct it87_data *it87_update_device(struct device *dev)
it87_read_value(client, IT87_REG_TEMP_LOW(i));
}
- /* The 8705 does not have VID capability */
- data->vid = 0x1f;
-
i = it87_read_value(client, IT87_REG_FAN_DIV);
data->fan_div[0] = i & 0x07;
data->fan_div[1] = (i >> 3) & 0x07;
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index d17aba4e42..e08000b948 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -37,7 +37,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
-SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
+SENSORS_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102);
/* The LM85 registers */
@@ -74,8 +74,10 @@ SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
#define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62
+#define LM85_VERSTEP_ADT7463C 0x6A
#define LM85_VERSTEP_EMC6D100_A0 0x60
#define LM85_VERSTEP_EMC6D100_A1 0x61
+#define LM85_VERSTEP_EMC6D102 0x65
#define LM85_REG_CONFIG 0x40
@@ -112,9 +114,13 @@ SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
#define EMC6D100_REG_ALARM3 0x7d
/* IN5, IN6 and IN7 */
-#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5))
-#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2)
-#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2)
+#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5))
+#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2)
+#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2)
+#define EMC6D102_REG_EXTEND_ADC1 0x85
+#define EMC6D102_REG_EXTEND_ADC2 0x86
+#define EMC6D102_REG_EXTEND_ADC3 0x87
+#define EMC6D102_REG_EXTEND_ADC4 0x88
#define LM85_ALARM_IN0 0x0001
#define LM85_ALARM_IN1 0x0002
@@ -139,35 +145,36 @@ SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
these macros are called: arguments may be evaluated more than once.
*/
-/* IN are scaled 1.000 == 0xc0, mag = 3 */
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val)*0xc0+500)/1000),0,255))
-#define INEXT_FROM_REG(val,ext) (((val)*1000 + (ext)*250 + 96)/0xc0)
-#define IN_FROM_REG(val) (INEXT_FROM_REG(val,0))
-
/* IN are scaled acording to built-in resistors */
static int lm85_scaling[] = { /* .001 Volts */
2500, 2250, 3300, 5000, 12000,
3300, 1500, 1800 /*EMC6D100*/
};
#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
-#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
-#define INSEXT_FROM_REG(n,val,ext) (SCALE((val)*4 + (ext),192*4,lm85_scaling[n]))
-#define INS_FROM_REG(n,val) (INSEXT_FROM_REG(n,val,0))
+
+#define INS_TO_REG(n,val) \
+ SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)
+
+#define INSEXT_FROM_REG(n,val,ext,scale) \
+ SCALE((val)*(scale) + (ext),192*(scale),lm85_scaling[n])
+
+#define INS_FROM_REG(n,val) INSEXT_FROM_REG(n,val,0,1)
/* FAN speed is measured using 90kHz clock */
#define FAN_TO_REG(val) (SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534))
#define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val))
/* Temperature is reported in .001 degC increments */
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+500)/1000,-127,127))
-#define TEMPEXT_FROM_REG(val,ext) ((val)*1000 + (ext)*250)
-#define TEMP_FROM_REG(val) (TEMPEXT_FROM_REG(val,0))
-#define EXTTEMP_TO_REG(val) (SENSORS_LIMIT((val)/250,-127,127))
+#define TEMP_TO_REG(val) \
+ SENSORS_LIMIT(SCALE(val,1000,1),-127,127)
+#define TEMPEXT_FROM_REG(val,ext,scale) \
+ SCALE((val)*scale + (ext),scale,1000)
+#define TEMP_FROM_REG(val) \
+ TEMPEXT_FROM_REG(val,0,1)
#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255))
#define PWM_FROM_REG(val) (val)
-#define EXT_FROM_REG(val,sensor) (((val)>>(sensor * 2))&0x03)
/* ZONEs have the following parameters:
* Limit (low) temp, 1. degC
@@ -355,7 +362,9 @@ struct lm85_data {
u8 pwm[3]; /* Register value */
u8 spinup_ctl; /* Register encoding, combined */
u8 tach_mode; /* Register encoding, combined */
- u16 extend_adc; /* Register value */
+ u8 temp_ext[3]; /* Decoded values */
+ u8 in_ext[8]; /* Decoded values */
+ u8 adc_scale; /* ADC Extended bits scaling factor */
u8 fan_ppr; /* Register value */
u8 smooth[3]; /* Register encoding */
u8 vid; /* Register value */
@@ -536,7 +545,10 @@ show_pwm_reg(3);
static ssize_t show_in(struct device *dev, char *buf, int nr)
{
struct lm85_data *data = lm85_update_device(dev);
- return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]) );
+ return sprintf( buf, "%d\n", INSEXT_FROM_REG(nr,
+ data->in[nr],
+ data->in_ext[nr],
+ data->adc_scale) );
}
static ssize_t show_in_min(struct device *dev, char *buf, int nr)
{
@@ -617,7 +629,9 @@ show_in_reg(4);
static ssize_t show_temp(struct device *dev, char *buf, int nr)
{
struct lm85_data *data = lm85_update_device(dev);
- return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]) );
+ return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr],
+ data->temp_ext[nr],
+ data->adc_scale) );
}
static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
{
@@ -1089,7 +1103,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
&& verstep == LM85_VERSTEP_ADM1027 ) {
kind = adm1027 ;
} else if( company == LM85_COMPANY_ANALOG_DEV
- && verstep == LM85_VERSTEP_ADT7463 ) {
+ && (verstep == LM85_VERSTEP_ADT7463
+ || verstep == LM85_VERSTEP_ADT7463C) ) {
kind = adt7463 ;
} else if( company == LM85_COMPANY_ANALOG_DEV
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
@@ -1107,6 +1122,9 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
*/
kind = emc6d100 ;
} else if( company == LM85_COMPANY_SMSC
+ && verstep == LM85_VERSTEP_EMC6D102) {
+ kind = emc6d102 ;
+ } else if( company == LM85_COMPANY_SMSC
&& (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
@@ -1142,6 +1160,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
type_name = "adt7463";
} else if ( kind == emc6d100){
type_name = "emc6d100";
+ } else if ( kind == emc6d102 ) {
+ type_name = "emc6d102";
}
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
@@ -1259,7 +1279,6 @@ int lm85_read_value(struct i2c_client *client, u8 reg)
case LM85_REG_FAN_MIN(2) :
case LM85_REG_FAN_MIN(3) :
case LM85_REG_ALARM1 : /* Read both bytes at once */
- case ADM1027_REG_EXTEND_ADC1 : /* Read two bytes at once */
res = i2c_smbus_read_byte_data(client, reg) & 0xff ;
res |= i2c_smbus_read_byte_data(client, reg+1) << 8 ;
break ;
@@ -1363,10 +1382,25 @@ static struct lm85_data *lm85_update_device(struct device *dev)
* more significant bits that are read later.
*/
if ( (data->type == adm1027) || (data->type == adt7463) ) {
- data->extend_adc =
- lm85_read_value(client, ADM1027_REG_EXTEND_ADC1);
+ int ext1 = lm85_read_value(client,
+ ADM1027_REG_EXTEND_ADC1);
+ int ext2 = lm85_read_value(client,
+ ADM1027_REG_EXTEND_ADC2);
+ int val = (ext1 << 8) + ext2;
+
+ for(i = 0; i <= 4; i++)
+ data->in_ext[i] = (val>>(i * 2))&0x03;
+
+ for(i = 0; i <= 2; i++)
+ data->temp_ext[i] = (val>>((i + 5) * 2))&0x03;
}
+ /* adc_scale is 2^(number of LSBs). There are 4 extra bits in
+ the emc6d102 and 2 in the adt7463 and adm1027. In all
+ other chips ext is always 0 and the value of scale is
+ irrelevant. So it is left in 4*/
+ data->adc_scale = (data->type == emc6d102 ) ? 16 : 4;
+
for (i = 0; i <= 4; ++i) {
data->in[i] =
lm85_read_value(client, LM85_REG_IN(i));
@@ -1403,6 +1437,28 @@ static struct lm85_data *lm85_update_device(struct device *dev)
/* More alarm bits */
data->alarms |=
lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
+ } else if (data->type == emc6d102 ) {
+ /* Have to read LSB bits after the MSB ones because
+ the reading of the MSB bits has frozen the
+ LSBs (backward from the ADM1027).
+ */
+ int ext1 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC1);
+ int ext2 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC2);
+ int ext3 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC3);
+ int ext4 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC4);
+ data->in_ext[0] = ext3 & 0x0f;
+ data->in_ext[1] = ext4 & 0x0f;
+ data->in_ext[2] = (ext4 >> 4) & 0x0f;
+ data->in_ext[3] = (ext3 >> 4) & 0x0f;
+ data->in_ext[4] = (ext2 >> 4) & 0x0f;
+
+ data->temp_ext[0] = ext1 & 0x0f;
+ data->temp_ext[1] = ext2 & 0x0f;
+ data->temp_ext[2] = (ext1 >> 4) & 0x0f;
}
data->last_reading = jiffies ;
diff --git a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c
index 8b9e2de21b..49d92326fa 100644
--- a/drivers/i2c/chips/lm87.c
+++ b/drivers/i2c/chips/lm87.c
@@ -317,20 +317,20 @@ show_temp(3);
static void set_temp_low(struct device *dev, const char *buf, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm87_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
- data->temp_low[nr] = TEMP_TO_REG(val);
- lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->temp_low[nr] = TEMP_TO_REG(val);
+ lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
}
static void set_temp_high(struct device *dev, const char *buf, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm87_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
- data->temp_high[nr] = TEMP_TO_REG(val);
- lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->temp_high[nr] = TEMP_TO_REG(val);
+ lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
}
#define set_temp(offset) \
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
index 7540b23017..02e22b128b 100644
--- a/drivers/i2c/chips/lm90.c
+++ b/drivers/i2c/chips/lm90.c
@@ -43,6 +43,14 @@
* variants. The extra address and features of the MAX6659 are not
* supported by this driver.
*
+ * This driver also supports the ADT7461 chip from Analog Devices but
+ * only in its "compatability mode". If an ADT7461 chip is found but
+ * is configured in non-compatible mode (where its temperature
+ * register values are decoded differently) it is ignored by this
+ * driver. Complete datasheet can be obtained from Analog's website
+ * at:
+ * http://products.analog.com/products/info.asp?product=ADT7461
+ *
* Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and
* concern all supported chipsets, unless mentioned otherwise.
@@ -77,6 +85,7 @@
* LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
* LM89-1, and LM99-1 have address 0x4d.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+ * ADT7461 always has address 0x4c.
*/
static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
@@ -86,7 +95,7 @@ static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
* Insmod parameters
*/
-SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657);
+SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
/*
* The LM90 registers
@@ -148,6 +157,19 @@ SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657);
#define HYST_TO_REG(val) ((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \
((val) + 500) / 1000)
+/*
+ * ADT7461 is almost identical to LM90 except that attempts to write
+ * values that are outside the range 0 < temp < 127 are treated as
+ * the boundary value.
+ */
+
+#define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
+ (val) >= 127000 ? 127 : \
+ ((val) + 500) / 1000)
+#define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
+ (val) >= 127750 ? 0x7FC0 : \
+ ((val) + 125) / 250 * 64)
+
/*
* Functions declaration
*/
@@ -181,6 +203,7 @@ struct lm90_data {
struct semaphore update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
+ int kind;
/* registers values */
s8 temp_input1, temp_low1, temp_high1; /* local */
@@ -216,7 +239,10 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
- data->value = TEMP1_TO_REG(val); \
+ if (data->kind == adt7461) \
+ data->value = TEMP1_TO_REG_ADT7461(val); \
+ else \
+ data->value = TEMP1_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
return count; \
}
@@ -227,7 +253,10 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
- data->value = TEMP2_TO_REG(val); \
+ if (data->kind == adt7461) \
+ data->value = TEMP2_TO_REG_ADT7461(val); \
+ else \
+ data->value = TEMP2_TO_REG(val); \
i2c_smbus_write_byte_data(client, regh, data->value >> 8); \
i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \
return count; \
@@ -381,6 +410,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
&& (reg_config1 & 0x3F) == 0x00
&& reg_convrate <= 0x0A) {
kind = adm1032;
+ } else
+ if (address == 0x4c
+ && chip_id == 0x51 /* ADT7461 */
+ && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
+ && reg_convrate <= 0x0A) {
+ kind = adt7461;
}
} else
if (man_id == 0x4D) { /* Maxim */
@@ -418,11 +453,14 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
name = "lm86";
} else if (kind == max6657) {
name = "max6657";
+ } else if (kind == adt7461) {
+ name = "adt7461";
}
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
+ data->kind = kind;
init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
diff --git a/drivers/i2c/chips/lm92.c b/drivers/i2c/chips/lm92.c
new file mode 100644
index 0000000000..3c9d0ef8ec
--- /dev/null
+++ b/drivers/i2c/chips/lm92.c
@@ -0,0 +1,423 @@
+/*
+ * lm92 - Hardware monitoring driver
+ * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
+ *
+ * Based on the lm90 driver, with some ideas taken from the lm_sensors
+ * lm92 driver as well.
+ *
+ * The LM92 is a sensor chip made by National Semiconductor. It reports
+ * its own temperature with a 0.0625 deg resolution and a 0.33 deg
+ * accuracy. Complete datasheet can be obtained from National's website
+ * at:
+ * http://www.national.com/pf/LM/LM92.html
+ *
+ * This driver also supports the MAX6635 sensor chip made by Maxim.
+ * This chip is compatible with the LM92, but has a lesser accuracy
+ * (1.0 deg). Complete datasheet can be obtained from Maxim's website
+ * at:
+ * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
+ *
+ * Since the LM92 was the first chipset supported by this driver, most
+ * comments will refer to this chipset, but are actually general and
+ * concern all supported chipsets, unless mentioned otherwise.
+ *
+ * Support could easily be added for the National Semiconductor LM76
+ * and Maxim MAX6633 and MAX6634 chips, which are mostly compatible
+ * with the LM92.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+
+/* The LM92 and MAX6635 have 2 two-state pins for address selection,
+ resulting in 4 possible addresses. */
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+ I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(lm92);
+
+/* The LM92 registers */
+#define LM92_REG_CONFIG 0x01 /* 8-bit, RW */
+#define LM92_REG_TEMP 0x00 /* 16-bit, RO */
+#define LM92_REG_TEMP_HYST 0x02 /* 16-bit, RW */
+#define LM92_REG_TEMP_CRIT 0x03 /* 16-bit, RW */
+#define LM92_REG_TEMP_LOW 0x04 /* 16-bit, RW */
+#define LM92_REG_TEMP_HIGH 0x05 /* 16-bit, RW */
+#define LM92_REG_MAN_ID 0x07 /* 16-bit, RO, LM92 only */
+
+/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
+ left-justified in 16-bit registers. No rounding is done, with such
+ a resolution it's just not worth it. Note that the MAX6635 doesn't
+ make use of the 4 lower bits for limits (i.e. effective resolution
+ for limits is 1 degree Celsius). */
+static inline int TEMP_FROM_REG(s16 reg)
+{
+ return reg / 8 * 625 / 10;
+}
+
+static inline s16 TEMP_TO_REG(int val)
+{
+ if (val <= -60000)
+ return -60000 * 10 / 625 * 8;
+ if (val >= 160000)
+ return 160000 * 10 / 625 * 8;
+ return val * 10 / 625 * 8;
+}
+
+/* Alarm flags are stored in the 3 LSB of the temperature register */
+static inline u8 ALARMS_FROM_REG(s16 reg)
+{
+ return reg & 0x0007;
+}
+
+/* Driver data (common to all clients) */
+static struct i2c_driver lm92_driver;
+
+/* Client data (each client gets its own) */
+struct lm92_data {
+ struct i2c_client client;
+ struct semaphore update_lock;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* in jiffies */
+
+ /* registers values */
+ s16 temp1_input, temp1_crit, temp1_min, temp1_max, temp1_hyst;
+};
+
+
+/*
+ * Sysfs attributes and callback functions
+ */
+
+static struct lm92_data *lm92_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm92_data *data = i2c_get_clientdata(client);
+
+ down(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ)
+ || !data->valid) {
+ dev_dbg(&client->dev, "Updating lm92 data\n");
+ data->temp1_input = swab16(i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP));
+ data->temp1_hyst = swab16(i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_HYST));
+ data->temp1_crit = swab16(i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_CRIT));
+ data->temp1_min = swab16(i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_LOW));
+ data->temp1_max = swab16(i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_HIGH));
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ up(&data->update_lock);
+
+ return data;
+}
+
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, char *buf) \
+{ \
+ struct lm92_data *data = lm92_update_device(dev); \
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
+}
+show_temp(temp1_input);
+show_temp(temp1_crit);
+show_temp(temp1_min);
+show_temp(temp1_max);
+
+#define set_temp(value, reg) \
+static ssize_t set_##value(struct device *dev, const char *buf, \
+ size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm92_data *data = i2c_get_clientdata(client); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = TEMP_TO_REG(val); \
+ i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
+ return count; \
+}
+set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
+set_temp(temp1_min, LM92_REG_TEMP_LOW);
+set_temp(temp1_max, LM92_REG_TEMP_HIGH);
+
+static ssize_t show_temp1_crit_hyst(struct device *dev, char *buf)
+{
+ struct lm92_data *data = lm92_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
+ - TEMP_FROM_REG(data->temp1_hyst));
+}
+static ssize_t show_temp1_max_hyst(struct device *dev, char *buf)
+{
+ struct lm92_data *data = lm92_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
+ - TEMP_FROM_REG(data->temp1_hyst));
+}
+static ssize_t show_temp1_min_hyst(struct device *dev, char *buf)
+{
+ struct lm92_data *data = lm92_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
+ + TEMP_FROM_REG(data->temp1_hyst));
+}
+
+static ssize_t set_temp1_crit_hyst(struct device *dev, const char *buf,
+ size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm92_data *data = i2c_get_clientdata(client);
+ data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) -
+ simple_strtol(buf, NULL, 10);
+ i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
+ swab16(TEMP_TO_REG(data->temp1_hyst)));
+ return count;
+}
+
+static ssize_t show_alarms(struct device *dev, char *buf)
+{
+ struct lm92_data *data = lm92_update_device(dev);
+ return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
+static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit,
+ set_temp1_crit);
+static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp1_crit_hyst,
+ set_temp1_crit_hyst);
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp1_min,
+ set_temp1_min);
+static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp1_min_hyst, NULL);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max,
+ set_temp1_max);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+
+/*
+ * Detection and registration
+ */
+
+static void lm92_init_client(struct i2c_client *client)
+{
+ u8 config;
+
+ /* Start the conversions if needed */
+ config = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
+ if (config & 0x01)
+ i2c_smbus_write_byte_data(client, LM92_REG_CONFIG,
+ config & 0xFE);
+}
+
+/* The MAX6635 has no identification register, so we have to use tricks
+ to identify it reliably. This is somewhat slow.
+ Note that we do NOT rely on the 2 MSB of the configuration register
+ always reading 0, as suggested by the datasheet, because it was once
+ reported not to be true. */
+static int max6635_check(struct i2c_client *client)
+{
+ u16 temp_low, temp_high, temp_hyst, temp_crit;
+ u8 conf;
+ int i;
+
+ /* No manufacturer ID register, so a read from this address will
+ always return the last read value. */
+ temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
+ if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
+ return 0;
+ temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
+ if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
+ return 0;
+
+ /* Limits are stored as integer values (signed, 9-bit). */
+ if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
+ return 0;
+ temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HYST);
+ temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TEMP_CRIT);
+ if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
+ return 0;
+
+ /* Registers addresses were found to cycle over 16-byte boundaries.
+ We don't test all registers with all offsets so as to save some
+ reads and time, but this should still be sufficient to dismiss
+ non-MAX6635 chips. */
+ conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
+ for (i=16; i<96; i*=2) {
+ if (temp_hyst != i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_HYST + i - 16)
+ || temp_crit != i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_CRIT + i)
+ || temp_low != i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_LOW + i + 16)
+ || temp_high != i2c_smbus_read_word_data(client,
+ LM92_REG_TEMP_HIGH + i + 32)
+ || conf != i2c_smbus_read_byte_data(client,
+ LM92_REG_CONFIG + i))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* The following function does more than just detection. If detection
+ succeeds, it also registers the new chip. */
+static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *new_client;
+ struct lm92_data *data;
+ int err = 0;
+ char *name;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_WORD_DATA))
+ goto exit;
+
+ if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ memset(data, 0, sizeof(struct lm92_data));
+
+ /* Fill in enough client fields so that we can read from the chip,
+ which is required for identication */
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &lm92_driver;
+ new_client->flags = 0;
+
+ /* A negative kind means that the driver was loaded with no force
+ parameter (default), so we must identify the chip. */
+ if (kind < 0) {
+ u8 config = i2c_smbus_read_byte_data(new_client,
+ LM92_REG_CONFIG);
+ u16 man_id = i2c_smbus_read_word_data(new_client,
+ LM92_REG_MAN_ID);
+
+ if ((config & 0xe0) == 0x00
+ && man_id == 0x0180) {
+ pr_info("lm92: Found National Semiconductor LM92 chip\n");
+ kind = lm92;
+ } else
+ if (max6635_check(new_client)) {
+ pr_info("lm92: Found Maxim MAX6635 chip\n");
+ kind = lm92; /* No separate prefix */
+ }
+ else
+ goto exit_free;
+ } else
+ if (kind == 0) /* Default to an LM92 if forced */
+ kind = lm92;
+
+ /* Give it the proper name */
+ if (kind == lm92) {
+ name = "lm92";
+ } else { /* Supposedly cannot happen */
+ dev_dbg(&new_client->dev, "Kind out of range?\n");
+ goto exit_free;
+ }
+
+ /* Fill in the remaining client fields */
+ strlcpy(new_client->name, name, I2C_NAME_SIZE);
+ data->valid = 0;
+ init_MUTEX(&data->update_lock);
+
+ /* Tell the i2c subsystem a new client has arrived */
+ if ((err = i2c_attach_client(new_client)))
+ goto exit_free;
+
+ /* Initialize the chipset */
+ lm92_init_client(new_client);
+
+ /* Register sysfs hooks */
+ device_create_file(&new_client->dev, &dev_attr_temp1_input);
+ device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+ device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
+ device_create_file(&new_client->dev, &dev_attr_temp1_min);
+ device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
+ device_create_file(&new_client->dev, &dev_attr_temp1_max);
+ device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+ device_create_file(&new_client->dev, &dev_attr_alarms);
+
+ return 0;
+
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int lm92_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_detect(adapter, &addr_data, lm92_detect);
+}
+
+static int lm92_detach_client(struct i2c_client *client)
+{
+ int err;
+
+ if ((err = i2c_detach_client(client))) {
+ dev_err(&client->dev, "Client deregistration failed, "
+ "client not detached.\n");
+ return err;
+ }
+
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+
+/*
+ * Module and driver stuff
+ */
+
+static struct i2c_driver lm92_driver = {
+ .owner = THIS_MODULE,
+ .name = "lm92",
+ .id = I2C_DRIVERID_LM92,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = lm92_attach_adapter,
+ .detach_client = lm92_detach_client,
+};
+
+static int __init sensors_lm92_init(void)
+{
+ return i2c_add_driver(&lm92_driver);
+}
+
+static void __exit sensors_lm92_exit(void)
+{
+ i2c_del_driver(&lm92_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("LM92/MAX6635 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm92_init);
+module_exit(sensors_lm92_exit);
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index de270e9202..e771566dff 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -184,7 +184,6 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
memset(client, 0, sizeof(struct i2c_client));
strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE);
- client->id = m41t00_driver.id;
client->flags = I2C_DF_NOTIFY;
client->addr = addr;
client->adapter = adap;
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
index 986dba3f0a..133e449dc1 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/i2c/chips/w83627hf.c
@@ -304,7 +304,6 @@ struct w83627hf_data {
u32 beep_mask; /* Register encoding, combined */
u8 beep_enable; /* Boolean */
u8 pwm[3]; /* Register value */
- u8 pwmenable[3]; /* bool */
u16 sens[3]; /* 782D/783S only.
1 = pentium diode; 2 = 3904 diode;
3000-5000 = thermistor beta.
@@ -1317,10 +1316,6 @@ static void w83627hf_init_client(struct i2c_client *client)
break;
}
- data->pwmenable[0] = 1;
- data->pwmenable[1] = 1;
- data->pwmenable[2] = 1;
-
if(init) {
/* Enable temp2 */
tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG);
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
index e893229239..628d769cf4 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/i2c/chips/w83781d.c
@@ -46,9 +46,6 @@
#include <asm/io.h>
#include "lm75.h"
-/* RT Table support #defined so we can take it out if it gets bothersome */
-#define W83781D_RT 1
-
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
@@ -258,9 +255,6 @@ struct w83781d_data {
3000-5000 = thermistor beta.
Default = 3435.
Other Betas unimplemented */
-#ifdef W83781D_RT
- u8 rt[3][32]; /* Register value */
-#endif
u8 vrm;
};
@@ -834,66 +828,6 @@ do { \
device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
} while (0)
-#ifdef W83781D_RT
-static ssize_t
-show_rt_reg(struct device *dev, char *buf, int nr)
-{
- struct w83781d_data *data = w83781d_update_device(dev);
- int i, j = 0;
-
- for (i = 0; i < 32; i++) {
- if (i > 0)
- j += sprintf(buf, " %ld", (long) data->rt[nr - 1][i]);
- else
- j += sprintf(buf, "%ld", (long) data->rt[nr - 1][i]);
- }
- j += sprintf(buf, "\n");
-
- return j;
-}
-
-static ssize_t
-store_rt_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
- u32 val, i;
-
- for (i = 0; i < count; i++) {
- val = simple_strtoul(buf + count, NULL, 10);
-
- /* fixme: no bounds checking 0-255 */
- data->rt[nr - 1][i] = val & 0xff;
- w83781d_write_value(client, W83781D_REG_RT_IDX, i);
- w83781d_write_value(client, W83781D_REG_RT_VAL,
- data->rt[nr - 1][i]);
- }
-
- return count;
-}
-
-#define sysfs_rt(offset) \
-static ssize_t show_regs_rt_##offset (struct device *dev, char *buf) \
-{ \
- return show_rt_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_rt_##offset (struct device *dev, const char *buf, size_t count) \
-{ \
- return store_rt_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset);
-
-sysfs_rt(1);
-sysfs_rt(2);
-sysfs_rt(3);
-
-#define device_create_file_rt(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_rt##offset); \
-} while (0)
-
-#endif /* ifdef W83781D_RT */
-
/* This function is called when:
* w83781d_driver is inserted (when this module is loaded), for each
available adapter
@@ -1304,13 +1238,6 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind != w83783s && kind != w83697hf)
device_create_file_sensor(new_client, 3);
}
-#ifdef W83781D_RT
- if (kind == w83781d) {
- device_create_file_rt(new_client, 1);
- device_create_file_rt(new_client, 2);
- device_create_file_rt(new_client, 3);
- }
-#endif
return 0;
@@ -1535,33 +1462,6 @@ w83781d_init_client(struct i2c_client *client)
break;
}
}
-#ifdef W83781D_RT
-/*
- Fill up the RT Tables.
- We assume that they are 32 bytes long, in order for temp 1-3.
- Data sheet documentation is sparse.
- We also assume that it is only for the 781D although I suspect
- that the others support it as well....
-*/
-
- if (init && type == w83781d) {
- u16 k = 0;
-/*
- Auto-indexing doesn't seem to work...
- w83781d_write_value(client,W83781D_REG_RT_IDX,0);
-*/
- for (i = 0; i < 3; i++) {
- int j;
- for (j = 0; j < 32; j++) {
- w83781d_write_value(client,
- W83781D_REG_RT_IDX, k++);
- data->rt[i][j] =
- w83781d_read_value(client,
- W83781D_REG_RT_VAL);
- }
- }
- }
-#endif /* W83781D_RT */
if (init && type != as99127f) {
/* Enable temp2 */
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 56a6745734..e62a91a45a 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -587,7 +587,13 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
int ret;
if (adap->algo->master_xfer) {
- dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", num);
+#ifdef DEBUG
+ for (ret = 0; ret < num; ret++) {
+ dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
+ "len=%d\n", ret, msgs[ret].flags & I2C_M_RD ?
+ 'R' : 'W', msgs[ret].addr, msgs[ret].len);
+ }
+#endif
down(&adap->bus_lock);
ret = adap->algo->master_xfer(adap,msgs,num);
@@ -709,7 +715,7 @@ int i2c_probe(struct i2c_adapter *adapter,
at all */
found = 0;
- for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 3) {
+ for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 2) {
if (((adap_id == address_data->force[i]) ||
(address_data->force[i] == ANY_I2C_BUS)) &&
(addr == address_data->force[i+1])) {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 3f70e4926c..5425e0f77d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -67,7 +67,7 @@ static void msi_set_mask_bit(unsigned int vector, int flag)
int pos;
u32 mask_bits;
- pos = (int)entry->mask_base;
+ pos = (long)entry->mask_base;
pci_read_config_dword(entry->dev, pos, &mask_bits);
mask_bits &= ~(1);
mask_bits |= flag;
@@ -555,7 +555,7 @@ static int msi_capability_init(struct pci_dev *dev)
dev->irq = vector;
entry->dev = dev;
if (is_mask_bit_support(control)) {
- entry->mask_base = (void __iomem *)msi_mask_bits_reg(pos,
+ entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
is_64bit_address(control));
}
/* Replace with MSI handler */
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index df102f9301..c0ddb1eb8c 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -219,9 +219,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
res->data.address64.min_address_range,
res->data.address64.address_length);
break;
+ case ACPI_RSTYPE_VENDOR:
+ break;
default:
- pnp_warn("PnPACPI: Alloc type : %d not handle",
- res->id);
+ pnp_warn("PnPACPI: unknown resource type %d", res->id);
return AE_ERROR;
}
@@ -508,7 +509,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
case ACPI_RSTYPE_END_DPF:
return AE_CTRL_TERMINATE;
default:
- pnp_warn("PnPACPI:Option type: %d not handle", res->id);
+ pnp_warn("PnPACPI: unknown resource type %d", res->id);
return AE_ERROR;
}
@@ -810,7 +811,7 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
mem ++;
break;
default: /* other type */
- pnp_warn("Invalid type");
+ pnp_warn("unknown resource type %d", resource->id);
return -EINVAL;
}
resource ++;