![Arnd Bergmann](/assets/img/avatar_default.png)
The TODO item named "make spi and sdio components coexist in one build"
was apparently addressed a long time ago, but never removed from the
TODO file. However, the new patch that tries to address it actually
makes it worse again by duplicating the common parts of the driver into
two separate modules rather than sharing them. This also introduces a
build regression when one of the two is built-in while the other is a
loadable module:
drivers/staging/wilc1000/wilc_debugfs.o:(.data+0x10): undefined reference to `__this_module'
Reverting the patch makes it build again. I'm leaving the TODO file
modification though, as there is nothing left to do for this item.
A related problem however still seems to exist: one still cannot have
multiple concurrent instances of wilc1000 devices present in the
system, as there are lots of shared global variables such as
host_interface.c:static struct wilc_vif *periodic_rssi_vif;
wilc_sdio.c:static struct wilc_sdio g_sdio;
wilc_wlan.c:static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP;
wilc_wlan.c:static u32 pending_acks;
wilc_wfi_cfgoperations.c:int wilc_connecting;
In order to have multiple instances working (sdio, spi, or mixed),
all such variables need to be dynamically allocated per instance and
stored in 'struct wilc' or one of the structures referenced by it.
Fixes: 9abc44ba4e
("staging: wilc1000: fix TODO to compile spi and sdio components in single module")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
116 lines
2.4 KiB
C
116 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#if defined(WILC_DEBUGFS)
|
|
#include <linux/module.h>
|
|
#include <linux/debugfs.h>
|
|
|
|
#include "wilc_wlan_if.h"
|
|
|
|
static struct dentry *wilc_dir;
|
|
|
|
#define DEBUG BIT(0)
|
|
#define INFO BIT(1)
|
|
#define WRN BIT(2)
|
|
#define ERR BIT(3)
|
|
|
|
#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR)
|
|
static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
|
|
EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
|
|
|
|
static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf,
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
char buf[128];
|
|
int res = 0;
|
|
|
|
/* only allow read from start */
|
|
if (*ppos > 0)
|
|
return 0;
|
|
|
|
res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n",
|
|
atomic_read(&WILC_DEBUG_LEVEL));
|
|
|
|
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
|
|
}
|
|
|
|
static ssize_t wilc_debug_level_write(struct file *filp,
|
|
const char __user *buf, size_t count,
|
|
loff_t *ppos)
|
|
{
|
|
int flag = 0;
|
|
int ret;
|
|
|
|
ret = kstrtouint_from_user(buf, count, 16, &flag);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (flag > DBG_LEVEL_ALL) {
|
|
pr_info("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n",
|
|
__func__, flag, atomic_read(&WILC_DEBUG_LEVEL));
|
|
return -EINVAL;
|
|
}
|
|
|
|
atomic_set(&WILC_DEBUG_LEVEL, (int)flag);
|
|
|
|
if (flag == 0)
|
|
pr_info("Debug-level disabled\n");
|
|
else
|
|
pr_info("Debug-level enabled\n");
|
|
|
|
return count;
|
|
}
|
|
|
|
#define FOPS(_open, _read, _write, _poll) { \
|
|
.owner = THIS_MODULE, \
|
|
.open = (_open), \
|
|
.read = (_read), \
|
|
.write = (_write), \
|
|
.poll = (_poll), \
|
|
}
|
|
|
|
struct wilc_debugfs_info_t {
|
|
const char *name;
|
|
int perm;
|
|
unsigned int data;
|
|
const struct file_operations fops;
|
|
};
|
|
|
|
static struct wilc_debugfs_info_t debugfs_info[] = {
|
|
{
|
|
"wilc_debug_level",
|
|
0666,
|
|
(DEBUG | ERR),
|
|
FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL),
|
|
},
|
|
};
|
|
|
|
static int __init wilc_debugfs_init(void)
|
|
{
|
|
int i;
|
|
struct wilc_debugfs_info_t *info;
|
|
|
|
wilc_dir = debugfs_create_dir("wilc_wifi", NULL);
|
|
for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) {
|
|
info = &debugfs_info[i];
|
|
debugfs_create_file(info->name,
|
|
info->perm,
|
|
wilc_dir,
|
|
&info->data,
|
|
&info->fops);
|
|
}
|
|
return 0;
|
|
}
|
|
module_init(wilc_debugfs_init);
|
|
|
|
static void __exit wilc_debugfs_remove(void)
|
|
{
|
|
debugfs_remove_recursive(wilc_dir);
|
|
}
|
|
module_exit(wilc_debugfs_remove);
|
|
|
|
#endif
|