* [PATCH 0/2] Save Brightness on Macs @ 2026-02-06 12:56 Atharva Tiwari 2026-02-06 12:56 ` [PATCH 1/2] efi: Save Brightness using EFI " Atharva Tiwari 2026-02-06 12:56 ` [PATCH 2/2] platform/apple-gmux: use apple_brightness to save brightness to EFI Atharva Tiwari 0 siblings, 2 replies; 6+ messages in thread From: Atharva Tiwari @ 2026-02-06 12:56 UTC (permalink / raw) Cc: Lukas Wunner, Atharva Tiwari, Ard Biesheuvel, Hans de Goede, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 Currently, when a Mac is rebooted, the display brightness does not reflect the level used during the previous boot. Instead, the brightness is reset to the value last stored by macOS, causing the system to ignore any changes made since that time. We fix this by writing the brightness value to efivar "backlight-level" every 300ms. Atharva Tiwari (2): efi: Save Brightness using EFI on Macs platform/apple-gmux: use apple_brightness to save brightness to EFI drivers/firmware/efi/Kconfig | 10 ++ drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/apple-brightness.c | 91 +++++++++++++++++++ drivers/platform/x86/apple-gmux.c | 7 ++ .../linux/platform_data/apple-brightness.h | 21 +++++ 5 files changed, 130 insertions(+) create mode 100644 drivers/firmware/efi/apple-brightness.c create mode 100644 include/linux/platform_data/apple-brightness.h -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] efi: Save Brightness using EFI on Macs 2026-02-06 12:56 [PATCH 0/2] Save Brightness on Macs Atharva Tiwari @ 2026-02-06 12:56 ` Atharva Tiwari 2026-02-08 10:45 ` Hans de Goede 2026-02-06 12:56 ` [PATCH 2/2] platform/apple-gmux: use apple_brightness to save brightness to EFI Atharva Tiwari 1 sibling, 1 reply; 6+ messages in thread From: Atharva Tiwari @ 2026-02-06 12:56 UTC (permalink / raw) Cc: Lukas Wunner, Atharva Tiwari, Ard Biesheuvel, Hans de Goede, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 Currently when a Mac reboots, the brightness is not the same as the previous boot instead its the same as the last time the Mac booted macOS. We can fix this issue by saving the brightness level to the efivar backlight-level. We use delayed work instead of a shutdown callback, as it still applies the brightness even during forced shutdowns and at 0% battery. (tested on iMac20,1) Suggested-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> --- drivers/firmware/efi/Kconfig | 10 ++ drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/apple-brightness.c | 91 +++++++++++++++++++ .../linux/platform_data/apple-brightness.h | 21 +++++ 4 files changed, 123 insertions(+) create mode 100644 drivers/firmware/efi/apple-brightness.c create mode 100644 include/linux/platform_data/apple-brightness.h diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 29e0729299f5..dd0a9c9a772a 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -167,6 +167,16 @@ config APPLE_PROPERTIES If unsure, say Y if you have a Mac. Otherwise N. +config APPLE_BRIGHTNESS + bool "Apple Backlight control for EFI" + depends on X86 + help + This will save the brightness level to EFI, so brightness + level is preserved across reboots and shutdows. allowing + for improved support of Apple hardware. + + If unsure, say Y if you have a Mac, Otherwise N. + config RESET_ATTACK_MITIGATION bool "Reset memory attack mitigation" depends on EFI_STUB diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 8efbcf699e4f..1f5705cc87a2 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o obj-$(CONFIG_EFI_TEST) += test/ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o +obj-$(CONFIG_APPLE_BRIGHTNESS) += apple-brightness.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o diff --git a/drivers/firmware/efi/apple-brightness.c b/drivers/firmware/efi/apple-brightness.c new file mode 100644 index 000000000000..c32e365dc511 --- /dev/null +++ b/drivers/firmware/efi/apple-brightness.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * apple-brightness.c - EFI brightness saver on Macs + * Copyright (C) 2026 Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/backlight.h> +#include <linux/cleanup.h> +#include <linux/efi.h> +#include <linux/mutex.h> +#include <linux/workqueue.h> +#include <linux/platform_data/apple-brightness.h> + +static DEFINE_MUTEX(apple_brightness_mutex); +static struct delayed_work apple_brightness_work; + +static u32 efi_attr; +static u16 last_saved_level; + +static int (*get_brightness)(struct backlight_device *bl); +static struct backlight_device *bl_dev; + +static void apple_brightness_workfn(struct work_struct *work) +{ + u16 level; + efi_status_t status; + + mutex_lock(&apple_brightness_mutex); + + level = (u16)get_brightness(bl_dev); + + if (level == last_saved_level) + goto out; + + status = efivar_set_variable(APPLE_BRIGHTNESS_NAME, &APPLE_BRIGHTNESS_GUID, + efi_attr, sizeof(level), &level); + if (status != EFI_SUCCESS) + pr_debug("Unable to set brightness: 0x%lx\n", status); + else + last_saved_level = level; + +out: + mutex_unlock(&apple_brightness_mutex); + + mod_delayed_work(system_wq, &apple_brightness_work, + msecs_to_jiffies(APPLE_BRIGHTNESS_POLL)); +} + +int apple_brightness_probe(struct backlight_device *bl, + int (*get_brightnessfn)(struct backlight_device *bl)) +{ + efi_status_t status; + unsigned long size = sizeof(last_saved_level); + int ret; + + guard(mutex)(&apple_brightness_mutex); + + bl_dev = bl; + get_brightness = get_brightnessfn; + + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) + return -ENODEV; + + ret = efivar_lock(); + if (ret) + return ret; + + status = efivar_get_variable(APPLE_BRIGHTNESS_NAME, &APPLE_BRIGHTNESS_GUID, + &efi_attr, &size, &last_saved_level); + + efivar_unlock(); + + if (status != EFI_SUCCESS) + return -ENODEV; + + bl_dev = bl; + get_brightness = get_brightnessfn; + + INIT_DELAYED_WORK(&apple_brightness_work, apple_brightness_workfn); + mod_delayed_work(system_wq, &apple_brightness_work, + msecs_to_jiffies(APPLE_BRIGHTNESS_POLL)); + + return 0; +} +EXPORT_SYMBOL(apple_brightness_probe); + +MODULE_AUTHOR("Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>"); +MODULE_DESCRIPTION("EFI Brightness saver for Macs"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/include/linux/platform_data/apple-brightness.h b/include/linux/platform_data/apple-brightness.h new file mode 100644 index 000000000000..4cf5e2d346cb --- /dev/null +++ b/include/linux/platform_data/apple-brightness.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * apple-brightness.h - EFI brightness saver for Macs + * Copyright (C) 2026 Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> + */ + +#ifndef _APPLE_BL_H_ +#define _APPLE_BL_H_ + +#include <linux/backlight.h> +#include <linux/efi.h> + +#define APPLE_BRIGHTNESS_NAME L"backlight-level" +#define APPLE_BRIGHTNESS_GUID EFI_GUID(0x7c436110, 0xab2a, 0x4bbb, 0xa8, 0x80, 0xfe, 0x41, 0x99, 0x5c, 0x9f, 0x82) + +#define APPLE_BRIGHTNESS_POLL 300 + +int apple_brightness_probe(struct backlight_device *bl, + int (*get_brightnessfn)(struct backlight_device *bl)); + +#endif /* _APPLE_BL_H */ -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] efi: Save Brightness using EFI on Macs 2026-02-06 12:56 ` [PATCH 1/2] efi: Save Brightness using EFI " Atharva Tiwari @ 2026-02-08 10:45 ` Hans de Goede 2026-02-08 13:16 ` Lukas Wunner 0 siblings, 1 reply; 6+ messages in thread From: Hans de Goede @ 2026-02-08 10:45 UTC (permalink / raw) To: Atharva Tiwari Cc: Lukas Wunner, Ard Biesheuvel, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 Hi, On 6-Feb-26 13:56, Atharva Tiwari wrote: > Currently when a Mac reboots, the brightness is not the same > as the previous boot instead its the same as the last time the > Mac booted macOS. > > We can fix this issue by saving the brightness level to the efivar > backlight-level. > > We use delayed work instead of a shutdown callback, > as it still applies the brightness > even during forced shutdowns and at 0% battery. > > (tested on iMac20,1) > > Suggested-by: Lukas Wunner <lukas@wunner.de> > Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> > --- > drivers/firmware/efi/Kconfig | 10 ++ > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/apple-brightness.c | 91 +++++++++++++++++++ > .../linux/platform_data/apple-brightness.h | 21 +++++ > 4 files changed, 123 insertions(+) > create mode 100644 drivers/firmware/efi/apple-brightness.c > create mode 100644 include/linux/platform_data/apple-brightness.h > > diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig > index 29e0729299f5..dd0a9c9a772a 100644 > --- a/drivers/firmware/efi/Kconfig > +++ b/drivers/firmware/efi/Kconfig > @@ -167,6 +167,16 @@ config APPLE_PROPERTIES > > If unsure, say Y if you have a Mac. Otherwise N. > > +config APPLE_BRIGHTNESS > + bool "Apple Backlight control for EFI" > + depends on X86 > + help > + This will save the brightness level to EFI, so brightness > + level is preserved across reboots and shutdows. allowing > + for improved support of Apple hardware. > + > + If unsure, say Y if you have a Mac, Otherwise N. > + > config RESET_ATTACK_MITIGATION > bool "Reset memory attack mitigation" > depends on EFI_STUB > diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile > index 8efbcf699e4f..1f5705cc87a2 100644 > --- a/drivers/firmware/efi/Makefile > +++ b/drivers/firmware/efi/Makefile > @@ -26,6 +26,7 @@ obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o > obj-$(CONFIG_EFI_TEST) += test/ > obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o > obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o > +obj-$(CONFIG_APPLE_BRIGHTNESS) += apple-brightness.o > obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o > obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o > obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o > diff --git a/drivers/firmware/efi/apple-brightness.c b/drivers/firmware/efi/apple-brightness.c > new file mode 100644 > index 000000000000..c32e365dc511 > --- /dev/null > +++ b/drivers/firmware/efi/apple-brightness.c > @@ -0,0 +1,91 @@ > +// SPDX-License-Identifier: GPL-2.0-only OR MIT > +/* > + * apple-brightness.c - EFI brightness saver on Macs > + * Copyright (C) 2026 Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> > + */ > + > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > + > +#include <linux/backlight.h> > +#include <linux/cleanup.h> > +#include <linux/efi.h> > +#include <linux/mutex.h> > +#include <linux/workqueue.h> > +#include <linux/platform_data/apple-brightness.h> > + > +static DEFINE_MUTEX(apple_brightness_mutex); > +static struct delayed_work apple_brightness_work; > + > +static u32 efi_attr; > +static u16 last_saved_level; > + > +static int (*get_brightness)(struct backlight_device *bl); > +static struct backlight_device *bl_dev; > + > +static void apple_brightness_workfn(struct work_struct *work) > +{ > + u16 level; > + efi_status_t status; > + > + mutex_lock(&apple_brightness_mutex); > + > + level = (u16)get_brightness(bl_dev); > + > + if (level == last_saved_level) > + goto out; > + > + status = efivar_set_variable(APPLE_BRIGHTNESS_NAME, &APPLE_BRIGHTNESS_GUID, > + efi_attr, sizeof(level), &level); > + if (status != EFI_SUCCESS) > + pr_debug("Unable to set brightness: 0x%lx\n", status); > + else > + last_saved_level = level; > + > +out: > + mutex_unlock(&apple_brightness_mutex); > + > + mod_delayed_work(system_wq, &apple_brightness_work, > + msecs_to_jiffies(APPLE_BRIGHTNESS_POLL)); Wait so this now writes an non-volatile EFI variable every 300ms ? I don't know how these are backed on Apple hw, but typically these are backed by some SPI-nor flash or something similar. Writing this every 300ms is a sure fire way to wear out the flash and brick the machine real fast. So NACK. I was already worried about the shutdown approach on v1, but did not say anything since I'm not that familiar with apple hw and other apple code is already doing something similar. But writing a non-volatile EFI variable every 300ms is just a very very bad idea. Also I do not understand why this is necessary at all? Systemd already has a service which saves the value of all /sys/class/backlight and /sys/class/leds/*kbd_backlight devices on shutdown/reboot and restores these on boot. So what is the advantage here? Only advantage I can see is having the old-brightness value right away rather then getting it restored during boot? Regards, Hans > +} > + > +int apple_brightness_probe(struct backlight_device *bl, > + int (*get_brightnessfn)(struct backlight_device *bl)) > +{ > + efi_status_t status; > + unsigned long size = sizeof(last_saved_level); > + int ret; > + > + guard(mutex)(&apple_brightness_mutex); > + > + bl_dev = bl; > + get_brightness = get_brightnessfn; > + > + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) > + return -ENODEV; > + > + ret = efivar_lock(); > + if (ret) > + return ret; > + > + status = efivar_get_variable(APPLE_BRIGHTNESS_NAME, &APPLE_BRIGHTNESS_GUID, > + &efi_attr, &size, &last_saved_level); > + > + efivar_unlock(); > + > + if (status != EFI_SUCCESS) > + return -ENODEV; > + > + bl_dev = bl; > + get_brightness = get_brightnessfn; > + > + INIT_DELAYED_WORK(&apple_brightness_work, apple_brightness_workfn); > + mod_delayed_work(system_wq, &apple_brightness_work, > + msecs_to_jiffies(APPLE_BRIGHTNESS_POLL)); > + > + return 0; > +} > +EXPORT_SYMBOL(apple_brightness_probe); > + > +MODULE_AUTHOR("Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>"); > +MODULE_DESCRIPTION("EFI Brightness saver for Macs"); > +MODULE_LICENSE("Dual MIT/GPL"); > diff --git a/include/linux/platform_data/apple-brightness.h b/include/linux/platform_data/apple-brightness.h > new file mode 100644 > index 000000000000..4cf5e2d346cb > --- /dev/null > +++ b/include/linux/platform_data/apple-brightness.h > @@ -0,0 +1,21 @@ > +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ > +/* > + * apple-brightness.h - EFI brightness saver for Macs > + * Copyright (C) 2026 Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> > + */ > + > +#ifndef _APPLE_BL_H_ > +#define _APPLE_BL_H_ > + > +#include <linux/backlight.h> > +#include <linux/efi.h> > + > +#define APPLE_BRIGHTNESS_NAME L"backlight-level" > +#define APPLE_BRIGHTNESS_GUID EFI_GUID(0x7c436110, 0xab2a, 0x4bbb, 0xa8, 0x80, 0xfe, 0x41, 0x99, 0x5c, 0x9f, 0x82) > + > +#define APPLE_BRIGHTNESS_POLL 300 > + > +int apple_brightness_probe(struct backlight_device *bl, > + int (*get_brightnessfn)(struct backlight_device *bl)); > + > +#endif /* _APPLE_BL_H */ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] efi: Save Brightness using EFI on Macs 2026-02-08 10:45 ` Hans de Goede @ 2026-02-08 13:16 ` Lukas Wunner 2026-02-09 8:46 ` Hans de Goede 0 siblings, 1 reply; 6+ messages in thread From: Lukas Wunner @ 2026-02-08 13:16 UTC (permalink / raw) To: Hans de Goede Cc: Atharva Tiwari, Ard Biesheuvel, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 On Sun, Feb 08, 2026 at 11:45:55AM +0100, Hans de Goede wrote: > I was already worried about the shutdown approach on v1, > but did not say anything since I'm not that familiar > with apple hw and other apple code is already doing > something similar. Yes, macOS saves the brightness so that it's persisted across reboots and can be set already by the EFI firmware, avoiding a bloom effect (brightness change) on handover to the OS. We want to provide the same seamless user experience on Linux that users have grown accustomed to on macOS, I think that's a reasonable thing to do. > But writing a non-volatile EFI variable every 300ms is > just a very very bad idea. Agreed. But what do you think about a delayed write when brightness is changed, so that brightness is persisted even if the OS crashes? Users don't change brightness that often, I can't imagine that it amounts to a significantly higher number of writes than if it's only done on shutdown. Thanks, Lukas ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] efi: Save Brightness using EFI on Macs 2026-02-08 13:16 ` Lukas Wunner @ 2026-02-09 8:46 ` Hans de Goede 0 siblings, 0 replies; 6+ messages in thread From: Hans de Goede @ 2026-02-09 8:46 UTC (permalink / raw) To: Lukas Wunner Cc: Atharva Tiwari, Ard Biesheuvel, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 Hi, On 8-Feb-26 14:16, Lukas Wunner wrote: > On Sun, Feb 08, 2026 at 11:45:55AM +0100, Hans de Goede wrote: >> I was already worried about the shutdown approach on v1, >> but did not say anything since I'm not that familiar >> with apple hw and other apple code is already doing >> something similar. > > Yes, macOS saves the brightness so that it's persisted across reboots > and can be set already by the EFI firmware, avoiding a bloom effect > (brightness change) on handover to the OS. We want to provide the > same seamless user experience on Linux that users have grown accustomed > to on macOS, I think that's a reasonable thing to do. > >> But writing a non-volatile EFI variable every 300ms is >> just a very very bad idea. > > Agreed. But what do you think about a delayed write when brightness > is changed, so that brightness is persisted even if the OS crashes? > Users don't change brightness that often, I can't imagine that it > amounts to a significantly higher number of writes than if it's > only done on shutdown. How about saving the bootup brightness and then on shutdown compare and store it only if it changed ? That seems the safest approach. OS crashes should be seldom and the brightness not getting restored will be the least of a user's worries if those happen. Something like this should really be written to minimize the amount of nvram writes. It might actually be a good idea to change the existing apply brightness saving code in the same way. Regards, Hans ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] platform/apple-gmux: use apple_brightness to save brightness to EFI 2026-02-06 12:56 [PATCH 0/2] Save Brightness on Macs Atharva Tiwari 2026-02-06 12:56 ` [PATCH 1/2] efi: Save Brightness using EFI " Atharva Tiwari @ 2026-02-06 12:56 ` Atharva Tiwari 1 sibling, 0 replies; 6+ messages in thread From: Atharva Tiwari @ 2026-02-06 12:56 UTC (permalink / raw) Cc: Lukas Wunner, Atharva Tiwari, Ard Biesheuvel, Hans de Goede, Ilpo Järvinen, linux-kernel, linux-efi, platform-driver-x86 use apple_brightness to save brightness to EFI. (tested on iMac20,1) Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> --- drivers/platform/x86/apple-gmux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 1417e230edbd..cfb20c115eb0 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -22,6 +22,7 @@ #include <linux/pci.h> #include <linux/vga_switcheroo.h> #include <linux/debugfs.h> +#include <linux/platform_data/apple-brightness.h> #include <acpi/video.h> #include <asm/io.h> @@ -960,6 +961,12 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) } gmux_init_debugfs(gmux_data); + if (IS_ENABLED(CONFIG_APPLE_BRIGHTNESS)) { + ret = apple_brightness_probe(gmux_data->bdev, &gmux_get_brightness); + if (ret) + pr_warn("Unable to Enable EFI brightness saver: %d\n", ret); + } + return 0; err_register_handler: -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-09 8:46 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-06 12:56 [PATCH 0/2] Save Brightness on Macs Atharva Tiwari 2026-02-06 12:56 ` [PATCH 1/2] efi: Save Brightness using EFI " Atharva Tiwari 2026-02-08 10:45 ` Hans de Goede 2026-02-08 13:16 ` Lukas Wunner 2026-02-09 8:46 ` Hans de Goede 2026-02-06 12:56 ` [PATCH 2/2] platform/apple-gmux: use apple_brightness to save brightness to EFI Atharva Tiwari
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox