diff options
Diffstat (limited to 'arch/powerpc/sysdev/scom.c')
| -rw-r--r-- | arch/powerpc/sysdev/scom.c | 223 | 
1 files changed, 0 insertions, 223 deletions
diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c deleted file mode 100644 index 94e885bf3aee..000000000000 --- a/arch/powerpc/sysdev/scom.c +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2010 Benjamin Herrenschmidt, IBM Corp - *                <[email protected]> - *     and        David Gibson, IBM Corporation. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/export.h> -#include <asm/debugfs.h> -#include <asm/prom.h> -#include <asm/scom.h> -#include <linux/uaccess.h> - -const struct scom_controller *scom_controller; -EXPORT_SYMBOL_GPL(scom_controller); - -struct device_node *scom_find_parent(struct device_node *node) -{ -	struct device_node *par, *tmp; -	const u32 *p; - -	for (par = of_node_get(node); par;) { -		if (of_get_property(par, "scom-controller", NULL)) -			break; -		p = of_get_property(par, "scom-parent", NULL); -		tmp = par; -		if (p == NULL) -			par = of_get_parent(par); -		else -			par = of_find_node_by_phandle(*p); -		of_node_put(tmp); -	} -	return par; -} -EXPORT_SYMBOL_GPL(scom_find_parent); - -scom_map_t scom_map_device(struct device_node *dev, int index) -{ -	struct device_node *parent; -	unsigned int cells, size; -	const __be32 *prop, *sprop; -	u64 reg, cnt; -	scom_map_t ret; - -	parent = scom_find_parent(dev); - -	if (parent == NULL) -		return NULL; - -	/* -	 * We support "scom-reg" properties for adding scom registers -	 * to a random device-tree node with an explicit scom-parent -	 * -	 * We also support the simple "reg" property if the device is -	 * a direct child of a scom controller. -	 * -	 * In case both exist, "scom-reg" takes precedence. -	 */ -	prop = of_get_property(dev, "scom-reg", &size); -	sprop = of_get_property(parent, "#scom-cells", NULL); -	if (!prop && parent == dev->parent) { -		prop = of_get_property(dev, "reg", &size); -		sprop = of_get_property(parent, "#address-cells", NULL); -	} -	if (!prop) -		return NULL; -	cells = sprop ? be32_to_cpup(sprop) : 1; -	size >>= 2; - -	if (index >= (size / (2*cells))) -		return NULL; - -	reg = of_read_number(&prop[index * cells * 2], cells); -	cnt = of_read_number(&prop[index * cells * 2 + cells], cells); - -	ret = scom_map(parent, reg, cnt); -	of_node_put(parent); - -	return ret; -} -EXPORT_SYMBOL_GPL(scom_map_device); - -#ifdef CONFIG_SCOM_DEBUGFS -struct scom_debug_entry { -	struct device_node *dn; -	struct debugfs_blob_wrapper path; -	char name[16]; -}; - -static ssize_t scom_debug_read(struct file *filp, char __user *ubuf, -			       size_t count, loff_t *ppos) -{ -	struct scom_debug_entry *ent = filp->private_data; -	u64 __user *ubuf64 = (u64 __user *)ubuf; -	loff_t off = *ppos; -	ssize_t done = 0;  -	u64 reg, reg_cnt, val; -	scom_map_t map; -	int rc; - -	if (off < 0 || (off & 7) || (count & 7)) -		return -EINVAL; -	reg = off >> 3; -	reg_cnt = count >> 3; - -	map = scom_map(ent->dn, reg, reg_cnt); -	if (!scom_map_ok(map)) -		return -ENXIO; - -	for (reg = 0; reg < reg_cnt; reg++) { -		rc = scom_read(map, reg, &val); -		if (!rc) -			rc = put_user(val, ubuf64); -		if (rc) { -			if (!done) -				done = rc; -			break; -		} -		ubuf64++; -		*ppos += 8; -		done += 8; -	} -	scom_unmap(map); -	return done; -} - -static ssize_t scom_debug_write(struct file* filp, const char __user *ubuf, -				size_t count, loff_t *ppos) -{ -	struct scom_debug_entry *ent = filp->private_data; -	u64 __user *ubuf64 = (u64 __user *)ubuf; -	loff_t off = *ppos; -	ssize_t done = 0;  -	u64 reg, reg_cnt, val; -	scom_map_t map; -	int rc; - -	if (off < 0 || (off & 7) || (count & 7)) -		return -EINVAL; -	reg = off >> 3; -	reg_cnt = count >> 3; - -	map = scom_map(ent->dn, reg, reg_cnt); -	if (!scom_map_ok(map)) -		return -ENXIO; - -	for (reg = 0; reg < reg_cnt; reg++) { -		rc = get_user(val, ubuf64); -		if (!rc) -			rc = scom_write(map, reg,  val); -		if (rc) { -			if (!done) -				done = rc; -			break; -		} -		ubuf64++; -		done += 8; -	} -	scom_unmap(map); -	return done; -} - -static const struct file_operations scom_debug_fops = { -	.read =		scom_debug_read, -	.write =	scom_debug_write, -	.open =		simple_open, -	.llseek =	default_llseek, -}; - -static int scom_debug_init_one(struct dentry *root, struct device_node *dn, -			       int i) -{ -	struct scom_debug_entry *ent; -	struct dentry *dir; - -	ent = kzalloc(sizeof(*ent), GFP_KERNEL); -	if (!ent) -		return -ENOMEM; - -	ent->dn = of_node_get(dn); -	snprintf(ent->name, 16, "%08x", i); -	ent->path.data = (void*)kasprintf(GFP_KERNEL, "%pOF", dn); -	ent->path.size = strlen((char *)ent->path.data); - -	dir = debugfs_create_dir(ent->name, root); -	if (!dir) { -		of_node_put(dn); -		kfree(ent->path.data); -		kfree(ent); -		return -1; -	} - -	debugfs_create_blob("devspec", 0400, dir, &ent->path); -	debugfs_create_file("access", 0600, dir, ent, &scom_debug_fops); - -	return 0; -} - -static int scom_debug_init(void) -{ -	struct device_node *dn; -	struct dentry *root; -	int i, rc; - -	root = debugfs_create_dir("scom", powerpc_debugfs_root); -	if (!root) -		return -1; - -	i = rc = 0; -	for_each_node_with_property(dn, "scom-controller") { -		int id = of_get_ibm_chip_id(dn); -		if (id == -1) -			id = i; -		rc |= scom_debug_init_one(root, dn, id); -		i++; -	} - -	return rc; -} -device_initcall(scom_debug_init); -#endif /* CONFIG_SCOM_DEBUGFS */  |