Contributors: 14
Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
Luciano Coelho |
545 |
77.41% |
5 |
22.73% |
Felipe Balbi |
87 |
12.36% |
3 |
13.64% |
Juuso Oikarinen |
34 |
4.83% |
2 |
9.09% |
Tony Lindgren |
10 |
1.42% |
2 |
9.09% |
Victor Goldenshtein |
7 |
0.99% |
1 |
4.55% |
Yue haibing |
5 |
0.71% |
1 |
4.55% |
Eliad Peller |
4 |
0.57% |
1 |
4.55% |
Silvan Jegen |
3 |
0.43% |
1 |
4.55% |
Li Zhijian |
3 |
0.43% |
1 |
4.55% |
Thomas Gleixner |
2 |
0.28% |
1 |
4.55% |
Joe Perches |
1 |
0.14% |
1 |
4.55% |
Chi Minghao |
1 |
0.14% |
1 |
4.55% |
Tian Tao |
1 |
0.14% |
1 |
4.55% |
Bhumika Goyal |
1 |
0.14% |
1 |
4.55% |
Total |
704 |
|
22 |
|
// SPDX-License-Identifier: GPL-2.0-only
/*
* This file is part of wlcore
*
* Copyright (C) 2013 Texas Instruments Inc.
*/
#include <linux/pm_runtime.h>
#include "acx.h"
#include "wlcore.h"
#include "debug.h"
#include "sysfs.h"
static ssize_t bt_coex_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
mutex_lock(&wl->mutex);
len = sysfs_emit(buf, "%d\n\n0 - off\n1 - on\n", wl->sg_enabled);
mutex_unlock(&wl->mutex);
return len;
}
static ssize_t bt_coex_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct wl1271 *wl = dev_get_drvdata(dev);
unsigned long res;
int ret;
ret = kstrtoul(buf, 10, &res);
if (ret < 0) {
wl1271_warning("incorrect value written to bt_coex_mode");
return count;
}
mutex_lock(&wl->mutex);
res = !!res;
if (res == wl->sg_enabled)
goto out;
wl->sg_enabled = res;
if (unlikely(wl->state != WLCORE_STATE_ON))
goto out;
ret = pm_runtime_resume_and_get(wl->dev);
if (ret < 0)
goto out;
wl1271_acx_sg_enable(wl, wl->sg_enabled);
pm_runtime_mark_last_busy(wl->dev);
pm_runtime_put_autosuspend(wl->dev);
out:
mutex_unlock(&wl->mutex);
return count;
}
static DEVICE_ATTR_RW(bt_coex_state);
static ssize_t hw_pg_ver_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
mutex_lock(&wl->mutex);
if (wl->hw_pg_ver >= 0)
len = sysfs_emit(buf, "%d\n", wl->hw_pg_ver);
else
len = sysfs_emit(buf, "n/a\n");
mutex_unlock(&wl->mutex);
return len;
}
static DEVICE_ATTR_RO(hw_pg_ver);
static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t pos, size_t count)
{
struct device *dev = kobj_to_dev(kobj);
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
int ret;
ret = mutex_lock_interruptible(&wl->mutex);
if (ret < 0)
return -ERESTARTSYS;
/* Check if the fwlog is still valid */
if (wl->fwlog_size < 0) {
mutex_unlock(&wl->mutex);
return 0;
}
/* Seeking is not supported - old logs are not kept. Disregard pos. */
len = min_t(size_t, count, wl->fwlog_size);
wl->fwlog_size -= len;
memcpy(buffer, wl->fwlog, len);
/* Make room for new messages */
memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size);
mutex_unlock(&wl->mutex);
return len;
}
static const struct bin_attribute fwlog_attr = {
.attr = { .name = "fwlog", .mode = 0400 },
.read = wl1271_sysfs_read_fwlog,
};
int wlcore_sysfs_init(struct wl1271 *wl)
{
int ret;
/* Create sysfs file to control bt coex state */
ret = device_create_file(wl->dev, &dev_attr_bt_coex_state);
if (ret < 0) {
wl1271_error("failed to create sysfs file bt_coex_state");
goto out;
}
/* Create sysfs file to get HW PG version */
ret = device_create_file(wl->dev, &dev_attr_hw_pg_ver);
if (ret < 0) {
wl1271_error("failed to create sysfs file hw_pg_ver");
goto out_bt_coex_state;
}
/* Create sysfs file for the FW log */
ret = device_create_bin_file(wl->dev, &fwlog_attr);
if (ret < 0) {
wl1271_error("failed to create sysfs file fwlog");
goto out_hw_pg_ver;
}
goto out;
out_hw_pg_ver:
device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
out_bt_coex_state:
device_remove_file(wl->dev, &dev_attr_bt_coex_state);
out:
return ret;
}
void wlcore_sysfs_free(struct wl1271 *wl)
{
device_remove_bin_file(wl->dev, &fwlog_attr);
device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
device_remove_file(wl->dev, &dev_attr_bt_coex_state);
}