diff options
Diffstat (limited to 'drivers/rtc/rtc-da9063.c')
| -rw-r--r-- | drivers/rtc/rtc-da9063.c | 114 |
1 files changed, 47 insertions, 67 deletions
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index ee2efb496174..557c9b29dcc1 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/regmap.h> #include <linux/rtc.h> #include <linux/slab.h> @@ -193,26 +194,17 @@ static void da9063_tm_to_data(struct rtc_time *tm, u8 *data, config->rtc_count_year_mask; } -static int da9063_rtc_stop_alarm(struct device *dev) -{ - struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); - const struct da9063_compatible_rtc_regmap *config = rtc->config; - - return regmap_update_bits(rtc->regmap, - config->rtc_alarm_year_reg, - config->rtc_alarm_on_mask, - 0); -} - -static int da9063_rtc_start_alarm(struct device *dev) +static int da9063_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) { struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); const struct da9063_compatible_rtc_regmap *config = rtc->config; + u8 set_bit = enabled ? config->rtc_alarm_on_mask : 0; return regmap_update_bits(rtc->regmap, config->rtc_alarm_year_reg, config->rtc_alarm_on_mask, - config->rtc_alarm_on_mask); + set_bit); } static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -311,7 +303,7 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) da9063_tm_to_data(&alrm->time, data, rtc); - ret = da9063_rtc_stop_alarm(dev); + ret = da9063_rtc_alarm_irq_enable(dev, 0); if (ret < 0) { dev_err(dev, "Failed to stop alarm: %d\n", ret); return ret; @@ -329,7 +321,7 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) da9063_data_to_tm(data, &rtc->alarm_time, rtc); if (alrm->enabled) { - ret = da9063_rtc_start_alarm(dev); + ret = da9063_rtc_alarm_irq_enable(dev, 1); if (ret < 0) { dev_err(dev, "Failed to start alarm: %d\n", ret); return ret; @@ -339,15 +331,6 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int da9063_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - if (enabled) - return da9063_rtc_start_alarm(dev); - else - return da9063_rtc_stop_alarm(dev); -} - static irqreturn_t da9063_alarm_event(int irq, void *data) { struct da9063_compatible_rtc *rtc = data; @@ -376,7 +359,6 @@ static int da9063_rtc_probe(struct platform_device *pdev) { struct da9063_compatible_rtc *rtc; const struct da9063_compatible_rtc_regmap *config; - const struct of_device_id *match; int irq_alarm; u8 data[RTC_DATA_LEN]; int ret; @@ -384,14 +366,11 @@ static int da9063_rtc_probe(struct platform_device *pdev) if (!pdev->dev.of_node) return -ENXIO; - match = of_match_node(da9063_compatible_reg_id_table, - pdev->dev.of_node); - rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; - rtc->config = match->data; + rtc->config = device_get_match_data(&pdev->dev); if (of_device_is_compatible(pdev->dev.of_node, "dlg,da9063-rtc")) { struct da9063 *chip = dev_get_drvdata(pdev->dev.parent); @@ -410,57 +389,49 @@ static int da9063_rtc_probe(struct platform_device *pdev) config->rtc_enable_reg, config->rtc_enable_mask, config->rtc_enable_mask); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to enable RTC\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, "Failed to enable RTC\n"); ret = regmap_update_bits(rtc->regmap, config->rtc_enable_32k_crystal_reg, config->rtc_crystal_mask, config->rtc_crystal_mask); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to run 32kHz oscillator\n"); ret = regmap_update_bits(rtc->regmap, config->rtc_alarm_secs_reg, config->rtc_alarm_status_mask, 0); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to access RTC alarm register\n"); ret = regmap_update_bits(rtc->regmap, config->rtc_alarm_secs_reg, DA9063_ALARM_STATUS_ALARM, DA9063_ALARM_STATUS_ALARM); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to access RTC alarm register\n"); ret = regmap_update_bits(rtc->regmap, config->rtc_alarm_year_reg, config->rtc_tick_on_mask, 0); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to disable TICKs\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to disable TICKs\n"); data[RTC_SEC] = 0; ret = regmap_bulk_read(rtc->regmap, config->rtc_alarm_secs_reg, &data[config->rtc_data_start], config->rtc_alarm_len); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", - ret); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to read initial alarm data\n"); platform_set_drvdata(pdev, rtc); @@ -484,19 +455,29 @@ static int da9063_rtc_probe(struct platform_device *pdev) clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtc_dev->features); } - irq_alarm = platform_get_irq_byname(pdev, "ALARM"); - if (irq_alarm < 0) + irq_alarm = platform_get_irq_byname_optional(pdev, "ALARM"); + if (irq_alarm >= 0) { + ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL, + da9063_alarm_event, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "ALARM", rtc); + if (ret) + dev_err(&pdev->dev, + "Failed to request ALARM IRQ %d: %d\n", + irq_alarm, ret); + + ret = dev_pm_set_wake_irq(&pdev->dev, irq_alarm); + if (ret) + dev_warn(&pdev->dev, + "Failed to set IRQ %d as a wake IRQ: %d\n", + irq_alarm, ret); + + device_init_wakeup(&pdev->dev, true); + } else if (irq_alarm != -ENXIO) { return irq_alarm; - - ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL, - da9063_alarm_event, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "ALARM", rtc); - if (ret) - dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n", - irq_alarm, ret); - - device_init_wakeup(&pdev->dev, true); + } else { + clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features); + } return devm_rtc_register_device(rtc->rtc_dev); } @@ -514,4 +495,3 @@ module_platform_driver(da9063_rtc_driver); MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); MODULE_DESCRIPTION("Real time clock device driver for Dialog DA9063"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DA9063_DRVNAME_RTC); |
