diff options
Diffstat (limited to 'drivers/soc/tegra/fuse')
-rw-r--r-- | drivers/soc/tegra/fuse/fuse-tegra.c | 54 | ||||
-rw-r--r-- | drivers/soc/tegra/fuse/fuse-tegra20.c | 1 | ||||
-rw-r--r-- | drivers/soc/tegra/fuse/fuse-tegra30.c | 6 | ||||
-rw-r--r-- | drivers/soc/tegra/fuse/fuse.h | 8 | ||||
-rw-r--r-- | drivers/soc/tegra/fuse/tegra-apbmisc.c | 10 |
5 files changed, 79 insertions, 0 deletions
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 802717b9f6a3..db65ddb6a5d2 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -300,6 +300,59 @@ static void tegra_enable_fuse_clk(void __iomem *base) 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; @@ -312,6 +365,7 @@ struct device * __init tegra_soc_device_register(void) 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)) { diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c index d4aef9c4a94c..16aaa28573ac 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra20.c +++ b/drivers/soc/tegra/fuse/fuse-tegra20.c @@ -164,4 +164,5 @@ const struct tegra_fuse_soc tegra20_fuse_soc = { .speedo_init = tegra20_init_speedo_data, .probe = tegra20_fuse_probe, .info = &tegra20_fuse_info, + .soc_attr_group = &tegra_soc_attr_group, }; diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index e6037f900fb7..85accef41fa1 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -111,6 +111,7 @@ const struct tegra_fuse_soc tegra30_fuse_soc = { .init = tegra30_fuse_init, .speedo_init = tegra30_init_speedo_data, .info = &tegra30_fuse_info, + .soc_attr_group = &tegra_soc_attr_group, }; #endif @@ -125,6 +126,7 @@ const struct tegra_fuse_soc tegra114_fuse_soc = { .init = tegra30_fuse_init, .speedo_init = tegra114_init_speedo_data, .info = &tegra114_fuse_info, + .soc_attr_group = &tegra_soc_attr_group, }; #endif @@ -205,6 +207,7 @@ const struct tegra_fuse_soc tegra124_fuse_soc = { .info = &tegra124_fuse_info, .lookups = tegra124_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups), + .soc_attr_group = &tegra_soc_attr_group, }; #endif @@ -290,6 +293,7 @@ const struct tegra_fuse_soc tegra210_fuse_soc = { .info = &tegra210_fuse_info, .lookups = tegra210_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups), + .soc_attr_group = &tegra_soc_attr_group, }; #endif @@ -319,6 +323,7 @@ const struct tegra_fuse_soc tegra186_fuse_soc = { .info = &tegra186_fuse_info, .lookups = tegra186_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups), + .soc_attr_group = &tegra_soc_attr_group, }; #endif @@ -348,5 +353,6 @@ const struct tegra_fuse_soc tegra194_fuse_soc = { .info = &tegra194_fuse_info, .lookups = tegra194_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups), + .soc_attr_group = &tegra194_soc_attr_group, }; #endif diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index 94a059e577a1..9d4fc315a007 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -32,6 +32,8 @@ struct tegra_fuse_soc { const struct nvmem_cell_lookup *lookups; unsigned int num_lookups; + + const struct attribute_group *soc_attr_group; }; struct tegra_fuse { @@ -64,6 +66,11 @@ void tegra_init_apbmisc(void); 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 @@ -110,6 +117,7 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc; #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 diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index 089d9340564b..44a154ca16b5 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -37,6 +37,16 @@ u8 tegra_get_chip_id(void) 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"); |