162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/kernel.h>
362306a36Sopenharmony_ci#include <linux/of.h>
462306a36Sopenharmony_ci#include <linux/of_device.h>
562306a36Sopenharmony_ci#include <linux/stat.h>
662306a36Sopenharmony_ci#include <asm/macio.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_cistatic ssize_t
962306a36Sopenharmony_cicompatible_show (struct device *dev, struct device_attribute *attr, char *buf)
1062306a36Sopenharmony_ci{
1162306a36Sopenharmony_ci	struct platform_device *of;
1262306a36Sopenharmony_ci	const char *compat;
1362306a36Sopenharmony_ci	int cplen;
1462306a36Sopenharmony_ci	int length = 0;
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	of = &to_macio_device (dev)->ofdev;
1762306a36Sopenharmony_ci	compat = of_get_property(of->dev.of_node, "compatible", &cplen);
1862306a36Sopenharmony_ci	if (!compat) {
1962306a36Sopenharmony_ci		*buf = '\0';
2062306a36Sopenharmony_ci		return 0;
2162306a36Sopenharmony_ci	}
2262306a36Sopenharmony_ci	while (cplen > 0) {
2362306a36Sopenharmony_ci		int l;
2462306a36Sopenharmony_ci		length += sprintf (buf, "%s\n", compat);
2562306a36Sopenharmony_ci		buf += length;
2662306a36Sopenharmony_ci		l = strlen (compat) + 1;
2762306a36Sopenharmony_ci		compat += l;
2862306a36Sopenharmony_ci		cplen -= l;
2962306a36Sopenharmony_ci	}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	return length;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_cistatic DEVICE_ATTR_RO(compatible);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
3662306a36Sopenharmony_ci			      char *buf)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	return of_device_modalias(dev, buf, PAGE_SIZE);
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic ssize_t devspec_show(struct device *dev,
4262306a36Sopenharmony_ci				struct device_attribute *attr, char *buf)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	struct platform_device *ofdev;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	ofdev = to_platform_device(dev);
4762306a36Sopenharmony_ci	return sprintf(buf, "%pOF\n", ofdev->dev.of_node);
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_cistatic DEVICE_ATTR_RO(modalias);
5062306a36Sopenharmony_cistatic DEVICE_ATTR_RO(devspec);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic ssize_t name_show(struct device *dev,
5362306a36Sopenharmony_ci			 struct device_attribute *attr, char *buf)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	return sprintf(buf, "%pOFn\n", dev->of_node);
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_cistatic DEVICE_ATTR_RO(name);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic ssize_t type_show(struct device *dev,
6062306a36Sopenharmony_ci			 struct device_attribute *attr, char *buf)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	return sprintf(buf, "%s\n", of_node_get_device_type(dev->of_node));
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_cistatic DEVICE_ATTR_RO(type);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic struct attribute *macio_dev_attrs[] = {
6762306a36Sopenharmony_ci	&dev_attr_name.attr,
6862306a36Sopenharmony_ci	&dev_attr_type.attr,
6962306a36Sopenharmony_ci	&dev_attr_compatible.attr,
7062306a36Sopenharmony_ci	&dev_attr_modalias.attr,
7162306a36Sopenharmony_ci	&dev_attr_devspec.attr,
7262306a36Sopenharmony_ci	NULL,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic const struct attribute_group macio_dev_group = {
7662306a36Sopenharmony_ci	.attrs = macio_dev_attrs,
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciconst struct attribute_group *macio_dev_groups[] = {
8062306a36Sopenharmony_ci	&macio_dev_group,
8162306a36Sopenharmony_ci	NULL,
8262306a36Sopenharmony_ci};
83