diff options
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r-- | arch/arm/mach-ep93xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 110 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/platform.h | 3 |
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" | |||
5 | config EP93XX_SOC_COMMON | 5 | config 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 | ||
10 | config CRUNCH | 11 | config 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 | ||
138 | static struct irqaction ep93xx_timer_irq = { | 140 | static 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 | } |
926 | EXPORT_SYMBOL(ep93xx_ide_release_gpio); | 928 | EXPORT_SYMBOL(ep93xx_ide_release_gpio); |
927 | 929 | ||
928 | void __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 | |||
955 | static char ep93xx_soc_id[33]; | ||
956 | |||
957 | static 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 | |||
979 | static 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 | |||
999 | static const char __init *ep93xx_get_machine_name(void) | ||
1000 | { | ||
1001 | return kasprintf(GFP_KERNEL,"%s", machine_desc->name); | ||
1002 | } | ||
1003 | |||
1004 | static 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 | |||
1028 | struct 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 | ||
954 | void ep93xx_restart(enum reboot_mode mode, const char *cmd) | 1060 | void 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 | ||
9 | struct device; | ||
9 | struct i2c_gpio_platform_data; | 10 | struct i2c_gpio_platform_data; |
10 | struct i2c_board_info; | 11 | struct i2c_board_info; |
11 | struct spi_board_info; | 12 | struct spi_board_info; |
@@ -54,7 +55,7 @@ void ep93xx_register_ide(void); | |||
54 | int ep93xx_ide_acquire_gpio(struct platform_device *pdev); | 55 | int ep93xx_ide_acquire_gpio(struct platform_device *pdev); |
55 | void ep93xx_ide_release_gpio(struct platform_device *pdev); | 56 | void ep93xx_ide_release_gpio(struct platform_device *pdev); |
56 | 57 | ||
57 | void ep93xx_init_devices(void); | 58 | struct device *ep93xx_init_devices(void); |
58 | extern void ep93xx_timer_init(void); | 59 | extern void ep93xx_timer_init(void); |
59 | 60 | ||
60 | void ep93xx_restart(enum reboot_mode, const char *); | 61 | void ep93xx_restart(enum reboot_mode, const char *); |