blob: 77bae48abadb3dfe790590ee94df0e383ebde061 [file] [log] [blame]
From 0874ed2d8f47be3b05c13c2847dd023e47f1a663 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= <korneld@google.com>
Date: Thu, 2 Feb 2023 14:41:17 +0000
Subject: [PATCH] CHROMIUM: net: wwan: t7xx: Add support for cold reboot
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This allows us to recover from a state where the device doesn't respond
to any commands. It calls the FHRF and SHRF ACPI methods, essentially
performing a cold reboot.
The reset can be triggered using a dedicated sysfs file - "cold_reboot".
For example:
"echo 1 > /sys/devices/pci0000:00/0000:00:1c.0/0000:57:00.0/cold_reboot"
BUG=b:241850118, b:302552686
TEST=Trigger the reboot and verify that the modem is working
UPSTREAM-TASK=b:269405297
Signed-off-by: Kornel Dulęba <korneld@google.com>
Change-Id: I25b3afc9d4e96a1c65bd44cc8611a48b942e722b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4218573
Reviewed-by: Radoslaw Biernacki <biernacki@google.com>
Commit-Queue: Radoslaw Biernacki <biernacki@google.com>
(cherry picked from commit c9f39b9e95117e74b4fac5c704ffd8032779abcc)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4903302
Reviewed-by: Rukun Mao <rmao@google.com>
Reviewed-by: Daniel Winkler <danielwinkler@google.com>
Tested-by: Rukun Mao <rmao@google.com>
---
drivers/net/wwan/t7xx/t7xx_pci.c | 32 +++++++++++++++++++++++
drivers/net/wwan/t7xx/t7xx_port_devlink.c | 2 +-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c
index 02d27c1cf7e42df407f8352762b15da8e2fdd71f..6dc133cbd1776a624ebd3c3b9c7384c44c3fc9d9 100644
--- a/drivers/net/wwan/t7xx/t7xx_pci.c
+++ b/drivers/net/wwan/t7xx/t7xx_pci.c
@@ -146,6 +146,26 @@ enum t7xx_pm_state {
MTK_PM_RESUMED,
};
+static ssize_t cold_reboot_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ t7xx_rescan_queue_work(pdev, true);
+ return count;
+}
+
+static DEVICE_ATTR_WO(cold_reboot);
+
+static struct attribute *cold_reboot_attr[] = {
+ &dev_attr_cold_reboot.attr,
+ NULL
+};
+
+static const struct attribute_group cold_reboot_attribute_group = {
+ .attrs = cold_reboot_attr,
+};
+
static void t7xx_dev_set_sleep_capability(struct t7xx_pci_dev *t7xx_dev, bool enable)
{
void __iomem *ctrl_reg = IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_CTRL;
@@ -843,6 +863,13 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
t7xx_pcie_mac_interrupts_dis(t7xx_dev);
+ ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj,
+ &cold_reboot_attribute_group);
+ if (ret) {
+ t7xx_md_exit(t7xx_dev);
+ goto err_devlink_unregister;
+ }
+
ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj,
&t7xx_mode_attribute_group);
if (ret)
@@ -861,6 +888,8 @@ static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_remove_group:
sysfs_remove_group(&t7xx_dev->pdev->dev.kobj,
&t7xx_mode_attribute_group);
+ sysfs_remove_group(&t7xx_dev->pdev->dev.kobj,
+ &cold_reboot_attribute_group);
err_md_exit:
t7xx_md_exit(t7xx_dev);
@@ -884,6 +913,9 @@ static void t7xx_pci_remove(struct pci_dev *pdev)
t7xx_md_exit(t7xx_dev);
t7xx_devlink_unregister(t7xx_dev);
+ sysfs_remove_group(&t7xx_dev->pdev->dev.kobj,
+ &cold_reboot_attribute_group);
+
for (i = 0; i < EXT_INT_NUM; i++) {
if (!t7xx_dev->intr_handler[i])
continue;
diff --git a/drivers/net/wwan/t7xx/t7xx_port_devlink.c b/drivers/net/wwan/t7xx/t7xx_port_devlink.c
index 8de2ee65fe0cb94bf6dfb476e767ccf831882d92..fa0c7d7e35302187d4db8e8e2e4c91ac54b7e553 100644
--- a/drivers/net/wwan/t7xx/t7xx_port_devlink.c
+++ b/drivers/net/wwan/t7xx/t7xx_port_devlink.c
@@ -442,7 +442,7 @@ static int t7xx_devlink_reload_up(struct devlink *devlink,
switch (action) {
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
- t7xx_rescan_queue_work(dl->t7xx_dev->pdev);
+ t7xx_rescan_queue_work(dl->t7xx_dev->pdev, false);
return 0;
default:
/* Unsupported action should not get to this function */
--
2.46.0.792.g87dc391469-goog