1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright © 2014 NVIDIA Corporation 4 * Copyright © 2015 Broadcom Corporation 5 */ 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 14 static u32 family_id; 15 static u32 product_id; 16 17 u32 brcmstb_get_family_id(void) 18 { 19 return family_id; 20 } 21 EXPORT_SYMBOL(brcmstb_get_family_id); 22 23 u32 brcmstb_get_product_id(void) 24 { 25 return product_id; 26 } 27 EXPORT_SYMBOL(brcmstb_get_product_id); 28 29 static 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 43 static 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 but 50 * bail out early 51 */ 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); 65 out: 66 of_node_put(sun_top_ctrl); 67 return ret; 68 } 69 early_initcall(brcmstb_soc_device_early_init); 70 71 static 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 but 79 * bail out early 80 */ 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 } 109 out: 110 of_node_put(sun_top_ctrl); 111 return ret; 112 } 113 arch_initcall(brcmstb_soc_device_init); 114