forked from mirrors/linux
		
	sfi: Remove framework for deprecated firmware
SFI-based platforms are gone. So does this framework. This removes mention of SFI through the drivers and other code as well. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									73f70d6c20
								
							
						
					
					
						commit
						4590d98f5a
					
				
					 42 changed files with 14 additions and 2695 deletions
				
			
		| 
						 | 
					@ -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".
 | 
							is connected. example: "/dev/ttyS0".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		The device name flows down to architecture specific board
 | 
							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
 | 
							firmware. The name exposed is read from the user-space
 | 
				
			||||||
		dameon and opens the device when install is requested.
 | 
							dameon and opens the device when install is requested.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16234,13 +16234,6 @@ S:	Maintained
 | 
				
			||||||
F:	Documentation/fb/sm712fb.rst
 | 
					F:	Documentation/fb/sm712fb.rst
 | 
				
			||||||
F:	drivers/video/fbdev/sm712*
 | 
					F:	drivers/video/fbdev/sm712*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
					SIMPLEFB FB DRIVER
 | 
				
			||||||
M:	Hans de Goede <hdegoede@redhat.com>
 | 
					M:	Hans de Goede <hdegoede@redhat.com>
 | 
				
			||||||
L:	linux-fbdev@vger.kernel.org
 | 
					L:	linux-fbdev@vger.kernel.org
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,7 +444,7 @@ config X86_X2APIC
 | 
				
			||||||
	  If you don't know what to do here, say N.
 | 
						  If you don't know what to do here, say N.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config X86_MPPARSE
 | 
					config X86_MPPARSE
 | 
				
			||||||
	bool "Enable MPS table" if ACPI || SFI
 | 
						bool "Enable MPS table" if ACPI
 | 
				
			||||||
	default y
 | 
						default y
 | 
				
			||||||
	depends on X86_LOCAL_APIC
 | 
						depends on X86_LOCAL_APIC
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
| 
						 | 
					@ -603,7 +603,6 @@ config X86_INTEL_MID
 | 
				
			||||||
	depends on PCI
 | 
						depends on PCI
 | 
				
			||||||
	depends on X86_64 || (PCI_GOANY && X86_32)
 | 
						depends on X86_64 || (PCI_GOANY && X86_32)
 | 
				
			||||||
	depends on X86_IO_APIC
 | 
						depends on X86_IO_APIC
 | 
				
			||||||
	select SFI
 | 
					 | 
				
			||||||
	select I2C
 | 
						select I2C
 | 
				
			||||||
	select DW_APB_TIMER
 | 
						select DW_APB_TIMER
 | 
				
			||||||
	select APB_TIMER
 | 
						select APB_TIMER
 | 
				
			||||||
| 
						 | 
					@ -2457,8 +2456,6 @@ source "kernel/power/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "drivers/acpi/Kconfig"
 | 
					source "drivers/acpi/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "drivers/sfi/Kconfig"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
config X86_APM_BOOT
 | 
					config X86_APM_BOOT
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
	depends on APM
 | 
						depends on APM
 | 
				
			||||||
| 
						 | 
					@ -2645,7 +2642,7 @@ config PCI_DIRECT
 | 
				
			||||||
config PCI_MMCONFIG
 | 
					config PCI_MMCONFIG
 | 
				
			||||||
	bool "Support mmconfig PCI config space access" if X86_64
 | 
						bool "Support mmconfig PCI config space access" if X86_64
 | 
				
			||||||
	default y
 | 
						default y
 | 
				
			||||||
	depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST)
 | 
						depends on PCI && (ACPI || JAILHOUSE_GUEST)
 | 
				
			||||||
	depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
 | 
						depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config PCI_OLPC
 | 
					config PCI_OLPC
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@
 | 
				
			||||||
#ifndef _ASM_X86_INTEL_MID_H
 | 
					#ifndef _ASM_X86_INTEL_MID_H
 | 
				
			||||||
