All of lore.kernel.org
 help / color / mirror / Atom feed
* [lm-sensors] [PATCH] adt7470: Update sensors periodically via timer
@ 2007-07-26  1:04 Darrick J. Wong
  2007-07-26  1:08 ` [lm-sensors] [PATCH] adt7470: Update sensors periodically via Darrick J. Wong
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Darrick J. Wong @ 2007-07-26  1:04 UTC (permalink / raw)
  To: lm-sensors


[-- Attachment #1.1: Type: text/plain, Size: 8468 bytes --]

To avoid blocking for 1s in the sysfs read functions, make it so
that adt7470 updates are done periodically with a timer instead
of being called from the read functions directly.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---

 drivers/hwmon/adt7470.c |   71 +++++++++++++++++++++++++++++++++++------------
 1 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 75aee3b..bfb0072 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/timer.h>
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
@@ -124,6 +125,8 @@ struct adt7470_data {
 	struct mutex		lock;
 	char			valid;
 	unsigned long		last_updated;	/* In jiffies */
+	struct timer_list	timer;
+	struct work_struct	ref_work;
 
 	s8			temp[ADT7470_TEMP_COUNT];
 	s8			temp_min[ADT7470_TEMP_COUNT];
@@ -184,10 +187,9 @@ static void adt7470_init_client(struct i2c_client *client)
 	}
 }
 
-static struct adt7470_data *adt7470_update_device(struct device *dev)
+static void adt7470_update_data(struct adt7470_data *data)
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct i2c_client *client = &data->client;
 	u8 cfg;
 	int i;
 
@@ -277,6 +279,29 @@ static struct adt7470_data *adt7470_update_device(struct device *dev)
 
 out:
 	mutex_unlock(&data->lock);
+}
+
+static void adt7470_work_function(struct work_struct *work)
+{
+	struct adt7470_data *data =
+		container_of(work, struct adt7470_data, ref_work);
+
+	adt7470_update_data(data);
+	mod_timer(&data->timer, jiffies + REFRESH_INTERVAL);
+}
+
+static void adt7470_timer_function(unsigned long x)
+{
+	struct adt7470_data *data = (struct adt7470_data *)x;
+
+	schedule_work(&data->ref_work);
+}
+
+static struct adt7470_data *dev_to_adt7470_data(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7470_data *data = i2c_get_clientdata(client);
+
 	return data;
 }
 
@@ -285,7 +310,7 @@ static ssize_t show_temp_min(struct device *dev,
 			     char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", 1000 * data->temp_min[attr->index]);
 }
 
@@ -313,7 +338,7 @@ static ssize_t show_temp_max(struct device *dev,
 			     char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]);
 }
 
@@ -340,7 +365,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
 			 char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]);
 }
 
@@ -349,7 +374,7 @@ static ssize_t show_alarms(struct device *dev,
 			   char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 
 	if (attr->index)
 		return sprintf(buf, "%x\n", data->alarms);
@@ -362,7 +387,7 @@ static ssize_t show_fan_max(struct device *dev,
 			    char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 
 	if (FAN_DATA_VALID(data->fan_max[attr->index]))
 		return sprintf(buf, "%d\n",
@@ -397,7 +422,7 @@ static ssize_t show_fan_min(struct device *dev,
 			    char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 
 	if (FAN_DATA_VALID(data->fan_min[attr->index]))
 		return sprintf(buf, "%d\n",
@@ -431,7 +456,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 			char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 
 	if (FAN_DATA_VALID(data->fan[attr->index]))
 		return sprintf(buf, "%d\n",
@@ -444,7 +469,7 @@ static ssize_t show_force_pwm_max(struct device *dev,
 				  struct device_attribute *devattr,
 				  char *buf)
 {
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", data->force_pwm_max);
 }
 
@@ -475,7 +500,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
 			char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", data->pwm[attr->index]);
 }
 
@@ -500,7 +525,7 @@ static ssize_t show_pwm_max(struct device *dev,
 			    char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", data->pwm_max[attr->index]);
 }
 
@@ -528,7 +553,7 @@ static ssize_t show_pwm_min(struct device *dev,
 			    char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
 }
 
@@ -556,7 +581,7 @@ static ssize_t show_pwm_tmax(struct device *dev,
 			     char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	/* the datasheet says that tmax = tmin + 20C */
 	return sprintf(buf, "%d\n", 1000 * (20 + data->pwm_tmin[attr->index]));
 }
@@ -566,7 +591,7 @@ static ssize_t show_pwm_tmin(struct device *dev,
 			     char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", 1000 * data->pwm_tmin[attr->index]);
 }
 
@@ -594,7 +619,7 @@ static ssize_t show_pwm_auto(struct device *dev,
 			     char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	return sprintf(buf, "%d\n", 1 + data->pwm_automatic[attr->index]);
 }
 
@@ -638,7 +663,7 @@ static ssize_t show_pwm_auto_temp(struct device *dev,
 				  char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct adt7470_data *data = adt7470_update_device(dev);
+	struct adt7470_data *data = dev_to_adt7470_data(dev);
 	u8 ctrl = data->pwm_auto_temp[attr->index];
 
 	if (ctrl)
@@ -913,6 +938,14 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind)
 		goto exit_remove;
 	}
 
+	/* Initialize automatic sensor refresh */
+	INIT_WORK(&data->ref_work, adt7470_work_function);
+	init_timer(&data->timer);
+	data->timer.expires = jiffies + REFRESH_INTERVAL;
+	data->timer.data = (unsigned long)data;
+	data->timer.function = adt7470_timer_function;
+	add_timer(&data->timer);
+
 	return 0;
 
 exit_remove:
@@ -930,6 +963,8 @@ static int adt7470_detach_client(struct i2c_client *client)
 	struct adt7470_data *data = i2c_get_clientdata(client);
 	int i;
 
+	del_timer_sync(&data->timer);
+	cancel_work_sync(&data->ref_work);
 	hwmon_device_unregister(data->class_dev);
 	for (i = 0; i < ARRAY_SIZE(adt7470_attr); i++)
 		device_remove_file(&client->dev, &adt7470_attr[i].dev_attr);

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-07-29 19:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-26  1:04 [lm-sensors] [PATCH] adt7470: Update sensors periodically via timer Darrick J. Wong
2007-07-26  1:08 ` [lm-sensors] [PATCH] adt7470: Update sensors periodically via Darrick J. Wong
2007-07-26  1:19 ` Juerg Haefliger
2007-07-26  7:30 ` Darrick J. Wong
2007-07-26  7:49 ` Hans de Goede
2007-07-26 15:08 ` Juerg Haefliger
2007-07-26 16:57 ` Darrick J. Wong
2007-07-26 16:58 ` Hans de Goede
2007-07-26 20:03 ` Philip Pokorny
2007-07-29 19:18 ` Mark M. Hoffman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.