// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-omap2/id.c
 *
 * OMAP2 CPU identification code
 *
 * Copyright (C) 2005 Nokia Corporation
 * Written by Tony Lindgren <tony@atomide.com>
 *
 * Copyright (C) 2009-11 Texas Instruments
 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/random.h>
#include <linux/slab.h>

#ifdef CONFIG_SOC_BUS
#include <linux/sys_soc.h>
#endif

#include <asm/cputype.h>

#include "common.h"

#include "id.h"

#include "soc.h"
#include "control.h"

#define OMAP4_SILICON_TYPE_STANDARD		0x01
#define OMAP4_SILICON_TYPE_PERFORMANCE		0x02

#define OMAP_SOC_MAX_NAME_LENGTH		16

static unsigned int omap_revision;
static char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
u32 omap_features;

unsigned int omap_rev(void)
{
	return omap_revision;
}
EXPORT_SYMBOL(omap_rev);

int omap_type(void)
{
	static u32 val = OMAP2_DEVICETYPE_MASK;

	if (val < OMAP2_DEVICETYPE_MASK)
		return val;

	if (soc_is_omap24xx()) {
		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
	} else if (soc_is_ti81xx()) {
		val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
	} else if (soc_is_am33xx() || soc_is_am43xx()) {
		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
	} else if (soc_is_omap34xx()) {
		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
	} else if (soc_is_omap44xx()) {
		val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
		val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
		val &= OMAP5_DEVICETYPE_MASK;
		val >>= 6;
		goto out;
	} else {
		pr_err("Cannot detect omap type!\n");
		goto out;
	}

	val &= OMAP2_DEVICETYPE_MASK;
	val >>= 8;

out:
	return val;
}
EXPORT_SYMBOL(omap_type);


/*----------------------------------------------------------------------------*/

#define OMAP_TAP_IDCODE		0x0204
#define OMAP_TAP_DIE_ID_0	0x0218
#define OMAP_TAP_DIE_ID_1	0x021C
#define OMAP_TAP_DIE_ID_2	0x0220
#define OMAP_TAP_DIE_ID_3	0x0224

#define OMAP_TAP_DIE_ID_44XX_0	0x0200
#define OMAP_TAP_DIE_ID_44XX_1	0x0208
#define OMAP_TAP_DIE_ID_44XX_2	0x020c
#define OMAP_TAP_DIE_ID_44XX_3	0x0210

#define read_tap_reg(reg)	readl_relaxed(tap_base  + (reg))

struct omap_id {
	u16	hawkeye;	/* Silicon type (Hawkeye id) */
	u8	dev;		/* Device type from production_id reg */
	u32	type;		/* Combined type id copied to omap_revision */
};

/* Register values to detect the OMAP version */
static struct omap_id omap_ids[] __initdata = {
	{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
	{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
	{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
	{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
	{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
	{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
};

static void __iomem *tap_base;
static u16 tap_prod_id;

static void omap_get_die_id(struct omap_die_id *odi)
{
	if (soc_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
		odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
		odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
		odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
		odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);

		return;
	}
	odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
	odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
	odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
	odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
}

static int __init omap_feed_randpool(void)
{
	struct omap_die_id odi;

	/* Throw the die ID into the entropy pool at boot */
	omap_get_die_id(&odi);
	add_device_randomness(&odi, sizeof(odi));
	return 0;
}
omap_device_initcall(omap_feed_randpool);

void __init omap2xxx_check_revision(void)
{
	int i, j;
	u32 idcode, prod_id;
	u16 hawkeye;
	u8  dev_type, rev;
	struct omap_die_id odi;

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	prod_id = read_tap_reg(tap_prod_id);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0x0f;
	dev_type = (prod_id >> 16) & 0x0f;
	omap_get_die_id(&odi);

	pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
		 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
	pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
	pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
		 odi.id_1, (odi.id_1 >> 28) & 0xf);
	pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
	pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
	pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
		 prod_id, dev_type);

	/* Check hawkeye ids */
	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
		if (hawkeye == omap_ids[i].hawkeye)
			break;
	}

	if (i == ARRAY_SIZE(omap_ids)) {
		printk(KERN_ERR "Unknown OMAP CPU id\n");
		return;
	}

	for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
		if (dev_type == omap_ids[j].dev)
			break;
	}

