Commit 90e17eda authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-apei', 'acpi-prm' and 'acpi-docs'

Merge APEI, PRM and documentation udpates for 5.16-rc1:

 - Mark apei_hest_parse() static (Christoph Hellwig).

 - Relax platform response timeout to 1 second after instructing it
   to inject an error (Shuai Xue).

 - Make the PRM code handle memory allocation and remapping failures
   more gracefully and drop some unnecessary blank lines from that
   code (Aubrey Li).

 - Fix spelling mistake in the ACPI documentation (Colin Ian King).

* acpi-apei:
  ACPI: APEI: mark apei_hest_parse() static
  ACPI: APEI: EINJ: Relax platform response timeout to 1 second

* acpi-prm:
  ACPI: PRM: Handle memory allocation and memory remap failure
  ACPI: PRM: Remove unnecessary blank lines

* acpi-docs:
  Documentation: ACPI: Fix spelling mistake "Millenium" -> "Millennium"
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ The ACPI BIOS flow would include an evaluation of _OS, and the AML
interpreter in the kernel would return to it a string identifying the OS:

Windows 98, SE: "Microsoft Windows"
Windows ME: "Microsoft WindowsME:Millenium Edition"
Windows ME: "Microsoft WindowsME:Millennium Edition"
Windows NT: "Microsoft Windows NT"

The idea was on a platform tasked with running multiple OS's,
+8 −7
Original line number Diff line number Diff line
@@ -28,9 +28,10 @@
#undef pr_fmt
#define pr_fmt(fmt) "EINJ: " fmt

#define SPIN_UNIT		100			/* 100ns */
/* Firmware should respond within 1 milliseconds */
#define FIRMWARE_TIMEOUT	(1 * NSEC_PER_MSEC)
#define SLEEP_UNIT_MIN		1000			/* 1ms */
#define SLEEP_UNIT_MAX		5000			/* 5ms */
/* Firmware should respond within 1 seconds */
#define FIRMWARE_TIMEOUT	(1 * USEC_PER_SEC)
#define ACPI5_VENDOR_BIT	BIT(31)
#define MEM_ERROR_MASK		(ACPI_EINJ_MEMORY_CORRECTABLE | \
				ACPI_EINJ_MEMORY_UNCORRECTABLE | \
@@ -171,13 +172,13 @@ static int einj_get_available_error_type(u32 *type)

static int einj_timedout(u64 *t)
{
	if ((s64)*t < SPIN_UNIT) {
	if ((s64)*t < SLEEP_UNIT_MIN) {
		pr_warn(FW_WARN "Firmware does not respond in time\n");
		return 1;
	}
	*t -= SPIN_UNIT;
	ndelay(SPIN_UNIT);
	touch_nmi_watchdog();
	*t -= SLEEP_UNIT_MIN;
	usleep_range(SLEEP_UNIT_MIN, SLEEP_UNIT_MAX);

	return 0;
}

+3 −2
Original line number Diff line number Diff line
@@ -86,7 +86,9 @@ static int hest_esrc_len(struct acpi_hest_header *hest_hdr)
	return len;
};

int apei_hest_parse(apei_hest_func_t func, void *data)
typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);

static int apei_hest_parse(apei_hest_func_t func, void *data)
{
	struct acpi_hest_header *hest_hdr;
	int i, rc, len;
@@ -121,7 +123,6 @@ int apei_hest_parse(apei_hest_func_t func, void *data)

	return 0;
}
EXPORT_SYMBOL_GPL(apei_hest_parse);

/*
 * Check if firmware advertises firmware first mode. We need FF bit to be set
+26 −9
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ struct prm_context_buffer {
};
#pragma pack()


static LIST_HEAD(prm_module_list);

struct prm_handler_info {
@@ -73,7 +72,6 @@ struct prm_module_info {
	struct prm_handler_info handlers[];
};


static u64 efi_pa_va_lookup(u64 pa)
{
	efi_memory_desc_t *md;
@@ -88,7 +86,6 @@ static u64 efi_pa_va_lookup(u64 pa)
	return 0;
}


#define get_first_handler(a) ((struct acpi_prmt_handler_info *) ((char *) (a) + a->handler_info_offset))
#define get_next_handler(a) ((struct acpi_prmt_handler_info *) (sizeof(struct acpi_prmt_handler_info) + (char *) a))

@@ -99,7 +96,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
	struct acpi_prmt_handler_info *handler_info;
	struct prm_handler_info *th;
	struct prm_module_info *tm;
	u64 mmio_count = 0;
	u64 *mmio_count;
	u64 cur_handler = 0;
	u32 module_info_size = 0;
	u64 mmio_range_size = 0;
@@ -108,6 +105,8 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
	module_info = (struct acpi_prmt_module_info *) header;
	module_info_size = struct_size(tm, handlers, module_info->handler_info_count);
	tm = kmalloc(module_info_size, GFP_KERNEL);
	if (!tm)
		goto parse_prmt_out1;

	guid_copy(&tm->guid, (guid_t *) module_info->module_guid);
	tm->major_rev = module_info->major_rev;
@@ -120,14 +119,24 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
		 * Each module is associated with a list of addr
		 * ranges that it can use during the service
		 */
		mmio_count = *(u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB);
		mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count);
		mmio_count = (u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB);
		if (!mmio_count)
			goto parse_prmt_out2;

		mmio_range_size = struct_size(tm->mmio_info, addr_ranges, *mmio_count);
		tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL);
		if (!tm->mmio_info)
			goto parse_prmt_out3;

		temp_mmio = memremap(module_info->mmio_list_pointer, mmio_range_size, MEMREMAP_WB);
		if (!temp_mmio)
			goto parse_prmt_out4;
		memmove(tm->mmio_info, temp_mmio, mmio_range_size);
	} else {
		mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count);
		tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL);
		tm->mmio_info = kmalloc(sizeof(*tm->mmio_info), GFP_KERNEL);
		if (!tm->mmio_info)
			goto parse_prmt_out2;

		tm->mmio_info->mmio_count = 0;
	}

@@ -145,6 +154,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
	} while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info)));

	return 0;

parse_prmt_out4:
	kfree(tm->mmio_info);
parse_prmt_out3:
	memunmap(mmio_count);
parse_prmt_out2:
	kfree(tm);
parse_prmt_out1:
	return -ENOMEM;
}

#define GET_MODULE	0
@@ -171,7 +189,6 @@ static void *find_guid_info(const guid_t *guid, u8 mode)
	return NULL;
}


static struct prm_module_info *find_prm_module(const guid_t *guid)
{
	return (struct prm_module_info *)find_guid_info(guid, GET_MODULE);
+0 −3
Original line number Diff line number Diff line
@@ -37,9 +37,6 @@ void __init acpi_hest_init(void);
static inline void acpi_hest_init(void) { return; }
#endif

typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
int apei_hest_parse(apei_hest_func_t func, void *data);

int erst_write(const struct cper_record_header *record);
ssize_t erst_get_record_count(void);
int erst_get_record_id_begin(int *pos);