static void __init tegra_dt_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device *parent = NULL; tegra_clocks_apply_init_table(); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) goto out; soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision); soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->family); kfree(soc_dev_attr->revision); kfree(soc_dev_attr->soc_id); kfree(soc_dev_attr); goto out; } parent = soc_device_to_device(soc_dev); /* * Finished with the static registrations now; fill in the missing * devices */ out: of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); }
struct soc_device * __init at91_soc_init(const struct at91_soc *socs) { struct soc_device_attribute *soc_dev_attr; const struct at91_soc *soc; struct soc_device *soc_dev; u32 cidr, exid; int ret; /* * With SAMA5D2 and later SoCs, CIDR and EXID registers are no more * in the dbgu device but in the chipid device whose purpose is only * to expose these two registers. */ ret = at91_get_cidr_exid_from_dbgu(&cidr, &exid); if (ret) ret = at91_get_cidr_exid_from_chipid(&cidr, &exid); if (ret) { if (ret == -ENODEV) pr_warn("Could not find identification node"); return NULL; } for (soc = socs; soc->name; soc++) { if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) continue; if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) break; } if (!soc->name) { pr_warn("Could not find matching SoC description\n"); return NULL; } soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return NULL; soc_dev_attr->family = soc->family; soc_dev_attr->soc_id = soc->name; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", AT91_CIDR_VERSION(cidr)); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree(soc_dev_attr); pr_warn("Could not register SoC device\n"); return NULL; } if (soc->family) pr_info("Detected SoC family: %s\n", soc->family); pr_info("Detected SoC: %s, revision %X\n", soc->name, AT91_CIDR_VERSION(cidr)); return soc_dev; }
static int __init imx8_soc_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device_node *root; const struct of_device_id *id; u32 soc_rev = 0; const struct imx8_soc_data *data; int ret; soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENODEV; soc_dev_attr->family = "Freescale i.MX"; root = of_find_node_by_path("/"); ret = of_property_read_string(root, "model", &soc_dev_attr->machine); if (ret) goto free_soc; id = of_match_node(imx8_soc_match, root); if (!id) goto free_soc; of_node_put(root); data = id->data; if (data) { soc_dev_attr->soc_id = data->name; if (data->soc_revision) soc_rev = data->soc_revision(); } soc_dev_attr->revision = imx8_revision(soc_rev); if (!soc_dev_attr->revision) goto free_soc; soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) goto free_rev; if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0); return 0; free_rev: kfree(soc_dev_attr->revision); free_soc: kfree(soc_dev_attr); of_node_put(root); return -ENODEV; }
static void __init intcp_init_of(void) { struct device_node *root; struct device_node *cpcon; struct device *parent; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; u32 intcp_sc_id; int err; /* Here we create an SoC device for the root node */ root = of_find_node_by_path("/"); if (!root) return; cpcon = of_find_matching_node(root, intcp_syscon_match); if (!cpcon) return; intcp_con_base = of_iomap(cpcon, 0); if (!intcp_con_base) return; intcp_sc_id = readl(intcp_con_base); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return; err = of_property_read_string(root, "compatible", &soc_dev_attr->soc_id); if (err) return; err = of_property_read_string(root, "model", &soc_dev_attr->machine); if (err) return; soc_dev_attr->family = "Integrator"; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", 'A' + (intcp_sc_id & 0x0f)); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree(soc_dev_attr); return; } parent = soc_device_to_device(soc_dev); integrator_init_sysfs(parent, intcp_sc_id); of_platform_populate(root, of_default_bus_match_table, intcp_auxdata_lookup, parent); }
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; }
static int realview_soc_probe(struct platform_device *pdev) { static struct regmap *syscon_regmap; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; struct device_node *np = pdev->dev.of_node; int ret; syscon_regmap = syscon_regmap_lookup_by_phandle(np, "regmap"); if (IS_ERR(syscon_regmap)) return PTR_ERR(syscon_regmap); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; ret = of_property_read_string(np, "compatible", &soc_dev_attr->soc_id); if (ret) return -EINVAL; soc_dev_attr->machine = "RealView"; soc_dev_attr->family = "Versatile"; soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr); return -ENODEV; } ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET, &realview_coreid); if (ret) return -ENODEV; device_create_file(soc_device_to_device(soc_dev), &realview_manf_attr); device_create_file(soc_device_to_device(soc_dev), &realview_board_attr); device_create_file(soc_device_to_device(soc_dev), &realview_arch_attr); device_create_file(soc_device_to_device(soc_dev), &realview_build_attr); dev_info(&pdev->dev, "RealView Syscon Core ID: 0x%08x, HBI-%03x\n", realview_coreid, ((realview_coreid >> 16) & 0xfff)); /* FIXME: add attributes for SoC to sysfs */ return 0; }
struct device * __init ux500_soc_device_init(const char *soc_id) { struct device *parent; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return ERR_PTR(-ENOMEM); soc_info_populate(soc_dev_attr, soc_id); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr); return NULL; } parent = soc_device_to_device(soc_dev); device_create_file(parent, &ux500_soc_attr); return parent; }
static struct device __init *ep93xx_init_soc(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return NULL; soc_dev_attr->machine = ep93xx_get_machine_name(); soc_dev_attr->family = "Cirrus Logic EP93xx"; soc_dev_attr->revision = ep93xx_get_soc_rev(); soc_dev_attr->soc_id = ep93xx_get_soc_id(); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->machine); kfree(soc_dev_attr); return NULL; } return soc_device_to_device(soc_dev); }
static int __init meson_mx_socinfo_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device_node *np; struct regmap *assist_regmap, *bootrom_regmap, *analog_top_regmap; unsigned int major_ver, misc_ver, metal_rev = 0; int ret; assist_regmap = syscon_regmap_lookup_by_compatible("amlogic,meson-mx-assist"); if (IS_ERR(assist_regmap)) return PTR_ERR(assist_regmap); bootrom_regmap = syscon_regmap_lookup_by_compatible("amlogic,meson-mx-bootrom"); if (IS_ERR(bootrom_regmap)) return PTR_ERR(bootrom_regmap); np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids); if (np) { analog_top_regmap = syscon_node_to_regmap(np); if (IS_ERR(analog_top_regmap)) return PTR_ERR(analog_top_regmap); ret = regmap_read(analog_top_regmap, MESON_MX_ANALOG_TOP_METAL_REVISION, &metal_rev); if (ret) return ret; } ret = regmap_read(assist_regmap, MESON_MX_ASSIST_HW_REV, &major_ver); if (ret < 0) return ret; ret = regmap_read(bootrom_regmap, MESON_MX_BOOTROM_MISC_VER, &misc_ver); if (ret < 0) return ret; soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENODEV; soc_dev_attr->family = "Amlogic Meson"; np = of_find_node_by_path("/"); of_property_read_string(np, "model", &soc_dev_attr->machine); of_node_put(np); soc_dev_attr->revision = meson_mx_socinfo_revision(major_ver, misc_ver, metal_rev); soc_dev_attr->soc_id = meson_mx_socinfo_soc_id(major_ver, metal_rev); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree_const(soc_dev_attr->revision); kfree_const(soc_dev_attr->soc_id); kfree(soc_dev_attr); return PTR_ERR(soc_dev); } dev_info(soc_device_to_device(soc_dev), "Amlogic %s %s detected\n", soc_dev_attr->soc_id, soc_dev_attr->revision); return 0; }
static void __init ap_init_of(void) { unsigned long sc_dec; struct device_node *root; struct device_node *syscon; struct device *parent; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; u32 ap_sc_id; int err; int i; /* Here we create an SoC device for the root node */ root = of_find_node_by_path("/"); if (!root) return; syscon = of_find_node_by_path("/syscon"); if (!syscon) return; ap_syscon_base = of_iomap(syscon, 0); if (!ap_syscon_base) return; ap_sc_id = readl(ap_syscon_base); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return; err = of_property_read_string(root, "compatible", &soc_dev_attr->soc_id); if (err) return; err = of_property_read_string(root, "model", &soc_dev_attr->machine); if (err) return; soc_dev_attr->family = "Integrator"; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", 'A' + (ap_sc_id & 0x0f)); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree(soc_dev_attr); return; } parent = soc_device_to_device(soc_dev); integrator_init_sysfs(parent, ap_sc_id); of_platform_populate(root, of_default_bus_match_table, ap_auxdata_lookup, parent); sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); for (i = 0; i < 4; i++) { struct lm_device *lmdev; if ((sc_dec & (16 << i)) == 0) continue; lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); if (!lmdev) continue; lmdev->resource.start = 0xc0000000 + 0x10000000 * i; lmdev->resource.end = lmdev->resource.start + 0x0fffffff; lmdev->resource.flags = IORESOURCE_MEM; lmdev->irq = IRQ_AP_EXPINT0 + i; lmdev->id = i; lm_device_register(lmdev); } }
int __init meson_gx_socinfo_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device_node *np; struct regmap *regmap; unsigned int socinfo; struct device *dev; int ret; /* look up for chipid node */ np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gx-ao-secure"); if (!np) return -ENODEV; /* check if interface is enabled */ if (!of_device_is_available(np)) return -ENODEV; /* check if chip-id is available */ if (!of_property_read_bool(np, "amlogic,has-chip-id")) return -ENODEV; /* node should be a syscon */ regmap = syscon_node_to_regmap(np); of_node_put(np); if (IS_ERR(regmap)) { pr_err("%s: failed to get regmap\n", __func__); return -ENODEV; } ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo); if (ret < 0) return ret; if (!socinfo) { pr_err("%s: invalid chipid value\n", __func__); return -EINVAL; } soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENODEV; soc_dev_attr->family = "Amlogic Meson"; np = of_find_node_by_path("/"); of_property_read_string(np, "model", &soc_dev_attr->machine); of_node_put(np); soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x", socinfo_to_major(socinfo), socinfo_to_minor(socinfo), socinfo_to_pack(socinfo), socinfo_to_misc(socinfo)); soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)", socinfo_to_soc_id(socinfo), socinfo_to_package_id(socinfo)); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree_const(soc_dev_attr->soc_id); kfree(soc_dev_attr); return PTR_ERR(soc_dev); } dev = soc_device_to_device(soc_dev); dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n", soc_dev_attr->soc_id, socinfo_to_major(socinfo), socinfo_to_minor(socinfo), socinfo_to_pack(socinfo), socinfo_to_misc(socinfo)); return 0; }