Commit 101ca8d0 authored by Shanker Donthineni's avatar Shanker Donthineni Committed by Alexandre Belloni
Browse files

rtc: efi: Enable SET/GET WAKEUP services as optional



The current implementation of rtc-efi is expecting all the 4
time services GET{SET}_TIME{WAKEUP} must be supported by UEFI
firmware. As per the EFI_RT_PROPERTIES_TABLE, the platform
specific implementations can choose to enable selective time
services based on the RTC device capabilities.

This patch does the following changes to provide GET/SET RTC
services on platforms that do not support the WAKEUP feature.

1) Relax time services cap check when creating a platform device.
2) Clear RTC_FEATURE_ALARM bit in the absence of WAKEUP services.
3) Conditional alarm entries in '/proc/driver/rtc'.

Cc: <stable@vger.kernel.org> # v6.0+
Signed-off-by: default avatarShanker Donthineni <sdonthineni@nvidia.com>
Link: https://lore.kernel.org/r/20230102230630.192911-1-sdonthineni@nvidia.com


Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 1b929c02
Loading
Loading
Loading
Loading
+27 −21
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@ static int efi_procfs(struct device *dev, struct seq_file *seq)
	efi_time_t        eft, alm;
	efi_time_cap_t    cap;
	efi_bool_t        enabled, pending;
	struct rtc_device *rtc = dev_get_drvdata(dev);

	memset(&eft, 0, sizeof(eft));
	memset(&alm, 0, sizeof(alm));
@@ -213,6 +214,7 @@ static int efi_procfs(struct device *dev, struct seq_file *seq)
		/* XXX fixme: convert to string? */
		seq_printf(seq, "Timezone\t: %u\n", eft.timezone);

	if (test_bit(RTC_FEATURE_ALARM, rtc->features)) {
		seq_printf(seq,
			   "Alarm Time\t: %u:%u:%u.%09u\n"
			   "Alarm Date\t: %u-%u-%u\n"
@@ -230,6 +232,7 @@ static int efi_procfs(struct device *dev, struct seq_file *seq)
		else
			/* XXX fixme: convert to string? */
			seq_printf(seq, "Timezone\t: %u\n", alm.timezone);
	}

	/*
	 * now prints the capabilities
@@ -269,7 +272,10 @@ static int __init efi_rtc_probe(struct platform_device *dev)

	rtc->ops = &efi_rtc_ops;
	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
	if (efi_rt_services_supported(EFI_RT_SUPPORTED_WAKEUP_SERVICES))
		set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features);
	else
		clear_bit(RTC_FEATURE_ALARM, rtc->features);

	device_init_wakeup(&dev->dev, true);

+2 −1
Original line number Diff line number Diff line
@@ -668,7 +668,8 @@ extern struct efi {

#define EFI_RT_SUPPORTED_ALL					0x3fff

#define EFI_RT_SUPPORTED_TIME_SERVICES				0x000f
#define EFI_RT_SUPPORTED_TIME_SERVICES				0x0003
#define EFI_RT_SUPPORTED_WAKEUP_SERVICES			0x000c
#define EFI_RT_SUPPORTED_VARIABLE_SERVICES			0x0070

extern struct mm_struct efi_mm;