if (!parent)
return 0;
+ /* Report serious errors */
irq = device_property_match_string(parent, "interrupt-names", "smbus_alert");
- if (irq == -EINVAL || irq == -ENODATA)
- return 0;
- else if (irq < 0)
+ if (irq < 0 && irq != -EINVAL && irq != -ENODATA)
return irq;
+ /* Skip setup when no irq was found */
+ if (irq < 0 && !device_property_present(parent, "smbalert-gpios"))
+ return 0;
+
return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL));
}
#endif
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/interrupt.h>
struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
struct i2c_smbus_alert *alert;
struct i2c_adapter *adapter = ara->adapter;
+ unsigned long irqflags = IRQF_SHARED | IRQF_ONESHOT;
+ struct gpio_desc *gpiod;
int res, irq;
alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
} else {
irq = fwnode_irq_get_byname(dev_fwnode(adapter->dev.parent),
"smbus_alert");
- if (irq <= 0)
- return irq;
+ if (irq <= 0) {
+ gpiod = devm_gpiod_get(adapter->dev.parent, "smbalert", GPIOD_IN);
+ if (IS_ERR(gpiod))
+ return PTR_ERR(gpiod);
+
+ irq = gpiod_to_irq(gpiod);
+ if (irq <= 0)
+ return irq;
+
+ irqflags |= IRQF_TRIGGER_FALLING;
+ }
}
INIT_WORK(&alert->alert, smbalert_work);
alert->ara = ara;
if (irq > 0) {
- res = devm_request_threaded_irq(&ara->dev, irq,
- NULL, smbus_alert,
- IRQF_SHARED | IRQF_ONESHOT,
- "smbus_alert", alert);
+ res = devm_request_threaded_irq(&ara->dev, irq, NULL, smbus_alert,
+ irqflags, "smbus_alert", alert);
if (res)
return res;
}