aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch
diff options
context:
space:
mode:
authorMarty Jones <mj8263788@gmail.com>2024-01-18 16:23:52 -0500
committerÁlvaro Fernández Rojas <noltari@gmail.com>2024-01-25 17:46:45 +0100
commit2e715fb4fc8014eefddf5d9232105740f10e06ba (patch)
tree439b916ff394d4f9d6e50ab1ad553c6bef96c5ed /target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch
parent65f599223d6d24fa68059066c6fa85b862841632 (diff)
downloadupstream-2e715fb4fc8014eefddf5d9232105740f10e06ba.tar.gz
upstream-2e715fb4fc8014eefddf5d9232105740f10e06ba.tar.bz2
upstream-2e715fb4fc8014eefddf5d9232105740f10e06ba.zip
bcm27xx: update 6.1 patches to latest version
Add support for BCM2712 (Raspberry Pi 5). https://github.com/raspberrypi/linux/commit/3bb5880ab3dd31f75c07c3c33bf29c5d469b28f3 Patches were generated from the diff between linux kernel branch linux-6.1.y and rpi-6.1.y from raspberry pi kernel source: - git format-patch linux-6.1.y...rpi-6.1.y Build system: x86_64 Build-tested: bcm2708, bcm2709, bcm2710, bcm2711 Run-tested: bcm2710/RPi3B, bcm2711/RPi4B Signed-off-by: Marty Jones <mj8263788@gmail.com> [Remove applied and reverted patches, squash patches and config commits] Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch')
-rw-r--r--target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch237
1 files changed, 237 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch b/target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch
new file mode 100644
index 00000000000..e2b8c6c6a10
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.1/950-0919-rtc-rtc-rpi-Add-simple-RTC-driver-for-Raspberry-Pi.patch
@@ -0,0 +1,237 @@
+From 222dedcdc09247126d39364a614ff2019789f52a Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Fri, 7 Jul 2023 20:00:45 +0100
+Subject: [PATCH] rtc: rtc-rpi: Add simple RTC driver for Raspberry Pi
+
+This supports setting and reading the real time clock
+and supports wakeup alarms.
+
+To support wake up alarms you want this bootloader config:
+ POWER_OFF_ON_HALT=1
+ WAKE_ON_GPIO=0
+
+You can test with:
+ echo +600 | sudo tee /sys/class/rtc/rtc0/wakealarm
+ sudo halt
+
+That will halt (in an almost no power state),
+then wake and restart after 10 minutes.
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/rtc/Kconfig | 11 +++
+ drivers/rtc/Makefile | 1 +
+ drivers/rtc/rtc-rpi.c | 177 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 189 insertions(+)
+ create mode 100644 drivers/rtc/rtc-rpi.c
+
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -223,6 +223,17 @@ config RTC_DRV_AC100
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ac100.
+
++config RTC_DRV_RPI
++ tristate "Raspberry Pi RTC"
++ depends on ARCH_BRCMSTB || COMPILE_TEST
++ default ARCH_BRCMSTB
++ help
++ If you say yes here you get support for the RTC found on
++ Raspberry Pi devices.
++
++ This driver can also be built as a module. If so, the module
++ will be called rtc-rpi.
++
+ config RTC_DRV_BRCMSTB
+ tristate "Broadcom STB wake-timer"
+ depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -140,6 +140,7 @@ obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5
+ obj-$(CONFIG_RTC_DRV_RC5T619) += rtc-rc5t619.o
+ obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o
+ obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
++obj-$(CONFIG_RTC_DRV_RPI) += rtc-rpi.o
+ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
+ obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
+ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
+--- /dev/null
++++ b/drivers/rtc/rtc-rpi.c
+@@ -0,0 +1,177 @@
++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
++/**
++ * rtc-rpi.c
++ *
++ * RTC driver using firmware mailbox
++ * Supports battery backed RTC and wake alarms
++ *
++ * Based on rtc-meson-vrtc by Neil Armstrong
++ *
++ * Copyright (c) 2023, Raspberry Pi Ltd.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++#include <linux/of.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++struct rpi_rtc_data {
++ struct rtc_device *rtc;
++ struct rpi_firmware *fw;
++};
++
++#define RPI_FIRMWARE_GET_RTC_REG 0x00030087
++#define RPI_FIRMWARE_SET_RTC_REG 0x00038087
++enum {RTC_TIME, RTC_ALARM, RTC_ALARM_PENDING, RTC_ALARM_ENABLE};
++
++static int rpi_rtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_TIME};
++ int err;
++
++ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
++ &data, sizeof(data));
++ rtc_time64_to_tm(data[1], tm);
++ return err;
++}
++
++static int rpi_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_TIME, rtc_tm_to_time64(tm)};
++
++ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
++ &data, sizeof(data));
++}
++
++static int rpi_rtc_alarm_irq_is_enabled(struct device *dev, unsigned char *enabled)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_ALARM_ENABLE};
++ s32 err = 0;
++
++ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
++ &data, sizeof(data));
++ *enabled = data[1] & 0x1;
++ return err;
++}
++
++static int rpi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_ALARM_ENABLE, enabled};
++
++ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
++ &data, sizeof(data));
++}
++
++static int rpi_rtc_alarm_clear_pending(struct device *dev)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_ALARM_PENDING, 1};
++
++ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
++ &data, sizeof(data));
++}
++
++static int rpi_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_ALARM};
++ s32 err = 0;
++
++ err = rpi_rtc_alarm_irq_is_enabled(dev, &alarm->enabled);
++ if (!err)
++ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
++ &data, sizeof(data));
++ rtc_time64_to_tm(data[1], &alarm->time);
++
++ return err;
++}
++
++static int rpi_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
++ u32 data[2] = {RTC_ALARM, rtc_tm_to_time64(&alarm->time)};
++ int err;
++
++ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
++ &data, sizeof(data));
++
++ if (err == 0)
++ err = rpi_rtc_alarm_irq_enable(dev, alarm->enabled);
++
++ return err;
++}
++
++static const struct rtc_class_ops rpi_rtc_ops = {
++ .read_time = rpi_rtc_read_time,
++ .set_time = rpi_rtc_set_time,
++ .read_alarm = rpi_rtc_read_alarm,
++ .set_alarm = rpi_rtc_set_alarm,
++ .alarm_irq_enable = rpi_rtc_alarm_irq_enable,
++};
++
++static int rpi_rtc_probe(struct platform_device *pdev)
++{
++ struct rpi_rtc_data *vrtc;
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct device_node *fw_node;
++ struct rpi_firmware *fw;
++ int ret;
++
++ fw_node = of_parse_phandle(np, "firmware", 0);
++ if (!fw_node) {
++ dev_err(dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ fw = rpi_firmware_get(fw_node);
++ if (!fw)
++ return -EPROBE_DEFER;
++
++ vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
++ if (!vrtc)
++ return -ENOMEM;
++
++ vrtc->fw = fw;
++
++ device_init_wakeup(&pdev->dev, 1);
++
++ platform_set_drvdata(pdev, vrtc);
++
++ vrtc->rtc = devm_rtc_allocate_device(&pdev->dev);
++ if (IS_ERR(vrtc->rtc))
++ return PTR_ERR(vrtc->rtc);
++
++ set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, vrtc->rtc->features);
++ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, vrtc->rtc->features);
++
++ vrtc->rtc->ops = &rpi_rtc_ops;
++ ret = devm_rtc_register_device(vrtc->rtc);
++
++ rpi_rtc_alarm_clear_pending(dev);
++ return ret;
++}
++
++static const struct of_device_id rpi_rtc_dt_match[] = {
++ { .compatible = "raspberrypi,rpi-rtc"},
++ {},
++};
++MODULE_DEVICE_TABLE(of, rpi_rtc_dt_match);
++
++static struct platform_driver rpi_rtc_driver = {
++ .probe = rpi_rtc_probe,
++ .driver = {
++ .name = "rpi-rtc",
++ .of_match_table = rpi_rtc_dt_match,
++ },
++};
++
++module_platform_driver(rpi_rtc_driver);
++
++MODULE_DESCRIPTION("Raspberry Pi RTC driver");
++MODULE_LICENSE("GPL");