	if (j == ARRAY_SIZE(omap_ids)) {
		pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n",
		       omap_ids[i].type >> 16);
		j = i;
	}

	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);

	pr_info("%s", soc_name);
	if ((omap_rev() >> 8) & 0x0f)
		pr_cont("%s", soc_rev);
	pr_cont("\n");
}

#define OMAP3_SHOW_FEATURE(feat)		\
	if (omap3_has_ ##feat())		\
		n += scnprintf(buf + n, sizeof(buf) - n, #feat " ");

static void __init omap3_cpuinfo(void)
{
	const char *cpu_name;
	char buf[64];
	int n = 0;

	memset(buf, 0, sizeof(buf));

	/*
	 * OMAP3430 and OMAP3530 are assumed to be same.
	 *
	 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
	 * on available features. Upon detection, update the CPU id
	 * and CPU class bits.
	 */
	if (soc_is_omap3630()) {
		if (omap3_has_iva() && omap3_has_sgx()) {
			cpu_name = (omap3_has_isp()) ? "OMAP3630/DM3730" : "OMAP3621";
		} else if (omap3_has_iva()) {
			cpu_name = "DM3725";
		} else if (omap3_has_sgx()) {
			cpu_name = "OMAP3615/AM3715";
		} else {
			cpu_name = (omap3_has_isp()) ? "AM3703" : "OMAP3611";
		}
	} else if (soc_is_am35xx()) {
		cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
	} else if (soc_is_ti816x()) {
		cpu_name = "TI816X";
	} else if (soc_is_am335x()) {
		cpu_name =  "AM335X";
	} else if (soc_is_am437x()) {
		cpu_name =  "AM437x";
	} else if (soc_is_ti814x()) {
		cpu_name = "TI814X";
	} else if (omap3_has_iva() && omap3_has_sgx()) {
		/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
		cpu_name = "OMAP3430/3530";
	} else if (omap3_has_iva()) {
		cpu_name = "OMAP3525";
	} else if (omap3_has_sgx()) {
		cpu_name = "OMAP3515";
	} else {
		cpu_name = "OMAP3503";
	}

	scnprintf(soc_name, sizeof(soc_name), "%s", cpu_name);

	/* Print verbose information */
	n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev);

	OMAP3_SHOW_FEATURE(l2cache);
	OMAP3_SHOW_FEATURE(iva);
	OMAP3_SHOW_FEATURE(sgx);
	OMAP3_SHOW_FEATURE(neon);
	OMAP3_SHOW_FEATURE(isp);
	OMAP3_SHOW_FEATURE(192mhz_clk);
	if (*(buf + n - 1) == ' ')
		n--;
	n += scnprintf(buf + n, sizeof(buf) - n, ")\n");
	pr_info("%s", buf);
}

#define OMAP3_CHECK_FEATURE(status,feat)				\
	if (((status & OMAP3_ ##feat## _MASK) 				\
		>> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { 	\
		omap_features |= OMAP3_HAS_ ##feat;			\
	}

void __init omap3xxx_check_features(void)
{
	u32 status;

	omap_features = 0;

	status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);

	OMAP3_CHECK_FEATURE(status, L2CACHE);
	OMAP3_CHECK_FEATURE(status, IVA);
	OMAP3_CHECK_FEATURE(status, SGX);
	OMAP3_CHECK_FEATURE(status, NEON);
	OMAP3_CHECK_FEATURE(status, ISP);
	if (soc_is_omap3630())
		omap_features |= OMAP3_HAS_192MHZ_CLK;
	if (soc_is_omap3430() || soc_is_omap3630())
		omap_features |= OMAP3_HAS_IO_WAKEUP;
	if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
	    omap_rev() == OMAP3430_REV_ES3_1_2)
		omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;

	omap_features |= OMAP3_HAS_SDRC;

	/*
	 * am35x fixups:
	 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
	 *   reserved and therefore return 0 when read.  Unfortunately,
	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
	 *   mean that a feature is present even though it isn't so clear
	 *   the incorrectly set feature bits.
	 */
	if (soc_is_am35xx())
		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);

	/*
	 * TODO: Get additional info (where applicable)
	 *       e.g. Size of L2 cache.
	 */

	omap3_cpuinfo();
}

void __init omap4xxx_check_features(void)
{
	u32 si_type;

	si_type =
	(read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03;

	if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
		omap_features = OMAP4_HAS_PERF_SILICON;
}

void __init ti81xx_check_features(void)
{
	omap_features = OMAP3_HAS_NEON;
	omap3_cpuinfo();
}

void __init am33xx_check_features(void)
{
	u32 status;

	omap_features = OMAP3_HAS_NEON;

	status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
	if (status & AM33XX_SGX_MASK)
		omap_features |= OMAP3_HAS_SGX;

	omap3_cpuinfo();
}

void __init omap3xxx_check_revision(void)
{
	const char *cpu_rev;
	u32 cpuid, idcode;
	u16 hawkeye;
	u8 rev;

	/*
	 * We cannot access revision registers on ES1.0.
	 * If the processor type is Cortex-A8 and the revision is 0x0
	 * it means its Cortex r0p0 which is 3430 ES1.0.
	 */
	cpuid = read_cpuid_id();
	if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
		omap_revision = OMAP3430_REV_ES1_0;
		cpu_rev = "1.0";
		return;
	}

	/*
	 * Detection for 34xx ES2.0 and above can be done with just
	 * hawkeye and rev. See TRM 1.5.2 Device Identification.
	 * Note that rev does not map directly to our defined processor
	 * revision numbers as ES1.0 uses value 0.
	 */
	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;

	switch (hawkeye) {
	case 0xb7ae:
		/* Handle 34xx/35xx devices */
		switch (rev) {
		case 0: /* Take care of early samples */
		case 1:
			omap_revision = OMAP3430_REV_ES2_0;
			cpu_rev = "2.0";
			break;
		case 2:
			omap_revision = OMAP3430_REV_ES2_1;
			cpu_rev = "2.1";
			break;
		case 3:
			omap_revision = OMAP3430_REV_ES3_0;
			cpu_rev = "3.0";
			break;
		case 4:
			omap_revision = OMAP3430_REV_ES3_1;
			cpu_rev = "3.1";
			break;
		case 7:
		default:
			/* Use the latest known revision as default */
			omap_revision = OMAP3430_REV_ES3_1_2;
			cpu_rev = "3.1.2";
		}
		break;
	case 0xb868:
		/*
		 * Handle OMAP/AM 3505/3517 devices
		 *
		 * Set the device to be OMAP3517 here. Actual device
		 * is identified later based on the features.
		 */
		switch (rev) {
		case 0:
			omap_revision = AM35XX_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
		default:
			omap_revision = AM35XX_REV_ES1_1;
			cpu_rev = "1.1";
		}
		break;
	case 0xb891:
		/* Handle 36xx devices */

		switch(rev) {
		case 0: /* Take care of early samples */
			omap_revision = OMAP3630_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = OMAP3630_REV_ES1_1;
			cpu_rev = "1.1";
			break;
		case 2:
		default:
			omap_revision = OMAP3630_REV_ES1_2;
			cpu_rev = "1.2";
		}
		break;
	case 0xb81e:
		switch (rev) {
		case 0:
			omap_revision = TI8168_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = TI8168_REV_ES1_1;
			cpu_rev = "1.1";
			break;
		case 2:
			omap_revision = TI8168_REV_ES2_0;
			cpu_rev = "2.0";
			break;
		case 3:
		default:
			omap_revision = TI8168_REV_ES2_1;
			cpu_rev = "2.1";
		}
		break;
	case 0xb944:
		switch (rev) {
		case 0:
			omap_revision = AM335X_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = AM335X_REV_ES2_0;
			cpu_rev = "2.0";
			break;
		case 2:
		default:
			omap_revision = AM335X_REV_ES2_1;
			cpu_rev = "2.1";
			break;
		}
		break;
	case 0xb98c:
		switch (rev) {
		case 0:
			omap_revision = AM437X_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = AM437X_REV_ES1_1;
			cpu_rev = "1.1";
			break;
		case 2:
		default:
			omap_revision = AM437X_REV_ES1_2;
			cpu_rev = "1.2";
			break;
		}
		break;
	case 0xb8f2:
	case 0xb968:
		switch (rev) {
		case 0:
		case 1:
			omap_revision = TI8148_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 2:
			omap_revision = TI8148_REV_ES2_0;
			cpu_rev = "2.0";
			break;
		case 3:
		default:
			omap_revision = TI8148_REV_ES2_1;
			cpu_rev = "2.1";
			break;
		}
		break;
	default:
		/* Unknown default to latest silicon rev as default */
		omap_revision = OMAP3630_REV_ES1_2;
		cpu_rev = "1.2";
		pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
			hawkeye);
	}
	sprintf(soc_rev, "ES%s", cpu_rev);
}

