From: "Sven Peter" <sven@svenpeter.dev>
To: "Russell King" <rmk+kernel@armlinux.org.uk>,
"Arnd Bergmann" <arnd@arndb.de>, "Lee Jones" <lee@kernel.org>,
"Linus Walleij" <linus.walleij@linaro.org>
Cc: "Alyssa Rosenzweig" <alyssa@rosenzweig.io>,
asahi@lists.linux.dev, "Bartosz Golaszewski" <brgl@bgdev.pl>,
"Hector Martin" <marcan@marcan.st>,
linux-arm-kernel@lists.infradead.org,
"open list:GPIO SUBSYSTEM" <linux-gpio@vger.kernel.org>
Subject: Re: [PATCH 4/6] platform/apple: Add new Apple Mac SMC driver
Date: Thu, 01 Sep 2022 19:50:31 +0200 [thread overview]
Message-ID: <1c876ae2-9d8b-4f47-8ca7-797fb484ad03@www.fastmail.com> (raw)
In-Reply-To: <E1oTkeW-003t9Y-Ey@rmk-PC.armlinux.org.uk>
Thanks for trying to upstream this!
I just have three minor comments:
On Thu, Sep 1, 2022, at 15:54, Russell King wrote:
> From: Hector Martin <marcan@marcan.st>
>
> This driver implements support for the SMC (System Management
> Controller) in Apple Macs. In contrast to the existing applesmc driver,
> it uses pluggable backends that allow it to support different SMC
> implementations, and uses the MFD subsystem to expose the core SMC
> functionality so that specific features (gpio, hwmon, battery, etc.) can
> be implemented by separate drivers in their respective downstream
> subsystems.
>
> The initial RTKit backend adds support for Apple Silicon Macs (M1 et
> al). We hope a backend for T2 Macs will be written in the future
> (since those are not supported by applesmc), and eventually an x86
> backend would allow us to fully deprecate applesmc in favor of this
> driver.
>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> ---
> drivers/platform/Kconfig | 2 +
> drivers/platform/Makefile | 1 +
> drivers/platform/apple/Kconfig | 49 ++++
> drivers/platform/apple/Makefile | 11 +
> drivers/platform/apple/smc.h | 28 ++
> drivers/platform/apple/smc_core.c | 249 ++++++++++++++++
> drivers/platform/apple/smc_rtkit.c | 451 +++++++++++++++++++++++++++++
> include/linux/mfd/macsmc.h | 86 ++++++
> 8 files changed, 877 insertions(+)
> create mode 100644 drivers/platform/apple/Kconfig
> create mode 100644 drivers/platform/apple/Makefile
> create mode 100644 drivers/platform/apple/smc.h
> create mode 100644 drivers/platform/apple/smc_core.c
> create mode 100644 drivers/platform/apple/smc_rtkit.c
> create mode 100644 include/linux/mfd/macsmc.h
>
> diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
> index b437847b6237..5f8b9bcdb830 100644
> --- a/drivers/platform/Kconfig
> +++ b/drivers/platform/Kconfig
> @@ -13,4 +13,6 @@ source "drivers/platform/olpc/Kconfig"
>
> source "drivers/platform/surface/Kconfig"
>
> +source "drivers/platform/apple/Kconfig"
> +
> source "drivers/platform/x86/Kconfig"
> diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
> index 4de08ef4ec9d..3e5d5039a28c 100644
> --- a/drivers/platform/Makefile
> +++ b/drivers/platform/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/
> obj-$(CONFIG_GOLDFISH) += goldfish/
> obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
> obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
> +obj-$(CONFIG_APPLE_PLATFORMS) += apple/
> diff --git a/drivers/platform/apple/Kconfig
> b/drivers/platform/apple/Kconfig
> new file mode 100644
> index 000000000000..42525aa9fbbe
> --- /dev/null
> +++ b/drivers/platform/apple/Kconfig
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Apple Platform-Specific Drivers
> +#
> +
> +menuconfig APPLE_PLATFORMS
> + bool "Apple Mac Platform-Specific Device Drivers"
> + default y
> + help
> + Say Y here to get to see options for platform-specific device
> drivers
> + for Apple devices. This option alone does not add any kernel code.
> +
> + If you say N, all options in this submenu will be skipped and
> disabled.
> +
> +if APPLE_PLATFORMS
> +
> +config APPLE_SMC
> + tristate "Apple SMC Driver"
> + depends on ARCH_APPLE || COMPILE_TEST
> + default ARCH_APPLE
> + select MFD_CORE
> + help
> + Build support for the Apple System Management Controller present in
> + Apple Macs. This driver currently supports the SMC in Apple Silicon
> + Macs. For x86 Macs, see the applesmc driver (SENSORS_APPLESMC).
> +
> + Say Y here if you have an Apple Silicon Mac.
> +
> + To compile this driver as a module, choose M here: the module will
> + be called macsmc.
> +
> +if APPLE_SMC
> +
> +config APPLE_SMC_RTKIT
> + tristate "RTKit (Apple Silicon) backend"
> + depends on ARCH_APPLE || COMPILE_TEST
> + depends on APPLE_RTKIT
> + default ARCH_APPLE
> + help
> + Build support for SMC communications via the RTKit backend. This is
> + required for Apple Silicon Macs.
> +
> + Say Y here if you have an Apple Silicon Mac.
> +
> + To compile this driver as a module, choose M here: the module will
> + be called macsmc-rtkit.
> +
> +endif
> +endif
> diff --git a/drivers/platform/apple/Makefile
> b/drivers/platform/apple/Makefile
> new file mode 100644
> index 000000000000..79fac195398b
> --- /dev/null
> +++ b/drivers/platform/apple/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for linux/drivers/platform/apple
> +# Apple Platform-Specific Drivers
> +#
> +
> +macsmc-y += smc_core.o
> +macsmc-rtkit-y += smc_rtkit.o
> +
> +obj-$(CONFIG_APPLE_SMC) += macsmc.o
> +obj-$(CONFIG_APPLE_SMC_RTKIT) += macsmc-rtkit.o
> diff --git a/drivers/platform/apple/smc.h b/drivers/platform/apple/smc.h
> new file mode 100644
> index 000000000000..8ae51887b2c5
> --- /dev/null
> +++ b/drivers/platform/apple/smc.h
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple SMC internal core definitions
> + * Copyright (C) The Asahi Linux Contributors
> + */
> +
> +#ifndef _SMC_H
> +#define _SMC_H
> +
> +#include <linux/mfd/macsmc.h>
> +
> +struct apple_smc_backend_ops {
> + int (*read_key)(void *cookie, smc_key key, void *buf, size_t size);
> + int (*write_key)(void *cookie, smc_key key, void *buf, size_t size);
> + int (*write_key_atomic)(void *cookie, smc_key key, void *buf, size_t
> size);
> + int (*rw_key)(void *cookie, smc_key key, void *wbuf, size_t wsize,
> + void *rbuf, size_t rsize);
> + int (*get_key_by_index)(void *cookie, int index, smc_key *key);
> + int (*get_key_info)(void *cookie, smc_key key, struct
> apple_smc_key_info *info);
> +};
> +
> +struct apple_smc *apple_smc_probe(struct device *dev, const struct
> apple_smc_backend_ops *ops,
> + void *cookie);
> +void *apple_smc_get_cookie(struct apple_smc *smc);
> +int apple_smc_remove(struct apple_smc *smc);
> +void apple_smc_event_received(struct apple_smc *smc, uint32_t event);
> +
> +#endif
> diff --git a/drivers/platform/apple/smc_core.c
> b/drivers/platform/apple/smc_core.c
> new file mode 100644
> index 000000000000..daf029cd072f
> --- /dev/null
> +++ b/drivers/platform/apple/smc_core.c
> @@ -0,0 +1,249 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple SMC core framework
> + * Copyright The Asahi Linux Contributors
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mutex.h>
> +#include <linux/notifier.h>
> +#include "smc.h"
> +
> +struct apple_smc {
> + struct device *dev;
> +
> + void *be_cookie;
> + const struct apple_smc_backend_ops *be;
> +
> + struct mutex mutex;
> +
> + u32 key_count;
> + smc_key first_key;
> + smc_key last_key;
> +
> + struct blocking_notifier_head event_handlers;
> +};
> +
> +static const struct mfd_cell apple_smc_devs[] = {
> + {
> + .name = "macsmc-gpio",
> + },
> + {
> + .name = "macsmc-hid",
> + },
> + {
> + .name = "macsmc-power",
> + },
> + {
> + .name = "macsmc-reboot",
> + },
> + {
> + .name = "macsmc-rtc",
> + },
> +};
> +
> +int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf,
> size_t size)
> +{
> + int ret;
> +
> + mutex_lock(&smc->mutex);
> + ret = smc->be->read_key(smc->be_cookie, key, buf, size);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_read);
> +
> +int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf,
> size_t size)
> +{
> + int ret;
> +
> + mutex_lock(&smc->mutex);
> + ret = smc->be->write_key(smc->be_cookie, key, buf, size);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_write);
> +
> +int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void
> *buf, size_t size)
> +{
> + int ret;
> +
> + /*
> + * Will fail if SMC is busy. This is only used by SMC reboot/poweroff
> + * final calls, so it doesn't really matter at that point.
> + */
> + if (!mutex_trylock(&smc->mutex))
> + return -EBUSY;
> +
> + ret = smc->be->write_key_atomic(smc->be_cookie, key, buf, size);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_write_atomic);
> +
> +int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf,
> size_t wsize,
> + void *rbuf, size_t rsize)
> +{
> + int ret;
> +
> + mutex_lock(&smc->mutex);
> + ret = smc->be->rw_key(smc->be_cookie, key, wbuf, wsize, rbuf, rsize);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_rw);
> +
> +int apple_smc_get_key_by_index(struct apple_smc *smc, int index,
> smc_key *key)
> +{
> + int ret;
> +
> + mutex_lock(&smc->mutex);
> + ret = smc->be->get_key_by_index(smc->be_cookie, index, key);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_get_key_by_index);
> +
> +int apple_smc_get_key_info(struct apple_smc *smc, smc_key key, struct
> apple_smc_key_info *info)
> +{
> + int ret;
> +
> + mutex_lock(&smc->mutex);
> + ret = smc->be->get_key_info(smc->be_cookie, key, info);
> + mutex_unlock(&smc->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(apple_smc_get_key_info);
> +
> +int apple_smc_find_first_key_index(struct apple_smc *smc, smc_key key)
> +{
> + int start = 0, count = smc->key_count;
> + int ret;
> +
> + if (key <= smc->first_key)
> + return 0;
> + if (key > smc->last_key)
> + return smc->key_count;
> +
> + while (count > 1) {
> + int pivot = start + ((count - 1) >> 1);
> + smc_key pkey;
> +
> + ret = apple_smc_get_key_by_index(smc, pivot, &pkey);
> + if (ret < 0)
> + return ret;
> +
> + if (pkey == key)
> + return pivot;
> +
> + pivot++;
> +
> + if (pkey < key) {
> + count -= pivot - start;
> + start = pivot;
> + } else {
> + count = pivot - start;
> + }
> + }
> +
> + return start;
> +}
> +EXPORT_SYMBOL(apple_smc_find_first_key_index);
> +
> +int apple_smc_get_key_count(struct apple_smc *smc)
> +{
> + return smc->key_count;
> +}
> +EXPORT_SYMBOL(apple_smc_get_key_count);
> +
> +void apple_smc_event_received(struct apple_smc *smc, uint32_t event)
> +{
> + dev_dbg(smc->dev, "Event: 0x%08x\n", event);
> + blocking_notifier_call_chain(&smc->event_handlers, event, NULL);
> +}
> +EXPORT_SYMBOL(apple_smc_event_received);
> +
> +int apple_smc_register_notifier(struct apple_smc *smc, struct
> notifier_block *n)
> +{
> + return blocking_notifier_chain_register(&smc->event_handlers, n);
> +}
> +EXPORT_SYMBOL(apple_smc_register_notifier);
> +
> +int apple_smc_unregister_notifier(struct apple_smc *smc, struct
> notifier_block *n)
> +{
> + return blocking_notifier_chain_unregister(&smc->event_handlers, n);
> +}
> +EXPORT_SYMBOL(apple_smc_unregister_notifier);
> +
> +void *apple_smc_get_cookie(struct apple_smc *smc)
> +{
> + return smc->be_cookie;
> +}
> +EXPORT_SYMBOL(apple_smc_get_cookie);
> +
> +struct apple_smc *apple_smc_probe(struct device *dev, const struct
> apple_smc_backend_ops *ops, void *cookie)
> +{
> + struct apple_smc *smc;
> + u32 count;
> + int ret;
> +
> + smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL);
> + if (!smc)
> + return ERR_PTR(-ENOMEM);
> +
> + smc->dev = dev;
> + smc->be_cookie = cookie;
> + smc->be = ops;
> + mutex_init(&smc->mutex);
> + BLOCKING_INIT_NOTIFIER_HEAD(&smc->event_handlers);
> +
> + ret = apple_smc_read_u32(smc, SMC_KEY(#KEY), &count);
> + if (ret)
> + return ERR_PTR(dev_err_probe(dev, ret, "Failed to get key count"));
> + smc->key_count = be32_to_cpu(count);
> +
> + ret = apple_smc_get_key_by_index(smc, 0, &smc->first_key);
> + if (ret)
> + return ERR_PTR(dev_err_probe(dev, ret, "Failed to get first key"));
> +
> + ret = apple_smc_get_key_by_index(smc, smc->key_count - 1,
> &smc->last_key);
> + if (ret)
> + return ERR_PTR(dev_err_probe(dev, ret, "Failed to get last key"));
> +
> + /* Enable notifications */
> + apple_smc_write_flag(smc, SMC_KEY(NTAP), 1);
> +
> + dev_info(dev, "Initialized (%d keys %p4ch..%p4ch)\n",
> + smc->key_count, &smc->first_key, &smc->last_key);
I don't think upstream supports %p4ch. marcan added that format in our downstream
tree iirc.
> +
> + dev_set_drvdata(dev, smc);
> +
> + ret = mfd_add_devices(dev, -1, apple_smc_devs,
> ARRAY_SIZE(apple_smc_devs), NULL, 0, NULL);
> + if (ret)
> + return ERR_PTR(dev_err_probe(dev, ret, "Subdevice initialization
> failed"));
> +
> + return smc;
> +}
> +EXPORT_SYMBOL(apple_smc_probe);
> +
> +int apple_smc_remove(struct apple_smc *smc)
> +{
> + mfd_remove_devices(smc->dev);
> +
> + /* Disable notifications */
> + apple_smc_write_flag(smc, SMC_KEY(NTAP), 1);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(apple_smc_remove);
> +
> +MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
> +MODULE_LICENSE("Dual MIT/GPL");
> +MODULE_DESCRIPTION("Apple SMC core");
> diff --git a/drivers/platform/apple/smc_rtkit.c
> b/drivers/platform/apple/smc_rtkit.c
> new file mode 100644
> index 000000000000..5b7c4c475bbb
> --- /dev/null
> +++ b/drivers/platform/apple/smc_rtkit.c
> @@ -0,0 +1,451 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple SMC RTKit backend
> + * Copyright The Asahi Linux Contributors
> + */
> +
> +#include <asm/unaligned.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/soc/apple/rtkit.h>
> +#include "smc.h"
> +
> +#define SMC_ENDPOINT 0x20
> +
> +/* Guess */
> +#define SMC_SHMEM_SIZE 0x1000
> +
> +#define SMC_MSG_READ_KEY 0x10
> +#define SMC_MSG_WRITE_KEY 0x11
> +#define SMC_MSG_GET_KEY_BY_INDEX 0x12
> +#define SMC_MSG_GET_KEY_INFO 0x13
> +#define SMC_MSG_INITIALIZE 0x17
> +#define SMC_MSG_NOTIFICATION 0x18
> +#define SMC_MSG_RW_KEY 0x20
> +
> +#define SMC_DATA GENMASK(63, 32)
> +#define SMC_WSIZE GENMASK(31, 24)
> +#define SMC_SIZE GENMASK(23, 16)
> +#define SMC_ID GENMASK(15, 12)
> +#define SMC_MSG GENMASK(7, 0)
> +#define SMC_RESULT SMC_MSG
> +
> +#define SMC_RECV_TIMEOUT 100
> +
> +struct apple_smc_rtkit {
> + struct device *dev;
> + struct apple_smc *core;
> + struct apple_rtkit *rtk;
> +
> + struct completion init_done;
> + bool initialized;
> + bool alive;
> +
> + struct resource *sram;
> + void __iomem *sram_base;
> + struct apple_rtkit_shmem shmem;
> +
> + unsigned int msg_id;
> +
> + bool atomic_pending;
> + struct completion cmd_done;
> + u64 cmd_ret;
> +};
> +
> +static int apple_smc_rtkit_write_key_atomic(void *cookie, smc_key key,
> void *buf, size_t size)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> + int ret;
> + u64 msg;
> + u8 result;
> +
> + if (size > SMC_SHMEM_SIZE || size == 0)
> + return -EINVAL;
> +
> + if (!smc->alive)
> + return -EIO;
> +
> + memcpy_toio(smc->shmem.iomem, buf, size);
> + smc->msg_id = (smc->msg_id + 1) & 0xf;
> + msg = (FIELD_PREP(SMC_MSG, SMC_MSG_WRITE_KEY) |
> + FIELD_PREP(SMC_SIZE, size) |
> + FIELD_PREP(SMC_ID, smc->msg_id) |
> + FIELD_PREP(SMC_DATA, key));
> + smc->atomic_pending = true;
> +
> + ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL,
> true);
> + if (ret < 0) {
> + dev_err(smc->dev, "Failed to send command (%d)\n", ret);
> + return ret;
> + }
> +
> + while (smc->atomic_pending) {
> + ret = apple_rtkit_poll(smc->rtk);
> + if (ret < 0) {
> + dev_err(smc->dev, "RTKit poll failed (%llx)", msg);
> + return ret;
> + }
> + udelay(100);
> + }
I guess we could use try_wait_for_completion here and get rid of the special
smc->atomic_pending path. Not sure if it makes the code much simpler though.
> +
> + if (FIELD_GET(SMC_ID, smc->cmd_ret) != smc->msg_id) {
> + dev_err(smc->dev, "Command sequence mismatch (expected %d, got
> %d)\n",
> + smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
> + return -EIO;
> + }
> +
> + result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
> + if (result != 0)
> + return -result;
> +
> + return FIELD_GET(SMC_SIZE, smc->cmd_ret);
> +}
> +
> +static int apple_smc_cmd(struct apple_smc_rtkit *smc, u64 cmd, u64 arg,
> + u64 size, u64 wsize, u32 *ret_data)
> +{
> + int ret;
> + u64 msg;
> + u8 result;
> +
> + if (!smc->alive)
> + return -EIO;
> +
> + reinit_completion(&smc->cmd_done);
> +
> + smc->msg_id = (smc->msg_id + 1) & 0xf;
> + msg = (FIELD_PREP(SMC_MSG, cmd) |
> + FIELD_PREP(SMC_SIZE, size) |
> + FIELD_PREP(SMC_WSIZE, wsize) |
> + FIELD_PREP(SMC_ID, smc->msg_id) |
> + FIELD_PREP(SMC_DATA, arg));
> +
> + ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL,
> false);
> + if (ret < 0) {
> + dev_err(smc->dev, "Failed to send command\n");
> + return ret;
> + }
> +
> + do {
> + if (wait_for_completion_timeout(&smc->cmd_done,
> + msecs_to_jiffies(SMC_RECV_TIMEOUT)) == 0) {
> + dev_err(smc->dev, "Command timed out (%llx)", msg);
> + return -ETIMEDOUT;
> + }
> + if (FIELD_GET(SMC_ID, smc->cmd_ret) == smc->msg_id)
> + break;
> + dev_err(smc->dev, "Command sequence mismatch (expected %d, got
> %d)\n",
> + smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
> + } while(1);
> +
> + result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
> + if (result != 0)
> + return -result;
> +
> + if (ret_data)
> + *ret_data = FIELD_GET(SMC_DATA, smc->cmd_ret);
> +
> + return FIELD_GET(SMC_SIZE, smc->cmd_ret);
> +}
> +
> +static int _apple_smc_rtkit_read_key(struct apple_smc_rtkit *smc,
> smc_key key,
> + void *buf, size_t size, size_t wsize)
> +{
> + int ret;
> + u32 rdata;
> + u64 cmd;
> +
> + if (size > SMC_SHMEM_SIZE || size == 0)
> + return -EINVAL;
> +
> + cmd = wsize ? SMC_MSG_RW_KEY : SMC_MSG_READ_KEY;
> +
> + ret = apple_smc_cmd(smc, cmd, key, size, wsize, &rdata);
> + if (ret < 0)
> + return ret;
> +
> + if (size <= 4)
> + memcpy(buf, &rdata, size);
> + else
> + memcpy_fromio(buf, smc->shmem.iomem, size);
> +
> + return ret;
> +}
> +
> +static int apple_smc_rtkit_read_key(void *cookie, smc_key key, void
> *buf, size_t size)
> +{
> + return _apple_smc_rtkit_read_key(cookie, key, buf, size, 0);
> +}
> +
> +static int apple_smc_rtkit_write_key(void *cookie, smc_key key, void
> *buf, size_t size)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> +
> + if (size > SMC_SHMEM_SIZE || size == 0)
> + return -EINVAL;
> +
> + memcpy_toio(smc->shmem.iomem, buf, size);
> + return apple_smc_cmd(smc, SMC_MSG_WRITE_KEY, key, size, 0, NULL);
> +}
> +
> +static int apple_smc_rtkit_rw_key(void *cookie, smc_key key,
> + void *wbuf, size_t wsize, void *rbuf, size_t rsize)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> +
> + if (wsize > SMC_SHMEM_SIZE || wsize == 0)
> + return -EINVAL;
> +
> + memcpy_toio(smc->shmem.iomem, wbuf, wsize);
> + return _apple_smc_rtkit_read_key(smc, key, rbuf, rsize, wsize);
> +}
> +
> +static int apple_smc_rtkit_get_key_by_index(void *cookie, int index,
> smc_key *key)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> + int ret;
> +
> + ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_BY_INDEX, index, 0, 0, key);
> +
> + *key = swab32(*key);
> + return ret;
> +}
> +
> +static int apple_smc_rtkit_get_key_info(void *cookie, smc_key key,
> struct apple_smc_key_info *info)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> + u8 key_info[6];
> + int ret;
> +
> + ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_INFO, key, 0, 0, NULL);
> + if (ret >= 0 && info) {
> + info->size = key_info[0];
> + info->type_code = get_unaligned_be32(&key_info[1]);
> + info->flags = key_info[5];
> + }
> + return ret;
> +}
> +
> +static const struct apple_smc_backend_ops apple_smc_rtkit_be_ops = {
> + .read_key = apple_smc_rtkit_read_key,
> + .write_key = apple_smc_rtkit_write_key,
> + .write_key_atomic = apple_smc_rtkit_write_key_atomic,
> + .rw_key = apple_smc_rtkit_rw_key,
> + .get_key_by_index = apple_smc_rtkit_get_key_by_index,
> + .get_key_info = apple_smc_rtkit_get_key_info,
> +};
> +
> +static void apple_smc_rtkit_crashed(void *cookie)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> +
> + dev_err(smc->dev, "SMC crashed! Your system will reboot in a few
> seconds...\n");
> + smc->alive = false;
> +}
> +
> +static int apple_smc_rtkit_shmem_setup(void *cookie, struct
> apple_rtkit_shmem *bfr)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> + struct resource res = {
> + .start = bfr->iova,
> + .end = bfr->iova + bfr->size - 1,
> + .name = "rtkit_map",
> + .flags = smc->sram->flags,
> + };
> +
> + if (!bfr->iova) {
> + dev_err(smc->dev, "RTKit wants a RAM buffer\n");
> + return -EIO;
> + }
> +
> + if (res.end < res.start || !resource_contains(smc->sram, &res)) {
> + dev_err(smc->dev,
> + "RTKit buffer request outside SRAM region: %pR", &res);
> + return -EFAULT;
> + }
> +
> + bfr->iomem = smc->sram_base + (res.start - smc->sram->start);
> + bfr->is_mapped = true;
> +
> + return 0;
> +}
> +
> +static void apple_smc_rtkit_shmem_destroy(void *cookie, struct
> apple_rtkit_shmem *bfr)
> +{
> + // no-op
> +}
> +
> +static bool apple_smc_rtkit_recv_early(void *cookie, u8 endpoint, u64
> message)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> +
> + if (endpoint != SMC_ENDPOINT) {
> + dev_err(smc->dev, "Received message for unknown endpoint 0x%x\n",
> endpoint);
> + return false;
> + }
> +
> + if (!smc->initialized) {
> + int ret;
> +
> + smc->shmem.iova = message;
> + smc->shmem.size = SMC_SHMEM_SIZE;
> + ret = apple_smc_rtkit_shmem_setup(smc, &smc->shmem);
> + if (ret < 0)
> + dev_err(smc->dev, "Failed to initialize shared memory\n");
> + else
> + smc->alive = true;
> + smc->initialized = true;
> + complete(&smc->init_done);
> + } else if (FIELD_GET(SMC_MSG, message) == SMC_MSG_NOTIFICATION) {
> + /* Handle these in the RTKit worker thread */
> + return false;
> + } else {
> + smc->cmd_ret = message;
> + if (smc->atomic_pending) {
> + smc->atomic_pending = false;
> + } else {
> + complete(&smc->cmd_done);
> + }
> + }
> +
> + return true;
> +}
> +
> +static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64
> message)
> +{
> + struct apple_smc_rtkit *smc = cookie;
> +
> + if (endpoint != SMC_ENDPOINT) {
> + dev_err(smc->dev, "Received message for unknown endpoint 0x%x\n",
> endpoint);
> + return;
> + }
> +
> + if (FIELD_GET(SMC_MSG, message) != SMC_MSG_NOTIFICATION) {
> + dev_err(smc->dev, "Received unknown message from worker: 0x%llx\n",
> message);
> + return;
> + }
> +
> + apple_smc_event_received(smc->core, FIELD_GET(SMC_DATA, message));
> +}
> +
> +static const struct apple_rtkit_ops apple_smc_rtkit_ops = {
> + .crashed = apple_smc_rtkit_crashed,
> + .recv_message = apple_smc_rtkit_recv,
> + .recv_message_early = apple_smc_rtkit_recv_early,
> + .shmem_setup = apple_smc_rtkit_shmem_setup,
> + .shmem_destroy = apple_smc_rtkit_shmem_destroy,
> +};
> +
> +static int apple_smc_rtkit_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct apple_smc_rtkit *smc;
> + int ret;
> +
> + smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL);
> + if (!smc)
> + return -ENOMEM;
> +
> + smc->dev = dev;
> +
> + smc->sram = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "sram");
> + if (!smc->sram)
> + return dev_err_probe(dev, EIO,
> + "No SRAM region");
> +
> + smc->sram_base = devm_ioremap_resource(dev, smc->sram);
> + if (IS_ERR(smc->sram_base))
> + return dev_err_probe(dev, PTR_ERR(smc->sram_base),
> + "Failed to map SRAM region");
> +
> + smc->rtk =
> + devm_apple_rtkit_init(dev, smc, NULL, 0, &apple_smc_rtkit_ops);
> + if (IS_ERR(smc->rtk))
> + return dev_err_probe(dev, PTR_ERR(smc->rtk),
> + "Failed to intialize RTKit");
> +
> + ret = apple_rtkit_wake(smc->rtk);
> + if (ret != 0)
> + return dev_err_probe(dev, ret,
> + "Failed to wake up SMC");
> +
> + ret = apple_rtkit_start_ep(smc->rtk, SMC_ENDPOINT);
> + if (ret != 0) {
> + dev_err(dev, "Failed to start endpoint");
> + goto cleanup;
> + }
> +
> + init_completion(&smc->init_done);
> + init_completion(&smc->cmd_done);
> +
> + ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT,
> + FIELD_PREP(SMC_MSG, SMC_MSG_INITIALIZE), NULL, false);
> + if (ret < 0)
> + return dev_err_probe(dev, ret,
> + "Failed to send init message");
This should probably also "goto cleanup" here just in case we somehow manage to
send the shutdown message after this one failed.
> +
> + if (wait_for_completion_timeout(&smc->init_done,
> + msecs_to_jiffies(SMC_RECV_TIMEOUT)) == 0) {
> + ret = -ETIMEDOUT;
> + dev_err(dev, "Timed out initializing SMC");
> + goto cleanup;
> + }
> +
> + if (!smc->alive) {
> + ret = -EIO;
> + goto cleanup;
> + }
> +
> + smc->core = apple_smc_probe(dev, &apple_smc_rtkit_be_ops, smc);
> + if (IS_ERR(smc->core)) {
> + ret = PTR_ERR(smc->core);
> + goto cleanup;
> + }
> +
> + return 0;
> +
> +cleanup:
> + /* Try to shut down RTKit, if it's not completely wedged */
> + if (apple_rtkit_is_running(smc->rtk))
> + apple_rtkit_quiesce(smc->rtk);
> +
> + return ret;
> +}
> +
> +static int apple_smc_rtkit_remove(struct platform_device *pdev)
> +{
> + struct apple_smc *core = platform_get_drvdata(pdev);
> + struct apple_smc_rtkit *smc = apple_smc_get_cookie(core);
> +
> + apple_smc_remove(core);
> +
> + if (apple_rtkit_is_running(smc->rtk))
> + apple_rtkit_quiesce(smc->rtk);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id apple_smc_rtkit_of_match[] = {
> + { .compatible = "apple,smc" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, apple_smc_rtkit_of_match);
> +
> +static struct platform_driver apple_smc_rtkit_driver = {
> + .driver = {
> + .name = "macsmc-rtkit",
> + .owner = THIS_MODULE,
> + .of_match_table = apple_smc_rtkit_of_match,
> + },
> + .probe = apple_smc_rtkit_probe,
> + .remove = apple_smc_rtkit_remove,
> +};
> +module_platform_driver(apple_smc_rtkit_driver);
> +
> +MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
> +MODULE_LICENSE("Dual MIT/GPL");
> +MODULE_DESCRIPTION("Apple SMC RTKit backend driver");
> diff --git a/include/linux/mfd/macsmc.h b/include/linux/mfd/macsmc.h
> new file mode 100644
> index 000000000000..39b4dc4ca881
> --- /dev/null
> +++ b/include/linux/mfd/macsmc.h
> @@ -0,0 +1,86 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple SMC core definitions
> + * Copyright (C) The Asahi Linux Contributors
> + */
> +
> +#ifndef _LINUX_MFD_MACSMC_H
> +#define _LINUX_MFD_MACSMC_H
> +
> +struct apple_smc;
> +
> +typedef u32 smc_key;
> +
> +#define SMC_KEY(s) (smc_key)(_SMC_KEY(#s))
> +#define _SMC_KEY(s) (((s)[0] << 24) | ((s)[1] << 16) | ((s)[2] << 8) |
> (s)[3])
> +
> +#define APPLE_SMC_READABLE BIT(7)
> +#define APPLE_SMC_WRITABLE BIT(6)
> +#define APPLE_SMC_FUNCTION BIT(4)
> +
> +struct apple_smc_key_info {
> + u8 size;
> + u32 type_code;
> + u8 flags;
> +};
> +
> +int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf,
> size_t size);
> +int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf,
> size_t size);
> +int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void
> *buf, size_t size);
> +int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf,
> size_t wsize,
> + void *rbuf, size_t rsize);
> +
> +int apple_smc_get_key_count(struct apple_smc *smc);
> +int apple_smc_find_first_key_index(struct apple_smc *smc, smc_key key);
> +int apple_smc_get_key_by_index(struct apple_smc *smc, int index,
> smc_key *key);
> +int apple_smc_get_key_info(struct apple_smc *smc, smc_key key, struct
> apple_smc_key_info *info);
> +
> +static inline bool apple_smc_key_exists(struct apple_smc *smc, smc_key
> key)
> +{
> + return apple_smc_get_key_info(smc, key, NULL) >= 0;
> +}
> +
> +#define APPLE_SMC_TYPE_OPS(type) \
> + static inline int apple_smc_read_##type(struct apple_smc *smc,
> smc_key key, type *p) \
> + { \
> + int ret = apple_smc_read(smc, key, p, sizeof(*p)); \
> + return (ret < 0) ? ret : ((ret != sizeof(*p)) ? -EINVAL : 0); \
> + } \
> + static inline int apple_smc_write_##type(struct apple_smc *smc,
> smc_key key, type p) \
> + { \
> + return apple_smc_write(smc, key, &p, sizeof(p)); \
> + } \
> + static inline int apple_smc_write_##type##_atomic(struct apple_smc
> *smc, smc_key key, type p) \
> + { \
> + return apple_smc_write_atomic(smc, key, &p, sizeof(p)); \
> + } \
> + static inline int apple_smc_rw_##type(struct apple_smc *smc, smc_key
> key, \
> + type w, type *r) \
> + { \
> + int ret = apple_smc_rw(smc, key, &w, sizeof(w), r, sizeof(*r)); \
> + return (ret < 0) ? ret : ((ret != sizeof(*r)) ? -EINVAL : 0); \
> + }
> +
> +APPLE_SMC_TYPE_OPS(u64)
> +APPLE_SMC_TYPE_OPS(u32)
> +APPLE_SMC_TYPE_OPS(u16)
> +APPLE_SMC_TYPE_OPS(u8)
> +APPLE_SMC_TYPE_OPS(s64)
> +APPLE_SMC_TYPE_OPS(s32)
> +APPLE_SMC_TYPE_OPS(s16)
> +APPLE_SMC_TYPE_OPS(s8)
> +
> +static inline int apple_smc_read_flag(struct apple_smc *smc, smc_key
> key)
> +{
> + u8 val;
> + int ret = apple_smc_read_u8(smc, key, &val);
> + if (ret < 0)
> + return ret;
> + return val ? 1 : 0;
> +}
> +#define apple_smc_write_flag apple_smc_write_u8
> +
> +int apple_smc_register_notifier(struct apple_smc *smc, struct
> notifier_block *n);
> +int apple_smc_unregister_notifier(struct apple_smc *smc, struct
> notifier_block *n);
> +
> +#endif
> --
> 2.30.2
Sven
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-09-01 17:52 UTC|newest]
Thread overview: 171+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-01 13:54 [PATCH 0/6] Add Apple Mac System Management Controller GPIOs Russell King (Oracle)
2022-09-01 13:54 ` [PATCH 1/6] dt-bindings: mfd: add binding for Apple Mac System Management Controller Russell King (Oracle)
2022-09-01 15:06 ` Krzysztof Kozlowski
2022-09-01 15:12 ` Russell King (Oracle)
2022-09-01 15:15 ` Krzysztof Kozlowski
2022-09-01 15:24 ` Russell King (Oracle)
2022-09-01 15:45 ` Krzysztof Kozlowski
2022-09-01 15:56 ` Russell King (Oracle)
2022-09-01 16:25 ` Krzysztof Kozlowski
2022-09-01 16:47 ` Russell King (Oracle)
2022-09-01 22:33 ` Rob Herring
2022-09-02 15:06 ` Mark Kettenis
2022-09-02 17:28 ` Rob Herring
2022-09-05 10:24 ` Russell King (Oracle)
2022-09-06 9:04 ` Russell King (Oracle)
2022-09-06 9:31 ` Mark Kettenis
2022-09-06 11:22 ` Linus Walleij
2022-09-06 11:36 ` Hector Martin
2022-09-06 11:57 ` Linus Walleij
2022-09-06 13:28 ` Hector Martin
2022-09-06 13:43 ` Russell King (Oracle)
2022-09-06 13:53 ` Hector Martin
2022-09-06 14:25 ` Mark Kettenis
2022-09-06 14:54 ` Russell King (Oracle)
2022-09-06 15:38 ` Mark Kettenis
2022-09-06 15:55 ` Rob Herring
2022-09-06 13:46 ` Linus Walleij
2022-09-06 15:34 ` Rob Herring
2022-09-06 16:10 ` Rob Herring
2022-09-06 17:00 ` Hector Martin
2022-09-06 17:35 ` Rob Herring
2022-09-06 17:40 ` Sven Peter
2022-09-06 18:38 ` Hector Martin
2022-09-07 9:39 ` Mark Kettenis
2022-09-01 22:26 ` Rob Herring
2022-09-02 14:49 ` Mark Kettenis
2022-09-02 17:04 ` Rob Herring
2022-09-01 19:14 ` Rob Herring
2022-09-01 13:54 ` [PATCH 2/6] dt-bindings: gpio: add binding for the GPIO block for Apple Mac SMC Russell King (Oracle)
2022-09-01 15:11 ` Krzysztof Kozlowski
2022-09-01 15:14 ` Russell King (Oracle)
2022-09-01 13:54 ` [PATCH 3/6] soc: apple: rtkit: Add apple_rtkit_poll Russell King
2022-09-01 17:00 ` Sven Peter
2022-09-01 17:25 ` Eric Curtin
2022-09-01 13:54 ` [PATCH 4/6] platform/apple: Add new Apple Mac SMC driver Russell King
2022-09-01 17:50 ` Sven Peter [this message]
2022-09-05 10:55 ` Russell King (Oracle)
2022-09-05 16:53 ` Hector Martin
2022-09-01 19:26 ` Andy Shevchenko
2022-09-02 6:45 ` Sven Peter
2022-09-05 14:45 ` Hector Martin
2022-09-05 15:00 ` Andy Shevchenko
2022-09-08 10:58 ` Lee Jones
2022-09-08 11:28 ` Hector Martin
2022-09-08 12:31 ` Lee Jones
2022-09-08 12:58 ` Hector Martin
2022-09-08 13:29 ` Linus Walleij
2022-09-08 13:36 ` Lee Jones
2022-09-08 13:58 ` Hector Martin
2022-09-09 7:50 ` Lee Jones
2022-09-12 10:03 ` Russell King (Oracle)
2022-09-12 10:55 ` Lee Jones
2022-10-28 15:36 ` Russell King (Oracle)
2022-10-31 8:46 ` Lee Jones
2022-10-31 9:03 ` Hector Martin
2022-10-31 9:44 ` Russell King (Oracle)
2022-10-31 17:24 ` Lee Jones
2022-10-31 19:47 ` Russell King (Oracle)
2022-11-01 9:59 ` Lee Jones
2022-10-29 6:40 ` Hector Martin
2022-10-31 8:48 ` Lee Jones
2022-10-31 8:58 ` Hector Martin
2022-10-31 9:29 ` Lee Jones
2022-10-31 9:44 ` Hector Martin
2022-10-31 17:23 ` Lee Jones
2022-10-31 19:34 ` Russell King (Oracle)
2022-11-02 13:12 ` Lee Jones
2022-11-02 15:54 ` Russell King (Oracle)
2022-09-01 13:54 ` [PATCH 5/6] gpio: Add new gpio-macsmc driver for Apple Macs Russell King
2022-09-01 18:55 ` Andy Shevchenko
2022-09-01 21:51 ` Martin Povišer
2022-09-02 6:31 ` Andy Shevchenko
[not found] ` <3B649A66-8116-432D-B88A-B5CE493EF930@cutebit.org>
[not found] ` <CAHp75VeB3_sZ2vsSxMSsLeJSkyemDh9iOPHXJCN1mhodA13LNQ@mail.gmail.com>
2022-09-02 11:12 ` Martin Povišer
2022-09-02 13:33 ` Andy Shevchenko
2022-09-02 13:36 ` Andy Shevchenko
2022-09-02 13:37 ` Martin Povišer
2022-09-02 14:41 ` Andy Shevchenko
2022-09-02 14:45 ` Russell King (Oracle)
2022-09-02 10:05 ` Russell King (Oracle)
2022-09-02 10:37 ` Andy Shevchenko
2022-09-02 11:32 ` Russell King (Oracle)
2022-09-02 13:39 ` Andy Shevchenko
2022-09-02 14:46 ` Russell King (Oracle)
2022-09-02 14:53 ` Andy Shevchenko
2022-09-02 15:34 ` Russell King (Oracle)
2022-09-02 15:43 ` Andy Shevchenko
2022-09-05 10:20 ` Russell King (Oracle)
2022-09-05 10:32 ` Andy Shevchenko
2022-09-05 13:10 ` Russell King (Oracle)
2022-09-05 13:16 ` Andy Shevchenko
2022-09-05 14:01 ` Russell King (Oracle)
2022-09-05 14:02 ` Russell King (Oracle)
2022-09-05 14:42 ` Andy Shevchenko
2022-09-05 14:53 ` Russell King (Oracle)
2022-09-05 14:50 ` Andy Shevchenko
2022-09-05 15:52 ` Hector Martin
2022-09-05 15:56 ` Russell King (Oracle)
2022-09-05 15:32 ` Russell King (Oracle)
2022-09-05 15:44 ` Martin Povišer
2022-09-05 15:58 ` Hector Martin
2022-09-05 16:13 ` Russell King (Oracle)
2022-09-05 19:10 ` Linus Walleij
2022-09-06 6:51 ` Hector Martin
2022-09-05 15:47 ` Hector Martin
2022-09-05 15:39 ` Hector Martin
2022-09-05 15:16 ` Hector Martin
2022-09-05 15:04 ` Hector Martin
2022-09-02 9:42 ` Linus Walleij
2022-09-01 13:54 ` [PATCH 6/6] gpio: macsmc: Add IRQ support Russell King
2022-09-01 18:03 ` Andy Shevchenko
2022-09-05 11:54 ` Russell King (Oracle)
[not found] ` <CAHp75VeDGCp8J6wnmCqGpV++vs2Zur9Mfp71Dk8dVXcuHFnCrQ@mail.gmail.com>
2022-09-05 13:21 ` Andy Shevchenko
2022-09-02 13:21 ` Linus Walleij
2022-09-05 12:47 ` Russell King (Oracle)
2022-09-05 13:19 ` Fwd: " Andy Shevchenko
2022-09-05 21:43 ` Russell King (Oracle)
2022-09-05 13:27 ` Linus Walleij
2022-09-06 7:00 ` Hector Martin
2022-09-06 7:47 ` Russell King (Oracle)
2022-09-06 8:00 ` Hector Martin
2022-09-01 15:12 ` [PATCH 0/6] Add Apple Mac System Management Controller GPIOs Krzysztof Kozlowski
2022-10-27 15:35 ` Russell King (Oracle)
2022-11-08 16:32 ` [PATCH v3 0/7] " Russell King (Oracle)
2022-11-08 16:33 ` [PATCH v3 1/7] mfd: Add core Apple Mac SMC driver Russell King
2022-11-14 9:52 ` Lee Jones
2022-11-14 10:35 ` Andy Shevchenko
2022-11-08 16:33 ` [PATCH v3 2/7] lib/vsprintf: Add support for generic FOURCCs by extending %p4cc Russell King
2022-11-14 15:34 ` Petr Mladek
2022-11-14 15:46 ` Andy Shevchenko
2022-11-14 16:18 ` Petr Mladek
2022-11-14 16:15 ` Russell King (Oracle)
2022-11-14 16:46 ` Russell King (Oracle)
2022-11-22 12:43 ` Petr Mladek
2022-11-22 14:49 ` Petr Mladek
2022-11-08 16:33 ` [PATCH v3 3/7] dt-bindings: mfd: add binding for Apple Mac System Management Controller Russell King (Oracle)
2022-11-08 20:42 ` Linus Walleij
2022-11-08 20:55 ` Krzysztof Kozlowski
2022-11-08 22:22 ` Russell King (Oracle)
2022-11-09 8:35 ` Krzysztof Kozlowski
2022-11-09 22:17 ` Rob Herring
2022-11-10 11:35 ` Hector Martin
2022-11-10 11:48 ` Russell King (Oracle)
2022-11-10 14:00 ` Krzysztof Kozlowski
2022-11-10 14:14 ` Russell King (Oracle)
2022-11-10 14:21 ` Krzysztof Kozlowski
2022-11-10 14:23 ` Russell King (Oracle)
2022-11-10 14:36 ` Krzysztof Kozlowski
2022-11-10 14:43 ` Russell King (Oracle)
2022-11-14 10:05 ` Lee Jones
2022-11-08 22:30 ` Rob Herring
2022-11-08 16:33 ` [PATCH v3 4/7] platform/apple: Add new Apple Mac SMC driver Russell King
2022-11-08 16:33 ` [PATCH v3 5/7] arm64: dts: apple: Add SMC node to t8103 devicetrees Russell King
2022-11-08 16:33 ` [PATCH v3 6/7] dt-bindings: gpio: add binding for the GPIO block for Apple Mac SMC Russell King (Oracle)
2022-11-08 20:56 ` Krzysztof Kozlowski
2022-11-08 22:09 ` Russell King (Oracle)
2022-11-09 7:31 ` Hector Martin
2022-11-09 8:36 ` Krzysztof Kozlowski
2022-11-09 9:12 ` Russell King (Oracle)
2022-11-09 9:19 ` Krzysztof Kozlowski
2022-11-08 22:30 ` Rob Herring
2022-11-08 16:33 ` [PATCH v3 7/7] gpio: Add new gpio-macsmc driver for Apple Macs Russell King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1c876ae2-9d8b-4f47-8ca7-797fb484ad03@www.fastmail.com \
--to=sven@svenpeter.dev \
--cc=alyssa@rosenzweig.io \
--cc=arnd@arndb.de \
--cc=asahi@lists.linux.dev \
--cc=brgl@bgdev.pl \
--cc=lee@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=marcan@marcan.st \
--cc=rmk+kernel@armlinux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).