aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 10:54:34 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 19:07:07 +0200
commit8299d1f057439f94c6a4412e2e5c5082b82a30c9 (patch)
tree1bf678d61f11f7394493be464c7876e496f7faed /target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch
parent33b6885975ce376ff075362b7f0890326043111b (diff)
downloadupstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.gz
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.bz2
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.zip
bcm27xx: add kernel 5.10 support
Rebased RPi foundation patches on linux 5.10.59, removed applied and reverted patches, wireless patches and defconfig patches. bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 4B v1.1 4G bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch394
1 files changed, 394 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch b/target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch
new file mode 100644
index 0000000000..121914c6a6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.10/950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch
@@ -0,0 +1,394 @@
+From 2150bf813a64c18cdc56ae6b84036377c242cebd Mon Sep 17 00:00:00 2001
+From: Serge Schneider <serge@raspberrypi.com>
+Date: Mon, 2 Dec 2019 14:48:05 +0000
+Subject: [PATCH] Add Raspberry Pi PoE+ HAT support
+
+Signed-off-by: Serge Schneider <serge@raspberrypi.com>
+---
+ drivers/hwmon/rpi-poe-fan.c | 35 +++-
+ drivers/power/supply/Kconfig | 6 +
+ drivers/power/supply/Makefile | 1 +
+ drivers/power/supply/rpi_poe_power.c | 227 +++++++++++++++++++++
+ include/soc/bcm2835/raspberrypi-firmware.h | 3 +-
+ 5 files changed, 261 insertions(+), 11 deletions(-)
+ create mode 100644 drivers/power/supply/rpi_poe_power.c
+
+--- a/drivers/hwmon/rpi-poe-fan.c
++++ b/drivers/hwmon/rpi-poe-fan.c
+@@ -28,6 +28,7 @@
+ struct rpi_poe_fan_ctx {
+ struct mutex lock;
+ struct rpi_firmware *fw;
++ u32 set_tag;
+ unsigned int pwm_value;
+ unsigned int def_pwm_value;
+ unsigned int rpi_poe_fan_state;
+@@ -43,13 +44,15 @@ struct fw_tag_data_s{
+ u32 ret;
+ };
+
+-static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val){
++static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val, u32 set_tag)
++{
+ struct fw_tag_data_s fw_tag_data = {
+ .reg = reg,
+ .val = *val
+ };
+ int ret;
+- ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POE_HAT_VAL,
++
++ ret = rpi_firmware_property(fw, set_tag,
+ &fw_tag_data, sizeof(fw_tag_data));
+ if (ret) {
+ return ret;
+@@ -82,7 +85,7 @@ static int rpi_poe_reboot(struct notifie
+ nb);
+
+ if (ctx->pwm_value != ctx->def_pwm_value)
+- write_reg(ctx->fw, POE_CUR_PWM, &ctx->def_pwm_value);
++ write_reg(ctx->fw, POE_CUR_PWM, &ctx->def_pwm_value, ctx->set_tag);
+
+ return NOTIFY_DONE;
+ }
+@@ -95,7 +98,7 @@ static int __set_pwm(struct rpi_poe_fan
+ if (ctx->pwm_value == pwm)
+ goto exit_set_pwm_err;
+
+- ret = write_reg(ctx->fw, POE_CUR_PWM, &pwm);
++ ret = write_reg(ctx->fw, POE_CUR_PWM, &pwm, ctx->set_tag);
+ if (!ret)
+ ctx->pwm_value = pwm;
+ exit_set_pwm_err:
+@@ -110,7 +113,7 @@ static int __set_def_pwm(struct rpi_poe
+ if (ctx->def_pwm_value == def_pwm)
+ goto exit_set_def_pwm_err;
+
+- ret = write_reg(ctx->fw, POE_DEF_PWM, &def_pwm);
++ ret = write_reg(ctx->fw, POE_DEF_PWM, &def_pwm, ctx->set_tag);
+ if (!ret)
+ ctx->def_pwm_value = def_pwm;
+ exit_set_def_pwm_err:
+@@ -297,6 +300,7 @@ static int rpi_poe_fan_probe(struct plat
+ struct device *hwmon;
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *fw_node;
++ u32 revision;
+ int ret;
+
+ fw_node = of_parse_phandle(np, "firmware", 0);
+@@ -314,6 +318,17 @@ static int rpi_poe_fan_probe(struct plat
+ ctx->fw = rpi_firmware_get(fw_node);
+ if (!ctx->fw)
+ return -EPROBE_DEFER;
++ ret = rpi_firmware_property(ctx->fw,
++ RPI_FIRMWARE_GET_FIRMWARE_REVISION,
++ &revision, sizeof(revision));
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to get firmware revision: %i\n", ret);
++ return ret;
++ }
++ if (revision < 0x60af72e8)
++ ctx->set_tag = RPI_FIRMWARE_SET_POE_HAT_VAL_OLD;
++ else
++ ctx->set_tag = RPI_FIRMWARE_SET_POE_HAT_VAL;
+
+ platform_set_drvdata(pdev, ctx);
+
+@@ -378,9 +393,9 @@ static int rpi_poe_fan_remove(struct pla
+
+ unregister_reboot_notifier(&ctx->nb);
+ thermal_cooling_device_unregister(ctx->cdev);
+- if (ctx->pwm_value != value) {
+- write_reg(ctx->fw, POE_CUR_PWM, &value);
+- }
++ if (ctx->pwm_value != value)
++ write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
++
+ return 0;
+ }
+
+@@ -392,7 +407,7 @@ static int rpi_poe_fan_suspend(struct de
+ int ret = 0;
+
+ if (ctx->pwm_value != value)
+- ret = write_reg(ctx->fw, POE_CUR_PWM, &value);
++ ret = write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
+ return ret;
+ }
+
+@@ -403,7 +418,7 @@ static int rpi_poe_fan_resume(struct dev
+ int ret = 0;
+
+ if (value != 0)
+- ret = write_reg(ctx->fw, POE_CUR_PWM, &value);
++ ret = write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
+
+ return ret;
+ }
+--- a/drivers/power/supply/Kconfig
++++ b/drivers/power/supply/Kconfig
+@@ -28,6 +28,12 @@ config POWER_SUPPLY_HWMON
+ Say 'Y' here if you want power supplies to
+ have hwmon sysfs interface too.
+
++config RPI_POE_POWER
++ tristate "Raspberry Pi PoE+ HAT power supply driver"
++ depends on RASPBERRYPI_FIRMWARE
++ help
++ Say Y here to enable support for Raspberry Pi PoE+ (Power over Ethernet
++ Plus) HAT current measurement.
+
+ config PDA_POWER
+ tristate "Generic PDA/phone power driver"
+--- a/drivers/power/supply/Makefile
++++ b/drivers/power/supply/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supp
+ obj-$(CONFIG_POWER_SUPPLY_HWMON) += power_supply_hwmon.o
+ obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
+
++obj-$(CONFIG_RPI_POE_POWER) += rpi_poe_power.o
+ obj-$(CONFIG_PDA_POWER) += pda_power.o
+ obj-$(CONFIG_APM_POWER) += apm_power.o
+ obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o
+--- /dev/null
++++ b/drivers/power/supply/rpi_poe_power.c
+@@ -0,0 +1,227 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * rpi-poe-power.c - Raspberry Pi PoE+ HAT power supply driver.
++ *
++ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd.
++ * Based on axp20x_ac_power.c by Quentin Schulz <quentin.schulz@free-electrons.com>
++ *
++ * Author: Serge Schneider <serge@raspberrypi.org>
++ */
++
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/power_supply.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++#define RPI_POE_ADC_REG 0x2
++#define RPI_POE_FLAG_REG 0x4
++
++#define RPI_POE_FLAG_AT BIT(0)
++#define RPI_POE_FLAG_OC BIT(1)
++
++#define RPI_POE_CURRENT_AF_MAX (2500 * 1000)
++#define RPI_POE_CURRENT_AT_MAX (5000 * 1000)
++
++#define DRVNAME "rpi-poe-power-supply"
++
++struct rpi_poe_power_supply_ctx {
++ struct power_supply *supply;
++ struct rpi_firmware *fw;
++};
++
++struct fw_tag_data_s {
++ u32 reg;
++ u32 val;
++ u32 ret;
++};
++
++static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val)
++{
++ struct fw_tag_data_s fw_tag_data = {
++ .reg = reg,
++ .val = *val
++ };
++ int ret;
++
++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POE_HAT_VAL,
++ &fw_tag_data, sizeof(fw_tag_data));
++ if (ret)
++ return ret;
++ else if (fw_tag_data.ret)
++ return -EIO;
++ return 0;
++}
++
++static int read_reg(struct rpi_firmware *fw, u32 reg, u32 *val)
++{
++ struct fw_tag_data_s fw_tag_data = {
++ .reg = reg,
++ .val = *val
++ };
++ int ret;
++
++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_POE_HAT_VAL,
++ &fw_tag_data, sizeof(fw_tag_data));
++ if (ret)
++ return ret;
++ else if (fw_tag_data.ret)
++ return -EIO;
++
++ *val = fw_tag_data.val;
++ return 0;
++}
++
++static int rpi_poe_power_supply_get_property(struct power_supply *psy,
++ enum power_supply_property psp,
++ union power_supply_propval *r_val)
++{
++ struct rpi_poe_power_supply_ctx *ctx = power_supply_get_drvdata(psy);
++ int ret;
++ unsigned int val = 0;
++
++ switch (psp) {
++ case POWER_SUPPLY_PROP_HEALTH:
++ ret = read_reg(ctx->fw, RPI_POE_FLAG_REG, &val);
++ if (ret)
++ return ret;
++
++ if (val & RPI_POE_FLAG_OC) {
++ r_val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
++ val = RPI_POE_FLAG_OC;
++ ret = write_reg(ctx->fw, RPI_POE_FLAG_REG, &val);
++ if (ret)
++ return ret;
++ return 0;
++ }
++
++ r_val->intval = POWER_SUPPLY_HEALTH_GOOD;
++ return 0;
++
++ case POWER_SUPPLY_PROP_ONLINE:
++ ret = read_reg(ctx->fw, RPI_POE_ADC_REG, &val);
++ if (ret)
++ return ret;
++
++ r_val->intval = (val > 5);
++ return 0;
++
++ case POWER_SUPPLY_PROP_CURRENT_AVG:
++ val = 50;
++ ret = read_reg(ctx->fw, RPI_POE_ADC_REG, &val);
++ if (ret)
++ return ret;
++ val = (val * 3300)/9821;
++ r_val->intval = val * 1000;
++ return 0;
++
++ case POWER_SUPPLY_PROP_CURRENT_NOW:
++ ret = read_reg(ctx->fw, RPI_POE_ADC_REG, &val);
++ if (ret)
++ return ret;
++ val = (val * 3300)/9821;
++ r_val->intval = val * 1000;
++ return 0;
++
++ case POWER_SUPPLY_PROP_CURRENT_MAX:
++ ret = read_reg(ctx->fw, RPI_POE_FLAG_REG, &val);
++ if (ret)
++ return ret;
++
++ if (val & RPI_POE_FLAG_AT) {
++ r_val->intval = RPI_POE_CURRENT_AT_MAX;
++ return 0;
++ }
++ r_val->intval = RPI_POE_CURRENT_AF_MAX;
++ return 0;
++
++ default:
++ return -EINVAL;
++ }
++
++ return -EINVAL;
++}
++
++static enum power_supply_property rpi_poe_power_supply_properties[] = {
++ POWER_SUPPLY_PROP_HEALTH,
++ POWER_SUPPLY_PROP_ONLINE,
++ POWER_SUPPLY_PROP_CURRENT_AVG,
++ POWER_SUPPLY_PROP_CURRENT_NOW,
++ POWER_SUPPLY_PROP_CURRENT_MAX,
++};
++
++static const struct power_supply_desc rpi_poe_power_supply_desc = {
++ .name = "rpi-poe",
++ .type = POWER_SUPPLY_TYPE_MAINS,
++ .properties = rpi_poe_power_supply_properties,
++ .num_properties = ARRAY_SIZE(rpi_poe_power_supply_properties),
++ .get_property = rpi_poe_power_supply_get_property,
++};
++
++static int rpi_poe_power_supply_probe(struct platform_device *pdev)
++{
++ struct power_supply_config psy_cfg = {};
++ struct rpi_poe_power_supply_ctx *ctx;
++ struct device_node *fw_node;
++ u32 revision;
++
++ if (!of_device_is_available(pdev->dev.of_node))
++ return -ENODEV;
++
++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
++ if (!fw_node) {
++ dev_err(&pdev->dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
++ if (!ctx)
++ return -ENOMEM;
++
++ ctx->fw = rpi_firmware_get(fw_node);
++ if (!ctx->fw)
++ return -EPROBE_DEFER;
++ if (rpi_firmware_property(ctx->fw,
++ RPI_FIRMWARE_GET_FIRMWARE_REVISION,
++ &revision, sizeof(revision))) {
++ dev_err(&pdev->dev, "Failed to get firmware revision\n");
++ return -ENOENT;
++ }
++ if (revision < 0x60af72e8) {
++ dev_err(&pdev->dev, "Unsupported firmware\n");
++ return -ENOENT;
++ }
++ platform_set_drvdata(pdev, ctx);
++
++ psy_cfg.of_node = pdev->dev.of_node;
++ psy_cfg.drv_data = ctx;
++
++ ctx->supply = devm_power_supply_register(&pdev->dev,
++ &rpi_poe_power_supply_desc,
++ &psy_cfg);
++ if (IS_ERR(ctx->supply))
++ return PTR_ERR(ctx->supply);
++
++ return 0;
++}
++
++static const struct of_device_id of_rpi_poe_power_supply_match[] = {
++ { .compatible = "raspberrypi,rpi-poe-power-supply", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_rpi_poe_power_supply_match);
++
++static struct platform_driver rpi_poe_power_supply_driver = {
++ .probe = rpi_poe_power_supply_probe,
++ .driver = {
++ .name = DRVNAME,
++ .of_match_table = of_rpi_poe_power_supply_match
++ },
++};
++
++module_platform_driver(rpi_poe_power_supply_driver);
++
++MODULE_AUTHOR("Serge Schneider <serge@raspberrypi.org>");
++MODULE_ALIAS("platform:" DRVNAME);
++MODULE_DESCRIPTION("Raspberry Pi PoE+ HAT power supply driver");
++MODULE_LICENSE("GPL");
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -94,7 +94,8 @@ enum rpi_firmware_property_tag {
+ RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045,
+ RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045,
+ RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
+- RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
++ RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00038049,
++ RPI_FIRMWARE_SET_POE_HAT_VAL_OLD = 0x00030050,
+ RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
+ RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
+ RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,