linux/drivers/soc/bcm/brcmstb/common.c
<<
>>
Prefs
   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
  24static u32 family_id;
  25static u32 product_id;
  26
  27static const struct of_device_id brcmstb_machine_match[] = {
  28        { .compatible = "brcm,brcmstb", },
  29        { }
  30};
  31
  32bool 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
  43static const struct of_device_id sun_top_ctrl_match[] = {
  44        { .compatible = "brcm,brcmstb-sun-top-ctrl", },
  45        { }
  46};
  47
  48static int __init brcmstb_soc_device_init(void)
  49{
  50        struct soc_device_attribute *soc_dev_attr;
  51        struct soc_device *soc_dev;
  52        struct device_node *sun_top_ctrl;
  53        void __iomem *sun_top_ctrl_base;
  54        int ret = 0;
  55
  56        sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
  57        if (!sun_top_ctrl)
  58                return -ENODEV;
  59
  60        sun_top_ctrl_base = of_iomap(sun_top_ctrl, 0);
  61        if (!sun_top_ctrl_base)
  62                return -ENODEV;
  63
  64        family_id = readl(sun_top_ctrl_base);
  65        product_id = readl(sun_top_ctrl_base + 0x4);
  66
  67        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
  68        if (!soc_dev_attr) {
  69                ret = -ENOMEM;
  70                goto out;
  71        }
  72
  73        soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",
  74                                         family_id >> 28 ?
  75                                         family_id >> 16 : family_id >> 8);
  76        soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%x",
  77                                         product_id >> 28 ?
  78                                         product_id >> 16 : product_id >> 8);
  79        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c%d",
  80                                         ((product_id & 0xf0) >> 4) + 'A',
  81                                           product_id & 0xf);
  82
  83        soc_dev = soc_device_register(soc_dev_attr);
  84        if (IS_ERR(soc_dev)) {
  85                kfree(soc_dev_attr->family);
  86                kfree(soc_dev_attr->soc_id);
  87                kfree(soc_dev_attr->revision);
  88                kfree(soc_dev_attr);
  89                ret = -ENODEV;
  90                goto out;
  91        }
  92
  93        return 0;
  94
  95out:
  96        iounmap(sun_top_ctrl_base);
  97        return ret;
  98}
  99arch_initcall(brcmstb_soc_device_init);
 100