From 4352b8aee98005853aa63f57d6377282de17a33f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 23 Aug 2026 13:28:57 -0700 Subject: Merge tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux Pull I3C updates from Alexandre Belloni: "A new driver this cycle, for the AMD AXI I3C controller. There are also new features such as IBI wakeup support, SETAASA device discovery and ACPI support for the the DAA methods, meaning we can now communicate with the SPD devices on DDR5 modules. New driver: - AMD AXI I3C master controller Subsystem: - I3C Common Command Code (CCC) handling improvements, especially around GET CCCs - SETAASA device discovery support - ACPI support for all existing DAA methods like SETDASA, SETNEWDA as well as I2C devices on I3C bus - IBI-based wakeup support Drivers: - dw: SETAASA support - mipi-i3c-hci: advertise IBI wakeup capability, AMD_PT I3C controller support, PIO queue management support for HCI v1.2 - renesas: improve suspend to RAM support, add runtime PM support" * tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (70 commits) i3c: dw: reduce do_daa time if there's no client i3c: mipi-i3c-hci: Add support for AMD_PT I3C controller i3c: mipi-i3c-hci: Add PIO queue management support for HCI v1.2 i3c: mipi-i3c-hci: Fix missing STAT_IBI_STATUS_THLD in PIO mode i3c: dw: rename "pclk" to "apb" to match dt-binding i3c: dw: make struct dw_i3c_cmd smaller i3c: dw: use COMMAND_PORT_TRANSFER_ARG instead of hardcoding i3c: renesas: Don't register devices when ENTDAA times out i3c: master: dw-i3c-master: fix OD timing for first broadcast i3c: mipi-i3c-hci: Advertise IBI wakeup capability i3c: mipi-i3c-hci: Factor out i3c_hci_sysdev() i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI i3c: master: Reject IBI requests from non-IBI-capable devices i3c: master: Add helper to query bus wakeup requirements i3c: master: Report wakeup events for IBIs i3c: master: Support IBI-based wakeup capability i3c: master: Fix potential UAF in i3c_device_match() i3c: master: Fix potential UAF in i3c_device_uevent() i3c: Make dev->desc locking assumptions explicit i3c: master: Fix use-after-free of master->this ... --- samples/pfsm/.gitignore | 2 + samples/pfsm/Makefile | 4 ++ samples/pfsm/pfsm-wakeup.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 samples/pfsm/.gitignore create mode 100644 samples/pfsm/Makefile create mode 100644 samples/pfsm/pfsm-wakeup.c (limited to 'samples/pfsm') diff --git a/samples/pfsm/.gitignore b/samples/pfsm/.gitignore new file mode 100644 index 000000000..f350a030a --- /dev/null +++ b/samples/pfsm/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +/pfsm-wakeup diff --git a/samples/pfsm/Makefile b/samples/pfsm/Makefile new file mode 100644 index 000000000..213e8d9f5 --- /dev/null +++ b/samples/pfsm/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +userprogs-always-y += pfsm-wakeup + +userccflags += -I usr/include diff --git a/samples/pfsm/pfsm-wakeup.c b/samples/pfsm/pfsm-wakeup.c new file mode 100644 index 000000000..299dd9e1f --- /dev/null +++ b/samples/pfsm/pfsm-wakeup.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TPS6594 PFSM userspace example + * + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ + * + * This example shows how to use PFSMs from a userspace application, + * on TI j721s2 platform. The PMIC is armed to be triggered by a RTC + * alarm to execute state transition (RETENTION to ACTIVE). + */ + +#include +#include +#include +#include + +#include +#include + +#define ALARM_DELTA_SEC 30 + +#define RTC_A "/dev/rtc0" + +#define PMIC_NB 3 +#define PMIC_A "/dev/pfsm-0-0x48" +#define PMIC_B "/dev/pfsm-0-0x4c" +#define PMIC_C "/dev/pfsm-2-0x58" + +static const char * const dev_pfsm[] = {PMIC_A, PMIC_B, PMIC_C}; + +int main(int argc, char *argv[]) +{ + int i, ret, fd_rtc, fd_pfsm[PMIC_NB] = { 0 }; + struct rtc_time rtc_tm; + struct pmic_state_opt pmic_opt = { 0 }; + unsigned long data; + + fd_rtc = open(RTC_A, O_RDONLY); + if (fd_rtc < 0) { + perror("Failed to open RTC device."); + goto out; + } + + for (i = 0 ; i < PMIC_NB ; i++) { + fd_pfsm[i] = open(dev_pfsm[i], O_RDWR); + if (fd_pfsm[i] < 0) { + perror("Failed to open PFSM device."); + goto out; + } + } + + /* Read RTC date/time */ + ret = ioctl(fd_rtc, RTC_RD_TIME, &rtc_tm); + if (ret < 0) { + perror("Failed to read RTC date/time."); + goto out; + } + printf("Current RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); + + /* Set RTC alarm to ALARM_DELTA_SEC sec in the future, and check for rollover */ + rtc_tm.tm_sec += ALARM_DELTA_SEC; + if (rtc_tm.tm_sec >= 60) { + rtc_tm.tm_sec %= 60; + rtc_tm.tm_min++; + } + if (rtc_tm.tm_min == 60) { + rtc_tm.tm_min = 0; + rtc_tm.tm_hour++; + } + if (rtc_tm.tm_hour == 24) + rtc_tm.tm_hour = 0; + ret = ioctl(fd_rtc, RTC_ALM_SET, &rtc_tm); + if (ret < 0) { + perror("Failed to set RTC alarm."); + goto out; + } + + /* Enable alarm interrupts */ + ret = ioctl(fd_rtc, RTC_AIE_ON, 0); + if (ret < 0) { + perror("Failed to enable alarm interrupts."); + goto out; + } + printf("Waiting %d seconds for alarm...\n", ALARM_DELTA_SEC); + + /* + * Set RETENTION state with options for PMIC_C/B/A respectively. + * Since PMIC_A is master, it should be the last one to be configured. + */ + pmic_opt.ddr_retention = 1; + for (i = PMIC_NB - 1 ; i >= 0 ; i--) { + printf("Set RETENTION state for PMIC_%d.\n", i); + sleep(1); + ret = ioctl(fd_pfsm[i], PMIC_SET_RETENTION_STATE, &pmic_opt); + if (ret < 0) { + perror("Failed to set RETENTION state."); + goto out_reset; + } + } + + /* This blocks until the alarm ring causes an interrupt */ + ret = read(fd_rtc, &data, sizeof(unsigned long)); + if (ret < 0) + perror("Failed to get RTC alarm."); + else + puts("Alarm rang.\n"); + +out_reset: + ioctl(fd_rtc, RTC_AIE_OFF, 0); + + /* Set ACTIVE state for PMIC_A */ + ioctl(fd_pfsm[0], PMIC_SET_ACTIVE_STATE, 0); + +out: + for (i = 0 ; i < PMIC_NB ; i++) + if (fd_pfsm[i]) + close(fd_pfsm[i]); + + if (fd_rtc) + close(fd_rtc); + + return 0; +} -- cgit v1.3.1