LoongArch: Old BPI compatibility
Upstream: no Signed-off-by: liuyun <liuyun@loongson.cn> Signed-off-by: Ming Wang <wangming01@loongson.cn>
This commit is contained in:
parent
eae789a871
commit
4fe09071db
|
@ -124,6 +124,7 @@ extern unsigned long vm_map_base;
|
|||
#define PCI_IOSIZE SZ_32M
|
||||
#define ISA_IOSIZE SZ_16K
|
||||
#define IO_SPACE_LIMIT (PCI_IOSIZE - 1)
|
||||
#define ISA_PHY_IOBASE LOONGSON_LIO_BASE
|
||||
|
||||
#define PHYS_LINK_KADDR PHYSADDR(VMLINUX_LOAD_ADDRESS)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define _ASM_LOONGARCH_EFI_H
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
|
||||
void __init efi_init(void);
|
||||
void __init efi_runtime_init(void);
|
||||
|
|
|
@ -9,6 +9,7 @@ obj-y += head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \
|
|||
traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \
|
||||
elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \
|
||||
alternative.o unwind.o
|
||||
obj-y += legacy_boot.o
|
||||
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/loongson.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
int acpi_disabled;
|
||||
EXPORT_SYMBOL(acpi_disabled);
|
||||
|
@ -58,7 +59,7 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int set_processor_mask(u32 id, u32 flags)
|
||||
int set_processor_mask(u32 id, u32 flags)
|
||||
{
|
||||
|
||||
int cpu, cpuid = id;
|
||||
|
@ -132,6 +133,10 @@ static void __init acpi_process_madt(void)
|
|||
__cpu_logical_map[i] = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (efi_bp && bpi_version <= BPI_VERSION_V1)
|
||||
legacy_madt_table_init();
|
||||
|
||||
acpi_table_parse_madt(ACPI_MADT_TYPE_CORE_PIC,
|
||||
acpi_parse_processor, MAX_CORE_PIC);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <asm/tlb.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
static unsigned long efi_nr_tables;
|
||||
static unsigned long efi_config_table;
|
||||
|
@ -172,6 +173,9 @@ static int __init set_virtual_map(void)
|
|||
efi_set_virtual_address_map_t *svam;
|
||||
efi_memory_desc_t *in, runtime_map[32];
|
||||
|
||||
if (efi_bp)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
size = sizeof(efi_memory_desc_t);
|
||||
|
||||
for_each_efi_memory_desc(in) {
|
||||
|
@ -254,10 +258,12 @@ void __init efi_init(void)
|
|||
void *config_tables;
|
||||
struct efi_boot_memmap *tbl;
|
||||
|
||||
if (!efi_system_table)
|
||||
return;
|
||||
if (efi_system_table)
|
||||
efi_systab = (efi_system_table_t *)early_memremap_ro(efi_system_table,
|
||||
sizeof(*efi_systab));
|
||||
else
|
||||
efi_systab = (efi_system_table_t *)efi_bp->systemtable;
|
||||
|
||||
efi_systab = (efi_system_table_t *)early_memremap_ro(efi_system_table, sizeof(*efi_systab));
|
||||
if (!efi_systab) {
|
||||
pr_err("Can't find EFI system table.\n");
|
||||
return;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <asm/bootinfo.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/setup.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
u64 efi_system_table;
|
||||
struct loongson_system_configuration loongson_sysconf;
|
||||
|
@ -22,6 +23,11 @@ void __init init_environ(void)
|
|||
int efi_boot = fw_arg0;
|
||||
char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE);
|
||||
|
||||
legacy_boot_init(fw_arg0, fw_arg1, fw_arg2);
|
||||
|
||||
if (efi_bp)
|
||||
return;
|
||||
|
||||
if (efi_boot)
|
||||
set_bit(EFI_BOOT, &efi.flags);
|
||||
else
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/setup.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
DEFINE_PER_CPU(unsigned long, irq_stack);
|
||||
DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
|
||||
|
@ -61,6 +62,12 @@ static int __init early_pci_mcfg_parse(struct acpi_table_header *header)
|
|||
if (header->length < sizeof(struct acpi_table_mcfg))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < MAX_IO_PICS; i++) {
|
||||
msi_group[i].pci_segment = -1;
|
||||
msi_group[i].node = -1;
|
||||
pch_group[i].node = -1;
|
||||
}
|
||||
|
||||
n = (header->length - sizeof(struct acpi_table_mcfg)) /
|
||||
sizeof(struct acpi_mcfg_allocation);
|
||||
mcfg = (struct acpi_table_mcfg *)header;
|
||||
|
@ -76,14 +83,6 @@ static int __init early_pci_mcfg_parse(struct acpi_table_header *header)
|
|||
|
||||
static void __init init_vec_parent_group(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_IO_PICS; i++) {
|
||||
msi_group[i].pci_segment = -1;
|
||||
msi_group[i].node = -1;
|
||||
pch_group[i].node = -1;
|
||||
}
|
||||
|
||||
acpi_table_parse(ACPI_SIG_MCFG, early_pci_mcfg_parse);
|
||||
}
|
||||
|
||||
|
@ -99,7 +98,7 @@ static int __init get_ipi_irq(void)
|
|||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
#ifdef CONFIG_SMP
|
||||
int r, ipi_irq;
|
||||
static int ipi_dummy_dev;
|
||||
|
@ -111,7 +110,13 @@ void __init init_IRQ(void)
|
|||
clear_csr_estat(ESTATF_IP);
|
||||
|
||||
init_vec_parent_group();
|
||||
irqchip_init();
|
||||
if (efi_bp && bpi_version <= BPI_VERSION_V1) {
|
||||
ret = setup_legacy_IRQ();
|
||||
if (ret)
|
||||
panic("IRQ domain init error!\n");
|
||||
} else {
|
||||
irqchip_init();
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
ipi_irq = get_ipi_irq();
|
||||
if (ipi_irq < 0)
|
||||
|
|
|
@ -0,0 +1,468 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Author: Yun Liu, liuyun@loongson.cn
|
||||
* Copyright (C) 2020 Loongson Technology Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/loongson.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
#define MAX_CORE_PIC 256
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
#define MSI_MSG_ADDRESS 0x2FF00000
|
||||
#define MSI_MSG_DEFAULT_COUNT 0xC0
|
||||
|
||||
struct boot_params *efi_bp;
|
||||
struct loongsonlist_mem_map *g_mmap;
|
||||
struct acpi_madt_lio_pic *acpi_liointc;
|
||||
struct acpi_madt_eio_pic *acpi_eiointc[MAX_IO_PICS];
|
||||
|
||||
struct acpi_madt_ht_pic *acpi_htintc;
|
||||
struct acpi_madt_lpc_pic *acpi_pchlpc;
|
||||
struct acpi_madt_msi_pic *acpi_pchmsi[MAX_IO_PICS];
|
||||
struct acpi_madt_bio_pic *acpi_pchpic[MAX_IO_PICS];
|
||||
|
||||
struct irq_domain *cpu_domain;
|
||||
struct irq_domain *liointc_domain;
|
||||
struct irq_domain *pch_lpc_domain;
|
||||
struct irq_domain *pch_msi_domain[MAX_IO_PICS];
|
||||
struct irq_domain *pch_pic_domain[MAX_IO_PICS];
|
||||
|
||||
char arcs_cmdline[COMMAND_LINE_SIZE];
|
||||
int nr_io_pics;
|
||||
int bpi_version;
|
||||
|
||||
struct acpi_madt_lio_pic liointc_default = {
|
||||
.address = LOONGSON_REG_BASE + 0x1400,
|
||||
.size = 256,
|
||||
.cascade = {2, 3},
|
||||
.cascade_map = {0x00FFFFFF, 0xff000000},
|
||||
};
|
||||
|
||||
struct acpi_madt_lpc_pic pchlpc_default = {
|
||||
.address = LS7A_LPC_REG_BASE,
|
||||
.size = SZ_4K,
|
||||
.cascade = 19,
|
||||
};
|
||||
|
||||
struct acpi_madt_eio_pic eiointc_default[MAX_IO_PICS];
|
||||
struct acpi_madt_msi_pic pchmsi_default[MAX_IO_PICS];
|
||||
struct acpi_madt_bio_pic pchpic_default[MAX_IO_PICS];
|
||||
|
||||
static int
|
||||
acpi_parse_lapic(union acpi_subtable_headers *header, const unsigned long end)
|
||||
{
|
||||
struct acpi_madt_local_apic *processor = NULL;
|
||||
|
||||
processor = (struct acpi_madt_local_apic *)header;
|
||||
if (BAD_MADT_ENTRY(processor, end))
|
||||
return -EINVAL;
|
||||
|
||||
acpi_table_print_madt_entry(&header->common);
|
||||
set_processor_mask(processor->id, processor->lapic_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bad_pch_pic(unsigned long address)
|
||||
{
|
||||
if (nr_io_pics >= MAX_IO_PICS) {
|
||||
pr_warn("WARNING: Max # of I/O PCH_PICs (%d) exceeded (found %d), skipping\n",
|
||||
MAX_IO_PICS, nr_io_pics);
|
||||
return 1;
|
||||
}
|
||||
if (!address) {
|
||||
pr_warn("WARNING: Bogus (zero) I/O PCH_PIC address found in table, skipping!\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void register_default_pic(int id, u32 address, u32 irq_base)
|
||||
{
|
||||
int idx, entries;
|
||||
unsigned long addr;
|
||||
|
||||
if (bad_pch_pic(address))
|
||||
return;
|
||||
|
||||
idx = nr_io_pics;
|
||||
|
||||
pchpic_default[idx].address = address;
|
||||
if (idx)
|
||||
pchpic_default[idx].address |= nid_to_addrbase(id) | HT1LO_OFFSET;
|
||||
pchpic_default[idx].id = id;
|
||||
pchpic_default[idx].version = 0;
|
||||
pchpic_default[idx].size = 0x1000;
|
||||
pchpic_default[idx].gsi_base = irq_base;
|
||||
|
||||
msi_group[nr_io_pics].pci_segment = nr_io_pics;
|
||||
pch_group[nr_io_pics].node = msi_group[nr_io_pics].node = id;
|
||||
|
||||
addr = pchpic_default[idx].address;
|
||||
/* Read INT_ID.int_num */
|
||||
entries = (((unsigned long)ls7a_readq(addr) >> 48) & 0xff) + 1;
|
||||
pchmsi_default[idx].msg_address = MSI_MSG_ADDRESS;
|
||||
pchmsi_default[idx].start = entries;
|
||||
pchmsi_default[idx].count = MSI_MSG_DEFAULT_COUNT;
|
||||
|
||||
eiointc_default[idx].cascade = 3;
|
||||
eiointc_default[idx].node = id;
|
||||
eiointc_default[idx].node_map = 1;
|
||||
|
||||
if (idx) {
|
||||
eiointc_default[idx].cascade = 0x4;
|
||||
eiointc_default[0].node_map = 0x1DF;
|
||||
eiointc_default[idx].node_map = 0xFE20;
|
||||
}
|
||||
|
||||
acpi_pchpic[idx] = &pchpic_default[idx];
|
||||
acpi_pchmsi[idx] = &pchmsi_default[idx];
|
||||
acpi_eiointc[idx] = &eiointc_default[idx];
|
||||
|
||||
nr_io_pics++;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_parse_legacy_pch_pic(union acpi_subtable_headers *header, const unsigned long end)
|
||||
{
|
||||
struct acpi_madt_io_apic *pch_pic = NULL;
|
||||
|
||||
pch_pic = (struct acpi_madt_io_apic *)header;
|
||||
|
||||
if (BAD_MADT_ENTRY(pch_pic, end))
|
||||
return -EINVAL;
|
||||
|
||||
acpi_table_print_madt_entry(&header->common);
|
||||
|
||||
register_default_pic(pch_pic->id, pch_pic->address,
|
||||
pch_pic->global_irq_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__init int legacy_madt_table_init(void)
|
||||
{
|
||||
/* Parse MADT LAPIC entries */
|
||||
acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_parse_lapic, MAX_CORE_PIC);
|
||||
acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_legacy_pch_pic, MAX_IO_PICS);
|
||||
|
||||
acpi_liointc = &liointc_default;
|
||||
acpi_pchlpc = &pchlpc_default;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setup_legacy_IRQ(void)
|
||||
{
|
||||
int i, ret;
|
||||
struct irq_domain *pic_domain;
|
||||
|
||||
if (!acpi_eiointc[0])
|
||||
cpu_data[0].options &= ~LOONGARCH_CPU_EXTIOI;
|
||||
|
||||
ret = cpuintc_acpi_init(NULL, 0);
|
||||
if (ret) {
|
||||
pr_err("CPU domain init error!\n");
|
||||
return -1;
|
||||
}
|
||||
cpu_domain = get_cpudomain();
|
||||
ret = liointc_acpi_init(cpu_domain, acpi_liointc);
|
||||
if (ret) {
|
||||
pr_err("Liointc domain init error!\n");
|
||||
return -1;
|
||||
}
|
||||
liointc_domain = irq_find_matching_fwnode(liointc_handle, DOMAIN_BUS_ANY);
|
||||
if (cpu_has_extioi) {
|
||||
pr_info("Using EIOINTC interrupt mode\n");
|
||||
for (i = 0; i < nr_io_pics; i++) {
|
||||
ret = eiointc_acpi_init(cpu_domain, acpi_eiointc[i]);
|
||||
if (ret) {
|
||||
pr_err("Eiointc domain init error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pch_pic_parse_madt((union acpi_subtable_headers *)acpi_pchpic[i], 0);
|
||||
pch_msi_parse_madt((union acpi_subtable_headers *)acpi_pchmsi[i], 0);
|
||||
}
|
||||
/* HTVECINTC maybe not use */
|
||||
} else {
|
||||
pr_info("Using HTVECINTC interrupt mode\n");
|
||||
ret = htvec_acpi_init(liointc_domain, acpi_htintc);
|
||||
if (ret) {
|
||||
pr_err("HTVECintc domain init error!\n");
|
||||
return -1;
|
||||
}
|
||||
pch_pic_parse_madt((union acpi_subtable_headers *)acpi_pchpic[0], 0);
|
||||
pch_msi_parse_madt((union acpi_subtable_headers *)acpi_pchmsi[0], 0);
|
||||
}
|
||||
|
||||
pic_domain = get_pchpic_irq_domain();
|
||||
if (pic_domain)
|
||||
pch_lpc_acpi_init(pic_domain, acpi_pchlpc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage initrd
|
||||
*/
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
static __init int rd_start_early(char *p)
|
||||
{
|
||||
phys_initrd_start = __pa(memparse(p, NULL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("rd_start", rd_start_early);
|
||||
|
||||
static __init int rd_size_early(char *p)
|
||||
{
|
||||
phys_initrd_size = memparse(p, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("rd_size", rd_size_early);
|
||||
|
||||
#endif
|
||||
|
||||
__init void fw_init_cmdline(unsigned long argc, unsigned long cmdp)
|
||||
{
|
||||
int i;
|
||||
char **_fw_argv;
|
||||
|
||||
_fw_argv = (char **)cmdp;
|
||||
|
||||
arcs_cmdline[0] = '\0';
|
||||
for (i = 1; i < argc; i++) {
|
||||
strlcat(arcs_cmdline, _fw_argv[i], COMMAND_LINE_SIZE);
|
||||
if (i < (argc - 1))
|
||||
strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
|
||||
}
|
||||
strscpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
|
||||
}
|
||||
|
||||
static u8 ext_listhdr_checksum(u8 *buffer, u32 length)
|
||||
{
|
||||
u8 sum = 0;
|
||||
u8 *end = buffer + length;
|
||||
|
||||
while (buffer < end)
|
||||
sum = (u8)(sum + *(buffer++));
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int parse_mem(struct _extention_list_hdr *head)
|
||||
{
|
||||
g_mmap = (struct loongsonlist_mem_map *)head;
|
||||
if (ext_listhdr_checksum((u8 *)g_mmap, head->length)) {
|
||||
pr_err("mem checksum error\n");
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* legacy firmware passed, add use this info if need vbios */
|
||||
static int parse_vbios(struct _extention_list_hdr *head)
|
||||
{
|
||||
struct loongsonlist_vbios *pvbios;
|
||||
|
||||
pvbios = (struct loongsonlist_vbios *)head;
|
||||
|
||||
if (ext_listhdr_checksum((u8 *)pvbios, head->length)) {
|
||||
pr_err("vbios_addr checksum error\n");
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* legacy firmware passed, add use this info if need screeninfo KVM? */
|
||||
static int parse_screeninfo(struct _extention_list_hdr *head)
|
||||
{
|
||||
struct loongsonlist_screeninfo *pscreeninfo;
|
||||
|
||||
pscreeninfo = (struct loongsonlist_screeninfo *)head;
|
||||
if (ext_listhdr_checksum((u8 *)pscreeninfo, head->length)) {
|
||||
pr_err("screeninfo_addr checksum error\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
memcpy(&screen_info, &pscreeninfo->si, sizeof(screen_info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int list_find(struct boot_params *bp)
|
||||
{
|
||||
struct _extention_list_hdr *fhead = NULL;
|
||||
unsigned long index;
|
||||
|
||||
fhead = bp->extlist;
|
||||
if (!fhead) {
|
||||
pr_err("the bp ext struct empty!\n");
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
if (memcmp(&(fhead->signature), LOONGSON_MEM_SIGNATURE, 3) == 0) {
|
||||
if (parse_mem(fhead) != 0) {
|
||||
pr_err("parse mem failed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
} else if (memcmp(&(fhead->signature), LOONGSON_VBIOS_SIGNATURE, 5) == 0) {
|
||||
if (parse_vbios(fhead) != 0) {
|
||||
pr_err("parse vbios failed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
} else if (memcmp(&(fhead->signature), LOONGSON_SCREENINFO_SIGNATURE, 5) == 0) {
|
||||
if (parse_screeninfo(fhead) != 0) {
|
||||
pr_err("parse screeninfo failed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
fhead = (struct _extention_list_hdr *)fhead->next;
|
||||
index = (unsigned long)fhead;
|
||||
} while (index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int bpi_init(void)
|
||||
{
|
||||
return list_find(efi_bp);
|
||||
}
|
||||
|
||||
static int get_bpi_version(u64 *signature)
|
||||
{
|
||||
u8 data[9];
|
||||
int version = BPI_VERSION_NONE;
|
||||
|
||||
data[8] = 0;
|
||||
|
||||
memcpy(data, signature, sizeof(*signature));
|
||||
if (kstrtoint(&data[3], 10, &version))
|
||||
return BPI_VERSION_NONE;
|
||||
return version;
|
||||
}
|
||||
|
||||
static void __init parse_bpi_flags(void)
|
||||
{
|
||||
if (efi_bp->flags & BPI_FLAGS_UEFI_SUPPORTED)
|
||||
set_bit(EFI_BOOT, &efi.flags);
|
||||
else
|
||||
clear_bit(EFI_BOOT, &efi.flags);
|
||||
}
|
||||
|
||||
__init unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr, unsigned long bpi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!bpi || argc < 2)
|
||||
return -1;
|
||||
efi_bp = (struct boot_params *)bpi;
|
||||
bpi_version = get_bpi_version(&efi_bp->signature);
|
||||
pr_info("BPI%d with boot flags %llx.\n", bpi_version, efi_bp->flags);
|
||||
if (bpi_version == BPI_VERSION_NONE)
|
||||
panic("Fatal error, bpi ver BONE!\n");
|
||||
else if (bpi_version == BPI_VERSION_V2)
|
||||
parse_bpi_flags();
|
||||
|
||||
fw_init_cmdline(argc, cmdptr);
|
||||
ret = bpi_init();
|
||||
if (ret) {
|
||||
pr_err("init legacy firmware error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, unsigned long isa_base)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long vaddr;
|
||||
struct logic_pio_hwaddr *range;
|
||||
|
||||
range = kzalloc(sizeof(*range), GFP_ATOMIC);
|
||||
if (!range)
|
||||
return -ENOMEM;
|
||||
|
||||
range->fwnode = fwnode;
|
||||
range->size = ISA_IOSIZE;
|
||||
range->hw_start = isa_base;
|
||||
range->flags = LOGIC_PIO_CPU_MMIO;
|
||||
|
||||
ret = logic_pio_register_range(range);
|
||||
if (ret) {
|
||||
kfree(range);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (range->io_start != 0) {
|
||||
logic_pio_unregister_range(range);
|
||||
kfree(range);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
|
||||
ret = ioremap_page_range(vaddr, vaddr + range->size, range->hw_start,
|
||||
pgprot_device(PAGE_KERNEL));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct fwnode_handle * __init parse_isa_base(u64 *cpu_addr)
|
||||
{
|
||||
struct device_node *np;
|
||||
const __be32 *ranges = NULL;
|
||||
int len;
|
||||
struct device_node *node;
|
||||
|
||||
for_each_node_by_name(np, "isa") {
|
||||
node = of_node_get(np);
|
||||
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
ranges = of_get_property(node, "ranges", &len);
|
||||
|
||||
if (!ranges || (ranges && len > 0))
|
||||
break;
|
||||
}
|
||||
if (ranges) {
|
||||
ranges += 2;
|
||||
*cpu_addr = of_translate_address(np, ranges);
|
||||
return &np->fwnode;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init register_legacy_isa_io(void)
|
||||
{
|
||||
struct fwnode_handle *fwnode;
|
||||
u64 cpu_addr;
|
||||
|
||||
if (!acpi_disabled) {
|
||||
cpu_addr = ISA_PHY_IOBASE;
|
||||
fwnode = kzalloc(sizeof(*fwnode), GFP_ATOMIC);
|
||||
} else {
|
||||
fwnode = parse_isa_base(&cpu_addr);
|
||||
}
|
||||
|
||||
if (fwnode)
|
||||
add_legacy_isa_io(fwnode, cpu_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(register_legacy_isa_io);
|
|
@ -0,0 +1,90 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LEGACY_BOOT_H_
|
||||
#define __LEGACY_BOOT_H_
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/of_address.h>
|
||||
#define ADDRESS_TYPE_SYSRAM 1
|
||||
#define ADDRESS_TYPE_RESERVED 2
|
||||
#define ADDRESS_TYPE_ACPI 3
|
||||
#define ADDRESS_TYPE_NVS 4
|
||||
#define ADDRESS_TYPE_PMEM 5
|
||||
|
||||
#define LOONGSON3_BOOT_MEM_MAP_MAX 128
|
||||
#define RT_MAP_START 100
|
||||
#define FIX_MAP_ENTRY 32
|
||||
|
||||
/* mask of the flags in bootparamsinterface */
|
||||
#define BPI_FLAGS_UEFI_SUPPORTED BIT(0)
|
||||
#define BPI_FLAGS_SOC_CPU BIT(1)
|
||||
|
||||
#define LOONGSON_DMA_MASK_BIT 64
|
||||
#define LOONGSON_MEM_SIGNATURE "MEM"
|
||||
#define LOONGSON_VBIOS_SIGNATURE "VBIOS"
|
||||
#define LOONGSON_EFIBOOT_SIGNATURE "BPI"
|
||||
#define LOONGSON_SCREENINFO_SIGNATURE "SINFO"
|
||||
#define LOONGSON_EFIBOOT_VERSION 1000
|
||||
|
||||
/* Values for Version firmware */
|
||||
|
||||
enum bpi_vers {
|
||||
BPI_VERSION_NONE = 0,
|
||||
BPI_VERSION_V1 = 1000,
|
||||
BPI_VERSION_V2 = 1001,
|
||||
};
|
||||
|
||||
struct boot_params {
|
||||
u64 signature; /* {"BPIXXXXX"} */
|
||||
void *systemtable;
|
||||
struct _extention_list_hdr *extlist;
|
||||
u64 flags;
|
||||
} __packed;
|
||||
|
||||
struct _extention_list_hdr {
|
||||
u64 signature;
|
||||
u32 length;
|
||||
u8 revision;
|
||||
u8 checksum;
|
||||
struct _extention_list_hdr *next;
|
||||
} __packed;
|
||||
|
||||
struct loongsonlist_mem_map {
|
||||
struct _extention_list_hdr header; /*{"M", "E", "M"}*/
|
||||
u8 map_count;
|
||||
struct _loongson_mem_map {
|
||||
u32 mem_type;
|
||||
u64 mem_start;
|
||||
u64 mem_size;
|
||||
} __packed map[LOONGSON3_BOOT_MEM_MAP_MAX];
|
||||
} __packed;
|
||||
|
||||
struct loongsonlist_vbios {
|
||||
struct _extention_list_hdr header; /* {VBIOS} */
|
||||
u64 vbios_addr;
|
||||
} __packed;
|
||||
|
||||
struct loongsonlist_screeninfo {
|
||||
struct _extention_list_hdr header;
|
||||
struct screen_info si;
|
||||
};
|
||||
unsigned long legacy_boot_init(unsigned long argc,
|
||||
unsigned long cmdptr, unsigned long bpi);
|
||||
extern int bpi_version;
|
||||
extern struct boot_params *efi_bp;
|
||||
extern struct loongsonlist_mem_map *g_mmap;
|
||||
extern int set_processor_mask(u32 id, u32 flags);
|
||||
extern int __init setup_legacy_IRQ(void);
|
||||
extern struct loongson_system_configuration loongson_sysconf;
|
||||
extern unsigned long long smp_group[MAX_PACKAGES];
|
||||
extern int legacy_madt_table_init(void);
|
||||
extern struct pch_pic *pch_pic_priv[MAX_IO_PICS];
|
||||
extern struct irq_domain *get_cpudomain(void);
|
||||
extern int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
|
||||
const unsigned long end);
|
||||
extern int __init
|
||||
pch_pic_parse_madt(union acpi_subtable_headers *header,
|
||||
const unsigned long end);
|
||||
extern int __init
|
||||
pch_msi_parse_madt(union acpi_subtable_headers *header,
|
||||
const unsigned long end);
|
||||
extern struct irq_domain *get_pchpic_irq_domain(void);
|
||||
#endif
|
|
@ -9,13 +9,36 @@
|
|||
#include <asm/bootinfo.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#include "legacy_boot.h"
|
||||
void __init memblock_init(void)
|
||||
{
|
||||
u32 mem_type;
|
||||
u32 i, mem_type;
|
||||
u64 mem_start, mem_end, mem_size;
|
||||
efi_memory_desc_t *md;
|
||||
if (g_mmap) {
|
||||
/* parse memory information */
|
||||
for (i = 0; i < g_mmap->map_count; i++) {
|
||||
mem_type = g_mmap->map[i].mem_type;
|
||||
mem_start = g_mmap->map[i].mem_start;
|
||||
mem_size = g_mmap->map[i].mem_size;
|
||||
mem_end = mem_start + mem_size;
|
||||
|
||||
switch (mem_type) {
|
||||
case ADDRESS_TYPE_SYSRAM:
|
||||
pr_info("add memory region memblock - base: 0x%llx size: 0x%llx\n",
|
||||
mem_start, mem_size);
|
||||
memblock_add(mem_start, mem_size);
|
||||
if (max_low_pfn < (mem_end >> PAGE_SHIFT))
|
||||
max_low_pfn = mem_end >> PAGE_SHIFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||
|
||||
memblock_reserve(__pa_symbol(&_text),
|
||||
__pa_symbol(&_end) - __pa_symbol(&_text));
|
||||
return;
|
||||
}
|
||||
/* Parse memory information */
|
||||
for_each_efi_memory_desc(md) {
|
||||
mem_type = md->type;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <asm/pgalloc.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/time.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
int numa_off;
|
||||
struct pglist_data *node_data[MAX_NUMNODES];
|
||||
|
@ -37,7 +38,6 @@ static struct numa_meminfo numa_meminfo;
|
|||
cpumask_t cpus_on_node[MAX_NUMNODES];
|
||||
cpumask_t phys_cpus_on_node[MAX_NUMNODES];
|
||||
EXPORT_SYMBOL(cpus_on_node);
|
||||
|
||||
/*
|
||||
* apicid, cpu, node mappings
|
||||
*/
|
||||
|
@ -301,10 +301,45 @@ static void __init add_numamem_region(u64 start, u64 end, u32 type)
|
|||
|
||||
static void __init init_node_memblock(void)
|
||||
{
|
||||
u32 mem_type;
|
||||
u32 i, mem_type;
|
||||
u64 mem_end, mem_start, mem_size;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
if (g_mmap) {
|
||||
for (i = 0; i < g_mmap->map_count; i++) {
|
||||
mem_type = g_mmap->map[i].mem_type;
|
||||
mem_start = g_mmap->map[i].mem_start;
|
||||
mem_size = g_mmap->map[i].mem_size;
|
||||
mem_end = g_mmap->map[i].mem_start + mem_size;
|
||||
|
||||
switch (mem_type) {
|
||||
case ADDRESS_TYPE_SYSRAM:
|
||||
mem_start = PFN_ALIGN(mem_start);
|
||||
mem_end = PFN_ALIGN(mem_end - PAGE_SIZE + 1);
|
||||
if (mem_start >= mem_end)
|
||||
break;
|
||||
add_numamem_region(mem_start, mem_end, EFI_PERSISTENT_MEMORY);
|
||||
break;
|
||||
|
||||
case ADDRESS_TYPE_ACPI:
|
||||
mem_start = PFN_ALIGN(mem_start - PAGE_SIZE + 1);
|
||||
mem_end = PFN_ALIGN(mem_end);
|
||||
mem_size = mem_end - mem_start;
|
||||
memblock_add(mem_start, mem_size);
|
||||
memblock_mark_nomap(mem_start, mem_size);
|
||||
memblock_set_node(mem_start, mem_size,
|
||||
&memblock.memory, 0);
|
||||
memblock_reserve(mem_start, mem_size);
|
||||
break;
|
||||
|
||||
case ADDRESS_TYPE_RESERVED:
|
||||
memblock_reserve(mem_start, mem_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse memory information and activate */
|
||||
for_each_efi_memory_desc(md) {
|
||||
mem_type = md->type;
|
||||
|
|
|
@ -49,7 +49,8 @@ void machine_power_off(void)
|
|||
#endif
|
||||
do_kernel_power_off();
|
||||
#ifdef CONFIG_EFI
|
||||
efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
|
||||
if (efi.reset_system)
|
||||
efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <asm/sections.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/time.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
#define SMBIOS_BIOSSIZE_OFFSET 0x09
|
||||
#define SMBIOS_BIOSEXTERN_OFFSET 0x13
|
||||
|
@ -134,9 +135,23 @@ static void __init parse_cpu_table(const struct dmi_header *dm)
|
|||
|
||||
static void __init parse_bios_table(const struct dmi_header *dm)
|
||||
{
|
||||
int bios_extern;
|
||||
char *dmi_data = (char *)dm;
|
||||
|
||||
bios_extern = *(dmi_data + SMBIOS_BIOSEXTERN_OFFSET);
|
||||
b_info.bios_size = (*(dmi_data + SMBIOS_BIOSSIZE_OFFSET) + 1) << 6;
|
||||
|
||||
if (bpi_version == BPI_VERSION_V2) {
|
||||
if ((!!(efi_bp->flags & BPI_FLAGS_UEFI_SUPPORTED))
|
||||
!= (!!(bios_extern & LOONGSON_EFI_ENABLE)))
|
||||
pr_err("There is a conflict of definitions between efi_bp->flags and smbios\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bios_extern & LOONGSON_EFI_ENABLE)
|
||||
set_bit(EFI_BOOT, &efi.flags);
|
||||
else
|
||||
clear_bit(EFI_BOOT, &efi.flags);
|
||||
}
|
||||
|
||||
static void __init find_tokens(const struct dmi_header *dm, void *dummy)
|
||||
|
@ -614,7 +629,9 @@ void __init setup_arch(char **cmdline_p)
|
|||
pagetable_init();
|
||||
bootcmdline_init(cmdline_p);
|
||||
parse_early_param();
|
||||
reserve_initrd_mem();
|
||||
/* The small fdt method should be skipped directly to avoid two reserved operations. */
|
||||
if (fw_arg2)
|
||||
reserve_initrd_mem();
|
||||
|
||||
platform_init();
|
||||
arch_mem_init(cmdline_p);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/time.h>
|
||||
#include "legacy_boot.h"
|
||||
|
||||
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
|
||||
EXPORT_SYMBOL(__cpu_number_map);
|
||||
|
@ -310,11 +311,12 @@ void __init loongson_prepare_cpus(unsigned int max_cpus)
|
|||
*/
|
||||
void loongson_boot_secondary(int cpu, struct task_struct *idle)
|
||||
{
|
||||
unsigned long entry;
|
||||
unsigned long entry = (unsigned long)&smpboot_entry;
|
||||
|
||||
pr_info("Booting CPU#%d...\n", cpu);
|
||||
|
||||
entry = __pa_symbol((unsigned long)&smpboot_entry);
|
||||
if (!efi_bp)
|
||||
entry = __pa_symbol((unsigned long)&smpboot_entry);
|
||||
cpuboot_data.stack = (unsigned long)__KSTK_TOS(idle);
|
||||
cpuboot_data.thread_info = (unsigned long)task_thread_info(idle);
|
||||
|
||||
|
|
|
@ -58,13 +58,159 @@ static void acpi_release_root_info(struct acpi_pci_root_info *ci)
|
|||
kfree(info);
|
||||
}
|
||||
|
||||
static void arch_pci_root_validate_resources(struct device *dev,
|
||||
struct list_head *resources,
|
||||
unsigned long type)
|
||||
{
|
||||
LIST_HEAD(list);
|
||||
struct resource *res1, *res2, *root = NULL;
|
||||
struct resource_entry *tmp, *entry, *entry2;
|
||||
|
||||
WARN_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
|
||||
root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
|
||||
|
||||
list_splice_init(resources, &list);
|
||||
resource_list_for_each_entry_safe(entry, tmp, &list) {
|
||||
bool free = false;
|
||||
resource_size_t end;
|
||||
|
||||
res1 = entry->res;
|
||||
if (!(res1->flags & type))
|
||||
goto next;
|
||||
|
||||
/* Exclude non-addressable range or non-addressable portion */
|
||||
end = min(res1->end, root->end);
|
||||
if (end <= res1->start) {
|
||||
dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
|
||||
res1);
|
||||
free = true;
|
||||
goto next;
|
||||
} else if (res1->end != end) {
|
||||
dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
|
||||
res1, (unsigned long long)end + 1,
|
||||
(unsigned long long)res1->end);
|
||||
res1->end = end;
|
||||
}
|
||||
|
||||
resource_list_for_each_entry(entry2, resources) {
|
||||
res2 = entry2->res;
|
||||
if (!(res2->flags & type))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* I don't like throwing away windows because then
|
||||
* our resources no longer match the ACPI _CRS, but
|
||||
* the kernel resource tree doesn't allow overlaps.
|
||||
*/
|
||||
if (resource_overlaps(res1, res2)) {
|
||||
res2->start = min(res1->start, res2->start);
|
||||
res2->end = max(res1->end, res2->end);
|
||||
dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
|
||||
res2, res1);
|
||||
free = true;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
resource_list_del(entry);
|
||||
if (free)
|
||||
resource_list_free_entry(entry);
|
||||
else
|
||||
resource_list_add_tail(entry, resources);
|
||||
}
|
||||
}
|
||||
static void arch_pci_root_remap_iospace(struct fwnode_handle *fwnode,
|
||||
struct resource_entry *entry)
|
||||
{
|
||||
struct resource *res = entry->res;
|
||||
resource_size_t cpu_addr = res->start;
|
||||
resource_size_t pci_addr = cpu_addr - entry->offset;
|
||||
resource_size_t length = resource_size(res);
|
||||
unsigned long port;
|
||||
|
||||
if (pci_register_io_range(fwnode, cpu_addr, length)) {
|
||||
res->start += ISA_IOSIZE;
|
||||
cpu_addr = res->start;
|
||||
pci_addr = cpu_addr - entry->offset;
|
||||
length = resource_size(res);
|
||||
if (pci_register_io_range(fwnode, cpu_addr, length))
|
||||
goto err;
|
||||
}
|
||||
|
||||
port = pci_address_to_pio(cpu_addr);
|
||||
if (port == (unsigned long)-1)
|
||||
goto err;
|
||||
|
||||
res->start = port;
|
||||
res->end = port + length - 1;
|
||||
entry->offset = port - pci_addr;
|
||||
|
||||
if (pci_remap_iospace(res, cpu_addr) < 0)
|
||||
goto err;
|
||||
|
||||
pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res);
|
||||
return;
|
||||
err:
|
||||
res->flags |= IORESOURCE_DISABLED;
|
||||
}
|
||||
|
||||
static int arch_pci_probe_root_resources(struct acpi_pci_root_info *info)
|
||||
{
|
||||
int ret;
|
||||
struct list_head *list = &info->resources;
|
||||
struct acpi_device *device = info->bridge;
|
||||
struct resource_entry *entry, *tmp;
|
||||
unsigned long flags;
|
||||
struct resource *res;
|
||||
|
||||
flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
|
||||
ret = acpi_dev_get_resources(device, list,
|
||||
acpi_dev_filter_resource_type_cb,
|
||||
(void *)flags);
|
||||
if (ret < 0)
|
||||
dev_warn(&device->dev,
|
||||
"failed to parse _CRS method, error code %d\n", ret);
|
||||
else if (ret == 0)
|
||||
dev_dbg(&device->dev,
|
||||
"no IO and memory resources present in _CRS\n");
|
||||
else {
|
||||
resource_list_for_each_entry_safe(entry, tmp, list) {
|
||||
if (entry->res->flags & IORESOURCE_IO) {
|
||||
res = entry->res;
|
||||
res->start = PFN_ALIGN(res->start);
|
||||
res->end += 1;
|
||||
res->end = PFN_ALIGN(res->end);
|
||||
res->end -= 1;
|
||||
if (!entry->offset) {
|
||||
entry->offset = LOONGSON_LIO_BASE;
|
||||
res->start |= LOONGSON_LIO_BASE;
|
||||
res->end |= LOONGSON_LIO_BASE;
|
||||
}
|
||||
arch_pci_root_remap_iospace(&device->fwnode,
|
||||
entry);
|
||||
}
|
||||
if (entry->res->flags & IORESOURCE_DISABLED)
|
||||
resource_list_destroy_entry(entry);
|
||||
else
|
||||
entry->res->name = info->name;
|
||||
}
|
||||
arch_pci_root_validate_resources(&device->dev, list,
|
||||
IORESOURCE_MEM);
|
||||
arch_pci_root_validate_resources(&device->dev, list,
|
||||
IORESOURCE_IO);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci)
|
||||
{
|
||||
int status;
|
||||
struct resource_entry *entry, *tmp;
|
||||
struct acpi_device *device = ci->bridge;
|
||||
|
||||
status = acpi_pci_probe_root_resources(ci);
|
||||
status = arch_pci_probe_root_resources(ci);
|
||||
if (status > 0) {
|
||||
resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
|
||||
if (entry->res->flags & IORESOURCE_MEM) {
|
||||
|
|
|
@ -37,6 +37,7 @@ obj-$(CONFIG_ARM) += $(arm-obj-y)
|
|||
obj-$(CONFIG_ARM64) += $(arm-obj-y)
|
||||
riscv-obj-$(CONFIG_EFI) := efi-init.o riscv-runtime.o
|
||||
obj-$(CONFIG_RISCV) += $(riscv-obj-y)
|
||||
#obj-$(CONFIG_LOONGARCH) += efi-init.o
|
||||
obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o
|
||||
obj-$(CONFIG_EFI_EARLYCON) += earlycon.o
|
||||
obj-$(CONFIG_UEFI_CPER_ARM) += cper-arm.o
|
||||
|
|
|
@ -141,7 +141,12 @@ static int __init acpi_cascade_irqdomain_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
|
||||
struct irq_domain *get_cpudomain(void)
|
||||
{
|
||||
return irq_domain;
|
||||
}
|
||||
|
||||
int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
|
||||
const unsigned long end)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -328,7 +328,7 @@ static struct syscore_ops eiointc_syscore_ops = {
|
|||
.resume = eiointc_resume,
|
||||
};
|
||||
|
||||
static int __init pch_pic_parse_madt(union acpi_subtable_headers *header,
|
||||
int __init pch_pic_parse_madt(union acpi_subtable_headers *header,
|
||||
const unsigned long end)
|
||||
{
|
||||
struct acpi_madt_bio_pic *pchpic_entry = (struct acpi_madt_bio_pic *)header;
|
||||
|
@ -341,7 +341,7 @@ static int __init pch_pic_parse_madt(union acpi_subtable_headers *header,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init pch_msi_parse_madt(union acpi_subtable_headers *header,
|
||||
int __init pch_msi_parse_madt(union acpi_subtable_headers *header,
|
||||
const unsigned long end)
|
||||
{
|
||||
struct irq_domain *parent;
|
||||
|
|
|
@ -52,6 +52,11 @@ static struct pch_pic *pch_pic_priv[MAX_IO_PICS];
|
|||
|
||||
struct fwnode_handle *pch_pic_handle[MAX_IO_PICS];
|
||||
|
||||
struct irq_domain *get_pchpic_irq_domain(void)
|
||||
{
|
||||
return pch_pic_priv[0]->pic_domain;
|
||||
}
|
||||
|
||||
static void pch_pic_bitset(struct pch_pic *priv, int offset, int bit)
|
||||
{
|
||||
u32 reg;
|
||||
|
|
Loading…
Reference in New Issue