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 static const struct of_device_id sun_top_ctrl_match[] = { 44 { .compatible = "brcm,bcm7125-sun-top-ctrl", }, 45 { .compatible = "brcm,bcm7346-sun-top-ctrl", }, 46 { .compatible = "brcm,bcm7358-sun-top-ctrl", }, 47 { .compatible = "brcm,bcm7360-sun-top-ctrl", }, 48 { .compatible = "brcm,bcm7362-sun-top-ctrl", }, 49 { .compatible = "brcm,bcm7420-sun-top-ctrl", }, 50 { .compatible = "brcm,bcm7425-sun-top-ctrl", }, 51 { .compatible = "brcm,bcm7429-sun-top-ctrl", }, 52 { .compatible = "brcm,bcm7435-sun-top-ctrl", }, 53 { .compatible = "brcm,brcmstb-sun-top-ctrl", }, 54 { } 55 }; 56 57 static int __init brcmstb_soc_device_init(void) 58 { 59 struct soc_device_attribute *soc_dev_attr; 60 struct soc_device *soc_dev; 61 struct device_node *sun_top_ctrl; 62 void __iomem *sun_top_ctrl_base; 63 int ret = 0; 64 65 sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); 66 if (!sun_top_ctrl) 67 return -ENODEV; 68 69 sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0); 70 if (!sun_top_ctrl_base) 71 return -ENODEV; 72 73 family_id = readl(sun_top_ctrl_base); 74 product_id = readl(sun_top_ctrl_base + 0x4); 75 76 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 77 if (!soc_dev_attr) { 78 ret = -ENOMEM; 79 goto out; 80 } 81 82 soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", 83 family_id >> 28 ? 84 family_id >> 16 : family_id >> 8); 85 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%x", 86 product_id >> 28 ? 87 product_id >> 16 : product_id >> 8); 88 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c%d", 89 ((product_id & 0xf0) >> 4) + 'A', 90 product_id & 0xf); 91 92 soc_dev = soc_device_register(soc_dev_attr); 93 if (IS_ERR(soc_dev)) { 94 kfree(soc_dev_attr->family); 95 kfree(soc_dev_attr->soc_id); 96 kfree(soc_dev_attr->revision); 97 kfree(soc_dev_attr); 98 ret = -ENODEV; 99 goto out; 100 } 101 102 return 0; 103 104 out: 105 iounmap(sun_top_ctrl_base); 106 return ret; 107 } 108 arch_initcall(brcmstb_soc_device_init); 109