void __init omap4xxx_check_revision(void)
{
	u32 idcode;
	u16 hawkeye;
	u8 rev;

	/*
	 * The IC rev detection is done with hawkeye and rev.
	 * Note that rev does not map directly to defined processor
	 * revision numbers as ES1.0 uses value 0.
	 */
	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xf;

	/*
	 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
	 * Use ARM register to detect the correct ES version
	 */
	if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
		idcode = read_cpuid_id();
		rev = (idcode & 0xf) - 1;
	}

	switch (hawkeye) {
	case 0xb852:
		switch (rev) {
		case 0:
			omap_revision = OMAP4430_REV_ES1_0;
			break;
		case 1:
		default:
			omap_revision = OMAP4430_REV_ES2_0;
		}
		break;
	case 0xb95c:
		switch (rev) {
		case 3:
			omap_revision = OMAP4430_REV_ES2_1;
			break;
		case 4:
			omap_revision = OMAP4430_REV_ES2_2;
			break;
		case 6:
		default:
			omap_revision = OMAP4430_REV_ES2_3;
		}
		break;
	case 0xb94e:
		switch (rev) {
		case 0:
			omap_revision = OMAP4460_REV_ES1_0;
			break;
		case 2:
		default:
			omap_revision = OMAP4460_REV_ES1_1;
			break;
		}
		break;
	case 0xb975:
		switch (rev) {
		case 0:
		default:
			omap_revision = OMAP4470_REV_ES1_0;
			break;
		}
		break;
	default:
		/* Unknown default to latest silicon rev as default */
		omap_revision = OMAP4430_REV_ES2_3;
	}

	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
						(omap_rev() >> 8) & 0xf);
	pr_info("%s %s\n", soc_name, soc_rev);
}

