]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/brcm80211/brcmfmac/debug.c
Merge remote-tracking branch 'sound-current/for-linus'
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / debug.c
index 2d6d0055385877087a467dfa1ab265538fdb7102..1299dccc78b4da22293677ec4cf0a1f763af2a19 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/netdevice.h>
 #include <linux/module.h>
+#include <linux/devcoredump.h>
 
 #include <brcmu_wifi.h>
 #include <brcmu_utils.h>
 #include "core.h"
 #include "bus.h"
+#include "fweh.h"
 #include "debug.h"
 
 static struct dentry *root_folder;
 
+static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
+                                     size_t len)
+{
+       void *dump;
+       size_t ramsize;
+
+       ramsize = brcmf_bus_get_ramsize(bus);
+       if (ramsize) {
+               dump = vzalloc(len + ramsize);
+               if (!dump)
+                       return -ENOMEM;
+               memcpy(dump, data, len);
+               brcmf_bus_get_memdump(bus, dump + len, ramsize);
+               dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
+       }
+       return 0;
+}
+
+static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
+                                          const struct brcmf_event_msg *evtmsg,
+                                          void *data)
+{
+       brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
+
+       return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
+                                         evtmsg->datalen);
+}
+
 void brcmf_debugfs_init(void)
 {
        root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
@@ -41,7 +71,7 @@ void brcmf_debugfs_exit(void)
        root_folder = NULL;
 }
 
-int brcmf_debugfs_attach(struct brcmf_pub *drvr)
+int brcmf_debug_attach(struct brcmf_pub *drvr)
 {
        struct device *dev = drvr->bus_if->dev;
 
@@ -49,12 +79,18 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
                return -ENODEV;
 
        drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
+       if (IS_ERR(drvr->dbgfs_dir))
+               return PTR_ERR(drvr->dbgfs_dir);
 
-       return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
+
+       return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
+                                  brcmf_debug_psm_watchdog_notify);
 }
 
-void brcmf_debugfs_detach(struct brcmf_pub *drvr)
+void brcmf_debug_detach(struct brcmf_pub *drvr)
 {
+       brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG);
+
        if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
                debugfs_remove_recursive(drvr->dbgfs_dir);
 }