#define _ASM_X86_INTEL_MID_H
 | 
					#define _ASM_X86_INTEL_MID_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/sfi.h>
 | 
					 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/platform_device.h>
 | 
					#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,39 +21,6 @@ extern void intel_mid_pwr_power_off(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int intel_mid_pwr_get_lss_id(struct pci_dev *pdev);
 | 
					extern int intel_mid_pwr_get_lss_id(struct pci_dev *pdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int get_gpio_by_name(const char *name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Here defines the array of devices platform data that IAFW would export
 | 
					 | 
				
			||||||
 * through SFI "DEVS" table, we use name and type to match the device and
 | 
					 | 
				
			||||||
 * its platform data.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct devs_id {
 | 
					 | 
				
			||||||
	char name[SFI_NAME_LEN + 1];
 | 
					 | 
				
			||||||
	u8 type;
 | 
					 | 
				
			||||||
	u8 delay;
 | 
					 | 
				
			||||||
	void *(*get_platform_data)(void *info);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#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
 | 
					 * Medfield is the follow-up of Moorestown, it combines two chip solution into
 | 
				
			||||||
 * one. Other than that it also added always-on and constant tsc and lapic
 | 
					 * one. Other than that it also added always-on and constant tsc and lapic
 | 
				
			||||||
| 
						 | 
					@ -99,7 +65,4 @@ static inline void intel_scu_devices_destroy(void) { }
 | 
				
			||||||
/* FSB 83MHz */
 | 
					/* FSB 83MHz */
 | 
				
			||||||
#define BSEL_SOC_FUSE_111		0x7
 | 
					#define BSEL_SOC_FUSE_111		0x7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The offset for the mapping of global gpio pin to irq */
 | 
					 | 
				
			||||||
#define INTEL_MID_IRQ_OFFSET		0x100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _ASM_X86_INTEL_MID_H */
 | 
					#endif /* _ASM_X86_INTEL_MID_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,73 +2,17 @@
 | 
				
			||||||
#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
 | 
					#ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
 | 
				
			||||||
#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
 | 
					#define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/notifier.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IPCMSG_INDIRECT_READ	0x02
 | 
					 | 
				
			||||||
#define IPCMSG_INDIRECT_WRITE	0x05
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IPCMSG_COLD_OFF		0x80	/* Only for Tangier */
 | 
					#define IPCMSG_COLD_OFF		0x80	/* Only for Tangier */
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IPCMSG_WARM_RESET	0xF0
 | 
					 | 
				
			||||||
#define IPCMSG_COLD_RESET	0xF1
 | 
					#define IPCMSG_COLD_RESET	0xF1
 | 
				
			||||||
#define IPCMSG_SOFT_RESET	0xF2
 | 
					 | 
				
			||||||
#define IPCMSG_COLD_BOOT	0xF3
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Don't call these in new code - they will be removed eventually */
 | 
					/* Don't call these in new code - they will be removed eventually */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 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 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 */
 | 
					/* Issue commands to the SCU with or without data */
 | 
				
			||||||
static inline int intel_scu_ipc_simple_command(int cmd, int sub)
 | 
					static inline int intel_scu_ipc_simple_command(int cmd, int sub)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return intel_scu_ipc_dev_simple_command(NULL, cmd, 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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,8 +10,6 @@
 | 
				
			||||||
#ifndef _PLATFORM_SST_AUDIO_H_
 | 
					#ifndef _PLATFORM_SST_AUDIO_H_
 | 
				
			||||||
#define _PLATFORM_SST_AUDIO_H_
 | 
					#define _PLATFORM_SST_AUDIO_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/sfi.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_NUM_STREAMS_MRFLD	25
 | 
					#define MAX_NUM_STREAMS_MRFLD	25
 | 
				
			||||||
#define MAX_NUM_STREAMS	MAX_NUM_STREAMS_MRFLD
 | 
					#define MAX_NUM_STREAMS	MAX_NUM_STREAMS_MRFLD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -198,7 +198,7 @@ static int __init parse_noapic(char *str)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
early_param("noapic", parse_noapic);
 | 
					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)
 | 
					void mp_save_irq(struct mpc_intsrc *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						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
 | 
						 * 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().
 | 
						 * we are still using bootmem allocator. So delay it to setup_IO_APIC().
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (hotplug) {
 | 
						if (hotplug) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,6 @@
 | 
				
			||||||
#include <linux/memblock.h>
 | 
					#include <linux/memblock.h>
 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/root_dev.h>
 | 
					#include <linux/root_dev.h>
 | 
				
			||||||
#include <linux/sfi.h>
 | 
					 | 
				
			||||||
#include <linux/hugetlb.h>
 | 
					#include <linux/hugetlb.h>
 | 
				
			||||||
#include <linux/tboot.h>
 | 
					#include <linux/tboot.h>
 | 
				
			||||||
#include <linux/usb/xhci-dbgp.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.
 | 
						 * Read APIC and some other early information from ACPI tables.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	acpi_boot_init();
 | 
						acpi_boot_init();
 | 
				
			||||||
	sfi_init();
 | 
					 | 
				
			||||||
	x86_dtb_init();
 | 
						x86_dtb_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,9 +11,9 @@
 | 
				
			||||||
 * themselves.
 | 
					 * themselves.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/acpi.h>
 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/init.h>
 | 
					#include <linux/init.h>
 | 
				
			||||||
#include <linux/sfi_acpi.h>
 | 
					 | 
				
			||||||
#include <linux/bitmap.h>
 | 
					#include <linux/bitmap.h>
 | 
				
			||||||
#include <linux/dmi.h>
 | 
					#include <linux/dmi.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
| 
						 | 
					@ -665,7 +665,7 @@ void __init pci_mmcfg_early_init(void)
 | 
				
			||||||
		if (pci_mmcfg_check_hostbridge())
 | 
							if (pci_mmcfg_check_hostbridge())
 | 
				
			||||||
			known_bridge = 1;
 | 
								known_bridge = 1;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
 | 
								acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
 | 
				
			||||||
		__pci_mmcfg_init(1);
 | 
							__pci_mmcfg_init(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		set_apei_filter();
 | 
							set_apei_filter();
 | 
				
			||||||
| 
						 | 
					@ -683,7 +683,7 @@ void __init pci_mmcfg_late_init(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* MMCONFIG hasn't been enabled yet, try again */
 | 
						/* MMCONFIG hasn't been enabled yet, try again */
 | 
				
			||||||
	if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
 | 
						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);
 | 
							__pci_mmcfg_init(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,5 @@ obj-y	+= intel-mid/
 | 
				
			||||||
obj-y	+= intel-quark/
 | 
					obj-y	+= intel-quark/
 | 
				
			||||||
obj-y	+= olpc/
 | 
					obj-y	+= olpc/
 | 
				
			||||||
obj-y	+= scx200/
 | 
					obj-y	+= scx200/
 | 
				
			||||||
obj-y	+= sfi/
 | 
					 | 
				
			||||||
obj-y	+= ts5500/
 | 
					obj-y	+= ts5500/
 | 
				
			||||||
obj-y	+= uv/
 | 
					obj-y	+= uv/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,2 @@
 | 
				
			||||||
# SPDX-License-Identifier: GPL-2.0-only
 | 
					# SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o pwr.o
 | 
					obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o pwr.o
 | 
				
			||||||
 | 
					 | 
				
			||||||
# SFI specific code
 | 
					 | 
				
			||||||
ifdef CONFIG_X86_INTEL_MID
 | 
					 | 
				
			||||||
obj-$(CONFIG_SFI) += sfi.o device_libs/
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,23 +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
 | 
					 | 
				
			||||||
# 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_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,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,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);
 | 
					 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,6 @@
 | 
				
			||||||
#include <linux/interrupt.h>
 | 
					#include <linux/interrupt.h>
 | 
				
			||||||
#include <linux/regulator/machine.h>
 | 
					#include <linux/regulator/machine.h>
 | 
				
			||||||
#include <linux/scatterlist.h>
 | 
					#include <linux/scatterlist.h>
 | 
				
			||||||
#include <linux/sfi.h>
 | 
					 | 
				
			||||||
#include <linux/irq.h>
 | 
					#include <linux/irq.h>
 | 
				
			||||||
#include <linux/export.h>
 | 
					#include <linux/export.h>
 | 
				
			||||||
#include <linux/notifier.h>
 | 
					#include <linux/notifier.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,419 +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/io.h>
 | 
					 | 
				
			||||||
#include <asm/i8259.h>
 | 
					 | 
				
			||||||
#include <asm/intel_scu_ipc.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 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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-y				+= char/ipmi/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_ACPI)		+= acpi/
 | 
					obj-$(CONFIG_ACPI)		+= acpi/
 | 
				
			||||||
obj-$(CONFIG_SFI)		+= sfi/
 | 
					
 | 
				
			||||||
# PnP must come after ACPI since it will eventually need to check if acpi
 | 
					# PnP must come after ACPI since it will eventually need to check if acpi
 | 
				
			||||||
# was used and do nothing if so
 | 
					# was used and do nothing if so
 | 
				
			||||||
obj-$(CONFIG_PNP)		+= pnp/
 | 
					obj-$(CONFIG_PNP)		+= pnp/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,6 @@
 | 
				
			||||||
static int intel_scu_pci_probe(struct pci_dev *pdev,
 | 
					static int intel_scu_pci_probe(struct pci_dev *pdev,
 | 
				
			||||||
			       const struct pci_device_id *id)
 | 
								       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_data scu_data = {};
 | 
				
			||||||
	struct intel_scu_ipc_dev *scu;
 | 
						struct intel_scu_ipc_dev *scu;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -30,27 +29,14 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
 | 
				
			||||||
	scu_data.irq = pdev->irq;
 | 
						scu_data.irq = pdev->irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scu = intel_scu_ipc_register(&pdev->dev, &scu_data);
 | 
						scu = intel_scu_ipc_register(&pdev->dev, &scu_data);
 | 
				
			||||||
	if (IS_ERR(scu))
 | 
						return PTR_ERR_OR_ZERO(scu);
 | 
				
			||||||
		return PTR_ERR(scu);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (setup_fn)
 | 
					 | 
				
			||||||
		setup_fn();
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void intel_mid_scu_setup(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	intel_scu_devices_create();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct pci_device_id pci_ids[] = {
 | 
					static const struct pci_device_id pci_ids[] = {
 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x080e),
 | 
						{ PCI_VDEVICE(INTEL, 0x080e) },
 | 
				
			||||||
	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
 | 
						{ PCI_VDEVICE(INTEL, 0x08ea) },
 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x08ea),
 | 
					 | 
				
			||||||
	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
 | 
					 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x0a94) },
 | 
						{ PCI_VDEVICE(INTEL, 0x0a94) },
 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x11a0),
 | 
						{ PCI_VDEVICE(INTEL, 0x11a0) },
 | 
				
			||||||
	  .driver_data = (kernel_ulong_t)intel_mid_scu_setup },
 | 
					 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x1a94) },
 | 
						{ PCI_VDEVICE(INTEL, 0x1a94) },
 | 
				
			||||||
	{ PCI_VDEVICE(INTEL, 0x5a94) },
 | 
						{ 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);
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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/kgdb.h>
 | 
				
			||||||
#include <linux/ftrace.h>
 | 
					#include <linux/ftrace.h>
 | 
				
			||||||
#include <linux/async.h>
 | 
					#include <linux/async.h>
 | 
				
			||||||
#include <linux/sfi.h>
 | 
					 | 
				
			||||||
#include <linux/shmem_fs.h>
 | 
					#include <linux/shmem_fs.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/perf_event.h>
 | 
					#include <linux/perf_event.h>
 | 
				
			||||||
| 
						 | 
					@ -1054,7 +1053,6 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	acpi_subsystem_init();
 | 
						acpi_subsystem_init();
 | 
				
			||||||
	arch_post_acpi_subsys_init();
 | 
						arch_post_acpi_subsys_init();
 | 
				
			||||||
	sfi_init_late();
 | 
					 | 
				
			||||||
	kcsan_init();
 | 
						kcsan_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Do the rest non-__init'ed, we're now alive */
 | 
						/* Do the rest non-__init'ed, we're now alive */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue