@@ -1702,6 +1702,15 @@ static int qca_power_on(struct hci_dev *hdev)
return ret;
}
+#ifdef CONFIG_DEV_COREDUMP
+static bool hciqca_coredump_enabled(struct hci_dev *hdev)
+{
+ struct hci_uart *hu = hci_get_drvdata(hdev);
+
+ return !hu->serdev->dev.coredump_disabled;
+}
+#endif
+
static int qca_setup(struct hci_uart *hu)
{
struct hci_dev *hdev = hu->hdev;
@@ -1780,6 +1789,9 @@ static int qca_setup(struct hci_uart *hu)
qca_debugfs_init(hdev);
hu->hdev->hw_error = qca_hw_error;
hu->hdev->cmd_timeout = qca_cmd_timeout;
+#ifdef CONFIG_DEV_COREDUMP
+ hu->hdev->dump.enabled = hciqca_coredump_enabled;
+#endif
if (device_can_wakeup(hu->serdev->ctrl->dev.parent))
hu->hdev->wakeup = qca_wakeup;
} else if (ret == -ENOENT) {
@@ -2380,6 +2392,18 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match);
#endif
+#ifdef CONFIG_DEV_COREDUMP
+static void hciqca_coredump(struct device *dev)
+{
+ struct serdev_device *serdev = to_serdev_device(dev);
+ struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+ struct hci_uart *hu = &qcadev->serdev_hu;
+ struct hci_dev *hdev = hu->hdev;
+
+ if (!dev->coredump_disabled && hdev->dump.coredump)
+ hdev->dump.coredump(hdev);
+}
+#endif
static struct serdev_device_driver qca_serdev_driver = {
.probe = qca_serdev_probe,
@@ -2390,6 +2414,9 @@ static struct serdev_device_driver qca_serdev_driver = {
.acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
.shutdown = qca_serdev_shutdown,
.pm = &qca_pm_ops,
+#ifdef CONFIG_DEV_COREDUMP
+ .coredump = hciqca_coredump,
+#endif
},
};