void __init omap5xxx_check_revision(void)
{
	u32 idcode;
	u16 hawkeye;
	u8 rev;

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;
	switch (hawkeye) {
	case 0xb942:
		switch (rev) {
		case 0:
			/* No support for ES1.0 Test chip */
			BUG();
		case 1:
		default:
			omap_revision = OMAP5430_REV_ES2_0;
		}
		break;

	case 0xb998:
		switch (rev) {
		case 0:
			/* No support for ES1.0 Test chip */
			BUG();
		case 1:
		default:
			omap_revision = OMAP5432_REV_ES2_0;
		}
		break;

	default:
		/* Unknown default to latest silicon rev as default*/
		omap_revision = OMAP5430_REV_ES2_0;
	}

	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);

	pr_info("%s %s\n", soc_name, soc_rev);
}

void __init dra7xxx_check_revision(void)
{
	u32 idcode;
	u16 hawkeye;
	u8 rev, package;
	struct omap_die_id odi;

	omap_get_die_id(&odi);
	package = (odi.id_2 >> 16) & 0x3;
	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;
	switch (hawkeye) {
	case 0xbb50:
		switch (rev) {
		case 0:
		default:
			switch (package) {
			case 0x2:
				omap_revision = DRA762_ABZ_REV_ES1_0;
				break;
			case 0x3:
				omap_revision = DRA762_ACD_REV_ES1_0;
				break;
			default:
				omap_revision = DRA762_REV_ES1_0;
				break;
			}
			break;
		}
		break;

	case 0xb990:
		switch (rev) {
		case 0:
			omap_revision = DRA752_REV_ES1_0;
			break;
		case 1:
			omap_revision = DRA752_REV_ES1_1;
			break;
		case 2:
		default:
			omap_revision = DRA752_REV_ES2_0;
			break;
		}
		break;

	case 0xb9bc:
		switch (rev) {
		case 0:
			omap_revision = DRA722_REV_ES1_0;
			break;
		case 1:
			omap_revision = DRA722_REV_ES2_0;
			break;
		case 2:
		default:
			omap_revision = DRA722_REV_ES2_1;
			break;
		}
		break;

	default:
		/* Unknown default to latest silicon rev as default*/
		pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
			__func__, idcode, hawkeye, rev);
		omap_revision = DRA752_REV_ES2_0;
	}

	sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
		(omap_rev() >> 8) & 0xf);

	pr_info("%s %s\n", soc_name, soc_rev);
}

