114 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright © 2014 NVIDIA Corporation4 * Copyright © 2015 Broadcom Corporation5 */6 7#include <linux/io.h>8#include <linux/of.h>9#include <linux/of_address.h>10#include <linux/slab.h>11#include <linux/soc/brcmstb/brcmstb.h>12#include <linux/sys_soc.h>13 14static u32 family_id;15static u32 product_id;16 17u32 brcmstb_get_family_id(void)18{19 return family_id;20}21EXPORT_SYMBOL(brcmstb_get_family_id);22 23u32 brcmstb_get_product_id(void)24{25 return product_id;26}27EXPORT_SYMBOL(brcmstb_get_product_id);28 29static const struct of_device_id sun_top_ctrl_match[] = {30 { .compatible = "brcm,bcm7125-sun-top-ctrl", },31 { .compatible = "brcm,bcm7346-sun-top-ctrl", },32 { .compatible = "brcm,bcm7358-sun-top-ctrl", },33 { .compatible = "brcm,bcm7360-sun-top-ctrl", },34 { .compatible = "brcm,bcm7362-sun-top-ctrl", },35 { .compatible = "brcm,bcm7420-sun-top-ctrl", },36 { .compatible = "brcm,bcm7425-sun-top-ctrl", },37 { .compatible = "brcm,bcm7429-sun-top-ctrl", },38 { .compatible = "brcm,bcm7435-sun-top-ctrl", },39 { .compatible = "brcm,brcmstb-sun-top-ctrl", },40 { }41};42 43static int __init brcmstb_soc_device_early_init(void)44{45 struct device_node *sun_top_ctrl;46 void __iomem *sun_top_ctrl_base;47 int ret = 0;48 49 /* We could be on a multi-platform kernel, don't make this fatal but50 * bail out early51 */52 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);53 if (!sun_top_ctrl)54 return ret;55 56 sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0);57 if (!sun_top_ctrl_base) {58 ret = -ENODEV;59 goto out;60 }61 62 family_id = readl(sun_top_ctrl_base);63 product_id = readl(sun_top_ctrl_base + 0x4);64 iounmap(sun_top_ctrl_base);65out:66 of_node_put(sun_top_ctrl);67 return ret;68}69early_initcall(brcmstb_soc_device_early_init);70 71static int __init brcmstb_soc_device_init(void)72{73 struct soc_device_attribute *soc_dev_attr;74 struct device_node *sun_top_ctrl;75 struct soc_device *soc_dev;76 int ret = 0;77 78 /* We could be on a multi-platform kernel, don't make this fatal but79 * bail out early80 */81 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);82 if (!sun_top_ctrl)83 return ret;84 85 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);86 if (!soc_dev_attr) {87 ret = -ENOMEM;88 goto out;89 }90 91 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",92 family_id >> 28 ?93 family_id >> 16 : family_id >> 8);94 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%x",95 product_id >> 28 ?96 product_id >> 16 : product_id >> 8);97 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c%d",98 ((product_id & 0xf0) >> 4) + 'A',99 product_id & 0xf);100 101 soc_dev = soc_device_register(soc_dev_attr);102 if (IS_ERR(soc_dev)) {103 kfree(soc_dev_attr->family);104 kfree(soc_dev_attr->soc_id);105 kfree(soc_dev_attr->revision);106 kfree(soc_dev_attr);107 ret = -ENOMEM;108 }109out:110 of_node_put(sun_top_ctrl);111 return ret;112}113arch_initcall(brcmstb_soc_device_init);114