SPID: Implement Soft_Platform_ID
authorFei Yang <fei.yang@intel.com>
Tue, 27 Mar 2012 22:27:06 +0000 (15:27 -0700)
committerbuildbot <buildbot@intel.com>
Wed, 16 May 2012 09:32:59 +0000 (02:32 -0700)
BZ: 23571

Soft Platform ID is defined to enable single kernel and IFWI binary (per
SoC solution) that can be used in Over-The-Air payload delivery. Soft
Platform ID consists of 2-bytes customer ID, 2-bytes vendor ID, 2-bytes
manufacturer ID, 2-bytes platform family ID, 2-bytes product line ID, 2-bytes
hardware ID, and 10-bytes Field Replaceable Unit region. FRU is further
devided into 20 nibbles (4-bits each) to identify changeable
parts/components/devices of a specific hardware which need the attention
from FW and OS.
Only OEMB table version 4 or later supports SPID, the older versions only
populate board_id and board_fab which are deprecated by the introduction of
SPID.
D0 Penwell based products will not support SPID, kernel identifies these by
checking OEMB revision and board_id.

Change-Id: Ifc06b4b17434e41433932e0f126bb89b6d7779b2
Signed-off-by: Fei Yang <fei.yang@intel.com>
Reviewed-on: http://android.intel.com:8080/41046
Reviewed-by: Yoke, Nicholas J <nicholas.j.yoke@intel.com>
Reviewed-by: Gross, Mark <mark.gross@intel.com>
Tested-by: Ng, Cheon-woei <cheon-woei.ng@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/include/asm/intel-mid.h
arch/x86/platform/intel-mid/intel-mid.c
include/linux/sfi.h

index 0ce7463..4e18416 100644 (file)
@@ -128,7 +128,7 @@ extern int mfld_board_type(void);
     GPIO0LV5  J15   FAB_ID1  0       0        0        1        0     1    0
  */
 enum {
-       MFLD_BID_UNKNOWN = 0,
+       MFLD_BID_UNKNOWN     = 0,
        MFLD_BID_CDK         = 0x12,
        MFLD_BID_AAVA        = 0x06,
        MFLD_BID_PR2_PROTO   = 0x15,
@@ -136,7 +136,11 @@ enum {
        MFLD_BID_PR2_VOLUME  = 0x25,
        MFLD_BID_PR3         = 0x35,
        MFLD_BID_PR3_PNP     = 0x18,
-       MFLD_BID_LEX    = 0xe0000025
+       MFLD_BID_RR_DV10     = 0x25,
+       MFLD_BID_RR_DV20     = 0x15,
+       MFLD_BID_LEX   = 0xe0000025,
+       CLVT_BID_VV          = 0x08,
+       CLVT_BID_PR0         = 0x04
 };
 extern u32 mfld_board_id(void);
 
@@ -149,6 +153,265 @@ enum {
 };
 extern u32 ctp_board_id(void);
 
+#define spid_attr(_name) \
+static struct kobj_attribute _name##_attr = {  \
+       .attr   = {                             \
+               .name = __stringify(_name),     \
+               .mode = 0444,                   \
+       },                                      \
+       .show   = _name##_show,                 \
+}
+
+/* Customer_ID table */
+enum {
+       CUSTOMER_INTEL,
+       CUSTOMER_AT,
+       CUSTOMER_OR,
+       CUSTOMER_UNKNOWN
+};
+
+/* Vendor_ID table */
+enum {
+       VENDOR_INTEL,
+       VENDOR_LN,
+       VENDOR_MO,
+       VENDOR_UNKNOWN
+};
+
+/* Manufacturer_ID table for Vendor_ID == VENDOR_INTEL */
+enum {
+       MANUFACTURER_FC_FAB1,
+       MANUFACTURER_FC_FAB2,
+       MANUFACTURER_INTEL_FAB1,
+       MANUFACTURER_UNKNOWN
+};
+
+/* Platform_Family_ID table for Vendor_ID == VENDOR_INTEL */
+enum {
+       INTEL_MFLD_PHONE,
+       INTEL_MFLD_TABLET,
+       INTEL_CLVTP_PHONE,
+       INTEL_CLVT_TABLET,
+       INTEL_MRFL_PHONE,
+       INTEL_MRFL_TABLET,
+       INTEL_PLATFORM_UNKNOWN
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MFLD_PHONE */
+enum {
+       INTEL_MFLDP_BB15_PRO = 0x0000,
+       INTEL_MFLDP_BB15_ENG = 0x8000,
+       INTEL_MFLDP_BB20_PRO = 0x0001,
+       INTEL_MFLDP_BB20_ENG = 0x8001,
+       INTEL_MFLDP_OR_PRO   = 0x0002,
+       INTEL_MFLDP_OR_ENG   = 0x8002,
+       INTEL_MFLDP_AT_PRO   = 0x0003,
+       INTEL_MFLDP_AT_ENG   = 0x8003,
+       INTEL_MFLDP_LEX_PRO  = 0x0004,
+       INTEL_MFLDP_LEX_ENG  = 0x8004,
+       INTEL_MFLDP_UNKNOWN  = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MFLD_TABLET */
+enum {
+       INTEL_MFLDT_RR_PRO  = 0x0000,
+       INTEL_MFLDT_RR_ENG  = 0x8000,
+       INTEL_MFLDT_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_CLVTP_PHONE */
+enum {
+       INTEL_CLVTPP_RHB_PRO = 0x0000,
+       INTEL_CLVTPP_RHB_ENG = 0x8000,
+       INTEL_CLVTPP_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_CLVT_TABLET */
+enum {
+       INTEL_CLVTT_TBD_PRO = 0x0000,
+       INTEL_CLVTT_TBD_ENG = 0x8000,
+       INTEL_CLVTT_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MRFL_PHONE */
+enum {
+       INTEL_MRFLP_TBD_PRO = 0x0000,
+       INTEL_MRFLP_TBD_ENG = 0x8000,
+       INTEL_MRFLP_UNKNOWN = 0xFFFF
+};
+
+/* Product_Line_ID table for Platform_Family_ID == INTEL_MRFL_TABLET */
+enum {
+       INTEL_MRFLT_TBD_PRO = 0x0000,
+       INTEL_MRFLT_TBD_ENG = 0x8000,
+       INTEL_MRFLT_UNKNOWN = 0xFFFF
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB15_PRO */
+enum {
+       MFLDP_BB15_PRO_PR33, /* CRAK D1 - 1.6GHz */
+       MFLDP_BB15_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB15_ENG */
+enum {
+       MFLDP_BB15_ENG_PR20, /* CRAK C0 */
+       MFLDP_BB15_ENG_PR31, /* CRAK D0 */
+       MFLDP_BB15_ENG_PR32, /* CRAK D0 */
+       MFLDP_BB15_ENG_PR33, /* CRAK D1 - 1.6GHz */
+       MFLDP_BB15_ENG_PR34, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2 */
+       MFLDP_BB15_ENG_PR35, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2 */
+       MFLDP_BB15_ENG_PR36, /* CRAK D1 - 1.6GHz, alt eMMC, DDR2, MSIC C2 */
+       MFLDP_BB15_ENG_PR40, /* CRAK D1 - 2.0GHz */
+       MFLDP_BB15_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB20_PRO */
+enum {
+       MFLDP_BB20_PRO_TBD,
+       MFLDP_BB20_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_BB20_ENG */
+enum {
+       MFLDP_BB20_ENG_TBD,
+       MFLDP_BB20_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_OR_PRO */
+enum {
+       MFLDP_OR_PRO_NHDV30, /* CRAK D1 */
+       MFLDP_OR_PRO_NHDV31, /* CRAK D1 */
+       MFLDP_OR_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_OR_ENG */
+enum {
+       MFLDP_OR_ENG_NHDV1, /* CRAK D0 */
+       MFLDP_OR_ENG_NHDV2, /* CRAK D1 */
+       MFLDP_OR_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_AT_PRO */
+enum {
+       MFLDP_AT_PRO_LA, /* CAAK D1 */
+       MFLDP_AT_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_AT_ENG */
+enum {
+       MFLDP_AT_ENG_LA, /* CAAK D1 */
+       MFLDP_AT_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_LEX_PRO */
+enum {
+       MFLDP_LEX_PRO_TBD,
+       MFLDP_LEX_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDP_LEX_ENG */
+enum {
+       MFLDP_LEX_ENG_PR11, /* RYS/PNW 1GHz CREK D1 */
+       MFLDP_LEX_ENG_PR1M, /* RYS/PNW 1GHz CREK D1 */
+       MFLDP_LEX_ENG_PR21, /* RYS/PNW 1GHz CSEK D1 */
+       MFLDP_LEX_ENG_PR2M, /* RYS/PNW 1GHz CSEK D1 */
+       MFLDP_LEX_ENG_PR30, /* RYS/PNW 1GHz CSEK D1 */
+       MFLDP_LEX_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDT_RR_PRO */
+enum {
+       MFLDT_RR_PRO_DV21, /* CRAK D1 */
+       MFLDT_RR_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MFLDT_RR_ENG */
+enum {
+       MFLDT_RR_ENG_DV10, /* CRAK D0 */
+       MFLDT_RR_ENG_DV15, /* CRAK D0/D1 */
+       MFLDT_RR_ENG_DV20, /* CRAK D1 */
+       MFLDT_RR_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTPP_RHB_PRO */
+enum {
+       CLVTPP_RHB_PRO_DV1,
+       CLVTPP_RHB_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTPP_RHB_ENG */
+enum {
+       CLVTPP_RHB_ENG_CCVVA,  /* Clover City VV FAB A */
+       CLVTPP_RHB_ENG_CCVVB,  /* Clover City VV FAB B */
+       CLVTPP_RHB_ENG_CCVVC,  /* Clover City VV FAB C */
+       CLVTPP_RHB_ENG_CLEV,   /* Clover Lake CRB EV */
+       CLVTPP_RHB_ENG_PR01,   /* CLV A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PR02,   /* CLV A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PMPR10, /* CLV A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PVV1,   /* CLV A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PPR10,  /* CLV A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_MPR10,  /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_VVPR10, /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PR10,   /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_MPR15,  /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_VVPR15, /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PR15,   /* CLV+ A0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_MPR20,  /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_VVPR20, /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PR20,   /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_MPR30,  /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_VVPR30, /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_PR30,   /* CLV+ B0 ?FUSE CLASS? */
+       CLVTPP_RHB_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTT_TBD_PRO */
+enum {
+       CLVTT_TBD_PRO_TBD,
+       CLVTT_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_CLVTT_TBD_ENG */
+enum {
+       CLVTT_TBD_ENG_CLEVA, /* Clover Lake EV - CRB - FAB A */
+       CLVTT_TBD_ENG_CLEVB, /* Clover Lake EV - CRB - FAB B */
+       CLVTT_TBD_ENG_CLEVC, /* Clover Lake EV - CRB - FAB C */
+       CLVTT_TBD_ENG_CLEVD, /* Clover Lake EV - CRB - FAB D */
+       CLVTT_TBD_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLP_TBD_PRO */
+enum {
+       MRFLP_TBD_PRO_TBD,
+       MRFLP_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLP_TBD_ENG */
+enum {
+       MRFLP_TBD_ENG_SRVVA, /* SilverRidge VV FAB A */
+       MRFLP_TBD_ENG_SRVVB, /* SilverRidge VV FAB B */
+       MRFLP_TBD_ENG_SRVVC, /* SilverRidge VV FAB C */
+       MRFLP_TBD_ENG_SRVVD, /* SilverRidge VV FAB D */
+       MRFLP_TBD_ENG_SRSVA, /* SilverRidge VV FAB A */
+       MRFLP_TBD_ENG_SRSVB, /* SilverRidge VV FAB B */
+       MRFLP_TBD_ENG_SRSVC, /* SilverRidge VV FAB C */
+       MRFLP_TBD_ENG_SRSVD, /* SilverRidge VV FAB D */
+       MRFLP_TBD_ENG_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLT_TBD_PRO */
+enum {
+       MRFLT_TBD_PRO_TBD,
+       MRFLT_TBD_PRO_UNKNOWN
+};
+
+/* Hardware_ID table for Product_Line_ID == INTEL_MRFLT_TBD_ENG */
+enum {
+       MRFLT_TBD_ENG_TBD,
+       MRFLT_TBD_ENG_UNKNOWN
+};
+
 /*
  * Penwell uses spread spectrum clock, so the freq number is not exactly
  * the same as reported by MSR based on SDM.
index fa1c589..3ed559a 100644 (file)
@@ -73,6 +73,8 @@
 
 __cpuinitdata enum intel_mid_timer_options intel_mid_timer_options;
 
+struct kobject *spid_kobj;
+struct sfi_soft_platform_id spid;
 u32 board_id;
 static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
 static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
@@ -781,6 +783,52 @@ static int __init sfi_parse_oemb(struct sfi_table_header *table)
 
        board_id = oemb->board_id | (oemb->board_fab << 4);
 
+       /* SPID support starts from version 4, D0 Penwell based products
+        * will stay with old firmware, so we still have to use the
+        * deprecating board_id to identify these hardware */
+       if (oemb->header.rev < 4) {
+               memset(spid.fru, 0, SPID_FRU_SIZE);
+               spid.customer_id = CUSTOMER_INTEL;
+               spid.vendor_id = VENDOR_INTEL;
+               spid.manufacturer_id = MANUFACTURER_INTEL_FAB1;
+               switch (board_id) {
+               case MFLD_BID_PR3:
+                    spid.platform_family_id = INTEL_MFLD_PHONE;
+                    spid.product_line_id = INTEL_MFLDP_BB15_ENG;
+                    spid.hardware_id = MFLDP_BB15_ENG_PR31;
+                    break;
+               case MFLD_BID_RR_DV10:
+                    spid.platform_family_id = INTEL_MFLD_TABLET;
+                    spid.product_line_id = INTEL_MFLDT_RR_ENG;
+                    spid.hardware_id = MFLDT_RR_ENG_DV10;
+                    break;
+               case MFLD_BID_RR_DV20:
+                    spid.platform_family_id = INTEL_MFLD_TABLET;
+                    spid.product_line_id = INTEL_MFLDT_RR_ENG;
+                    spid.hardware_id = MFLDT_RR_ENG_DV20;
+                    break;
+               case MFLD_BID_LEX:
+                    spid.platform_family_id = INTEL_MFLD_PHONE;
+                    spid.product_line_id = INTEL_MFLDP_LEX_ENG;
+                    spid.hardware_id = MFLDP_LEX_ENG_PR11;
+                    break;
+               case CLVT_BID_VV:
+                    spid.platform_family_id = INTEL_CLVTP_PHONE;
+                    spid.product_line_id = INTEL_CLVTPP_RHB_ENG;
+                    spid.hardware_id = CLVTPP_RHB_ENG_CCVVA;
+                    break;
+               case CLVT_BID_PR0:
+                    spid.platform_family_id = INTEL_CLVTP_PHONE;
+                    spid.product_line_id = INTEL_CLVTPP_RHB_ENG;
+                    spid.hardware_id = CLVTPP_RHB_ENG_PR01;
+                    break;
+               default:
+                    memset(&spid, 0xff, sizeof(struct sfi_soft_platform_id));
+                    break;
+               }
+       } else
+               memcpy(&spid, &oemb->spid, sizeof(struct sfi_soft_platform_id));
+
        snprintf(sig, (SFI_SIGNATURE_SIZE + 1), "%s",
                oemb->header.sig);
        snprintf(oem_id, (SFI_OEM_ID_SIZE + 1), "%s",
@@ -788,18 +836,26 @@ static int __init sfi_parse_oemb(struct sfi_table_header *table)
        snprintf(oem_table_id, (SFI_OEM_TABLE_ID_SIZE + 1), "%s",
                oemb->header.oem_table_id);
        pr_info("MFLD Validation SFI OEMB Layout\n");
-       pr_info("\tOEMB signature            : %s\n"
-               "\tOEMB length               : %d\n"
-               "\tOEMB revision             : %d\n"
-               "\tOEMB checksum             : 0x%X\n"
-               "\tOEMB oem_id               : %s\n"
-               "\tOEMB oem_table_id         : %s\n"
-               "\tOEMB board_id             : 0x%02X\n"
-               "\tOEMB iafw version         : %03d.%03d\n"
-               "\tOEMB val_hooks version    : %03d.%03d\n"
-               "\tOEMB ia suppfw version    : %03d.%03d\n"
-               "\tOEMB scu runtime version  : %03d.%03d\n"
-               "\tOEMB ifwi version         : %03d.%03d\n",
+       pr_info("\tOEMB signature               : %s\n"
+               "\tOEMB length                  : %d\n"
+               "\tOEMB revision                : %d\n"
+               "\tOEMB checksum                : 0x%X\n"
+               "\tOEMB oem_id                  : %s\n"
+               "\tOEMB oem_table_id            : %s\n"
+               "\tOEMB board_id                : 0x%02X\n"
+               "\tOEMB iafw version            : %03d.%03d\n"
+               "\tOEMB val_hooks version       : %03d.%03d\n"
+               "\tOEMB ia suppfw version       : %03d.%03d\n"
+               "\tOEMB scu runtime version     : %03d.%03d\n"
+               "\tOEMB ifwi version            : %03d.%03d\n"
+               "\tOEMB spid customer id        : %04x\n"
+               "\tOEMB spid vendor id          : %04x\n"
+               "\tOEMB spid manufacturer id    : %04x\n"
+               "\tOEMB spid platform family id : %04x\n"
+               "\tOEMB spid product line id    : %04x\n"
+               "\tOEMB spid hardware id        : %04x\n"
+               "\tOEMB spid fru[4..0]          : %02x %02x %02x %02x %02x\n"
+               "\tOEMB spid fru[9..5]          : %02x %02x %02x %02x %02x\n",
                sig,
                oemb->header.len,
                oemb->header.rev,
@@ -816,10 +872,87 @@ static int __init sfi_parse_oemb(struct sfi_table_header *table)
                oemb->scu_runtime_major_version,
                oemb->scu_runtime_minor_version,
                oemb->ifwi_major_version,
-               oemb->ifwi_minor_version);
+               oemb->ifwi_minor_version,
+               spid.customer_id,
+               spid.vendor_id,
+               spid.manufacturer_id,
+               spid.platform_family_id,
+               spid.product_line_id,
+               spid.hardware_id,
+               spid.fru[4], spid.fru[3], spid.fru[2], spid.fru[1],
+               spid.fru[0], spid.fru[9], spid.fru[8], spid.fru[7],
+               spid.fru[6], spid.fru[5]);
        return 0;
 }
 
+static ssize_t customer_id_show(struct kobject *kobj,
+                               struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.customer_id);
+}
+spid_attr(customer_id);
+
+static ssize_t vendor_id_show(struct kobject *kobj, struct kobj_attribute *attr,
+                             char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.vendor_id);
+}
+spid_attr(vendor_id);
+
+static ssize_t manufacturer_id_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.manufacturer_id);
+}
+spid_attr(manufacturer_id);
+
+static ssize_t platform_family_id_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.platform_family_id);
+}
+spid_attr(platform_family_id);
+
+static ssize_t product_line_id_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.product_line_id);
+}
+spid_attr(product_line_id);
+
+static ssize_t hardware_id_show(struct kobject *kobj,
+                               struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%04x\n", spid.hardware_id);
+}
+spid_attr(hardware_id);
+
+static ssize_t fru_show(struct kobject *kobj, struct kobj_attribute *attr,
+                       char *buf)
+{
+       return sprintf(buf, "%02x\n%02x\n%02x\n%02x\n%02x\n"
+                           "%02x\n%02x\n%02x\n%02x\n%02x\n",
+                      spid.fru[0], spid.fru[1], spid.fru[2], spid.fru[3],
+                      spid.fru[4], spid.fru[5], spid.fru[6], spid.fru[7],
+                      spid.fru[8], spid.fru[9]);
+}
+spid_attr(fru);
+
+static struct attribute *spid_attrs[] = {
+       &customer_id_attr.attr,
+       &vendor_id_attr.attr,
+       &manufacturer_id_attr.attr,
+       &platform_family_id_attr.attr,
+       &product_line_id_attr.attr,
+       &hardware_id_attr.attr,
+       &fru_attr.attr,
+       NULL,
+};
+
+static struct attribute_group spid_attr_group = {
+       .attrs = spid_attrs,
+};
+
 static struct kobject *board_properties;
 
 static int __init intel_mid_board_properties(void)
@@ -847,6 +980,13 @@ static int __init intel_mid_platform_init(void)
 {
        intel_mid_board_properties();
 
+       /* create sysfs entries for soft platform id */
+       spid_kobj = kobject_create_and_add("spid", NULL);
+       if (!spid_kobj)
+               pr_err("SPID: ENOMEM for spid_kobj\n");
+       if (sysfs_create_group(spid_kobj, &spid_attr_group))
+               pr_err("SPID: failed to create /sys/spid\n");
+
        /* Get MFD Validation SFI OEMB Layout */
        sfi_table_parse(SFI_SIG_OEMB, NULL, NULL, sfi_parse_oemb);
        sfi_table_parse(SFI_SIG_OEM0, NULL, NULL, sfi_parse_oem0);
index f928c68..9fefd8d 100644 (file)
@@ -87,6 +87,8 @@
 #define SFI_GET_NUM_ENTRIES(ptable, entry_type) \
        ((ptable->header.len - sizeof(struct sfi_table_header)) / \
        (sizeof(entry_type)))
+
+#define SPID_FRU_SIZE  10
 /*
  * Table structures must be byte-packed to match the SFI specification,
  * as they are provided by the BIOS.
@@ -105,6 +107,22 @@ struct sfi_table_simple {
        u64                             pentry[1];
 } __packed;
 
+struct sfi_soft_platform_id {
+       u16 customer_id; /*Defines the final customer for the product */
+       u16 vendor_id; /* Defines who owns the final product delivery */
+       u16 manufacturer_id; /* Defines who build the hardware. This can be
+                             * different for the same product */
+       u16 platform_family_id; /* Defined by vendor and defines the family of
+                                * the product with the same root components */
+       u16 product_line_id; /* Defined by vendor and defines the name of the
+                             * product. This can be used to differentiate the
+                             * feature set for the same product family (low
+                             * cost vs full feature). */
+       u16 hardware_id; /* Defined by vendor and defines the physical hardware
+                         * component set present on the PCB/FAB */
+       u8  fru[SPID_FRU_SIZE]; /* Field Replaceabl Unit */
+} __packed;
+
 /* OEMB table */
 struct sfi_table_oemb {
        struct sfi_table_header header;
@@ -120,6 +138,7 @@ struct sfi_table_oemb {
        u8 scu_runtime_minor_version;
        u8 ifwi_major_version;
        u8 ifwi_minor_version;
+       struct sfi_soft_platform_id spid;
 } __packed;
 
 /* Comply with UEFI spec 2.1 */