3030#include <linux/err.h>
3131#include <linux/mutex.h>
3232#include <linux/delay.h>
33+ #include <linux/interrupt.h>
3334
3435#include "adt7x10.h"
3536
@@ -112,6 +113,25 @@ static const u8 ADT7X10_REG_TEMP[4] = {
112113 ADT7X10_T_CRIT , /* critical */
113114};
114115
116+ static irqreturn_t adt7x10_irq_handler (int irq , void * private )
117+ {
118+ struct device * dev = private ;
119+ int status ;
120+
121+ status = adt7x10_read_byte (dev , ADT7X10_STATUS );
122+ if (status < 0 )
123+ return IRQ_HANDLED ;
124+
125+ if (status & ADT7X10_STAT_T_HIGH )
126+ sysfs_notify (& dev -> kobj , NULL , "temp1_max_alarm" );
127+ if (status & ADT7X10_STAT_T_LOW )
128+ sysfs_notify (& dev -> kobj , NULL , "temp1_min_alarm" );
129+ if (status & ADT7X10_STAT_T_CRIT )
130+ sysfs_notify (& dev -> kobj , NULL , "temp1_crit_alarm" );
131+
132+ return IRQ_HANDLED ;
133+ }
134+
115135static int adt7x10_temp_ready (struct device * dev )
116136{
117137 int i , status ;
@@ -359,7 +379,7 @@ static const struct attribute_group adt7x10_group = {
359379 .attrs = adt7x10_attributes ,
360380};
361381
362- int adt7x10_probe (struct device * dev , const char * name ,
382+ int adt7x10_probe (struct device * dev , const char * name , int irq ,
363383 const struct adt7x10_ops * ops )
364384{
365385 struct adt7x10_data * data ;
@@ -387,8 +407,10 @@ int adt7x10_probe(struct device *dev, const char *name,
387407 * Set to 16 bit resolution, continous conversion and comparator mode.
388408 */
389409 data -> config = data -> oldconfig ;
390- data -> config &= ~ADT7X10_MODE_MASK ;
410+ data -> config &= ~(ADT7X10_MODE_MASK | ADT7X10_CT_POLARITY |
411+ ADT7X10_INT_POLARITY );
391412 data -> config |= ADT7X10_FULL | ADT7X10_RESOLUTION | ADT7X10_EVENT_MODE ;
413+
392414 if (data -> config != data -> oldconfig ) {
393415 ret = adt7x10_write_byte (dev , ADT7X10_CONFIG , data -> config );
394416 if (ret )
@@ -422,8 +444,18 @@ int adt7x10_probe(struct device *dev, const char *name,
422444 goto exit_remove_name ;
423445 }
424446
447+ if (irq > 0 ) {
448+ ret = request_threaded_irq (irq , NULL , adt7x10_irq_handler ,
449+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT ,
450+ dev_name (dev ), dev );
451+ if (ret )
452+ goto exit_hwmon_device_unregister ;
453+ }
454+
425455 return 0 ;
426456
457+ exit_hwmon_device_unregister :
458+ hwmon_device_unregister (data -> hwmon_dev );
427459exit_remove_name :
428460 if (name )
429461 device_remove_file (dev , & dev_attr_name );
@@ -435,10 +467,13 @@ int adt7x10_probe(struct device *dev, const char *name,
435467}
436468EXPORT_SYMBOL_GPL (adt7x10_probe );
437469
438- int adt7x10_remove (struct device * dev )
470+ int adt7x10_remove (struct device * dev , int irq )
439471{
440472 struct adt7x10_data * data = dev_get_drvdata (dev );
441473
474+ if (irq > 0 )
475+ free_irq (irq , dev );
476+
442477 hwmon_device_unregister (data -> hwmon_dev );
443478 if (data -> name )
444479 device_remove_file (dev , & dev_attr_name );
0 commit comments