writel(reg, base + 0x14);
}
+static ssize_t major_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", tegra_get_major_rev());
+}
+
+static DEVICE_ATTR_RO(major);
+
+static ssize_t minor_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", tegra_get_minor_rev());
+}
+
+static DEVICE_ATTR_RO(minor);
+
+static struct attribute *tegra_soc_attr[] = {
+ &dev_attr_major.attr,
+ &dev_attr_minor.attr,
+ NULL,
+};
+
+const struct attribute_group tegra_soc_attr_group = {
+ .attrs = tegra_soc_attr,
+};
+
+#ifdef CONFIG_ARCH_TEGRA_194_SOC
+static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ /*
+ * Displays the value in the 'pre_si_platform' field of the HIDREV
+ * register for Tegra194 devices. A value of 0 indicates that the
+ * platform type is silicon and all other non-zero values indicate
+ * the type of simulation platform is being used.
+ */
+ return sprintf(buf, "%d\n", (tegra_read_chipid() >> 20) & 0xf);
+}
+
+static DEVICE_ATTR_RO(platform);
+
+static struct attribute *tegra194_soc_attr[] = {
+ &dev_attr_major.attr,
+ &dev_attr_minor.attr,
+ &dev_attr_platform.attr,
+ NULL,
+};
+
+const struct attribute_group tegra194_soc_attr_group = {
+ .attrs = tegra194_soc_attr,
+};
+#endif
+
struct device * __init tegra_soc_device_register(void)
{
struct soc_device_attribute *attr;
attr->family = kasprintf(GFP_KERNEL, "Tegra");
attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
+ attr->custom_attr_group = fuse->soc->soc_attr_group;
dev = soc_device_register(attr);
if (IS_ERR(dev)) {
.speedo_init = tegra20_init_speedo_data,
.probe = tegra20_fuse_probe,
.info = &tegra20_fuse_info,
+ .soc_attr_group = &tegra_soc_attr_group,
};
.init = tegra30_fuse_init,
.speedo_init = tegra30_init_speedo_data,
.info = &tegra30_fuse_info,
+ .soc_attr_group = &tegra_soc_attr_group,
};
#endif
.init = tegra30_fuse_init,
.speedo_init = tegra114_init_speedo_data,
.info = &tegra114_fuse_info,
+ .soc_attr_group = &tegra_soc_attr_group,
};
#endif
.info = &tegra124_fuse_info,
.lookups = tegra124_fuse_lookups,
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
+ .soc_attr_group = &tegra_soc_attr_group,
};
#endif
.info = &tegra210_fuse_info,
.lookups = tegra210_fuse_lookups,
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
+ .soc_attr_group = &tegra_soc_attr_group,
};
#endif
.info = &tegra186_fuse_info,
.lookups = tegra186_fuse_lookups,
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
+ .soc_attr_group = &tegra_soc_attr_group,
};
#endif
.info = &tegra194_fuse_info,
.lookups = tegra194_fuse_lookups,
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
+ .soc_attr_group = &tegra194_soc_attr_group,
};
#endif
const struct nvmem_cell_lookup *lookups;
unsigned int num_lookups;
+
+ const struct attribute_group *soc_attr_group;
};
struct tegra_fuse {
bool __init tegra_fuse_read_spare(unsigned int spare);
u32 __init tegra_fuse_read_early(unsigned int offset);
+u8 tegra_get_major_rev(void);
+u8 tegra_get_minor_rev(void);
+
+extern const struct attribute_group tegra_soc_attr_group;
+
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);
#endif
#ifdef CONFIG_ARCH_TEGRA_194_SOC
extern const struct tegra_fuse_soc tegra194_fuse_soc;
+extern const struct attribute_group tegra194_soc_attr_group;
#endif
#endif
return (tegra_read_chipid() >> 8) & 0xff;
}
+u8 tegra_get_major_rev(void)
+{
+ return (tegra_read_chipid() >> 4) & 0xf;
+}
+
+u8 tegra_get_minor_rev(void)
+{
+ return (tegra_read_chipid() >> 16) & 0xf;
+}
+
u32 tegra_read_straps(void)
{
WARN(!chipid, "Tegra ABP MISC not yet available\n");