armbian_build/patch/kernel/archive/sunxi-5.16/patches.megous/misc-modem-power-Add-blocking-variant-of-sysfs-power-state-upda.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

164 lines
4.5 KiB
Diff

From 09b7c8d5454bd260aea1feba1e1438ad0a8e3576 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 8 Sep 2020 02:51:57 +0200
Subject: [PATCH 110/446] misc: modem-power: Add blocking variant of sysfs
power state update function
Makes writing modem powerup scripts easier.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
drivers/misc/modem-power.c | 77 +++++++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 27 deletions(-)
diff --git a/drivers/misc/modem-power.c b/drivers/misc/modem-power.c
index 5cb4e76c7..68aa7ecc6 100644
--- a/drivers/misc/modem-power.c
+++ b/drivers/misc/modem-power.c
@@ -944,14 +944,7 @@ static void mpwr_power_down(struct mpwr_dev* mpwr)
dev_info(dev, "powering down");
- set_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
- sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
-
ret = mpwr->variant->power_down(mpwr);
-
- clear_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
- sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
-
if (ret) {
dev_err(dev, "power down failed");
} else {
@@ -978,14 +971,7 @@ static void mpwr_power_up(struct mpwr_dev* mpwr)
dev_info(dev, "powering up");
- set_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
- sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
-
ret = mpwr->variant->power_up(mpwr);
-
- clear_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
- sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
-
if (ret) {
dev_err(dev, "power up failed");
} else {
@@ -1099,9 +1085,27 @@ static void mpwr_work_handler(struct work_struct *work)
mutex_unlock(&mpwr->modem_lock);
+ clear_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
+ sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
+ wake_up(&mpwr->wait);
+
pm_relax(mpwr->dev);
}
+static void mpwr_request_power_change(struct mpwr_dev* mpwr, int request)
+{
+ unsigned long flags;
+
+ set_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags);
+ sysfs_notify(&mpwr->dev->kobj, NULL, "is_busy");
+
+ spin_lock_irqsave(&mpwr->lock, flags);
+ mpwr->last_request = request;
+ spin_unlock_irqrestore(&mpwr->lock, flags);
+
+ queue_work(mpwr->wq, &mpwr->power_work);
+}
+
static irqreturn_t mpwr_gpio_isr(int irq, void *dev_id)
{
struct mpwr_dev *mpwr = dev_id;
@@ -1162,7 +1166,6 @@ 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));
- unsigned long flags;
bool status;
int ret;
@@ -1170,11 +1173,35 @@ static ssize_t powered_store(struct device *dev,
if (ret)
return ret;
- spin_lock_irqsave(&mpwr->lock, flags);
- mpwr->last_request = status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN;
- spin_unlock_irqrestore(&mpwr->lock, flags);
+ mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN);
- queue_work(mpwr->wq, &mpwr->power_work);
+ return len;
+}
+
+static ssize_t powered_blocking_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 status;
+ int ret;
+
+ ret = kstrtobool(buf, &status);
+ if (ret)
+ return ret;
+
+ mpwr_request_power_change(mpwr, status ? MPWR_REQ_PWUP : MPWR_REQ_PWDN);
+
+ ret = wait_event_interruptible_timeout(mpwr->wait,
+ !test_bit(MPWR_F_POWER_CHANGE_INPROGRESS, mpwr->flags),
+ msecs_to_jiffies(60000));
+ if (ret <= 0) {
+ dev_err(mpwr->dev, "Power state change timeout\n");
+ return -EIO;
+ }
+
+ if (!!status != !!test_bit(MPWR_F_POWERED, mpwr->flags))
+ return -EIO;
return len;
}
@@ -1260,25 +1287,20 @@ static ssize_t hard_reset_store(struct device *dev,
const char *buf, size_t len)
{
struct mpwr_dev *mpwr = platform_get_drvdata(to_platform_device(dev));
- unsigned long flags;
bool val;
int ret;
ret = kstrtobool(buf, &val);
if (ret)
return ret;
-
- if (val) {
- spin_lock_irqsave(&mpwr->lock, flags);
- mpwr->last_request = MPWR_REQ_RESET;
- spin_unlock_irqrestore(&mpwr->lock, flags);
- queue_work(mpwr->wq, &mpwr->power_work);
- }
+ if (val)
+ mpwr_request_power_change(mpwr, MPWR_REQ_RESET);
return len;
}
static DEVICE_ATTR_RW(powered);
+static DEVICE_ATTR_WO(powered_blocking);
static DEVICE_ATTR_RW(dumb_powerup);
static DEVICE_ATTR_RW(wait_rdy);
static DEVICE_ATTR_RO(killswitched);
@@ -1287,6 +1309,7 @@ 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_wait_rdy.attr,
&dev_attr_killswitched.attr,
--
2.31.1