/*
 * Set up things for map_io and processor detection later on. Gets called
 * pretty much first thing from board init. For multi-omap, this gets
 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
 * detect the exact revision later on in omap2_detect_revision() once map_io
 * is done.
 */
void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
{
	omap_revision = class;
	tap_base = tap;

	/* XXX What is this intended to do? */
	if (soc_is_omap34xx())
		tap_prod_id = 0x0210;
	else
		tap_prod_id = 0x0208;
}

#ifdef CONFIG_SOC_BUS

static const char * const omap_types[] = {
	[OMAP2_DEVICE_TYPE_TEST]	= "TST",
	[OMAP2_DEVICE_TYPE_EMU]		= "EMU",
	[OMAP2_DEVICE_TYPE_SEC]		= "HS",
	[OMAP2_DEVICE_TYPE_GP]		= "GP",
	[OMAP2_DEVICE_TYPE_BAD]		= "BAD",
};

static const char * __init omap_get_family(void)
{
	if (soc_is_omap24xx())
		return kasprintf(GFP_KERNEL, "OMAP2");
	else if (soc_is_omap34xx())
		return kasprintf(GFP_KERNEL, "OMAP3");
	else if (soc_is_omap44xx())
		return kasprintf(GFP_KERNEL, "OMAP4");
	else if (soc_is_omap54xx())
		return kasprintf(GFP_KERNEL, "OMAP5");
	else if (soc_is_am33xx() || soc_is_am335x())
		return kasprintf(GFP_KERNEL, "AM33xx");
	else if (soc_is_am43xx())
		return kasprintf(GFP_KERNEL, "AM43xx");
	else if (soc_is_dra7xx())
		return kasprintf(GFP_KERNEL, "DRA7");
	else
		return kasprintf(GFP_KERNEL, "Unknown");
}

static ssize_t
type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", omap_types[omap_type()]);
}

static DEVICE_ATTR_RO(type);

static struct attribute *omap_soc_attrs[] = {
	&dev_attr_type.attr,
	NULL
};

ATTRIBUTE_GROUPS(omap_soc);

void __init omap_soc_device_init(void)
{
	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;

	soc_dev_attr->machine  = soc_name;
	soc_dev_attr->family   = omap_get_family();
	if (!soc_dev_attr->family) {
		kfree(soc_dev_attr);
		return;
	}
	soc_dev_attr->revision = soc_rev;
	soc_dev_attr->custom_attr_group = omap_soc_groups[0];

	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree(soc_dev_attr->family);
		kfree(soc_dev_attr);
		return;
	}
}
#endif /* CONFIG_SOC_BUS */
