blob: ba7dd569a55a191357005a6110a701dc1ba1bbda [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Support for atomisp driver sysfs interface
*
* Copyright (c) 2014 Intel Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include "atomisp_compat.h"
#include "atomisp_internal.h"
#include "atomisp_ioctl.h"
#include "atomisp_drvfs.h"
#include "hmm/hmm.h"
#include "ia_css_debug.h"
#define OPTION_BIN_LIST BIT(0)
#define OPTION_BIN_RUN BIT(1)
#define OPTION_VALID (OPTION_BIN_LIST | OPTION_BIN_RUN)
/*
* dbgopt: iunit debug option:
* bit 0: binary list
* bit 1: running binary
* bit 2: memory statistic
*/
static unsigned int dbgopt = OPTION_BIN_LIST;
static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
unsigned int opt)
{
int ret = 0;
if (opt & OPTION_VALID) {
if (opt & OPTION_BIN_LIST) {
ret = atomisp_css_dump_blob_infor(isp);
if (ret) {
dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n",
__func__, ret);
goto opt_err;
}
}
if (opt & OPTION_BIN_RUN) {
if (isp->asd.streaming) {
atomisp_css_dump_sp_raw_copy_linecount(true);
atomisp_css_debug_dump_isp_binary();
} else {
ret = -EPERM;
dev_err(isp->dev, "%s dump running bin err[ret:%d]\n",
__func__, ret);
goto opt_err;
}
}
} else {
ret = -EINVAL;
dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret);
}
opt_err:
return ret;
}
static ssize_t dbglvl_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
unsigned int dbglvl = ia_css_debug_get_dtrace_level();
return sysfs_emit(buf, "dtrace level:%u\n", dbglvl);
}
static ssize_t dbglvl_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned int dbglvl;
int ret;
ret = kstrtouint(buf, 10, &dbglvl);
if (ret)
return ret;
if (dbglvl < 1 || dbglvl > 9)
return -ERANGE;
ia_css_debug_set_dtrace_level(dbglvl);
return size;
}
static DEVICE_ATTR_RW(dbglvl);
static ssize_t dbgfun_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
unsigned int dbgfun = atomisp_get_css_dbgfunc();
return sysfs_emit(buf, "dbgfun opt:%u\n", dbgfun);
}
static ssize_t dbgfun_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
struct atomisp_device *isp = dev_get_drvdata(dev);
unsigned int opt;
int ret;
ret = kstrtouint(buf, 10, &opt);
if (ret)
return ret;
return atomisp_set_css_dbgfunc(isp, opt);
}
static DEVICE_ATTR_RW(dbgfun);
static ssize_t dbgopt_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sysfs_emit(buf, "option:0x%x\n", dbgopt);
}
static ssize_t dbgopt_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
struct atomisp_device *isp = dev_get_drvdata(dev);
unsigned int opt;
int ret;
ret = kstrtouint(buf, 10, &opt);
if (ret)
return ret;
dbgopt = opt;
ret = iunit_dump_dbgopt(isp, dbgopt);
if (ret)
return ret;
return size;
}
static DEVICE_ATTR_RW(dbgopt);
static struct attribute *dbg_attrs[] = {
&dev_attr_dbglvl.attr,
&dev_attr_dbgfun.attr,
&dev_attr_dbgopt.attr,
NULL
};
static const struct attribute_group dbg_attr_group = {
.attrs = dbg_attrs,
};
const struct attribute_group *dbg_attr_groups[] = {
&dbg_attr_group,
NULL
};