140 lines
4.5 KiB
Diff
140 lines
4.5 KiB
Diff
From 0a34eb1232490d5e15764696c8e2c49fed9153c8 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Jirman <megous@megous.com>
|
|
Date: Thu, 17 Sep 2020 00:10:50 +0200
|
|
Subject: [PATCH 186/351] 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.34.0
|
|
|