diff options
Diffstat (limited to 'drivers/leds/ledtrig-gpio.c')
| -rw-r--r-- | drivers/leds/ledtrig-gpio.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c index a247ae63374f..1bc5db4ece0d 100644 --- a/drivers/leds/ledtrig-gpio.c +++ b/drivers/leds/ledtrig-gpio.c | |||
| @@ -117,6 +117,9 @@ static ssize_t gpio_trig_inverted_store(struct device *dev, | |||
| 117 | 117 | ||
| 118 | gpio_data->inverted = !!inverted; | 118 | gpio_data->inverted = !!inverted; |
| 119 | 119 | ||
| 120 | /* After inverting, we need to update the LED. */ | ||
| 121 | schedule_work(&gpio_data->work); | ||
| 122 | |||
| 120 | return n; | 123 | return n; |
| 121 | } | 124 | } |
| 122 | static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show, | 125 | static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show, |
| @@ -146,20 +149,26 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, | |||
| 146 | return -EINVAL; | 149 | return -EINVAL; |
| 147 | } | 150 | } |
| 148 | 151 | ||
| 152 | if (gpio_data->gpio == gpio) | ||
| 153 | return n; | ||
| 154 | |||
| 149 | if (!gpio) { | 155 | if (!gpio) { |
| 150 | free_irq(gpio_to_irq(gpio_data->gpio), led); | 156 | if (gpio_data->gpio != 0) |
| 157 | free_irq(gpio_to_irq(gpio_data->gpio), led); | ||
| 158 | gpio_data->gpio = 0; | ||
| 151 | return n; | 159 | return n; |
| 152 | } | 160 | } |
| 153 | 161 | ||
| 154 | if (gpio_data->gpio > 0 && gpio_data->gpio != gpio) | ||
| 155 | free_irq(gpio_to_irq(gpio_data->gpio), led); | ||
| 156 | |||
| 157 | gpio_data->gpio = gpio; | ||
| 158 | ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq, | 162 | ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq, |
| 159 | IRQF_SHARED | IRQF_TRIGGER_RISING | 163 | IRQF_SHARED | IRQF_TRIGGER_RISING |
| 160 | | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led); | 164 | | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led); |
| 161 | if (ret) | 165 | if (ret) { |
| 162 | dev_err(dev, "request_irq failed with error %d\n", ret); | 166 | dev_err(dev, "request_irq failed with error %d\n", ret); |
| 167 | } else { | ||
| 168 | if (gpio_data->gpio != 0) | ||
| 169 | free_irq(gpio_to_irq(gpio_data->gpio), led); | ||
| 170 | gpio_data->gpio = gpio; | ||
| 171 | } | ||
| 163 | 172 | ||
| 164 | return ret ? ret : n; | 173 | return ret ? ret : n; |
| 165 | } | 174 | } |
| @@ -211,7 +220,8 @@ static void gpio_trig_deactivate(struct led_classdev *led) | |||
| 211 | device_remove_file(led->dev, &dev_attr_inverted); | 220 | device_remove_file(led->dev, &dev_attr_inverted); |
| 212 | device_remove_file(led->dev, &dev_attr_desired_brightness); | 221 | device_remove_file(led->dev, &dev_attr_desired_brightness); |
| 213 | flush_work(&gpio_data->work); | 222 | flush_work(&gpio_data->work); |
| 214 | free_irq(gpio_to_irq(gpio_data->gpio),led); | 223 | if (gpio_data->gpio != 0) |
| 224 | free_irq(gpio_to_irq(gpio_data->gpio), led); | ||
| 215 | kfree(gpio_data); | 225 | kfree(gpio_data); |
| 216 | } | 226 | } |
| 217 | } | 227 | } |
