aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorPhilip Prindeville <philipp@redfish-solutions.com>2012-03-05 18:05:14 -0500
committerIngo Molnar <mingo@elte.hu>2012-03-06 03:23:56 -0500
commit373913b568cbfbefcee3263b98bd5a1a8b491f1b (patch)
tree96f2d7925a7c66d145d9db0f452d318d07a93eac /arch/x86/platform
parent8bee7cea6c93b5514b672d1c347dad9960823f12 (diff)
x86/geode/alix2: Supplement driver to include GPIO button support
GPIO 24 is used in reference designs as a soft-reset button, and the alix2 is no exception. Add it as a gpio-button. Use symbolic values to describe BIOS addresses. Record the model number. Signed-off-by: Philip A. Prindeville <philipp@redfish-solutions.com> Acked-by: Ed Wildgoose <kernel@wildgooses.com> Acked-by: Andres Salomon <dilinger@queued.net> Cc: Matthew Garrett <mjg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/n/tip-sjp6k1rjksitx1pej0c0qxd1@git.kernel.org [ tidied up the code a bit ] Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/geode/alix.c76
1 files changed, 67 insertions, 9 deletions
diff --git a/arch/x86/platform/geode/alix.c b/arch/x86/platform/geode/alix.c
index dc5f1d32ace..90e23e7679a 100644
--- a/arch/x86/platform/geode/alix.c
+++ b/arch/x86/platform/geode/alix.c
@@ -6,6 +6,7 @@
6 * 6 *
7 * Copyright (C) 2008 Constantin Baranov <const@mimas.ru> 7 * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
8 * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com> 8 * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com>
9 * and Philip Prindeville <philipp@redfish-solutions.com>
9 * 10 *
10 * TODO: There are large similarities with leds-net5501.c 11 * TODO: There are large similarities with leds-net5501.c
11 * by Alessandro Zummo <a.zummo@towertech.it> 12 * by Alessandro Zummo <a.zummo@towertech.it>
@@ -24,14 +25,47 @@
24#include <linux/leds.h> 25#include <linux/leds.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/input.h>
29#include <linux/gpio_keys.h>
30#include <linux/dmi.h>
27 31
28#include <asm/geode.h> 32#include <asm/geode.h>
29 33
34#define BIOS_SIGNATURE_TINYBIOS 0xf0000
35#define BIOS_SIGNATURE_COREBOOT 0x500
36#define BIOS_REGION_SIZE 0x10000
37
30static bool force = 0; 38static bool force = 0;
31module_param(force, bool, 0444); 39module_param(force, bool, 0444);
32/* FIXME: Award bios is not automatically detected as Alix platform */ 40/* FIXME: Award bios is not automatically detected as Alix platform */
33MODULE_PARM_DESC(force, "Force detection as ALIX.2/ALIX.3 platform"); 41MODULE_PARM_DESC(force, "Force detection as ALIX.2/ALIX.3 platform");
34 42
43static struct gpio_keys_button alix_gpio_buttons[] = {
44 {
45 .code = KEY_RESTART,
46 .gpio = 24,
47 .active_low = 1,
48 .desc = "Reset button",
49 .type = EV_KEY,
50 .wakeup = 0,
51 .debounce_interval = 100,
52 .can_disable = 0,
53 }
54};
55static struct gpio_keys_platform_data alix_buttons_data = {
56 .buttons = alix_gpio_buttons,
57 .nbuttons = ARRAY_SIZE(alix_gpio_buttons),
58 .poll_interval = 20,
59};
60
61static struct platform_device alix_buttons_dev = {
62 .name = "gpio-keys-polled",
63 .id = 1,
64 .dev = {
65 .platform_data = &alix_buttons_data,
66 }
67};
68
35static struct gpio_led alix_leds[] = { 69static struct gpio_led alix_leds[] = {
36 { 70 {
37 .name = "alix:1", 71 .name = "alix:1",
@@ -64,17 +98,22 @@ static struct platform_device alix_leds_dev = {
64 .dev.platform_data = &alix_leds_data, 98 .dev.platform_data = &alix_leds_data,
65}; 99};
66 100
101static struct __initdata platform_device *alix_devs[] = {
102 &alix_buttons_dev,
103 &alix_leds_dev,
104};
105
67static void __init register_alix(void) 106static void __init register_alix(void)
68{ 107{
69 /* Setup LED control through leds-gpio driver */ 108 /* Setup LED control through leds-gpio driver */
70 platform_device_register(&alix_leds_dev); 109 platform_add_devices(alix_devs, ARRAY_SIZE(alix_devs));
71} 110}
72 111
73static int __init alix_present(unsigned long bios_phys, 112static bool __init alix_present(unsigned long bios_phys,
74 const char *alix_sig, 113 const char *alix_sig,
75 size_t alix_sig_len) 114 size_t alix_sig_len)
76{ 115{
77 const size_t bios_len = 0x00010000; 116 const size_t bios_len = BIOS_REGION_SIZE;
78 const char *bios_virt; 117 const char *bios_virt;
79 const char *scan_end; 118 const char *scan_end;
80 const char *p; 119 const char *p;
@@ -84,7 +123,7 @@ static int __init alix_present(unsigned long bios_phys,
84 printk(KERN_NOTICE "%s: forced to skip BIOS test, " 123 printk(KERN_NOTICE "%s: forced to skip BIOS test, "
85 "assume system is ALIX.2/ALIX.3\n", 124 "assume system is ALIX.2/ALIX.3\n",
86 KBUILD_MODNAME); 125 KBUILD_MODNAME);
87 return 1; 126 return true;
88 } 127 }
89 128
90 bios_virt = phys_to_virt(bios_phys); 129 bios_virt = phys_to_virt(bios_phys);
@@ -109,15 +148,33 @@ static int __init alix_present(unsigned long bios_phys,
109 *a = '\0'; 148 *a = '\0';
110 149
111 tail = p + alix_sig_len; 150 tail = p + alix_sig_len;
112 if ((tail[0] == '2' || tail[0] == '3')) { 151 if ((tail[0] == '2' || tail[0] == '3' || tail[0] == '6')) {
113 printk(KERN_INFO 152 printk(KERN_INFO
114 "%s: system is recognized as \"%s\"\n", 153 "%s: system is recognized as \"%s\"\n",
115 KBUILD_MODNAME, name); 154 KBUILD_MODNAME, name);
116 return 1; 155 return true;
117 } 156 }
118 } 157 }
119 158
120 return 0; 159 return false;
160}
161
162static bool __init alix_present_dmi(void)
163{
164 const char *vendor, *product;
165
166 vendor = dmi_get_system_info(DMI_SYS_VENDOR);
167 if (!vendor || strcmp(vendor, "PC Engines"))
168 return false;
169
170 product = dmi_get_system_info(DMI_PRODUCT_NAME);
171 if (!product || (strcmp(product, "ALIX.2D") && strcmp(product, "ALIX.6")))
172 return false;
173
174 printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
175 KBUILD_MODNAME, vendor, product);
176
177 return true;
121} 178}
122 179
123static int __init alix_init(void) 180static int __init alix_init(void)
@@ -128,8 +185,9 @@ static int __init alix_init(void)
128 if (!is_geode()) 185 if (!is_geode())
129 return 0; 186 return 0;
130 187
131 if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) || 188 if (alix_present(BIOS_SIGNATURE_TINYBIOS, tinybios_sig, sizeof(tinybios_sig) - 1) ||
132 alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1)) 189 alix_present(BIOS_SIGNATURE_COREBOOT, coreboot_sig, sizeof(coreboot_sig) - 1) ||
190 alix_present_dmi())
133 register_alix(); 191 register_alix();
134 192
135 return 0; 193 return 0;