// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corp. 2016
 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 *
 * Adjunct processor bus, card related code.
 */

#define KMSG_COMPONENT "ap"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/init.h>
#include <linux/slab.h>
#include <asm/facility.h>

#include "ap_bus.h"

/*
 * AP card related attributes.
 */
static ssize_t hwtype_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct ap_card *ac = to_ap_card(dev);

	return scnprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
}

static DEVICE_ATTR_RO(hwtype);

static ssize_t raw_hwtype_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct ap_card *ac = to_ap_card(dev);

	return scnprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
}

static DEVICE_ATTR_RO(raw_hwtype);

static ssize_t depth_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct ap_card *ac = to_ap_card(dev);

	return scnprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
}

static DEVICE_ATTR_RO(depth);

static ssize_t ap_functions_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	struct ap_card *ac = to_ap_card(dev);

	return scnprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions);
}

static DEVICE_ATTR_RO(ap_functions);

static ssize_t request_count_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct ap_card *ac = to_ap_card(dev);
	u64 req_cnt;

	req_cnt = 0;
	spin_lock_bh(&ap_queues_lock);
	req_cnt = atomic64_read(&ac->total_request_count);
	spin_unlock_bh(&ap_queues_lock);
	return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
}

static ssize_t request_count_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	int bkt;
	struct ap_queue *aq;
	struct ap_card *ac = to_ap_card(dev);

	spin_lock_bh(&ap_queues_lock);
	hash_for_each(ap_queues, bkt, aq, hnode)
		if (ac == aq->card)
			aq->total_request_count = 0;
	spin_unlock_bh(&ap_queues_lock);
	atomic64_set(&ac->total_request_count, 0);

	return count;
}

static DEVICE_ATTR_RW(request_count);

static ssize_t requestq_count_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	int bkt;
	struct ap_queue *aq;
	unsigned int reqq_cnt;
	struct ap_card *ac = to_ap_card(dev);

	reqq_cnt = 0;
	spin_lock_bh(&ap_queues_lock);
	hash_for_each(ap_queues, bkt, aq, hnode)
		if (ac == aq->card)
			reqq_cnt += aq->requestq_count;
	spin_unlock_bh(&ap_queues_lock);
	return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
}

static DEVICE_ATTR_RO(requestq_count);

static ssize_t pendingq_count_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	int bkt;
	struct ap_queue *aq;
	unsigned int penq_cnt;
	struct ap_card *ac = to_ap_card(dev);

	penq_cnt = 0;
	spin_lock_bh(&ap_queues_lock);
	hash_for_each(ap_queues, bkt, aq, hnode)
		if (ac == aq->card)
			penq_cnt += aq->pendingq_count;
	spin_unlock_bh(&ap_queues_lock);
	return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
}

static DEVICE_ATTR_RO(pendingq_count);

static ssize_t modalias_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "ap:t%02X\n",
			 to_ap_dev(dev)->device_type);
}

static DEVICE_ATTR_RO(modalias);

static struct attribute *ap_card_dev_attrs[] = {
	&dev_attr_hwtype.attr,
	&dev_attr_raw_hwtype.attr,
	&dev_attr_depth.attr,
	&dev_attr_ap_functions.attr,
	&dev_attr_request_count.attr,
	&dev_attr_requestq_count.attr,
	&dev_attr_pendingq_count.attr,
	&dev_attr_modalias.attr,
	NULL
};

static struct attribute_group ap_card_dev_attr_group = {
	.attrs = ap_card_dev_attrs
};

static const struct attribute_group *ap_card_dev_attr_groups[] = {
	&ap_card_dev_attr_group,
	NULL
};

static struct device_type ap_card_type = {
	.name = "ap_card",
	.groups = ap_card_dev_attr_groups,
};

static void ap_card_device_release(struct device *dev)
{
	struct ap_card *ac = to_ap_card(dev);

	kfree(ac);
}

struct ap_card *ap_card_create(int id, int queue_depth, int raw_type,
			       int comp_type, unsigned int functions)
{
	struct ap_card *ac;

	ac = kzalloc(sizeof(*ac), GFP_KERNEL);
	if (!ac)
		return NULL;
	ac->ap_dev.device.release = ap_card_device_release;
	ac->ap_dev.device.type = &ap_card_type;
	ac->ap_dev.device_type = comp_type;
	ac->raw_hwtype = raw_type;
	ac->queue_depth = queue_depth;
	ac->functions = functions;
	ac->id = id;
	return ac;
}
