Commit dba538ff authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-intel-mid-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86/intel-mid changes from Ingo Molnar:
 "Update the 'intel mid' (mobile internet device) platform code as Intel
  is rolling out more SoC designs.

  This gets rid of most of the 'MRST' platform code in the process,
  mostly by renaming and shuffling code around into their respective
  'intel-mid' platform drivers"

* 'x86-intel-mid-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, intel-mid: Do not re-introduce usage of obsolete __cpuinit
  intel_mid: Move platform device setups to their own platform_<device>.* files
  x86: intel-mid: Add section for sfi device table
  intel-mid: sfi: Allow struct devs_id.get_platform_data to be NULL
  intel_mid: Moved SFI related code to sfi.c
  intel_mid: Added custom handler for ipc devices
  intel_mid: Added custom device_handler support
  intel_mid: Refactored sfi_parse_devs() function
  intel_mid: Renamed *mrst* to *intel_mid*
  pci: intel_mid: Return true/false in function returning bool
  intel_mid: Renamed *mrst* to *intel_mid*
  mrst: Fixed indentation issues
  mrst: Fixed printk/pr_* related issues
parents 2dc1733f aeeca404
...@@ -3492,11 +3492,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -3492,11 +3492,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
default x2apic cluster mode on platforms default x2apic cluster mode on platforms
supporting x2apic. supporting x2apic.
x86_mrst_timer= [X86-32,APBT] x86_intel_mid_timer= [X86-32,APBT]
Choose timer option for x86 Moorestown MID platform. Choose timer option for x86 Intel MID platform.
Two valid options are apbt timer only and lapic timer Two valid options are apbt timer only and lapic timer
plus one apbt timer for broadcast timer. plus one apbt timer for broadcast timer.
x86_mrst_timer=apbt_only | lapic_and_apbt x86_intel_mid_timer=apbt_only | lapic_and_apbt
xen_emul_unplug= [HW,X86,XEN] xen_emul_unplug= [HW,X86,XEN]
Unplug Xen emulated devices Unplug Xen emulated devices
......
/* /*
* mrst.h: Intel Moorestown platform specific setup code * intel-mid.h: Intel MID specific setup code
* *
* (C) Copyright 2009 Intel Corporation * (C) Copyright 2009 Intel Corporation
* *
...@@ -8,16 +8,39 @@ ...@@ -8,16 +8,39 @@
* as published by the Free Software Foundation; version 2 * as published by the Free Software Foundation; version 2
* of the License. * of the License.
*/ */
#ifndef _ASM_X86_MRST_H #ifndef _ASM_X86_INTEL_MID_H
#define _ASM_X86_MRST_H #define _ASM_X86_INTEL_MID_H
#include <linux/sfi.h> #include <linux/sfi.h>
#include <linux/platform_device.h>
extern int pci_mrst_init(void); extern int intel_mid_pci_init(void);
extern int get_gpio_by_name(const char *name);
extern void intel_scu_device_register(struct platform_device *pdev);
extern int __init sfi_parse_mrtc(struct sfi_table_header *table); extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
extern int __init sfi_parse_mtmr(struct sfi_table_header *table);
extern int sfi_mrtc_num; extern int sfi_mrtc_num;
extern struct sfi_rtc_table_entry sfi_mrtc_array[]; extern struct sfi_rtc_table_entry sfi_mrtc_array[];
/*
* Here defines the array of devices platform data that IAFW would export
* through SFI "DEVS" table, we use name and type to match the device and
* its platform data.
*/
struct devs_id {
char name[SFI_NAME_LEN + 1];
u8 type;
u8 delay;
void *(*get_platform_data)(void *info);
/* Custom handler for devices */
void (*device_handler)(struct sfi_device_table_entry *pentry,
struct devs_id *dev);
};
#define sfi_device(i) \
static const struct devs_id *const __intel_mid_sfi_##i##_dev __used \
__attribute__((__section__(".x86_intel_mid_dev.init"))) = &i
/* /*
* Medfield is the follow-up of Moorestown, it combines two chip solution into * Medfield is the follow-up of Moorestown, it combines two chip solution into
* one. Other than that it also added always-on and constant tsc and lapic * one. Other than that it also added always-on and constant tsc and lapic
...@@ -25,33 +48,39 @@ extern struct sfi_rtc_table_entry sfi_mrtc_array[]; ...@@ -25,33 +48,39 @@ extern struct sfi_rtc_table_entry sfi_mrtc_array[];
* we treat Medfield/Penwell as a variant of Moorestown. Penwell can be * we treat Medfield/Penwell as a variant of Moorestown. Penwell can be
* identified via MSRs. * identified via MSRs.
*/ */
enum mrst_cpu_type { enum intel_mid_cpu_type {
/* 1 was Moorestown */ /* 1 was Moorestown */
MRST_CPU_CHIP_PENWELL = 2, INTEL_MID_CPU_CHIP_PENWELL = 2,
}; };
extern enum mrst_cpu_type __mrst_cpu_chip; extern enum intel_mid_cpu_type __intel_mid_cpu_chip;
#ifdef CONFIG_X86_INTEL_MID #ifdef CONFIG_X86_INTEL_MID
static inline enum mrst_cpu_type mrst_identify_cpu(void) static inline enum intel_mid_cpu_type intel_mid_identify_cpu(void)
{ {
return __mrst_cpu_chip; return __intel_mid_cpu_chip;
}
static inline bool intel_mid_has_msic(void)
{
return (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL);
} }
#else /* !CONFIG_X86_INTEL_MID */ #else /* !CONFIG_X86_INTEL_MID */
#define mrst_identify_cpu() (0) #define intel_mid_identify_cpu() (0)
#define intel_mid_has_msic() (0)
#endif /* !CONFIG_X86_INTEL_MID */ #endif /* !CONFIG_X86_INTEL_MID */
enum mrst_timer_options { enum intel_mid_timer_options {
MRST_TIMER_DEFAULT, INTEL_MID_TIMER_DEFAULT,
MRST_TIMER_APBT_ONLY, INTEL_MID_TIMER_APBT_ONLY,
MRST_TIMER_LAPIC_APBT, INTEL_MID_TIMER_LAPIC_APBT,
}; };
extern enum mrst_timer_options mrst_timer_options; extern enum intel_mid_timer_options intel_mid_timer_options;
/* /*
* Penwell uses spread spectrum clock, so the freq number is not exactly * Penwell uses spread spectrum clock, so the freq number is not exactly
...@@ -76,6 +105,9 @@ extern void intel_scu_devices_destroy(void); ...@@ -76,6 +105,9 @@ extern void intel_scu_devices_destroy(void);
#define MRST_VRTC_MAP_SZ (1024) #define MRST_VRTC_MAP_SZ (1024)
/*#define MRST_VRTC_PGOFFSET (0xc00) */ /*#define MRST_VRTC_PGOFFSET (0xc00) */
extern void mrst_rtc_init(void); extern void intel_mid_rtc_init(void);
/* the offset for the mapping of global gpio pin to irq */
#define INTEL_MID_IRQ_OFFSET 0x100
#endif /* _ASM_X86_MRST_H */ #endif /* _ASM_X86_INTEL_MID_H */
#ifndef _MRST_VRTC_H #ifndef _INTEL_MID_VRTC_H
#define _MRST_VRTC_H #define _INTEL_MID_VRTC_H
extern unsigned char vrtc_cmos_read(unsigned char reg); extern unsigned char vrtc_cmos_read(unsigned char reg);
extern void vrtc_cmos_write(unsigned char val, unsigned char reg); extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
......
...@@ -51,9 +51,9 @@ extern void i386_reserve_resources(void); ...@@ -51,9 +51,9 @@ extern void i386_reserve_resources(void);
extern void setup_default_timer_irq(void); extern void setup_default_timer_irq(void);
#ifdef CONFIG_X86_INTEL_MID #ifdef CONFIG_X86_INTEL_MID
extern void x86_mrst_early_setup(void); extern void x86_intel_mid_early_setup(void);
#else #else
static inline void x86_mrst_early_setup(void) { } static inline void x86_intel_mid_early_setup(void) { }
#endif #endif
#ifdef CONFIG_X86_INTEL_CE #ifdef CONFIG_X86_INTEL_CE
......
...@@ -158,7 +158,7 @@ enum { ...@@ -158,7 +158,7 @@ enum {
X86_SUBARCH_PC = 0, X86_SUBARCH_PC = 0,
X86_SUBARCH_LGUEST, X86_SUBARCH_LGUEST,
X86_SUBARCH_XEN, X86_SUBARCH_XEN,
X86_SUBARCH_MRST, X86_SUBARCH_INTEL_MID,
X86_SUBARCH_CE4100, X86_SUBARCH_CE4100,
X86_NR_SUBARCHS, X86_NR_SUBARCHS,
}; };
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/apb_timer.h> #include <asm/apb_timer.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/time.h> #include <asm/time.h>
#define APBT_CLOCKEVENT_RATING 110 #define APBT_CLOCKEVENT_RATING 110
...@@ -157,13 +157,13 @@ static int __init apbt_clockevent_register(void) ...@@ -157,13 +157,13 @@ static int __init apbt_clockevent_register(void)
adev->num = smp_processor_id(); adev->num = smp_processor_id();
adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0", adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0",
mrst_timer_options == MRST_TIMER_LAPIC_APBT ? intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ?
APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING, APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING,
adev_virt_addr(adev), 0, apbt_freq); adev_virt_addr(adev), 0, apbt_freq);
/* Firmware does EOI handling for us. */ /* Firmware does EOI handling for us. */
adev->timer->eoi = NULL; adev->timer->eoi = NULL;
if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) {
global_clock_event = &adev->timer->ced; global_clock_event = &adev->timer->ced;
printk(KERN_DEBUG "%s clockevent registered as global\n", printk(KERN_DEBUG "%s clockevent registered as global\n",
global_clock_event->name); global_clock_event->name);
...@@ -253,7 +253,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n, ...@@ -253,7 +253,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
static __init int apbt_late_init(void) static __init int apbt_late_init(void)
{ {
if (mrst_timer_options == MRST_TIMER_LAPIC_APBT || if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ||
!apb_timer_block_enabled) !apb_timer_block_enabled)
return 0; return 0;
/* This notifier should be called after workqueue is ready */ /* This notifier should be called after workqueue is ready */
...@@ -340,7 +340,7 @@ void __init apbt_time_init(void) ...@@ -340,7 +340,7 @@ void __init apbt_time_init(void)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* kernel cmdline disable apb timer, so we will use lapic timers */ /* kernel cmdline disable apb timer, so we will use lapic timers */
if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) {
printk(KERN_INFO "apbt: disabled per cpu timer\n"); printk(KERN_INFO "apbt: disabled per cpu timer\n");
return; return;
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <xen/hvc-console.h> #include <xen/hvc-console.h>
#include <asm/pci-direct.h> #include <asm/pci-direct.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <linux/usb/ehci_def.h> #include <linux/usb/ehci_def.h>
#include <linux/efi.h> #include <linux/efi.h>
......
...@@ -35,8 +35,8 @@ asmlinkage void __init i386_start_kernel(void) ...@@ -35,8 +35,8 @@ asmlinkage void __init i386_start_kernel(void)
/* Call the subarch specific early setup function */ /* Call the subarch specific early setup function */
switch (boot_params.hdr.hardware_subarch) { switch (boot_params.hdr.hardware_subarch) {
case X86_SUBARCH_MRST: case X86_SUBARCH_INTEL_MID:
x86_mrst_early_setup(); x86_intel_mid_early_setup();
break; break;
case X86_SUBARCH_CE4100: case X86_SUBARCH_CE4100:
x86_ce4100_early_setup(); x86_ce4100_early_setup();
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <asm/vsyscall.h> #include <asm/vsyscall.h>
#include <asm/x86_init.h> #include <asm/x86_init.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/rtc.h> #include <asm/rtc.h>
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
...@@ -189,7 +189,7 @@ static __init int add_rtc_cmos(void) ...@@ -189,7 +189,7 @@ static __init int add_rtc_cmos(void)
return 0; return 0;
/* Intel MID platforms don't have ioport rtc */ /* Intel MID platforms don't have ioport rtc */
if (mrst_identify_cpu()) if (intel_mid_identify_cpu())
return -ENODEV; return -ENODEV;
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
......
...@@ -199,6 +199,15 @@ SECTIONS ...@@ -199,6 +199,15 @@ SECTIONS
__x86_cpu_dev_end = .; __x86_cpu_dev_end = .;
} }
#ifdef CONFIG_X86_INTEL_MID
.x86_intel_mid_dev.init : AT(ADDR(.x86_intel_mid_dev.init) - \
LOAD_OFFSET) {
__x86_intel_mid_dev_start = .;
*(.x86_intel_mid_dev.init)
__x86_intel_mid_dev_end = .;
}
#endif
/* /*
* start address and size of operations which during runtime * start address and size of operations which during runtime
* can be patched with virtualization friendly instructions or * can be patched with virtualization friendly instructions or
......
...@@ -18,7 +18,7 @@ obj-$(CONFIG_X86_VISWS) += visws.o ...@@ -18,7 +18,7 @@ obj-$(CONFIG_X86_VISWS) += visws.o
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
obj-$(CONFIG_X86_NUMACHIP) += numachip.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o
obj-$(CONFIG_X86_INTEL_MID) += mrst.o obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o
obj-y += common.o early.o obj-y += common.o early.o
obj-y += bus_numa.o obj-y += bus_numa.o
......
/* /*
* Moorestown PCI support * Intel MID PCI support
* Copyright (c) 2008 Intel Corporation * Copyright (c) 2008 Intel Corporation
* Jesse Barnes <jesse.barnes@intel.com> * Jesse Barnes <jesse.barnes@intel.com>
* *
...@@ -150,12 +150,12 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) ...@@ -150,12 +150,12 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
* shim. Therefore, use the header type in shim instead. * shim. Therefore, use the header type in shim instead.
*/ */
if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
return 0; return false;
if (bus == 0 && (devfn == PCI_DEVFN(2, 0) if (bus == 0 && (devfn == PCI_DEVFN(2, 0)
|| devfn == PCI_DEVFN(0, 0) || devfn == PCI_DEVFN(0, 0)
|| devfn == PCI_DEVFN(3, 0))) || devfn == PCI_DEVFN(3, 0)))
return 1; return true;
return 0; /* Langwell on others */ return false; /* Langwell on others */
} }
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
...@@ -205,7 +205,7 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -205,7 +205,7 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
where, size, value); where, size, value);
} }
static int mrst_pci_irq_enable(struct pci_dev *dev) static int intel_mid_pci_irq_enable(struct pci_dev *dev)
{ {
u8 pin; u8 pin;
struct io_apic_irq_attr irq_attr; struct io_apic_irq_attr irq_attr;
...@@ -225,23 +225,23 @@ static int mrst_pci_irq_enable(struct pci_dev *dev) ...@@ -225,23 +225,23 @@ static int mrst_pci_irq_enable(struct pci_dev *dev)
return 0; return 0;
} }
struct pci_ops pci_mrst_ops = { struct pci_ops intel_mid_pci_ops = {
.read = pci_read, .read = pci_read,
.write = pci_write, .write = pci_write,
}; };
/** /**
* pci_mrst_init - installs pci_mrst_ops * intel_mid_pci_init - installs intel_mid_pci_ops
* *
* Moorestown has an interesting PCI implementation (see above). * Moorestown has an interesting PCI implementation (see above).
* Called when the early platform detection installs it. * Called when the early platform detection installs it.
*/ */
int __init pci_mrst_init(void) int __init intel_mid_pci_init(void)
{ {
pr_info("Intel MID platform detected, using MID PCI ops\n"); pr_info("Intel MID platform detected, using MID PCI ops\n");
pci_mmcfg_late_init(); pci_mmcfg_late_init();
pcibios_enable_irq = mrst_pci_irq_enable; pcibios_enable_irq = intel_mid_pci_irq_enable;
pci_root_ops = pci_mrst_ops; pci_root_ops = intel_mid_pci_ops;
pci_soc_mode = 1; pci_soc_mode = 1;
/* Continue with standard init */ /* Continue with standard init */
return 1; return 1;
......
...@@ -4,7 +4,7 @@ obj-y += efi/ ...@@ -4,7 +4,7 @@ obj-y += efi/
obj-y += geode/ obj-y += geode/
obj-y += goldfish/ obj-y += goldfish/
obj-y += iris/ obj-y += iris/
obj-y += mrst/ obj-y += intel-mid/
obj-y += olpc/ obj-y += olpc/
obj-y += scx200/ obj-y += scx200/
obj-y += sfi/ obj-y += sfi/
......
obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o
obj-$(CONFIG_X86_INTEL_MID) += intel_mid_vrtc.o
obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o
# SFI specific code
ifdef CONFIG_X86_INTEL_MID
obj-$(CONFIG_SFI) += sfi.o device_libs/
endif
# IPC Devices
obj-y += platform_ipc.o
obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic.o
obj-$(subst m,y,$(CONFIG_SND_MFLD_MACHINE)) += platform_msic_audio.o
obj-$(subst m,y,$(CONFIG_GPIO_MSIC)) += platform_msic_gpio.o
obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic_ocd.o
obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic_battery.o
obj-$(subst m,y,$(CONFIG_INTEL_MID_POWER_BUTTON)) += platform_msic_power_btn.o
obj-$(subst m,y,$(CONFIG_GPIO_INTEL_PMIC)) += platform_pmic_gpio.o
obj-$(subst m,y,$(CONFIG_INTEL_MFLD_THERMAL)) += platform_msic_thermal.o
# I2C Devices
obj-$(subst m,y,$(CONFIG_SENSORS_EMC1403)) += platform_emc1403.o
obj-$(subst m,y,$(CONFIG_SENSORS_LIS3LV02D)) += platform_lis331.o
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_max7315.o
obj-$(subst m,y,$(CONFIG_INPUT_MPU3050)) += platform_mpu3050.o
obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o
obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o
# SPI Devices
obj-$(subst m,y,$(CONFIG_SERIAL_MRST_MAX3110)) += platform_max3111.o
# MISC Devices
obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o
/*
* platform_bma023.c: bma023 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <asm/intel-mid.h>
static const struct devs_id bma023_dev_id __initconst = {
.name = "bma023",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
};
sfi_device(bma023_dev_id);
/*
* platform_emc1403.c: emc1403 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <asm/intel-mid.h>
static void __init *emc1403_platform_data(void *info)
{
static short intr2nd_pdata;
struct i2c_board_info *i2c_info = info;
int intr = get_gpio_by_name("thermal_int");
int intr2nd = get_gpio_by_name("thermal_alert");
if (intr == -1 || intr2nd == -1)
return NULL;
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET;
return &intr2nd_pdata;
}
static const struct devs_id emc1403_dev_id __initconst = {
.name = "emc1403",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
.get_platform_data = &emc1403_platform_data,
};
sfi_device(emc1403_dev_id);
/*
* platform_gpio_keys.c: gpio_keys platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/input.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/platform_device.h>
#include <asm/intel-mid.h>
#define DEVICE_NAME "gpio-keys"
/*
* we will search these buttons in SFI GPIO table (by name)
* and register them dynamically. Please add all possible
* buttons here, we will shrink them if no GPIO found.
*/
static struct gpio_keys_button gpio_button[] = {
{KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000},
{KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20},
{KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20},
{SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20},
{KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20},
{KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20},
{KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20},
{KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20},
{SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20},
{SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20},
};
static struct gpio_keys_platform_data gpio_keys = {
.buttons = gpio_button,
.rep = 1,
.nbuttons = -1, /* will fill it after search */
};
static struct platform_device pb_device = {
.name = DEVICE_NAME,
.id = -1,
.dev = {
.platform_data = &gpio_keys,
},
};
/*
* Shrink the non-existent buttons, register the gpio button
* device if there is some
*/
static int __init pb_keys_init(void)
{
struct gpio_keys_button *gb = gpio_button;
int i, num, good = 0;
num = sizeof(gpio_button) / sizeof(struct gpio_keys_button);
for (i = 0; i < num; i++) {
gb[i].gpio = get_gpio_by_name(gb[i].desc);
pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc,
gb[i].gpio);
if (gb[i].gpio == -1)
continue;
if (i != good)
gb[good] = gb[i];
good++;
}
if (good) {
gpio_keys.nbuttons = good;
return platform_device_register(&pb_device);
}
return 0;
}
late_initcall(pb_keys_init);
/*
* platform_ipc.c: IPC platform library file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/sfi.h>
#include <linux/gpio.h>
#include <asm/intel-mid.h>
#include "platform_ipc.h"
void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
struct devs_id *dev)
{
struct platform_device *pdev;
void *pdata = NULL;
static struct resource res __initdata = {
.name = "IRQ",
.flags = IORESOURCE_IRQ,
};
pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n",
pentry->name, pentry->irq);
/*
* We need to call platform init of IPC devices to fill misc_pdata
* structure. It will be used in msic_init for initialization.
*/
if (dev != NULL)
pdata = dev->get_platform_data(pentry);
/*
* On Medfield the platform device creation is handled by the MSIC
* MFD driver so we don't need to do it here.
*/
if (intel_mid_has_msic())
return;
pdev = platform_device_alloc(pentry->name, 0);
if (pdev == NULL) {
pr_err("out of memory for SFI platform device '%s'.\n",
pentry->name);
return;
}
res.start = pentry->irq;
platform_device_add_resources(pdev, &res, 1);
pdev->dev.platform_data = pdata;
intel_scu_device_register(pdev);
}
static const struct devs_id pmic_audio_dev_id __initconst = {
.name = "pmic_audio",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.device_handler = &ipc_device_handler,
};
sfi_device(pmic_audio_dev_id);
/*
* platform_ipc.h: IPC platform library header file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#ifndef _PLATFORM_IPC_H_
#define _PLATFORM_IPC_H_
extern void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
struct devs_id *dev) __attribute__((weak));
#endif
/*
* platform_lis331.c: lis331 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <asm/intel-mid.h>
static void __init *lis331dl_platform_data(void *info)
{
static short intr2nd_pdata;
struct i2c_board_info *i2c_info = info;
int intr = get_gpio_by_name("accel_int");
int intr2nd = get_gpio_by_name("accel_2");
if (intr == -1 || intr2nd == -1)
return NULL;
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET;
return &intr2nd_pdata;
}
static const struct devs_id lis331dl_dev_id __initconst = {
.name = "i2c_accel",
.type = SFI_DEV_TYPE_I2C,
.get_platform_data = &lis331dl_platform_data,
};
sfi_device(lis331dl_dev_id);
/*
* platform_max3111.c: max3111 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <asm/intel-mid.h>
static void __init *max3111_platform_data(void *info)
{
struct spi_board_info *spi_info = info;
int intr = get_gpio_by_name("max3111_int");
spi_info->mode = SPI_MODE_0;
if (intr == -1)
return NULL;
spi_info->irq = intr + INTEL_MID_IRQ_OFFSET;
return NULL;
}
static const struct devs_id max3111_dev_id __initconst = {
.name = "spi_max3111",
.type = SFI_DEV_TYPE_SPI,
.get_platform_data = &max3111_platform_data,
};
sfi_device(max3111_dev_id);
/*
* platform_max7315.c: max7315 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/platform_data/pca953x.h>
#include <asm/intel-mid.h>
#define MAX7315_NUM 2
static void __init *max7315_platform_data(void *info)
{
static struct pca953x_platform_data max7315_pdata[MAX7315_NUM];
static int nr;
struct pca953x_platform_data *max7315 = &max7315_pdata[nr];
struct i2c_board_info *i2c_info = info;
int gpio_base, intr;
char base_pin_name[SFI_NAME_LEN + 1];
char intr_pin_name[SFI_NAME_LEN + 1];
if (nr == MAX7315_NUM) {
pr_err("too many max7315s, we only support %d\n",
MAX7315_NUM);
return NULL;
}
/* we have several max7315 on the board, we only need load several
* instances of the same pca953x driver to cover them
*/
strcpy(i2c_info->type, "max7315");
if (nr++) {
sprintf(base_pin_name, "max7315_%d_base", nr);
sprintf(intr_pin_name, "max7315_%d_int", nr);
} else {
strcpy(base_pin_name, "max7315_base");
strcpy(intr_pin_name, "max7315_int");
}
gpio_base = get_gpio_by_name(base_pin_name);
intr = get_gpio_by_name(intr_pin_name);
if (gpio_base == -1)
return NULL;
max7315->gpio_base = gpio_base;
if (intr != -1) {
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
max7315->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
} else {
i2c_info->irq = -1;
max7315->irq_base = -1;
}
return max7315;
}
static const struct devs_id max7315_dev_id __initconst = {
.name = "i2c_max7315",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
.get_platform_data = &max7315_platform_data,
};
static const struct devs_id max7315_2_dev_id __initconst = {
.name = "i2c_max7315_2",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
.get_platform_data = &max7315_platform_data,
};
sfi_device(max7315_dev_id);
sfi_device(max7315_2_dev_id);
/*
* platform_mpu3050.c: mpu3050 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <asm/intel-mid.h>
static void *mpu3050_platform_data(void *info)
{
struct i2c_board_info *i2c_info = info;
int intr = get_gpio_by_name("mpu3050_int");
if (intr == -1)
return NULL;
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
return NULL;
}
static const struct devs_id mpu3050_dev_id __initconst = {
.name = "mpu3050",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
.get_platform_data = &mpu3050_platform_data,
};
sfi_device(mpu3050_dev_id);
/*
* platform_msic.c: MSIC platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel_scu_ipc.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
struct intel_msic_platform_data msic_pdata;
static struct resource msic_resources[] = {
{
.start = INTEL_MSIC_IRQ_PHYS_BASE,
.end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device msic_device = {
.name = "intel_msic",
.id = -1,
.dev = {
.platform_data = &msic_pdata,
},
.num_resources = ARRAY_SIZE(msic_resources),
.resource = msic_resources,
};
static int msic_scu_status_change(struct notifier_block *nb,
unsigned long code, void *data)
{
if (code == SCU_DOWN) {
platform_device_unregister(&msic_device);
return 0;
}
return platform_device_register(&msic_device);
}
static int __init msic_init(void)
{
static struct notifier_block msic_scu_notifier = {
.notifier_call = msic_scu_status_change,
};
/*
* We need to be sure that the SCU IPC is ready before MSIC device
* can be registered.
*/
if (intel_mid_has_msic())
intel_scu_notifier_add(&msic_scu_notifier);
return 0;
}
arch_initcall(msic_init);
/*
* msic_generic_platform_data - sets generic platform data for the block
* @info: pointer to the SFI device table entry for this block
* @block: MSIC block
*
* Function sets IRQ number from the SFI table entry for given device to
* the MSIC platform data.
*/
void *msic_generic_platform_data(void *info, enum intel_msic_block block)
{
struct sfi_device_table_entry *entry = info;
BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST);
msic_pdata.irq[block] = entry->irq;
return NULL;
}
/*
* platform_msic.h: MSIC platform data header file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#ifndef _PLATFORM_MSIC_H_
#define _PLATFORM_MSIC_H_
extern struct intel_msic_platform_data msic_pdata;
extern void *msic_generic_platform_data(void *info,
enum intel_msic_block block) __attribute__((weak));
#endif
/*
* platform_msic_audio.c: MSIC audio platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/platform_device.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void *msic_audio_platform_data(void *info)
{
struct platform_device *pdev;
pdev = platform_device_register_simple("sst-platform", -1, NULL, 0);
if (IS_ERR(pdev)) {
pr_err("failed to create audio platform device\n");
return NULL;
}
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO);
}
static const struct devs_id msic_audio_dev_id __initconst = {
.name = "msic_audio",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_audio_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_audio_dev_id);
/*
* platform_msic_battery.c: MSIC battery platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void __init *msic_battery_platform_data(void *info)
{
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY);
}
static const struct devs_id msic_battery_dev_id __initconst = {
.name = "msic_battery",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_battery_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_battery_dev_id);
/*
* platform_msic_gpio.c: MSIC GPIO platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/sfi.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void __init *msic_gpio_platform_data(void *info)
{
static struct intel_msic_gpio_pdata msic_gpio_pdata;
int gpio = get_gpio_by_name("msic_gpio_base");
if (gpio < 0)
return NULL;
msic_gpio_pdata.gpio_base = gpio;
msic_pdata.gpio = &msic_gpio_pdata;
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO);
}
static const struct devs_id msic_gpio_dev_id __initconst = {
.name = "msic_gpio",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_gpio_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_gpio_dev_id);
/*
* platform_msic_ocd.c: MSIC OCD platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/sfi.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void __init *msic_ocd_platform_data(void *info)
{
static struct intel_msic_ocd_pdata msic_ocd_pdata;
int gpio;
gpio = get_gpio_by_name("ocd_gpio");
if (gpio < 0)
return NULL;
msic_ocd_pdata.gpio = gpio;
msic_pdata.ocd = &msic_ocd_pdata;
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD);
}
static const struct devs_id msic_ocd_dev_id __initconst = {
.name = "msic_ocd",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_ocd_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_ocd_dev_id);
/*
* platform_msic_power_btn.c: MSIC power btn platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/sfi.h>
#include <linux/init.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void __init *msic_power_btn_platform_data(void *info)
{
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN);
}
static const struct devs_id msic_power_btn_dev_id __initconst = {
.name = "msic_power_btn",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_power_btn_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_power_btn_dev_id);
/*
* platform_msic_thermal.c: msic_thermal platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/input.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mfd/intel_msic.h>
#include <asm/intel-mid.h>
#include "platform_msic.h"
#include "platform_ipc.h"
static void __init *msic_thermal_platform_data(void *info)
{
return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_THERMAL);
}
static const struct devs_id msic_thermal_dev_id __initconst = {
.name = "msic_thermal",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &msic_thermal_platform_data,
.device_handler = &ipc_device_handler,
};
sfi_device(msic_thermal_dev_id);
/*
* platform_pmic_gpio.c: PMIC GPIO platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/intel_pmic_gpio.h>
#include <asm/intel-mid.h>
#include "platform_ipc.h"
static void __init *pmic_gpio_platform_data(void *info)
{
static struct intel_pmic_gpio_platform_data pmic_gpio_pdata;
int gpio_base = get_gpio_by_name("pmic_gpio_base");
if (gpio_base == -1)
gpio_base = 64;
pmic_gpio_pdata.gpio_base = gpio_base;
pmic_gpio_pdata.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
pmic_gpio_pdata.gpiointr = 0xffffeff8;
return &pmic_gpio_pdata;
}
static const struct devs_id pmic_gpio_spi_dev_id __initconst = {
.name = "pmic_gpio",
.type = SFI_DEV_TYPE_SPI,
.delay = 1,
.get_platform_data = &pmic_gpio_platform_data,
};
static const struct devs_id pmic_gpio_ipc_dev_id __initconst = {
.name = "pmic_gpio",
.type = SFI_DEV_TYPE_IPC,
.delay = 1,
.get_platform_data = &pmic_gpio_platform_data,
.device_handler = &ipc_device_handler
};
sfi_device(pmic_gpio_spi_dev_id);
sfi_device(pmic_gpio_ipc_dev_id);
/*
* platform_tc35876x.c: tc35876x platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/gpio.h>
#include <linux/i2c/tc35876x.h>
#include <asm/intel-mid.h>
/*tc35876x DSI_LVDS bridge chip and panel platform data*/
static void *tc35876x_platform_data(void *data)
{
static struct tc35876x_platform_data pdata;
/* gpio pins set to -1 will not be used by the driver */
pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN");
pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN");
pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3");
return &pdata;
}
static const struct devs_id tc35876x_dev_id __initconst = {
.name = "i2c_disp_brig",
.type = SFI_DEV_TYPE_I2C,
.get_platform_data = &tc35876x_platform_data,
};
sfi_device(tc35876x_dev_id);
/*
* platform_tca6416.c: tca6416 platform data initilization file
*
* (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/platform_data/pca953x.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <asm/intel-mid.h>
#define TCA6416_NAME "tca6416"
#define TCA6416_BASE "tca6416_base"
#define TCA6416_INTR "tca6416_int"
static void *tca6416_platform_data(void *info)
{
static struct pca953x_platform_data tca6416;
struct i2c_board_info *i2c_info = info;
int gpio_base, intr;
char base_pin_name[SFI_NAME_LEN + 1];
char intr_pin_name[SFI_NAME_LEN + 1];
strcpy(i2c_info->type, TCA6416_NAME);
strcpy(base_pin_name, TCA6416_BASE);
strcpy(intr_pin_name, TCA6416_INTR);
gpio_base = get_gpio_by_name(base_pin_name);
intr = get_gpio_by_name(intr_pin_name);
if (gpio_base == -1)
return NULL;
tca6416.gpio_base = gpio_base;
if (intr != -1) {
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
tca6416.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
} else {
i2c_info->irq = -1;
tca6416.irq_base = -1;
}
return &tca6416;
}
static const struct devs_id tca6416_dev_id __initconst = {
.name = "tca6416",
.type = SFI_DEV_TYPE_I2C,
.delay = 1,
.get_platform_data = &tca6416_platform_data,
};
sfi_device(tca6416_dev_id);
/* /*
* early_printk_mrst.c - early consoles for Intel MID platforms * early_printk_intel_mid.c - early consoles for Intel MID platforms
* *
* Copyright (c) 2008-2010, Intel Corporation * Copyright (c) 2008-2010, Intel Corporation
* *
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#define MRST_SPI_TIMEOUT 0x200000 #define MRST_SPI_TIMEOUT 0x200000
#define MRST_REGBASE_SPI0 0xff128000 #define MRST_REGBASE_SPI0 0xff128000
...@@ -152,7 +152,7 @@ void mrst_early_console_init(void) ...@@ -152,7 +152,7 @@ void mrst_early_console_init(void)
spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9; spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
freq = 100000000 / (spi0_cdiv + 1); freq = 100000000 / (spi0_cdiv + 1);
if (mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL) if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL)
mrst_spi_paddr = MRST_REGBASE_SPI1; mrst_spi_paddr = MRST_REGBASE_SPI1;
pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
...@@ -213,13 +213,14 @@ static void early_mrst_spi_putc(char c) ...@@ -213,13 +213,14 @@ static void early_mrst_spi_putc(char c)
} }
if (!timeout) if (!timeout)
pr_warning("MRST earlycon: timed out\n"); pr_warn("MRST earlycon: timed out\n");
else else
max3110_write_data(c); max3110_write_data(c);
} }
/* Early SPI only uses polling mode */ /* Early SPI only uses polling mode */
static void early_mrst_spi_write(struct console *con, const char *str, unsigned n) static void early_mrst_spi_write(struct console *con, const char *str,
unsigned n)
{ {
int i; int i;
......
/*
* intel-mid.c: Intel MID platform setup code
*
* (C) Copyright 2008, 2012 Intel Corporation
* Author: Jacob Pan (jacob.jun.pan@intel.com)
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#define pr_fmt(fmt) "intel_mid: " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/sfi.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <asm/setup.h>
#include <asm/mpspec_def.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/intel-mid.h>
#include <asm/intel_mid_vrtc.h>
#include <asm/io.h>
#include <asm/i8259.h>
#include <asm/intel_scu_ipc.h>
#include <asm/apb_timer.h>
#include <asm/reboot.h>
/*
* the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock,
* cmdline option x86_intel_mid_timer can be used to override the configuration
* to prefer one or the other.
* at runtime, there are basically three timer configurations:
* 1. per cpu apbt clock only
* 2. per cpu always-on lapic clocks only, this is Penwell/Medfield only
* 3. per cpu lapic clock (C3STOP) and one apbt clock, with broadcast.
*
* by default (without cmdline option), platform code first detects cpu type
* to see if we are on lincroft or penwell, then set up both lapic or apbt
* clocks accordingly.
* i.e. by default, medfield uses configuration #2, moorestown uses #1.
* config #3 is supported but not recommended on medfield.
*
* rating and feature summary:
* lapic (with C3STOP) --------- 100
* apbt (always-on) ------------ 110
* lapic (always-on,ARAT) ------ 150
*/
enum intel_mid_timer_options intel_mid_timer_options;
enum intel_mid_cpu_type __intel_mid_cpu_chip;
EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
static void intel_mid_power_off(void)
{
}
static void intel_mid_reboot(void)
{
intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
}
static unsigned long __init intel_mid_calibrate_tsc(void)
{
unsigned long fast_calibrate;
u32 lo, hi, ratio, fsb;
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
ratio = (hi >> 8) & 0x1f;
pr_debug("ratio is %d\n", ratio);
if (!ratio) {
pr_err("read a zero ratio, should be incorrect!\n");
pr_err("force tsc ratio to 16 ...\n");
ratio = 16;
}
rdmsr(MSR_FSB_FREQ, lo, hi);
if ((lo & 0x7) == 0x7)
fsb = PENWELL_FSB_FREQ_83SKU;
else
fsb = PENWELL_FSB_FREQ_100SKU;
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
/* mark tsc clocksource as reliable */
set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
if (fast_calibrate)
return fast_calibrate;
return 0;
}
static void __init intel_mid_time_init(void)
{
sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
switch (intel_mid_timer_options) {
case INTEL_MID_TIMER_APBT_ONLY:
break;
case INTEL_MID_TIMER_LAPIC_APBT:
x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
break;
default:
if (!boot_cpu_has(X86_FEATURE_ARAT))
break;
x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
return;
}
/* we need at least one APB timer */
pre_init_apic_IRQ0();
apbt_time_init();
}
static void intel_mid_arch_setup(void)
{
if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27)
__intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
else {
pr_err("Unknown Intel MID CPU (%d:%d), default to Penwell\n",
boot_cpu_data.x86, boot_cpu_data.x86_model);
__intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
}
}
/* MID systems don't have i8042 controller */
static int intel_mid_i8042_detect(void)
{
return 0;
}
/*
* Moorestown does not have external NMI source nor port 0x61 to report
* NMI status. The possible NMI sources are from pmu as a result of NMI
* watchdog or lock debug. Reading io port 0x61 results in 0xff which
* misled NMI handler.
*/
static unsigned char intel_mid_get_nmi_reason(void)
{
return 0;
}
/*
* Moorestown specific x86_init function overrides and early setup
* calls.
*/
void __init x86_intel_mid_early_setup(void)
{
x86_init.resources.probe_roms = x86_init_noop;
x86_init.resources.reserve_resources = x86_init_noop;
x86_init.timers.timer_init = intel_mid_time_init;
x86_init.timers.setup_percpu_clockev = x86_init_noop;
x86_init.irqs.pre_vector_init = x86_init_noop;
x86_init.oem.arch_setup = intel_mid_arch_setup;
x86_cpuinit.setup_percpu_clockev = apbt_setup_secondary_clock;
x86_platform.calibrate_tsc = intel_mid_calibrate_tsc;
x86_platform.i8042_detect = intel_mid_i8042_detect;
x86_init.timers.wallclock_init = intel_mid_rtc_init;
x86_platform.get_nmi_reason = intel_mid_get_nmi_reason;
x86_init.pci.init = intel_mid_pci_init;
x86_init.pci.fixup_irqs = x86_init_noop;
legacy_pic = &null_legacy_pic;
pm_power_off = intel_mid_power_off;
machine_ops.emergency_restart = intel_mid_reboot;
/* Avoid searching for BIOS MP tables */
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.mpparse.get_smp_config = x86_init_uint_noop;
set_bit(MP_BUS_ISA, mp_bus_not_pci);
}
/*
* if user does not want to use per CPU apb timer, just give it a lower rating
* than local apic timer and skip the late per cpu timer init.
*/
static inline int __init setup_x86_intel_mid_timer(char *arg)
{
if (!arg)
return -EINVAL;
if (strcmp("apbt_only", arg) == 0)
intel_mid_timer_options = INTEL_MID_TIMER_APBT_ONLY;
else if (strcmp("lapic_and_apbt", arg) == 0)
intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT;
else {
pr_warn("X86 INTEL_MID timer option %s not recognised"
" use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n",
arg);
return -EINVAL;
}
return 0;
}
__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer);
/* /*
* vrtc.c: Driver for virtual RTC device on Intel MID platform * intel_mid_vrtc.c: Driver for virtual RTC device on Intel MID platform
* *
* (C) Copyright 2009 Intel Corporation * (C) Copyright 2009 Intel Corporation
* *
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include <linux/sfi.h> #include <linux/sfi.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/mrst-vrtc.h> #include <asm/intel_mid_vrtc.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
...@@ -79,7 +79,7 @@ void vrtc_get_time(struct timespec *now) ...@@ -79,7 +79,7 @@ void vrtc_get_time(struct timespec *now)
/* vRTC YEAR reg contains the offset to 1972 */ /* vRTC YEAR reg contains the offset to 1972 */
year += 1972; year += 1972;
printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " pr_info("vRTC: sec: %d min: %d hour: %d day: %d "
"mon: %d year: %d\n", sec, min, hour, mday, mon, year); "mon: %d year: %d\n", sec, min, hour, mday, mon, year);
now->tv_sec = mktime(year, mon, mday, hour, min, sec); now->tv_sec = mktime(year, mon, mday, hour, min, sec);
...@@ -109,15 +109,14 @@ int vrtc_set_mmss(const struct timespec *now) ...@@ -109,15 +109,14 @@ int vrtc_set_mmss(const struct timespec *now)
vrtc_cmos_write(tm.tm_sec, RTC_SECONDS); vrtc_cmos_write(tm.tm_sec, RTC_SECONDS);
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
} else { } else {
printk(KERN_ERR pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n",
"%s: Invalid vRTC value: write of %lx to vRTC failed\n",
__FUNCTION__, now->tv_sec); __FUNCTION__, now->tv_sec);
retval = -EINVAL; retval = -EINVAL;
} }
return retval; return retval;
} }
void __init mrst_rtc_init(void) void __init intel_mid_rtc_init(void)
{ {
unsigned long vrtc_paddr; unsigned long vrtc_paddr;
...@@ -155,10 +154,10 @@ static struct platform_device vrtc_device = { ...@@ -155,10 +154,10 @@ static struct platform_device vrtc_device = {
}; };
/* Register the RTC device if appropriate */ /* Register the RTC device if appropriate */
static int __init mrst_device_create(void) static int __init intel_mid_device_create(void)
{ {
/* No Moorestown, no device */ /* No Moorestown, no device */
if (!mrst_identify_cpu()) if (!intel_mid_identify_cpu())
return -ENODEV; return -ENODEV;
/* No timer, no device */ /* No timer, no device */
if (!sfi_mrtc_num) if (!sfi_mrtc_num)
...@@ -175,4 +174,4 @@ static int __init mrst_device_create(void) ...@@ -175,4 +174,4 @@ static int __init mrst_device_create(void)
return platform_device_register(&vrtc_device); return platform_device_register(&vrtc_device);
} }
module_init(mrst_device_create); module_init(intel_mid_device_create);
obj-$(CONFIG_X86_INTEL_MID) += mrst.o
obj-$(CONFIG_X86_INTEL_MID) += vrtc.o
obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_mrst.o
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include "mdfld_output.h" #include "mdfld_output.h"
#include <asm/mrst.h> #include <asm/intel-mid.h>
#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/intel_scu_ipc.h> #include <asm/intel_scu_ipc.h>
#include "mid_bios.h" #include "mid_bios.h"
#include "intel_bios.h" #include "intel_bios.h"
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include "intel_bios.h" #include "intel_bios.h"
#include "psb_drv.h" #include "psb_drv.h"
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sfi.h> #include <linux/sfi.h>
#include <linux/module.h> #include <linux/module.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/intel_scu_ipc.h> #include <asm/intel_scu_ipc.h>
/* IPC defines the following message types */ /* IPC defines the following message types */
...@@ -579,7 +579,7 @@ static struct pci_driver ipc_driver = { ...@@ -579,7 +579,7 @@ static struct pci_driver ipc_driver = {
static int __init intel_scu_ipc_init(void) static int __init intel_scu_ipc_init(void)
{ {
platform = mrst_identify_cpu(); platform = intel_mid_identify_cpu();
if (platform == 0) if (platform == 0)
return -ENODEV; return -ENODEV;
return pci_register_driver(&ipc_driver); return pci_register_driver(&ipc_driver);
......
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#include <asm-generic/rtc.h> #include <asm-generic/rtc.h>
#include <asm/intel_scu_ipc.h> #include <asm/intel_scu_ipc.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include <asm/mrst-vrtc.h> #include <asm/intel_mid_vrtc.h>
struct mrst_rtc { struct mrst_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/intel_scu_ipc.h> #include <asm/intel_scu_ipc.h>
#include <asm/apb_timer.h> #include <asm/apb_timer.h>
#include <asm/mrst.h> #include <asm/intel-mid.h>
#include "intel_scu_watchdog.h" #include "intel_scu_watchdog.h"
...@@ -445,7 +445,7 @@ static int __init intel_scu_watchdog_init(void) ...@@ -445,7 +445,7 @@ static int __init intel_scu_watchdog_init(void)
* *
* If it isn't an intel MID device then it doesn't have this watchdog * If it isn't an intel MID device then it doesn't have this watchdog
*/ */
if (!mrst_identify_cpu()) if (!intel_mid_identify_cpu())
return -ENODEV; return -ENODEV;
/* Check boot parameters to verify that their initial values */ /* Check boot parameters to verify that their initial values */
......
...@@ -59,6 +59,9 @@ ...@@ -59,6 +59,9 @@
#ifndef _LINUX_SFI_H #ifndef _LINUX_SFI_H
#define _LINUX_SFI_H #define _LINUX_SFI_H
#include <linux/init.h>
#include <linux/types.h>
/* Table signatures reserved by the SFI specification */ /* Table signatures reserved by the SFI specification */
#define SFI_SIG_SYST "SYST" #define SFI_SIG_SYST "SYST"
#define SFI_SIG_FREQ "FREQ" #define SFI_SIG_FREQ "FREQ"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment