Thread (3 messages) 3 messages, 3 authors, 2013-02-20

[RFC PATCH 3/9] hwmon: (lm90) add support to handle irq

From: Wei Ni <hidden>
Date: 2013-02-18 11:30:25
Also in: linux-arm-kernel, linux-devicetree, linux-pm
Subsystem: hardware monitoring, lm90 hardware monitor driver, the rest · Maintainers: Guenter Roeck, Jean Delvare, Linus Torvalds

Possibly related (same subject, not in this thread)

Add support to handle irq. When the temperature touch the limit value, the
driver can handle the interrupt.

Signed-off-by: Alexandre Courbot <redacted>
Signed-off-by: Wei Ni <redacted>
---
 drivers/hwmon/lm90.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index caf01b0..80311ef 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -89,6 +89,8 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
 
 /*
  * Addresses to scan
@@ -302,6 +304,7 @@ static const struct lm90_params lm90_params[] = {
 struct lm90_data {
 	struct device *hwmon_dev;
 	struct mutex update_lock;
+	struct work_struct irq_work;
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 	int kind;
@@ -1418,6 +1421,29 @@ static void lm90_init_client(struct i2c_client *client)
 		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
 }
 
+static void lm90_alert(struct i2c_client *client, unsigned int flag);
+
+static void lm90_irq_work(struct work_struct *work)
+{
+	struct lm90_data *data = container_of(work, struct lm90_data,
+					      irq_work);
+	struct i2c_client *client = to_i2c_client(data->hwmon_dev->parent);
+
+	lm90_alert(client, 0);
+
+	enable_irq(client->irq);
+}
+
+static irqreturn_t lm90_irq(int irq, void *dev_id)
+{
+	struct lm90_data *data = dev_id;
+
+	disable_irq_nosync(irq);
+	schedule_work(&data->irq_work);
+
+	return IRQ_HANDLED;
+}
+
 static int lm90_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id)
 {
@@ -1494,6 +1520,17 @@ static int lm90_probe(struct i2c_client *client,
 		goto exit_remove_files;
 	}
 
+	if (client->irq >= 0) {
+		INIT_WORK(&data->irq_work, lm90_irq_work);
+		dev_dbg(dev, "lm90 irq: %d\n", client->irq);
+		err = request_irq(client->irq, lm90_irq, IRQF_TRIGGER_LOW,
+				       "lm90", data);
+		if (err < 0) {
+			dev_err(dev, "cannot request interrupt\n");
+			goto exit_remove_files;
+		}
+	}
+
 	return 0;
 
 exit_remove_files:
@@ -1507,6 +1544,7 @@ static int lm90_remove(struct i2c_client *client)
 {
 	struct lm90_data *data = i2c_get_clientdata(client);
 
+	free_irq(client->irq, data);
 	hwmon_device_unregister(data->hwmon_dev);
 	lm90_remove_files(client, data);
 	lm90_restore_conf(client, data);
-- 
1.7.9.5
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help