build/patch/kernel/archive/sunxi-5.15/patches.megous/misc-modem-power-Add-fastboot-powerup-mode.patch

140 lines
4.5 KiB
Diff

From 612e1c86f4d7a94797838d50f5bf7b760affad06 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Thu, 17 Sep 2020 00:10:50 +0200
Subject: [PATCH 268/478] misc: modem-power: Add fastboot powerup mode
This may work with a patched bootloader from https://github.com/Biktorgj
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
drivers/misc/modem-power.c | 53 +++++++++++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/modem-power.c b/drivers/misc/modem-power.c
index 1a1ba4bf7841..aee4479b0d6a 100644
--- a/drivers/misc/modem-power.c
+++ b/drivers/misc/modem-power.c
@@ -178,6 +178,7 @@ enum {
MPWR_F_GOT_PDN,
/* config options */
MPWR_F_DUMB_POWERUP,
+ MPWR_F_FASTBOOT_POWERUP,
/* file */
MPWR_F_OPEN,
MPWR_F_OVERFLOW,
@@ -386,11 +387,13 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
{
struct gpio_desc *pwrkey_gpio = mpwr_eg25_get_pwrkey_gpio(mpwr);
bool wakeup_ok, status_ok;
- bool needs_restart = false;
+ bool needs_restart = false, fastboot;
u32 speed = 115200;
int ret, i, off;
ktime_t start;
+ fastboot = test_and_clear_bit(MPWR_F_FASTBOOT_POWERUP, mpwr->flags);
+
if (regulator_is_enabled(mpwr->regulator))
dev_warn(mpwr->dev,
"regulator was already enabled during powerup");
@@ -405,7 +408,14 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
/* Drive default gpio signals during powerup */
gpiod_direction_output(mpwr->host_ready_gpio, 1);
- gpiod_direction_output(mpwr->enable_gpio, 1);
+ /* #W_DISABLE must be left pulled up during modem power up
+ * early on, because opensource bootloader uses this signal to enter
+ * fastboot mode when it's pulled down.
+ *
+ * This should be 1 for normal powerup and 0 for fastboot mode with
+ * special Biktor's firmware.
+ */
+ gpiod_direction_output(mpwr->enable_gpio, !fastboot);
gpiod_direction_output(mpwr->sleep_gpio, 0);
gpiod_direction_output(mpwr->reset_gpio, 0);
gpiod_direction_output(pwrkey_gpio, 0);
@@ -419,6 +429,10 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
msleep(200);
gpiod_set_value(pwrkey_gpio, 0);
+ /* skip modem killswitch status checks in fastboot bootloader entry mode */
+ if (fastboot)
+ goto open_serdev;
+
/* Switch status key to input, in case it's multiplexed with pwrkey. */
gpiod_direction_input(mpwr->status_gpio);
@@ -464,6 +478,7 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
if (test_and_clear_bit(MPWR_F_KILLSWITCHED, mpwr->flags))
sysfs_notify(&mpwr->dev->kobj, NULL, "killswitched");
+open_serdev:
/* open serial console */
ret = serdev_device_open(mpwr->serdev);
if (ret) {
@@ -480,7 +495,7 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
goto err_shutdown;
}
- if (test_bit(MPWR_F_DUMB_POWERUP, mpwr->flags))
+ if (test_bit(MPWR_F_DUMB_POWERUP, mpwr->flags) || fastboot)
goto powered_up;
ret = mpwr_serdev_at_cmd_with_retry_ignore_timeout(mpwr, "AT&FE0", 1000, 30);
@@ -1230,6 +1245,36 @@ static ssize_t dumb_powerup_store(struct device *dev,
return len;
}
+static ssize_t fastboot_powerup_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mpwr_dev *mpwr = platform_get_drvdata(to_platform_device(dev));
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ !!test_bit(MPWR_F_FASTBOOT_POWERUP, mpwr->flags));
+}
+
+static ssize_t fastboot_powerup_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct mpwr_dev *mpwr = platform_get_drvdata(to_platform_device(dev));
+ bool val;
+ int ret;
+
+ ret = kstrtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ if (val) {
+ dev_warn(mpwr->dev, "Fastboot powerup needs a special bootloader!\n");
+ set_bit(MPWR_F_FASTBOOT_POWERUP, mpwr->flags);
+ } else
+ clear_bit(MPWR_F_FASTBOOT_POWERUP, mpwr->flags);
+
+ return len;
+}
+
static ssize_t killswitched_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1268,6 +1313,7 @@ static ssize_t hard_reset_store(struct device *dev,
static DEVICE_ATTR_RW(powered);
static DEVICE_ATTR_WO(powered_blocking);
static DEVICE_ATTR_RW(dumb_powerup);
+static DEVICE_ATTR_RW(fastboot_powerup);
static DEVICE_ATTR_RO(killswitched);
static DEVICE_ATTR_RO(is_busy);
static DEVICE_ATTR_WO(hard_reset);
@@ -1276,6 +1322,7 @@ static struct attribute *mpwr_attrs[] = {
&dev_attr_powered.attr,
&dev_attr_powered_blocking.attr,
&dev_attr_dumb_powerup.attr,
+ &dev_attr_fastboot_powerup.attr,
&dev_attr_killswitched.attr,
&dev_attr_is_busy.attr,
&dev_attr_hard_reset.attr,
--
2.35.3