Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

authored by

Andy Shevchenko and committed by
Rafael J. Wysocki
4590d98f 73f70d6c

+14 -2695
-15
Documentation/ABI/testing/sysfs-firmware-sfi
··· 1 - What: /sys/firmware/sfi/tables/ 2 - Date: May 2010 3 - Contact: Len Brown <lenb@kernel.org> 4 - Description: 5 - SFI defines a number of small static memory tables 6 - so the kernel can get platform information from firmware. 7 - 8 - The tables are defined in the latest SFI specification: 9 - http://simplefirmware.org/documentation 10 - 11 - While the tables are used by the kernel, user-space 12 - can observe them this way:: 13 - 14 - # cd /sys/firmware/sfi/tables 15 - # cat $TABLENAME > $TABLENAME.bin
+1 -1
Documentation/ABI/testing/sysfs-platform-kim
··· 7 7 is connected. example: "/dev/ttyS0". 8 8 9 9 The device name flows down to architecture specific board 10 - initialization file from the SFI/ATAGS bootloader 10 + initialization file from the ATAGS bootloader 11 11 firmware. The name exposed is read from the user-space 12 12 dameon and opens the device when install is requested. 13 13
-7
MAINTAINERS
··· 16234 16234 F: Documentation/fb/sm712fb.rst 16235 16235 F: drivers/video/fbdev/sm712* 16236 16236 16237 - SIMPLE FIRMWARE INTERFACE (SFI) 16238 - S: Obsolete 16239 - W: http://simplefirmware.org/ 16240 - F: arch/x86/platform/sfi/ 16241 - F: drivers/sfi/ 16242 - F: include/linux/sfi*.h 16243 - 16244 16237 SIMPLEFB FB DRIVER 16245 16238 M: Hans de Goede <hdegoede@redhat.com> 16246 16239 L: linux-fbdev@vger.kernel.org
+2 -5
arch/x86/Kconfig
··· 444 444 If you don't know what to do here, say N. 445 445 446 446 config X86_MPPARSE 447 - bool "Enable MPS table" if ACPI || SFI 447 + bool "Enable MPS table" if ACPI 448 448 default y 449 449 depends on X86_LOCAL_APIC 450 450 help ··· 603 603 depends on PCI 604 604 depends on X86_64 || (PCI_GOANY && X86_32) 605 605 depends on X86_IO_APIC 606 - select SFI 607 606 select I2C 608 607 select DW_APB_TIMER 609 608 select APB_TIMER ··· 2456 2457 2457 2458 source "drivers/acpi/Kconfig" 2458 2459 2459 - source "drivers/sfi/Kconfig" 2460 - 2461 2460 config X86_APM_BOOT 2462 2461 def_bool y 2463 2462 depends on APM ··· 2642 2645 config PCI_MMCONFIG 2643 2646 bool "Support mmconfig PCI config space access" if X86_64 2644 2647 default y 2645 - depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST) 2648 + depends on PCI && (ACPI || JAILHOUSE_GUEST) 2646 2649 depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG) 2647 2650 2648 2651 config PCI_OLPC
-37
arch/x86/include/asm/intel-mid.h
··· 7 7 #ifndef _ASM_X86_INTEL_MID_H 8 8 #define _ASM_X86_INTEL_MID_H 9 9 10 - #include <linux/sfi.h> 11 10 #include <linux/pci.h> 12 11 #include <linux/platform_device.h> 13 12 ··· 20 21 #define INTEL_MID_PWR_LSS_TYPE (1 << 7) 21 22 22 23 extern int intel_mid_pwr_get_lss_id(struct pci_dev *pdev); 23 - 24 - extern int get_gpio_by_name(const char *name); 25 - 26 - /* 27 - * Here defines the array of devices platform data that IAFW would export 28 - * through SFI "DEVS" table, we use name and type to match the device and 29 - * its platform data. 30 - */ 31 - struct devs_id { 32 - char name[SFI_NAME_LEN + 1]; 33 - u8 type; 34 - u8 delay; 35 - void *(*get_platform_data)(void *info); 36 - }; 37 - 38 - #define sfi_device(i) \ 39 - static const struct devs_id *const __intel_mid_sfi_##i##_dev __used \ 40 - __section(".x86_intel_mid_dev.init") = &i 41 - 42 - /** 43 - * struct mid_sd_board_info - template for SD device creation 44 - * @name: identifies the driver 45 - * @bus_num: board-specific identifier for a given SD controller 46 - * @max_clk: the maximum frequency device supports 47 - * @platform_data: the particular data stored there is driver-specific 48 - */ 49 - struct mid_sd_board_info { 50 - char name[SFI_NAME_LEN]; 51 - int bus_num; 52 - unsigned short addr; 53 - u32 max_clk; 54 - void *platform_data; 55 - }; 56 24 57 25 /* 58 26 * Medfield is the follow-up of Moorestown, it combines two chip solution into ··· 64 98 #define BSEL_SOC_FUSE_101 0x5 65 99 /* FSB 83MHz */ 66 100 #define BSEL_SOC_FUSE_111 0x7 67 - 68 - /* The offset for the mapping of global gpio pin to irq */ 69 - #define INTEL_MID_IRQ_OFFSET 0x100 70 101 71 102 #endif /* _ASM_X86_INTEL_MID_H */
+1 -57
arch/x86/include/asm/intel_scu_ipc_legacy.h
··· 2 2 #ifndef _ASM_X86_INTEL_SCU_IPC_LEGACY_H_ 3 3 #define _ASM_X86_INTEL_SCU_IPC_LEGACY_H_ 4 4 5 - #include <linux/notifier.h> 6 - 7 - #define IPCMSG_INDIRECT_READ 0x02 8 - #define IPCMSG_INDIRECT_WRITE 0x05 5 + #include <linux/types.h> 9 6 10 7 #define IPCMSG_COLD_OFF 0x80 /* Only for Tangier */ 11 - 12 - #define IPCMSG_WARM_RESET 0xF0 13 8 #define IPCMSG_COLD_RESET 0xF1 14 - #define IPCMSG_SOFT_RESET 0xF2 15 - #define IPCMSG_COLD_BOOT 0xF3 16 9 17 10 /* Don't call these in new code - they will be removed eventually */ 18 - 19 - /* Read a vector */ 20 - static inline int intel_scu_ipc_readv(u16 *addr, u8 *data, int len) 21 - { 22 - return intel_scu_ipc_dev_readv(NULL, addr, data, len); 23 - } 24 - 25 - /* Write a vector */ 26 - static inline int intel_scu_ipc_writev(u16 *addr, u8 *data, int len) 27 - { 28 - return intel_scu_ipc_dev_writev(NULL, addr, data, len); 29 - } 30 - 31 - /* Update single register based on the mask */ 32 - static inline int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask) 33 - { 34 - return intel_scu_ipc_dev_update(NULL, addr, data, mask); 35 - } 36 11 37 12 /* Issue commands to the SCU with or without data */ 38 13 static inline int intel_scu_ipc_simple_command(int cmd, int sub) 39 14 { 40 15 return intel_scu_ipc_dev_simple_command(NULL, cmd, sub); 41 16 } 42 - 43 - static inline int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, 44 - u32 *out, int outlen) 45 - { 46 - /* New API takes both inlen and outlen as bytes so convert here */ 47 - size_t inbytes = inlen * sizeof(u32); 48 - size_t outbytes = outlen * sizeof(u32); 49 - 50 - return intel_scu_ipc_dev_command_with_size(NULL, cmd, sub, in, inbytes, 51 - inlen, out, outbytes); 52 - } 53 - 54 - extern struct blocking_notifier_head intel_scu_notifier; 55 - 56 - static inline void intel_scu_notifier_add(struct notifier_block *nb) 57 - { 58 - blocking_notifier_chain_register(&intel_scu_notifier, nb); 59 - } 60 - 61 - static inline void intel_scu_notifier_remove(struct notifier_block *nb) 62 - { 63 - blocking_notifier_chain_unregister(&intel_scu_notifier, nb); 64 - } 65 - 66 - static inline int intel_scu_notifier_post(unsigned long v, void *p) 67 - { 68 - return blocking_notifier_call_chain(&intel_scu_notifier, v, p); 69 - } 70 - 71 - #define SCU_AVAILABLE 1 72 - #define SCU_DOWN 2 73 17 74 18 #endif
-2
arch/x86/include/asm/platform_sst_audio.h
··· 10 10 #ifndef _PLATFORM_SST_AUDIO_H_ 11 11 #define _PLATFORM_SST_AUDIO_H_ 12 12 13 - #include <linux/sfi.h> 14 - 15 13 #define MAX_NUM_STREAMS_MRFLD 25 16 14 #define MAX_NUM_STREAMS MAX_NUM_STREAMS_MRFLD 17 15
+2 -2
arch/x86/kernel/apic/io_apic.c
··· 198 198 } 199 199 early_param("noapic", parse_noapic); 200 200 201 - /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ 201 + /* Will be called in mpparse/ACPI codes for saving IRQ info */ 202 202 void mp_save_irq(struct mpc_intsrc *m) 203 203 { 204 204 int i; ··· 2863 2863 2864 2864 /* 2865 2865 * If mp_register_ioapic() is called during early boot stage when 2866 - * walking ACPI/SFI/DT tables, it's too early to create irqdomain, 2866 + * walking ACPI/DT tables, it's too early to create irqdomain, 2867 2867 * we are still using bootmem allocator. So delay it to setup_IO_APIC(). 2868 2868 */ 2869 2869 if (hotplug) {
-2
arch/x86/kernel/setup.c
··· 16 16 #include <linux/memblock.h> 17 17 #include <linux/pci.h> 18 18 #include <linux/root_dev.h> 19 - #include <linux/sfi.h> 20 19 #include <linux/hugetlb.h> 21 20 #include <linux/tboot.h> 22 21 #include <linux/usb/xhci-dbgp.h> ··· 1184 1185 * Read APIC and some other early information from ACPI tables. 1185 1186 */ 1186 1187 acpi_boot_init(); 1187 - sfi_init(); 1188 1188 x86_dtb_init(); 1189 1189 1190 1190 /*
+3 -3
arch/x86/pci/mmconfig-shared.c
··· 11 11 * themselves. 12 12 */ 13 13 14 + #include <linux/acpi.h> 14 15 #include <linux/pci.h> 15 16 #include <linux/init.h> 16 - #include <linux/sfi_acpi.h> 17 17 #include <linux/bitmap.h> 18 18 #include <linux/dmi.h> 19 19 #include <linux/slab.h> ··· 665 665 if (pci_mmcfg_check_hostbridge()) 666 666 known_bridge = 1; 667 667 else 668 - acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); 668 + acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); 669 669 __pci_mmcfg_init(1); 670 670 671 671 set_apei_filter(); ··· 683 683 684 684 /* MMCONFIG hasn't been enabled yet, try again */ 685 685 if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) { 686 - acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); 686 + acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); 687 687 __pci_mmcfg_init(0); 688 688 } 689 689 }
-1
arch/x86/platform/Makefile
··· 11 11 obj-y += intel-quark/ 12 12 obj-y += olpc/ 13 13 obj-y += scx200/ 14 - obj-y += sfi/ 15 14 obj-y += ts5500/ 16 15 obj-y += uv/
-5
arch/x86/platform/intel-mid/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o pwr.o 3 - 4 - # SFI specific code 5 - ifdef CONFIG_X86_INTEL_MID 6 - obj-$(CONFIG_SFI) += sfi.o device_libs/ 7 - endif
-23
arch/x86/platform/intel-mid/device_libs/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - # Family-Level Interface Shim (FLIS) 3 - obj-$(subst m,y,$(CONFIG_PINCTRL_MERRIFIELD)) += platform_mrfld_pinctrl.o 4 - # SDHCI Devices 5 - obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += platform_mrfld_sd.o 6 - # WiFi + BT 7 - obj-$(subst m,y,$(CONFIG_BRCMFMAC_SDIO)) += platform_bcm43xx.o 8 - obj-$(subst m,y,$(CONFIG_BT_HCIUART_BCM)) += platform_bt.o 9 - # SPI Devices 10 - obj-$(subst m,y,$(CONFIG_SPI_SPIDEV)) += platform_mrfld_spidev.o 11 - # I2C Devices 12 - obj-$(subst m,y,$(CONFIG_SENSORS_EMC1403)) += platform_emc1403.o 13 - obj-$(subst m,y,$(CONFIG_SENSORS_LIS3LV02D)) += platform_lis331.o 14 - obj-$(subst m,y,$(CONFIG_MPU3050_I2C)) += platform_mpu3050.o 15 - obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o 16 - obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o 17 - # I2C GPIO Expanders 18 - obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_max7315.o 19 - obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_pcal9555a.o 20 - obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o 21 - # MISC Devices 22 - obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o 23 - obj-$(subst m,y,$(CONFIG_RTC_DRV_CMOS)) += platform_mrfld_rtc.o
-101
arch/x86/platform/intel-mid/device_libs/platform_bcm43xx.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_bcm43xx.c: bcm43xx platform data initialization file 4 - * 5 - * (C) Copyright 2016 Intel Corporation 6 - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 7 - */ 8 - 9 - #include <linux/gpio/machine.h> 10 - #include <linux/platform_device.h> 11 - #include <linux/regulator/machine.h> 12 - #include <linux/regulator/fixed.h> 13 - #include <linux/sfi.h> 14 - 15 - #include <asm/intel-mid.h> 16 - 17 - #define WLAN_SFI_GPIO_IRQ_NAME "WLAN-interrupt" 18 - #define WLAN_SFI_GPIO_ENABLE_NAME "WLAN-enable" 19 - 20 - #define WLAN_DEV_NAME "0000:00:01.3" 21 - 22 - static struct regulator_consumer_supply bcm43xx_vmmc_supply = { 23 - .dev_name = WLAN_DEV_NAME, 24 - .supply = "vmmc", 25 - }; 26 - 27 - static struct regulator_init_data bcm43xx_vmmc_data = { 28 - .constraints = { 29 - .valid_ops_mask = REGULATOR_CHANGE_STATUS, 30 - }, 31 - .num_consumer_supplies = 1, 32 - .consumer_supplies = &bcm43xx_vmmc_supply, 33 - }; 34 - 35 - static struct fixed_voltage_config bcm43xx_vmmc = { 36 - .supply_name = "bcm43xx-vmmc-regulator", 37 - /* 38 - * Announce 2.0V here to be compatible with SDIO specification. The 39 - * real voltage and signaling are still 1.8V. 40 - */ 41 - .microvolts = 2000000, /* 1.8V */ 42 - .startup_delay = 250 * 1000, /* 250ms */ 43 - .enabled_at_boot = 0, /* disabled at boot */ 44 - .init_data = &bcm43xx_vmmc_data, 45 - }; 46 - 47 - static struct platform_device bcm43xx_vmmc_regulator = { 48 - .name = "reg-fixed-voltage", 49 - .id = PLATFORM_DEVID_AUTO, 50 - .dev = { 51 - .platform_data = &bcm43xx_vmmc, 52 - }, 53 - }; 54 - 55 - static struct gpiod_lookup_table bcm43xx_vmmc_gpio_table = { 56 - .dev_id = "reg-fixed-voltage.0", 57 - .table = { 58 - GPIO_LOOKUP("0000:00:0c.0", -1, NULL, GPIO_ACTIVE_LOW), 59 - {} 60 - }, 61 - }; 62 - 63 - static int __init bcm43xx_regulator_register(void) 64 - { 65 - struct gpiod_lookup_table *table = &bcm43xx_vmmc_gpio_table; 66 - struct gpiod_lookup *lookup = table->table; 67 - int ret; 68 - 69 - lookup[0].chip_hwnum = get_gpio_by_name(WLAN_SFI_GPIO_ENABLE_NAME); 70 - gpiod_add_lookup_table(table); 71 - 72 - ret = platform_device_register(&bcm43xx_vmmc_regulator); 73 - if (ret) { 74 - pr_err("%s: vmmc regulator register failed\n", __func__); 75 - return ret; 76 - } 77 - 78 - return 0; 79 - } 80 - 81 - static void __init *bcm43xx_platform_data(void *info) 82 - { 83 - int ret; 84 - 85 - ret = bcm43xx_regulator_register(); 86 - if (ret) 87 - return NULL; 88 - 89 - pr_info("Using generic wifi platform data\n"); 90 - 91 - /* For now it's empty */ 92 - return NULL; 93 - } 94 - 95 - static const struct devs_id bcm43xx_clk_vmmc_dev_id __initconst = { 96 - .name = "bcm43xx_clk_vmmc", 97 - .type = SFI_DEV_TYPE_SD, 98 - .get_platform_data = &bcm43xx_platform_data, 99 - }; 100 - 101 - sfi_device(bcm43xx_clk_vmmc_dev_id);
-16
arch/x86/platform/intel-mid/device_libs/platform_bma023.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_bma023.c: bma023 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - */ 7 - 8 - #include <asm/intel-mid.h> 9 - 10 - static const struct devs_id bma023_dev_id __initconst = { 11 - .name = "bma023", 12 - .type = SFI_DEV_TYPE_I2C, 13 - .delay = 1, 14 - }; 15 - 16 - sfi_device(bma023_dev_id);
-101
arch/x86/platform/intel-mid/device_libs/platform_bt.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Bluetooth platform data initialization file 4 - * 5 - * (C) Copyright 2017 Intel Corporation 6 - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 7 - */ 8 - 9 - #include <linux/gpio/machine.h> 10 - #include <linux/pci.h> 11 - #include <linux/platform_device.h> 12 - 13 - #include <asm/cpu_device_id.h> 14 - #include <asm/intel-family.h> 15 - #include <asm/intel-mid.h> 16 - 17 - struct bt_sfi_data { 18 - struct device *dev; 19 - const char *name; 20 - int (*setup)(struct bt_sfi_data *ddata); 21 - }; 22 - 23 - static struct gpiod_lookup_table tng_bt_sfi_gpio_table = { 24 - .dev_id = "hci_bcm", 25 - .table = { 26 - GPIO_LOOKUP("0000:00:0c.0", -1, "device-wakeup", GPIO_ACTIVE_HIGH), 27 - GPIO_LOOKUP("0000:00:0c.0", -1, "shutdown", GPIO_ACTIVE_HIGH), 28 - GPIO_LOOKUP("0000:00:0c.0", -1, "host-wakeup", GPIO_ACTIVE_HIGH), 29 - { }, 30 - }, 31 - }; 32 - 33 - #define TNG_BT_SFI_GPIO_DEVICE_WAKEUP "bt_wakeup" 34 - #define TNG_BT_SFI_GPIO_SHUTDOWN "BT-reset" 35 - #define TNG_BT_SFI_GPIO_HOST_WAKEUP "bt_uart_enable" 36 - 37 - static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata) 38 - { 39 - struct gpiod_lookup_table *table = &tng_bt_sfi_gpio_table; 40 - struct gpiod_lookup *lookup = table->table; 41 - struct pci_dev *pdev; 42 - 43 - /* Connected to /dev/ttyS0 */ 44 - pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(4, 1)); 45 - if (!pdev) 46 - return -ENODEV; 47 - 48 - ddata->dev = &pdev->dev; 49 - ddata->name = table->dev_id; 50 - 51 - lookup[0].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_DEVICE_WAKEUP); 52 - lookup[1].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_SHUTDOWN); 53 - lookup[2].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_HOST_WAKEUP); 54 - 55 - gpiod_add_lookup_table(table); 56 - return 0; 57 - } 58 - 59 - static struct bt_sfi_data tng_bt_sfi_data __initdata = { 60 - .setup = tng_bt_sfi_setup, 61 - }; 62 - 63 - static const struct x86_cpu_id bt_sfi_cpu_ids[] = { 64 - X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &tng_bt_sfi_data), 65 - {} 66 - }; 67 - 68 - static int __init bt_sfi_init(void) 69 - { 70 - struct platform_device_info info; 71 - struct platform_device *pdev; 72 - const struct x86_cpu_id *id; 73 - struct bt_sfi_data *ddata; 74 - int ret; 75 - 76 - id = x86_match_cpu(bt_sfi_cpu_ids); 77 - if (!id) 78 - return -ENODEV; 79 - 80 - ddata = (struct bt_sfi_data *)id->driver_data; 81 - if (!ddata) 82 - return -ENODEV; 83 - 84 - ret = ddata->setup(ddata); 85 - if (ret) 86 - return ret; 87 - 88 - memset(&info, 0, sizeof(info)); 89 - info.fwnode = ddata->dev->fwnode; 90 - info.parent = ddata->dev; 91 - info.name = ddata->name, 92 - info.id = PLATFORM_DEVID_NONE, 93 - 94 - pdev = platform_device_register_full(&info); 95 - if (IS_ERR(pdev)) 96 - return PTR_ERR(pdev); 97 - 98 - dev_info(ddata->dev, "Registered Bluetooth device: %s\n", ddata->name); 99 - return 0; 100 - } 101 - device_initcall(bt_sfi_init);
-39
arch/x86/platform/intel-mid/device_libs/platform_emc1403.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_emc1403.c: emc1403 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/init.h> 10 - #include <linux/gpio.h> 11 - #include <linux/i2c.h> 12 - #include <asm/intel-mid.h> 13 - 14 - static void __init *emc1403_platform_data(void *info) 15 - { 16 - static short intr2nd_pdata; 17 - struct i2c_board_info *i2c_info = info; 18 - int intr = get_gpio_by_name("thermal_int"); 19 - int intr2nd = get_gpio_by_name("thermal_alert"); 20 - 21 - if (intr < 0) 22 - return NULL; 23 - if (intr2nd < 0) 24 - return NULL; 25 - 26 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 27 - intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET; 28 - 29 - return &intr2nd_pdata; 30 - } 31 - 32 - static const struct devs_id emc1403_dev_id __initconst = { 33 - .name = "emc1403", 34 - .type = SFI_DEV_TYPE_I2C, 35 - .delay = 1, 36 - .get_platform_data = &emc1403_platform_data, 37 - }; 38 - 39 - sfi_device(emc1403_dev_id);
-81
arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_gpio_keys.c: gpio_keys platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/input.h> 10 - #include <linux/init.h> 11 - #include <linux/kernel.h> 12 - #include <linux/gpio.h> 13 - #include <linux/gpio_keys.h> 14 - #include <linux/platform_device.h> 15 - #include <asm/intel-mid.h> 16 - 17 - #define DEVICE_NAME "gpio-keys" 18 - 19 - /* 20 - * we will search these buttons in SFI GPIO table (by name) 21 - * and register them dynamically. Please add all possible 22 - * buttons here, we will shrink them if no GPIO found. 23 - */ 24 - static struct gpio_keys_button gpio_button[] = { 25 - {KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000}, 26 - {KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20}, 27 - {KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20}, 28 - {SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20}, 29 - {KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20}, 30 - {KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20}, 31 - {KEY_MUTE, -1, 1, "mute_enable", EV_KEY, 0, 20}, 32 - {KEY_VOLUMEUP, -1, 1, "volume_up", EV_KEY, 0, 20}, 33 - {KEY_VOLUMEDOWN, -1, 1, "volume_down", EV_KEY, 0, 20}, 34 - {KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20}, 35 - {KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20}, 36 - {SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20}, 37 - {SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20}, 38 - }; 39 - 40 - static struct gpio_keys_platform_data gpio_keys = { 41 - .buttons = gpio_button, 42 - .rep = 1, 43 - .nbuttons = -1, /* will fill it after search */ 44 - }; 45 - 46 - static struct platform_device pb_device = { 47 - .name = DEVICE_NAME, 48 - .id = -1, 49 - .dev = { 50 - .platform_data = &gpio_keys, 51 - }, 52 - }; 53 - 54 - /* 55 - * Shrink the non-existent buttons, register the gpio button 56 - * device if there is some 57 - */ 58 - static int __init pb_keys_init(void) 59 - { 60 - struct gpio_keys_button *gb = gpio_button; 61 - int i, good = 0; 62 - 63 - for (i = 0; i < ARRAY_SIZE(gpio_button); i++) { 64 - gb[i].gpio = get_gpio_by_name(gb[i].desc); 65 - pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc, 66 - gb[i].gpio); 67 - if (gb[i].gpio < 0) 68 - continue; 69 - 70 - if (i != good) 71 - gb[good] = gb[i]; 72 - good++; 73 - } 74 - 75 - if (good) { 76 - gpio_keys.nbuttons = good; 77 - return platform_device_register(&pb_device); 78 - } 79 - return 0; 80 - } 81 - late_initcall(pb_keys_init);
-37
arch/x86/platform/intel-mid/device_libs/platform_lis331.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_lis331.c: lis331 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/i2c.h> 10 - #include <linux/gpio.h> 11 - #include <asm/intel-mid.h> 12 - 13 - static void __init *lis331dl_platform_data(void *info) 14 - { 15 - static short intr2nd_pdata; 16 - struct i2c_board_info *i2c_info = info; 17 - int intr = get_gpio_by_name("accel_int"); 18 - int intr2nd = get_gpio_by_name("accel_2"); 19 - 20 - if (intr < 0) 21 - return NULL; 22 - if (intr2nd < 0) 23 - return NULL; 24 - 25 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 26 - intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET; 27 - 28 - return &intr2nd_pdata; 29 - } 30 - 31 - static const struct devs_id lis331dl_dev_id __initconst = { 32 - .name = "i2c_accel", 33 - .type = SFI_DEV_TYPE_I2C, 34 - .get_platform_data = &lis331dl_platform_data, 35 - }; 36 - 37 - sfi_device(lis331dl_dev_id);
-77
arch/x86/platform/intel-mid/device_libs/platform_max7315.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_max7315.c: max7315 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/init.h> 10 - #include <linux/gpio.h> 11 - #include <linux/i2c.h> 12 - #include <linux/platform_data/pca953x.h> 13 - #include <asm/intel-mid.h> 14 - 15 - #define MAX7315_NUM 2 16 - 17 - static void __init *max7315_platform_data(void *info) 18 - { 19 - static struct pca953x_platform_data max7315_pdata[MAX7315_NUM]; 20 - static int nr; 21 - struct pca953x_platform_data *max7315 = &max7315_pdata[nr]; 22 - struct i2c_board_info *i2c_info = info; 23 - int gpio_base, intr; 24 - char base_pin_name[SFI_NAME_LEN + 1]; 25 - char intr_pin_name[SFI_NAME_LEN + 1]; 26 - 27 - if (nr == MAX7315_NUM) { 28 - pr_err("too many max7315s, we only support %d\n", 29 - MAX7315_NUM); 30 - return NULL; 31 - } 32 - /* we have several max7315 on the board, we only need load several 33 - * instances of the same pca953x driver to cover them 34 - */ 35 - strcpy(i2c_info->type, "max7315"); 36 - if (nr++) { 37 - snprintf(base_pin_name, sizeof(base_pin_name), 38 - "max7315_%d_base", nr); 39 - snprintf(intr_pin_name, sizeof(intr_pin_name), 40 - "max7315_%d_int", nr); 41 - } else { 42 - strcpy(base_pin_name, "max7315_base"); 43 - strcpy(intr_pin_name, "max7315_int"); 44 - } 45 - 46 - gpio_base = get_gpio_by_name(base_pin_name); 47 - intr = get_gpio_by_name(intr_pin_name); 48 - 49 - if (gpio_base < 0) 50 - return NULL; 51 - max7315->gpio_base = gpio_base; 52 - if (intr != -1) { 53 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 54 - max7315->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; 55 - } else { 56 - i2c_info->irq = -1; 57 - max7315->irq_base = -1; 58 - } 59 - return max7315; 60 - } 61 - 62 - static const struct devs_id max7315_dev_id __initconst = { 63 - .name = "i2c_max7315", 64 - .type = SFI_DEV_TYPE_I2C, 65 - .delay = 1, 66 - .get_platform_data = &max7315_platform_data, 67 - }; 68 - 69 - static const struct devs_id max7315_2_dev_id __initconst = { 70 - .name = "i2c_max7315_2", 71 - .type = SFI_DEV_TYPE_I2C, 72 - .delay = 1, 73 - .get_platform_data = &max7315_platform_data, 74 - }; 75 - 76 - sfi_device(max7315_dev_id); 77 - sfi_device(max7315_2_dev_id);
-32
arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_mpu3050.c: mpu3050 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/gpio.h> 10 - #include <linux/i2c.h> 11 - #include <asm/intel-mid.h> 12 - 13 - static void *mpu3050_platform_data(void *info) 14 - { 15 - struct i2c_board_info *i2c_info = info; 16 - int intr = get_gpio_by_name("mpu3050_int"); 17 - 18 - if (intr < 0) 19 - return NULL; 20 - 21 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 22 - return NULL; 23 - } 24 - 25 - static const struct devs_id mpu3050_dev_id __initconst = { 26 - .name = "mpu3050", 27 - .type = SFI_DEV_TYPE_I2C, 28 - .delay = 1, 29 - .get_platform_data = &mpu3050_platform_data, 30 - }; 31 - 32 - sfi_device(mpu3050_dev_id);
-39
arch/x86/platform/intel-mid/device_libs/platform_mrfld_pinctrl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Intel Merrifield FLIS platform device initialization file 4 - * 5 - * Copyright (C) 2016, Intel Corporation 6 - * 7 - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 - */ 9 - 10 - #include <linux/init.h> 11 - #include <linux/ioport.h> 12 - #include <linux/platform_device.h> 13 - 14 - #include <asm/intel-mid.h> 15 - 16 - #define FLIS_BASE_ADDR 0xff0c0000 17 - #define FLIS_LENGTH 0x8000 18 - 19 - static struct resource mrfld_pinctrl_mmio_resource = { 20 - .start = FLIS_BASE_ADDR, 21 - .end = FLIS_BASE_ADDR + FLIS_LENGTH - 1, 22 - .flags = IORESOURCE_MEM, 23 - }; 24 - 25 - static struct platform_device mrfld_pinctrl_device = { 26 - .name = "pinctrl-merrifield", 27 - .id = PLATFORM_DEVID_NONE, 28 - .resource = &mrfld_pinctrl_mmio_resource, 29 - .num_resources = 1, 30 - }; 31 - 32 - static int __init mrfld_pinctrl_init(void) 33 - { 34 - if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) 35 - return platform_device_register(&mrfld_pinctrl_device); 36 - 37 - return -ENODEV; 38 - } 39 - arch_initcall(mrfld_pinctrl_init);
-44
arch/x86/platform/intel-mid/device_libs/platform_mrfld_rtc.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Intel Merrifield legacy RTC initialization file 4 - * 5 - * (C) Copyright 2017 Intel Corporation 6 - * 7 - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 - */ 9 - 10 - #include <linux/init.h> 11 - 12 - #include <asm/hw_irq.h> 13 - #include <asm/intel-mid.h> 14 - #include <asm/io_apic.h> 15 - #include <asm/time.h> 16 - #include <asm/x86_init.h> 17 - 18 - static int __init mrfld_legacy_rtc_alloc_irq(void) 19 - { 20 - struct irq_alloc_info info; 21 - int ret; 22 - 23 - if (!x86_platform.legacy.rtc) 24 - return -ENODEV; 25 - 26 - ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 1, 0); 27 - ret = mp_map_gsi_to_irq(RTC_IRQ, IOAPIC_MAP_ALLOC, &info); 28 - if (ret < 0) { 29 - pr_info("Failed to allocate RTC interrupt. Disabling RTC\n"); 30 - x86_platform.legacy.rtc = 0; 31 - return ret; 32 - } 33 - 34 - return 0; 35 - } 36 - 37 - static int __init mrfld_legacy_rtc_init(void) 38 - { 39 - if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER) 40 - return -ENODEV; 41 - 42 - return mrfld_legacy_rtc_alloc_irq(); 43 - } 44 - arch_initcall(mrfld_legacy_rtc_init);
-43
arch/x86/platform/intel-mid/device_libs/platform_mrfld_sd.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * SDHCI platform data initilisation file 4 - * 5 - * (C) Copyright 2016 Intel Corporation 6 - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 7 - */ 8 - 9 - #include <linux/init.h> 10 - #include <linux/pci.h> 11 - 12 - #include <linux/mmc/sdhci-pci-data.h> 13 - 14 - #include <asm/intel-mid.h> 15 - 16 - #define INTEL_MRFLD_SD 2 17 - #define INTEL_MRFLD_SD_CD_GPIO 77 18 - 19 - static struct sdhci_pci_data mrfld_sdhci_pci_data = { 20 - .rst_n_gpio = -EINVAL, 21 - .cd_gpio = INTEL_MRFLD_SD_CD_GPIO, 22 - }; 23 - 24 - static struct sdhci_pci_data * 25 - mrfld_sdhci_pci_get_data(struct pci_dev *pdev, int slotno) 26 - { 27 - unsigned int func = PCI_FUNC(pdev->devfn); 28 - 29 - if (func == INTEL_MRFLD_SD) 30 - return &mrfld_sdhci_pci_data; 31 - 32 - return NULL; 33 - } 34 - 35 - static int __init mrfld_sd_init(void) 36 - { 37 - if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER) 38 - return -ENODEV; 39 - 40 - sdhci_pci_get_data = mrfld_sdhci_pci_get_data; 41 - return 0; 42 - } 43 - arch_initcall(mrfld_sd_init);
-50
arch/x86/platform/intel-mid/device_libs/platform_mrfld_spidev.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * spidev platform data initialization file 4 - * 5 - * (C) Copyright 2014, 2016 Intel Corporation 6 - * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 7 - * Dan O'Donovan <dan@emutex.com> 8 - */ 9 - 10 - #include <linux/err.h> 11 - #include <linux/init.h> 12 - #include <linux/sfi.h> 13 - #include <linux/spi/pxa2xx_spi.h> 14 - #include <linux/spi/spi.h> 15 - 16 - #include <asm/intel-mid.h> 17 - 18 - #define MRFLD_SPI_DEFAULT_DMA_BURST 8 19 - #define MRFLD_SPI_DEFAULT_TIMEOUT 500 20 - 21 - /* GPIO pin for spidev chipselect */ 22 - #define MRFLD_SPIDEV_GPIO_CS 111 23 - 24 - static struct pxa2xx_spi_chip spidev_spi_chip = { 25 - .dma_burst_size = MRFLD_SPI_DEFAULT_DMA_BURST, 26 - .timeout = MRFLD_SPI_DEFAULT_TIMEOUT, 27 - .gpio_cs = MRFLD_SPIDEV_GPIO_CS, 28 - }; 29 - 30 - static void __init *spidev_platform_data(void *info) 31 - { 32 - struct spi_board_info *spi_info = info; 33 - 34 - if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER) 35 - return ERR_PTR(-ENODEV); 36 - 37 - spi_info->mode = SPI_MODE_0; 38 - spi_info->controller_data = &spidev_spi_chip; 39 - 40 - return NULL; 41 - } 42 - 43 - static const struct devs_id spidev_dev_id __initconst = { 44 - .name = "spidev", 45 - .type = SFI_DEV_TYPE_SPI, 46 - .delay = 0, 47 - .get_platform_data = &spidev_platform_data, 48 - }; 49 - 50 - sfi_device(spidev_dev_id);
-95
arch/x86/platform/intel-mid/device_libs/platform_pcal9555a.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * PCAL9555a platform data initialization file 4 - * 5 - * Copyright (C) 2016, Intel Corporation 6 - * 7 - * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 - * Dan O'Donovan <dan@emutex.com> 9 - */ 10 - 11 - #include <linux/gpio.h> 12 - #include <linux/init.h> 13 - #include <linux/i2c.h> 14 - #include <linux/platform_data/pca953x.h> 15 - #include <linux/sfi.h> 16 - 17 - #include <asm/intel-mid.h> 18 - 19 - #define PCAL9555A_NUM 4 20 - 21 - static struct pca953x_platform_data pcal9555a_pdata[PCAL9555A_NUM]; 22 - static int nr; 23 - 24 - static void __init *pcal9555a_platform_data(void *info) 25 - { 26 - struct i2c_board_info *i2c_info = info; 27 - char *type = i2c_info->type; 28 - struct pca953x_platform_data *pcal9555a; 29 - char base_pin_name[SFI_NAME_LEN + 1]; 30 - char intr_pin_name[SFI_NAME_LEN + 1]; 31 - int gpio_base, intr; 32 - 33 - snprintf(base_pin_name, sizeof(base_pin_name), "%s_base", type); 34 - snprintf(intr_pin_name, sizeof(intr_pin_name), "%s_int", type); 35 - 36 - gpio_base = get_gpio_by_name(base_pin_name); 37 - intr = get_gpio_by_name(intr_pin_name); 38 - 39 - /* Check if the SFI record valid */ 40 - if (gpio_base == -1) 41 - return NULL; 42 - 43 - if (nr >= PCAL9555A_NUM) { 44 - pr_err("%s: Too many instances, only %d supported\n", __func__, 45 - PCAL9555A_NUM); 46 - return NULL; 47 - } 48 - 49 - pcal9555a = &pcal9555a_pdata[nr++]; 50 - pcal9555a->gpio_base = gpio_base; 51 - 52 - if (intr >= 0) { 53 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 54 - pcal9555a->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; 55 - } else { 56 - i2c_info->irq = -1; 57 - pcal9555a->irq_base = -1; 58 - } 59 - 60 - strcpy(type, "pcal9555a"); 61 - return pcal9555a; 62 - } 63 - 64 - static const struct devs_id pcal9555a_1_dev_id __initconst = { 65 - .name = "pcal9555a-1", 66 - .type = SFI_DEV_TYPE_I2C, 67 - .delay = 1, 68 - .get_platform_data = &pcal9555a_platform_data, 69 - }; 70 - 71 - static const struct devs_id pcal9555a_2_dev_id __initconst = { 72 - .name = "pcal9555a-2", 73 - .type = SFI_DEV_TYPE_I2C, 74 - .delay = 1, 75 - .get_platform_data = &pcal9555a_platform_data, 76 - }; 77 - 78 - static const struct devs_id pcal9555a_3_dev_id __initconst = { 79 - .name = "pcal9555a-3", 80 - .type = SFI_DEV_TYPE_I2C, 81 - .delay = 1, 82 - .get_platform_data = &pcal9555a_platform_data, 83 - }; 84 - 85 - static const struct devs_id pcal9555a_4_dev_id __initconst = { 86 - .name = "pcal9555a-4", 87 - .type = SFI_DEV_TYPE_I2C, 88 - .delay = 1, 89 - .get_platform_data = &pcal9555a_platform_data, 90 - }; 91 - 92 - sfi_device(pcal9555a_1_dev_id); 93 - sfi_device(pcal9555a_2_dev_id); 94 - sfi_device(pcal9555a_3_dev_id); 95 - sfi_device(pcal9555a_4_dev_id);
-42
arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_tc35876x.c: tc35876x platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/gpio/machine.h> 10 - #include <asm/intel-mid.h> 11 - 12 - static struct gpiod_lookup_table tc35876x_gpio_table = { 13 - .dev_id = "i2c_disp_brig", 14 - .table = { 15 - GPIO_LOOKUP("0000:00:0c.0", -1, "bridge-reset", GPIO_ACTIVE_HIGH), 16 - GPIO_LOOKUP("0000:00:0c.0", -1, "bl-en", GPIO_ACTIVE_HIGH), 17 - GPIO_LOOKUP("0000:00:0c.0", -1, "vadd", GPIO_ACTIVE_HIGH), 18 - { }, 19 - }, 20 - }; 21 - 22 - /*tc35876x DSI_LVDS bridge chip and panel platform data*/ 23 - static void *tc35876x_platform_data(void *data) 24 - { 25 - struct gpiod_lookup_table *table = &tc35876x_gpio_table; 26 - struct gpiod_lookup *lookup = table->table; 27 - 28 - lookup[0].chip_hwnum = get_gpio_by_name("LCMB_RXEN"); 29 - lookup[1].chip_hwnum = get_gpio_by_name("6S6P_BL_EN"); 30 - lookup[2].chip_hwnum = get_gpio_by_name("EN_VREG_LCD_V3P3"); 31 - gpiod_add_lookup_table(table); 32 - 33 - return NULL; 34 - } 35 - 36 - static const struct devs_id tc35876x_dev_id __initconst = { 37 - .name = "i2c_disp_brig", 38 - .type = SFI_DEV_TYPE_I2C, 39 - .get_platform_data = &tc35876x_platform_data, 40 - }; 41 - 42 - sfi_device(tc35876x_dev_id);
-53
arch/x86/platform/intel-mid/device_libs/platform_tca6416.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * platform_tca6416.c: tca6416 platform data initialization file 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/platform_data/pca953x.h> 10 - #include <linux/i2c.h> 11 - #include <linux/gpio.h> 12 - #include <asm/intel-mid.h> 13 - 14 - #define TCA6416_NAME "tca6416" 15 - #define TCA6416_BASE "tca6416_base" 16 - #define TCA6416_INTR "tca6416_int" 17 - 18 - static void *tca6416_platform_data(void *info) 19 - { 20 - static struct pca953x_platform_data tca6416; 21 - struct i2c_board_info *i2c_info = info; 22 - int gpio_base, intr; 23 - char base_pin_name[SFI_NAME_LEN + 1]; 24 - char intr_pin_name[SFI_NAME_LEN + 1]; 25 - 26 - strcpy(i2c_info->type, TCA6416_NAME); 27 - strcpy(base_pin_name, TCA6416_BASE); 28 - strcpy(intr_pin_name, TCA6416_INTR); 29 - 30 - gpio_base = get_gpio_by_name(base_pin_name); 31 - intr = get_gpio_by_name(intr_pin_name); 32 - 33 - if (gpio_base < 0) 34 - return NULL; 35 - tca6416.gpio_base = gpio_base; 36 - if (intr >= 0) { 37 - i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET; 38 - tca6416.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET; 39 - } else { 40 - i2c_info->irq = -1; 41 - tca6416.irq_base = -1; 42 - } 43 - return &tca6416; 44 - } 45 - 46 - static const struct devs_id tca6416_dev_id __initconst = { 47 - .name = "tca6416", 48 - .type = SFI_DEV_TYPE_I2C, 49 - .delay = 1, 50 - .get_platform_data = &tca6416_platform_data, 51 - }; 52 - 53 - sfi_device(tca6416_dev_id);
-1
arch/x86/platform/intel-mid/intel-mid.c
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/regulator/machine.h> 16 16 #include <linux/scatterlist.h> 17 - #include <linux/sfi.h> 18 17 #include <linux/irq.h> 19 18 #include <linux/export.h> 20 19 #include <linux/notifier.h>
-419
arch/x86/platform/intel-mid/sfi.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * intel_mid_sfi.c: Intel MID SFI initialization code 4 - * 5 - * (C) Copyright 2013 Intel Corporation 6 - * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> 7 - */ 8 - 9 - #include <linux/init.h> 10 - #include <linux/kernel.h> 11 - #include <linux/interrupt.h> 12 - #include <linux/scatterlist.h> 13 - #include <linux/sfi.h> 14 - #include <linux/spi/spi.h> 15 - #include <linux/i2c.h> 16 - #include <linux/skbuff.h> 17 - #include <linux/gpio.h> 18 - #include <linux/gpio_keys.h> 19 - #include <linux/input.h> 20 - #include <linux/platform_device.h> 21 - #include <linux/irq.h> 22 - #include <linux/export.h> 23 - #include <linux/notifier.h> 24 - #include <linux/mmc/core.h> 25 - #include <linux/mmc/card.h> 26 - #include <linux/blkdev.h> 27 - 28 - #include <asm/setup.h> 29 - #include <asm/mpspec_def.h> 30 - #include <asm/hw_irq.h> 31 - #include <asm/apic.h> 32 - #include <asm/io_apic.h> 33 - #include <asm/intel-mid.h> 34 - #include <asm/io.h> 35 - #include <asm/i8259.h> 36 - #include <asm/intel_scu_ipc.h> 37 - #include <asm/reboot.h> 38 - 39 - #define SFI_SIG_OEM0 "OEM0" 40 - #define MAX_IPCDEVS 24 41 - #define MAX_SCU_SPI 24 42 - #define MAX_SCU_I2C 24 43 - 44 - static struct platform_device *ipc_devs[MAX_IPCDEVS]; 45 - static struct spi_board_info *spi_devs[MAX_SCU_SPI]; 46 - static struct i2c_board_info *i2c_devs[MAX_SCU_I2C]; 47 - static struct sfi_gpio_table_entry *gpio_table; 48 - static int ipc_next_dev; 49 - static int spi_next_dev; 50 - static int i2c_next_dev; 51 - static int i2c_bus[MAX_SCU_I2C]; 52 - static int gpio_num_entry; 53 - 54 - struct blocking_notifier_head intel_scu_notifier = 55 - BLOCKING_NOTIFIER_INIT(intel_scu_notifier); 56 - EXPORT_SYMBOL_GPL(intel_scu_notifier); 57 - 58 - #define intel_mid_sfi_get_pdata(dev, priv) \ 59 - ((dev)->get_platform_data ? (dev)->get_platform_data(priv) : NULL) 60 - 61 - /* 62 - * Parsing GPIO table first, since the DEVS table will need this table 63 - * to map the pin name to the actual pin. 64 - */ 65 - static int __init sfi_parse_gpio(struct sfi_table_header *table) 66 - { 67 - struct sfi_table_simple *sb; 68 - struct sfi_gpio_table_entry *pentry; 69 - int num, i; 70 - 71 - if (gpio_table) 72 - return 0; 73 - sb = (struct sfi_table_simple *)table; 74 - num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); 75 - pentry = (struct sfi_gpio_table_entry *)sb->pentry; 76 - 77 - gpio_table = kmemdup(pentry, num * sizeof(*pentry), GFP_KERNEL); 78 - if (!gpio_table) 79 - return -1; 80 - gpio_num_entry = num; 81 - 82 - pr_debug("GPIO pin info:\n"); 83 - for (i = 0; i < num; i++, pentry++) 84 - pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s," 85 - " pin = %d\n", i, 86 - pentry->controller_name, 87 - pentry->pin_name, 88 - pentry->pin_no); 89 - return 0; 90 - } 91 - 92 - int get_gpio_by_name(const char *name) 93 - { 94 - struct sfi_gpio_table_entry *pentry = gpio_table; 95 - int i; 96 - 97 - if (!pentry) 98 - return -1; 99 - for (i = 0; i < gpio_num_entry; i++, pentry++) { 100 - if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN)) 101 - return pentry->pin_no; 102 - } 103 - return -EINVAL; 104 - } 105 - 106 - static void __init intel_scu_ipc_device_register(struct platform_device *pdev) 107 - { 108 - if (ipc_next_dev == MAX_IPCDEVS) 109 - pr_err("too many SCU IPC devices"); 110 - else 111 - ipc_devs[ipc_next_dev++] = pdev; 112 - } 113 - 114 - static void __init intel_scu_spi_device_register(struct spi_board_info *sdev) 115 - { 116 - struct spi_board_info *new_dev; 117 - 118 - if (spi_next_dev == MAX_SCU_SPI) { 119 - pr_err("too many SCU SPI devices"); 120 - return; 121 - } 122 - 123 - new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL); 124 - if (!new_dev) { 125 - pr_err("failed to alloc mem for delayed spi dev %s\n", 126 - sdev->modalias); 127 - return; 128 - } 129 - *new_dev = *sdev; 130 - 131 - spi_devs[spi_next_dev++] = new_dev; 132 - } 133 - 134 - static void __init intel_scu_i2c_device_register(int bus, 135 - struct i2c_board_info *idev) 136 - { 137 - struct i2c_board_info *new_dev; 138 - 139 - if (i2c_next_dev == MAX_SCU_I2C) { 140 - pr_err("too many SCU I2C devices"); 141 - return; 142 - } 143 - 144 - new_dev = kzalloc(sizeof(*idev), GFP_KERNEL); 145 - if (!new_dev) { 146 - pr_err("failed to alloc mem for delayed i2c dev %s\n", 147 - idev->type); 148 - return; 149 - } 150 - *new_dev = *idev; 151 - 152 - i2c_bus[i2c_next_dev] = bus; 153 - i2c_devs[i2c_next_dev++] = new_dev; 154 - } 155 - 156 - /* Called by IPC driver */ 157 - void intel_scu_devices_create(void) 158 - { 159 - int i; 160 - 161 - for (i = 0; i < ipc_next_dev; i++) 162 - platform_device_add(ipc_devs[i]); 163 - 164 - for (i = 0; i < spi_next_dev; i++) 165 - spi_register_board_info(spi_devs[i], 1); 166 - 167 - for (i = 0; i < i2c_next_dev; i++) { 168 - struct i2c_adapter *adapter; 169 - struct i2c_client *client; 170 - 171 - adapter = i2c_get_adapter(i2c_bus[i]); 172 - if (adapter) { 173 - client = i2c_new_client_device(adapter, i2c_devs[i]); 174 - if (IS_ERR(client)) 175 - pr_err("can't create i2c device %s\n", 176 - i2c_devs[i]->type); 177 - } else 178 - i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); 179 - } 180 - intel_scu_notifier_post(SCU_AVAILABLE, NULL); 181 - } 182 - EXPORT_SYMBOL_GPL(intel_scu_devices_create); 183 - 184 - /* Called by IPC driver */ 185 - void intel_scu_devices_destroy(void) 186 - { 187 - int i; 188 - 189 - intel_scu_notifier_post(SCU_DOWN, NULL); 190 - 191 - for (i = 0; i < ipc_next_dev; i++) 192 - platform_device_del(ipc_devs[i]); 193 - } 194 - EXPORT_SYMBOL_GPL(intel_scu_devices_destroy); 195 - 196 - static void __init install_irq_resource(struct platform_device *pdev, int irq) 197 - { 198 - /* Single threaded */ 199 - static struct resource res __initdata = { 200 - .name = "IRQ", 201 - .flags = IORESOURCE_IRQ, 202 - }; 203 - res.start = irq; 204 - platform_device_add_resources(pdev, &res, 1); 205 - } 206 - 207 - static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry, 208 - struct devs_id *dev) 209 - { 210 - struct platform_device *pdev; 211 - void *pdata = NULL; 212 - 213 - pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n", 214 - pentry->name, pentry->irq); 215 - 216 - /* 217 - * We need to call platform init of IPC devices to fill misc_pdata 218 - * structure. It will be used in msic_init for initialization. 219 - */ 220 - pdata = intel_mid_sfi_get_pdata(dev, pentry); 221 - if (IS_ERR(pdata)) 222 - return; 223 - 224 - pdev = platform_device_alloc(pentry->name, 0); 225 - if (pdev == NULL) { 226 - pr_err("out of memory for SFI platform device '%s'.\n", 227 - pentry->name); 228 - return; 229 - } 230 - install_irq_resource(pdev, pentry->irq); 231 - 232 - pdev->dev.platform_data = pdata; 233 - if (dev->delay) 234 - intel_scu_ipc_device_register(pdev); 235 - else 236 - platform_device_add(pdev); 237 - } 238 - 239 - static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry, 240 - struct devs_id *dev) 241 - { 242 - struct spi_board_info spi_info; 243 - void *pdata = NULL; 244 - 245 - memset(&spi_info, 0, sizeof(spi_info)); 246 - strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); 247 - spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq); 248 - spi_info.bus_num = pentry->host_num; 249 - spi_info.chip_select = pentry->addr; 250 - spi_info.max_speed_hz = pentry->max_freq; 251 - pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n", 252 - spi_info.bus_num, 253 - spi_info.modalias, 254 - spi_info.irq, 255 - spi_info.max_speed_hz, 256 - spi_info.chip_select); 257 - 258 - pdata = intel_mid_sfi_get_pdata(dev, &spi_info); 259 - if (IS_ERR(pdata)) 260 - return; 261 - 262 - spi_info.platform_data = pdata; 263 - if (dev->delay) 264 - intel_scu_spi_device_register(&spi_info); 265 - else 266 - spi_register_board_info(&spi_info, 1); 267 - } 268 - 269 - static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry, 270 - struct devs_id *dev) 271 - { 272 - struct i2c_board_info i2c_info; 273 - void *pdata = NULL; 274 - 275 - memset(&i2c_info, 0, sizeof(i2c_info)); 276 - strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); 277 - i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq); 278 - i2c_info.addr = pentry->addr; 279 - pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n", 280 - pentry->host_num, 281 - i2c_info.type, 282 - i2c_info.irq, 283 - i2c_info.addr); 284 - pdata = intel_mid_sfi_get_pdata(dev, &i2c_info); 285 - i2c_info.platform_data = pdata; 286 - if (IS_ERR(pdata)) 287 - return; 288 - 289 - if (dev->delay) 290 - intel_scu_i2c_device_register(pentry->host_num, &i2c_info); 291 - else 292 - i2c_register_board_info(pentry->host_num, &i2c_info, 1); 293 - } 294 - 295 - static void __init sfi_handle_sd_dev(struct sfi_device_table_entry *pentry, 296 - struct devs_id *dev) 297 - { 298 - struct mid_sd_board_info sd_info; 299 - void *pdata; 300 - 301 - memset(&sd_info, 0, sizeof(sd_info)); 302 - strncpy(sd_info.name, pentry->name, SFI_NAME_LEN); 303 - sd_info.bus_num = pentry->host_num; 304 - sd_info.max_clk = pentry->max_freq; 305 - sd_info.addr = pentry->addr; 306 - pr_debug("SD bus = %d, name = %16.16s, max_clk = %d, addr = 0x%x\n", 307 - sd_info.bus_num, 308 - sd_info.name, 309 - sd_info.max_clk, 310 - sd_info.addr); 311 - pdata = intel_mid_sfi_get_pdata(dev, &sd_info); 312 - if (IS_ERR(pdata)) 313 - return; 314 - 315 - /* Nothing we can do with this for now */ 316 - sd_info.platform_data = pdata; 317 - 318 - pr_debug("Successfully registered %16.16s", sd_info.name); 319 - } 320 - 321 - extern struct devs_id *const __x86_intel_mid_dev_start[], 322 - *const __x86_intel_mid_dev_end[]; 323 - 324 - static struct devs_id __init *get_device_id(u8 type, char *name) 325 - { 326 - struct devs_id *const *dev_table; 327 - 328 - for (dev_table = __x86_intel_mid_dev_start; 329 - dev_table < __x86_intel_mid_dev_end; dev_table++) { 330 - struct devs_id *dev = *dev_table; 331 - if (dev->type == type && 332 - !strncmp(dev->name, name, SFI_NAME_LEN)) { 333 - return dev; 334 - } 335 - } 336 - 337 - return NULL; 338 - } 339 - 340 - static int __init sfi_parse_devs(struct sfi_table_header *table) 341 - { 342 - struct sfi_table_simple *sb; 343 - struct sfi_device_table_entry *pentry; 344 - struct devs_id *dev = NULL; 345 - int num, i, ret; 346 - int polarity; 347 - struct irq_alloc_info info; 348 - 349 - sb = (struct sfi_table_simple *)table; 350 - num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry); 351 - pentry = (struct sfi_device_table_entry *)sb->pentry; 352 - 353 - for (i = 0; i < num; i++, pentry++) { 354 - int irq = pentry->irq; 355 - 356 - if (irq != (u8)0xff) { /* native RTE case */ 357 - /* these SPI2 devices are not exposed to system as PCI 358 - * devices, but they have separate RTE entry in IOAPIC 359 - * so we have to enable them one by one here 360 - */ 361 - if (intel_mid_identify_cpu() == 362 - INTEL_MID_CPU_CHIP_TANGIER) { 363 - if (!strncmp(pentry->name, "r69001-ts-i2c", 13)) 364 - /* active low */ 365 - polarity = 1; 366 - else if (!strncmp(pentry->name, 367 - "synaptics_3202", 14)) 368 - /* active low */ 369 - polarity = 1; 370 - else if (irq == 41) 371 - /* fast_int_1 */ 372 - polarity = 1; 373 - else 374 - /* active high */ 375 - polarity = 0; 376 - } else { 377 - /* PNW and CLV go with active low */ 378 - polarity = 1; 379 - } 380 - 381 - ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 1, polarity); 382 - ret = mp_map_gsi_to_irq(irq, IOAPIC_MAP_ALLOC, &info); 383 - WARN_ON(ret < 0); 384 - } 385 - 386 - dev = get_device_id(pentry->type, pentry->name); 387 - 388 - if (!dev) 389 - continue; 390 - 391 - switch (pentry->type) { 392 - case SFI_DEV_TYPE_IPC: 393 - sfi_handle_ipc_dev(pentry, dev); 394 - break; 395 - case SFI_DEV_TYPE_SPI: 396 - sfi_handle_spi_dev(pentry, dev); 397 - break; 398 - case SFI_DEV_TYPE_I2C: 399 - sfi_handle_i2c_dev(pentry, dev); 400 - break; 401 - case SFI_DEV_TYPE_SD: 402 - sfi_handle_sd_dev(pentry, dev); 403 - break; 404 - case SFI_DEV_TYPE_UART: 405 - case SFI_DEV_TYPE_HSI: 406 - default: 407 - break; 408 - } 409 - } 410 - return 0; 411 - } 412 - 413 - static int __init intel_mid_platform_init(void) 414 - { 415 - sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio); 416 - sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs); 417 - return 0; 418 - } 419 - arch_initcall(intel_mid_platform_init);
-2
arch/x86/platform/sfi/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - obj-$(CONFIG_SFI) += sfi.o
-100
arch/x86/platform/sfi/sfi.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * sfi.c - x86 architecture SFI support. 4 - * 5 - * Copyright (c) 2009, Intel Corporation. 6 - */ 7 - 8 - #define KMSG_COMPONENT "SFI" 9 - #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 - 11 - #include <linux/acpi.h> 12 - #include <linux/init.h> 13 - #include <linux/sfi.h> 14 - #include <linux/io.h> 15 - 16 - #include <asm/irqdomain.h> 17 - #include <asm/io_apic.h> 18 - #include <asm/mpspec.h> 19 - #include <asm/setup.h> 20 - #include <asm/apic.h> 21 - 22 - #ifdef CONFIG_X86_LOCAL_APIC 23 - static unsigned long sfi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; 24 - 25 - /* All CPUs enumerated by SFI must be present and enabled */ 26 - static void __init mp_sfi_register_lapic(u8 id) 27 - { 28 - if (MAX_LOCAL_APIC - id <= 0) { 29 - pr_warn("Processor #%d invalid (max %d)\n", id, MAX_LOCAL_APIC); 30 - return; 31 - } 32 - 33 - pr_info("registering lapic[%d]\n", id); 34 - 35 - generic_processor_info(id, GET_APIC_VERSION(apic_read(APIC_LVR))); 36 - } 37 - 38 - static int __init sfi_parse_cpus(struct sfi_table_header *table) 39 - { 40 - struct sfi_table_simple *sb; 41 - struct sfi_cpu_table_entry *pentry; 42 - int i; 43 - int cpu_num; 44 - 45 - sb = (struct sfi_table_simple *)table; 46 - cpu_num = SFI_GET_NUM_ENTRIES(sb, struct sfi_cpu_table_entry); 47 - pentry = (struct sfi_cpu_table_entry *)sb->pentry; 48 - 49 - for (i = 0; i < cpu_num; i++) { 50 - mp_sfi_register_lapic(pentry->apic_id); 51 - pentry++; 52 - } 53 - 54 - smp_found_config = 1; 55 - return 0; 56 - } 57 - #endif /* CONFIG_X86_LOCAL_APIC */ 58 - 59 - #ifdef CONFIG_X86_IO_APIC 60 - 61 - static int __init sfi_parse_ioapic(struct sfi_table_header *table) 62 - { 63 - struct sfi_table_simple *sb; 64 - struct sfi_apic_table_entry *pentry; 65 - int i, num; 66 - struct ioapic_domain_cfg cfg = { 67 - .type = IOAPIC_DOMAIN_STRICT, 68 - .ops = &mp_ioapic_irqdomain_ops, 69 - }; 70 - 71 - sb = (struct sfi_table_simple *)table; 72 - num = SFI_GET_NUM_ENTRIES(sb, struct sfi_apic_table_entry); 73 - pentry = (struct sfi_apic_table_entry *)sb->pentry; 74 - 75 - for (i = 0; i < num; i++) { 76 - mp_register_ioapic(i, pentry->phys_addr, gsi_top, &cfg); 77 - pentry++; 78 - } 79 - 80 - WARN(pic_mode, KERN_WARNING 81 - "SFI: pic_mod shouldn't be 1 when IOAPIC table is present\n"); 82 - pic_mode = 0; 83 - return 0; 84 - } 85 - #endif /* CONFIG_X86_IO_APIC */ 86 - 87 - /* 88 - * sfi_platform_init(): register lapics & io-apics 89 - */ 90 - int __init sfi_platform_init(void) 91 - { 92 - #ifdef CONFIG_X86_LOCAL_APIC 93 - register_lapic_address(sfi_lapic_addr); 94 - sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, sfi_parse_cpus); 95 - #endif 96 - #ifdef CONFIG_X86_IO_APIC 97 - sfi_table_parse(SFI_SIG_APIC, NULL, NULL, sfi_parse_ioapic); 98 - #endif 99 - return 0; 100 - }
+1 -1
drivers/Makefile
··· 27 27 obj-y += char/ipmi/ 28 28 29 29 obj-$(CONFIG_ACPI) += acpi/ 30 - obj-$(CONFIG_SFI) += sfi/ 30 + 31 31 # PnP must come after ACPI since it will eventually need to check if acpi 32 32 # was used and do nothing if so 33 33 obj-$(CONFIG_PNP) += pnp/
+4 -18
drivers/platform/x86/intel_scu_pcidrv.c
··· 17 17 static int intel_scu_pci_probe(struct pci_dev *pdev, 18 18 const struct pci_device_id *id) 19 19 { 20 - void (*setup_fn)(void) = (void (*)(void))id->driver_data; 21 20 struct intel_scu_ipc_data scu_data = {}; 22 21 struct intel_scu_ipc_dev *scu; 23 22 int ret; ··· 29 30 scu_data.irq = pdev->irq; 30 31 31 32 scu = intel_scu_ipc_register(&pdev->dev, &scu_data); 32 - if (IS_ERR(scu)) 33 - return PTR_ERR(scu); 34 - 35 - if (setup_fn) 36 - setup_fn(); 37 - return 0; 38 - } 39 - 40 - static void intel_mid_scu_setup(void) 41 - { 42 - intel_scu_devices_create(); 33 + return PTR_ERR_OR_ZERO(scu); 43 34 } 44 35 45 36 static const struct pci_device_id pci_ids[] = { 46 - { PCI_VDEVICE(INTEL, 0x080e), 47 - .driver_data = (kernel_ulong_t)intel_mid_scu_setup }, 48 - { PCI_VDEVICE(INTEL, 0x08ea), 49 - .driver_data = (kernel_ulong_t)intel_mid_scu_setup }, 37 + { PCI_VDEVICE(INTEL, 0x080e) }, 38 + { PCI_VDEVICE(INTEL, 0x08ea) }, 50 39 { PCI_VDEVICE(INTEL, 0x0a94) }, 51 - { PCI_VDEVICE(INTEL, 0x11a0), 52 - .driver_data = (kernel_ulong_t)intel_mid_scu_setup }, 40 + { PCI_VDEVICE(INTEL, 0x11a0) }, 53 41 { PCI_VDEVICE(INTEL, 0x1a94) }, 54 42 { PCI_VDEVICE(INTEL, 0x5a94) }, 55 43 {}
-18
drivers/sfi/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # SFI Configuration 4 - # 5 - 6 - menuconfig SFI 7 - bool "SFI (Simple Firmware Interface) Support" 8 - help 9 - The Simple Firmware Interface (SFI) provides a lightweight method 10 - for platform firmware to pass information to the operating system 11 - via static tables in memory. Kernel SFI support is required to 12 - boot on SFI-only platforms. Currently, all SFI-only platforms are 13 - based on the 2nd generation Intel Atom processor platform, 14 - code-named Moorestown. 15 - 16 - For more information, see http://simplefirmware.org 17 - 18 - Say 'Y' here to enable the kernel to boot on SFI-only platforms.
-4
drivers/sfi/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - obj-y += sfi_acpi.o 3 - obj-y += sfi_core.o 4 -
-214
drivers/sfi/sfi_acpi.c
··· 1 - /* sfi_acpi.c Simple Firmware Interface - ACPI extensions */ 2 - 3 - /* 4 - 5 - This file is provided under a dual BSD/GPLv2 license. When using or 6 - redistributing this file, you may do so under either license. 7 - 8 - GPL LICENSE SUMMARY 9 - 10 - Copyright(c) 2009 Intel Corporation. All rights reserved. 11 - 12 - This program is free software; you can redistribute it and/or modify 13 - it under the terms of version 2 of the GNU General Public License as 14 - published by the Free Software Foundation. 15 - 16 - This program is distributed in the hope that it will be useful, but 17 - WITHOUT ANY WARRANTY; without even the implied warranty of 18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 - General Public License for more details. 20 - 21 - You should have received a copy of the GNU General Public License 22 - along with this program; if not, write to the Free Software 23 - Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 - The full GNU General Public License is included in this distribution 25 - in the file called LICENSE.GPL. 26 - 27 - BSD LICENSE 28 - 29 - Copyright(c) 2009 Intel Corporation. All rights reserved. 30 - 31 - Redistribution and use in source and binary forms, with or without 32 - modification, are permitted provided that the following conditions 33 - are met: 34 - 35 - * Redistributions of source code must retain the above copyright 36 - notice, this list of conditions and the following disclaimer. 37 - * Redistributions in binary form must reproduce the above copyright 38 - notice, this list of conditions and the following disclaimer in 39 - the documentation and/or other materials provided with the 40 - distribution. 41 - * Neither the name of Intel Corporation nor the names of its 42 - contributors may be used to endorse or promote products derived 43 - from this software without specific prior written permission. 44 - 45 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 49 - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 51 - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 55 - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 - 57 - */ 58 - 59 - #define KMSG_COMPONENT "SFI" 60 - #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 61 - 62 - #include <linux/kernel.h> 63 - #include <linux/sfi_acpi.h> 64 - #include "sfi_core.h" 65 - 66 - /* 67 - * SFI can access ACPI-defined tables via an optional ACPI XSDT. 68 - * 69 - * This allows re-use, and avoids re-definition, of standard tables. 70 - * For example, the "MCFG" table is defined by PCI, reserved by ACPI, 71 - * and is expected to be present many SFI-only systems. 72 - */ 73 - 74 - static struct acpi_table_xsdt *xsdt_va __read_mostly; 75 - 76 - #define XSDT_GET_NUM_ENTRIES(ptable, entry_type) \ 77 - ((ptable->header.length - sizeof(struct acpi_table_header)) / \ 78 - (sizeof(entry_type))) 79 - 80 - static inline struct sfi_table_header *acpi_to_sfi_th( 81 - struct acpi_table_header *th) 82 - { 83 - return (struct sfi_table_header *)th; 84 - } 85 - 86 - static inline struct acpi_table_header *sfi_to_acpi_th( 87 - struct sfi_table_header *th) 88 - { 89 - return (struct acpi_table_header *)th; 90 - } 91 - 92 - /* 93 - * sfi_acpi_parse_xsdt() 94 - * 95 - * Parse the ACPI XSDT for later access by sfi_acpi_table_parse(). 96 - */ 97 - static int __init sfi_acpi_parse_xsdt(struct sfi_table_header *th) 98 - { 99 - struct sfi_table_key key = SFI_ANY_KEY; 100 - int tbl_cnt, i; 101 - void *ret; 102 - 103 - xsdt_va = (struct acpi_table_xsdt *)th; 104 - tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 105 - for (i = 0; i < tbl_cnt; i++) { 106 - ret = sfi_check_table(xsdt_va->table_offset_entry[i], &key); 107 - if (IS_ERR(ret)) { 108 - disable_sfi(); 109 - return -1; 110 - } 111 - } 112 - 113 - return 0; 114 - } 115 - 116 - int __init sfi_acpi_init(void) 117 - { 118 - struct sfi_table_key xsdt_key = { .sig = SFI_SIG_XSDT }; 119 - 120 - sfi_table_parse(SFI_SIG_XSDT, NULL, NULL, sfi_acpi_parse_xsdt); 121 - 122 - /* Only call the get_table to keep the table mapped */ 123 - xsdt_va = (struct acpi_table_xsdt *)sfi_get_table(&xsdt_key); 124 - return 0; 125 - } 126 - 127 - static struct acpi_table_header *sfi_acpi_get_table(struct sfi_table_key *key) 128 - { 129 - u32 tbl_cnt, i; 130 - void *ret; 131 - 132 - tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 133 - for (i = 0; i < tbl_cnt; i++) { 134 - ret = sfi_check_table(xsdt_va->table_offset_entry[i], key); 135 - if (!IS_ERR(ret) && ret) 136 - return sfi_to_acpi_th(ret); 137 - } 138 - 139 - return NULL; 140 - } 141 - 142 - static void sfi_acpi_put_table(struct acpi_table_header *table) 143 - { 144 - sfi_put_table(acpi_to_sfi_th(table)); 145 - } 146 - 147 - /* 148 - * sfi_acpi_table_parse() 149 - * 150 - * Find specified table in XSDT, run handler on it and return its return value 151 - */ 152 - int sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id, 153 - int(*handler)(struct acpi_table_header *)) 154 - { 155 - struct acpi_table_header *table = NULL; 156 - struct sfi_table_key key; 157 - int ret = 0; 158 - 159 - if (sfi_disabled) 160 - return -1; 161 - 162 - key.sig = signature; 163 - key.oem_id = oem_id; 164 - key.oem_table_id = oem_table_id; 165 - 166 - table = sfi_acpi_get_table(&key); 167 - if (!table) 168 - return -EINVAL; 169 - 170 - ret = handler(table); 171 - sfi_acpi_put_table(table); 172 - return ret; 173 - } 174 - 175 - static ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj, 176 - struct bin_attribute *bin_attr, char *buf, 177 - loff_t offset, size_t count) 178 - { 179 - struct sfi_table_attr *tbl_attr = 180 - container_of(bin_attr, struct sfi_table_attr, attr); 181 - struct acpi_table_header *th = NULL; 182 - struct sfi_table_key key; 183 - ssize_t cnt; 184 - 185 - key.sig = tbl_attr->name; 186 - key.oem_id = NULL; 187 - key.oem_table_id = NULL; 188 - 189 - th = sfi_acpi_get_table(&key); 190 - if (!th) 191 - return 0; 192 - 193 - cnt = memory_read_from_buffer(buf, count, &offset, 194 - th, th->length); 195 - sfi_acpi_put_table(th); 196 - 197 - return cnt; 198 - } 199 - 200 - 201 - void __init sfi_acpi_sysfs_init(void) 202 - { 203 - u32 tbl_cnt, i; 204 - struct sfi_table_attr *tbl_attr; 205 - 206 - tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 207 - for (i = 0; i < tbl_cnt; i++) { 208 - tbl_attr = 209 - sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]); 210 - tbl_attr->attr.read = sfi_acpi_table_show; 211 - } 212 - 213 - return; 214 - }
-522
drivers/sfi/sfi_core.c
··· 1 - /* sfi_core.c Simple Firmware Interface - core internals */ 2 - 3 - /* 4 - 5 - This file is provided under a dual BSD/GPLv2 license. When using or 6 - redistributing this file, you may do so under either license. 7 - 8 - GPL LICENSE SUMMARY 9 - 10 - Copyright(c) 2009 Intel Corporation. All rights reserved. 11 - 12 - This program is free software; you can redistribute it and/or modify 13 - it under the terms of version 2 of the GNU General Public License as 14 - published by the Free Software Foundation. 15 - 16 - This program is distributed in the hope that it will be useful, but 17 - WITHOUT ANY WARRANTY; without even the implied warranty of 18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 - General Public License for more details. 20 - 21 - You should have received a copy of the GNU General Public License 22 - along with this program; if not, write to the Free Software 23 - Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 - The full GNU General Public License is included in this distribution 25 - in the file called LICENSE.GPL. 26 - 27 - BSD LICENSE 28 - 29 - Copyright(c) 2009 Intel Corporation. All rights reserved. 30 - 31 - Redistribution and use in source and binary forms, with or without 32 - modification, are permitted provided that the following conditions 33 - are met: 34 - 35 - * Redistributions of source code must retain the above copyright 36 - notice, this list of conditions and the following disclaimer. 37 - * Redistributions in binary form must reproduce the above copyright 38 - notice, this list of conditions and the following disclaimer in 39 - the documentation and/or other materials provided with the 40 - distribution. 41 - * Neither the name of Intel Corporation nor the names of its 42 - contributors may be used to endorse or promote products derived 43 - from this software without specific prior written permission. 44 - 45 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 49 - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 51 - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 55 - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 - 57 - */ 58 - 59 - #define KMSG_COMPONENT "SFI" 60 - #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 61 - 62 - #include <linux/memblock.h> 63 - #include <linux/kernel.h> 64 - #include <linux/module.h> 65 - #include <linux/errno.h> 66 - #include <linux/types.h> 67 - #include <linux/acpi.h> 68 - #include <linux/init.h> 69 - #include <linux/sfi.h> 70 - #include <linux/slab.h> 71 - #include <linux/io.h> 72 - 73 - #include "sfi_core.h" 74 - 75 - #define ON_SAME_PAGE(addr1, addr2) \ 76 - (((unsigned long)(addr1) & PAGE_MASK) == \ 77 - ((unsigned long)(addr2) & PAGE_MASK)) 78 - #define TABLE_ON_PAGE(page, table, size) (ON_SAME_PAGE(page, table) && \ 79 - ON_SAME_PAGE(page, table + size)) 80 - 81 - int sfi_disabled __read_mostly; 82 - EXPORT_SYMBOL(sfi_disabled); 83 - 84 - static u64 syst_pa __read_mostly; 85 - static struct sfi_table_simple *syst_va __read_mostly; 86 - 87 - /* 88 - * FW creates and saves the SFI tables in memory. When these tables get 89 - * used, they may need to be mapped to virtual address space, and the mapping 90 - * can happen before or after the memremap() is ready, so a flag is needed 91 - * to indicating this 92 - */ 93 - static u32 sfi_use_memremap __read_mostly; 94 - 95 - /* 96 - * sfi_un/map_memory calls early_memremap/memunmap which is a __init function 97 - * and introduces section mismatch. So use __ref to make it calm. 98 - */ 99 - static void __iomem * __ref sfi_map_memory(u64 phys, u32 size) 100 - { 101 - if (!phys || !size) 102 - return NULL; 103 - 104 - if (sfi_use_memremap) 105 - return memremap(phys, size, MEMREMAP_WB); 106 - else 107 - return early_memremap(phys, size); 108 - } 109 - 110 - static void __ref sfi_unmap_memory(void __iomem *virt, u32 size) 111 - { 112 - if (!virt || !size) 113 - return; 114 - 115 - if (sfi_use_memremap) 116 - memunmap(virt); 117 - else 118 - early_memunmap(virt, size); 119 - } 120 - 121 - static void sfi_print_table_header(unsigned long long pa, 122 - struct sfi_table_header *header) 123 - { 124 - pr_info("%4.4s %llX, %04X (v%d %6.6s %8.8s)\n", 125 - header->sig, pa, 126 - header->len, header->rev, header->oem_id, 127 - header->oem_table_id); 128 - } 129 - 130 - /* 131 - * sfi_verify_table() 132 - * Sanity check table lengh, calculate checksum 133 - */ 134 - static int sfi_verify_table(struct sfi_table_header *table) 135 - { 136 - 137 - u8 checksum = 0; 138 - u8 *puchar = (u8 *)table; 139 - u32 length = table->len; 140 - 141 - /* Sanity check table length against arbitrary 1MB limit */ 142 - if (length > 0x100000) { 143 - pr_err("Invalid table length 0x%x\n", length); 144 - return -1; 145 - } 146 - 147 - while (length--) 148 - checksum += *puchar++; 149 - 150 - if (checksum) { 151 - pr_err("Checksum %2.2X should be %2.2X\n", 152 - table->csum, table->csum - checksum); 153 - return -1; 154 - } 155 - return 0; 156 - } 157 - 158 - /* 159 - * sfi_map_table() 160 - * 161 - * Return address of mapped table 162 - * Check for common case that we can re-use mapping to SYST, 163 - * which requires syst_pa, syst_va to be initialized. 164 - */ 165 - static struct sfi_table_header *sfi_map_table(u64 pa) 166 - { 167 - struct sfi_table_header *th; 168 - u32 length; 169 - 170 - if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header))) 171 - th = sfi_map_memory(pa, sizeof(struct sfi_table_header)); 172 - else 173 - th = (void *)syst_va + (pa - syst_pa); 174 - 175 - /* If table fits on same page as its header, we are done */ 176 - if (TABLE_ON_PAGE(th, th, th->len)) 177 - return th; 178 - 179 - /* Entire table does not fit on same page as SYST */ 180 - length = th->len; 181 - if (!TABLE_ON_PAGE(syst_pa, pa, sizeof(struct sfi_table_header))) 182 - sfi_unmap_memory(th, sizeof(struct sfi_table_header)); 183 - 184 - return sfi_map_memory(pa, length); 185 - } 186 - 187 - /* 188 - * sfi_unmap_table() 189 - * 190 - * Undoes effect of sfi_map_table() by unmapping table 191 - * if it did not completely fit on same page as SYST. 192 - */ 193 - static void sfi_unmap_table(struct sfi_table_header *th) 194 - { 195 - if (!TABLE_ON_PAGE(syst_va, th, th->len)) 196 - sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ? 197 - sizeof(*th) : th->len); 198 - } 199 - 200 - static int sfi_table_check_key(struct sfi_table_header *th, 201 - struct sfi_table_key *key) 202 - { 203 - 204 - if (strncmp(th->sig, key->sig, SFI_SIGNATURE_SIZE) 205 - || (key->oem_id && strncmp(th->oem_id, 206 - key->oem_id, SFI_OEM_ID_SIZE)) 207 - || (key->oem_table_id && strncmp(th->oem_table_id, 208 - key->oem_table_id, SFI_OEM_TABLE_ID_SIZE))) 209 - return -1; 210 - 211 - return 0; 212 - } 213 - 214 - /* 215 - * This function will be used in 2 cases: 216 - * 1. used to enumerate and verify the tables addressed by SYST/XSDT, 217 - * thus no signature will be given (in kernel boot phase) 218 - * 2. used to parse one specific table, signature must exist, and 219 - * the mapped virt address will be returned, and the virt space 220 - * will be released by call sfi_put_table() later 221 - * 222 - * This two cases are from two different functions with two different 223 - * sections and causes section mismatch warning. So use __ref to tell 224 - * modpost not to make any noise. 225 - * 226 - * Return value: 227 - * NULL: when can't find a table matching the key 228 - * ERR_PTR(error): error value 229 - * virt table address: when a matched table is found 230 - */ 231 - struct sfi_table_header * 232 - __ref sfi_check_table(u64 pa, struct sfi_table_key *key) 233 - { 234 - struct sfi_table_header *th; 235 - void *ret = NULL; 236 - 237 - th = sfi_map_table(pa); 238 - if (!th) 239 - return ERR_PTR(-ENOMEM); 240 - 241 - if (!key->sig) { 242 - sfi_print_table_header(pa, th); 243 - if (sfi_verify_table(th)) 244 - ret = ERR_PTR(-EINVAL); 245 - } else { 246 - if (!sfi_table_check_key(th, key)) 247 - return th; /* Success */ 248 - } 249 - 250 - sfi_unmap_table(th); 251 - return ret; 252 - } 253 - 254 - /* 255 - * sfi_get_table() 256 - * 257 - * Search SYST for the specified table with the signature in 258 - * the key, and return the mapped table 259 - */ 260 - struct sfi_table_header *sfi_get_table(struct sfi_table_key *key) 261 - { 262 - struct sfi_table_header *th; 263 - u32 tbl_cnt, i; 264 - 265 - tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64); 266 - for (i = 0; i < tbl_cnt; i++) { 267 - th = sfi_check_table(syst_va->pentry[i], key); 268 - if (!IS_ERR(th) && th) 269 - return th; 270 - } 271 - 272 - return NULL; 273 - } 274 - 275 - void sfi_put_table(struct sfi_table_header *th) 276 - { 277 - sfi_unmap_table(th); 278 - } 279 - 280 - /* Find table with signature, run handler on it */ 281 - int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id, 282 - sfi_table_handler handler) 283 - { 284 - struct sfi_table_header *table = NULL; 285 - struct sfi_table_key key; 286 - int ret = -EINVAL; 287 - 288 - if (sfi_disabled || !handler || !signature) 289 - goto exit; 290 - 291 - key.sig = signature; 292 - key.oem_id = oem_id; 293 - key.oem_table_id = oem_table_id; 294 - 295 - table = sfi_get_table(&key); 296 - if (!table) 297 - goto exit; 298 - 299 - ret = handler(table); 300 - sfi_put_table(table); 301 - exit: 302 - return ret; 303 - } 304 - EXPORT_SYMBOL_GPL(sfi_table_parse); 305 - 306 - /* 307 - * sfi_parse_syst() 308 - * Checksum all the tables in SYST and print their headers 309 - * 310 - * success: set syst_va, return 0 311 - */ 312 - static int __init sfi_parse_syst(void) 313 - { 314 - struct sfi_table_key key = SFI_ANY_KEY; 315 - int tbl_cnt, i; 316 - void *ret; 317 - 318 - syst_va = sfi_map_memory(syst_pa, sizeof(struct sfi_table_simple)); 319 - if (!syst_va) 320 - return -ENOMEM; 321 - 322 - tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64); 323 - for (i = 0; i < tbl_cnt; i++) { 324 - ret = sfi_check_table(syst_va->pentry[i], &key); 325 - if (IS_ERR(ret)) 326 - return PTR_ERR(ret); 327 - } 328 - 329 - return 0; 330 - } 331 - 332 - /* 333 - * The OS finds the System Table by searching 16-byte boundaries between 334 - * physical address 0x000E0000 and 0x000FFFFF. The OS shall search this region 335 - * starting at the low address and shall stop searching when the 1st valid SFI 336 - * System Table is found. 337 - * 338 - * success: set syst_pa, return 0 339 - * fail: return -1 340 - */ 341 - static __init int sfi_find_syst(void) 342 - { 343 - unsigned long offset, len; 344 - void *start; 345 - 346 - len = SFI_SYST_SEARCH_END - SFI_SYST_SEARCH_BEGIN; 347 - start = sfi_map_memory(SFI_SYST_SEARCH_BEGIN, len); 348 - if (!start) 349 - return -1; 350 - 351 - for (offset = 0; offset < len; offset += 16) { 352 - struct sfi_table_header *syst_hdr; 353 - 354 - syst_hdr = start + offset; 355 - if (strncmp(syst_hdr->sig, SFI_SIG_SYST, 356 - SFI_SIGNATURE_SIZE)) 357 - continue; 358 - 359 - if (syst_hdr->len > PAGE_SIZE) 360 - continue; 361 - 362 - sfi_print_table_header(SFI_SYST_SEARCH_BEGIN + offset, 363 - syst_hdr); 364 - 365 - if (sfi_verify_table(syst_hdr)) 366 - continue; 367 - 368 - /* 369 - * Enforce SFI spec mandate that SYST reside within a page. 370 - */ 371 - if (!ON_SAME_PAGE(syst_pa, syst_pa + syst_hdr->len)) { 372 - pr_info("SYST 0x%llx + 0x%x crosses page\n", 373 - syst_pa, syst_hdr->len); 374 - continue; 375 - } 376 - 377 - /* Success */ 378 - syst_pa = SFI_SYST_SEARCH_BEGIN + offset; 379 - sfi_unmap_memory(start, len); 380 - return 0; 381 - } 382 - 383 - sfi_unmap_memory(start, len); 384 - return -1; 385 - } 386 - 387 - static struct kobject *sfi_kobj; 388 - static struct kobject *tables_kobj; 389 - 390 - static ssize_t sfi_table_show(struct file *filp, struct kobject *kobj, 391 - struct bin_attribute *bin_attr, char *buf, 392 - loff_t offset, size_t count) 393 - { 394 - struct sfi_table_attr *tbl_attr = 395 - container_of(bin_attr, struct sfi_table_attr, attr); 396 - struct sfi_table_header *th = NULL; 397 - struct sfi_table_key key; 398 - ssize_t cnt; 399 - 400 - key.sig = tbl_attr->name; 401 - key.oem_id = NULL; 402 - key.oem_table_id = NULL; 403 - 404 - if (strncmp(SFI_SIG_SYST, tbl_attr->name, SFI_SIGNATURE_SIZE)) { 405 - th = sfi_get_table(&key); 406 - if (!th) 407 - return 0; 408 - 409 - cnt = memory_read_from_buffer(buf, count, &offset, 410 - th, th->len); 411 - sfi_put_table(th); 412 - } else 413 - cnt = memory_read_from_buffer(buf, count, &offset, 414 - syst_va, syst_va->header.len); 415 - 416 - return cnt; 417 - } 418 - 419 - struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa) 420 - { 421 - struct sfi_table_attr *tbl_attr; 422 - struct sfi_table_header *th; 423 - int ret; 424 - 425 - tbl_attr = kzalloc(sizeof(struct sfi_table_attr), GFP_KERNEL); 426 - if (!tbl_attr) 427 - return NULL; 428 - 429 - th = sfi_map_table(pa); 430 - if (!th || !th->sig[0]) { 431 - kfree(tbl_attr); 432 - return NULL; 433 - } 434 - 435 - sysfs_attr_init(&tbl_attr->attr.attr); 436 - memcpy(tbl_attr->name, th->sig, SFI_SIGNATURE_SIZE); 437 - 438 - tbl_attr->attr.size = 0; 439 - tbl_attr->attr.read = sfi_table_show; 440 - tbl_attr->attr.attr.name = tbl_attr->name; 441 - tbl_attr->attr.attr.mode = 0400; 442 - 443 - ret = sysfs_create_bin_file(tables_kobj, 444 - &tbl_attr->attr); 445 - if (ret) { 446 - kfree(tbl_attr); 447 - tbl_attr = NULL; 448 - } 449 - 450 - sfi_unmap_table(th); 451 - return tbl_attr; 452 - } 453 - 454 - static int __init sfi_sysfs_init(void) 455 - { 456 - int tbl_cnt, i; 457 - 458 - if (sfi_disabled) 459 - return 0; 460 - 461 - sfi_kobj = kobject_create_and_add("sfi", firmware_kobj); 462 - if (!sfi_kobj) 463 - return 0; 464 - 465 - tables_kobj = kobject_create_and_add("tables", sfi_kobj); 466 - if (!tables_kobj) { 467 - kobject_put(sfi_kobj); 468 - return 0; 469 - } 470 - 471 - sfi_sysfs_install_table(syst_pa); 472 - 473 - tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64); 474 - 475 - for (i = 0; i < tbl_cnt; i++) 476 - sfi_sysfs_install_table(syst_va->pentry[i]); 477 - 478 - sfi_acpi_sysfs_init(); 479 - kobject_uevent(sfi_kobj, KOBJ_ADD); 480 - kobject_uevent(tables_kobj, KOBJ_ADD); 481 - pr_info("SFI sysfs interfaces init success\n"); 482 - return 0; 483 - } 484 - 485 - void __init sfi_init(void) 486 - { 487 - if (!acpi_disabled) 488 - disable_sfi(); 489 - 490 - if (sfi_disabled) 491 - return; 492 - 493 - pr_info("Simple Firmware Interface v0.81 http://simplefirmware.org\n"); 494 - 495 - if (sfi_find_syst() || sfi_parse_syst() || sfi_platform_init()) 496 - disable_sfi(); 497 - 498 - return; 499 - } 500 - 501 - void __init sfi_init_late(void) 502 - { 503 - int length; 504 - 505 - if (sfi_disabled) 506 - return; 507 - 508 - length = syst_va->header.len; 509 - sfi_unmap_memory(syst_va, sizeof(struct sfi_table_simple)); 510 - 511 - /* Use memremap now after it is ready */ 512 - sfi_use_memremap = 1; 513 - syst_va = sfi_map_memory(syst_pa, length); 514 - 515 - sfi_acpi_init(); 516 - } 517 - 518 - /* 519 - * The reason we put it here because we need wait till the /sys/firmware 520 - * is setup, then our interface can be registered in /sys/firmware/sfi 521 - */ 522 - core_initcall(sfi_sysfs_init);
-81
drivers/sfi/sfi_core.h
··· 1 - /* sfi_core.h Simple Firmware Interface, internal header */ 2 - 3 - /* 4 - 5 - This file is provided under a dual BSD/GPLv2 license. When using or 6 - redistributing this file, you may do so under either license. 7 - 8 - GPL LICENSE SUMMARY 9 - 10 - Copyright(c) 2009 Intel Corporation. All rights reserved. 11 - 12 - This program is free software; you can redistribute it and/or modify 13 - it under the terms of version 2 of the GNU General Public License as 14 - published by the Free Software Foundation. 15 - 16 - This program is distributed in the hope that it will be useful, but 17 - WITHOUT ANY WARRANTY; without even the implied warranty of 18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 - General Public License for more details. 20 - 21 - You should have received a copy of the GNU General Public License 22 - along with this program; if not, write to the Free Software 23 - Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 - The full GNU General Public License is included in this distribution 25 - in the file called LICENSE.GPL. 26 - 27 - BSD LICENSE 28 - 29 - Copyright(c) 2009 Intel Corporation. All rights reserved. 30 - 31 - Redistribution and use in source and binary forms, with or without 32 - modification, are permitted provided that the following conditions 33 - are met: 34 - 35 - * Redistributions of source code must retain the above copyright 36 - notice, this list of conditions and the following disclaimer. 37 - * Redistributions in binary form must reproduce the above copyright 38 - notice, this list of conditions and the following disclaimer in 39 - the documentation and/or other materials provided with the 40 - distribution. 41 - * Neither the name of Intel Corporation nor the names of its 42 - contributors may be used to endorse or promote products derived 43 - from this software without specific prior written permission. 44 - 45 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 49 - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 51 - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 55 - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 - 57 - */ 58 - 59 - #include <linux/sysfs.h> 60 - 61 - struct sfi_table_key{ 62 - char *sig; 63 - char *oem_id; 64 - char *oem_table_id; 65 - }; 66 - 67 - /* sysfs interface */ 68 - struct sfi_table_attr { 69 - struct bin_attribute attr; 70 - char name[8]; 71 - }; 72 - 73 - #define SFI_ANY_KEY { .sig = NULL, .oem_id = NULL, .oem_table_id = NULL } 74 - 75 - extern int __init sfi_acpi_init(void); 76 - extern struct sfi_table_header *sfi_check_table(u64 paddr, 77 - struct sfi_table_key *key); 78 - struct sfi_table_header *sfi_get_table(struct sfi_table_key *key); 79 - extern void sfi_put_table(struct sfi_table_header *table); 80 - extern struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa); 81 - extern void __init sfi_acpi_sysfs_init(void);
-210
include/linux/sfi.h
··· 1 - /* sfi.h Simple Firmware Interface */ 2 - 3 - /* 4 - 5 - This file is provided under a dual BSD/GPLv2 license. When using or 6 - redistributing this file, you may do so under either license. 7 - 8 - GPL LICENSE SUMMARY 9 - 10 - Copyright(c) 2009 Intel Corporation. All rights reserved. 11 - 12 - This program is free software; you can redistribute it and/or modify 13 - it under the terms of version 2 of the GNU General Public License as 14 - published by the Free Software Foundation. 15 - 16 - This program is distributed in the hope that it will be useful, but 17 - WITHOUT ANY WARRANTY; without even the implied warranty of 18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 - General Public License for more details. 20 - 21 - You should have received a copy of the GNU General Public License 22 - along with this program; if not, write to the Free Software 23 - Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 - The full GNU General Public License is included in this distribution 25 - in the file called LICENSE.GPL. 26 - 27 - BSD LICENSE 28 - 29 - Copyright(c) 2009 Intel Corporation. All rights reserved. 30 - 31 - Redistribution and use in source and binary forms, with or without 32 - modification, are permitted provided that the following conditions 33 - are met: 34 - 35 - * Redistributions of source code must retain the above copyright 36 - notice, this list of conditions and the following disclaimer. 37 - * Redistributions in binary form must reproduce the above copyright 38 - notice, this list of conditions and the following disclaimer in 39 - the documentation and/or other materials provided with the 40 - distribution. 41 - * Neither the name of Intel Corporation nor the names of its 42 - contributors may be used to endorse or promote products derived 43 - from this software without specific prior written permission. 44 - 45 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 49 - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 51 - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 55 - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 - 57 - */ 58 - 59 - #ifndef _LINUX_SFI_H 60 - #define _LINUX_SFI_H 61 - 62 - #include <linux/init.h> 63 - #include <linux/types.h> 64 - 65 - /* Table signatures reserved by the SFI specification */ 66 - #define SFI_SIG_SYST "SYST" 67 - #define SFI_SIG_FREQ "FREQ" 68 - #define SFI_SIG_IDLE "IDLE" 69 - #define SFI_SIG_CPUS "CPUS" 70 - #define SFI_SIG_MTMR "MTMR" 71 - #define SFI_SIG_MRTC "MRTC" 72 - #define SFI_SIG_MMAP "MMAP" 73 - #define SFI_SIG_APIC "APIC" 74 - #define SFI_SIG_XSDT "XSDT" 75 - #define SFI_SIG_WAKE "WAKE" 76 - #define SFI_SIG_DEVS "DEVS" 77 - #define SFI_SIG_GPIO "GPIO" 78 - 79 - #define SFI_SIGNATURE_SIZE 4 80 - #define SFI_OEM_ID_SIZE 6 81 - #define SFI_OEM_TABLE_ID_SIZE 8 82 - 83 - #define SFI_NAME_LEN 16 84 - 85 - #define SFI_SYST_SEARCH_BEGIN 0x000E0000 86 - #define SFI_SYST_SEARCH_END 0x000FFFFF 87 - 88 - #define SFI_GET_NUM_ENTRIES(ptable, entry_type) \ 89 - ((ptable->header.len - sizeof(struct sfi_table_header)) / \ 90 - (sizeof(entry_type))) 91 - /* 92 - * Table structures must be byte-packed to match the SFI specification, 93 - * as they are provided by the BIOS. 94 - */ 95 - struct sfi_table_header { 96 - char sig[SFI_SIGNATURE_SIZE]; 97 - u32 len; 98 - u8 rev; 99 - u8 csum; 100 - char oem_id[SFI_OEM_ID_SIZE]; 101 - char oem_table_id[SFI_OEM_TABLE_ID_SIZE]; 102 - } __packed; 103 - 104 - struct sfi_table_simple { 105 - struct sfi_table_header header; 106 - u64 pentry[1]; 107 - } __packed; 108 - 109 - /* Comply with UEFI spec 2.1 */ 110 - struct sfi_mem_entry { 111 - u32 type; 112 - u64 phys_start; 113 - u64 virt_start; 114 - u64 pages; 115 - u64 attrib; 116 - } __packed; 117 - 118 - struct sfi_cpu_table_entry { 119 - u32 apic_id; 120 - } __packed; 121 - 122 - struct sfi_cstate_table_entry { 123 - u32 hint; /* MWAIT hint */ 124 - u32 latency; /* latency in ms */ 125 - } __packed; 126 - 127 - struct sfi_apic_table_entry { 128 - u64 phys_addr; /* phy base addr for APIC reg */ 129 - } __packed; 130 - 131 - struct sfi_freq_table_entry { 132 - u32 freq_mhz; /* in MHZ */ 133 - u32 latency; /* transition latency in ms */ 134 - u32 ctrl_val; /* value to write to PERF_CTL */ 135 - } __packed; 136 - 137 - struct sfi_wake_table_entry { 138 - u64 phys_addr; /* pointer to where the wake vector locates */ 139 - } __packed; 140 - 141 - struct sfi_timer_table_entry { 142 - u64 phys_addr; /* phy base addr for the timer */ 143 - u32 freq_hz; /* in HZ */ 144 - u32 irq; 145 - } __packed; 146 - 147 - struct sfi_rtc_table_entry { 148 - u64 phys_addr; /* phy base addr for the RTC */ 149 - u32 irq; 150 - } __packed; 151 - 152 - struct sfi_device_table_entry { 153 - u8 type; /* bus type, I2C, SPI or ...*/ 154 - #define SFI_DEV_TYPE_SPI 0 155 - #define SFI_DEV_TYPE_I2C 1 156 - #define SFI_DEV_TYPE_UART 2 157 - #define SFI_DEV_TYPE_HSI 3 158 - #define SFI_DEV_TYPE_IPC 4 159 - #define SFI_DEV_TYPE_SD 5 160 - 161 - u8 host_num; /* attached to host 0, 1...*/ 162 - u16 addr; 163 - u8 irq; 164 - u32 max_freq; 165 - char name[SFI_NAME_LEN]; 166 - } __packed; 167 - 168 - struct sfi_gpio_table_entry { 169 - char controller_name[SFI_NAME_LEN]; 170 - u16 pin_no; 171 - char pin_name[SFI_NAME_LEN]; 172 - } __packed; 173 - 174 - typedef int (*sfi_table_handler) (struct sfi_table_header *table); 175 - 176 - #ifdef CONFIG_SFI 177 - extern void __init sfi_init(void); 178 - extern int __init sfi_platform_init(void); 179 - extern void __init sfi_init_late(void); 180 - extern int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id, 181 - sfi_table_handler handler); 182 - 183 - extern int sfi_disabled; 184 - static inline void disable_sfi(void) 185 - { 186 - sfi_disabled = 1; 187 - } 188 - 189 - #else /* !CONFIG_SFI */ 190 - 191 - static inline void sfi_init(void) 192 - { 193 - } 194 - 195 - static inline void sfi_init_late(void) 196 - { 197 - } 198 - 199 - #define sfi_disabled 0 200 - 201 - static inline int sfi_table_parse(char *signature, char *oem_id, 202 - char *oem_table_id, 203 - sfi_table_handler handler) 204 - { 205 - return -1; 206 - } 207 - 208 - #endif /* !CONFIG_SFI */ 209 - 210 - #endif /*_LINUX_SFI_H*/
-93
include/linux/sfi_acpi.h
··· 1 - /* sfi.h Simple Firmware Interface */ 2 - 3 - /* 4 - 5 - This file is provided under a dual BSD/GPLv2 license. When using or 6 - redistributing this file, you may do so under either license. 7 - 8 - GPL LICENSE SUMMARY 9 - 10 - Copyright(c) 2009 Intel Corporation. All rights reserved. 11 - 12 - This program is free software; you can redistribute it and/or modify 13 - it under the terms of version 2 of the GNU General Public License as 14 - published by the Free Software Foundation. 15 - 16 - This program is distributed in the hope that it will be useful, but 17 - WITHOUT ANY WARRANTY; without even the implied warranty of 18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 - General Public License for more details. 20 - 21 - You should have received a copy of the GNU General Public License 22 - along with this program; if not, write to the Free Software 23 - Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 24 - The full GNU General Public License is included in this distribution 25 - in the file called LICENSE.GPL. 26 - 27 - BSD LICENSE 28 - 29 - Copyright(c) 2009 Intel Corporation. All rights reserved. 30 - 31 - Redistribution and use in source and binary forms, with or without 32 - modification, are permitted provided that the following conditions 33 - are met: 34 - 35 - * Redistributions of source code must retain the above copyright 36 - notice, this list of conditions and the following disclaimer. 37 - * Redistributions in binary form must reproduce the above copyright 38 - notice, this list of conditions and the following disclaimer in 39 - the documentation and/or other materials provided with the 40 - distribution. 41 - * Neither the name of Intel Corporation nor the names of its 42 - contributors may be used to endorse or promote products derived 43 - from this software without specific prior written permission. 44 - 45 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 48 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 49 - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 51 - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 55 - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 - 57 - */ 58 - 59 - #ifndef _LINUX_SFI_ACPI_H 60 - #define _LINUX_SFI_ACPI_H 61 - 62 - #include <linux/acpi.h> 63 - #include <linux/sfi.h> 64 - 65 - #ifdef CONFIG_SFI 66 - extern int sfi_acpi_table_parse(char *signature, char *oem_id, 67 - char *oem_table_id, 68 - int (*handler)(struct acpi_table_header *)); 69 - 70 - static inline int __init acpi_sfi_table_parse(char *signature, 71 - int (*handler)(struct acpi_table_header *)) 72 - { 73 - if (!acpi_table_parse(signature, handler)) 74 - return 0; 75 - 76 - return sfi_acpi_table_parse(signature, NULL, NULL, handler); 77 - } 78 - #else /* !CONFIG_SFI */ 79 - static inline int sfi_acpi_table_parse(char *signature, char *oem_id, 80 - char *oem_table_id, 81 - int (*handler)(struct acpi_table_header *)) 82 - { 83 - return -1; 84 - } 85 - 86 - static inline int __init acpi_sfi_table_parse(char *signature, 87 - int (*handler)(struct acpi_table_header *)) 88 - { 89 - return acpi_table_parse(signature, handler); 90 - } 91 - #endif /* !CONFIG_SFI */ 92 - 93 - #endif /*_LINUX_SFI_ACPI_H*/
-2
init/main.c
··· 74 74 #include <linux/kgdb.h> 75 75 #include <linux/ftrace.h> 76 76 #include <linux/async.h> 77 - #include <linux/sfi.h> 78 77 #include <linux/shmem_fs.h> 79 78 #include <linux/slab.h> 80 79 #include <linux/perf_event.h> ··· 1053 1054 1054 1055 acpi_subsystem_init(); 1055 1056 arch_post_acpi_subsys_init(); 1056 - sfi_init_late(); 1057 1057 kcsan_init(); 1058 1058 1059 1059 /* Do the rest non-__init'ed, we're now alive */