brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · cf91abe Raw
145 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2014 Linaro Ltd.4 *5 * Author: Linus Walleij <linus.walleij@linaro.org>6 */7#include <linux/device.h>8#include <linux/init.h>9#include <linux/io.h>10#include <linux/slab.h>11#include <linux/sys_soc.h>12#include <linux/platform_device.h>13#include <linux/mfd/syscon.h>14#include <linux/regmap.h>15#include <linux/of.h>16 17/* System ID in syscon */18#define REALVIEW_SYS_ID_OFFSET 0x0019 20static const struct of_device_id realview_soc_of_match[] = {21	{ .compatible = "arm,realview-eb-soc",	},22	{ .compatible = "arm,realview-pb1176-soc", },23	{ .compatible = "arm,realview-pb11mp-soc", },24	{ .compatible = "arm,realview-pba8-soc", },25	{ .compatible = "arm,realview-pbx-soc", },26	{ }27};28 29static u32 realview_coreid;30 31static const char *realview_arch_str(u32 id)32{33	switch ((id >> 8) & 0xf) {34	case 0x04:35		return "AHB";36	case 0x05:37		return "Multi-layer AXI";38	default:39		return "Unknown";40	}41}42 43static ssize_t44manufacturer_show(struct device *dev, struct device_attribute *attr, char *buf)45{46	return sprintf(buf, "%02x\n", realview_coreid >> 24);47}48 49static DEVICE_ATTR_RO(manufacturer);50 51static ssize_t52board_show(struct device *dev, struct device_attribute *attr, char *buf)53{54	return sprintf(buf, "HBI-%03x\n", ((realview_coreid >> 16) & 0xfff));55}56 57static DEVICE_ATTR_RO(board);58 59static ssize_t60fpga_show(struct device *dev, struct device_attribute *attr, char *buf)61{62	return sprintf(buf, "%s\n", realview_arch_str(realview_coreid));63}64 65static DEVICE_ATTR_RO(fpga);66 67static ssize_t68build_show(struct device *dev, struct device_attribute *attr, char *buf)69{70	return sprintf(buf, "%02x\n", (realview_coreid & 0xFF));71}72 73static DEVICE_ATTR_RO(build);74 75static struct attribute *realview_attrs[] = {76	&dev_attr_manufacturer.attr,77	&dev_attr_board.attr,78	&dev_attr_fpga.attr,79	&dev_attr_build.attr,80	NULL81};82 83ATTRIBUTE_GROUPS(realview);84 85static void realview_soc_socdev_release(void *data)86{87	struct soc_device *soc_dev = data;88 89	soc_device_unregister(soc_dev);90}91 92static int realview_soc_probe(struct platform_device *pdev)93{94	struct regmap *syscon_regmap;95	struct soc_device *soc_dev;96	struct soc_device_attribute *soc_dev_attr;97	struct device_node *np = pdev->dev.of_node;98	int ret;99 100	syscon_regmap = syscon_regmap_lookup_by_phandle(np, "regmap");101	if (IS_ERR(syscon_regmap))102		return PTR_ERR(syscon_regmap);103 104	soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), GFP_KERNEL);105	if (!soc_dev_attr)106		return -ENOMEM;107 108	ret = of_property_read_string(np, "compatible",109				      &soc_dev_attr->soc_id);110	if (ret)111		return -EINVAL;112 113	soc_dev_attr->machine = "RealView";114	soc_dev_attr->family = "Versatile";115	soc_dev_attr->custom_attr_group = realview_groups[0];116	soc_dev = soc_device_register(soc_dev_attr);117	if (IS_ERR(soc_dev))118		return -ENODEV;119 120	ret = devm_add_action_or_reset(&pdev->dev, realview_soc_socdev_release,121				       soc_dev);122	if (ret)123		return ret;124 125	ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET,126			  &realview_coreid);127	if (ret)128		return -ENODEV;129 130	dev_info(&pdev->dev, "RealView Syscon Core ID: 0x%08x, HBI-%03x\n",131		 realview_coreid,132		 ((realview_coreid >> 16) & 0xfff));133	/* FIXME: add attributes for SoC to sysfs */134	return 0;135}136 137static struct platform_driver realview_soc_driver = {138	.probe = realview_soc_probe,139	.driver = {140		.name = "realview-soc",141		.of_match_table = realview_soc_of_match,142	},143};144builtin_platform_driver(realview_soc_driver);145