mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-22 12:21:00 +02:00
Merge tag 'sfi-removal-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull Simple Firmware Interface (SFI) support removal from Rafael Wysocki: "Drop support for depercated platforms using SFI, drop the entire support for SFI that has been long deprecated too and make some janitorial changes on top of that (Andy Shevchenko)" * tag 'sfi-removal-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: x86/platform/intel-mid: Update Copyright year and drop file names x86/platform/intel-mid: Remove unused header inclusion in intel-mid.h x86/platform/intel-mid: Drop unused __intel_mid_cpu_chip and Co. x86/platform/intel-mid: Get rid of intel_scu_ipc_legacy.h x86/PCI: Describe @reg for type1_access_ok() x86/PCI: Get rid of custom x86 model comparison sfi: Remove framework for deprecated firmware cpufreq: sfi-cpufreq: Remove driver for deprecated firmware media: atomisp: Remove unused header mfd: intel_msic: Remove driver for deprecated platform x86/apb_timer: Remove driver for deprecated platform x86/platform/intel-mid: Remove unused leftovers (vRTC) x86/platform/intel-mid: Remove unused leftovers (msic) x86/platform/intel-mid: Remove unused leftovers (msic_thermal) x86/platform/intel-mid: Remove unused leftovers (msic_power_btn) x86/platform/intel-mid: Remove unused leftovers (msic_gpio) x86/platform/intel-mid: Remove unused leftovers (msic_battery) x86/platform/intel-mid: Remove unused leftovers (msic_ocd) x86/platform/intel-mid: Remove unused leftovers (msic_audio) platform/x86: intel_scu_wdt: Drop mistakenly added const
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
What: /sys/firmware/sfi/tables/
|
||||
Date: May 2010
|
||||
Contact: Len Brown <lenb@kernel.org>
|
||||
Description:
|
||||
SFI defines a number of small static memory tables
|
||||
so the kernel can get platform information from firmware.
|
||||
|
||||
The tables are defined in the latest SFI specification:
|
||||
http://simplefirmware.org/documentation
|
||||
|
||||
While the tables are used by the kernel, user-space
|
||||
can observe them this way::
|
||||
|
||||
# cd /sys/firmware/sfi/tables
|
||||
# cat $TABLENAME > $TABLENAME.bin
|
@@ -7,7 +7,7 @@ Description:
|
||||
is connected. example: "/dev/ttyS0".
|
||||
|
||||
The device name flows down to architecture specific board
|
||||
initialization file from the SFI/ATAGS bootloader
|
||||
initialization file from the ATAGS bootloader
|
||||
firmware. The name exposed is read from the user-space
|
||||
dameon and opens the device when install is requested.
|
||||
|
||||
|
@@ -5990,12 +5990,6 @@
|
||||
default x2apic cluster mode on platforms
|
||||
supporting x2apic.
|
||||
|
||||
x86_intel_mid_timer= [X86-32,APBT]
|
||||
Choose timer option for x86 Intel MID platform.
|
||||
Two valid options are apbt timer only and lapic timer
|
||||
plus one apbt timer for broadcast timer.
|
||||
x86_intel_mid_timer=apbt_only | lapic_and_apbt
|
||||
|
||||
xen_512gb_limit [KNL,X86-64,XEN]
|
||||
Restricts the kernel running paravirtualized under Xen
|
||||
to use only up to 512 GB of RAM. The reason to do so is
|
||||
|
@@ -9122,9 +9122,7 @@ F: drivers/gpio/gpio-*cove.c
|
||||
INTEL PMIC MULTIFUNCTION DEVICE DRIVERS
|
||||
M: Andy Shevchenko <andy@kernel.org>
|
||||
S: Maintained
|
||||
F: drivers/mfd/intel_msic.c
|
||||
F: drivers/mfd/intel_soc_pmic*
|
||||
F: include/linux/mfd/intel_msic.h
|
||||
F: include/linux/mfd/intel_soc_pmic*
|
||||
|
||||
INTEL PMT DRIVER
|
||||
@@ -16322,13 +16320,6 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml
|
||||
F: drivers/i3c/master/svc-i3c-master.c
|
||||
|
||||
SIMPLE FIRMWARE INTERFACE (SFI)
|
||||
S: Obsolete
|
||||
W: http://simplefirmware.org/
|
||||
F: arch/x86/platform/sfi/
|
||||
F: drivers/sfi/
|
||||
F: include/linux/sfi*.h
|
||||
|
||||
SIMPLEFB FB DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
|
@@ -448,7 +448,7 @@ config X86_X2APIC
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config X86_MPPARSE
|
||||
bool "Enable MPS table" if ACPI || SFI
|
||||
bool "Enable MPS table" if ACPI
|
||||
default y
|
||||
depends on X86_LOCAL_APIC
|
||||
help
|
||||
@@ -607,7 +607,6 @@ config X86_INTEL_MID
|
||||
depends on PCI
|
||||
depends on X86_64 || (PCI_GOANY && X86_32)
|
||||
depends on X86_IO_APIC
|
||||
select SFI
|
||||
select I2C
|
||||
select DW_APB_TIMER
|
||||
select APB_TIMER
|
||||
@@ -896,18 +895,6 @@ config HPET_EMULATE_RTC
|
||||
def_bool y
|
||||
depends on HPET_TIMER && (RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
|
||||
|
||||
config APB_TIMER
|
||||
def_bool y if X86_INTEL_MID
|
||||
prompt "Intel MID APB Timer Support" if X86_INTEL_MID
|
||||
select DW_APB_TIMER
|
||||
depends on X86_INTEL_MID && SFI
|
||||
help
|
||||
APB timer is the replacement for 8254, HPET on X86 MID platforms.
|
||||
The APBT provides a stable time base on SMP
|
||||
systems, unlike the TSC, but it is more expensive to access,
|
||||
as it is off-chip. APB timers are always running regardless of CPU
|
||||
C states, they are used as per CPU clockevent device when possible.
|
||||
|
||||
# Mark as expert because too many people got it wrong.
|
||||
# The code disables itself when not needed.
|
||||
config DMI
|
||||
@@ -2469,8 +2456,6 @@ source "kernel/power/Kconfig"
|
||||
|
||||
source "drivers/acpi/Kconfig"
|
||||
|
||||
source "drivers/sfi/Kconfig"
|
||||
|
||||
config X86_APM_BOOT
|
||||
def_bool y
|
||||
depends on APM
|
||||
@@ -2657,7 +2642,7 @@ config PCI_DIRECT
|
||||
config PCI_MMCONFIG
|
||||
bool "Support mmconfig PCI config space access" if X86_64
|
||||
default y
|
||||
depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST)
|
||||
depends on PCI && (ACPI || JAILHOUSE_GUEST)
|
||||
depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
|
||||
|
||||
config PCI_OLPC
|
||||
|
@@ -1,40 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* apb_timer.h: Driver for Langwell APB timer based on Synopsis DesignWare
|
||||
*
|
||||
* (C) Copyright 2009 Intel Corporation
|
||||
* Author: Jacob Pan (jacob.jun.pan@intel.com)
|
||||
*
|
||||
* Note:
|
||||
*/
|
||||
|
||||
#ifndef ASM_X86_APBT_H
|
||||
#define ASM_X86_APBT_H
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#ifdef CONFIG_APB_TIMER
|
||||
|
||||
/* default memory mapped register base */
|
||||
#define LNW_SCU_ADDR 0xFF100000
|
||||
#define LNW_EXT_TIMER_OFFSET 0x1B800
|
||||
#define APBT_DEFAULT_BASE (LNW_SCU_ADDR+LNW_EXT_TIMER_OFFSET)
|
||||
#define LNW_EXT_TIMER_PGOFFSET 0x800
|
||||
|
||||
/* APBT clock speed range from PCLK to fabric base, 25-100MHz */
|
||||
#define APBT_MAX_FREQ 50000000
|
||||
#define APBT_MIN_FREQ 1000000
|
||||
#define APBT_MMAP_SIZE 1024
|
||||
|
||||
extern void apbt_time_init(void);
|
||||
extern void apbt_setup_secondary_clock(void);
|
||||
|
||||
extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
|
||||
extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
|
||||
extern int sfi_mtimer_num;
|
||||
|
||||
#else /* CONFIG_APB_TIMER */
|
||||
|
||||
static inline void apbt_time_init(void) { }
|
||||
|
||||
#endif
|
||||
#endif /* ASM_X86_APBT_H */
|
@@ -108,9 +108,6 @@ enum fixed_addresses {
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
FIX_PARAVIRT_BOOTMAP,
|
||||
#endif
|
||||
#ifdef CONFIG_X86_INTEL_MID
|
||||
FIX_LNW_VRTC,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_GHES
|
||||
/* Used for GHES mapping from assorted contexts */
|
||||
|
@@ -1,15 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* intel-mid.h: Intel MID specific setup code
|
||||
* Intel MID specific setup code
|
||||
*
|
||||
* (C) Copyright 2009 Intel Corporation
|
||||
* (C) Copyright 2009, 2021 Intel Corporation
|
||||
*/
|
||||
#ifndef _ASM_X86_INTEL_MID_H
|
||||
#define _ASM_X86_INTEL_MID_H
|
||||
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern int intel_mid_pci_init(void);
|
||||
extern int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state);
|
||||
@@ -22,93 +20,18 @@ extern void intel_mid_pwr_power_off(void);
|
||||
|
||||
extern int intel_mid_pwr_get_lss_id(struct pci_dev *pdev);
|
||||
|
||||
extern int get_gpio_by_name(const char *name);
|
||||
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 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;
|
||||
u8 msic;
|
||||
void *(*get_platform_data)(void *info);
|
||||
};
|
||||
|
||||
#define sfi_device(i) \
|
||||
static const struct devs_id *const __intel_mid_sfi_##i##_dev __used \
|
||||
__section(".x86_intel_mid_dev.init") = &i
|
||||
|
||||
/**
|
||||
* struct mid_sd_board_info - template for SD device creation
|
||||
* @name: identifies the driver
|
||||
* @bus_num: board-specific identifier for a given SD controller
|
||||
* @max_clk: the maximum frequency device supports
|
||||
* @platform_data: the particular data stored there is driver-specific
|
||||
*/
|
||||
struct mid_sd_board_info {
|
||||
char name[SFI_NAME_LEN];
|
||||
int bus_num;
|
||||
unsigned short addr;
|
||||
u32 max_clk;
|
||||
void *platform_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
* timers. Medfield is the platform name, and the chip name is called Penwell
|
||||
* we treat Medfield/Penwell as a variant of Moorestown. Penwell can be
|
||||
* identified via MSRs.
|
||||
*/
|
||||
enum intel_mid_cpu_type {
|
||||
/* 1 was Moorestown */
|
||||
INTEL_MID_CPU_CHIP_PENWELL = 2,
|
||||
INTEL_MID_CPU_CHIP_CLOVERVIEW,
|
||||
INTEL_MID_CPU_CHIP_TANGIER,
|
||||
};
|
||||
|
||||
extern enum intel_mid_cpu_type __intel_mid_cpu_chip;
|
||||
|
||||
#ifdef CONFIG_X86_INTEL_MID
|
||||
|
||||
static inline enum intel_mid_cpu_type intel_mid_identify_cpu(void)
|
||||
{
|
||||
return __intel_mid_cpu_chip;
|
||||
}
|
||||
|
||||
static inline bool intel_mid_has_msic(void)
|
||||
{
|
||||
return (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL);
|
||||
}
|
||||
|
||||
extern void intel_scu_devices_create(void);
|
||||
extern void intel_scu_devices_destroy(void);
|
||||
|
||||
#else /* !CONFIG_X86_INTEL_MID */
|
||||
|
||||
#define intel_mid_identify_cpu() 0
|
||||
#define intel_mid_has_msic() 0
|
||||
|
||||
static inline void intel_scu_devices_create(void) { }
|
||||
static inline void intel_scu_devices_destroy(void) { }
|
||||
|
||||
#endif /* !CONFIG_X86_INTEL_MID */
|
||||
|
||||
enum intel_mid_timer_options {
|
||||
INTEL_MID_TIMER_DEFAULT,
|
||||
INTEL_MID_TIMER_APBT_ONLY,
|
||||
INTEL_MID_TIMER_LAPIC_APBT,
|
||||
};
|
||||
|
||||
extern enum intel_mid_timer_options intel_mid_timer_options;
|
||||
|
||||
/* Bus Select SoC Fuse value */
|
||||
#define BSEL_SOC_FUSE_MASK 0x7
|
||||
/* FSB 133MHz */
|
||||
@@ -118,16 +41,4 @@ extern enum intel_mid_timer_options intel_mid_timer_options;
|
||||
/* FSB 83MHz */
|
||||
#define BSEL_SOC_FUSE_111 0x7
|
||||
|
||||
#define SFI_MTMR_MAX_NUM 8
|
||||
#define SFI_MRTC_MAX 8
|
||||
|
||||
/* VRTC timer */
|
||||
#define MRST_VRTC_MAP_SZ 1024
|
||||
/* #define MRST_VRTC_PGOFFSET 0xc00 */
|
||||
|
||||
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_INTEL_MID_H */
|
||||
|
@@ -1,10 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _INTEL_MID_VRTC_H
|
||||
#define _INTEL_MID_VRTC_H
|
||||
|
||||
extern unsigned char vrtc_cmos_read(unsigned char reg);
|
||||
extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
|
||||
extern void vrtc_get_time(struct timespec64 *now);
|
||||
extern int vrtc_set_mmss(const struct timespec64 *now);
|
||||
|
||||
#endif
|
@@ -65,6 +65,4 @@ static inline int intel_scu_ipc_dev_command(struct intel_scu_ipc_dev *scu, int c
|
||||
inlen, out, outlen);
|
||||
}
|
||||
|
||||
#include <asm/intel_scu_ipc_legacy.h>
|
||||
|
||||
#endif
|
||||
|
@@ -1,91 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
|
||||
#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define IPCMSG_INDIRECT_READ 0x02
|
||||
#define IPCMSG_INDIRECT_WRITE 0x05
|
||||
|
||||
#define IPCMSG_COLD_OFF 0x80 /* Only for Tangier */
|
||||
|
||||
#define IPCMSG_WARM_RESET 0xF0
|
||||
#define IPCMSG_COLD_RESET 0xF1
|
||||
#define IPCMSG_SOFT_RESET 0xF2
|
||||
#define IPCMSG_COLD_BOOT 0xF3
|
||||
|
||||
#define IPCMSG_VRTC 0xFA /* Set vRTC device */
|
||||
/* Command id associated with message IPCMSG_VRTC */
|
||||
#define IPC_CMD_VRTC_SETTIME 1 /* Set time */
|
||||
#define IPC_CMD_VRTC_SETALARM 2 /* Set alarm */
|
||||
|
||||
/* Don't call these in new code - they will be removed eventually */
|
||||
|
||||
/* Read single register */
|
||||
static inline int intel_scu_ipc_ioread8(u16 addr, u8 *data)
|
||||
{
|
||||
return intel_scu_ipc_dev_ioread8(NULL, addr, data);
|
||||
}
|
||||
|
||||
/* Read a vector */
|
||||
static inline int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
|
||||
{
|
||||
return intel_scu_ipc_dev_readv(NULL, addr, data, len);
|
||||
}
|
||||
|
||||
/* Write single register */
|
||||
static inline int intel_scu_ipc_iowrite8(u16 addr, u8 data)
|
||||
{
|
||||
return intel_scu_ipc_dev_iowrite8(NULL, addr, data);
|
||||
}
|
||||
|
||||
/* Write a vector */
|
||||
static inline int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
|
||||
{
|
||||
return intel_scu_ipc_dev_writev(NULL, addr, data, len);
|
||||
}
|
||||
|
||||
/* Update single register based on the mask */
|
||||
static inline int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask)
|
||||
{
|
||||
return intel_scu_ipc_dev_update(NULL, addr, data, mask);
|
||||
}
|
||||
|
||||
/* Issue commands to the SCU with or without data */
|
||||
static inline int intel_scu_ipc_simple_command(int cmd, int sub)
|
||||
{
|
||||
return intel_scu_ipc_dev_simple_command(NULL, cmd, sub);
|
||||
}
|
||||
|
||||
static inline int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
|
||||
u32 *out, int outlen)
|
||||
{
|
||||
/* New API takes both inlen and outlen as bytes so convert here */
|
||||
size_t inbytes = inlen * sizeof(u32);
|
||||
size_t outbytes = outlen * sizeof(u32);
|
||||
|
||||
return intel_scu_ipc_dev_command_with_size(NULL, cmd, sub, in, inbytes,
|
||||
inlen, out, outbytes);
|
||||
}
|
||||
|
||||
extern struct blocking_notifier_head intel_scu_notifier;
|
||||
|
||||
static inline void intel_scu_notifier_add(struct notifier_block *nb)
|
||||
{
|
||||
blocking_notifier_chain_register(&intel_scu_notifier, nb);
|
||||
}
|
||||
|
||||
static inline void intel_scu_notifier_remove(struct notifier_block *nb)
|
||||
{
|
||||
blocking_notifier_chain_unregister(&intel_scu_notifier, nb);
|
||||
}
|
||||
|
||||
static inline int intel_scu_notifier_post(unsigned long v, void *p)
|
||||
{
|
||||
return blocking_notifier_call_chain(&intel_scu_notifier, v, p);
|
||||
}
|
||||
|
||||
#define SCU_AVAILABLE 1
|
||||
#define SCU_DOWN 2
|
||||
|
||||
#endif
|
@@ -10,8 +10,6 @@
|
||||
#ifndef _PLATFORM_SST_AUDIO_H_
|
||||
#define _PLATFORM_SST_AUDIO_H_
|
||||
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#define MAX_NUM_STREAMS_MRFLD 25
|
||||
#define MAX_NUM_STREAMS MAX_NUM_STREAMS_MRFLD
|
||||
|
||||
|
@@ -116,7 +116,6 @@ obj-$(CONFIG_VM86) += vm86_32.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_HPET_TIMER) += hpet.o
|
||||
obj-$(CONFIG_APB_TIMER) += apb_timer.o
|
||||
|
||||
obj-$(CONFIG_AMD_NB) += amd_nb.o
|
||||
obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
|
||||
|
@@ -1,347 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* apb_timer.c: Driver for Langwell APB timers
|
||||
*
|
||||
* (C) Copyright 2009 Intel Corporation
|
||||
* Author: Jacob Pan (jacob.jun.pan@intel.com)
|
||||
*
|
||||
* Note:
|
||||
* Langwell is the south complex of Intel Moorestown MID platform. There are
|
||||
* eight external timers in total that can be used by the operating system.
|
||||
* The timer information, such as frequency and addresses, is provided to the
|
||||
* OS via SFI tables.
|
||||
* Timer interrupts are routed via FW/HW emulated IOAPIC independently via
|
||||
* individual redirection table entries (RTE).
|
||||
* Unlike HPET, there is no master counter, therefore one of the timers are
|
||||
* used as clocksource. The overall allocation looks like:
|
||||
* - timer 0 - NR_CPUs for per cpu timer
|
||||
* - one timer for clocksource
|
||||
* - one timer for watchdog driver.
|
||||
* It is also worth notice that APB timer does not support true one-shot mode,
|
||||
* free-running mode will be used here to emulate one-shot mode.
|
||||
* APB timer can also be used as broadcast timer along with per cpu local APIC
|
||||
* timer, but by default APB timer has higher rating than local APIC timers.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dw_apb_timer.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/apb_timer.h>
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#define APBT_CLOCKEVENT_RATING 110
|
||||
#define APBT_CLOCKSOURCE_RATING 250
|
||||
|
||||
#define APBT_CLOCKEVENT0_NUM (0)
|
||||
#define APBT_CLOCKSOURCE_NUM (2)
|
||||
|
||||
static phys_addr_t apbt_address;
|
||||
static int apb_timer_block_enabled;
|
||||
static void __iomem *apbt_virt_address;
|
||||
|
||||
/*
|
||||
* Common DW APB timer info
|
||||
*/
|
||||
static unsigned long apbt_freq;
|
||||
|
||||
struct apbt_dev {
|
||||
struct dw_apb_clock_event_device *timer;
|
||||
unsigned int num;
|
||||
int cpu;
|
||||
unsigned int irq;
|
||||
char name[10];
|
||||
};
|
||||
|
||||
static struct dw_apb_clocksource *clocksource_apbt;
|
||||
|
||||
static inline void __iomem *adev_virt_addr(struct apbt_dev *adev)
|
||||
{
|
||||
return apbt_virt_address + adev->num * APBTMRS_REG_SIZE;
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static unsigned int apbt_num_timers_used;
|
||||
#endif
|
||||
|
||||
static inline void apbt_set_mapping(void)
|
||||
{
|
||||
struct sfi_timer_table_entry *mtmr;
|
||||
int phy_cs_timer_id = 0;
|
||||
|
||||
if (apbt_virt_address) {
|
||||
pr_debug("APBT base already mapped\n");
|
||||
return;
|
||||
}
|
||||
mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
|
||||
if (mtmr == NULL) {
|
||||
printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
|
||||
APBT_CLOCKEVENT0_NUM);
|
||||
return;
|
||||
}
|
||||
apbt_address = (phys_addr_t)mtmr->phys_addr;
|
||||
if (!apbt_address) {
|
||||
printk(KERN_WARNING "No timer base from SFI, use default\n");
|
||||
apbt_address = APBT_DEFAULT_BASE;
|
||||
}
|
||||
apbt_virt_address = ioremap(apbt_address, APBT_MMAP_SIZE);
|
||||
if (!apbt_virt_address) {
|
||||
pr_debug("Failed mapping APBT phy address at %lu\n",\
|
||||
(unsigned long)apbt_address);
|
||||
goto panic_noapbt;
|
||||
}
|
||||
apbt_freq = mtmr->freq_hz;
|
||||
sfi_free_mtmr(mtmr);
|
||||
|
||||
/* Now figure out the physical timer id for clocksource device */
|
||||
mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
|
||||
if (mtmr == NULL)
|
||||
goto panic_noapbt;
|
||||
|
||||
/* Now figure out the physical timer id */
|
||||
pr_debug("Use timer %d for clocksource\n",
|
||||
(int)(mtmr->phys_addr & 0xff) / APBTMRS_REG_SIZE);
|
||||
phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) /
|
||||
APBTMRS_REG_SIZE;
|
||||
|
||||
clocksource_apbt = dw_apb_clocksource_init(APBT_CLOCKSOURCE_RATING,
|
||||
"apbt0", apbt_virt_address + phy_cs_timer_id *
|
||||
APBTMRS_REG_SIZE, apbt_freq);
|
||||
return;
|
||||
|
||||
panic_noapbt:
|
||||
panic("Failed to setup APB system timer\n");
|
||||
|
||||
}
|
||||
|
||||
static inline void apbt_clear_mapping(void)
|
||||
{
|
||||
iounmap(apbt_virt_address);
|
||||
apbt_virt_address = NULL;
|
||||
}
|
||||
|
||||
static int __init apbt_clockevent_register(void)
|
||||
{
|
||||
struct sfi_timer_table_entry *mtmr;
|
||||
struct apbt_dev *adev = this_cpu_ptr(&cpu_apbt_dev);
|
||||
|
||||
mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
|
||||
if (mtmr == NULL) {
|
||||
printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
|
||||
APBT_CLOCKEVENT0_NUM);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
adev->num = smp_processor_id();
|
||||
adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0",
|
||||
intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ?
|
||||
APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING,
|
||||
adev_virt_addr(adev), 0, apbt_freq);
|
||||
/* Firmware does EOI handling for us. */
|
||||
adev->timer->eoi = NULL;
|
||||
|
||||
if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) {
|
||||
global_clock_event = &adev->timer->ced;
|
||||
printk(KERN_DEBUG "%s clockevent registered as global\n",
|
||||
global_clock_event->name);
|
||||
}
|
||||
|
||||
dw_apb_clockevent_register(adev->timer);
|
||||
|
||||
sfi_free_mtmr(mtmr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
static void apbt_setup_irq(struct apbt_dev *adev)
|
||||
{
|
||||
irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
|
||||
irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
|
||||
}
|
||||
|
||||
/* Should be called with per cpu */
|
||||
void apbt_setup_secondary_clock(void)
|
||||
{
|
||||
struct apbt_dev *adev;
|
||||
int cpu;
|
||||
|
||||
/* Don't register boot CPU clockevent */
|
||||
cpu = smp_processor_id();
|
||||
if (!cpu)
|
||||
return;
|
||||
|
||||
adev = this_cpu_ptr(&cpu_apbt_dev);
|
||||
if (!adev->timer) {
|
||||
adev->timer = dw_apb_clockevent_init(cpu, adev->name,
|
||||
APBT_CLOCKEVENT_RATING, adev_virt_addr(adev),
|
||||
adev->irq, apbt_freq);
|
||||
adev->timer->eoi = NULL;
|
||||
} else {
|
||||
dw_apb_clockevent_resume(adev->timer);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Registering CPU %d clockevent device %s, cpu %08x\n",
|
||||
cpu, adev->name, adev->cpu);
|
||||
|
||||
apbt_setup_irq(adev);
|
||||
dw_apb_clockevent_register(adev->timer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* this notify handler process CPU hotplug events. in case of S0i3, nonboot
|
||||
* cpus are disabled/enabled frequently, for performance reasons, we keep the
|
||||
* per cpu timer irq registered so that we do need to do free_irq/request_irq.
|
||||
*
|
||||
* TODO: it might be more reliable to directly disable percpu clockevent device
|
||||
* without the notifier chain. currently, cpu 0 may get interrupts from other
|
||||
* cpu timers during the offline process due to the ordering of notification.
|
||||
* the extra interrupt is harmless.
|
||||
*/
|
||||
static int apbt_cpu_dead(unsigned int cpu)
|
||||
{
|
||||
struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
|
||||
|
||||
dw_apb_clockevent_pause(adev->timer);
|
||||
if (system_state == SYSTEM_RUNNING) {
|
||||
pr_debug("skipping APBT CPU %u offline\n", cpu);
|
||||
} else {
|
||||
pr_debug("APBT clockevent for cpu %u offline\n", cpu);
|
||||
dw_apb_clockevent_stop(adev->timer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __init int apbt_late_init(void)
|
||||
{
|
||||
if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ||
|
||||
!apb_timer_block_enabled)
|
||||
return 0;
|
||||
return cpuhp_setup_state(CPUHP_X86_APB_DEAD, "x86/apb:dead", NULL,
|
||||
apbt_cpu_dead);
|
||||
}
|
||||
fs_initcall(apbt_late_init);
|
||||
#else
|
||||
|
||||
void apbt_setup_secondary_clock(void) {}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
static int apbt_clocksource_register(void)
|
||||
{
|
||||
u64 start, now;
|
||||
u64 t1;
|
||||
|
||||
/* Start the counter, use timer 2 as source, timer 0/1 for event */
|
||||
dw_apb_clocksource_start(clocksource_apbt);
|
||||
|
||||
/* Verify whether apbt counter works */
|
||||
t1 = dw_apb_clocksource_read(clocksource_apbt);
|
||||
start = rdtsc();
|
||||
|
||||
/*
|
||||
* We don't know the TSC frequency yet, but waiting for
|
||||
* 200000 TSC cycles is safe:
|
||||
* 4 GHz == 50us
|
||||
* 1 GHz == 200us
|
||||
*/
|
||||
do {
|
||||
rep_nop();
|
||||
now = rdtsc();
|
||||
} while ((now - start) < 200000UL);
|
||||
|
||||
/* APBT is the only always on clocksource, it has to work! */
|
||||
if (t1 == dw_apb_clocksource_read(clocksource_apbt))
|
||||
panic("APBT counter not counting. APBT disabled\n");
|
||||
|
||||
dw_apb_clocksource_register(clocksource_apbt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Early setup the APBT timer, only use timer 0 for booting then switch to
|
||||
* per CPU timer if possible.
|
||||
* returns 1 if per cpu apbt is setup
|
||||
* returns 0 if no per cpu apbt is chosen
|
||||
* panic if set up failed, this is the only platform timer on Moorestown.
|
||||
*/
|
||||
void __init apbt_time_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
int i;
|
||||
struct sfi_timer_table_entry *p_mtmr;
|
||||
struct apbt_dev *adev;
|
||||
#endif
|
||||
|
||||
if (apb_timer_block_enabled)
|
||||
return;
|
||||
apbt_set_mapping();
|
||||
if (!apbt_virt_address)
|
||||
goto out_noapbt;
|
||||
/*
|
||||
* Read the frequency and check for a sane value, for ESL model
|
||||
* we extend the possible clock range to allow time scaling.
|
||||
*/
|
||||
|
||||
if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
|
||||
pr_debug("APBT has invalid freq 0x%lx\n", apbt_freq);
|
||||
goto out_noapbt;
|
||||
}
|
||||
if (apbt_clocksource_register()) {
|
||||
pr_debug("APBT has failed to register clocksource\n");
|
||||
goto out_noapbt;
|
||||
}
|
||||
if (!apbt_clockevent_register())
|
||||
apb_timer_block_enabled = 1;
|
||||
else {
|
||||
pr_debug("APBT has failed to register clockevent\n");
|
||||
goto out_noapbt;
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
/* kernel cmdline disable apb timer, so we will use lapic timers */
|
||||
if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT) {
|
||||
printk(KERN_INFO "apbt: disabled per cpu timer\n");
|
||||
return;
|
||||
}
|
||||
pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
|
||||
if (num_possible_cpus() <= sfi_mtimer_num)
|
||||
apbt_num_timers_used = num_possible_cpus();
|
||||
else
|
||||
apbt_num_timers_used = 1;
|
||||
pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
|
||||
|
||||
/* here we set up per CPU timer data structure */
|
||||
for (i = 0; i < apbt_num_timers_used; i++) {
|
||||
adev = &per_cpu(cpu_apbt_dev, i);
|
||||
adev->num = i;
|
||||
adev->cpu = i;
|
||||
p_mtmr = sfi_get_mtmr(i);
|
||||
if (p_mtmr)
|
||||
adev->irq = p_mtmr->irq;
|
||||
else
|
||||
printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
|
||||
snprintf(adev->name, sizeof(adev->name) - 1, "apbt%d", i);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
out_noapbt:
|
||||
apbt_clear_mapping();
|
||||
apb_timer_block_enabled = 0;
|
||||
panic("failed to enable APB timer\n");
|
||||
}
|
@@ -198,7 +198,7 @@ static int __init parse_noapic(char *str)
|
||||
}
|
||||
early_param("noapic", parse_noapic);
|
||||
|
||||
/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
|
||||
/* Will be called in mpparse/ACPI codes for saving IRQ info */
|
||||
void mp_save_irq(struct mpc_intsrc *m)
|
||||
{
|
||||
int i;
|
||||
@@ -2863,7 +2863,7 @@ int mp_register_ioapic(int id, u32 address, u32 gsi_base,
|
||||
|
||||
/*
|
||||
* If mp_register_ioapic() is called during early boot stage when
|
||||
* walking ACPI/SFI/DT tables, it's too early to create irqdomain,
|
||||
* walking ACPI/DT tables, it's too early to create irqdomain,
|
||||
* we are still using bootmem allocator. So delay it to setup_IO_APIC().
|
||||
*/
|
||||
if (hotplug) {
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/tboot.h>
|
||||
#include <linux/usb/xhci-dbgp.h>
|
||||
@@ -1185,7 +1184,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
* Read APIC and some other early information from ACPI tables.
|
||||
*/
|
||||
acpi_boot_init();
|
||||
sfi_init();
|
||||
x86_dtb_init();
|
||||
|
||||
/*
|
||||
|
@@ -28,10 +28,12 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/pci_x86.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
@@ -140,6 +142,7 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
|
||||
* type1_access_ok - check whether to use type 1
|
||||
* @bus: bus number
|
||||
* @devfn: device & function in question
|
||||
* @reg: configuration register offset
|
||||
*
|
||||
* If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
|
||||
* all, the we can go ahead with any reads & writes. If it's on a Lincroft,
|
||||
@@ -212,10 +215,17 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
where, size, value);
|
||||
}
|
||||
|
||||
static const struct x86_cpu_id intel_mid_cpu_ids[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, NULL),
|
||||
{}
|
||||
};
|
||||
|
||||
static int intel_mid_pci_irq_enable(struct pci_dev *dev)
|
||||
{
|
||||
const struct x86_cpu_id *id;
|
||||
struct irq_alloc_info info;
|
||||
bool polarity_low;
|
||||
u16 model = 0;
|
||||
int ret;
|
||||
u8 gsi;
|
||||
|
||||
@@ -228,8 +238,12 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (intel_mid_identify_cpu()) {
|
||||
case INTEL_MID_CPU_CHIP_TANGIER:
|
||||
id = x86_match_cpu(intel_mid_cpu_ids);
|
||||
if (id)
|
||||
model = id->model;
|
||||
|
||||
switch (model) {
|
||||
case INTEL_FAM6_ATOM_SILVERMONT_MID:
|
||||
polarity_low = false;
|
||||
|
||||
/* Special treatment for IRQ0 */
|
||||
|
@@ -11,9 +11,9 @@
|
||||
* themselves.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sfi_acpi.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -665,7 +665,7 @@ void __init pci_mmcfg_early_init(void)
|
||||
if (pci_mmcfg_check_hostbridge())
|
||||
known_bridge = 1;
|
||||
else
|
||||
acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
|
||||
acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
|
||||
__pci_mmcfg_init(1);
|
||||
|
||||
set_apei_filter();
|
||||
@@ -683,7 +683,7 @@ void __init pci_mmcfg_late_init(void)
|
||||
|
||||
/* MMCONFIG hasn't been enabled yet, try again */
|
||||
if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
|
||||
acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
|
||||
acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
|
||||
__pci_mmcfg_init(0);
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,5 @@ obj-y += intel-mid/
|
||||
obj-y += intel-quark/
|
||||
obj-y += olpc/
|
||||
obj-y += scx200/
|
||||
obj-y += sfi/
|
||||
obj-y += ts5500/
|
||||
obj-y += uv/
|
||||
|
@@ -1,7 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o intel_mid_vrtc.o pwr.o
|
||||
|
||||
# SFI specific code
|
||||
ifdef CONFIG_X86_INTEL_MID
|
||||
obj-$(CONFIG_SFI) += sfi.o device_libs/
|
||||
endif
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o pwr.o
|
||||
|
@@ -1,32 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Family-Level Interface Shim (FLIS)
|
||||
obj-$(subst m,y,$(CONFIG_PINCTRL_MERRIFIELD)) += platform_mrfld_pinctrl.o
|
||||
# SDHCI Devices
|
||||
obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += platform_mrfld_sd.o
|
||||
# WiFi + BT
|
||||
obj-$(subst m,y,$(CONFIG_BRCMFMAC_SDIO)) += platform_bcm43xx.o
|
||||
obj-$(subst m,y,$(CONFIG_BT_HCIUART_BCM)) += platform_bt.o
|
||||
# IPC Devices
|
||||
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_INTEL_MFLD_THERMAL)) += platform_msic_thermal.o
|
||||
# SPI Devices
|
||||
obj-$(subst m,y,$(CONFIG_SPI_SPIDEV)) += platform_mrfld_spidev.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_MPU3050_I2C)) += platform_mpu3050.o
|
||||
obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o
|
||||
obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o
|
||||
# I2C GPIO Expanders
|
||||
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_max7315.o
|
||||
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_pcal9555a.o
|
||||
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o
|
||||
# MISC Devices
|
||||
obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o
|
||||
obj-$(subst m,y,$(CONFIG_INTEL_MID_POWER_BUTTON)) += platform_mrfld_power_btn.o
|
||||
obj-$(subst m,y,$(CONFIG_RTC_DRV_CMOS)) += platform_mrfld_rtc.o
|
@@ -1,101 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_bcm43xx.c: bcm43xx platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2016 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/fixed.h>
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define WLAN_SFI_GPIO_IRQ_NAME "WLAN-interrupt"
|
||||
#define WLAN_SFI_GPIO_ENABLE_NAME "WLAN-enable"
|
||||
|
||||
#define WLAN_DEV_NAME "0000:00:01.3"
|
||||
|
||||
static struct regulator_consumer_supply bcm43xx_vmmc_supply = {
|
||||
.dev_name = WLAN_DEV_NAME,
|
||||
.supply = "vmmc",
|
||||
};
|
||||
|
||||
static struct regulator_init_data bcm43xx_vmmc_data = {
|
||||
.constraints = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &bcm43xx_vmmc_supply,
|
||||
};
|
||||
|
||||
static struct fixed_voltage_config bcm43xx_vmmc = {
|
||||
.supply_name = "bcm43xx-vmmc-regulator",
|
||||
/*
|
||||
* Announce 2.0V here to be compatible with SDIO specification. The
|
||||
* real voltage and signaling are still 1.8V.
|
||||
*/
|
||||
.microvolts = 2000000, /* 1.8V */
|
||||
.startup_delay = 250 * 1000, /* 250ms */
|
||||
.enabled_at_boot = 0, /* disabled at boot */
|
||||
.init_data = &bcm43xx_vmmc_data,
|
||||
};
|
||||
|
||||
static struct platform_device bcm43xx_vmmc_regulator = {
|
||||
.name = "reg-fixed-voltage",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dev = {
|
||||
.platform_data = &bcm43xx_vmmc,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table bcm43xx_vmmc_gpio_table = {
|
||||
.dev_id = "reg-fixed-voltage.0",
|
||||
.table = {
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, NULL, GPIO_ACTIVE_LOW),
|
||||
{}
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bcm43xx_regulator_register(void)
|
||||
{
|
||||
struct gpiod_lookup_table *table = &bcm43xx_vmmc_gpio_table;
|
||||
struct gpiod_lookup *lookup = table->table;
|
||||
int ret;
|
||||
|
||||
lookup[0].chip_hwnum = get_gpio_by_name(WLAN_SFI_GPIO_ENABLE_NAME);
|
||||
gpiod_add_lookup_table(table);
|
||||
|
||||
ret = platform_device_register(&bcm43xx_vmmc_regulator);
|
||||
if (ret) {
|
||||
pr_err("%s: vmmc regulator register failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init *bcm43xx_platform_data(void *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bcm43xx_regulator_register();
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
pr_info("Using generic wifi platform data\n");
|
||||
|
||||
/* For now it's empty */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct devs_id bcm43xx_clk_vmmc_dev_id __initconst = {
|
||||
.name = "bcm43xx_clk_vmmc",
|
||||
.type = SFI_DEV_TYPE_SD,
|
||||
.get_platform_data = &bcm43xx_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(bcm43xx_clk_vmmc_dev_id);
|
@@ -1,16 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_bma023.c: bma023 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
*/
|
||||
|
||||
#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);
|
@@ -1,101 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Bluetooth platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2017 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
struct bt_sfi_data {
|
||||
struct device *dev;
|
||||
const char *name;
|
||||
int (*setup)(struct bt_sfi_data *ddata);
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table tng_bt_sfi_gpio_table = {
|
||||
.dev_id = "hci_bcm",
|
||||
.table = {
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "device-wakeup", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "shutdown", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "host-wakeup", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
#define TNG_BT_SFI_GPIO_DEVICE_WAKEUP "bt_wakeup"
|
||||
#define TNG_BT_SFI_GPIO_SHUTDOWN "BT-reset"
|
||||
#define TNG_BT_SFI_GPIO_HOST_WAKEUP "bt_uart_enable"
|
||||
|
||||
static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata)
|
||||
{
|
||||
struct gpiod_lookup_table *table = &tng_bt_sfi_gpio_table;
|
||||
struct gpiod_lookup *lookup = table->table;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* Connected to /dev/ttyS0 */
|
||||
pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(4, 1));
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
ddata->dev = &pdev->dev;
|
||||
ddata->name = table->dev_id;
|
||||
|
||||
lookup[0].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_DEVICE_WAKEUP);
|
||||
lookup[1].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_SHUTDOWN);
|
||||
lookup[2].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_HOST_WAKEUP);
|
||||
|
||||
gpiod_add_lookup_table(table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bt_sfi_data tng_bt_sfi_data __initdata = {
|
||||
.setup = tng_bt_sfi_setup,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id bt_sfi_cpu_ids[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &tng_bt_sfi_data),
|
||||
{}
|
||||
};
|
||||
|
||||
static int __init bt_sfi_init(void)
|
||||
{
|
||||
struct platform_device_info info;
|
||||
struct platform_device *pdev;
|
||||
const struct x86_cpu_id *id;
|
||||
struct bt_sfi_data *ddata;
|
||||
int ret;
|
||||
|
||||
id = x86_match_cpu(bt_sfi_cpu_ids);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
ddata = (struct bt_sfi_data *)id->driver_data;
|
||||
if (!ddata)
|
||||
return -ENODEV;
|
||||
|
||||
ret = ddata->setup(ddata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.fwnode = ddata->dev->fwnode;
|
||||
info.parent = ddata->dev;
|
||||
info.name = ddata->name;
|
||||
info.id = PLATFORM_DEVID_NONE;
|
||||
|
||||
pdev = platform_device_register_full(&info);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
dev_info(ddata->dev, "Registered Bluetooth device: %s\n", ddata->name);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(bt_sfi_init);
|
@@ -1,39 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_emc1403.c: emc1403 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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 < 0)
|
||||
return NULL;
|
||||
if (intr2nd < 0)
|
||||
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);
|
@@ -1,81 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_gpio_keys.c: gpio_keys platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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_MUTE, -1, 1, "mute_enable", EV_KEY, 0, 20},
|
||||
{KEY_VOLUMEUP, -1, 1, "volume_up", EV_KEY, 0, 20},
|
||||
{KEY_VOLUMEDOWN, -1, 1, "volume_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, good = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gpio_button); 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 < 0)
|
||||
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);
|
@@ -1,37 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_lis331.c: lis331 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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 < 0)
|
||||
return NULL;
|
||||
if (intr2nd < 0)
|
||||
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);
|
@@ -1,77 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_max7315.c: max7315 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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++) {
|
||||
snprintf(base_pin_name, sizeof(base_pin_name),
|
||||
"max7315_%d_base", nr);
|
||||
snprintf(intr_pin_name, sizeof(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 < 0)
|
||||
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);
|
@@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_mpu3050.c: mpu3050 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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 < 0)
|
||||
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);
|
@@ -1,39 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Intel Merrifield FLIS platform device initialization file
|
||||
*
|
||||
* Copyright (C) 2016, Intel Corporation
|
||||
*
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define FLIS_BASE_ADDR 0xff0c0000
|
||||
#define FLIS_LENGTH 0x8000
|
||||
|
||||
static struct resource mrfld_pinctrl_mmio_resource = {
|
||||
.start = FLIS_BASE_ADDR,
|
||||
.end = FLIS_BASE_ADDR + FLIS_LENGTH - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device mrfld_pinctrl_device = {
|
||||
.name = "pinctrl-merrifield",
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.resource = &mrfld_pinctrl_mmio_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static int __init mrfld_pinctrl_init(void)
|
||||
{
|
||||
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
|
||||
return platform_device_register(&mrfld_pinctrl_device);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
arch_initcall(mrfld_pinctrl_init);
|
@@ -1,78 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Intel Merrifield power button support
|
||||
*
|
||||
* (C) Copyright 2017 Intel Corporation
|
||||
*
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
|
||||
static struct resource mrfld_power_btn_resources[] = {
|
||||
{
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mrfld_power_btn_dev = {
|
||||
.name = "msic_power_btn",
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.num_resources = ARRAY_SIZE(mrfld_power_btn_resources),
|
||||
.resource = mrfld_power_btn_resources,
|
||||
};
|
||||
|
||||
static int mrfld_power_btn_scu_status_change(struct notifier_block *nb,
|
||||
unsigned long code, void *data)
|
||||
{
|
||||
if (code == SCU_DOWN) {
|
||||
platform_device_unregister(&mrfld_power_btn_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return platform_device_register(&mrfld_power_btn_dev);
|
||||
}
|
||||
|
||||
static struct notifier_block mrfld_power_btn_scu_notifier = {
|
||||
.notifier_call = mrfld_power_btn_scu_status_change,
|
||||
};
|
||||
|
||||
static int __init register_mrfld_power_btn(void)
|
||||
{
|
||||
if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* We need to be sure that the SCU IPC is ready before
|
||||
* PMIC power button device can be registered:
|
||||
*/
|
||||
intel_scu_notifier_add(&mrfld_power_btn_scu_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(register_mrfld_power_btn);
|
||||
|
||||
static void __init *mrfld_power_btn_platform_data(void *info)
|
||||
{
|
||||
struct resource *res = mrfld_power_btn_resources;
|
||||
struct sfi_device_table_entry *pentry = info;
|
||||
|
||||
res->start = res->end = pentry->irq;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct devs_id mrfld_power_btn_dev_id __initconst = {
|
||||
.name = "bcove_power_btn",
|
||||
.type = SFI_DEV_TYPE_IPC,
|
||||
.delay = 1,
|
||||
.msic = 1,
|
||||
.get_platform_data = &mrfld_power_btn_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(mrfld_power_btn_dev_id);
|
@@ -1,44 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Intel Merrifield legacy RTC initialization file
|
||||
*
|
||||
* (C) Copyright 2017 Intel Corporation
|
||||
*
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/hw_irq.h>
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
static int __init mrfld_legacy_rtc_alloc_irq(void)
|
||||
{
|
||||
struct irq_alloc_info info;
|
||||
int ret;
|
||||
|
||||
if (!x86_platform.legacy.rtc)
|
||||
return -ENODEV;
|
||||
|
||||
ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 1, 0);
|
||||
ret = mp_map_gsi_to_irq(RTC_IRQ, IOAPIC_MAP_ALLOC, &info);
|
||||
if (ret < 0) {
|
||||
pr_info("Failed to allocate RTC interrupt. Disabling RTC\n");
|
||||
x86_platform.legacy.rtc = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init mrfld_legacy_rtc_init(void)
|
||||
{
|
||||
if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
|
||||
return -ENODEV;
|
||||
|
||||
return mrfld_legacy_rtc_alloc_irq();
|
||||
}
|
||||
arch_initcall(mrfld_legacy_rtc_init);
|
@@ -1,43 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SDHCI platform data initilisation file
|
||||
*
|
||||
* (C) Copyright 2016 Intel Corporation
|
||||
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <linux/mmc/sdhci-pci-data.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define INTEL_MRFLD_SD 2
|
||||
#define INTEL_MRFLD_SD_CD_GPIO 77
|
||||
|
||||
static struct sdhci_pci_data mrfld_sdhci_pci_data = {
|
||||
.rst_n_gpio = -EINVAL,
|
||||
.cd_gpio = INTEL_MRFLD_SD_CD_GPIO,
|
||||
};
|
||||
|
||||
static struct sdhci_pci_data *
|
||||
mrfld_sdhci_pci_get_data(struct pci_dev *pdev, int slotno)
|
||||
{
|
||||
unsigned int func = PCI_FUNC(pdev->devfn);
|
||||
|
||||
if (func == INTEL_MRFLD_SD)
|
||||
return &mrfld_sdhci_pci_data;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init mrfld_sd_init(void)
|
||||
{
|
||||
if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
|
||||
return -ENODEV;
|
||||
|
||||
sdhci_pci_get_data = mrfld_sdhci_pci_get_data;
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(mrfld_sd_init);
|
@@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* spidev platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2014, 2016 Intel Corporation
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Dan O'Donovan <dan@emutex.com>
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/spi/pxa2xx_spi.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define MRFLD_SPI_DEFAULT_DMA_BURST 8
|
||||
#define MRFLD_SPI_DEFAULT_TIMEOUT 500
|
||||
|
||||
/* GPIO pin for spidev chipselect */
|
||||
#define MRFLD_SPIDEV_GPIO_CS 111
|
||||
|
||||
static struct pxa2xx_spi_chip spidev_spi_chip = {
|
||||
.dma_burst_size = MRFLD_SPI_DEFAULT_DMA_BURST,
|
||||
.timeout = MRFLD_SPI_DEFAULT_TIMEOUT,
|
||||
.gpio_cs = MRFLD_SPIDEV_GPIO_CS,
|
||||
};
|
||||
|
||||
static void __init *spidev_platform_data(void *info)
|
||||
{
|
||||
struct spi_board_info *spi_info = info;
|
||||
|
||||
if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
spi_info->mode = SPI_MODE_0;
|
||||
spi_info->controller_data = &spidev_spi_chip;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct devs_id spidev_dev_id __initconst = {
|
||||
.name = "spidev",
|
||||
.type = SFI_DEV_TYPE_SPI,
|
||||
.delay = 0,
|
||||
.get_platform_data = &spidev_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(spidev_dev_id);
|
@@ -1,83 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic.c: MSIC platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* platform_msic.h: MSIC platform data header file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
#ifndef _PLATFORM_MSIC_H_
|
||||
#define _PLATFORM_MSIC_H_
|
||||
|
||||
extern struct intel_msic_platform_data msic_pdata;
|
||||
|
||||
void *msic_generic_platform_data(void *info, enum intel_msic_block block);
|
||||
|
||||
#endif
|
@@ -1,42 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_audio.c: MSIC audio platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_audio_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_audio_dev_id);
|
@@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_battery.c: MSIC battery platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_battery_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_battery_dev_id);
|
@@ -1,43 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_gpio.c: MSIC GPIO platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_gpio_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_gpio_dev_id);
|
@@ -1,44 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_ocd.c: MSIC OCD platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_ocd_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_ocd_dev_id);
|
@@ -1,31 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_power_btn.c: MSIC power btn platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_power_btn_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_power_btn_dev_id);
|
@@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_msic_thermal.c: msic_thermal platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
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,
|
||||
.msic = 1,
|
||||
.get_platform_data = &msic_thermal_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(msic_thermal_dev_id);
|
@@ -1,95 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PCAL9555a platform data initialization file
|
||||
*
|
||||
* Copyright (C) 2016, Intel Corporation
|
||||
*
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Dan O'Donovan <dan@emutex.com>
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_data/pca953x.h>
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define PCAL9555A_NUM 4
|
||||
|
||||
static struct pca953x_platform_data pcal9555a_pdata[PCAL9555A_NUM];
|
||||
static int nr;
|
||||
|
||||
static void __init *pcal9555a_platform_data(void *info)
|
||||
{
|
||||
struct i2c_board_info *i2c_info = info;
|
||||
char *type = i2c_info->type;
|
||||
struct pca953x_platform_data *pcal9555a;
|
||||
char base_pin_name[SFI_NAME_LEN + 1];
|
||||
char intr_pin_name[SFI_NAME_LEN + 1];
|
||||
int gpio_base, intr;
|
||||
|
||||
snprintf(base_pin_name, sizeof(base_pin_name), "%s_base", type);
|
||||
snprintf(intr_pin_name, sizeof(intr_pin_name), "%s_int", type);
|
||||
|
||||
gpio_base = get_gpio_by_name(base_pin_name);
|
||||
intr = get_gpio_by_name(intr_pin_name);
|
||||
|
||||
/* Check if the SFI record valid */
|
||||
if (gpio_base == -1)
|
||||
return NULL;
|
||||
|
||||
if (nr >= PCAL9555A_NUM) {
|
||||
pr_err("%s: Too many instances, only %d supported\n", __func__,
|
||||
PCAL9555A_NUM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcal9555a = &pcal9555a_pdata[nr++];
|
||||
pcal9555a->gpio_base = gpio_base;
|
||||
|
||||
if (intr >= 0) {
|
||||
i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
|
||||
pcal9555a->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
|
||||
} else {
|
||||
i2c_info->irq = -1;
|
||||
pcal9555a->irq_base = -1;
|
||||
}
|
||||
|
||||
strcpy(type, "pcal9555a");
|
||||
return pcal9555a;
|
||||
}
|
||||
|
||||
static const struct devs_id pcal9555a_1_dev_id __initconst = {
|
||||
.name = "pcal9555a-1",
|
||||
.type = SFI_DEV_TYPE_I2C,
|
||||
.delay = 1,
|
||||
.get_platform_data = &pcal9555a_platform_data,
|
||||
};
|
||||
|
||||
static const struct devs_id pcal9555a_2_dev_id __initconst = {
|
||||
.name = "pcal9555a-2",
|
||||
.type = SFI_DEV_TYPE_I2C,
|
||||
.delay = 1,
|
||||
.get_platform_data = &pcal9555a_platform_data,
|
||||
};
|
||||
|
||||
static const struct devs_id pcal9555a_3_dev_id __initconst = {
|
||||
.name = "pcal9555a-3",
|
||||
.type = SFI_DEV_TYPE_I2C,
|
||||
.delay = 1,
|
||||
.get_platform_data = &pcal9555a_platform_data,
|
||||
};
|
||||
|
||||
static const struct devs_id pcal9555a_4_dev_id __initconst = {
|
||||
.name = "pcal9555a-4",
|
||||
.type = SFI_DEV_TYPE_I2C,
|
||||
.delay = 1,
|
||||
.get_platform_data = &pcal9555a_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(pcal9555a_1_dev_id);
|
||||
sfi_device(pcal9555a_2_dev_id);
|
||||
sfi_device(pcal9555a_3_dev_id);
|
||||
sfi_device(pcal9555a_4_dev_id);
|
@@ -1,42 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_tc35876x.c: tc35876x platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
static struct gpiod_lookup_table tc35876x_gpio_table = {
|
||||
.dev_id = "i2c_disp_brig",
|
||||
.table = {
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "bridge-reset", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "bl-en", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("0000:00:0c.0", -1, "vadd", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
/*tc35876x DSI_LVDS bridge chip and panel platform data*/
|
||||
static void *tc35876x_platform_data(void *data)
|
||||
{
|
||||
struct gpiod_lookup_table *table = &tc35876x_gpio_table;
|
||||
struct gpiod_lookup *lookup = table->table;
|
||||
|
||||
lookup[0].chip_hwnum = get_gpio_by_name("LCMB_RXEN");
|
||||
lookup[1].chip_hwnum = get_gpio_by_name("6S6P_BL_EN");
|
||||
lookup[2].chip_hwnum = get_gpio_by_name("EN_VREG_LCD_V3P3");
|
||||
gpiod_add_lookup_table(table);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
@@ -1,53 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* platform_tca6416.c: tca6416 platform data initialization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#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 < 0)
|
||||
return NULL;
|
||||
tca6416.gpio_base = gpio_base;
|
||||
if (intr >= 0) {
|
||||
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);
|
@@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* intel-mid.c: Intel MID platform setup code
|
||||
* Intel MID platform setup code
|
||||
*
|
||||
* (C) Copyright 2008, 2012 Intel Corporation
|
||||
* (C) Copyright 2008, 2012, 2021 Intel Corporation
|
||||
* Author: Jacob Pan (jacob.jun.pan@intel.com)
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/notifier.h>
|
||||
@@ -25,38 +24,13 @@
|
||||
#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);
|
||||
#define IPCMSG_COLD_OFF 0x80 /* Only for Tangier */
|
||||
#define IPCMSG_COLD_RESET 0xF1
|
||||
|
||||
static void intel_mid_power_off(void)
|
||||
{
|
||||
@@ -64,69 +38,32 @@ static void intel_mid_power_off(void)
|
||||
intel_mid_pwr_power_off();
|
||||
|
||||
/* Only for Tangier, the rest will ignore this command */
|
||||
intel_scu_ipc_simple_command(IPCMSG_COLD_OFF, 1);
|
||||
intel_scu_ipc_dev_simple_command(NULL, IPCMSG_COLD_OFF, 1);
|
||||
};
|
||||
|
||||
static void intel_mid_reboot(void)
|
||||
{
|
||||
intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
|
||||
}
|
||||
|
||||
static void __init intel_mid_setup_bp_timer(void)
|
||||
{
|
||||
apbt_time_init();
|
||||
setup_boot_APIC_clock();
|
||||
intel_scu_ipc_dev_simple_command(NULL, IPCMSG_COLD_RESET, 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:
|
||||
/* Use apbt and local apic */
|
||||
x86_init.timers.setup_percpu_clockev = intel_mid_setup_bp_timer;
|
||||
x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
|
||||
return;
|
||||
default:
|
||||
if (!boot_cpu_has(X86_FEATURE_ARAT))
|
||||
break;
|
||||
/* Lapic only, no apbt */
|
||||
x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
|
||||
x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
|
||||
return;
|
||||
}
|
||||
|
||||
x86_init.timers.setup_percpu_clockev = apbt_time_init;
|
||||
/* Lapic only, no apbt */
|
||||
x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
|
||||
x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
|
||||
}
|
||||
|
||||
static void intel_mid_arch_setup(void)
|
||||
{
|
||||
if (boot_cpu_data.x86 != 6) {
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (boot_cpu_data.x86_model) {
|
||||
case 0x35:
|
||||
__intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_CLOVERVIEW;
|
||||
break;
|
||||
case 0x3C:
|
||||
case 0x4A:
|
||||
__intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_TANGIER;
|
||||
x86_platform.legacy.rtc = 1;
|
||||
break;
|
||||
case 0x27:
|
||||
default:
|
||||
__intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* Intel MID platforms are using explicitly defined regulators.
|
||||
*
|
||||
@@ -159,14 +96,11 @@ void __init x86_intel_mid_early_setup(void)
|
||||
|
||||
x86_init.timers.timer_init = intel_mid_time_init;
|
||||
x86_init.timers.setup_percpu_clockev = x86_init_noop;
|
||||
x86_init.timers.wallclock_init = intel_mid_rtc_init;
|
||||
|
||||
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.get_nmi_reason = intel_mid_get_nmi_reason;
|
||||
|
||||
x86_init.pci.arch_init = intel_mid_pci_init;
|
||||
@@ -188,25 +122,3 @@ void __init x86_intel_mid_early_setup(void)
|
||||
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);
|
||||
|
@@ -1,173 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* intel_mid_vrtc.c: Driver for virtual RTC device on Intel MID platform
|
||||
*
|
||||
* (C) Copyright 2009 Intel Corporation
|
||||
*
|
||||
* Note:
|
||||
* VRTC is emulated by system controller firmware, the real HW
|
||||
* RTC is located in the PMIC device. SCU FW shadows PMIC RTC
|
||||
* in a memory mapped IO space that is visible to the host IA
|
||||
* processor.
|
||||
*
|
||||
* This driver is based on RTC CMOS driver.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/intel_mid_vrtc.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
static unsigned char __iomem *vrtc_virt_base;
|
||||
|
||||
unsigned char vrtc_cmos_read(unsigned char reg)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
/* vRTC's registers range from 0x0 to 0xD */
|
||||
if (reg > 0xd || !vrtc_virt_base)
|
||||
return 0xff;
|
||||
|
||||
lock_cmos_prefix(reg);
|
||||
retval = __raw_readb(vrtc_virt_base + (reg << 2));
|
||||
lock_cmos_suffix(reg);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vrtc_cmos_read);
|
||||
|
||||
void vrtc_cmos_write(unsigned char val, unsigned char reg)
|
||||
{
|
||||
if (reg > 0xd || !vrtc_virt_base)
|
||||
return;
|
||||
|
||||
lock_cmos_prefix(reg);
|
||||
__raw_writeb(val, vrtc_virt_base + (reg << 2));
|
||||
lock_cmos_suffix(reg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vrtc_cmos_write);
|
||||
|
||||
void vrtc_get_time(struct timespec64 *now)
|
||||
{
|
||||
u8 sec, min, hour, mday, mon;
|
||||
unsigned long flags;
|
||||
u32 year;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
|
||||
while ((vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP))
|
||||
cpu_relax();
|
||||
|
||||
sec = vrtc_cmos_read(RTC_SECONDS);
|
||||
min = vrtc_cmos_read(RTC_MINUTES);
|
||||
hour = vrtc_cmos_read(RTC_HOURS);
|
||||
mday = vrtc_cmos_read(RTC_DAY_OF_MONTH);
|
||||
mon = vrtc_cmos_read(RTC_MONTH);
|
||||
year = vrtc_cmos_read(RTC_YEAR);
|
||||
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
/* vRTC YEAR reg contains the offset to 1972 */
|
||||
year += 1972;
|
||||
|
||||
pr_info("vRTC: sec: %d min: %d hour: %d day: %d "
|
||||
"mon: %d year: %d\n", sec, min, hour, mday, mon, year);
|
||||
|
||||
now->tv_sec = mktime64(year, mon, mday, hour, min, sec);
|
||||
now->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int vrtc_set_mmss(const struct timespec64 *now)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct rtc_time tm;
|
||||
int year;
|
||||
int retval = 0;
|
||||
|
||||
rtc_time64_to_tm(now->tv_sec, &tm);
|
||||
if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) {
|
||||
/*
|
||||
* tm.year is the number of years since 1900, and the
|
||||
* vrtc need the years since 1972.
|
||||
*/
|
||||
year = tm.tm_year - 72;
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
vrtc_cmos_write(year, RTC_YEAR);
|
||||
vrtc_cmos_write(tm.tm_mon, RTC_MONTH);
|
||||
vrtc_cmos_write(tm.tm_mday, RTC_DAY_OF_MONTH);
|
||||
vrtc_cmos_write(tm.tm_hour, RTC_HOURS);
|
||||
vrtc_cmos_write(tm.tm_min, RTC_MINUTES);
|
||||
vrtc_cmos_write(tm.tm_sec, RTC_SECONDS);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
} else {
|
||||
pr_err("%s: Invalid vRTC value: write of %llx to vRTC failed\n",
|
||||
__func__, (s64)now->tv_sec);
|
||||
retval = -EINVAL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void __init intel_mid_rtc_init(void)
|
||||
{
|
||||
unsigned long vrtc_paddr;
|
||||
|
||||
sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
|
||||
|
||||
vrtc_paddr = sfi_mrtc_array[0].phys_addr;
|
||||
if (!sfi_mrtc_num || !vrtc_paddr)
|
||||
return;
|
||||
|
||||
vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC,
|
||||
vrtc_paddr);
|
||||
x86_platform.get_wallclock = vrtc_get_time;
|
||||
x86_platform.set_wallclock = vrtc_set_mmss;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Moorestown platform has a memory mapped virtual RTC device that emulates
|
||||
* the programming interface of the RTC.
|
||||
*/
|
||||
|
||||
static struct resource vrtc_resources[] = {
|
||||
[0] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device vrtc_device = {
|
||||
.name = "rtc_mrst",
|
||||
.id = -1,
|
||||
.resource = vrtc_resources,
|
||||
.num_resources = ARRAY_SIZE(vrtc_resources),
|
||||
};
|
||||
|
||||
/* Register the RTC device if appropriate */
|
||||
static int __init intel_mid_device_create(void)
|
||||
{
|
||||
/* No Moorestown, no device */
|
||||
if (!intel_mid_identify_cpu())
|
||||
return -ENODEV;
|
||||
/* No timer, no device */
|
||||
if (!sfi_mrtc_num)
|
||||
return -ENODEV;
|
||||
|
||||
/* iomem resource */
|
||||
vrtc_resources[0].start = sfi_mrtc_array[0].phys_addr;
|
||||
vrtc_resources[0].end = sfi_mrtc_array[0].phys_addr +
|
||||
MRST_VRTC_MAP_SZ;
|
||||
/* irq resource */
|
||||
vrtc_resources[1].start = sfi_mrtc_array[0].irq;
|
||||
vrtc_resources[1].end = sfi_mrtc_array[0].irq;
|
||||
|
||||
return platform_device_register(&vrtc_device);
|
||||
}
|
||||
device_initcall(intel_mid_device_create);
|
@@ -1,543 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* intel_mid_sfi.c: Intel MID SFI initialization code
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/blkdev.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>
|
||||
|
||||
#define SFI_SIG_OEM0 "OEM0"
|
||||
#define MAX_IPCDEVS 24
|
||||
#define MAX_SCU_SPI 24
|
||||
#define MAX_SCU_I2C 24
|
||||
|
||||
static struct platform_device *ipc_devs[MAX_IPCDEVS];
|
||||
static struct spi_board_info *spi_devs[MAX_SCU_SPI];
|
||||
static struct i2c_board_info *i2c_devs[MAX_SCU_I2C];
|
||||
static struct sfi_gpio_table_entry *gpio_table;
|
||||
static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
|
||||
static int ipc_next_dev;
|
||||
static int spi_next_dev;
|
||||
static int i2c_next_dev;
|
||||
static int i2c_bus[MAX_SCU_I2C];
|
||||
static int gpio_num_entry;
|
||||
static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
|
||||
int sfi_mrtc_num;
|
||||
int sfi_mtimer_num;
|
||||
|
||||
struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
|
||||
EXPORT_SYMBOL_GPL(sfi_mrtc_array);
|
||||
|
||||
struct blocking_notifier_head intel_scu_notifier =
|
||||
BLOCKING_NOTIFIER_INIT(intel_scu_notifier);
|
||||
EXPORT_SYMBOL_GPL(intel_scu_notifier);
|
||||
|
||||
#define intel_mid_sfi_get_pdata(dev, priv) \
|
||||
((dev)->get_platform_data ? (dev)->get_platform_data(priv) : NULL)
|
||||
|
||||
/* parse all the mtimer info to a static mtimer array */
|
||||
int __init sfi_parse_mtmr(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_timer_table_entry *pentry;
|
||||
struct mpc_intsrc mp_irq;
|
||||
int totallen;
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
if (!sfi_mtimer_num) {
|
||||
sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
|
||||
struct sfi_timer_table_entry);
|
||||
pentry = (struct sfi_timer_table_entry *) sb->pentry;
|
||||
totallen = sfi_mtimer_num * sizeof(*pentry);
|
||||
memcpy(sfi_mtimer_array, pentry, totallen);
|
||||
}
|
||||
|
||||
pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num);
|
||||
pentry = sfi_mtimer_array;
|
||||
for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
|
||||
pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz, irq = %d\n",
|
||||
totallen, (u32)pentry->phys_addr,
|
||||
pentry->freq_hz, pentry->irq);
|
||||
mp_irq.type = MP_INTSRC;
|
||||
mp_irq.irqtype = mp_INT;
|
||||
mp_irq.irqflag = MP_IRQTRIG_EDGE | MP_IRQPOL_ACTIVE_HIGH;
|
||||
mp_irq.srcbus = MP_BUS_ISA;
|
||||
mp_irq.srcbusirq = pentry->irq; /* IRQ */
|
||||
mp_irq.dstapic = MP_APIC_ALL;
|
||||
mp_irq.dstirq = pentry->irq;
|
||||
mp_save_irq(&mp_irq);
|
||||
mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
|
||||
{
|
||||
int i;
|
||||
if (hint < sfi_mtimer_num) {
|
||||
if (!sfi_mtimer_usage[hint]) {
|
||||
pr_debug("hint taken for timer %d irq %d\n",
|
||||
hint, sfi_mtimer_array[hint].irq);
|
||||
sfi_mtimer_usage[hint] = 1;
|
||||
return &sfi_mtimer_array[hint];
|
||||
}
|
||||
}
|
||||
/* take the first timer available */
|
||||
for (i = 0; i < sfi_mtimer_num;) {
|
||||
if (!sfi_mtimer_usage[i]) {
|
||||
sfi_mtimer_usage[i] = 1;
|
||||
return &sfi_mtimer_array[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sfi_mtimer_num;) {
|
||||
if (mtmr->irq == sfi_mtimer_array[i].irq) {
|
||||
sfi_mtimer_usage[i] = 0;
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse all the mrtc info to a global mrtc array */
|
||||
int __init sfi_parse_mrtc(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_rtc_table_entry *pentry;
|
||||
struct mpc_intsrc mp_irq;
|
||||
|
||||
int totallen;
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
if (!sfi_mrtc_num) {
|
||||
sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
|
||||
struct sfi_rtc_table_entry);
|
||||
pentry = (struct sfi_rtc_table_entry *)sb->pentry;
|
||||
totallen = sfi_mrtc_num * sizeof(*pentry);
|
||||
memcpy(sfi_mrtc_array, pentry, totallen);
|
||||
}
|
||||
|
||||
pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num);
|
||||
pentry = sfi_mrtc_array;
|
||||
for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
|
||||
pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n",
|
||||
totallen, (u32)pentry->phys_addr, pentry->irq);
|
||||
mp_irq.type = MP_INTSRC;
|
||||
mp_irq.irqtype = mp_INT;
|
||||
mp_irq.irqflag = MP_IRQTRIG_LEVEL | MP_IRQPOL_ACTIVE_LOW;
|
||||
mp_irq.srcbus = MP_BUS_ISA;
|
||||
mp_irq.srcbusirq = pentry->irq; /* IRQ */
|
||||
mp_irq.dstapic = MP_APIC_ALL;
|
||||
mp_irq.dstirq = pentry->irq;
|
||||
mp_save_irq(&mp_irq);
|
||||
mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parsing GPIO table first, since the DEVS table will need this table
|
||||
* to map the pin name to the actual pin.
|
||||
*/
|
||||
static int __init sfi_parse_gpio(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_gpio_table_entry *pentry;
|
||||
int num, i;
|
||||
|
||||
if (gpio_table)
|
||||
return 0;
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
|
||||
pentry = (struct sfi_gpio_table_entry *)sb->pentry;
|
||||
|
||||
gpio_table = kmemdup(pentry, num * sizeof(*pentry), GFP_KERNEL);
|
||||
if (!gpio_table)
|
||||
return -1;
|
||||
gpio_num_entry = num;
|
||||
|
||||
pr_debug("GPIO pin info:\n");
|
||||
for (i = 0; i < num; i++, pentry++)
|
||||
pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s,"
|
||||
" pin = %d\n", i,
|
||||
pentry->controller_name,
|
||||
pentry->pin_name,
|
||||
pentry->pin_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_gpio_by_name(const char *name)
|
||||
{
|
||||
struct sfi_gpio_table_entry *pentry = gpio_table;
|
||||
int i;
|
||||
|
||||
if (!pentry)
|
||||
return -1;
|
||||
for (i = 0; i < gpio_num_entry; i++, pentry++) {
|
||||
if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN))
|
||||
return pentry->pin_no;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __init intel_scu_ipc_device_register(struct platform_device *pdev)
|
||||
{
|
||||
if (ipc_next_dev == MAX_IPCDEVS)
|
||||
pr_err("too many SCU IPC devices");
|
||||
else
|
||||
ipc_devs[ipc_next_dev++] = pdev;
|
||||
}
|
||||
|
||||
static void __init intel_scu_spi_device_register(struct spi_board_info *sdev)
|
||||
{
|
||||
struct spi_board_info *new_dev;
|
||||
|
||||
if (spi_next_dev == MAX_SCU_SPI) {
|
||||
pr_err("too many SCU SPI devices");
|
||||
return;
|
||||
}
|
||||
|
||||
new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL);
|
||||
if (!new_dev) {
|
||||
pr_err("failed to alloc mem for delayed spi dev %s\n",
|
||||
sdev->modalias);
|
||||
return;
|
||||
}
|
||||
*new_dev = *sdev;
|
||||
|
||||
spi_devs[spi_next_dev++] = new_dev;
|
||||
}
|
||||
|
||||
static void __init intel_scu_i2c_device_register(int bus,
|
||||
struct i2c_board_info *idev)
|
||||
{
|
||||
struct i2c_board_info *new_dev;
|
||||
|
||||
if (i2c_next_dev == MAX_SCU_I2C) {
|
||||
pr_err("too many SCU I2C devices");
|
||||
return;
|
||||
}
|
||||
|
||||
new_dev = kzalloc(sizeof(*idev), GFP_KERNEL);
|
||||
if (!new_dev) {
|
||||
pr_err("failed to alloc mem for delayed i2c dev %s\n",
|
||||
idev->type);
|
||||
return;
|
||||
}
|
||||
*new_dev = *idev;
|
||||
|
||||
i2c_bus[i2c_next_dev] = bus;
|
||||
i2c_devs[i2c_next_dev++] = new_dev;
|
||||
}
|
||||
|
||||
/* Called by IPC driver */
|
||||
void intel_scu_devices_create(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ipc_next_dev; i++)
|
||||
platform_device_add(ipc_devs[i]);
|
||||
|
||||
for (i = 0; i < spi_next_dev; i++)
|
||||
spi_register_board_info(spi_devs[i], 1);
|
||||
|
||||
for (i = 0; i < i2c_next_dev; i++) {
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *client;
|
||||
|
||||
adapter = i2c_get_adapter(i2c_bus[i]);
|
||||
if (adapter) {
|
||||
client = i2c_new_client_device(adapter, i2c_devs[i]);
|
||||
if (IS_ERR(client))
|
||||
pr_err("can't create i2c device %s\n",
|
||||
i2c_devs[i]->type);
|
||||
} else
|
||||
i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
|
||||
}
|
||||
intel_scu_notifier_post(SCU_AVAILABLE, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_scu_devices_create);
|
||||
|
||||
/* Called by IPC driver */
|
||||
void intel_scu_devices_destroy(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
intel_scu_notifier_post(SCU_DOWN, NULL);
|
||||
|
||||
for (i = 0; i < ipc_next_dev; i++)
|
||||
platform_device_del(ipc_devs[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_scu_devices_destroy);
|
||||
|
||||
static void __init install_irq_resource(struct platform_device *pdev, int irq)
|
||||
{
|
||||
/* Single threaded */
|
||||
static struct resource res __initdata = {
|
||||
.name = "IRQ",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
};
|
||||
res.start = irq;
|
||||
platform_device_add_resources(pdev, &res, 1);
|
||||
}
|
||||
|
||||
static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry,
|
||||
struct devs_id *dev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
void *pdata = NULL;
|
||||
|
||||
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.
|
||||
*/
|
||||
pdata = intel_mid_sfi_get_pdata(dev, pentry);
|
||||
if (IS_ERR(pdata))
|
||||
return;
|
||||
|
||||
/*
|
||||
* On Medfield the platform device creation is handled by the MSIC
|
||||
* MFD driver so we don't need to do it here.
|
||||
*/
|
||||
if (dev->msic && 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;
|
||||
}
|
||||
install_irq_resource(pdev, pentry->irq);
|
||||
|
||||
pdev->dev.platform_data = pdata;
|
||||
if (dev->delay)
|
||||
intel_scu_ipc_device_register(pdev);
|
||||
else
|
||||
platform_device_add(pdev);
|
||||
}
|
||||
|
||||
static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry,
|
||||
struct devs_id *dev)
|
||||
{
|
||||
struct spi_board_info spi_info;
|
||||
void *pdata = NULL;
|
||||
|
||||
memset(&spi_info, 0, sizeof(spi_info));
|
||||
strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN);
|
||||
spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
|
||||
spi_info.bus_num = pentry->host_num;
|
||||
spi_info.chip_select = pentry->addr;
|
||||
spi_info.max_speed_hz = pentry->max_freq;
|
||||
pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n",
|
||||
spi_info.bus_num,
|
||||
spi_info.modalias,
|
||||
spi_info.irq,
|
||||
spi_info.max_speed_hz,
|
||||
spi_info.chip_select);
|
||||
|
||||
pdata = intel_mid_sfi_get_pdata(dev, &spi_info);
|
||||
if (IS_ERR(pdata))
|
||||
return;
|
||||
|
||||
spi_info.platform_data = pdata;
|
||||
if (dev->delay)
|
||||
intel_scu_spi_device_register(&spi_info);
|
||||
else
|
||||
spi_register_board_info(&spi_info, 1);
|
||||
}
|
||||
|
||||
static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry,
|
||||
struct devs_id *dev)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
void *pdata = NULL;
|
||||
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN);
|
||||
i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
|
||||
i2c_info.addr = pentry->addr;
|
||||
pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n",
|
||||
pentry->host_num,
|
||||
i2c_info.type,
|
||||
i2c_info.irq,
|
||||
i2c_info.addr);
|
||||
pdata = intel_mid_sfi_get_pdata(dev, &i2c_info);
|
||||
i2c_info.platform_data = pdata;
|
||||
if (IS_ERR(pdata))
|
||||
return;
|
||||
|
||||
if (dev->delay)
|
||||
intel_scu_i2c_device_register(pentry->host_num, &i2c_info);
|
||||
else
|
||||
i2c_register_board_info(pentry->host_num, &i2c_info, 1);
|
||||
}
|
||||
|
||||
static void __init sfi_handle_sd_dev(struct sfi_device_table_entry *pentry,
|
||||
struct devs_id *dev)
|
||||
{
|
||||
struct mid_sd_board_info sd_info;
|
||||
void *pdata;
|
||||
|
||||
memset(&sd_info, 0, sizeof(sd_info));
|
||||
strncpy(sd_info.name, pentry->name, SFI_NAME_LEN);
|
||||
sd_info.bus_num = pentry->host_num;
|
||||
sd_info.max_clk = pentry->max_freq;
|
||||
sd_info.addr = pentry->addr;
|
||||
pr_debug("SD bus = %d, name = %16.16s, max_clk = %d, addr = 0x%x\n",
|
||||
sd_info.bus_num,
|
||||
sd_info.name,
|
||||
sd_info.max_clk,
|
||||
sd_info.addr);
|
||||
pdata = intel_mid_sfi_get_pdata(dev, &sd_info);
|
||||
if (IS_ERR(pdata))
|
||||
return;
|
||||
|
||||
/* Nothing we can do with this for now */
|
||||
sd_info.platform_data = pdata;
|
||||
|
||||
pr_debug("Successfully registered %16.16s", sd_info.name);
|
||||
}
|
||||
|
||||
extern struct devs_id *const __x86_intel_mid_dev_start[],
|
||||
*const __x86_intel_mid_dev_end[];
|
||||
|
||||
static struct devs_id __init *get_device_id(u8 type, char *name)
|
||||
{
|
||||
struct devs_id *const *dev_table;
|
||||
|
||||
for (dev_table = __x86_intel_mid_dev_start;
|
||||
dev_table < __x86_intel_mid_dev_end; dev_table++) {
|
||||
struct devs_id *dev = *dev_table;
|
||||
if (dev->type == type &&
|
||||
!strncmp(dev->name, name, SFI_NAME_LEN)) {
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init sfi_parse_devs(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_device_table_entry *pentry;
|
||||
struct devs_id *dev = NULL;
|
||||
int num, i, ret;
|
||||
int polarity;
|
||||
struct irq_alloc_info info;
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry);
|
||||
pentry = (struct sfi_device_table_entry *)sb->pentry;
|
||||
|
||||
for (i = 0; i < num; i++, pentry++) {
|
||||
int irq = pentry->irq;
|
||||
|
||||
if (irq != (u8)0xff) { /* native RTE case */
|
||||
/* these SPI2 devices are not exposed to system as PCI
|
||||
* devices, but they have separate RTE entry in IOAPIC
|
||||
* so we have to enable them one by one here
|
||||
*/
|
||||
if (intel_mid_identify_cpu() ==
|
||||
INTEL_MID_CPU_CHIP_TANGIER) {
|
||||
if (!strncmp(pentry->name, "r69001-ts-i2c", 13))
|
||||
/* active low */
|
||||
polarity = 1;
|
||||
else if (!strncmp(pentry->name,
|
||||
"synaptics_3202", 14))
|
||||
/* active low */
|
||||
polarity = 1;
|
||||
else if (irq == 41)
|
||||
/* fast_int_1 */
|
||||
polarity = 1;
|
||||
else
|
||||
/* active high */
|
||||
polarity = 0;
|
||||
} else {
|
||||
/* PNW and CLV go with active low */
|
||||
polarity = 1;
|
||||
}
|
||||
|
||||
ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 1, polarity);
|
||||
ret = mp_map_gsi_to_irq(irq, IOAPIC_MAP_ALLOC, &info);
|
||||
WARN_ON(ret < 0);
|
||||
}
|
||||
|
||||
dev = get_device_id(pentry->type, pentry->name);
|
||||
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
switch (pentry->type) {
|
||||
case SFI_DEV_TYPE_IPC:
|
||||
sfi_handle_ipc_dev(pentry, dev);
|
||||
break;
|
||||
case SFI_DEV_TYPE_SPI:
|
||||
sfi_handle_spi_dev(pentry, dev);
|
||||
break;
|
||||
case SFI_DEV_TYPE_I2C:
|
||||
sfi_handle_i2c_dev(pentry, dev);
|
||||
break;
|
||||
case SFI_DEV_TYPE_SD:
|
||||
sfi_handle_sd_dev(pentry, dev);
|
||||
break;
|
||||
case SFI_DEV_TYPE_UART:
|
||||
case SFI_DEV_TYPE_HSI:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init intel_mid_platform_init(void)
|
||||
{
|
||||
sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio);
|
||||
sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(intel_mid_platform_init);
|
@@ -1,2 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_SFI) += sfi.o
|
@@ -1,100 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* sfi.c - x86 architecture SFI support.
|
||||
*
|
||||
* Copyright (c) 2009, Intel Corporation.
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "SFI"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/irqdomain.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/apic.h>
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
|
||||
|
||||
/* All CPUs enumerated by SFI must be present and enabled */
|
||||
static void __init mp_sfi_register_lapic(u8 id)
|
||||
{
|
||||
if (MAX_LOCAL_APIC - id <= 0) {
|
||||
pr_warn("Processor #%d invalid (max %d)\n", id, MAX_LOCAL_APIC);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("registering lapic[%d]\n", id);
|
||||
|
||||
generic_processor_info(id, GET_APIC_VERSION(apic_read(APIC_LVR)));
|
||||
}
|
||||
|
||||
static int __init sfi_parse_cpus(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_cpu_table_entry *pentry;
|
||||
int i;
|
||||
int cpu_num;
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
cpu_num = SFI_GET_NUM_ENTRIES(sb, struct sfi_cpu_table_entry);
|
||||
pentry = (struct sfi_cpu_table_entry *)sb->pentry;
|
||||
|
||||
for (i = 0; i < cpu_num; i++) {
|
||||
mp_sfi_register_lapic(pentry->apic_id);
|
||||
pentry++;
|
||||
}
|
||||
|
||||
smp_found_config = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_X86_LOCAL_APIC */
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
|
||||
static int __init sfi_parse_ioapic(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_apic_table_entry *pentry;
|
||||
int i, num;
|
||||
struct ioapic_domain_cfg cfg = {
|
||||
.type = IOAPIC_DOMAIN_STRICT,
|
||||
.ops = &mp_ioapic_irqdomain_ops,
|
||||
};
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
num = SFI_GET_NUM_ENTRIES(sb, struct sfi_apic_table_entry);
|
||||
pentry = (struct sfi_apic_table_entry *)sb->pentry;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
mp_register_ioapic(i, pentry->phys_addr, gsi_top, &cfg);
|
||||
pentry++;
|
||||
}
|
||||
|
||||
WARN(pic_mode, KERN_WARNING
|
||||
"SFI: pic_mod shouldn't be 1 when IOAPIC table is present\n");
|
||||
pic_mode = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_X86_IO_APIC */
|
||||
|
||||
/*
|
||||
* sfi_platform_init(): register lapics & io-apics
|
||||
*/
|
||||
int __init sfi_platform_init(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
register_lapic_address(sfi_lapic_addr);
|
||||
sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, sfi_parse_cpus);
|
||||
#endif
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
sfi_table_parse(SFI_SIG_APIC, NULL, NULL, sfi_parse_ioapic);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@@ -27,7 +27,7 @@ obj-y += idle/
|
||||
obj-y += char/ipmi/
|
||||
|
||||
obj-$(CONFIG_ACPI) += acpi/
|
||||
obj-$(CONFIG_SFI) += sfi/
|
||||
|
||||
# PnP must come after ACPI since it will eventually need to check if acpi
|
||||
# was used and do nothing if so
|
||||
obj-$(CONFIG_PNP) += pnp/
|
||||
|
@@ -62,16 +62,6 @@ config X86_ACPI_CPUFREQ_CPB
|
||||
By enabling this option the acpi_cpufreq driver provides the old
|
||||
entry in addition to the new boost ones, for compatibility reasons.
|
||||
|
||||
config X86_SFI_CPUFREQ
|
||||
tristate "SFI Performance-States driver"
|
||||
depends on X86_INTEL_MID && SFI
|
||||
help
|
||||
This adds a CPUFreq driver for some Silvermont based Intel Atom
|
||||
architectures like Z34xx and Z35xx which enumerate processor
|
||||
performance states through SFI.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config ELAN_CPUFREQ
|
||||
tristate "AMD Elan SC400 and SC410"
|
||||
depends on MELAN
|
||||
|
@@ -43,7 +43,6 @@ obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
|
||||
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
|
||||
obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o
|
||||
obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o
|
||||
obj-$(CONFIG_X86_SFI_CPUFREQ) += sfi-cpufreq.o
|
||||
|
||||
##################################################################################
|
||||
# ARM SoC drivers
|
||||
|
@@ -1,127 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SFI Performance States Driver
|
||||
*
|
||||
* Author: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
|
||||
* Author: Srinidhi Kasagar <srinidhi.kasagar@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
static struct sfi_freq_table_entry *sfi_cpufreq_array;
|
||||
static int num_freq_table_entries;
|
||||
|
||||
static int sfi_parse_freq(struct sfi_table_header *table)
|
||||
{
|
||||
struct sfi_table_simple *sb;
|
||||
struct sfi_freq_table_entry *pentry;
|
||||
int totallen;
|
||||
|
||||
sb = (struct sfi_table_simple *)table;
|
||||
num_freq_table_entries = SFI_GET_NUM_ENTRIES(sb,
|
||||
struct sfi_freq_table_entry);
|
||||
if (num_freq_table_entries <= 1) {
|
||||
pr_err("No p-states discovered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pentry = (struct sfi_freq_table_entry *)sb->pentry;
|
||||
totallen = num_freq_table_entries * sizeof(*pentry);
|
||||
|
||||
sfi_cpufreq_array = kmemdup(pentry, totallen, GFP_KERNEL);
|
||||
if (!sfi_cpufreq_array)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfi_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
|
||||
{
|
||||
unsigned int next_perf_state = 0; /* Index into perf table */
|
||||
u32 lo, hi;
|
||||
|
||||
next_perf_state = policy->freq_table[index].driver_data;
|
||||
|
||||
rdmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, &lo, &hi);
|
||||
lo = (lo & ~INTEL_PERF_CTL_MASK) |
|
||||
((u32) sfi_cpufreq_array[next_perf_state].ctrl_val &
|
||||
INTEL_PERF_CTL_MASK);
|
||||
wrmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, lo, hi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
|
||||
policy->cpuinfo.transition_latency = 100000; /* 100us */
|
||||
policy->freq_table = freq_table;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver sfi_cpufreq_driver = {
|
||||
.flags = CPUFREQ_CONST_LOOPS,
|
||||
.verify = cpufreq_generic_frequency_table_verify,
|
||||
.target_index = sfi_cpufreq_target,
|
||||
.init = sfi_cpufreq_cpu_init,
|
||||
.name = "sfi-cpufreq",
|
||||
.attr = cpufreq_generic_attr,
|
||||
};
|
||||
|
||||
static int __init sfi_cpufreq_init(void)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
/* parse the freq table from SFI */
|
||||
ret = sfi_table_parse(SFI_SIG_FREQ, NULL, NULL, sfi_parse_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
freq_table = kcalloc(num_freq_table_entries + 1, sizeof(*freq_table),
|
||||
GFP_KERNEL);
|
||||
if (!freq_table) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_array;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_freq_table_entries; i++) {
|
||||
freq_table[i].driver_data = i;
|
||||
freq_table[i].frequency = sfi_cpufreq_array[i].freq_mhz * 1000;
|
||||
}
|
||||
freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
ret = cpufreq_register_driver(&sfi_cpufreq_driver);
|
||||
if (ret)
|
||||
goto err_free_tbl;
|
||||
|
||||
return ret;
|
||||
|
||||
err_free_tbl:
|
||||
kfree(freq_table);
|
||||
err_free_array:
|
||||
kfree(sfi_cpufreq_array);
|
||||
return ret;
|
||||
}
|
||||
late_initcall(sfi_cpufreq_init);
|
||||
|
||||
static void __exit sfi_cpufreq_exit(void)
|
||||
{
|
||||
cpufreq_unregister_driver(&sfi_cpufreq_driver);
|
||||
kfree(freq_table);
|
||||
kfree(sfi_cpufreq_array);
|
||||
}
|
||||
module_exit(sfi_cpufreq_exit);
|
||||
|
||||
MODULE_AUTHOR("Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>");
|
||||
MODULE_DESCRIPTION("SFI Performance-States Driver");
|
||||
MODULE_LICENSE("GPL");
|
@@ -659,15 +659,6 @@ config MFD_INTEL_LPSS_PCI
|
||||
I2C, SPI and HS-UART starting from Intel Sunrisepoint (Intel Skylake
|
||||
PCH) in PCI mode.
|
||||
|
||||
config MFD_INTEL_MSIC
|
||||
bool "Intel MSIC"
|
||||
depends on INTEL_SCU
|
||||
select MFD_CORE
|
||||
help
|
||||
Select this option to enable access to Intel MSIC (Avatele
|
||||
Passage) chip. This chip embeds audio, battery, GPIO, etc.
|
||||
devices used in Intel Medfield platforms.
|
||||
|
||||
config MFD_INTEL_PMC_BXT
|
||||
tristate "Intel PMC Driver for Broxton"
|
||||
depends on X86
|
||||
|
@@ -214,7 +214,6 @@ obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o
|
||||
obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o
|
||||
obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o
|
||||
obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o
|
||||
obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
|
||||
obj-$(CONFIG_MFD_INTEL_PMC_BXT) += intel_pmc_bxt.o
|
||||
obj-$(CONFIG_MFD_INTEL_PMT) += intel_pmt.o
|
||||
obj-$(CONFIG_MFD_PALMAS) += palmas.o
|
||||
|
@@ -1,425 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for Intel MSIC
|
||||
*
|
||||
* Copyright (C) 2011, Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/intel_msic.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
|
||||
#define MSIC_VENDOR(id) ((id >> 6) & 3)
|
||||
#define MSIC_VERSION(id) (id & 0x3f)
|
||||
#define MSIC_MAJOR(id) ('A' + ((id >> 3) & 7))
|
||||
#define MSIC_MINOR(id) (id & 7)
|
||||
|
||||
/*
|
||||
* MSIC interrupt tree is readable from SRAM at INTEL_MSIC_IRQ_PHYS_BASE.
|
||||
* Since IRQ block starts from address 0x002 we need to subtract that from
|
||||
* the actual IRQ status register address.
|
||||
*/
|
||||
#define MSIC_IRQ_STATUS(x) (INTEL_MSIC_IRQ_PHYS_BASE + ((x) - 2))
|
||||
#define MSIC_IRQ_STATUS_ACCDET MSIC_IRQ_STATUS(INTEL_MSIC_ACCDET)
|
||||
|
||||
/*
|
||||
* The SCU hardware has limitation of 16 bytes per read/write buffer on
|
||||
* Medfield.
|
||||
*/
|
||||
#define SCU_IPC_RWBUF_LIMIT 16
|
||||
|
||||
/**
|
||||
* struct intel_msic - an MSIC MFD instance
|
||||
* @pdev: pointer to the platform device
|
||||
* @vendor: vendor ID
|
||||
* @version: chip version
|
||||
* @irq_base: base address of the mapped MSIC SRAM interrupt tree
|
||||
*/
|
||||
struct intel_msic {
|
||||
struct platform_device *pdev;
|
||||
unsigned vendor;
|
||||
unsigned version;
|
||||
void __iomem *irq_base;
|
||||
};
|
||||
|
||||
static const struct resource msic_touch_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_adc_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_battery_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_gpio_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_audio_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(0, "IRQ"),
|
||||
/*
|
||||
* We will pass IRQ_BASE to the driver now but this can be removed
|
||||
* when/if the driver starts to use intel_msic_irq_read().
|
||||
*/
|
||||
DEFINE_RES_MEM_NAMED(MSIC_IRQ_STATUS_ACCDET, 1, "IRQ_BASE"),
|
||||
};
|
||||
|
||||
static const struct resource msic_hdmi_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_thermal_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_power_btn_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
static const struct resource msic_ocd_resources[] = {
|
||||
DEFINE_RES_IRQ(0),
|
||||
};
|
||||
|
||||
/*
|
||||
* Devices that are part of the MSIC and are available via firmware
|
||||
* populated SFI DEVS table.
|
||||
*/
|
||||
static struct mfd_cell msic_devs[] = {
|
||||
[INTEL_MSIC_BLOCK_TOUCH] = {
|
||||
.name = "msic_touch",
|
||||
.num_resources = ARRAY_SIZE(msic_touch_resources),
|
||||
.resources = msic_touch_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_ADC] = {
|
||||
.name = "msic_adc",
|
||||
.num_resources = ARRAY_SIZE(msic_adc_resources),
|
||||
.resources = msic_adc_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_BATTERY] = {
|
||||
.name = "msic_battery",
|
||||
.num_resources = ARRAY_SIZE(msic_battery_resources),
|
||||
.resources = msic_battery_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_GPIO] = {
|
||||
.name = "msic_gpio",
|
||||
.num_resources = ARRAY_SIZE(msic_gpio_resources),
|
||||
.resources = msic_gpio_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_AUDIO] = {
|
||||
.name = "msic_audio",
|
||||
.num_resources = ARRAY_SIZE(msic_audio_resources),
|
||||
.resources = msic_audio_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_HDMI] = {
|
||||
.name = "msic_hdmi",
|
||||
.num_resources = ARRAY_SIZE(msic_hdmi_resources),
|
||||
.resources = msic_hdmi_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_THERMAL] = {
|
||||
.name = "msic_thermal",
|
||||
.num_resources = ARRAY_SIZE(msic_thermal_resources),
|
||||
.resources = msic_thermal_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_POWER_BTN] = {
|
||||
.name = "msic_power_btn",
|
||||
.num_resources = ARRAY_SIZE(msic_power_btn_resources),
|
||||
.resources = msic_power_btn_resources,
|
||||
},
|
||||
[INTEL_MSIC_BLOCK_OCD] = {
|
||||
.name = "msic_ocd",
|
||||
.num_resources = ARRAY_SIZE(msic_ocd_resources),
|
||||
.resources = msic_ocd_resources,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Other MSIC related devices which are not directly available via SFI DEVS
|
||||
* table. These can be pseudo devices, regulators etc. which are needed for
|
||||
* different purposes.
|
||||
*
|
||||
* These devices appear only after the MSIC driver itself is initialized so
|
||||
* we can guarantee that the SCU IPC interface is ready.
|
||||
*/
|
||||
static const struct mfd_cell msic_other_devs[] = {
|
||||
/* Audio codec in the MSIC */
|
||||
{
|
||||
.id = -1,
|
||||
.name = "sn95031",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* intel_msic_reg_read - read a single MSIC register
|
||||
* @reg: register to read
|
||||
* @val: register value is placed here
|
||||
*
|
||||
* Read a single register from MSIC. Returns %0 on success and negative
|
||||
* errno in case of failure.
|
||||
*
|
||||
* Function may sleep.
|
||||
*/
|
||||
int intel_msic_reg_read(unsigned short reg, u8 *val)
|
||||
{
|
||||
return intel_scu_ipc_ioread8(reg, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_reg_read);
|
||||
|
||||
/**
|
||||
* intel_msic_reg_write - write a single MSIC register
|
||||
* @reg: register to write
|
||||
* @val: value to write to that register
|
||||
*
|
||||
* Write a single MSIC register. Returns 0 on success and negative
|
||||
* errno in case of failure.
|
||||
*
|
||||
* Function may sleep.
|
||||
*/
|
||||
int intel_msic_reg_write(unsigned short reg, u8 val)
|
||||
{
|
||||
return intel_scu_ipc_iowrite8(reg, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_reg_write);
|
||||
|
||||
/**
|
||||
* intel_msic_reg_update - update a single MSIC register
|
||||
* @reg: register to update
|
||||
* @val: value to write to the register
|
||||
* @mask: specifies which of the bits are updated (%0 = don't update,
|
||||
* %1 = update)
|
||||
*
|
||||
* Perform an update to a register @reg. @mask is used to specify which
|
||||
* bits are updated. Returns %0 in case of success and negative errno in
|
||||
* case of failure.
|
||||
*
|
||||
* Function may sleep.
|
||||
*/
|
||||
int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask)
|
||||
{
|
||||
return intel_scu_ipc_update_register(reg, val, mask);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_reg_update);
|
||||
|
||||
/**
|
||||
* intel_msic_bulk_read - read an array of registers
|
||||
* @reg: array of register addresses to read
|
||||
* @buf: array where the read values are placed
|
||||
* @count: number of registers to read
|
||||
*
|
||||
* Function reads @count registers from the MSIC using addresses passed in
|
||||
* @reg. Read values are placed in @buf. Reads are performed atomically
|
||||
* wrt. MSIC.
|
||||
*
|
||||
* Returns %0 in case of success and negative errno in case of failure.
|
||||
*
|
||||
* Function may sleep.
|
||||
*/
|
||||
int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count)
|
||||
{
|
||||
if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT))
|
||||
return -EINVAL;
|
||||
|
||||
return intel_scu_ipc_readv(reg, buf, count);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_bulk_read);
|
||||
|
||||
/**
|
||||
* intel_msic_bulk_write - write an array of values to the MSIC registers
|
||||
* @reg: array of registers to write
|
||||
* @buf: values to write to each register
|
||||
* @count: number of registers to write
|
||||
*
|
||||
* Function writes @count registers in @buf to MSIC. Writes are performed
|
||||
* atomically wrt MSIC. Returns %0 in case of success and negative errno in
|
||||
* case of failure.
|
||||
*
|
||||
* Function may sleep.
|
||||
*/
|
||||
int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count)
|
||||
{
|
||||
if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT))
|
||||
return -EINVAL;
|
||||
|
||||
return intel_scu_ipc_writev(reg, buf, count);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_bulk_write);
|
||||
|
||||
/**
|
||||
* intel_msic_irq_read - read a register from an MSIC interrupt tree
|
||||
* @msic: MSIC instance
|
||||
* @reg: interrupt register (between %INTEL_MSIC_IRQLVL1 and
|
||||
* %INTEL_MSIC_RESETIRQ2)
|
||||
* @val: value of the register is placed here
|
||||
*
|
||||
* This function can be used by an MSIC subdevice interrupt handler to read
|
||||
* a register value from the MSIC interrupt tree. In this way subdevice
|
||||
* drivers don't have to map in the interrupt tree themselves but can just
|
||||
* call this function instead.
|
||||
*
|
||||
* Function doesn't sleep and is callable from interrupt context.
|
||||
*
|
||||
* Returns %-EINVAL if @reg is outside of the allowed register region.
|
||||
*/
|
||||
int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val)
|
||||
{
|
||||
if (WARN_ON(reg < INTEL_MSIC_IRQLVL1 || reg > INTEL_MSIC_RESETIRQ2))
|
||||
return -EINVAL;
|
||||
|
||||
*val = readb(msic->irq_base + (reg - INTEL_MSIC_IRQLVL1));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_msic_irq_read);
|
||||
|
||||
static int intel_msic_init_devices(struct intel_msic *msic)
|
||||
{
|
||||
struct platform_device *pdev = msic->pdev;
|
||||
struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
int ret, i;
|
||||
|
||||
if (pdata->gpio) {
|
||||
struct mfd_cell *cell = &msic_devs[INTEL_MSIC_BLOCK_GPIO];
|
||||
|
||||
cell->platform_data = pdata->gpio;
|
||||
cell->pdata_size = sizeof(*pdata->gpio);
|
||||
}
|
||||
|
||||
if (pdata->ocd) {
|
||||
unsigned gpio = pdata->ocd->gpio;
|
||||
|
||||
ret = devm_gpio_request_one(&pdev->dev, gpio,
|
||||
GPIOF_IN, "ocd_gpio");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register OCD GPIO\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpio_to_irq(gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "no IRQ number for OCD GPIO\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update the IRQ number for the OCD */
|
||||
pdata->irq[INTEL_MSIC_BLOCK_OCD] = ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(msic_devs); i++) {
|
||||
if (!pdata->irq[i])
|
||||
continue;
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL,
|
||||
pdata->irq[i], NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs,
|
||||
ARRAY_SIZE(msic_other_devs), NULL, 0, NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void intel_msic_remove_devices(struct intel_msic *msic)
|
||||
{
|
||||
struct platform_device *pdev = msic->pdev;
|
||||
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
}
|
||||
|
||||
static int intel_msic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct intel_msic_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct intel_msic *msic;
|
||||
struct resource *res;
|
||||
u8 id0, id1;
|
||||
int ret;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data passed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* First validate that we have an MSIC in place */
|
||||
ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID0, &id0);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to identify the MSIC chip (ID0)\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID1, &id1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to identify the MSIC chip (ID1)\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (MSIC_VENDOR(id0) != MSIC_VENDOR(id1)) {
|
||||
dev_err(&pdev->dev, "invalid vendor ID: %x, %x\n", id0, id1);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
msic = devm_kzalloc(&pdev->dev, sizeof(*msic), GFP_KERNEL);
|
||||
if (!msic)
|
||||
return -ENOMEM;
|
||||
|
||||
msic->vendor = MSIC_VENDOR(id0);
|
||||
msic->version = MSIC_VERSION(id0);
|
||||
msic->pdev = pdev;
|
||||
|
||||
/*
|
||||
* Map in the MSIC interrupt tree area in SRAM. This is exposed to
|
||||
* the clients via intel_msic_irq_read().
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
msic->irq_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(msic->irq_base))
|
||||
return PTR_ERR(msic->irq_base);
|
||||
|
||||
platform_set_drvdata(pdev, msic);
|
||||
|
||||
ret = intel_msic_init_devices(msic);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to initialize MSIC devices\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n",
|
||||
MSIC_MAJOR(msic->version), MSIC_MINOR(msic->version),
|
||||
msic->vendor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_msic_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct intel_msic *msic = platform_get_drvdata(pdev);
|
||||
|
||||
intel_msic_remove_devices(msic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver intel_msic_driver = {
|
||||
.probe = intel_msic_probe,
|
||||
.remove = intel_msic_remove,
|
||||
.driver = {
|
||||
.name = "intel_msic",
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(intel_msic_driver);
|
@@ -17,7 +17,6 @@
|
||||
static int intel_scu_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
void (*setup_fn)(void) = (void (*)(void))id->driver_data;
|
||||
struct intel_scu_ipc_data scu_data = {};
|
||||
struct intel_scu_ipc_dev *scu;
|
||||
int ret;
|
||||
@@ -30,27 +29,14 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
|
||||
scu_data.irq = pdev->irq;
|
||||
|
||||
scu = intel_scu_ipc_register(&pdev->dev, &scu_data);
|
||||
if (IS_ERR(scu))
|
||||
return PTR_ERR(scu);
|
||||
|
||||
if (setup_fn)
|
||||
setup_fn();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_mid_scu_setup(void)
|
||||
{
|
||||
intel_scu_devices_create();
|
||||
return PTR_ERR_OR_ZERO(scu);
|
||||
}
|
||||
|
||||
static const struct pci_device_id pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x080e),
|
||||
.driver_data = (kernel_ulong_t)intel_mid_scu_setup },
|
||||
{ PCI_VDEVICE(INTEL, 0x08ea),
|
||||
.driver_data = (kernel_ulong_t)intel_mid_scu_setup },
|
||||
{ PCI_VDEVICE(INTEL, 0x080e) },
|
||||
{ PCI_VDEVICE(INTEL, 0x08ea) },
|
||||
{ PCI_VDEVICE(INTEL, 0x0a94) },
|
||||
{ PCI_VDEVICE(INTEL, 0x11a0),
|
||||
.driver_data = (kernel_ulong_t)intel_mid_scu_setup },
|
||||
{ PCI_VDEVICE(INTEL, 0x11a0) },
|
||||
{ PCI_VDEVICE(INTEL, 0x1a94) },
|
||||
{ PCI_VDEVICE(INTEL, 0x5a94) },
|
||||
{}
|
||||
|
@@ -1,18 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# SFI Configuration
|
||||
#
|
||||
|
||||
menuconfig SFI
|
||||
bool "SFI (Simple Firmware Interface) Support"
|
||||
help
|
||||
The Simple Firmware Interface (SFI) provides a lightweight method
|
||||
for platform firmware to pass information to the operating system
|
||||
via static tables in memory. Kernel SFI support is required to
|
||||
boot on SFI-only platforms. Currently, all SFI-only platforms are
|
||||
based on the 2nd generation Intel Atom processor platform,
|
||||
code-named Moorestown.
|
||||
|
||||
For more information, see http://simplefirmware.org
|
||||
|
||||
Say 'Y' here to enable the kernel to boot on SFI-only platforms.
|
@@ -1,4 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y += sfi_acpi.o
|
||||
obj-y += sfi_core.o
|
||||
|
@@ -1,214 +0,0 @@
|
||||
/* sfi_acpi.c Simple Firmware Interface - ACPI extensions */
|
||||
|
||||
/*
|
||||
|
||||
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
redistributing this file, you may do so under either license.
|
||||
|
||||
GPL LICENSE SUMMARY
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
The full GNU General Public License is included in this distribution
|
||||
in the file called LICENSE.GPL.
|
||||
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "SFI"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sfi_acpi.h>
|
||||
#include "sfi_core.h"
|
||||
|
||||
/*
|
||||
* SFI can access ACPI-defined tables via an optional ACPI XSDT.
|
||||
*
|
||||
* This allows re-use, and avoids re-definition, of standard tables.
|
||||
* For example, the "MCFG" table is defined by PCI, reserved by ACPI,
|
||||
* and is expected to be present many SFI-only systems.
|
||||
*/
|
||||
|
||||
static struct acpi_table_xsdt *xsdt_va __read_mostly;
|
||||
|
||||
#define XSDT_GET_NUM_ENTRIES(ptable, entry_type) \
|
||||
((ptable->header.length - sizeof(struct acpi_table_header)) / \
|
||||
(sizeof(entry_type)))
|
||||
|
||||
static inline struct sfi_table_header *acpi_to_sfi_th(
|
||||
struct acpi_table_header *th)
|
||||
{
|
||||
return (struct sfi_table_header *)th;
|
||||
}
|
||||
|
||||
static inline struct acpi_table_header *sfi_to_acpi_th(
|
||||
struct sfi_table_header *th)
|
||||
{
|
||||
return (struct acpi_table_header *)th;
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_acpi_parse_xsdt()
|
||||
*
|
||||
* Parse the ACPI XSDT for later access by sfi_acpi_table_parse().
|
||||
*/
|
||||
static int __init sfi_acpi_parse_xsdt(struct sfi_table_header *th)
|
||||
{
|
||||
struct sfi_table_key key = SFI_ANY_KEY;
|
||||
int tbl_cnt, i;
|
||||
void *ret;
|
||||
|
||||
xsdt_va = (struct acpi_table_xsdt *)th;
|
||||
tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
|
||||
for (i = 0; i < tbl_cnt; i++) {
|
||||
ret = sfi_check_table(xsdt_va->table_offset_entry[i], &key);
|
||||
if (IS_ERR(ret)) {
|
||||
disable_sfi();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init sfi_acpi_init(void)
|
||||
{
|
||||
struct sfi_table_key xsdt_key = { .sig = SFI_SIG_XSDT };
|
||||
|
||||
sfi_table_parse(SFI_SIG_XSDT, NULL, NULL, sfi_acpi_parse_xsdt);
|
||||
|
||||
/* Only call the get_table to keep the table mapped */
|
||||
xsdt_va = (struct acpi_table_xsdt *)sfi_get_table(&xsdt_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct acpi_table_header *sfi_acpi_get_table(struct sfi_table_key *key)
|
||||
{
|
||||
u32 tbl_cnt, i;
|
||||
void *ret;
|
||||
|
||||
tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
|
||||
for (i = 0; i < tbl_cnt; i++) {
|
||||
ret = sfi_check_table(xsdt_va->table_offset_entry[i], key);
|
||||
if (!IS_ERR(ret) && ret)
|
||||
return sfi_to_acpi_th(ret);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sfi_acpi_put_table(struct acpi_table_header *table)
|
||||
{
|
||||
sfi_put_table(acpi_to_sfi_th(table));
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_acpi_table_parse()
|
||||
*
|
||||
* Find specified table in XSDT, run handler on it and return its return value
|
||||
*/
|
||||
int sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id,
|
||||
int(*handler)(struct acpi_table_header *))
|
||||
{
|
||||
struct acpi_table_header *table = NULL;
|
||||
struct sfi_table_key key;
|
||||
int ret = 0;
|
||||
|
||||
if (sfi_disabled)
|
||||
return -1;
|
||||
|
||||
key.sig = signature;
|
||||
key.oem_id = oem_id;
|
||||
key.oem_table_id = oem_table_id;
|
||||
|
||||
table = sfi_acpi_get_table(&key);
|
||||
if (!table)
|
||||
return -EINVAL;
|
||||
|
||||
ret = handler(table);
|
||||
sfi_acpi_put_table(table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf,
|
||||
loff_t offset, size_t count)
|
||||
{
|
||||
struct sfi_table_attr *tbl_attr =
|
||||
container_of(bin_attr, struct sfi_table_attr, attr);
|
||||
struct acpi_table_header *th = NULL;
|
||||
struct sfi_table_key key;
|
||||
ssize_t cnt;
|
||||
|
||||
key.sig = tbl_attr->name;
|
||||
key.oem_id = NULL;
|
||||
key.oem_table_id = NULL;
|
||||
|
||||
th = sfi_acpi_get_table(&key);
|
||||
if (!th)
|
||||
return 0;
|
||||
|
||||
cnt = memory_read_from_buffer(buf, count, &offset,
|
||||
th, th->length);
|
||||
sfi_acpi_put_table(th);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
void __init sfi_acpi_sysfs_init(void)
|
||||
{
|
||||
u32 tbl_cnt, i;
|
||||
struct sfi_table_attr *tbl_attr;
|
||||
|
||||
tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
|
||||
for (i = 0; i < tbl_cnt; i++) {
|
||||
tbl_attr =
|
||||
sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]);
|
||||
tbl_attr->attr.read = sfi_acpi_table_show;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
@@ -1,522 +0,0 @@
|
||||
/* sfi_core.c Simple Firmware Interface - core internals */
|
||||
|
||||
/*
|
||||
|
||||
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
redistributing this file, you may do so under either license.
|
||||
|
||||
GPL LICENSE SUMMARY
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
The full GNU General Public License is included in this distribution
|
||||
in the file called LICENSE.GPL.
|
||||
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "SFI"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "sfi_core.h"
|
||||
|
||||
#define ON_SAME_PAGE(addr1, addr2) \
|
||||
(((unsigned long)(addr1) & PAGE_MASK) == \
|
||||
((unsigned long)(addr2) & PAGE_MASK))
|
||||
#define TABLE_ON_PAGE(page, table, size) (ON_SAME_PAGE(page, table) && \
|
||||
ON_SAME_PAGE(page, table + size))
|
||||
|
||||
int sfi_disabled __read_mostly;
|
||||
EXPORT_SYMBOL(sfi_disabled);
|
||||
|
||||
static u64 syst_pa __read_mostly;
|
||||
static struct sfi_table_simple *syst_va __read_mostly;
|
||||
|
||||
/*
|
||||
* FW creates and saves the SFI tables in memory. When these tables get
|
||||
* used, they may need to be mapped to virtual address space, and the mapping
|
||||
* can happen before or after the memremap() is ready, so a flag is needed
|
||||
* to indicating this
|
||||
*/
|
||||
static u32 sfi_use_memremap __read_mostly;
|
||||
|
||||
/*
|
||||
* sfi_un/map_memory calls early_memremap/memunmap which is a __init function
|
||||
* and introduces section mismatch. So use __ref to make it calm.
|
||||
*/
|
||||
static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
|
||||
{
|
||||
if (!phys || !size)
|
||||
return NULL;
|
||||
|
||||
if (sfi_use_memremap)
|
||||
return memremap(phys, size, MEMREMAP_WB);
|
||||
else
|
||||
return early_memremap(phys, size);
|
||||
}
|
||||
|
||||
static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
|
||||
{
|
||||
if (!virt || !size)
|
||||
return;
|
||||
|
||||
if (sfi_use_memremap)
|
||||
memunmap(virt);
|
||||
else
|
||||
early_memunmap(virt, size);
|
||||
}
|
||||
|
||||
static void sfi_print_table_header(unsigned long long pa,
|
||||
struct sfi_table_header *header)
|
||||
{
|
||||
pr_info("%4.4s %llX, %04X (v%d %6.6s %8.8s)\n",
|
||||
header->sig, pa,
|
||||
header->len, header->rev, header->oem_id,
|
||||
header->oem_table_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_verify_table()
|
||||
* Sanity check table lengh, calculate checksum
|
||||
*/
|
||||
static int sfi_verify_table(struct sfi_table_header *table)
|
||||
{
|
||||
|
||||
u8 checksum = 0;
|
||||
u8 *puchar = (u8 *)table;
|
||||
u32 length = table->len;
|
||||
|
||||
/* Sanity check table length against arbitrary 1MB limit */
|
||||
if (length > 0x100000) {
|
||||
pr_err("Invalid table length 0x%x\n", length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (length--)
|
||||
checksum += *puchar++;
|
||||
|
||||
if (checksum) {
|
||||
pr_err("Checksum %2.2X should be %2.2X\n",
|
||||
table->csum, table->csum - checksum);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_map_table()
|
||||
*
|
||||
* Return address of mapped table
|
||||
* Check for common case that we can re-use mapping to SYST,
|
||||
* which requires syst_pa, syst_va to be initialized.
|
||||
*/
|
||||
static struct sfi_table_header *sfi_map_table(u64 pa)
|
||||
{
|
||||
struct sfi_table_header *th;
|
||||
u32 length;
|
||||
|
||||
if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header)))
|
||||
th = sfi_map_memory(pa, sizeof(struct sfi_table_header));
|
||||
else
|
||||
th = (void *)syst_va + (pa - syst_pa);
|
||||
|
||||
/* If table fits on same page as its header, we are done */
|
||||
if (TABLE_ON_PAGE(th, th, th->len))
|
||||
return th;
|
||||
|
||||
/* Entire table does not fit on same page as SYST */
|
||||
length = th->len;
|
||||
if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header)))
|
||||
sfi_unmap_memory(th, sizeof(struct sfi_table_header));
|
||||
|
||||
return sfi_map_memory(pa, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_unmap_table()
|
||||
*
|
||||
* Undoes effect of sfi_map_table() by unmapping table
|
||||
* if it did not completely fit on same page as SYST.
|
||||
*/
|
||||
static void sfi_unmap_table(struct sfi_table_header *th)
|
||||
{
|
||||
if (!TABLE_ON_PAGE(syst_va, th, th->len))
|
||||
sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ?
|
||||
sizeof(*th) : th->len);
|
||||
}
|
||||
|
||||
static int sfi_table_check_key(struct sfi_table_header *th,
|
||||
struct sfi_table_key *key)
|
||||
{
|
||||
|
||||
if (strncmp(th->sig, key->sig, SFI_SIGNATURE_SIZE)
|
||||
|| (key->oem_id && strncmp(th->oem_id,
|
||||
key->oem_id, SFI_OEM_ID_SIZE))
|
||||
|| (key->oem_table_id && strncmp(th->oem_table_id,
|
||||
key->oem_table_id, SFI_OEM_TABLE_ID_SIZE)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will be used in 2 cases:
|
||||
* 1. used to enumerate and verify the tables addressed by SYST/XSDT,
|
||||
* thus no signature will be given (in kernel boot phase)
|
||||
* 2. used to parse one specific table, signature must exist, and
|
||||
* the mapped virt address will be returned, and the virt space
|
||||
* will be released by call sfi_put_table() later
|
||||
*
|
||||
* This two cases are from two different functions with two different
|
||||
* sections and causes section mismatch warning. So use __ref to tell
|
||||
* modpost not to make any noise.
|
||||
*
|
||||
* Return value:
|
||||
* NULL: when can't find a table matching the key
|
||||
* ERR_PTR(error): error value
|
||||
* virt table address: when a matched table is found
|
||||
*/
|
||||
struct sfi_table_header *
|
||||
__ref sfi_check_table(u64 pa, struct sfi_table_key *key)
|
||||
{
|
||||
struct sfi_table_header *th;
|
||||
void *ret = NULL;
|
||||
|
||||
th = sfi_map_table(pa);
|
||||
if (!th)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (!key->sig) {
|
||||
sfi_print_table_header(pa, th);
|
||||
if (sfi_verify_table(th))
|
||||
ret = ERR_PTR(-EINVAL);
|
||||
} else {
|
||||
if (!sfi_table_check_key(th, key))
|
||||
return th; /* Success */
|
||||
}
|
||||
|
||||
sfi_unmap_table(th);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* sfi_get_table()
|
||||
*
|
||||
* Search SYST for the specified table with the signature in
|
||||
* the key, and return the mapped table
|
||||
*/
|
||||
struct sfi_table_header *sfi_get_table(struct sfi_table_key *key)
|
||||
{
|
||||
struct sfi_table_header *th;
|
||||
u32 tbl_cnt, i;
|
||||
|
||||
tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64);
|
||||
for (i = 0; i < tbl_cnt; i++) {
|
||||
th = sfi_check_table(syst_va->pentry[i], key);
|
||||
if (!IS_ERR(th) && th)
|
||||
return th;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sfi_put_table(struct sfi_table_header *th)
|
||||
{
|
||||
sfi_unmap_table(th);
|
||||
}
|
||||
|
||||
/* Find table with signature, run handler on it */
|
||||
int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id,
|
||||
sfi_table_handler handler)
|
||||
{
|
||||
struct sfi_table_header *table = NULL;
|
||||
struct sfi_table_key key;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (sfi_disabled || !handler || !signature)
|
||||
goto exit;
|
||||
|
||||
key.sig = signature;
|
||||
key.oem_id = oem_id;
|
||||
key.oem_table_id = oem_table_id;
|
||||
|
||||
table = sfi_get_table(&key);
|
||||
if (!table)
|
||||
goto exit;
|
||||
|
||||
ret = handler(table);
|
||||
sfi_put_table(table);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sfi_table_parse);
|
||||
|
||||
/*
|
||||
* sfi_parse_syst()
|
||||
* Checksum all the tables in SYST and print their headers
|
||||
*
|
||||
* success: set syst_va, return 0
|
||||
*/
|
||||
static int __init sfi_parse_syst(void)
|
||||
{
|
||||
struct sfi_table_key key = SFI_ANY_KEY;
|
||||
int tbl_cnt, i;
|
||||
void *ret;
|
||||
|
||||
syst_va = sfi_map_memory(syst_pa, sizeof(struct sfi_table_simple));
|
||||
if (!syst_va)
|
||||
return -ENOMEM;
|
||||
|
||||
tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64);
|
||||
for (i = 0; i < tbl_cnt; i++) {
|
||||
ret = sfi_check_table(syst_va->pentry[i], &key);
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The OS finds the System Table by searching 16-byte boundaries between
|
||||
* physical address 0x000E0000 and 0x000FFFFF. The OS shall search this region
|
||||
* starting at the low address and shall stop searching when the 1st valid SFI
|
||||
* System Table is found.
|
||||
*
|
||||
* success: set syst_pa, return 0
|
||||
* fail: return -1
|
||||
*/
|
||||
static __init int sfi_find_syst(void)
|
||||
{
|
||||
unsigned long offset, len;
|
||||
void *start;
|
||||
|
||||
len = SFI_SYST_SEARCH_END - SFI_SYST_SEARCH_BEGIN;
|
||||
start = sfi_map_memory(SFI_SYST_SEARCH_BEGIN, len);
|
||||
if (!start)
|
||||
return -1;
|
||||
|
||||
for (offset = 0; offset < len; offset += 16) {
|
||||
struct sfi_table_header *syst_hdr;
|
||||
|
||||
syst_hdr = start + offset;
|
||||
if (strncmp(syst_hdr->sig, SFI_SIG_SYST,
|
||||
SFI_SIGNATURE_SIZE))
|
||||
continue;
|
||||
|
||||
if (syst_hdr->len > PAGE_SIZE)
|
||||
continue;
|
||||
|
||||
sfi_print_table_header(SFI_SYST_SEARCH_BEGIN + offset,
|
||||
syst_hdr);
|
||||
|
||||
if (sfi_verify_table(syst_hdr))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Enforce SFI spec mandate that SYST reside within a page.
|
||||
*/
|
||||
if (!ON_SAME_PAGE(syst_pa, syst_pa + syst_hdr->len)) {
|
||||
pr_info("SYST 0x%llx + 0x%x crosses page\n",
|
||||
syst_pa, syst_hdr->len);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
syst_pa = SFI_SYST_SEARCH_BEGIN + offset;
|
||||
sfi_unmap_memory(start, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sfi_unmap_memory(start, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct kobject *sfi_kobj;
|
||||
static struct kobject *tables_kobj;
|
||||
|
||||
static ssize_t sfi_table_show(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr, char *buf,
|
||||
loff_t offset, size_t count)
|
||||
{
|
||||
struct sfi_table_attr *tbl_attr =
|
||||
container_of(bin_attr, struct sfi_table_attr, attr);
|
||||
struct sfi_table_header *th = NULL;
|
||||
struct sfi_table_key key;
|
||||
ssize_t cnt;
|
||||
|
||||
key.sig = tbl_attr->name;
|
||||
key.oem_id = NULL;
|
||||
key.oem_table_id = NULL;
|
||||
|
||||
if (strncmp(SFI_SIG_SYST, tbl_attr->name, SFI_SIGNATURE_SIZE)) {
|
||||
th = sfi_get_table(&key);
|
||||
if (!th)
|
||||
return 0;
|
||||
|
||||
cnt = memory_read_from_buffer(buf, count, &offset,
|
||||
th, th->len);
|
||||
sfi_put_table(th);
|
||||
} else
|
||||
cnt = memory_read_from_buffer(buf, count, &offset,
|
||||
syst_va, syst_va->header.len);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa)
|
||||
{
|
||||
struct sfi_table_attr *tbl_attr;
|
||||
struct sfi_table_header *th;
|
||||
int ret;
|
||||
|
||||
tbl_attr = kzalloc(sizeof(struct sfi_table_attr), GFP_KERNEL);
|
||||
if (!tbl_attr)
|
||||
return NULL;
|
||||
|
||||
th = sfi_map_table(pa);
|
||||
if (!th || !th->sig[0]) {
|
||||
kfree(tbl_attr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sysfs_attr_init(&tbl_attr->attr.attr);
|
||||
memcpy(tbl_attr->name, th->sig, SFI_SIGNATURE_SIZE);
|
||||
|
||||
tbl_attr->attr.size = 0;
|
||||
tbl_attr->attr.read = sfi_table_show;
|
||||
tbl_attr->attr.attr.name = tbl_attr->name;
|
||||
tbl_attr->attr.attr.mode = 0400;
|
||||
|
||||
ret = sysfs_create_bin_file(tables_kobj,
|
||||
&tbl_attr->attr);
|
||||
if (ret) {
|
||||
kfree(tbl_attr);
|
||||
tbl_attr = NULL;
|
||||
}
|
||||
|
||||
sfi_unmap_table(th);
|
||||
return tbl_attr;
|
||||
}
|
||||
|
||||
static int __init sfi_sysfs_init(void)
|
||||
{
|
||||
int tbl_cnt, i;
|
||||
|
||||
if (sfi_disabled)
|
||||
return 0;
|
||||
|
||||
sfi_kobj = kobject_create_and_add("sfi", firmware_kobj);
|
||||
if (!sfi_kobj)
|
||||
return 0;
|
||||
|
||||
tables_kobj = kobject_create_and_add("tables", sfi_kobj);
|
||||
if (!tables_kobj) {
|
||||
kobject_put(sfi_kobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sfi_sysfs_install_table(syst_pa);
|
||||
|
||||
tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64);
|
||||
|
||||
for (i = 0; i < tbl_cnt; i++)
|
||||
sfi_sysfs_install_table(syst_va->pentry[i]);
|
||||
|
||||
sfi_acpi_sysfs_init();
|
||||
kobject_uevent(sfi_kobj, KOBJ_ADD);
|
||||
kobject_uevent(tables_kobj, KOBJ_ADD);
|
||||
pr_info("SFI sysfs interfaces init success\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init sfi_init(void)
|
||||
{
|
||||
if (!acpi_disabled)
|
||||
disable_sfi();
|
||||
|
||||
if (sfi_disabled)
|
||||
return;
|
||||
|
||||
pr_info("Simple Firmware Interface v0.81 http://simplefirmware.org\n");
|
||||
|
||||
if (sfi_find_syst() || sfi_parse_syst() || sfi_platform_init())
|
||||
disable_sfi();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void __init sfi_init_late(void)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (sfi_disabled)
|
||||
return;
|
||||
|
||||
length = syst_va->header.len;
|
||||
sfi_unmap_memory(syst_va, sizeof(struct sfi_table_simple));
|
||||
|
||||
/* Use memremap now after it is ready */
|
||||
sfi_use_memremap = 1;
|
||||
syst_va = sfi_map_memory(syst_pa, length);
|
||||
|
||||
sfi_acpi_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* The reason we put it here because we need wait till the /sys/firmware
|
||||
* is setup, then our interface can be registered in /sys/firmware/sfi
|
||||
*/
|
||||
core_initcall(sfi_sysfs_init);
|
@@ -1,81 +0,0 @@
|
||||
/* sfi_core.h Simple Firmware Interface, internal header */
|
||||
|
||||
/*
|
||||
|
||||
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
redistributing this file, you may do so under either license.
|
||||
|
||||
GPL LICENSE SUMMARY
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
The full GNU General Public License is included in this distribution
|
||||
in the file called LICENSE.GPL.
|
||||
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
struct sfi_table_key{
|
||||
char *sig;
|
||||
char *oem_id;
|
||||
char *oem_table_id;
|
||||
};
|
||||
|
||||
/* sysfs interface */
|
||||
struct sfi_table_attr {
|
||||
struct bin_attribute attr;
|
||||
char name[8];
|
||||
};
|
||||
|
||||
#define SFI_ANY_KEY { .sig = NULL, .oem_id = NULL, .oem_table_id = NULL }
|
||||
|
||||
extern int __init sfi_acpi_init(void);
|
||||
extern struct sfi_table_header *sfi_check_table(u64 paddr,
|
||||
struct sfi_table_key *key);
|
||||
struct sfi_table_header *sfi_get_table(struct sfi_table_key *key);
|
||||
extern void sfi_put_table(struct sfi_table_header *table);
|
||||
extern struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa);
|
||||
extern void __init sfi_acpi_sysfs_init(void);
|
@@ -22,7 +22,6 @@
|
||||
#include <asm/processor.h>
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include "atomisp.h"
|
||||
|
||||
|
@@ -1,453 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Core interface for Intel MSIC
|
||||
*
|
||||
* Copyright (C) 2011, Intel Corporation
|
||||
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_INTEL_MSIC_H__
|
||||
#define __LINUX_MFD_INTEL_MSIC_H__
|
||||
|
||||
/* ID */
|
||||
#define INTEL_MSIC_ID0 0x000 /* RO */
|
||||
#define INTEL_MSIC_ID1 0x001 /* RO */
|
||||
|
||||
/* IRQ */
|
||||
#define INTEL_MSIC_IRQLVL1 0x002
|
||||
#define INTEL_MSIC_ADC1INT 0x003
|
||||
#define INTEL_MSIC_CCINT 0x004
|
||||
#define INTEL_MSIC_PWRSRCINT 0x005
|
||||
#define INTEL_MSIC_PWRSRCINT1 0x006
|
||||
#define INTEL_MSIC_CHRINT 0x007
|
||||
#define INTEL_MSIC_CHRINT1 0x008
|
||||
#define INTEL_MSIC_RTCIRQ 0x009
|
||||
#define INTEL_MSIC_GPIO0LVIRQ 0x00a
|
||||
#define INTEL_MSIC_GPIO1LVIRQ 0x00b
|
||||
#define INTEL_MSIC_GPIOHVIRQ 0x00c
|
||||
#define INTEL_MSIC_VRINT 0x00d
|
||||
#define INTEL_MSIC_OCAUDIO 0x00e
|
||||
#define INTEL_MSIC_ACCDET 0x00f
|
||||
#define INTEL_MSIC_RESETIRQ1 0x010
|
||||
#define INTEL_MSIC_RESETIRQ2 0x011
|
||||
#define INTEL_MSIC_MADC1INT 0x012
|
||||
#define INTEL_MSIC_MCCINT 0x013
|
||||
#define INTEL_MSIC_MPWRSRCINT 0x014
|
||||
#define INTEL_MSIC_MPWRSRCINT1 0x015
|
||||
#define INTEL_MSIC_MCHRINT 0x016
|
||||
#define INTEL_MSIC_MCHRINT1 0x017
|
||||
#define INTEL_MSIC_RTCIRQMASK 0x018
|
||||
#define INTEL_MSIC_GPIO0LVIRQMASK 0x019
|
||||
#define INTEL_MSIC_GPIO1LVIRQMASK 0x01a
|
||||
#define INTEL_MSIC_GPIOHVIRQMASK 0x01b
|
||||
#define INTEL_MSIC_VRINTMASK 0x01c
|
||||
#define INTEL_MSIC_OCAUDIOMASK 0x01d
|
||||
#define INTEL_MSIC_ACCDETMASK 0x01e
|
||||
#define INTEL_MSIC_RESETIRQ1MASK 0x01f
|
||||
#define INTEL_MSIC_RESETIRQ2MASK 0x020
|
||||
#define INTEL_MSIC_IRQLVL1MSK 0x021
|
||||
#define INTEL_MSIC_PBCONFIG 0x03e
|
||||
#define INTEL_MSIC_PBSTATUS 0x03f /* RO */
|
||||
|
||||
/* GPIO */
|
||||
#define INTEL_MSIC_GPIO0LV7CTLO 0x040
|
||||
#define INTEL_MSIC_GPIO0LV6CTLO 0x041
|
||||
#define INTEL_MSIC_GPIO0LV5CTLO 0x042
|
||||
#define INTEL_MSIC_GPIO0LV4CTLO 0x043
|
||||
#define INTEL_MSIC_GPIO0LV3CTLO 0x044
|
||||
#define INTEL_MSIC_GPIO0LV2CTLO 0x045
|
||||
#define INTEL_MSIC_GPIO0LV1CTLO 0x046
|
||||
#define INTEL_MSIC_GPIO0LV0CTLO 0x047
|
||||
#define INTEL_MSIC_GPIO1LV7CTLOS 0x048
|
||||
#define INTEL_MSIC_GPIO1LV6CTLO 0x049
|
||||
#define INTEL_MSIC_GPIO1LV5CTLO 0x04a
|
||||
#define INTEL_MSIC_GPIO1LV4CTLO 0x04b
|
||||
#define INTEL_MSIC_GPIO1LV3CTLO 0x04c
|
||||
#define INTEL_MSIC_GPIO1LV2CTLO 0x04d
|
||||
#define INTEL_MSIC_GPIO1LV1CTLO 0x04e
|
||||
#define INTEL_MSIC_GPIO1LV0CTLO 0x04f
|
||||
#define INTEL_MSIC_GPIO0LV7CTLI 0x050
|
||||
#define INTEL_MSIC_GPIO0LV6CTLI 0x051
|
||||
#define INTEL_MSIC_GPIO0LV5CTLI 0x052
|
||||
#define INTEL_MSIC_GPIO0LV4CTLI 0x053
|
||||
#define INTEL_MSIC_GPIO0LV3CTLI 0x054
|
||||
#define INTEL_MSIC_GPIO0LV2CTLI 0x055
|
||||
#define INTEL_MSIC_GPIO0LV1CTLI 0x056
|
||||
#define INTEL_MSIC_GPIO0LV0CTLI 0x057
|
||||
#define INTEL_MSIC_GPIO1LV7CTLIS 0x058
|
||||
#define INTEL_MSIC_GPIO1LV6CTLI 0x059
|
||||
#define INTEL_MSIC_GPIO1LV5CTLI 0x05a
|
||||
#define INTEL_MSIC_GPIO1LV4CTLI 0x05b
|
||||
#define INTEL_MSIC_GPIO1LV3CTLI 0x05c
|
||||
#define INTEL_MSIC_GPIO1LV2CTLI 0x05d
|
||||
#define INTEL_MSIC_GPIO1LV1CTLI 0x05e
|
||||
#define INTEL_MSIC_GPIO1LV0CTLI 0x05f
|
||||
#define INTEL_MSIC_PWM0CLKDIV1 0x061
|
||||
#define INTEL_MSIC_PWM0CLKDIV0 0x062
|
||||
#define INTEL_MSIC_PWM1CLKDIV1 0x063
|
||||
#define INTEL_MSIC_PWM1CLKDIV0 0x064
|
||||
#define INTEL_MSIC_PWM2CLKDIV1 0x065
|
||||
#define INTEL_MSIC_PWM2CLKDIV0 0x066
|
||||
#define INTEL_MSIC_PWM0DUTYCYCLE 0x067
|
||||
#define INTEL_MSIC_PWM1DUTYCYCLE 0x068
|
||||
#define INTEL_MSIC_PWM2DUTYCYCLE 0x069
|
||||
#define INTEL_MSIC_GPIO0HV3CTLO 0x06d
|
||||
#define INTEL_MSIC_GPIO0HV2CTLO 0x06e
|
||||
#define INTEL_MSIC_GPIO0HV1CTLO 0x06f
|
||||
#define INTEL_MSIC_GPIO0HV0CTLO 0x070
|
||||
#define INTEL_MSIC_GPIO1HV3CTLO 0x071
|
||||
#define INTEL_MSIC_GPIO1HV2CTLO 0x072
|
||||
#define INTEL_MSIC_GPIO1HV1CTLO 0x073
|
||||
#define INTEL_MSIC_GPIO1HV0CTLO 0x074
|
||||
#define INTEL_MSIC_GPIO0HV3CTLI 0x075
|
||||
#define INTEL_MSIC_GPIO0HV2CTLI 0x076
|
||||
#define INTEL_MSIC_GPIO0HV1CTLI 0x077
|
||||
#define INTEL_MSIC_GPIO0HV0CTLI 0x078
|
||||
#define INTEL_MSIC_GPIO1HV3CTLI 0x079
|
||||
#define INTEL_MSIC_GPIO1HV2CTLI 0x07a
|
||||
#define INTEL_MSIC_GPIO1HV1CTLI 0x07b
|
||||
#define INTEL_MSIC_GPIO1HV0CTLI 0x07c
|
||||
|
||||
/* SVID */
|
||||
#define INTEL_MSIC_SVIDCTRL0 0x080
|
||||
#define INTEL_MSIC_SVIDCTRL1 0x081
|
||||
#define INTEL_MSIC_SVIDCTRL2 0x082
|
||||
#define INTEL_MSIC_SVIDTXLASTPKT3 0x083 /* RO */
|
||||
#define INTEL_MSIC_SVIDTXLASTPKT2 0x084 /* RO */
|
||||
#define INTEL_MSIC_SVIDTXLASTPKT1 0x085 /* RO */
|
||||
#define INTEL_MSIC_SVIDTXLASTPKT0 0x086 /* RO */
|
||||
#define INTEL_MSIC_SVIDPKTOUTBYTE3 0x087
|
||||
#define INTEL_MSIC_SVIDPKTOUTBYTE2 0x088
|
||||
#define INTEL_MSIC_SVIDPKTOUTBYTE1 0x089
|
||||
#define INTEL_MSIC_SVIDPKTOUTBYTE0 0x08a
|
||||
#define INTEL_MSIC_SVIDRXVPDEBUG1 0x08b
|
||||
#define INTEL_MSIC_SVIDRXVPDEBUG0 0x08c
|
||||
#define INTEL_MSIC_SVIDRXLASTPKT3 0x08d /* RO */
|
||||
#define INTEL_MSIC_SVIDRXLASTPKT2 0x08e /* RO */
|
||||
#define INTEL_MSIC_SVIDRXLASTPKT1 0x08f /* RO */
|
||||
#define INTEL_MSIC_SVIDRXLASTPKT0 0x090 /* RO */
|
||||
#define INTEL_MSIC_SVIDRXCHKSTATUS3 0x091 /* RO */
|
||||
#define INTEL_MSIC_SVIDRXCHKSTATUS2 0x092 /* RO */
|
||||
#define INTEL_MSIC_SVIDRXCHKSTATUS1 0x093 /* RO */
|
||||
#define INTEL_MSIC_SVIDRXCHKSTATUS0 0x094 /* RO */
|
||||
|
||||
/* VREG */
|
||||
#define INTEL_MSIC_VCCLATCH 0x0c0
|
||||
#define INTEL_MSIC_VNNLATCH 0x0c1
|
||||
#define INTEL_MSIC_VCCCNT 0x0c2
|
||||
#define INTEL_MSIC_SMPSRAMP 0x0c3
|
||||
#define INTEL_MSIC_VNNCNT 0x0c4
|
||||
#define INTEL_MSIC_VNNAONCNT 0x0c5
|
||||
#define INTEL_MSIC_VCC122AONCNT 0x0c6
|
||||
#define INTEL_MSIC_V180AONCNT 0x0c7
|
||||
#define INTEL_MSIC_V500CNT 0x0c8
|
||||
#define INTEL_MSIC_VIHFCNT 0x0c9
|
||||
#define INTEL_MSIC_LDORAMP1 0x0ca
|
||||
#define INTEL_MSIC_LDORAMP2 0x0cb
|
||||
#define INTEL_MSIC_VCC108AONCNT 0x0cc
|
||||
#define INTEL_MSIC_VCC108ASCNT 0x0cd
|
||||
#define INTEL_MSIC_VCC108CNT 0x0ce
|
||||
#define INTEL_MSIC_VCCA100ASCNT 0x0cf
|
||||
#define INTEL_MSIC_VCCA100CNT 0x0d0
|
||||
#define INTEL_MSIC_VCC180AONCNT 0x0d1
|
||||
#define INTEL_MSIC_VCC180CNT 0x0d2
|
||||
#define INTEL_MSIC_VCC330CNT 0x0d3
|
||||
#define INTEL_MSIC_VUSB330CNT 0x0d4
|
||||
#define INTEL_MSIC_VCCSDIOCNT 0x0d5
|
||||
#define INTEL_MSIC_VPROG1CNT 0x0d6
|
||||
#define INTEL_MSIC_VPROG2CNT 0x0d7
|
||||
#define INTEL_MSIC_VEMMCSCNT 0x0d8
|
||||
#define INTEL_MSIC_VEMMC1CNT 0x0d9
|
||||
#define INTEL_MSIC_VEMMC2CNT 0x0da
|
||||
#define INTEL_MSIC_VAUDACNT 0x0db
|
||||
#define INTEL_MSIC_VHSPCNT 0x0dc
|
||||
#define INTEL_MSIC_VHSNCNT 0x0dd
|
||||
#define INTEL_MSIC_VHDMICNT 0x0de
|
||||
#define INTEL_MSIC_VOTGCNT 0x0df
|
||||
#define INTEL_MSIC_V1P35CNT 0x0e0
|
||||
#define INTEL_MSIC_V330AONCNT 0x0e1
|
||||
|
||||
/* RESET */
|
||||
#define INTEL_MSIC_CHIPCNTRL 0x100 /* WO */
|
||||
#define INTEL_MSIC_ERCONFIG 0x101
|
||||
|
||||
/* BURST */
|
||||
#define INTEL_MSIC_BATCURRENTLIMIT12 0x102
|
||||
#define INTEL_MSIC_BATTIMELIMIT12 0x103
|
||||
#define INTEL_MSIC_BATTIMELIMIT3 0x104
|
||||
#define INTEL_MSIC_BATTIMEDB 0x105
|
||||
#define INTEL_MSIC_BRSTCONFIGOUTPUTS 0x106
|
||||
#define INTEL_MSIC_BRSTCONFIGACTIONS 0x107
|
||||
#define INTEL_MSIC_BURSTCONTROLSTATUS 0x108
|
||||
|
||||
/* RTC */
|
||||
#define INTEL_MSIC_RTCB1 0x140 /* RO */
|
||||
#define INTEL_MSIC_RTCB2 0x141 /* RO */
|
||||
#define INTEL_MSIC_RTCB3 0x142 /* RO */
|
||||
#define INTEL_MSIC_RTCB4 0x143 /* RO */
|
||||
#define INTEL_MSIC_RTCOB1 0x144
|
||||
#define INTEL_MSIC_RTCOB2 0x145
|
||||
#define INTEL_MSIC_RTCOB3 0x146
|
||||
#define INTEL_MSIC_RTCOB4 0x147
|
||||
#define INTEL_MSIC_RTCAB1 0x148
|
||||
#define INTEL_MSIC_RTCAB2 0x149
|
||||
#define INTEL_MSIC_RTCAB3 0x14a
|
||||
#define INTEL_MSIC_RTCAB4 0x14b
|
||||
#define INTEL_MSIC_RTCWAB1 0x14c
|
||||
#define INTEL_MSIC_RTCWAB2 0x14d
|
||||
#define INTEL_MSIC_RTCWAB3 0x14e
|
||||
#define INTEL_MSIC_RTCWAB4 0x14f
|
||||
#define INTEL_MSIC_RTCSC1 0x150
|
||||
#define INTEL_MSIC_RTCSC2 0x151
|
||||
#define INTEL_MSIC_RTCSC3 0x152
|
||||
#define INTEL_MSIC_RTCSC4 0x153
|
||||
#define INTEL_MSIC_RTCSTATUS 0x154 /* RO */
|
||||
#define INTEL_MSIC_RTCCONFIG1 0x155
|
||||
#define INTEL_MSIC_RTCCONFIG2 0x156
|
||||
|
||||
/* CHARGER */
|
||||
#define INTEL_MSIC_BDTIMER 0x180
|
||||
#define INTEL_MSIC_BATTRMV 0x181
|
||||
#define INTEL_MSIC_VBUSDET 0x182
|
||||
#define INTEL_MSIC_VBUSDET1 0x183
|
||||
#define INTEL_MSIC_ADPHVDET 0x184
|
||||
#define INTEL_MSIC_ADPLVDET 0x185
|
||||
#define INTEL_MSIC_ADPDETDBDM 0x186
|
||||
#define INTEL_MSIC_LOWBATTDET 0x187
|
||||
#define INTEL_MSIC_CHRCTRL 0x188
|
||||
#define INTEL_MSIC_CHRCVOLTAGE 0x189
|
||||
#define INTEL_MSIC_CHRCCURRENT 0x18a
|
||||
#define INTEL_MSIC_SPCHARGER 0x18b
|
||||
#define INTEL_MSIC_CHRTTIME 0x18c
|
||||
#define INTEL_MSIC_CHRCTRL1 0x18d
|
||||
#define INTEL_MSIC_PWRSRCLMT 0x18e
|
||||
#define INTEL_MSIC_CHRSTWDT 0x18f
|
||||
#define INTEL_MSIC_WDTWRITE 0x190 /* WO */
|
||||
#define INTEL_MSIC_CHRSAFELMT 0x191
|
||||
#define INTEL_MSIC_SPWRSRCINT 0x192 /* RO */
|
||||
#define INTEL_MSIC_SPWRSRCINT1 0x193 /* RO */
|
||||
#define INTEL_MSIC_CHRLEDPWM 0x194
|
||||
#define INTEL_MSIC_CHRLEDCTRL 0x195
|
||||
|
||||
/* ADC */
|
||||
#define INTEL_MSIC_ADC1CNTL1 0x1c0
|
||||
#define INTEL_MSIC_ADC1CNTL2 0x1c1
|
||||
#define INTEL_MSIC_ADC1CNTL3 0x1c2
|
||||
#define INTEL_MSIC_ADC1OFFSETH 0x1c3 /* RO */
|
||||
#define INTEL_MSIC_ADC1OFFSETL 0x1c4 /* RO */
|
||||
#define INTEL_MSIC_ADC1ADDR0 0x1c5
|
||||
#define INTEL_MSIC_ADC1ADDR1 0x1c6
|
||||
#define INTEL_MSIC_ADC1ADDR2 0x1c7
|
||||
#define INTEL_MSIC_ADC1ADDR3 0x1c8
|
||||
#define INTEL_MSIC_ADC1ADDR4 0x1c9
|
||||
#define INTEL_MSIC_ADC1ADDR5 0x1ca
|
||||
#define INTEL_MSIC_ADC1ADDR6 0x1cb
|
||||
#define INTEL_MSIC_ADC1ADDR7 0x1cc
|
||||
#define INTEL_MSIC_ADC1ADDR8 0x1cd
|
||||
#define INTEL_MSIC_ADC1ADDR9 0x1ce
|
||||
#define INTEL_MSIC_ADC1ADDR10 0x1cf
|
||||
#define INTEL_MSIC_ADC1ADDR11 0x1d0
|
||||
#define INTEL_MSIC_ADC1ADDR12 0x1d1
|
||||
#define INTEL_MSIC_ADC1ADDR13 0x1d2
|
||||
#define INTEL_MSIC_ADC1ADDR14 0x1d3
|
||||
#define INTEL_MSIC_ADC1SNS0H 0x1d4 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS0L 0x1d5 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS1H 0x1d6 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS1L 0x1d7 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS2H 0x1d8 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS2L 0x1d9 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS3H 0x1da /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS3L 0x1db /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS4H 0x1dc /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS4L 0x1dd /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS5H 0x1de /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS5L 0x1df /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS6H 0x1e0 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS6L 0x1e1 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS7H 0x1e2 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS7L 0x1e3 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS8H 0x1e4 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS8L 0x1e5 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS9H 0x1e6 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS9L 0x1e7 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS10H 0x1e8 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS10L 0x1e9 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS11H 0x1ea /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS11L 0x1eb /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS12H 0x1ec /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS12L 0x1ed /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS13H 0x1ee /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS13L 0x1ef /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS14H 0x1f0 /* RO */
|
||||
#define INTEL_MSIC_ADC1SNS14L 0x1f1 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV0H 0x1f2 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV0L 0x1f3 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV1H 0x1f4 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV1L 0x1f5 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV2H 0x1f6 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV2L 0x1f7 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV3H 0x1f8 /* RO */
|
||||
#define INTEL_MSIC_ADC1BV3L 0x1f9 /* RO */
|
||||
#define INTEL_MSIC_ADC1BI0H 0x1fa /* RO */
|
||||
#define INTEL_MSIC_ADC1BI0L 0x1fb /* RO */
|
||||
#define INTEL_MSIC_ADC1BI1H 0x1fc /* RO */
|
||||
#define INTEL_MSIC_ADC1BI1L 0x1fd /* RO */
|
||||
#define INTEL_MSIC_ADC1BI2H 0x1fe /* RO */
|
||||
#define INTEL_MSIC_ADC1BI2L 0x1ff /* RO */
|
||||
#define INTEL_MSIC_ADC1BI3H 0x200 /* RO */
|
||||
#define INTEL_MSIC_ADC1BI3L 0x201 /* RO */
|
||||
#define INTEL_MSIC_CCCNTL 0x202
|
||||
#define INTEL_MSIC_CCOFFSETH 0x203 /* RO */
|
||||
#define INTEL_MSIC_CCOFFSETL 0x204 /* RO */
|
||||
#define INTEL_MSIC_CCADCHA 0x205 /* RO */
|
||||
#define INTEL_MSIC_CCADCLA 0x206 /* RO */
|
||||
|
||||
/* AUDIO */
|
||||
#define INTEL_MSIC_AUDPLLCTRL 0x240
|
||||
#define INTEL_MSIC_DMICBUF0123 0x241
|
||||
#define INTEL_MSIC_DMICBUF45 0x242
|
||||
#define INTEL_MSIC_DMICGPO 0x244
|
||||
#define INTEL_MSIC_DMICMUX 0x245
|
||||
#define INTEL_MSIC_DMICCLK 0x246
|
||||
#define INTEL_MSIC_MICBIAS 0x247
|
||||
#define INTEL_MSIC_ADCCONFIG 0x248
|
||||
#define INTEL_MSIC_MICAMP1 0x249
|
||||
#define INTEL_MSIC_MICAMP2 0x24a
|
||||
#define INTEL_MSIC_NOISEMUX 0x24b
|
||||
#define INTEL_MSIC_AUDIOMUX12 0x24c
|
||||
#define INTEL_MSIC_AUDIOMUX34 0x24d
|
||||
#define INTEL_MSIC_AUDIOSINC 0x24e
|
||||
#define INTEL_MSIC_AUDIOTXEN 0x24f
|
||||
#define INTEL_MSIC_HSEPRXCTRL 0x250
|
||||
#define INTEL_MSIC_IHFRXCTRL 0x251
|
||||
#define INTEL_MSIC_VOICETXVOL 0x252
|
||||
#define INTEL_MSIC_SIDETONEVOL 0x253
|
||||
#define INTEL_MSIC_MUSICSHARVOL 0x254
|
||||
#define INTEL_MSIC_VOICETXCTRL 0x255
|
||||
#define INTEL_MSIC_HSMIXER 0x256
|
||||
#define INTEL_MSIC_DACCONFIG 0x257
|
||||
#define INTEL_MSIC_SOFTMUTE 0x258
|
||||
#define INTEL_MSIC_HSLVOLCTRL 0x259
|
||||
#define INTEL_MSIC_HSRVOLCTRL 0x25a
|
||||
#define INTEL_MSIC_IHFLVOLCTRL 0x25b
|
||||
#define INTEL_MSIC_IHFRVOLCTRL 0x25c
|
||||
#define INTEL_MSIC_DRIVEREN 0x25d
|
||||
#define INTEL_MSIC_LINEOUTCTRL 0x25e
|
||||
#define INTEL_MSIC_VIB1CTRL1 0x25f
|
||||
#define INTEL_MSIC_VIB1CTRL2 0x260
|
||||
#define INTEL_MSIC_VIB1CTRL3 0x261
|
||||
#define INTEL_MSIC_VIB1SPIPCM_1 0x262
|
||||
#define INTEL_MSIC_VIB1SPIPCM_2 0x263
|
||||
#define INTEL_MSIC_VIB1CTRL5 0x264
|
||||
#define INTEL_MSIC_VIB2CTRL1 0x265
|
||||
#define INTEL_MSIC_VIB2CTRL2 0x266
|
||||
#define INTEL_MSIC_VIB2CTRL3 0x267
|
||||
#define INTEL_MSIC_VIB2SPIPCM_1 0x268
|
||||
#define INTEL_MSIC_VIB2SPIPCM_2 0x269
|
||||
#define INTEL_MSIC_VIB2CTRL5 0x26a
|
||||
#define INTEL_MSIC_BTNCTRL1 0x26b
|
||||
#define INTEL_MSIC_BTNCTRL2 0x26c
|
||||
#define INTEL_MSIC_PCM1TXSLOT01 0x26d
|
||||
#define INTEL_MSIC_PCM1TXSLOT23 0x26e
|
||||
#define INTEL_MSIC_PCM1TXSLOT45 0x26f
|
||||
#define INTEL_MSIC_PCM1RXSLOT0123 0x270
|
||||
#define INTEL_MSIC_PCM1RXSLOT045 0x271
|
||||
#define INTEL_MSIC_PCM2TXSLOT01 0x272
|
||||
#define INTEL_MSIC_PCM2TXSLOT23 0x273
|
||||
#define INTEL_MSIC_PCM2TXSLOT45 0x274
|
||||
#define INTEL_MSIC_PCM2RXSLOT01 0x275
|
||||
#define INTEL_MSIC_PCM2RXSLOT23 0x276
|
||||
#define INTEL_MSIC_PCM2RXSLOT45 0x277
|
||||
#define INTEL_MSIC_PCM1CTRL1 0x278
|
||||
#define INTEL_MSIC_PCM1CTRL2 0x279
|
||||
#define INTEL_MSIC_PCM1CTRL3 0x27a
|
||||
#define INTEL_MSIC_PCM2CTRL1 0x27b
|
||||
#define INTEL_MSIC_PCM2CTRL2 0x27c
|
||||
|
||||
/* HDMI */
|
||||
#define INTEL_MSIC_HDMIPUEN 0x280
|
||||
#define INTEL_MSIC_HDMISTATUS 0x281 /* RO */
|
||||
|
||||
/* Physical address of the start of the MSIC interrupt tree in SRAM */
|
||||
#define INTEL_MSIC_IRQ_PHYS_BASE 0xffff7fc0
|
||||
|
||||
/**
|
||||
* struct intel_msic_gpio_pdata - platform data for the MSIC GPIO driver
|
||||
* @gpio_base: base number for the GPIOs
|
||||
*/
|
||||
struct intel_msic_gpio_pdata {
|
||||
unsigned gpio_base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct intel_msic_ocd_pdata - platform data for the MSIC OCD driver
|
||||
* @gpio: GPIO number used for OCD interrupts
|
||||
*
|
||||
* The MSIC MFD driver converts @gpio into an IRQ number and passes it to
|
||||
* the OCD driver as %IORESOURCE_IRQ.
|
||||
*/
|
||||
struct intel_msic_ocd_pdata {
|
||||
unsigned gpio;
|
||||
};
|
||||
|
||||
/* MSIC embedded blocks (subdevices) */
|
||||
enum intel_msic_block {
|
||||
INTEL_MSIC_BLOCK_TOUCH,
|
||||
INTEL_MSIC_BLOCK_ADC,
|
||||
INTEL_MSIC_BLOCK_BATTERY,
|
||||
INTEL_MSIC_BLOCK_GPIO,
|
||||
INTEL_MSIC_BLOCK_AUDIO,
|
||||
INTEL_MSIC_BLOCK_HDMI,
|
||||
INTEL_MSIC_BLOCK_THERMAL,
|
||||
INTEL_MSIC_BLOCK_POWER_BTN,
|
||||
INTEL_MSIC_BLOCK_OCD,
|
||||
|
||||
INTEL_MSIC_BLOCK_LAST,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct intel_msic_platform_data - platform data for the MSIC driver
|
||||
* @irq: array of interrupt numbers, one per device. If @irq is set to %0
|
||||
* for a given block, the corresponding platform device is not
|
||||
* created. For devices which don't have an interrupt, use %0xff
|
||||
* (this is same as in SFI spec).
|
||||
* @gpio: platform data for the MSIC GPIO driver
|
||||
* @ocd: platform data for the MSIC OCD driver
|
||||
*
|
||||
* Once the MSIC driver is initialized, the register interface is ready to
|
||||
* use. All the platform devices for subdevices are created after the
|
||||
* register interface is ready so that we can guarantee its availability to
|
||||
* the subdevice drivers.
|
||||
*
|
||||
* Interrupt numbers are passed to the subdevices via %IORESOURCE_IRQ
|
||||
* resources of the created platform device.
|
||||
*/
|
||||
struct intel_msic_platform_data {
|
||||
int irq[INTEL_MSIC_BLOCK_LAST];
|
||||
struct intel_msic_gpio_pdata *gpio;
|
||||
struct intel_msic_ocd_pdata *ocd;
|
||||
};
|
||||
|
||||
struct intel_msic;
|
||||
|
||||
extern int intel_msic_reg_read(unsigned short reg, u8 *val);
|
||||
extern int intel_msic_reg_write(unsigned short reg, u8 val);
|
||||
extern int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask);
|
||||
extern int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count);
|
||||
extern int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count);
|
||||
|
||||
/*
|
||||
* pdev_to_intel_msic - gets an MSIC instance from the platform device
|
||||
* @pdev: platform device pointer
|
||||
*
|
||||
* The client drivers need to have pointer to the MSIC instance if they
|
||||
* want to call intel_msic_irq_read(). This macro can be used for
|
||||
* convenience to get the MSIC pointer from @pdev where needed. This is
|
||||
* _only_ valid for devices which are managed by the MSIC.
|
||||
*/
|
||||
#define pdev_to_intel_msic(pdev) (dev_get_drvdata(pdev->dev.parent))
|
||||
|
||||
extern int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg,
|
||||
u8 *val);
|
||||
|
||||
#endif /* __LINUX_MFD_INTEL_MSIC_H__ */
|
@@ -1,210 +0,0 @@
|
||||
/* sfi.h Simple Firmware Interface */
|
||||
|
||||
/*
|
||||
|
||||
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
redistributing this file, you may do so under either license.
|
||||
|
||||
GPL LICENSE SUMMARY
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
The full GNU General Public License is included in this distribution
|
||||
in the file called LICENSE.GPL.
|
||||
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SFI_H
|
||||
#define _LINUX_SFI_H
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Table signatures reserved by the SFI specification */
|
||||
#define SFI_SIG_SYST "SYST"
|
||||
#define SFI_SIG_FREQ "FREQ"
|
||||
#define SFI_SIG_IDLE "IDLE"
|
||||
#define SFI_SIG_CPUS "CPUS"
|
||||
#define SFI_SIG_MTMR "MTMR"
|
||||
#define SFI_SIG_MRTC "MRTC"
|
||||
#define SFI_SIG_MMAP "MMAP"
|
||||
#define SFI_SIG_APIC "APIC"
|
||||
#define SFI_SIG_XSDT "XSDT"
|
||||
#define SFI_SIG_WAKE "WAKE"
|
||||
#define SFI_SIG_DEVS "DEVS"
|
||||
#define SFI_SIG_GPIO "GPIO"
|
||||
|
||||
#define SFI_SIGNATURE_SIZE 4
|
||||
#define SFI_OEM_ID_SIZE 6
|
||||
#define SFI_OEM_TABLE_ID_SIZE 8
|
||||
|
||||
#define SFI_NAME_LEN 16
|
||||
|
||||
#define SFI_SYST_SEARCH_BEGIN 0x000E0000
|
||||
#define SFI_SYST_SEARCH_END 0x000FFFFF
|
||||
|
||||
#define SFI_GET_NUM_ENTRIES(ptable, entry_type) \
|
||||
((ptable->header.len - sizeof(struct sfi_table_header)) / \
|
||||
(sizeof(entry_type)))
|
||||
/*
|
||||
* Table structures must be byte-packed to match the SFI specification,
|
||||
* as they are provided by the BIOS.
|
||||
*/
|
||||
struct sfi_table_header {
|
||||
char sig[SFI_SIGNATURE_SIZE];
|
||||
u32 len;
|
||||
u8 rev;
|
||||
u8 csum;
|
||||
char oem_id[SFI_OEM_ID_SIZE];
|
||||
char oem_table_id[SFI_OEM_TABLE_ID_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct sfi_table_simple {
|
||||
struct sfi_table_header header;
|
||||
u64 pentry[1];
|
||||
} __packed;
|
||||
|
||||
/* Comply with UEFI spec 2.1 */
|
||||
struct sfi_mem_entry {
|
||||
u32 type;
|
||||
u64 phys_start;
|
||||
u64 virt_start;
|
||||
u64 pages;
|
||||
u64 attrib;
|
||||
} __packed;
|
||||
|
||||
struct sfi_cpu_table_entry {
|
||||
u32 apic_id;
|
||||
} __packed;
|
||||
|
||||
struct sfi_cstate_table_entry {
|
||||
u32 hint; /* MWAIT hint */
|
||||
u32 latency; /* latency in ms */
|
||||
} __packed;
|
||||
|
||||
struct sfi_apic_table_entry {
|
||||
u64 phys_addr; /* phy base addr for APIC reg */
|
||||
} __packed;
|
||||
|
||||
struct sfi_freq_table_entry {
|
||||
u32 freq_mhz; /* in MHZ */
|
||||
u32 latency; /* transition latency in ms */
|
||||
u32 ctrl_val; /* value to write to PERF_CTL */
|
||||
} __packed;
|
||||
|
||||
struct sfi_wake_table_entry {
|
||||
u64 phys_addr; /* pointer to where the wake vector locates */
|
||||
} __packed;
|
||||
|
||||
struct sfi_timer_table_entry {
|
||||
u64 phys_addr; /* phy base addr for the timer */
|
||||
u32 freq_hz; /* in HZ */
|
||||
u32 irq;
|
||||
} __packed;
|
||||
|
||||
struct sfi_rtc_table_entry {
|
||||
u64 phys_addr; /* phy base addr for the RTC */
|
||||
u32 irq;
|
||||
} __packed;
|
||||
|
||||
struct sfi_device_table_entry {
|
||||
u8 type; /* bus type, I2C, SPI or ...*/
|
||||
#define SFI_DEV_TYPE_SPI 0
|
||||
#define SFI_DEV_TYPE_I2C 1
|
||||
#define SFI_DEV_TYPE_UART 2
|
||||
#define SFI_DEV_TYPE_HSI 3
|
||||
#define SFI_DEV_TYPE_IPC 4
|
||||
#define SFI_DEV_TYPE_SD 5
|
||||
|
||||
u8 host_num; /* attached to host 0, 1...*/
|
||||
u16 addr;
|
||||
u8 irq;
|
||||
u32 max_freq;
|
||||
char name[SFI_NAME_LEN];
|
||||
} __packed;
|
||||
|
||||
struct sfi_gpio_table_entry {
|
||||
char controller_name[SFI_NAME_LEN];
|
||||
u16 pin_no;
|
||||
char pin_name[SFI_NAME_LEN];
|
||||
} __packed;
|
||||
|
||||
typedef int (*sfi_table_handler) (struct sfi_table_header *table);
|
||||
|
||||
#ifdef CONFIG_SFI
|
||||
extern void __init sfi_init(void);
|
||||
extern int __init sfi_platform_init(void);
|
||||
extern void __init sfi_init_late(void);
|
||||
extern int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id,
|
||||
sfi_table_handler handler);
|
||||
|
||||
extern int sfi_disabled;
|
||||
static inline void disable_sfi(void)
|
||||
{
|
||||
sfi_disabled = 1;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_SFI */
|
||||
|
||||
static inline void sfi_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void sfi_init_late(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define sfi_disabled 0
|
||||
|
||||
static inline int sfi_table_parse(char *signature, char *oem_id,
|
||||
char *oem_table_id,
|
||||
sfi_table_handler handler)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_SFI */
|
||||
|
||||
#endif /*_LINUX_SFI_H*/
|
@@ -1,93 +0,0 @@
|
||||
/* sfi.h Simple Firmware Interface */
|
||||
|
||||
/*
|
||||
|
||||
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
redistributing this file, you may do so under either license.
|
||||
|
||||
GPL LICENSE SUMMARY
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
The full GNU General Public License is included in this distribution
|
||||
in the file called LICENSE.GPL.
|
||||
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SFI_ACPI_H
|
||||
#define _LINUX_SFI_ACPI_H
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/sfi.h>
|
||||
|
||||
#ifdef CONFIG_SFI
|
||||
extern int sfi_acpi_table_parse(char *signature, char *oem_id,
|
||||
char *oem_table_id,
|
||||
int (*handler)(struct acpi_table_header *));
|
||||
|
||||
static inline int __init acpi_sfi_table_parse(char *signature,
|
||||
int (*handler)(struct acpi_table_header *))
|
||||
{
|
||||
if (!acpi_table_parse(signature, handler))
|
||||
return 0;
|
||||
|
||||
return sfi_acpi_table_parse(signature, NULL, NULL, handler);
|
||||
}
|
||||
#else /* !CONFIG_SFI */
|
||||
static inline int sfi_acpi_table_parse(char *signature, char *oem_id,
|
||||
char *oem_table_id,
|
||||
int (*handler)(struct acpi_table_header *))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int __init acpi_sfi_table_parse(char *signature,
|
||||
int (*handler)(struct acpi_table_header *))
|
||||
{
|
||||
return acpi_table_parse(signature, handler);
|
||||
}
|
||||
#endif /* !CONFIG_SFI */
|
||||
|
||||
#endif /*_LINUX_SFI_ACPI_H*/
|
@@ -74,7 +74,6 @@
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/sfi.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/perf_event.h>
|
||||
@@ -1054,7 +1053,6 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
|
||||
|
||||
acpi_subsystem_init();
|
||||
arch_post_acpi_subsys_init();
|
||||
sfi_init_late();
|
||||
kcsan_init();
|
||||
|
||||
/* Do the rest non-__init'ed, we're now alive */
|
||||
|
Reference in New Issue
Block a user