diff options
-rw-r--r-- | arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi | 18 | ||||
-rw-r--r-- | arch/arm/mach-k3/am65x/Kconfig | 2 | ||||
-rw-r--r-- | board/siemens/iot2050/board.c | 142 | ||||
-rw-r--r-- | drivers/sysinfo/Kconfig | 7 | ||||
-rw-r--r-- | drivers/sysinfo/Makefile | 1 | ||||
-rw-r--r-- | drivers/sysinfo/iot2050.c | 202 | ||||
-rw-r--r-- | drivers/sysinfo/iot2050.h | 14 | ||||
-rw-r--r-- | drivers/sysinfo/sysinfo-uclass.c | 29 | ||||
-rw-r--r-- | include/sysinfo.h | 65 | ||||
-rw-r--r-- | lib/smbios.c | 6 |
10 files changed, 424 insertions, 62 deletions
diff --git a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi index b6d2c816acc..55337179f9f 100644 --- a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi +++ b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi @@ -14,6 +14,24 @@ spi0 = &ospi0; }; + sysinfo { + compatible = "siemens,sysinfo-iot2050"; + /* TI_SRAM_SCRATCH_BOARD_EEPROM_START */ + offset = <0x40280000>; + bootph-all; + + smbios { + system { + manufacturer = "SIEMENS AG"; + product = "SIMATIC IOT2050"; + }; + + baseboard { + manufacturer = "SIEMENS AG"; + }; + }; + }; + leds { bootph-all; status-led-red { diff --git a/arch/arm/mach-k3/am65x/Kconfig b/arch/arm/mach-k3/am65x/Kconfig index 72a8298aebf..056ae118c9e 100644 --- a/arch/arm/mach-k3/am65x/Kconfig +++ b/arch/arm/mach-k3/am65x/Kconfig @@ -35,6 +35,8 @@ config TARGET_IOT2050_A53 select BOARD_LATE_INIT select SYS_DISABLE_DCACHE_OPS select BINMAN + select SYSINFO + select SPL_SYSINFO if SPL help This builds U-Boot for the IOT2050 devices. diff --git a/board/siemens/iot2050/board.c b/board/siemens/iot2050/board.c index e6bedc38917..d827f728a08 100644 --- a/board/siemens/iot2050/board.c +++ b/board/siemens/iot2050/board.c @@ -25,28 +25,7 @@ #include <asm/gpio.h> #include <asm/io.h> -#define IOT2050_INFO_MAGIC 0x20502050 - -struct iot2050_info { - u32 magic; - u16 size; - char name[20 + 1]; - char serial[16 + 1]; - char mlfb[18 + 1]; - char uuid[32 + 1]; - char a5e[18 + 1]; - u8 mac_addr_cnt; - u8 mac_addr[8][ARP_HLEN]; - char seboot_version[40 + 1]; - u8 padding[3]; - u32 ddr_size_mb; -} __packed; - -/* - * Scratch SRAM (available before DDR RAM) contains extracted EEPROM data. - */ -#define IOT2050_INFO_DATA ((struct iot2050_info *) \ - TI_SRAM_SCRATCH_BOARD_EEPROM_START) +#include "../../../../drivers/sysinfo/iot2050.h" DECLARE_GLOBAL_DATA_PTR; @@ -117,6 +96,8 @@ static const char *m2_connector_mode_name[] = { static enum m2_connector_mode connector_mode; +static char iot2050_board_name[21]; + #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) static void *connector_overlay; static u32 connector_overlay_size; @@ -149,37 +130,57 @@ static void set_pinvalue(const char *gpio_name, const char *label, int value) dm_gpio_set_value(&gpio, value); } +static bool setup_sysinfo(struct udevice **sysinfo_ptr) +{ + if (sysinfo_get(sysinfo_ptr)) { + pr_err("Could not find sysinfo device.\n"); + return false; + } + if (sysinfo_detect(*sysinfo_ptr)) { + pr_err("Board info parsing error\n"); + return false; + } + return true; +} + +static void get_board_name(void) +{ + struct udevice *sysinfo; + + if (iot2050_board_name[0] != 0) + return; + + if (!setup_sysinfo(&sysinfo)) + return; + + sysinfo_get_str(sysinfo, BOARD_NAME, sizeof(iot2050_board_name), + iot2050_board_name); +} + static bool board_is_advanced(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - return info->magic == IOT2050_INFO_MAGIC && - strstr((char *)info->name, "IOT2050-ADVANCED") != NULL; + get_board_name(); + return strstr(iot2050_board_name, "IOT2050-ADVANCED") != NULL; } static bool board_is_pg1(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - - return info->magic == IOT2050_INFO_MAGIC && - (strcmp((char *)info->name, "IOT2050-BASIC") == 0 || - strcmp((char *)info->name, "IOT2050-ADVANCED") == 0); + get_board_name(); + return strcmp(iot2050_board_name, "IOT2050-BASIC") == 0 || + strcmp(iot2050_board_name, "IOT2050-ADVANCED") == 0; } static bool board_is_m2(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - - return info->magic == IOT2050_INFO_MAGIC && - strcmp((char *)info->name, "IOT2050-ADVANCED-M2") == 0; + get_board_name(); + return strcmp(iot2050_board_name, "IOT2050-ADVANCED-M2") == 0; } static bool board_is_sm(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - - return info->magic == IOT2050_INFO_MAGIC && - strcmp((char *)info->name, "IOT2050-ADVANCED-SM") == 0; + get_board_name(); + return strcmp(iot2050_board_name, "IOT2050-ADVANCED-SM") == 0; } static void remove_mmc1_target(void) @@ -206,33 +207,43 @@ static void enable_pcie_connector_power(void) void set_board_info_env(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - u8 __maybe_unused mac_cnt; + struct udevice *sysinfo; const char *fdtfile; + char buf[41]; - if (info->magic != IOT2050_INFO_MAGIC) { - pr_err("IOT2050: Board info parsing error!\n"); + if (env_get("board_uuid")) return; - } - if (env_get("board_uuid")) + if (!setup_sysinfo(&sysinfo)) return; - env_set("board_name", info->name); - env_set("board_serial", info->serial); - env_set("mlfb", info->mlfb); - env_set("board_uuid", info->uuid); - env_set("board_a5e", info->a5e); + if (sysinfo_get_str(sysinfo, BOARD_NAME, sizeof(buf), buf) == 0) + env_set("board_name", buf); + if (sysinfo_get_str(sysinfo, SYSID_SM_SYSTEM_SERIAL, sizeof(buf), buf) == 0) + env_set("board_serial", buf); + if (sysinfo_get_str(sysinfo, BOARD_MLFB, sizeof(buf), buf) == 0) + env_set("mlfb", buf); + if (sysinfo_get_str(sysinfo, BOARD_UUID, sizeof(buf), buf) == 0) + env_set("board_uuid", buf); + if (sysinfo_get_str(sysinfo, BOARD_A5E, sizeof(buf), buf) == 0) + env_set("board_a5e", buf); + if (sysinfo_get_str(sysinfo, BOARD_SEBOOT_VER, sizeof(buf), buf) == 0) + env_set("seboot_version", buf); env_set("fw_version", PLAIN_VERSION); - env_set("seboot_version", info->seboot_version); if (IS_ENABLED(CONFIG_NET)) { + int mac_cnt; + + mac_cnt = sysinfo_get_item_count(sysinfo, SYSID_BOARD_MAC_ADDR); /* set MAC addresses to ensure forwarding to the OS */ - for (mac_cnt = 0; mac_cnt < info->mac_addr_cnt; mac_cnt++) { - if (is_valid_ethaddr(info->mac_addr[mac_cnt])) - eth_env_set_enetaddr_by_index("eth", - mac_cnt + 1, - info->mac_addr[mac_cnt]); + for (int i = 0; i < mac_cnt; i++) { + u8 *mac = NULL; + size_t bytes = 0; + + sysinfo_get_data_by_index(sysinfo, SYSID_BOARD_MAC_ADDR, + i, (void **)&mac, &bytes); + if (bytes == ARP_HLEN && is_valid_ethaddr(mac)) + eth_env_set_enetaddr_by_index("eth", i + 1, mac); } } @@ -288,7 +299,7 @@ static void do_overlay_prepare(const char *overlay_path) return; fit_error: - pr_err("M.2 device tree overlay %s not available,\n", overlay_path); + pr_err("M.2 device tree overlay %s not available.\n", overlay_path); #endif } @@ -362,8 +373,15 @@ int board_init(void) int dram_init(void) { - struct iot2050_info *info = IOT2050_INFO_DATA; - gd->ram_size = ((phys_size_t)(info->ddr_size_mb)) << 20; + struct udevice *sysinfo; + u32 ddr_size_mb; + + if (!setup_sysinfo(&sysinfo)) + return -ENODEV; + + sysinfo_get_int(sysinfo, SYSID_BOARD_RAM_SIZE_MB, &ddr_size_mb); + + gd->ram_size = ((phys_size_t)(ddr_size_mb)) << 20; return 0; } @@ -405,18 +423,18 @@ int dram_init_banksize(void) #ifdef CONFIG_SPL_LOAD_FIT int board_fit_config_name_match(const char *name) { - struct iot2050_info *info = IOT2050_INFO_DATA; char upper_name[32]; + get_board_name(); + /* skip the prefix "ti/k3-am65x8-" */ name += 13; - if (info->magic != IOT2050_INFO_MAGIC || - strlen(name) >= sizeof(upper_name)) + if (strlen(name) >= sizeof(upper_name)) return -1; str_to_upper(name, upper_name, sizeof(upper_name)); - if (!strcmp(upper_name, (char *)info->name)) + if (!strcmp(upper_name, iot2050_board_name)) return 0; return -1; diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig index 2030e4babc9..df83df69ffb 100644 --- a/drivers/sysinfo/Kconfig +++ b/drivers/sysinfo/Kconfig @@ -31,6 +31,13 @@ config SYSINFO_RCAR3 help Support querying SoC version information for Renesas R-Car Gen3. +config SYSINFO_IOT2050 + bool "Enable sysinfo driver for the Siemens IOT2050" + depends on TARGET_IOT2050_A53 + default y if TARGET_IOT2050_A53 + help + Support querying device information for Siemens IOT2050. + config SYSINFO_SANDBOX bool "Enable sysinfo driver for the Sandbox board" help diff --git a/drivers/sysinfo/Makefile b/drivers/sysinfo/Makefile index 680dde77fe8..26ca3150999 100644 --- a/drivers/sysinfo/Makefile +++ b/drivers/sysinfo/Makefile @@ -5,6 +5,7 @@ obj-y += sysinfo-uclass.o obj-$(CONFIG_SYSINFO_GAZERBEAM) += gazerbeam.o obj-$(CONFIG_SYSINFO_GPIO) += gpio.o +obj-$(CONFIG_SYSINFO_IOT2050) += iot2050.o obj-$(CONFIG_SYSINFO_RCAR3) += rcar3.o obj-$(CONFIG_SYSINFO_SANDBOX) += sandbox.o obj-$(CONFIG_SYSINFO_SMBIOS) += smbios.o diff --git a/drivers/sysinfo/iot2050.c b/drivers/sysinfo/iot2050.c new file mode 100644 index 00000000000..579a9f4711d --- /dev/null +++ b/drivers/sysinfo/iot2050.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Siemens AG, 2025 + */ + +#include <dm.h> +#include <sysinfo.h> +#include <net.h> +#include <u-boot/uuid.h> +#include <asm/arch/hardware.h> + +#include "iot2050.h" + +#define IOT2050_INFO_MAGIC 0x20502050 + +#define IOT2050_UUID_STR_LEN (32) + +struct iot2050_info { + u32 magic; + u16 size; + char name[20 + 1]; + char serial[16 + 1]; + char mlfb[18 + 1]; + char uuid[IOT2050_UUID_STR_LEN + 1]; + char a5e[18 + 1]; + u8 mac_addr_cnt; + u8 mac_addr[8][ARP_HLEN]; + char seboot_version[40 + 1]; + u8 padding[3]; + u32 ddr_size_mb; +} __packed; + +/** + * struct sysinfo_iot2050_priv - sysinfo private data + * @info: iot2050 board info + */ +struct sysinfo_iot2050_priv { + struct iot2050_info *info; + u8 uuid_smbios[16]; +}; + +static int sysinfo_iot2050_detect(struct udevice *dev) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + if (!priv->info || priv->info->magic != IOT2050_INFO_MAGIC) + return -EFAULT; + + return 0; +} + +static int sysinfo_iot2050_get_str(struct udevice *dev, int id, size_t size, + char *val) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + switch (id) { + case BOARD_NAME: + case SYSID_SM_BASEBOARD_VERSION: + strlcpy(val, priv->info->name, size); + break; + case SYSID_SM_SYSTEM_SERIAL: + strlcpy(val, priv->info->serial, size); + break; + case BOARD_MLFB: + case SYSID_SM_SYSTEM_VERSION: + strlcpy(val, priv->info->mlfb, size); + break; + case BOARD_UUID: + strlcpy(val, priv->info->uuid, size); + break; + case BOARD_A5E: + case SYSID_SM_BASEBOARD_PRODUCT: + strlcpy(val, priv->info->a5e, size); + break; + case BOARD_SEBOOT_VER: + case SYSID_PRIOR_STAGE_VERSION: + strlcpy(val, priv->info->seboot_version, size); + break; + default: + return -EINVAL; + }; + + val[size - 1] = '\0'; + return 0; +} + +static int sysinfo_iot2050_get_int(struct udevice *dev, int id, int *val) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_BOARD_RAM_SIZE_MB: + *val = priv->info->ddr_size_mb; + return 0; + default: + return -EINVAL; + }; +} + +static int sysinfo_iot2050_get_data(struct udevice *dev, int id, void **data, + size_t *size) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_SM_SYSTEM_UUID: + *data = priv->uuid_smbios; + *size = 16; + return 0; + default: + return -EINVAL; + }; +} + +static int sysinfo_iot2050_get_item_count(struct udevice *dev, int id) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_BOARD_MAC_ADDR: + return priv->info->mac_addr_cnt; + default: + return -EINVAL; + }; +} + +static int sysinfo_iot2050_get_data_by_index(struct udevice *dev, int id, + int index, void **data, + size_t *size) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_BOARD_MAC_ADDR: + if (index >= priv->info->mac_addr_cnt) + return -EINVAL; + *data = priv->info->mac_addr[index]; + *size = ARP_HLEN; + return 0; + default: + return -EINVAL; + }; +} + +static const struct sysinfo_ops sysinfo_iot2050_ops = { + .detect = sysinfo_iot2050_detect, + .get_str = sysinfo_iot2050_get_str, + .get_int = sysinfo_iot2050_get_int, + .get_data = sysinfo_iot2050_get_data, + .get_item_count = sysinfo_iot2050_get_item_count, + .get_data_by_index = sysinfo_iot2050_get_data_by_index, +}; + +/** + * @brief Convert the IOT2050 UUID string to the SMBIOS format + * + * @param uuid_raw The IOT2050 UUID string parsed from the eeprom + * @param uuid_smbios The buffer to hold the SMBIOS formatted UUID + */ +static void sysinfo_iot2050_convert_uuid(const char *uuid_iot2050, + u8 *uuid_smbios) +{ + char uuid_rfc4122_str[IOT2050_UUID_STR_LEN + 4 + 1] = {0}; + char *tmp = uuid_rfc4122_str; + + for (int i = 0; i < 16; i++) { + memcpy(tmp, uuid_iot2050 + i * 2, 2); + tmp += 2; + if (i == 3 || i == 5 || i == 7 || i == 9) + *tmp++ = '-'; + } + uuid_str_to_bin(uuid_rfc4122_str, uuid_smbios, UUID_STR_FORMAT_GUID); +} + +static int sysinfo_iot2050_probe(struct udevice *dev) +{ + struct sysinfo_iot2050_priv *priv = dev_get_priv(dev); + unsigned long offset; + + offset = dev_read_u32_default(dev, "offset", + TI_SRAM_SCRATCH_BOARD_EEPROM_START); + priv->info = (struct iot2050_info *)offset; + + sysinfo_iot2050_convert_uuid(priv->info->uuid, priv->uuid_smbios); + + return 0; +} + +static const struct udevice_id sysinfo_iot2050_ids[] = { + { .compatible = "siemens,sysinfo-iot2050" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sysinfo_iot2050) = { + .name = "sysinfo_iot2050", + .id = UCLASS_SYSINFO, + .of_match = sysinfo_iot2050_ids, + .ops = &sysinfo_iot2050_ops, + .priv_auto = sizeof(struct sysinfo_iot2050_priv), + .probe = sysinfo_iot2050_probe, +}; diff --git a/drivers/sysinfo/iot2050.h b/drivers/sysinfo/iot2050.h new file mode 100644 index 00000000000..657221db096 --- /dev/null +++ b/drivers/sysinfo/iot2050.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Siemens AG, 2025 + */ + +#include <sysinfo.h> + +enum sysinfo_id_iot2050 { + BOARD_MLFB = SYSID_USER, + BOARD_A5E, + BOARD_NAME, + BOARD_UUID, + BOARD_SEBOOT_VER, +}; diff --git a/drivers/sysinfo/sysinfo-uclass.c b/drivers/sysinfo/sysinfo-uclass.c index 3c0cd51273e..f04998ef8bb 100644 --- a/drivers/sysinfo/sysinfo-uclass.c +++ b/drivers/sysinfo/sysinfo-uclass.c @@ -119,6 +119,35 @@ int sysinfo_get_data(struct udevice *dev, int id, void **data, size_t *size) return ops->get_data(dev, id, data, size); } +int sysinfo_get_item_count(struct udevice *dev, int id) +{ + struct sysinfo_priv *priv = dev_get_uclass_priv(dev); + struct sysinfo_ops *ops = sysinfo_get_ops(dev); + + if (!priv->detected) + return -EPERM; + + if (!ops->get_item_count) + return -ENOSYS; + + return ops->get_item_count(dev, id); +} + +int sysinfo_get_data_by_index(struct udevice *dev, int id, int index, + void **data, size_t *size) +{ + struct sysinfo_priv *priv = dev_get_uclass_priv(dev); + struct sysinfo_ops *ops = sysinfo_get_ops(dev); + + if (!priv->detected) + return -EPERM; + + if (!ops->get_data_by_index) + return -ENOSYS; + + return ops->get_data_by_index(dev, id, index, data, size); +} + UCLASS_DRIVER(sysinfo) = { .id = UCLASS_SYSINFO, .name = "sysinfo", diff --git a/include/sysinfo.h b/include/sysinfo.h index ba2ac273e8e..e87cf969fcd 100644 --- a/include/sysinfo.h +++ b/include/sysinfo.h @@ -57,6 +57,7 @@ enum sysinfo_id { SYSID_SM_SYSTEM_WAKEUP, SYSID_SM_SYSTEM_SKU, SYSID_SM_SYSTEM_FAMILY, + SYSID_SM_SYSTEM_UUID, /* Baseboard (or Module) Information (Type 2) */ SYSID_SM_BASEBOARD_MANUFACTURER, @@ -151,6 +152,8 @@ enum sysinfo_id { /* For show_board_info() */ SYSID_BOARD_MODEL, SYSID_BOARD_MANUFACTURER, + SYSID_BOARD_MAC_ADDR, + SYSID_BOARD_RAM_SIZE_MB, SYSID_PRIOR_STAGE_VERSION, SYSID_PRIOR_STAGE_DATE, @@ -221,6 +224,30 @@ struct sysinfo_ops { int (*get_data)(struct udevice *dev, int id, void **data, size_t *size); /** + * get_item_count() - Get the item count of the specific data area that + * describes the hardware setup. + * @dev: The sysinfo instance to gather the data. + * @id: A unique identifier for the data area to be get. + * + * Return: non-negative item count if OK, -ve on error. + */ + int (*get_item_count)(struct udevice *dev, int id); + + /** + * get_data_by_index() - Get a data value by index from the platform. + * + * @dev: The sysinfo instance to gather the data. + * @id: A unique identifier for the data area to be get. + * @index: The item index, starting from 0. + * @data: Pointer to the address of the data area. + * @size: Pointer to the size of the data area. + * + * Return: 0 if OK, -ve on error. + */ + int (*get_data_by_index)(struct udevice *dev, int id, int index, + void **data, size_t *size); + + /** * get_fit_loadable - Get the name of an image to load from FIT * This function can be used to provide the image names based on runtime * detection. A classic use-case would when DTBOs are used to describe @@ -304,6 +331,32 @@ int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val); int sysinfo_get_data(struct udevice *dev, int id, void **data, size_t *size); /** + * sysinfo_get_item_count() - Get the item count of the specific data area that + * describes the hardware setup. + * @dev: The sysinfo instance to gather the data. + * @id: A unique identifier for the data area to be get. + * + * Return: non-negative item count if OK, -EPERM if called before + * sysinfo_detect(), else -ve on error. + */ +int sysinfo_get_item_count(struct udevice *dev, int id); + +/** + * sysinfo_get_data_by_index() - Get a data value by index from the platform. + * + * @dev: The sysinfo instance to gather the data. + * @id: A unique identifier for the data area to be get. + * @index: The item index, starting from 0. + * @data: Pointer to the address of the data area. + * @size: Pointer to the size of the data area. + * + * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on + * error. + */ +int sysinfo_get_data_by_index(struct udevice *dev, int id, int index, + void **data, size_t *size); + +/** * sysinfo_get() - Return the sysinfo device for the sysinfo in question. * @devp: Pointer to structure to receive the sysinfo device. * @@ -364,6 +417,18 @@ static inline int sysinfo_get_data(struct udevice *dev, int id, void **data, return -ENOSYS; } +static inline int sysinfo_get_item_count(struct udevice *dev, int id) +{ + return -ENOSYS; +} + +static inline int sysinfo_get_data_by_index(struct udevice *dev, int id, + int index, void **data, + size_t *size) +{ + return -ENOSYS; +} + static inline int sysinfo_get(struct udevice **devp) { return -ENOSYS; diff --git a/lib/smbios.c b/lib/smbios.c index 78cee8c0c26..7c9701a57f9 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -429,6 +429,8 @@ static int smbios_write_type1(ulong *current, int handle, struct smbios_type1 *t; int len = sizeof(*t); char *serial_str = env_get("serial#"); + size_t uuid_len; + void *uuid; t = map_sysmem(*current, len); memset(t, 0, len); @@ -450,6 +452,10 @@ static int smbios_write_type1(ulong *current, int handle, SYSID_SM_SYSTEM_SERIAL, NULL); } + if (!sysinfo_get_data(ctx->dev, SYSID_SM_SYSTEM_UUID, &uuid, + &uuid_len) && + uuid_len == sizeof(t->uuid)) + memcpy(t->uuid, uuid, sizeof(t->uuid)); t->wakeup_type = smbios_get_val_si(ctx, "wakeup-type", SYSID_SM_SYSTEM_WAKEUP, SMBIOS_WAKEUP_TYPE_UNKNOWN); |