Skip to content

Commit 101ca8d

Browse files
shankerd04alexandrebelloni
authored andcommitted
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: <[email protected]> # v6.0+ Signed-off-by: Shanker Donthineni <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 1b929c0 commit 101ca8d

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

drivers/rtc/rtc-efi.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,10 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm)
188188

189189
static int efi_procfs(struct device *dev, struct seq_file *seq)
190190
{
191-
efi_time_t eft, alm;
192-
efi_time_cap_t cap;
193-
efi_bool_t enabled, pending;
191+
efi_time_t eft, alm;
192+
efi_time_cap_t cap;
193+
efi_bool_t enabled, pending;
194+
struct rtc_device *rtc = dev_get_drvdata(dev);
194195

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

216-
seq_printf(seq,
217-
"Alarm Time\t: %u:%u:%u.%09u\n"
218-
"Alarm Date\t: %u-%u-%u\n"
219-
"Alarm Daylight\t: %u\n"
220-
"Enabled\t\t: %s\n"
221-
"Pending\t\t: %s\n",
222-
alm.hour, alm.minute, alm.second, alm.nanosecond,
223-
alm.year, alm.month, alm.day,
224-
alm.daylight,
225-
enabled == 1 ? "yes" : "no",
226-
pending == 1 ? "yes" : "no");
227-
228-
if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
229-
seq_puts(seq, "Timezone\t: unspecified\n");
230-
else
231-
/* XXX fixme: convert to string? */
232-
seq_printf(seq, "Timezone\t: %u\n", alm.timezone);
217+
if (test_bit(RTC_FEATURE_ALARM, rtc->features)) {
218+
seq_printf(seq,
219+
"Alarm Time\t: %u:%u:%u.%09u\n"
220+
"Alarm Date\t: %u-%u-%u\n"
221+
"Alarm Daylight\t: %u\n"
222+
"Enabled\t\t: %s\n"
223+
"Pending\t\t: %s\n",
224+
alm.hour, alm.minute, alm.second, alm.nanosecond,
225+
alm.year, alm.month, alm.day,
226+
alm.daylight,
227+
enabled == 1 ? "yes" : "no",
228+
pending == 1 ? "yes" : "no");
229+
230+
if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE)
231+
seq_puts(seq, "Timezone\t: unspecified\n");
232+
else
233+
/* XXX fixme: convert to string? */
234+
seq_printf(seq, "Timezone\t: %u\n", alm.timezone);
235+
}
233236

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

270273
rtc->ops = &efi_rtc_ops;
271274
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
272-
set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features);
275+
if (efi_rt_services_supported(EFI_RT_SUPPORTED_WAKEUP_SERVICES))
276+
set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features);
277+
else
278+
clear_bit(RTC_FEATURE_ALARM, rtc->features);
273279

274280
device_init_wakeup(&dev->dev, true);
275281

include/linux/efi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ extern struct efi {
668668

669669
#define EFI_RT_SUPPORTED_ALL 0x3fff
670670

671-
#define EFI_RT_SUPPORTED_TIME_SERVICES 0x000f
671+
#define EFI_RT_SUPPORTED_TIME_SERVICES 0x0003
672+
#define EFI_RT_SUPPORTED_WAKEUP_SERVICES 0x000c
672673
#define EFI_RT_SUPPORTED_VARIABLE_SERVICES 0x0070
673674

674675
extern struct mm_struct efi_mm;

0 commit comments

Comments
 (0)