# CONFIG_PCH_PHUB is not set
# CONFIG_WL127X_RFKILL is not set
# CONFIG_APANIC is not set
+CONFIG_SCU_LOGGING=y
+CONFIG_UUID=y
CONFIG_A1026=y
CONFIG_EMMC_IPANIC=y
# CONFIG_C2PORT is not set
Driver which handles kernel panics and attempts to write
critical debugging data to EMMC.
+config SCU_LOGGING
+ tristate "Intel SCU fabric debug driver"
+ default n
+ ---help---
+ Driver that enable for debugging Intel SCU firmware fabric related error.
+
+config UUID
+ tristate "get uuid"
+ default n
+ ---help---
+ Driver for get UUID.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
# Makefile for misc devices that really don't fit anywhere else.
#
+intel_fabric_logging-objs := intel_fw_logging.o intel_fabricerr_status.o
obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
obj-$(CONFIG_A1026) += a1026.o
obj-$(CONFIG_MID_I2S_DEV) += mid_i2s_dev/
obj-$(CONFIG_EMMC_IPANIC) += emmc_ipanic.o
+obj-$(CONFIG_SCU_LOGGING) += intel_fabric_logging.o
+obj-$(CONFIG_UUID) += uuid.o
--- /dev/null
+/*
+ * drivers/misc/intel_fabricerr_status.c
+ *
+ * Copyright (C) 2011 Intel Corp
+ * Author: winson.w.yung@intel.com
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/types.h>
+
+#include "intel_fabricid_def.h"
+
+static char *FullChip_FlagStatusLow32[] = {
+ "cdmi_iocp (IA Burst Timeout)", /* bit 0 */
+ "cha_iahb (IA Burst Timeout)", /* bit 1 */
+ "nand_iaxi (IA Burst Timeout)", /* bit 2 */
+ "otg_iahb (IA Burst Timeout)", /* bit 3 */
+ "usb_iahb (IA Burst Timeout)", /* bit 4 */
+ "usc0a_iahb (IA Burst Timeout)", /* bit 5 */
+ "usc0b_iahb (IA Burst Timeout)", /* bit 6 */
+ "usc2_iahb (IA Burst Timeout)", /* bit 7 */
+ "tra0_iocp (IA Burst Timeout)", /* bit 8 */
+ "", /* bit 9 */
+ "", /* bit 10 */
+ "", /* bit 11 */
+ "", /* bit 12 */
+ "", /* bit 13 */
+ "", /* bit 14 */
+ "", /* bit 15 */
+ "cdmi_iocp (IA Resp Timeout)", /* bit 16 */
+ "cha_iahb (IA Resp Timeout)", /* bit 17 */
+ "nand_iaxi (IA Resp Timeout)", /* bit 18 */
+ "otg_iahb (IA Resp Timeout)", /* bit 19 */
+ "usb_iahb (IA Resp Timeout)", /* bit 20 */
+ "usc0a_iahb (IA Resp Timeout)", /* bit 21 */
+ "usc0b_iahb (IA Resp Timeout)", /* bit 22 */
+ "usc2_iahb (IA Resp Timeout)", /* bit 23 */
+ "tra0_iocp (IA Resp Timeout)", /* bit 24 */
+ "", /* bit 25 */
+ "", /* bit 26 */
+ "", /* bit 27 */
+ "", /* bit 28 */
+ "", /* bit 29 */
+ "", /* bit 30 */
+ "" /* bit 31 */
+};
+
+static char *FullChip_FlagStatusHi32[] = {
+ "cdmi_iocp (IA Inband Error)", /* bit 32 */
+ "cha_iahb (IA Inband Error)", /* bit 33 */
+ "nand_iaxi (IA Inband Error)", /* bit 34 */
+ "otg_iahb (IA Inband Error)", /* bit 35 */
+ "usb_iahb (IA Inband Error)", /* bit 36 */
+ "usc0a_iahb (IA Inband Error)", /* bit 37 */
+ "usc0b_iahb (IA Inband Error)", /* bit 38 */
+ "usc2_iahb (IA Inband Error)", /* bit 39 */
+ "tra0_iocp (IA Inband Error)", /* bit 40 */
+ "", /* bit 41 */
+ "", /* bit 42 */
+ "", /* bit 43 */
+ "", /* bit 44 */
+ "", /* bit 45 */
+ "", /* bit 46 */
+ "", /* bit 47 */
+ "cdmi_tocp (TA Req Timeout)", /* bit 48 */
+ "cha_tahb (TA Req Timeout)", /* bit 49 */
+ "nand_taxi (TA Req Timeout)", /* bit 50 */
+ "nandreg_taxi (TA Req Timeout)", /* bit 51 */
+ "otg_tahb (TA Req Timeout)", /* bit 52 */
+ "usb_tahb (TA Req Timeout)", /* bit 53 */
+ "usc0a_tahb (TA Req Timeout)", /* bit 54 */
+ "usc0b_tahb (TA Req Timeout)", /* bit 55 */
+ "usc2_tahb (TA Req Timeout)", /* bit 56 */
+ "pti_tocp (TA Req Timeout)", /* bit 57 */
+ "tra0_tocp (TA Req Timeout)", /* bit 58 */
+ "", /* bit 59 */
+ "", /* bit 60 */
+ "", /* bit 61 */
+ "", /* bit 62 */
+ "" /* bit 63 */
+};
+
+static char *Secondary_FlagStatusLow32[] = {
+ "usc1a_iahb (IA Burst Timeout)", /* bit 0 */
+ "usc1b_iahb (IA Burst Timeout)", /* bit 1 */
+ "hsidma_iahb (IA Burst Timeout)", /* bit 2 */
+ "tra1_iocp (IA Burst Timeout)", /* bit 3 */
+ "dfx_iahb (IA Burst Timeout)", /* bit 4 */
+ "", /* bit 5 */
+ "", /* bit 6 */
+ "", /* bit 7 */
+ "", /* bit 8 */
+ "", /* bit 9 */
+ "", /* bit 10 */
+ "", /* bit 11 */
+ "", /* bit 12 */
+ "", /* bit 13 */
+ "", /* bit 14 */
+ "", /* bit 15 */
+ "usc1a_iahb (IA Resp Timeout)", /* bit 16 */
+ "usc1b_iahb (IA Resp Timeout)", /* bit 17 */
+ "hsidma_iahb (IA Resp Timeout)", /* bit 18 */
+ "tra1_iocp (IA Resp Timeout)", /* bit 19 */
+ "dfx_iahb (IA Resp Timeout)", /* bit 20 */
+ "", /* bit 21 */
+ "", /* bit 22 */
+ "", /* bit 23 */
+ "", /* bit 24 */
+ "", /* bit 25 */
+ "", /* bit 26 */
+ "", /* bit 27 */
+ "", /* bit 28 */
+ "", /* bit 29 */
+ "", /* bit 30 */
+ "" /* bit 31 */
+};
+
+static char *Secondary_FlagStatusHi32[] = {
+ "usc1a_iahb (IA Inband Error)", /* bit 32 */
+ "usc1b_iahb (IA Inband Error)", /* bit 33 */
+ "hsidma_iahb (IA Inband Error)", /* bit 34 */
+ "tra1_iocp (IA Inband Error)", /* bit 35 */
+ "dfx_iahb (IA Inband Error)", /* bit 36 */
+ "", /* bit 37 */
+ "", /* bit 38 */
+ "", /* bit 39 */
+ "", /* bit 40 */
+ "", /* bit 41 */
+ "", /* bit 42 */
+ "", /* bit 43 */
+ "", /* bit 44 */
+ "", /* bit 45 */
+ "", /* bit 46 */
+ "", /* bit 47 */
+ "usc1a_tahb (TA Req Timeout)", /* bit 48 */
+ "usc1b_tahb (TA Req Timeout)", /* bit 49 */
+ "hsi_tocp (TA Req Timeout)", /* bit 50 */
+ "hsidma_tahb (TA Req Timeout)", /* bit 51 */
+ "sram_tocp (TA Req Timeout)", /* bit 52 */
+ "tra1_tocp (TA Req Timeout)", /* bit 53 */
+ "i2c3ssc_tocp (TA Req Timeout)", /* bit 54 */
+ "", /* bit 55 */
+ "", /* bit 56 */
+ "", /* bit 57 */
+ "", /* bit 58 */
+ "", /* bit 59 */
+ "", /* bit 60 */
+ "", /* bit 61 */
+ "", /* bit 62 */
+ "" /* bit 63 */
+};
+
+static char *Audio_FlagStatusLow32[] = {
+ "aes_iahb (IA Burst Timeout)", /* bit 0 */
+ "adma_iahb (IA Burst Timeout)", /* bit 1 */
+ "adma2_iahb (IA Burst Timeout)", /* bit 2 */
+ "", /* bit 3 */
+ "", /* bit 4 */
+ "", /* bit 5 */
+ "", /* bit 6 */
+ "", /* bit 7 */
+ "", /* bit 8 */
+ "", /* bit 9 */
+ "", /* bit 10 */
+ "", /* bit 11 */
+ "", /* bit 12 */
+ "", /* bit 13 */
+ "", /* bit 14 */
+ "", /* bit 15 */
+ "aes_iahb (IA Resp Timeout)", /* bit 16 */
+ "adma_iahb (IA Resp Timeout)", /* bit 17 */
+ "adma2_iahb (IA Resp Timeout)", /* bit 18 */
+ "", /* bit 19 */
+ "", /* bit 20 */
+ "", /* bit 21 */
+ "", /* bit 22 */
+ "", /* bit 23 */
+ "", /* bit 24 */
+ "", /* bit 25 */
+ "", /* bit 26 */
+ "", /* bit 27 */
+ "", /* bit 28 */
+ "", /* bit 29 */
+ "", /* bit 30 */
+ "" /* bit 31 */
+};
+
+static char *Audio_FlagStatusHi32[] = {
+ "aes_iahb (IA Inband Error)", /* bit 32 */
+ "adma_iahb (IA Inband Error)", /* bit 33 */
+ "adma2_iahb (IA Inband Error)", /* bit 34 */
+ "", /* bit 35 */
+ "", /* bit 36 */
+ "", /* bit 37 */
+ "", /* bit 38 */
+ "", /* bit 39 */
+ "", /* bit 40 */
+ "", /* bit 41 */
+ "", /* bit 42 */
+ "", /* bit 43 */
+ "", /* bit 44 */
+ "", /* bit 44 */
+ "", /* bit 45 */
+ "", /* bit 46 */
+ "", /* bit 47 */
+ "aes_tahb (TA Req Timeout)", /* bit 48 */
+ "adma_tahb (TA Req Timeout)", /* bit 49 */
+ "adram2_tocp (TA Req Timeout)", /* bit 50 */
+ "adram_tocp (TA Req Timeout)", /* bit 51 */
+ "airam_tocp (TA Req Timeout)", /* bit 52 */
+ "assp1_1_tapb (TA Req Timeout)", /* bit 53 */
+ "assp2_2_tahb (TA Req Timeout)", /* bit 54 */
+ "adma2_tahb (TA Req Timeout)", /* bit 55 */
+ "slim0_iocp (TA Req Timeout)", /* bit 56 */
+ "slim1_iocp (TA Req Timeout)", /* bit 57 */
+ "slim2_iocp (TA Req Timeout)", /* bit 58 */
+ "", /* bit 59 */
+ "", /* bit 60 */
+ "", /* bit 61 */
+ "", /* bit 62 */
+ "" /* bit 63 */
+};
+
+static char *GP_FlagStatusLow32[] = {
+ "gpdma_iahb (IA Burst Timeout)", /* bit 0 */
+ "", /* bit 1 */
+ "", /* bit 2 */
+ "", /* bit 3 */
+ "", /* bit 4 */
+ "", /* bit 5 */
+ "", /* bit 6 */
+ "", /* bit 7 */
+ "", /* bit 8 */
+ "", /* bit 9 */
+ "", /* bit 10 */
+ "", /* bit 11 */
+ "", /* bit 12 */
+ "", /* bit 13 */
+ "", /* bit 14 */
+ "", /* bit 15 */
+ "gpdma_iahb (IA Resp Timeout)", /* bit 16 */
+ "", /* bit 17 */
+ "", /* bit 18 */
+ "", /* bit 19 */
+ "", /* bit 20 */
+ "", /* bit 21 */
+ "", /* bit 22 */
+ "", /* bit 23 */
+ "", /* bit 24 */
+ "", /* bit 25 */
+ "", /* bit 26 */
+ "", /* bit 27 */
+ "", /* bit 28 */
+ "", /* bit 29 */
+ "", /* bit 30 */
+ "" /* bit 31 */
+};
+
+static char *GP_FlagStatusHi32[] = {
+ "gpdma_iahb (IA Inband Error)", /* bit 32 */
+ "", /* bit 33 */
+ "", /* bit 34 */
+ "", /* bit 35 */
+ "", /* bit 36 */
+ "", /* bit 37 */
+ "", /* bit 38 */
+ "", /* bit 39 */
+ "", /* bit 40 */
+ "", /* bit 41 */
+ "", /* bit 42 */
+ "", /* bit 43 */
+ "", /* bit 44 */
+ "", /* bit 45 */
+ "", /* bit 46 */
+ "", /* bit 47 */
+ "gpio1_tocp (TA Req Timeout)", /* bit 48 */
+ "i2c0_tocp (TA Req Timeout)", /* bit 49 */
+ "i2c1_tocp (TA Req Timeout)", /* bit 50 */
+ "i2c2_tocp (TA Req Timeout)", /* bit 51 */
+ "i2c3hdmi_tocp (TA Req Timeout)", /* bit 52 */
+ "i2c4_tocp (TA Req Timeout)", /* bit 53 */
+ "i2c5_tocp (TA Req Timeout)", /* bit 54 */
+ "spi1_tocp (TA Req Timeout)", /* bit 55 */
+ "spi2_tocp (TA Req Timeout)", /* bit 56 */
+ "spi3_tocp (TA Req Timeout)", /* bit 57 */
+ "gpdma_tahb (TA Req Timeout)", /* bit 58 */
+ "i2c3scc_tocp (TA Req Timeout)", /* bit 59 */
+ "", /* bit 60 */
+ "", /* bit 61 */
+ "", /* bit 62 */
+ "" /* bit 63 */
+};
+
+static char *SC_FlagStatusLow32[] = {
+ "MFlag0 (Audio)", /* bit 0 */
+ "MFlag1 (Secondary)", /* bit 1 */
+ "MFlag2 (FullChip)", /* bit 2 */
+ "MFlag3 (GP)", /* bit 3 */
+ "", /* bit 4 */
+ "", /* bit 5 */
+ "", /* bit 6 */
+ "", /* bit 7 */
+ "arc_iocp (IA Burst Timeout)", /* bit 8 */
+ "scdma_iocp (IA Burst Timeout)", /* bit 9 */
+ "uart_iocp (IA Burst Timeout)", /* bit 10 */
+ "", /* bit 11 */
+ "", /* bit 12 */
+ "", /* bit 13 */
+ "", /* bit 14 */
+ "", /* bit 15 */
+ "arc_iocp (IA Resp Timeout)", /* bit 16 */
+ "scdma_iocp (IA Resp Timeout)", /* bit 17 */
+ "uart_iocp (IA Resp Timeout)", /* bit 18 */
+ "", /* bit 19 */
+ "", /* bit 20 */
+ "", /* bit 21 */
+ "", /* bit 22 */
+ "", /* bit 23 */
+ "arc_iocp (IA Inband Error)", /* bit 24 */
+ "scdma_iocp (IA Inband Error)", /* bit 25 */
+ "uart_iocp (IA Inband Error)", /* bit 26 */
+ "", /* bit 27 */
+ "", /* bit 28 */
+ "", /* bit 29 */
+ "", /* bit 30 */
+ "" /* bit 31 */
+};
+
+static char *SC_FlagStatusHi32[] = {
+ "", /* bit 32 */
+ "", /* bit 33 */
+ "", /* bit 34 */
+ "", /* bit 35 */
+ "", /* bit 36 */
+ "", /* bit 37 */
+ "", /* bit 38 */
+ "", /* bit 39 */
+ "", /* bit 40 */
+ "", /* bit 41 */
+ "", /* bit 42 */
+ "", /* bit 43 */
+ "", /* bit 44 */
+ "", /* bit 45 */
+ "", /* bit 46 */
+ "", /* bit 47 */
+ "gpio_tocp (TA Req Timeout)", /* bit 48 */
+ "uart_tocp (TA Req Timeout)", /* bit 49 */
+ "ipc1_tocp (TA Req Timeout)", /* bit 50 */
+ "ipc2_tocp (TA Req Timeout)", /* bit 51 */
+ "kbd_tocp (TA Req Timeout)", /* bit 52 */
+ "pmu_tocp (TA Req Timeout)", /* bit 53 */
+ "scdma_tocp (TA Req Timeout)", /* bit 54 */
+ "spi0_tocp (TA Req Timeout)", /* bit 55 */
+ "tim_ocp (TA Req Timeout)", /* bit 56 */
+ "vrtc_tocp (TA Req Timeout)", /* bit 57 */
+ "arcs_tocp (TA Req Timeout)", /* bit 58 */
+ "", /* bit 59 */
+ "", /* bit 60 */
+ "", /* bit 61 */
+ "", /* bit 62 */
+ "" /* bit 63 */
+};
+
+char *fabric_error_lookup(u32 fab_id, u32 error_index, int use_hidword)
+{
+ if (error_index > 31) /* Out of range of 32bit */
+ return NULL;
+
+ switch (fab_id) {
+ case FAB_ID_FULLCHIP:
+ return use_hidword ? FullChip_FlagStatusHi32[error_index] :
+ FullChip_FlagStatusLow32[error_index];
+
+ case FAB_ID_SECONDARY:
+ return use_hidword ? Secondary_FlagStatusHi32[error_index] :
+ Secondary_FlagStatusLow32[error_index];
+
+ case FAB_ID_AUDIO:
+ return use_hidword ? Audio_FlagStatusHi32[error_index] :
+ Audio_FlagStatusLow32[error_index];
+
+ case FAB_ID_GP:
+ return use_hidword ? GP_FlagStatusHi32[error_index] :
+ GP_FlagStatusLow32[error_index];
+
+ case FAB_ID_SC:
+ return use_hidword ? SC_FlagStatusHi32[error_index] :
+ SC_FlagStatusLow32[error_index];
+
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * drivers/misc/intel_fabricid_def.h
+ *
+ * Copyright (C) 2011 Intel Corp
+ * Author: winson.w.yung@intel.com
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef __INTEL_FABRICID_DEF_H
+#define __INTEL_FABRICID_DEF_H
+
+#define FAB_ID_FULLCHIP 0
+#define FAB_ID_AUDIO 1
+#define FAB_ID_SECONDARY 2
+#define FAB_ID_GP 3
+#define FAB_ID_SC 4
+#define FAB_ID_UNKNOWN 5
+
+char *fabric_error_lookup(u32 fab_id, u32 error_index, int use_hidword);
+
+#endif /* __INTEL_FABRICID_DEF_H */
--- /dev/null
+/*
+ * drivers/misc/intel_fw_logging.c
+ *
+ * Copyright (C) 2011 Intel Corp
+ * Author: winson.w.yung@intel.com
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/pti.h>
+
+#include <linux/io.h>
+#include <asm/intel_scu_ipc.h>
+
+#include "intel_fabricid_def.h"
+
+#define IPCMSG_GET_HOBADDR 0xE5
+#define IPCMSG_CLEAR_FABERROR 0xE3
+#define OSHOB_SIZE 120
+
+/*
+ OSHOB - OS Handoff Buffer
+
+ This buffer contains the 32-byte value that is persists across cold and warm
+ resets only, but loses context on a cold boot.
+
+ More info about OSHOB, OSNIB could be found in FAS Section 2.8.
+ We use the first byte in OSNIB to store and pass the Reboot/boot Reason.
+ The attribute of OS image is selected for Reboot/boot reason.
+*/
+
+#define OSFAB_ERR_OFFSET 0x38
+#define MAX_BUFFER_SIZE 1024
+#define FID_MSB_MAPPING 32
+#define MAX_FID_REG_LEN 32
+#define MAX_NUM_LOGDWORDS 12
+#define FABERR_INDICATOR 0x15
+#define FLAG_HILOW_MASK 8
+#define FAB_ID_MASK 7
+#define MAX_AGENT_IDX 15
+
+union error_log_dw10 {
+ struct {
+ u32 cmd:3;
+ u32 signature:5;
+ u32 initid:8;
+ u32 num_err_logs:4;
+ u32 agent_idx:4;
+ u32 err_code:4;
+ u32 reserved1:3;
+ u32 multi_err:1;
+ } fields;
+ u32 data;
+};
+
+union fabric_status_dw0 {
+ struct {
+ u32 status_has_hilo:11;
+ u32 flag_status_cnt:5;
+ u32 status_has_hilo1:12;
+ u32 regidx:4;
+ } fields;
+ u32 data;
+};
+
+union flag_status_hilo {
+ struct {
+ /* Maps to flag_status [10..0] or [42..32] */
+ u32 bits_rang0:11;
+ u32 reserved1:5;
+
+ /* Maps to flag_status [27..16] or [59..48] */
+ u32 bits_rang1:12;
+ u32 reserved:4;
+ } fields;
+ u32 data;
+};
+
+static void __iomem *oshob_base;
+static char log_buffer[MAX_BUFFER_SIZE] = {0};
+
+static char *Fabric_Names[] = {
+ "\nFull Chip Fabric [error]\n\n",
+ "\nAudio Fabric [error]\n\n",
+ "\nSecondary Chip Fabric [error]\n\n",
+ "\nGP Fabric [error]\n\n",
+ "\nSC Fabric [error]\n\n",
+ "\nUnknown Fabric [error]\n\n"
+};
+
+static char *Agent_Names[] = {
+ "FULLFAB_FLAG_STATUS",
+ "AUDIO",
+ "SECONDARY",
+ "GP",
+ "SC",
+ "CDMI_TOCP_TA",
+ "CDMI_IOCP_IA",
+ "FCSF_IOCP_IA",
+ "FCGF_IOCP_IA",
+ "AFSF_IOCP_IA",
+ "SFFC_IOCP_IA",
+ "SFAF_IOCP_IA",
+ "SFSC_IOCP_IA",
+ "GFFC_IOCP_IA",
+ "ARC_IOCP_IA",
+ "SCSF_TOCP_TA"
+};
+
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *ipanic_faberr;
+
+static int intel_fw_logging_proc_read(char *buffer, char **start, off_t offset,
+ int count, int *peof, void *data)
+{
+ if (offset > 0) {
+ /* We have finished to read, return 0 */
+ return 0;
+ } else {
+ /* Fill the buffer, return the buffer size */
+ memcpy(buffer, log_buffer, MAX_BUFFER_SIZE);
+ return MAX_BUFFER_SIZE;
+ }
+}
+#endif /* CONFIG_PROC_FS */
+
+static void __iomem *get_oshob_addr(void)
+{
+ int ret;
+ u32 oshob_base;
+ void __iomem *oshob_addr;
+
+ ret = intel_scu_ipc_command(IPCMSG_GET_HOBADDR, 0, NULL,
+ 0, &oshob_base, 1);
+
+ if (ret < 0) {
+ pr_err("ipc_read_oshob address failed!!\n");
+ return NULL;
+ }
+
+ pr_debug("OSHOB addr is 0x%x\n", oshob_base);
+ oshob_addr = ioremap_nocache(oshob_base, OSHOB_SIZE);
+
+ if (!oshob_addr) {
+ pr_err("ioremap of oshob address failed!!\n");
+ return NULL;
+ }
+
+ return oshob_addr; /* Return OSHOB base address */
+}
+
+static void get_fabric_error_cause_detail(char *buf, u32 FabId,
+ u32 *fid_status, int IsHiDword)
+{
+ int index = 0;
+ char *ptr;
+ u32 fid_mask = 1;
+
+ while (index < MAX_FID_REG_LEN) {
+
+ if ((*fid_status) & fid_mask) {
+ ptr = fabric_error_lookup(FabId, index, IsHiDword);
+
+ if (ptr != NULL && strlen(ptr)) {
+ strcat(buf, ptr);
+ strcat(buf, "\n");
+ }
+ }
+
+ index++;
+ fid_mask <<= 1;
+ }
+
+ strcat(buf, "\n");
+}
+
+static void get_additional_error(char *buf, int num_err_log,
+ u32 *faberr_dwords, int max_dw_left)
+{
+ int i = 0;
+ char temp[100], str[50];
+ union error_log_dw10 log;
+
+ strcat(buf, "\nAdditional logs associated with error(s): ");
+
+ if (num_err_log) {
+
+ while (i < num_err_log && i < max_dw_left) {
+
+ sprintf(temp, "\nerror_log: 0x%X\n",
+ *(faberr_dwords + i));
+
+ strcat(buf, temp);
+ sprintf(temp, "error_addr: 0x%X\n",
+ *(faberr_dwords + i + 1));
+
+ strcat(buf, temp);
+ log.data = *(faberr_dwords + i);
+
+ strcat(buf, "\nDecoded error log detail\n");
+ strcat(buf, "---------------------------\n\n");
+
+ if (log.fields.agent_idx > MAX_AGENT_IDX)
+ sprintf(str, "Unknown agent index (%d)\n",
+ log.fields.agent_idx);
+ else
+ sprintf(str, "%s\n",
+ Agent_Names[log.fields.agent_idx]);
+
+ sprintf(temp, "Agent Index: %s\n", str);
+ strcat(buf, temp);
+
+ sprintf(temp, "Cmd initiator ID: %d\n",
+ log.fields.initid);
+ strcat(buf, temp);
+
+ sprintf(temp, "Command: %d\n", log.fields.cmd);
+ strcat(buf, temp);
+
+ sprintf(temp, "Code: %d\n", log.fields.err_code);
+ strcat(buf, temp);
+
+ if (log.fields.multi_err)
+ strcat(buf, "\n* Multiple errors detected!\n");
+
+ i += 2; /* Skip one error_log/addr pair */
+ }
+ } else {
+ strcat(buf, "Not present\n");
+ }
+}
+
+char *get_fabric_name(u32 fabric_idx, u32 *fab_id)
+{
+ switch (fabric_idx) {
+ case 0: /* REGIDX [31..28] is x000 */
+ case 1: /* REGIDX [31..28] is x001 */
+ case 2: /* REGIDX [31..28] is x010 */
+ case 3: /* REGIDX [31..28] is x011 */
+ case 4: /* REGIDX [31..28] is x100 */
+ *fab_id = fabric_idx;
+ break;
+ default:
+ *fab_id = FAB_ID_UNKNOWN;
+ break;
+ }
+
+ return Fabric_Names[*fab_id];
+}
+
+static int create_fwerr_log(char *output_buf, void __iomem *oshob_ptr)
+{
+ char *ptr = NULL;
+ union error_log_dw10 err_log_dw10;
+ union flag_status_hilo flag_status;
+ union fabric_status_dw0 err_status_dw0;
+ u32 id, faberr_dwords[MAX_NUM_LOGDWORDS] = {0};
+ int count, num_flag_status, num_err_logs;
+ int prev_id = FAB_ID_UNKNOWN, offset = 0;
+
+ void __iomem *fabric_err_dump_offset = oshob_ptr + OSFAB_ERR_OFFSET;
+
+ for (count = 0; count < MAX_NUM_LOGDWORDS; count++) {
+ faberr_dwords[count] = readl(fabric_err_dump_offset +
+ count * sizeof(u32));
+ }
+
+ err_status_dw0.data = faberr_dwords[0];
+ err_log_dw10.data = faberr_dwords[10];
+
+ /* No fabric error if tenth DW signature field is not 10101 */
+ if (err_log_dw10.fields.signature != FABERR_INDICATOR)
+ return 0;
+
+ num_flag_status = err_status_dw0.fields.flag_status_cnt;
+ /* num_err_logs indicates num of error_log/addr pairs */
+ num_err_logs = err_log_dw10.fields.num_err_logs * 2;
+
+ sprintf(output_buf, "SCU Fabric summary:\n");
+ strcat(output_buf, "===================\n");
+
+ for (count = 0; count < num_flag_status; count++) {
+
+ err_status_dw0.data = faberr_dwords[count];
+ ptr = get_fabric_name(
+ err_status_dw0.fields.regidx & FAB_ID_MASK, &id);
+
+ /*
+ * Only print the fabric name if is unknown
+ * type, or we haven't printed out it yet.
+ */
+
+ if (prev_id != id || id == FAB_ID_UNKNOWN) {
+ strcat(output_buf, ptr);
+ prev_id = id;
+ }
+
+ flag_status.data = 0;
+ flag_status.fields.bits_rang0 =
+ err_status_dw0.fields.status_has_hilo;
+
+ flag_status.fields.bits_rang1 =
+ err_status_dw0.fields.status_has_hilo1;
+
+ /*
+ * The most significant bit in REGIDX field is set
+ * the flag_status has the high 32bit of the dword
+ * otherwise the flag_status has the low 32bit of
+ * the dword
+ */
+
+ if (err_status_dw0.fields.regidx & FLAG_HILOW_MASK)
+ get_fabric_error_cause_detail(output_buf, id,
+ &flag_status.data, 1);
+ else
+ get_fabric_error_cause_detail(output_buf, id,
+ &flag_status.data, 0);
+
+ offset++; /* Use this to track error_log/address offset */
+ }
+
+ if (offset & 1)
+ offset++; /* If offset is odd number, adjust to even offset */
+
+ get_additional_error(output_buf, num_err_logs, &faberr_dwords[offset],
+ MAX_NUM_LOGDWORDS - offset);
+ return strlen(output_buf);
+}
+
+static int __init intel_fw_logging_init(void)
+{
+ int length = 0;
+
+ oshob_base = get_oshob_addr();
+
+ if (oshob_base == NULL)
+ return -EINVAL;
+
+ length = create_fwerr_log(log_buffer, oshob_base);
+ if (length != 0) {
+
+#ifdef CONFIG_PROC_FS
+ ipanic_faberr = create_proc_entry("ipanic_fabric_err",
+ S_IFREG | S_IRUGO, NULL);
+ if (ipanic_faberr == 0) {
+ pr_err("Fail creating procfile ipanic_fabric_err\n");
+ return -ENOMEM;
+ }
+
+ ipanic_faberr->read_proc = intel_fw_logging_proc_read;
+ ipanic_faberr->write_proc = NULL;
+ ipanic_faberr->size = length;
+
+#endif /* CONFIG_PROC_FS */
+
+ /* Dump log as error to console */
+ pr_err("%s", log_buffer);
+
+ /* Clear fabric error region inside OSHOB if neccessary */
+ intel_scu_ipc_simple_command(IPCMSG_CLEAR_FABERROR, 0);
+ }
+
+ iounmap(oshob_base);
+ return 0;
+}
+
+static void __exit intel_fw_logging_exit(void)
+{
+#ifdef CONFIG_PROC_FS
+ if (ipanic_faberr)
+ remove_proc_entry("ipanic_fabric_err", NULL);
+#endif /* CONFIG_PROC_FS */
+}
+
+module_init(intel_fw_logging_init);
+module_exit(intel_fw_logging_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Utility driver for getting intel scu fw debug info");
+MODULE_AUTHOR("Winson Yung <winson.w.yung@intel.com>");
--- /dev/null
+/*
+ * drivers/misc/uuid.c
+ *
+ * Copyright (C) 2011 Intel Corp
+ * Author: jun.zhang@intel.com
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/pti.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdhci.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/card.h>
+#include <linux/genhd.h>
+#include <linux/jhash.h>
+#include <linux/io.h>
+#include <asm/intel_scu_ipc.h>
+
+#define EMMC0_ID_LENGTH 17
+static char emmc0_id[EMMC0_ID_LENGTH];
+struct proc_dir_entry *emmc0_id_entry;
+
+static int emmc0_id_read(char *buffer, char **start, off_t offset,
+ int count, int *peof, void *data)
+{
+ if (offset > 0) {
+ /* We have finished to read, return 0 */
+ return 0;
+ } else {
+ /* Fill the buffer, return the buffer size */
+ memcpy(buffer, emmc0_id, sizeof(emmc0_id)-1);
+ return sizeof(emmc0_id)-1;
+ }
+}
+
+static int mmcblk0_match(struct device *dev, void *data)
+{
+ if (strcmp(dev_name(dev), "mmcblk0") == 0)
+ return 1;
+ return 0;
+}
+
+static int get_emmc0_cid(void)
+{
+ struct device *emmc_disk;
+ /*
+ * Automation people are needing proper serial number for ADB
+ * lets derivate from the serial number of the emmc card.
+ */
+ emmc_disk = class_find_device(&block_class, NULL, NULL, mmcblk0_match);
+ if (emmc_disk) {
+ struct gendisk *disk = dev_to_disk(emmc_disk);
+ struct mmc_card *card = mmc_dev_to_card(disk->driverfs_dev);
+ if (card) {
+ snprintf(emmc0_id, sizeof(emmc0_id),
+ "Medfield%08X",
+ jhash(&card->cid, sizeof(card->cid), 0));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static int __init uuid_init(void)
+{
+
+ memset(emmc0_id, 0x00, sizeof(emmc0_id));
+ if (get_emmc0_cid()) {
+ emmc0_id_entry = create_proc_entry("emmc0_id_entry",
+ S_IFREG | S_IRUGO, NULL);
+ if (emmc0_id_entry == 0) {
+ pr_err("Fail creating procfile emmc0_id_entry\n");
+ return -ENOMEM;
+ }
+ emmc0_id_entry->read_proc = emmc0_id_read;
+ emmc0_id_entry->write_proc = NULL;
+ emmc0_id_entry->size = sizeof(emmc0_id)-1;
+ }
+ return 0;
+}
+
+static void __exit uuid_exit(void)
+{
+
+ if (emmc0_id_entry)
+ remove_proc_entry("emmc0_id_entry", NULL);
+
+}
+
+late_initcall(uuid_init);
+module_exit(uuid_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("get uuid");
+MODULE_AUTHOR("Zhang Jun<jun.zhang@intel.com>");
+