aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/mrst.h4
-rw-r--r--arch/x86/platform/mrst/mrst.c515
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c5
-rw-r--r--include/linux/sfi.h8
5 files changed, 527 insertions, 7 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e8327686d3c5..b306b84fc8c8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -385,6 +385,8 @@ config X86_MRST
385 depends on X86_EXTENDED_PLATFORM 385 depends on X86_EXTENDED_PLATFORM
386 depends on X86_IO_APIC 386 depends on X86_IO_APIC
387 select APB_TIMER 387 select APB_TIMER
388 select I2C
389 select SPI
388 ---help--- 390 ---help---
389 Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin 391 Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
390 Internet Device(MID) platform. Moorestown consists of two chips: 392 Internet Device(MID) platform. Moorestown consists of two chips:
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index 4a711a684b17..283debd29fc0 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -50,4 +50,8 @@ extern void mrst_early_console_init(void);
50 50
51extern struct console early_hsu_console; 51extern struct console early_hsu_console;
52extern void hsu_early_console_init(void); 52extern void hsu_early_console_init(void);
53
54extern void intel_scu_devices_create(void);
55extern void intel_scu_devices_destroy(void);
56
53#endif /* _ASM_X86_MRST_H */ 57#endif /* _ASM_X86_MRST_H */
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index 79ae68154e87..cfa1af24edd5 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -9,9 +9,19 @@
9 * as published by the Free Software Foundation; version 2 9 * as published by the Free Software Foundation; version 2
10 * of the License. 10 * of the License.
11 */ 11 */
12
13#define pr_fmt(fmt) "mrst: " fmt
14
12#include <linux/init.h> 15#include <linux/init.h>
13#include <linux/kernel.h> 16#include <linux/kernel.h>
14#include <linux/sfi.h> 17#include <linux/sfi.h>
18#include <linux/intel_pmic_gpio.h>
19#include <linux/spi/spi.h>
20#include <linux/i2c.h>
21#include <linux/i2c/pca953x.h>
22#include <linux/gpio_keys.h>
23#include <linux/input.h>
24#include <linux/platform_device.h>
15#include <linux/irq.h> 25#include <linux/irq.h>
16#include <linux/module.h> 26#include <linux/module.h>
17 27
@@ -23,8 +33,10 @@
23#include <asm/mrst.h> 33#include <asm/mrst.h>
24#include <asm/io.h> 34#include <asm/io.h>
25#include <asm/i8259.h> 35#include <asm/i8259.h>
36#include <asm/intel_scu_ipc.h>
26#include <asm/apb_timer.h> 37#include <asm/apb_timer.h>
27 38
39
28/* 40/*
29 * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock, 41 * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock,
30 * cmdline option x86_mrst_timer can be used to override the configuration 42 * cmdline option x86_mrst_timer can be used to override the configuration
@@ -102,10 +114,10 @@ static int __init sfi_parse_mtmr(struct sfi_table_header *table)
102 memcpy(sfi_mtimer_array, pentry, totallen); 114 memcpy(sfi_mtimer_array, pentry, totallen);
103 } 115 }
104 116
105 printk(KERN_INFO "SFI: MTIMER info (num = %d):\n", sfi_mtimer_num); 117 pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num);
106 pentry = sfi_mtimer_array; 118 pentry = sfi_mtimer_array;
107 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) { 119 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
108 printk(KERN_INFO "timer[%d]: paddr = 0x%08x, freq = %dHz," 120 pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz,"
109 " irq = %d\n", totallen, (u32)pentry->phys_addr, 121 " irq = %d\n", totallen, (u32)pentry->phys_addr,
110 pentry->freq_hz, pentry->irq); 122 pentry->freq_hz, pentry->irq);
111 if (!pentry->irq) 123 if (!pentry->irq)
@@ -176,10 +188,10 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
176 memcpy(sfi_mrtc_array, pentry, totallen); 188 memcpy(sfi_mrtc_array, pentry, totallen);
177 } 189 }
178 190
179 printk(KERN_INFO "SFI: RTC info (num = %d):\n", sfi_mrtc_num); 191 pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num);
180 pentry = sfi_mrtc_array; 192 pentry = sfi_mrtc_array;
181 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) { 193 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
182 printk(KERN_INFO "RTC[%d]: paddr = 0x%08x, irq = %d\n", 194 pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n",
183 totallen, (u32)pentry->phys_addr, pentry->irq); 195 totallen, (u32)pentry->phys_addr, pentry->irq);
184 mp_irq.type = MP_IOAPIC; 196 mp_irq.type = MP_IOAPIC;
185 mp_irq.irqtype = mp_INT; 197 mp_irq.irqtype = mp_INT;
@@ -309,3 +321,498 @@ static inline int __init setup_x86_mrst_timer(char *arg)
309 return 0; 321 return 0;
310} 322}
311__setup("x86_mrst_timer=", setup_x86_mrst_timer); 323__setup("x86_mrst_timer=", setup_x86_mrst_timer);
324
325/*
326 * Parsing GPIO table first, since the DEVS table will need this table
327 * to map the pin name to the actual pin.
328 */
329static struct sfi_gpio_table_entry *gpio_table;
330static int gpio_num_entry;
331
332static int __init sfi_parse_gpio(struct sfi_table_header *table)
333{
334 struct sfi_table_simple *sb;
335 struct sfi_gpio_table_entry *pentry;
336 int num, i;
337
338 if (gpio_table)
339 return 0;
340 sb = (struct sfi_table_simple *)table;
341 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
342 pentry = (struct sfi_gpio_table_entry *)sb->pentry;
343
344 gpio_table = (struct sfi_gpio_table_entry *)
345 kmalloc(num * sizeof(*pentry), GFP_KERNEL);
346 if (!gpio_table)
347 return -1;
348 memcpy(gpio_table, pentry, num * sizeof(*pentry));
349 gpio_num_entry = num;
350
351 pr_debug("GPIO pin info:\n");
352 for (i = 0; i < num; i++, pentry++)
353 pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s,"
354 " pin = %d\n", i,
355 pentry->controller_name,
356 pentry->pin_name,
357 pentry->pin_no);
358 return 0;
359}
360
361static int get_gpio_by_name(const char *name)
362{
363 struct sfi_gpio_table_entry *pentry = gpio_table;
364 int i;
365
366 if (!pentry)
367 return -1;
368 for (i = 0; i < gpio_num_entry; i++, pentry++) {
369 if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN))
370 return pentry->pin_no;
371 }
372 return -1;
373}
374
375/*
376 * Here defines the array of devices platform data that IAFW would export
377 * through SFI "DEVS" table, we use name and type to match the device and
378 * its platform data.
379 */
380struct devs_id {
381 char name[SFI_NAME_LEN + 1];
382 u8 type;
383 u8 delay;
384 void *(*get_platform_data)(void *info);
385};
386
387/* the offset for the mapping of global gpio pin to irq */
388#define MRST_IRQ_OFFSET 0x100
389
390static void __init *pmic_gpio_platform_data(void *info)
391{
392 static struct intel_pmic_gpio_platform_data pmic_gpio_pdata;
393 int gpio_base = get_gpio_by_name("pmic_gpio_base");
394
395 if (gpio_base == -1)
396 gpio_base = 64;
397 pmic_gpio_pdata.gpio_base = gpio_base;
398 pmic_gpio_pdata.irq_base = gpio_base + MRST_IRQ_OFFSET;
399 pmic_gpio_pdata.gpiointr = 0xffffeff8;
400
401 return &pmic_gpio_pdata;
402}
403
404static void __init *max3111_platform_data(void *info)
405{
406 struct spi_board_info *spi_info = info;
407 int intr = get_gpio_by_name("max3111_int");
408
409 if (intr == -1)
410 return NULL;
411 spi_info->irq = intr + MRST_IRQ_OFFSET;
412 return NULL;
413}