diff options
| author | Ingo Molnar <mingo@kernel.org> | 2018-12-03 13:42:17 +0300 | 
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2018-12-03 13:42:17 +0300 | 
| commit | 5f675231e456cb599b283f8361f01cf34b0617df (patch) | |
| tree | afb2bdfd6fdbb18336146f41ba7659120a5ff9d2 /drivers/rtc/rtc-cmos.c | |
| parent | 3e184501083c38fa091f640acb13af17a21fd228 (diff) | |
| parent | 2595646791c319cadfdbf271563aac97d0843dc7 (diff) | |
| download | linux-5f675231e456cb599b283f8361f01cf34b0617df.tar.xz | |
Merge tag 'v4.20-rc5' into sched/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
| -rw-r--r-- | drivers/rtc/rtc-cmos.c | 45 | 
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index cd3a2411bc2f..a5a19ff10535 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -50,6 +50,7 @@  /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */  #include <linux/mc146818rtc.h> +#ifdef CONFIG_ACPI  /*   * Use ACPI SCI to replace HPET interrupt for RTC Alarm event   * @@ -61,6 +62,18 @@  static bool use_acpi_alarm;  module_param(use_acpi_alarm, bool, 0444); +static inline int cmos_use_acpi_alarm(void) +{ +	return use_acpi_alarm; +} +#else /* !CONFIG_ACPI */ + +static inline int cmos_use_acpi_alarm(void) +{ +	return 0; +} +#endif +  struct cmos_rtc {  	struct rtc_device	*rtc;  	struct device		*dev; @@ -167,9 +180,9 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)  #endif  /* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */ -static int use_hpet_alarm(void) +static inline int use_hpet_alarm(void)  { -	return is_hpet_enabled() && !use_acpi_alarm; +	return is_hpet_enabled() && !cmos_use_acpi_alarm();  }  /*----------------------------------------------------------------*/ @@ -244,6 +257,7 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)  	struct cmos_rtc	*cmos = dev_get_drvdata(dev);  	unsigned char	rtc_control; +	/* This not only a rtc_op, but also called directly */  	if (!is_valid_irq(cmos->irq))  		return -EIO; @@ -340,7 +354,7 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)  	if (use_hpet_alarm())  		hpet_set_rtc_irq_bit(mask); -	if ((mask & RTC_AIE) && use_acpi_alarm) { +	if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {  		if (cmos->wake_on)  			cmos->wake_on(cmos->dev);  	} @@ -358,7 +372,7 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)  	if (use_hpet_alarm())  		hpet_mask_rtc_irq_bit(mask); -	if ((mask & RTC_AIE) && use_acpi_alarm) { +	if ((mask & RTC_AIE) && cmos_use_acpi_alarm()) {  		if (cmos->wake_off)  			cmos->wake_off(cmos->dev);  	} @@ -439,6 +453,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)  	unsigned char mon, mday, hrs, min, sec, rtc_control;  	int ret; +	/* This not only a rtc_op, but also called directly */  	if (!is_valid_irq(cmos->irq))  		return -EIO; @@ -503,9 +518,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  	struct cmos_rtc	*cmos = dev_get_drvdata(dev);  	unsigned long	flags; -	if (!is_valid_irq(cmos->irq)) -		return -EINVAL; -  	spin_lock_irqsave(&rtc_lock, flags);  	if (enabled) @@ -566,6 +578,12 @@ static const struct rtc_class_ops cmos_rtc_ops = {  	.alarm_irq_enable	= cmos_alarm_irq_enable,  }; +static const struct rtc_class_ops cmos_rtc_ops_no_alarm = { +	.read_time		= cmos_read_time, +	.set_time		= cmos_set_time, +	.proc			= cmos_procfs, +}; +  /*----------------------------------------------------------------*/  /* @@ -842,9 +860,12 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  			dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);  			goto cleanup1;  		} + +		cmos_rtc.rtc->ops = &cmos_rtc_ops; +	} else { +		cmos_rtc.rtc->ops = &cmos_rtc_ops_no_alarm;  	} -	cmos_rtc.rtc->ops = &cmos_rtc_ops;  	cmos_rtc.rtc->nvram_old_abi = true;  	retval = rtc_register_device(cmos_rtc.rtc);  	if (retval) @@ -980,7 +1001,7 @@ static int cmos_suspend(struct device *dev)  	}  	spin_unlock_irq(&rtc_lock); -	if ((tmp & RTC_AIE) && !use_acpi_alarm) { +	if ((tmp & RTC_AIE) && !cmos_use_acpi_alarm()) {  		cmos->enabled_wake = 1;  		if (cmos->wake_on)  			cmos->wake_on(dev); @@ -1031,7 +1052,7 @@ static void cmos_check_wkalrm(struct device *dev)  	 * ACPI RTC wake event is cleared after resume from STR,  	 * ACK the rtc irq here  	 */ -	if (t_now >= cmos->alarm_expires && use_acpi_alarm) { +	if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) {  		cmos_interrupt(0, (void *)cmos->rtc);  		return;  	} @@ -1053,7 +1074,7 @@ static int __maybe_unused cmos_resume(struct device *dev)  	struct cmos_rtc	*cmos = dev_get_drvdata(dev);  	unsigned char tmp; -	if (cmos->enabled_wake && !use_acpi_alarm) { +	if (cmos->enabled_wake && !cmos_use_acpi_alarm()) {  		if (cmos->wake_off)  			cmos->wake_off(dev);  		else @@ -1132,7 +1153,7 @@ static u32 rtc_handler(void *context)  	 * Or else, ACPI SCI is enabled during suspend/resume only,  	 * update rtc irq in that case.  	 */ -	if (use_acpi_alarm) +	if (cmos_use_acpi_alarm())  		cmos_interrupt(0, (void *)cmos->rtc);  	else {  		/* Fix me: can we use cmos_interrupt() here as well? */  | 
