summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Chang <chengcha@google.com>2023-09-27 05:19:01 +0000
committerCheng Chang <chengcha@google.com>2023-10-26 01:19:05 +0000
commit0ccccb07d33454bfe2c1bb0837ee587b6bbbcb5e (patch)
treea60f38c91e680a42fdc6c3eeb15019e4ef5710cf
parent197e2b19da4c94dcfcdbe784dd9ac233ef0535b7 (diff)
downloadbcm47765-android-gs-shusky-5.15-android14-qpr2-beta.tar.gz
Bug: 303343788 Test: Toggle coredump sysnode at b/303343788 Change-Id: I55a09f7cb694aa2fa804869fdb550117f05a2754 Signed-off-by: Cheng Chang <chengcha@google.com>
-rw-r--r--Documentation/ABI/stable/sysfs-devices-platform-spi7
-rw-r--r--bcm_gps_spi.c69
-rw-r--r--bcm_gps_spi.h6
3 files changed, 82 insertions, 0 deletions
diff --git a/Documentation/ABI/stable/sysfs-devices-platform-spi b/Documentation/ABI/stable/sysfs-devices-platform-spi
new file mode 100644
index 0000000..1e2a03d
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-platform-spi
@@ -0,0 +1,7 @@
+What: /sys/devices/platform/spi.N/coredump
+Date: Oct, 2023
+Contact: chengcha@google.com
+Description:
+ (WO) Writing to this file causes the bcm47765 driver to initiate an
+ ssrdump.
+ Format: "{REASON};{DUMPSTRING}"
diff --git a/bcm_gps_spi.c b/bcm_gps_spi.c
index ff4085b..94ede05 100644
--- a/bcm_gps_spi.c
+++ b/bcm_gps_spi.c
@@ -34,6 +34,7 @@
#include <asm/irq.h>
#include <linux/kernel_stat.h>
#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
#include "bbd.h"
#include "bcm_gps_spi.h"
@@ -49,10 +50,57 @@
* Just for startup info notification.
*/
#define BCM_BITRATE 12000
+#define DEVICE_NAME "gnss"
static void bcm_on_packet_received(
void *_priv, unsigned char *data, unsigned int size);
+static void sscd_release(struct device *dev) {
+ (void)dev;
+}
+
+static ssize_t coredump_store(struct device *dev, struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ char *next;
+ int length;
+ char *reason;
+ static time64_t last_trigger_time;
+ struct sscd_segment seg;
+ time64_t trigger_time = ktime_get_seconds();
+ struct spi_device *spi = to_spi_device(dev);
+ struct bcm_spi_priv *priv = spi_get_drvdata(spi);
+ struct sscd_platform_data *pdata = dev_get_platdata(&priv->sscd_dev.dev);
+
+ if (pdata->sscd_report)
+ return -EPIPE;
+
+ /* Ignore the trigger time less than 30 seconds */
+ if (trigger_time - last_trigger_time < 30)
+ return -EBUSY;
+ last_trigger_time = trigger_time;
+
+ /* ; separate the crash reason and coredump value */
+ next = strchr(buf, ';');
+ if (!next)
+ return -EINVAL;
+
+ length = (int)(next - buf);
+ reason = kstrndup(buf, length + 1, GFP_KERNEL);
+ if (!reason)
+ return -ENOMEM;
+ reason[length] = '\0';
+
+ length = strlen(next + 1);
+ seg.addr = next + 1;
+ seg.size = length;
+ pdata->sscd_report(&priv->sscd_dev, &seg, 1, 0, reason);
+
+ kfree(reason);
+
+ return count;
+}
+static DEVICE_ATTR_WO(coredump);
static ssize_t nstandby_show(
struct device *dev, struct device_attribute *attr, char *buf)
@@ -1429,6 +1477,22 @@ static int bcm_spi_probe(struct spi_device *spi)
/* Set driver data */
spi_set_drvdata(spi, priv);
+ /* Register ssrdump platform */
+ priv->sscd_dev = (struct platform_device){
+ .name = DEVICE_NAME,
+ .driver_override = SSCD_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &priv->sscd_pdata,
+ .release = sscd_release,
+ },
+ };
+
+ platform_device_register(&priv->sscd_dev);
+
+ if (device_create_file(&spi->dev, &dev_attr_coredump))
+ dev_err(&spi->dev, "Unable to create sysfs coredump entry");
+
/* Init - miscdev stuff */
init_waitqueue_head(&priv->poll_wait);
priv->read_buf.buf = priv->_read_buf;
@@ -1509,8 +1573,13 @@ static int bcm_spi_remove(struct spi_device *spi)
/* Free everything */
bbd_exit(&spi->dev);
+ /* Clean ssr dump driver */
+ platform_device_unregister(&priv->sscd_dev);
+
device_remove_file(&priv->spi->dev, &dev_attr_nstandby);
device_remove_file(&priv->spi->dev, &dev_attr_sspmcureq);
+ device_remove_file(&priv->spi->dev, &dev_attr_coredump);
+
return 0;
}
diff --git a/bcm_gps_spi.h b/bcm_gps_spi.h
index 3ed34e5..d4231a3 100644
--- a/bcm_gps_spi.h
+++ b/bcm_gps_spi.h
@@ -8,6 +8,8 @@
#ifndef __BCM_GPS_SPI_H__
#define __BCM_GPS_SPI_H__
+#include <linux/platform_data/sscoredump.h>
+
#define WORD_BURST_SIZE 4
#define CONFIG_SPI_DMA_BYTES_PER_WORD 4
#define CONFIG_SPI_DMA_BITS_PER_WORD (CONFIG_SPI_DMA_BYTES_PER_WORD * 8)
@@ -218,6 +220,10 @@ struct bcm_spi_priv {
unsigned long rx_buffer_avail_bytes;// = HSI_PZC_MAX_RX_BUFFER;
/* Should be more MAX_SPI_FRAME_LEN. See below */
struct bbd_device *bbd;
+ /* To register ssrdump platform */
+ struct platform_device sscd_dev;
+ /* To register ssrdump driver */
+ struct sscd_platform_data sscd_pdata;
};
/* bcm_gps_regs.cpp */