static ssize_t mode_store()

in coresight/coresight-etm3x-sysfs.c [106:177]


static ssize_t mode_store(struct device *dev,
			  struct device_attribute *attr,
			  const char *buf, size_t size)
{
	int ret;
	unsigned long val;
	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
	struct etm_config *config = &drvdata->config;

	ret = kstrtoul(buf, 16, &val);
	if (ret)
		return ret;

	spin_lock(&drvdata->spinlock);
	config->mode = val & ETM_MODE_ALL;

	if (config->mode & ETM_MODE_EXCLUDE)
		config->enable_ctrl1 |= ETMTECR1_INC_EXC;
	else
		config->enable_ctrl1 &= ~ETMTECR1_INC_EXC;

	if (config->mode & ETM_MODE_CYCACC)
		config->ctrl |= ETMCR_CYC_ACC;
	else
		config->ctrl &= ~ETMCR_CYC_ACC;

	if (config->mode & ETM_MODE_STALL) {
		if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) {
			dev_warn(dev, "stall mode not supported\n");
			ret = -EINVAL;
			goto err_unlock;
		}
		config->ctrl |= ETMCR_STALL_MODE;
	} else
		config->ctrl &= ~ETMCR_STALL_MODE;

	if (config->mode & ETM_MODE_TIMESTAMP) {
		if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) {
			dev_warn(dev, "timestamp not supported\n");
			ret = -EINVAL;
			goto err_unlock;
		}
		config->ctrl |= ETMCR_TIMESTAMP_EN;
	} else
		config->ctrl &= ~ETMCR_TIMESTAMP_EN;

	if (config->mode & ETM_MODE_CTXID)
		config->ctrl |= ETMCR_CTXID_SIZE;
	else
		config->ctrl &= ~ETMCR_CTXID_SIZE;

	if (config->mode & ETM_MODE_BBROAD)
		config->ctrl |= ETMCR_BRANCH_BROADCAST;
	else
		config->ctrl &= ~ETMCR_BRANCH_BROADCAST;

	if (config->mode & ETM_MODE_RET_STACK)
		config->ctrl |= ETMCR_RETURN_STACK;
	else
		config->ctrl &= ~ETMCR_RETURN_STACK;

	if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
		etm_config_trace_mode(config);

	spin_unlock(&drvdata->spinlock);

	return size;

err_unlock:
	spin_unlock(&drvdata->spinlock);
	return ret;
}