armbian_build/patch/kernel/archive/sunxi-5.16/patches.megous/misc-modem-power-Simpler-boot-mode-selection-API-add-more-boot-.patch
The-going f80117f21c
Recycling of megous v5.16.4 patches (#3449)
* Recycling of megous v5.16.4 patches

The patches were sorted as far as possible. Some patches are renamed
according to their place of application. The length of the patch name
has been changed to improve readability using
the `git format-patch --filename-max-length=75` method.

The folder containing the patches will have the name `patches.name`
and the corresponding file `series.name` for the convenience
of processing and moving them upstream. But the control file remains
`series.conf`.


Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>

* Add a series of armbian patches for 5.16

Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>

* Remove patches whose fixes are already in the kernel

Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>
2022-02-02 11:03:44 +01:00

323 lines
10 KiB
Diff

From f9a5d118bb18c3c8d67ff094b6480fe960eddac4 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Thu, 3 Dec 2020 20:00:06 +0100
Subject: [PATCH 122/446] misc: modem-power: Simpler boot mode selection API,
add more boot modes
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
drivers/misc/modem-power.c | 139 ++++++++++++++-----------------------
1 file changed, 52 insertions(+), 87 deletions(-)
diff --git a/drivers/misc/modem-power.c b/drivers/misc/modem-power.c
index c33e56f0d..4cb0a335e 100644
--- a/drivers/misc/modem-power.c
+++ b/drivers/misc/modem-power.c
@@ -66,6 +66,14 @@ enum {
MPWR_REQ_PWUP,
};
+enum {
+ MPWR_MODE_NORMAL = 1,
+ MPWR_MODE_DUMB,
+ MPWR_MODE_FASTBOOT,
+ MPWR_MODE_ALT1,
+ MPWR_MODE_ALT2,
+};
+
struct mpwr_dev;
struct mpwr_gpio {
@@ -157,6 +165,7 @@ struct mpwr_dev {
// change
spinlock_t lock; /* protects last_request */
int last_request;
+ int powerup_mode;
ktime_t last_wakeup;
struct timer_list wd_timer;
@@ -172,14 +181,12 @@ enum {
MPWR_F_KILLSWITCHED,
/* we got a wakeup from the modem */
MPWR_F_GOT_WAKEUP,
- /* serdev */
- MPWR_F_RECEIVING_MSG,
- /* eg25 */
- MPWR_F_GOT_PDN,
+ /* serdev */
+ MPWR_F_RECEIVING_MSG,
+ /* eg25 */
+ MPWR_F_GOT_PDN,
/* config options */
- MPWR_F_DUMB_POWERUP,
- MPWR_F_FASTBOOT_POWERUP,
- MPWR_F_BLOCKED,
+ MPWR_F_BLOCKED,
/* file */
MPWR_F_OPEN,
MPWR_F_OVERFLOW,
@@ -318,7 +325,7 @@ static const struct mpwr_eg25_qcfg mpwr_eg25_qcfgs[] = {
{ "airplanecontrol", "1", mpwr_eg25_qcfg_airplanecontrol_is_ok },
// available since firmware R07A08_01.002.01.002
- { "fast/poweroff", "1" },
+ { "fast/poweroff", "1" },
};
static char* mpwr_serdev_get_response_value(struct mpwr_dev *mpwr,
@@ -388,12 +395,11 @@ 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, fastboot;
+ bool needs_restart = false;
u32 speed = 115200;
int ret, i, off;
ktime_t start;
-
- fastboot = test_and_clear_bit(MPWR_F_FASTBOOT_POWERUP, mpwr->flags);
+ int mode = mpwr->powerup_mode;
if (regulator_is_enabled(mpwr->regulator))
dev_warn(mpwr->dev,
@@ -408,7 +414,8 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
}
/* Drive default gpio signals during powerup */
- gpiod_direction_output(mpwr->host_ready_gpio, 1);
+ /* host_ready_gpio should be 1 during normal powerup */
+ gpiod_direction_output(mpwr->host_ready_gpio, mode != MPWR_MODE_ALT2);
/* #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.
@@ -416,11 +423,12 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
* 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->enable_gpio, mode != MPWR_MODE_FASTBOOT);
gpiod_direction_output(mpwr->sleep_gpio, 0);
gpiod_direction_output(mpwr->reset_gpio, 0);
gpiod_direction_output(pwrkey_gpio, 0);
- gpiod_direction_output(mpwr->dtr_gpio, 0);
+ /* dtr_gpio should be 0 during normal powerup */
+ gpiod_direction_output(mpwr->dtr_gpio, mode == MPWR_MODE_ALT1);
/* Wait for powerup. (30ms min. according to datasheet) */
msleep(50);
@@ -431,7 +439,7 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
gpiod_set_value(pwrkey_gpio, 0);
/* skip modem killswitch status checks in fastboot bootloader entry mode */
- if (fastboot)
+ if (mode != MPWR_MODE_NORMAL)
goto open_serdev;
/* Switch status key to input, in case it's multiplexed with pwrkey. */
@@ -496,7 +504,7 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
goto err_shutdown;
}
- if (test_bit(MPWR_F_DUMB_POWERUP, mpwr->flags) || fastboot)
+ if (mode != MPWR_MODE_NORMAL)
goto powered_up;
ret = mpwr_serdev_at_cmd_with_retry_ignore_timeout(mpwr, "AT&FE0", 1000, 30);
@@ -556,7 +564,7 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
/* reset the modem, to apply QDAI config if necessary */
if (needs_restart) {
dev_info(mpwr->dev, "Restarting modem\n");
-
+
/* reboot is broken with fastboot enabled */
mpwr_serdev_at_cmd(mpwr, "AT+QCFG=\"fast/poweroff\",0", 5000);
@@ -624,6 +632,11 @@ static int mpwr_eg25_power_up(struct mpwr_dev* mpwr)
dev_err(mpwr->dev, "Modem will probably not sleep!\n");
powered_up:
+ // if we're signaling some alternate boot mode via GPIO, we need to
+ // sleep here so that modem's boot script notices the gpio
+ if (mode == MPWR_MODE_ALT1 || mode == MPWR_MODE_FASTBOOT || mode == MPWR_MODE_ALT2)
+ msleep(12000);
+
gpiod_direction_output(mpwr->dtr_gpio, 1);
return 0;
@@ -738,7 +751,7 @@ static int mpwr_eg25_power_down_finish(struct mpwr_dev* mpwr)
static int mpwr_eg25_power_down(struct mpwr_dev* mpwr)
{
struct gpio_desc *pwrkey_gpio = mpwr_eg25_get_pwrkey_gpio(mpwr);
- int ret;
+ //int ret;
/* Send 800ms pwrkey pulse to initiate powerdown. */
gpiod_direction_output(pwrkey_gpio, 1);
@@ -1112,7 +1125,7 @@ static void mpwr_work_handler(struct work_struct *work)
pm_relax(mpwr->dev);
}
-static void mpwr_request_power_change(struct mpwr_dev* mpwr, int request)
+static void mpwr_request_power_change(struct mpwr_dev* mpwr, int request, int mode)
{
unsigned long flags;
@@ -1121,6 +1134,8 @@ static void mpwr_request_power_change(struct mpwr_dev* mpwr, int request)
spin_lock_irqsave(&mpwr->lock, flags);
mpwr->last_request = request;
+ if (mode >= 0)
+ mpwr->powerup_mode = mode;
spin_unlock_irqrestore(&mpwr->lock, flags);
queue_work(mpwr->wq, &mpwr->power_work);
@@ -1189,17 +1204,17 @@ static ssize_t powered_store(struct device *dev,
const char *buf, size_t len)
{
struct mpwr_dev *mpwr = platform_get_drvdata(to_platform_device(dev));
- bool status;
+ unsigned status;
int ret;
if (test_bit(MPWR_F_BLOCKED, mpwr->flags))
return -EPERM;
- ret = kstrtobool(buf, &status);
+ ret = kstrtouint(buf, 10, &status);
if (ret)
return ret;
- mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN);
+ mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN, status);
return len;
}
@@ -1209,17 +1224,17 @@ static ssize_t powered_blocking_store(struct device *dev,
const char *buf, size_t len)
{
struct mpwr_dev *mpwr = platform_get_drvdata(to_platform_device(dev));
- bool status;
+ unsigned status;
int ret;
if (test_bit(MPWR_F_BLOCKED, mpwr->flags))
return -EPERM;
- ret = kstrtobool(buf, &status);
+ ret = kstrtouint(buf, 10, &status);
if (ret)
return ret;
- mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN);
+ mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN, status);
ret = wait_event_interruptible_timeout(mpwr->wait,
!test_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags),
@@ -1235,64 +1250,16 @@ static ssize_t powered_blocking_store(struct device *dev,
return len;
}
-static ssize_t dumb_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_DUMB_POWERUP, mpwr->flags));
-}
-
-static ssize_t dumb_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_err(mpwr->dev, "Don't use dumb_powerup, it's just a debug function!\n");
- set_bit(MPWR_F_DUMB_POWERUP, mpwr->flags);
- } else
- clear_bit(MPWR_F_DUMB_POWERUP, mpwr->flags);
-
- 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)
+static ssize_t help_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- 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;
+ return scnprintf(buf, PAGE_SIZE,
+ "echo N > powered, where N can be:\n"
+ "0: power off\n"
+ "1: normal powerup\n"
+ "2: dumb powerup (no AT commands and little error checking during powerup)\n"
+ "3: fastboot powerup (with biktor's patched aboot - #W_DISABLE held low during powerup)\n"
+ "4: alternate powerup (megi's userspace - DTR held high during powerup)\n\n"
+ "echo N > powered_blocking can be used for the write to block until power status transition completes\n");
}
static ssize_t killswitched_show(struct device *dev,
@@ -1328,26 +1295,24 @@ static ssize_t hard_reset_store(struct device *dev,
if (ret)
return ret;
if (val)
- mpwr_request_power_change(mpwr, MPWR_REQ_RESET);
+ mpwr_request_power_change(mpwr, MPWR_REQ_RESET, -1);
return len;
}
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_RO(help);
static DEVICE_ATTR_WO(hard_reset);
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_help.attr,
&dev_attr_hard_reset.attr,
NULL,
};
--
2.31.1