|
20 | 20 | #include <linux/platform_device.h>
|
21 | 21 | #include <linux/pm_domain.h>
|
22 | 22 | #include <linux/pm_opp.h>
|
| 23 | +#include <linux/reboot.h> |
23 | 24 | #include <linux/regulator/driver.h>
|
24 | 25 | #include <linux/regulator/fixed.h>
|
25 | 26 | #include <linux/gpio/consumer.h>
|
|
29 | 30 | #include <linux/regulator/machine.h>
|
30 | 31 | #include <linux/clk.h>
|
31 | 32 |
|
| 33 | +/* Default time in millisecond to wait for emergency shutdown */ |
| 34 | +#define FV_DEF_EMERG_SHUTDWN_TMO 10 |
32 | 35 |
|
33 | 36 | struct fixed_voltage_data {
|
34 | 37 | struct regulator_desc desc;
|
@@ -105,6 +108,49 @@ static int reg_is_enabled(struct regulator_dev *rdev)
|
105 | 108 | return priv->enable_counter > 0;
|
106 | 109 | }
|
107 | 110 |
|
| 111 | +static irqreturn_t reg_fixed_under_voltage_irq_handler(int irq, void *data) |
| 112 | +{ |
| 113 | + struct fixed_voltage_data *priv = data; |
| 114 | + struct regulator_dev *rdev = priv->dev; |
| 115 | + |
| 116 | + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, |
| 117 | + NULL); |
| 118 | + |
| 119 | + return IRQ_HANDLED; |
| 120 | +} |
| 121 | + |
| 122 | +/** |
| 123 | + * reg_fixed_get_irqs - Get and register the optional IRQ for fixed voltage |
| 124 | + * regulator. |
| 125 | + * @dev: Pointer to the device structure. |
| 126 | + * @priv: Pointer to fixed_voltage_data structure containing private data. |
| 127 | + * |
| 128 | + * This function tries to get the IRQ from the device firmware node. |
| 129 | + * If it's an optional IRQ and not found, it returns 0. |
| 130 | + * Otherwise, it attempts to request the threaded IRQ. |
| 131 | + * |
| 132 | + * Return: 0 on success, or error code on failure. |
| 133 | + */ |
| 134 | +static int reg_fixed_get_irqs(struct device *dev, |
| 135 | + struct fixed_voltage_data *priv) |
| 136 | +{ |
| 137 | + int ret; |
| 138 | + |
| 139 | + ret = fwnode_irq_get(dev_fwnode(dev), 0); |
| 140 | + /* This is optional IRQ. If not found we will get -EINVAL */ |
| 141 | + if (ret == -EINVAL) |
| 142 | + return 0; |
| 143 | + if (ret < 0) |
| 144 | + return dev_err_probe(dev, ret, "Failed to get IRQ\n"); |
| 145 | + |
| 146 | + ret = devm_request_threaded_irq(dev, ret, NULL, |
| 147 | + reg_fixed_under_voltage_irq_handler, |
| 148 | + IRQF_ONESHOT, "under-voltage", priv); |
| 149 | + if (ret) |
| 150 | + return dev_err_probe(dev, ret, "Failed to request IRQ\n"); |
| 151 | + |
| 152 | + return 0; |
| 153 | +} |
108 | 154 |
|
109 | 155 | /**
|
110 | 156 | * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
|
@@ -294,6 +340,10 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
|
294 | 340 | dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
|
295 | 341 | drvdata->desc.fixed_uV);
|
296 | 342 |
|
| 343 | + ret = reg_fixed_get_irqs(dev, drvdata); |
| 344 | + if (ret) |
| 345 | + return ret; |
| 346 | + |
297 | 347 | return 0;
|
298 | 348 | }
|
299 | 349 |
|
|
0 commit comments