1 /* 2 * Copyright © 2014 NVIDIA Corporation 3 * Copyright © 2015 Broadcom Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15 #include <linux/io.h> 16 #include <linux/of.h> 17 #include <linux/of_address.h> 18 #include <linux/slab.h> 19 #include <linux/soc/brcmstb/brcmstb.h> 20 #include <linux/sys_soc.h> 21 22 #include <soc/brcmstb/common.h> 23 24 static u32 family_id; 25 static u32 product_id; 26 27 static const struct of_device_id brcmstb_machine_match[] = { 28 { .compatible = "brcm,brcmstb", }, 29 { } 30 }; 31 32 bool soc_is_brcmstb(void) 33 { 34 struct device_node *root; 35 36 root = of_find_node_by_path("/"); 37 if (!root) 38 return false; 39 40 return of_match_node(brcmstb_machine_match, root) != NULL; 41 } 42 43 u32 brcmstb_get_family_id(void) 44 { 45 return family_id; 46 } 47 EXPORT_SYMBOL(brcmstb_get_family_id); 48 49 u32 brcmstb_get_product_id(void) 50 { 51 return product_id; 52 } 53 EXPORT_SYMBOL(brcmstb_get_product_id); 54 55 static const struct of_device_id sun_top_ctrl_match[] = { 56 { .compatible = "brcm,bcm7125-sun-top-ctrl", }, 57 { .compatible = "brcm,bcm7346-sun-top-ctrl", }, 58 { .compatible = "brcm,bcm7358-sun-top-ctrl", }, 59 { .compatible = "brcm,bcm7360-sun-top-ctrl", }, 60 { .compatible = "brcm,bcm7362-sun-top-ctrl", }, 61 { .compatible = "brcm,bcm7420-sun-top-ctrl", }, 62 { .compatible = "brcm,bcm7425-sun-top-ctrl", }, 63 { .compatible = "brcm,bcm7429-sun-top-ctrl", }, 64 { .compatible = "brcm,bcm7435-sun-top-ctrl", }, 65 { .compatible = "brcm,brcmstb-sun-top-ctrl", }, 66 { } 67 }; 68 69 static int __init brcmstb_soc_device_init(void) 70 { 71 struct soc_device_attribute *soc_dev_attr; 72 struct soc_device *soc_dev; 73 struct device_node *sun_top_ctrl; 74 void __iomem *sun_top_ctrl_base; 75 int ret = 0; 76 77 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); 78 if (!sun_top_ctrl) 79 return -ENODEV; 80 81 sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0); 82 if (!sun_top_ctrl_base) 83 return -ENODEV; 84 85 family_id = readl(sun_top_ctrl_base); 86 product_id = readl(sun_top_ctrl_base + 0x4); 87 88 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 89 if (!soc_dev_attr) { 90 ret = -ENOMEM; 91 goto out; 92 } 93 94 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", 95 family_id >> 28 ? 96 family_id >> 16 : family_id >> 8); 97 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%x", 98 product_id >> 28 ? 99 product_id >> 16 : product_id >> 8); 100 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c%d", 101 ((product_id & 0xf0) >> 4) + 'A', 102 product_id & 0xf); 103 104 soc_dev = soc_device_register(soc_dev_attr); 105 if (IS_ERR(soc_dev)) { 106 kfree(soc_dev_attr->family); 107 kfree(soc_dev_attr->soc_id); 108 kfree(soc_dev_attr->revision); 109 kfree(soc_dev_attr); 110 ret = -ENODEV; 111 goto out; 112 } 113 114 return 0; 115 116 out: 117 iounmap(sun_top_ctrl_base); 118 return ret; 119 } 120 arch_initcall(brcmstb_soc_device_init); 121