aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/Kconfig1
-rw-r--r--arch/arm/mach-ep93xx/core.c110
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h3
3 files changed, 111 insertions, 3 deletions
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 93e54fd4e3d5..bec570ae6494 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -5,6 +5,7 @@ menu "Cirrus EP93xx Implementation Options"
5config EP93XX_SOC_COMMON 5config EP93XX_SOC_COMMON
6 bool 6 bool
7 default y 7 default y
8 select SOC_BUS
8 select LEDS_GPIO_REGISTER 9 select LEDS_GPIO_REGISTER
9 10
10config CRUNCH 11config CRUNCH
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 94b141fcf944..6c705472da6c 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
24#include <linux/sys_soc.h>
24#include <linux/timex.h> 25#include <linux/timex.h>
25#include <linux/irq.h> 26#include <linux/irq.h>
26#include <linux/io.h> 27#include <linux/io.h>
@@ -44,6 +45,7 @@
44#include <linux/platform_data/spi-ep93xx.h> 45#include <linux/platform_data/spi-ep93xx.h>
45#include <mach/gpio-ep93xx.h> 46#include <mach/gpio-ep93xx.h>
46 47
48#include <asm/mach/arch.h>
47#include <asm/mach/map.h> 49#include <asm/mach/map.h>
48#include <asm/mach/time.h> 50#include <asm/mach/time.h>
49 51
@@ -137,7 +139,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
137 139
138static struct irqaction ep93xx_timer_irq = { 140static struct irqaction ep93xx_timer_irq = {
139 .name = "ep93xx timer", 141 .name = "ep93xx timer",
140 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 142 .flags = IRQF_TIMER | IRQF_IRQPOLL,
141 .handler = ep93xx_timer_interrupt, 143 .handler = ep93xx_timer_interrupt,
142}; 144};
143 145
@@ -925,8 +927,108 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev)
925} 927}
926EXPORT_SYMBOL(ep93xx_ide_release_gpio); 928EXPORT_SYMBOL(ep93xx_ide_release_gpio);
927 929
928void __init ep93xx_init_devices(void) 930/*************************************************************************
931 * EP93xx Security peripheral
932 *************************************************************************/
933
934/*
935 * The Maverick Key is 256 bits of micro fuses blown at the factory during
936 * manufacturing to uniquely identify a part.
937 *
938 * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key
939 */
940#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x))
941#define EP93XX_SECURITY_SECFLG EP93XX_SECURITY_REG(0x2400)
942#define EP93XX_SECURITY_FUSEFLG EP93XX_SECURITY_REG(0x2410)
943#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440)
944#define EP93XX_SECURITY_UNIQCHK EP93XX_SECURITY_REG(0x2450)
945#define EP93XX_SECURITY_UNIQVAL EP93XX_SECURITY_REG(0x2460)
946#define EP93XX_SECURITY_SECID1 EP93XX_SECURITY_REG(0x2500)
947#define EP93XX_SECURITY_SECID2 EP93XX_SECURITY_REG(0x2504)
948#define EP93XX_SECURITY_SECCHK1 EP93XX_SECURITY_REG(0x2520)
949#define EP93XX_SECURITY_SECCHK2 EP93XX_SECURITY_REG(0x2524)
950#define EP93XX_SECURITY_UNIQID2 EP93XX_SECURITY_REG(0x2700)
951#define EP93XX_SECURITY_UNIQID3 EP93XX_SECURITY_REG(0x2704)
952#define EP93XX_SECURITY_UNIQID4 EP93XX_SECURITY_REG(0x2708)
953#define EP93XX_SECURITY_UNIQID5 EP93XX_SECURITY_REG(0x270c)
954
955static char ep93xx_soc_id[33];
956
957static const char __init *ep93xx_get_soc_id(void)
929{ 958{
959 unsigned int id, id2, id3, id4, id5;
960
961 if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1)
962 return "bad Hamming code";
963
964 id = __raw_readl(EP93XX_SECURITY_UNIQID);
965 id2 = __raw_readl(EP93XX_SECURITY_UNIQID2);
966 id3 = __raw_readl(EP93XX_SECURITY_UNIQID3);
967 id4 = __raw_readl(EP93XX_SECURITY_UNIQID4);
968 id5 = __raw_readl(EP93XX_SECURITY_UNIQID5);
969
970 if (id != id2)
971 return "invalid";
972
973 snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
974 "%08x%08x%08x%08x", id2, id3, id4, id5);
975
976 return ep93xx_soc_id;
977}
978
979static const char __init *ep93xx_get_soc_rev(void)
980{
981 int rev = ep93xx_chip_revision();
982
983 switch (rev) {
984 case EP93XX_CHIP_REV_D0:
985 return "D0";
986 case EP93XX_CHIP_REV_D1:
987 return "D1";
988 case EP93XX_CHIP_REV_E0:
989 return "E0";
990 case EP93XX_CHIP_REV_E1:
991 return "E1";
992 case EP93XX_CHIP_REV_E2:
993 return "E2";
994 default:
995 return "unknown";
996 }
997}
998
999static const char __init *ep93xx_get_machine_name(void)
1000{
1001 return kasprintf(GFP_KERNEL,"%s", machine_desc->name);
1002}
1003
1004static struct device __init *ep93xx_init_soc(void)
1005{
1006 struct soc_device_attribute *soc_dev_attr;
1007 struct soc_device *soc_dev;
1008
1009 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
1010 if (!soc_dev_attr)
1011 return NULL;
1012
1013 soc_dev_attr->machine = ep93xx_get_machine_name();
1014 soc_dev_attr->family = "Cirrus Logic EP93xx";
1015 soc_dev_attr->revision = ep93xx_get_soc_rev();
1016 soc_dev_attr->soc_id = ep93xx_get_soc_id();
1017
1018 soc_dev = soc_device_register(soc_dev_attr);
1019 if (IS_ERR(soc_dev)) {
1020 kfree(soc_dev_attr->machine);
1021 kfree(soc_dev_attr);
1022 return NULL;
1023 }
1024
1025 return soc_device_to_device(soc_dev);
1026}
1027
1028struct device __init *ep93xx_init_devices(void)
1029{
1030 struct device *parent;
1031
930 /* Disallow access to MaverickCrunch initially */ 1032 /* Disallow access to MaverickCrunch initially */
931 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); 1033 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
932 1034
@@ -937,6 +1039,8 @@ void __init ep93xx_init_devices(void)
937 EP93XX_SYSCON_DEVCFG_GONIDE | 1039 EP93XX_SYSCON_DEVCFG_GONIDE |
938 EP93XX_SYSCON_DEVCFG_HONIDE); 1040 EP93XX_SYSCON_DEVCFG_HONIDE);
939 1041
1042 parent = ep93xx_init_soc();
1043
940 /* Get the GPIO working early, other devices need it */ 1044 /* Get the GPIO working early, other devices need it */
941 platform_device_register(&ep93xx_gpio_device); 1045 platform_device_register(&ep93xx_gpio_device);
942 1046
@@ -949,6 +1053,8 @@ void __init ep93xx_init_devices(void)
949 platform_device_register(&ep93xx_wdt_device); 1053 platform_device_register(&ep93xx_wdt_device);
950 1054
951 gpio_led_register_device(-1, &ep93xx_led_data); 1055 gpio_led_register_device(-1, &ep93xx_led_data);
1056
1057 return parent;
952} 1058}
953 1059
954void ep93xx_restart(enum reboot_mode mode, const char *cmd) 1060void ep93xx_restart(enum reboot_mode mode, const char *cmd)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index e256e0baec2e..4c0bbd97f741 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/reboot.h> 7#include <linux/reboot.h>
8 8
9struct device;
9struct i2c_gpio_platform_data; 10struct i2c_gpio_platform_data;
10struct i2c_board_info; 11struct i2c_board_info;
11struct spi_board_info; 12struct spi_board_info;
@@ -54,7 +55,7 @@ void ep93xx_register_ide(void);
54int ep93xx_ide_acquire_gpio(struct platform_device *pdev); 55int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
55void ep93xx_ide_release_gpio(struct platform_device *pdev); 56void ep93xx_ide_release_gpio(struct platform_device *pdev);
56 57
57void ep93xx_init_devices(void); 58struct device *ep93xx_init_devices(void);
58extern void ep93xx_timer_init(void); 59extern void ep93xx_timer_init(void);
59 60
60void ep93xx_restart(enum reboot_mode, const char *); 61void ep93xx_restart(enum reboot_mode, const char *);