aboutsummaryrefslogtreecommitdiff
path: root/drivers/hwmon/acpi_power_meter.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/acpi_power_meter.c')
-rw-r--r--drivers/hwmon/acpi_power_meter.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 34ad5a27a7e..579bdf93be4 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -2,7 +2,7 @@
* A hwmon driver for ACPI 4.0 power meters
* Copyright (C) 2009 IBM
*
- * Author: Darrick J. Wong <djwong@us.ibm.com>
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
*
* 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
@@ -29,8 +29,8 @@
#include <linux/kdev_t.h>
#include <linux/sched.h>
#include <linux/time.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
+#include <linux/err.h>
+#include <linux/acpi.h>
#define ACPI_POWER_METER_NAME "power_meter"
ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
@@ -101,7 +101,7 @@ struct acpi_power_meter_resource {
unsigned long sensors_last_updated;
struct sensor_device_attribute sensors[NUM_SENSORS];
int num_sensors;
- int trip[2];
+ s64 trip[2];
int num_domain_devices;
struct acpi_device **domain_devices;
struct kobject *holders_dir;
@@ -237,7 +237,7 @@ static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
if (res)
return res;
- temp /= 1000;
+ temp = DIV_ROUND_CLOSEST(temp, 1000);
if (temp > resource->caps.max_cap || temp < resource->caps.min_cap)
return -EINVAL;
arg0.integer.value = temp;
@@ -307,9 +307,7 @@ static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
if (res)
return res;
- temp /= 1000;
- if (temp < 0)
- return -EINVAL;
+ temp = DIV_ROUND_CLOSEST(temp, 1000);
mutex_lock(&resource->lock);
resource->trip[attr->index - 7] = temp;
@@ -382,8 +380,10 @@ static ssize_t show_str(struct device *dev,
val = resource->oem_info;
break;
default:
- BUG();
+ WARN(1, "Implementation error: unexpected attribute index %d\n",
+ attr->index);
val = "";
+ break;
}
return sprintf(buf, "%s\n", val);
@@ -437,7 +437,9 @@ static ssize_t show_val(struct device *dev,
val = resource->trip[attr->index - 7] * 1000;
break;
default:
- BUG();
+ WARN(1, "Implementation error: unexpected attribute index %d\n",
+ attr->index);
+ break;
}
return sprintf(buf, "%llu\n", val);
@@ -599,9 +601,8 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource)
/* Create a symlink to domain objects */
resource->domain_devices[i] = NULL;
- status = acpi_bus_get_device(element->reference.handle,
- &resource->domain_devices[i]);
- if (ACPI_FAILURE(status))
+ if (acpi_bus_get_device(element->reference.handle,
+ &resource->domain_devices[i]))
continue;
obj = resource->domain_devices[i];
@@ -856,7 +857,8 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
dev_info(&device->dev, "Capping in progress.\n");
break;
default:
- BUG();
+ WARN(1, "Unexpected event %d\n", event);
+ break;
}
mutex_unlock(&resource->lock);
@@ -912,7 +914,7 @@ exit:
return res;
}
-static int acpi_power_meter_remove(struct acpi_device *device, int type)
+static int acpi_power_meter_remove(struct acpi_device *device)
{
struct acpi_power_meter_resource *resource;
@@ -929,20 +931,29 @@ static int acpi_power_meter_remove(struct acpi_device *device, int type)
return 0;
}
-static int acpi_power_meter_resume(struct acpi_device *device)
+#ifdef CONFIG_PM_SLEEP
+
+static int acpi_power_meter_resume(struct device *dev)
{
struct acpi_power_meter_resource *resource;
- if (!device || !acpi_driver_data(device))
+ if (!dev)
+ return -EINVAL;
+
+ resource = acpi_driver_data(to_acpi_device(dev));
+ if (!resource)
return -EINVAL;
- resource = acpi_driver_data(device);
free_capabilities(resource);
read_capabilities(resource);
return 0;
}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(acpi_power_meter_pm, NULL, acpi_power_meter_resume);
+
static struct acpi_driver acpi_power_meter_driver = {
.name = "power_meter",
.class = ACPI_POWER_METER_CLASS,
@@ -950,9 +961,9 @@ static struct acpi_driver acpi_power_meter_driver = {
.ops = {
.add = acpi_power_meter_add,
.remove = acpi_power_meter_remove,
- .resume = acpi_power_meter_resume,
.notify = acpi_power_meter_notify,
},
+ .drv.pm = &acpi_power_meter_pm,
};
/* Module init/exit routines */
@@ -983,7 +994,7 @@ static int __init acpi_power_meter_init(void)
result = acpi_bus_register_driver(&acpi_power_meter_driver);
if (result < 0)
- return -ENODEV;
+ return result;
return 0;
}
@@ -993,7 +1004,7 @@ static void __exit acpi_power_meter_exit(void)
acpi_bus_unregister_driver(&acpi_power_meter_driver);
}
-MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
+MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
MODULE_DESCRIPTION("ACPI 4.0 power meter driver");
MODULE_LICENSE("GPL");