bcm27xx: remove linux 5.10 compatibility
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.10 / 950-0622-Add-Raspberry-Pi-PoE-HAT-support.patch
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
deleted file mode 100644 (file)
index 121914c..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-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,