diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
commit | 863981e96738983919de841ec669e157e6bdaeb0 (patch) | |
tree | d6d89a12e7eb8017837c057935a2271290907f76 /drivers/soc/brcmstb | |
parent | 8dec7c70575785729a6a9e6719a955e9c545bcab (diff) |
Linux-libre 4.7.1-gnupck-4.7.1-gnu
Diffstat (limited to 'drivers/soc/brcmstb')
-rw-r--r-- | drivers/soc/brcmstb/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/brcmstb/common.c | 66 |
2 files changed, 67 insertions, 0 deletions
diff --git a/drivers/soc/brcmstb/Kconfig b/drivers/soc/brcmstb/Kconfig index 39cab3bd5..7fec3b4c8 100644 --- a/drivers/soc/brcmstb/Kconfig +++ b/drivers/soc/brcmstb/Kconfig @@ -1,6 +1,7 @@ menuconfig SOC_BRCMSTB bool "Broadcom STB SoC drivers" depends on ARM + select SOC_BUS help Enables drivers for the Broadcom Set-Top Box (STB) series of chips. This option alone enables only some support code, while the drivers diff --git a/drivers/soc/brcmstb/common.c b/drivers/soc/brcmstb/common.c index c262c029b..94e733555 100644 --- a/drivers/soc/brcmstb/common.c +++ b/drivers/soc/brcmstb/common.c @@ -12,10 +12,18 @@ * GNU General Public License for more details. */ +#include <linux/io.h> #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/soc/brcmstb/brcmstb.h> +#include <linux/sys_soc.h> #include <soc/brcmstb/common.h> +static u32 family_id; +static u32 product_id; + static const struct of_device_id brcmstb_machine_match[] = { { .compatible = "brcm,brcmstb", }, { } @@ -31,3 +39,61 @@ bool soc_is_brcmstb(void) return of_match_node(brcmstb_machine_match, root) != NULL; } + +static const struct of_device_id sun_top_ctrl_match[] = { + { .compatible = "brcm,brcmstb-sun-top-ctrl", }, + { } +}; + +static int __init brcmstb_soc_device_init(void) +{ + struct soc_device_attribute *soc_dev_attr; + struct soc_device *soc_dev; + struct device_node *sun_top_ctrl; + void __iomem *sun_top_ctrl_base; + int ret = 0; + + sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); + if (!sun_top_ctrl) + return -ENODEV; + + sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0); + if (!sun_top_ctrl_base) + return -ENODEV; + + family_id = readl(sun_top_ctrl_base); + product_id = readl(sun_top_ctrl_base + 0x4); + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) { + ret = -ENOMEM; + goto out; + } + + soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", + family_id >> 28 ? + family_id >> 16 : family_id >> 8); + soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%x", + product_id >> 28 ? + product_id >> 16 : product_id >> 8); + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c%d", + ((product_id & 0xf0) >> 4) + 'A', + product_id & 0xf); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->family); + kfree(soc_dev_attr->soc_id); + kfree(soc_dev_attr->revision); + kfree(soc_dev_attr); + ret = -ENODEV; + goto out; + } + + return 0; + +out: + iounmap(sun_top_ctrl_base); + return ret; +} +arch_initcall(brcmstb_soc_device_init); |