mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-08 02:19:51 +01:00
This mainly implements detection of these devices and will allow secondary drivers to work on such machines. The identification is DMI-based with a vendor specific way to tell them apart in a reliable way. Drivers for LEDs and Watchdogs will follow to make use of that platform detection. There is also some code to allow secondary drivers to find GPIO memory, that needs to be in place because the pinctrl drivers do not come up. Signed-off-by: Henning Schild <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Hans de Goede <[email protected]>
73 lines
1.9 KiB
C
73 lines
1.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Siemens SIMATIC IPC drivers
|
|
*
|
|
* Copyright (c) Siemens AG, 2018-2021
|
|
*
|
|
* Authors:
|
|
* Henning Schild <[email protected]>
|
|
* Gerd Haeussler <[email protected]>
|
|
*/
|
|
|
|
#ifndef __PLATFORM_DATA_X86_SIMATIC_IPC_H
|
|
#define __PLATFORM_DATA_X86_SIMATIC_IPC_H
|
|
|
|
#include <linux/dmi.h>
|
|
#include <linux/platform_data/x86/simatic-ipc-base.h>
|
|
|
|
#define SIMATIC_IPC_DMI_ENTRY_OEM 129
|
|
/* binary type */
|
|
#define SIMATIC_IPC_DMI_TYPE 0xff
|
|
#define SIMATIC_IPC_DMI_GROUP 0x05
|
|
#define SIMATIC_IPC_DMI_ENTRY 0x02
|
|
#define SIMATIC_IPC_DMI_TID 0x02
|
|
|
|
enum simatic_ipc_station_ids {
|
|
SIMATIC_IPC_INVALID_STATION_ID = 0,
|
|
SIMATIC_IPC_IPC227D = 0x00000501,
|
|
SIMATIC_IPC_IPC427D = 0x00000701,
|
|
SIMATIC_IPC_IPC227E = 0x00000901,
|
|
SIMATIC_IPC_IPC277E = 0x00000902,
|
|
SIMATIC_IPC_IPC427E = 0x00000A01,
|
|
SIMATIC_IPC_IPC477E = 0x00000A02,
|
|
SIMATIC_IPC_IPC127E = 0x00000D01,
|
|
};
|
|
|
|
static inline u32 simatic_ipc_get_station_id(u8 *data, int max_len)
|
|
{
|
|
struct {
|
|
u8 type; /* type (0xff = binary) */
|
|
u8 len; /* len of data entry */
|
|
u8 group;
|
|
u8 entry;
|
|
u8 tid;
|
|
__le32 station_id; /* station id (LE) */
|
|
} __packed * data_entry = (void *)data + sizeof(struct dmi_header);
|
|
|
|
while ((u8 *)data_entry < data + max_len) {
|
|
if (data_entry->type == SIMATIC_IPC_DMI_TYPE &&
|
|
data_entry->len == sizeof(*data_entry) &&
|
|
data_entry->group == SIMATIC_IPC_DMI_GROUP &&
|
|
data_entry->entry == SIMATIC_IPC_DMI_ENTRY &&
|
|
data_entry->tid == SIMATIC_IPC_DMI_TID) {
|
|
return le32_to_cpu(data_entry->station_id);
|
|
}
|
|
data_entry = (void *)((u8 *)(data_entry) + data_entry->len);
|
|
}
|
|
|
|
return SIMATIC_IPC_INVALID_STATION_ID;
|
|
}
|
|
|
|
static inline void
|
|
simatic_ipc_find_dmi_entry_helper(const struct dmi_header *dh, void *_data)
|
|
{
|
|
u32 *id = _data;
|
|
|
|
if (dh->type != SIMATIC_IPC_DMI_ENTRY_OEM)
|
|
return;
|
|
|
|
*id = simatic_ipc_get_station_id((u8 *)dh, dh->length);
|
|
}
|
|
|
|
#endif /* __PLATFORM_DATA_X86_SIMATIC_IPC_H */
|