// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 Linaro Limited, All rights reserved.
* Author: Mike Leach <mike.leach@linaro.org>
*/
#include <linux/atomic.h>
#include <linux/coresight.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include "coresight-cti.h"
/*
* Declare the number of static declared attribute groups
* Value includes groups + NULL value at end of table.
*/
#define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
/*
* List of trigger signal type names. Match the constants declared in
* include\dt-bindings\arm\coresight-cti-dt.h
*/
static const char * const sig_type_names[] = {
"genio", /* GEN_IO */
"intreq", /* GEN_INTREQ */
"intack", /* GEN_INTACK */
"haltreq", /* GEN_HALTREQ */
"restartreq", /* GEN_RESTARTREQ */
"pe_edbgreq", /* PE_EDBGREQ */
"pe_dbgrestart",/* PE_DBGRESTART */
"pe_ctiirq", /* PE_CTIIRQ */
"pe_pmuirq", /* PE_PMUIRQ */
"pe_dbgtrigger",/* PE_DBGTRIGGER */
"etm_extout", /* ETM_EXTOUT */
"etm_extin", /* ETM_EXTIN */
"snk_full", /* SNK_FULL */
"snk_acqcomp", /* SNK_ACQCOMP */
"snk_flushcomp",/* SNK_FLUSHCOMP */
"snk_flushin", /* SNK_FLUSHIN */
"snk_trigin", /* SNK_TRIGIN */
"stm_asyncout", /* STM_ASYNCOUT */
"stm_tout_spte",/* STM_TOUT_SPTE */
"stm_tout_sw", /* STM_TOUT_SW */
"stm_tout_hete",/* STM_TOUT_HETE */
"stm_hwevent", /* STM_HWEVENT */
"ela_tstart", /* ELA_TSTART */
"ela_tstop", /* ELA_TSTOP */
"ela_dbgreq", /* ELA_DBGREQ */
};
/* Show function pointer used in the connections dynamic declared attributes*/
typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
char *buf);
/* Connection attribute types */
enum cti_conn_attr_type {
CTI_CON_ATTR_NAME,
CTI_CON_ATTR_TRIGIN_SIG,
CTI_CON_ATTR_TRIGOUT_SIG,
CTI_CON_ATTR_TRIGIN_TYPES,
CTI_CON_ATTR_TRIGOUT_TYPES,
CTI_CON_ATTR_MAX,
};
/* Names for the connection attributes */
static const char * const con_attr_names[CTI_CON_ATTR_MAX] = {
"name",
"in_signals",
"out_signals",
"in_types",
"out_types",
};
/* basic attributes */
static ssize_t enable_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int enable_req;
bool enabled, powered;
struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
enable_req = atomic_read(&drvdata->config.enable_req_count);
spin_lock(&drvdata->spinlock);
powered = drvdata->config.hw_powered;
enabled = drvdata->config.hw_enabled;
spin_unlock(&drvdata->spinlock);
if (powered)
return sprintf(buf, "%d\n", enabled);
else
return sprintf(buf, "%d\n", !!enable_req);
}
static ssize_t enable_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
int ret = 0;
unsigned long val;
struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
ret = kstrtoul(buf, 0, &val