diff --git a/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c b/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c index 36796270d5bfba6c4a048e0cac9ee1d6ec168a96..d7693d9a0d354ca12d1e8652dc34455b5715a34c 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c +++ b/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c @@ -28,7 +28,7 @@ #include "hrdCommon.h" #include "hrd_sflash_driver.h" -#define SFC_DRIVER_VERSION "1.7.9.0" +#define SFC_DRIVER_VERSION "1.8.3.0" static const char *sflashMtdList[] = { "sflash", NULL }; @@ -132,9 +132,9 @@ static unsigned int flash_map_init(struct platform_device *pdev) u32 i; u32 mapsNum; struct device *dev = &pdev->dev; - struct resource *sfc_regres; - struct resource *flash_iores; - struct sfc_host *host; + struct resource *sfc_regres = NULL; + struct resource *flash_iores = NULL; + struct sfc_host *host = NULL; pr_info("SFC Driver\n"); host = devm_kzalloc(dev, sizeof(struct sfc_host), GFP_KERNEL); diff --git a/drivers/mtd/hisilicon/sfc/hrd_sflash_driver.c b/drivers/mtd/hisilicon/sfc/hrd_sflash_driver.c index 659dbe1eccc3b4dd8160d34a1e8f6b7748b297e9..2cdce1b91d9a471f83170a0f104359c4b76973a6 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sflash_driver.c +++ b/drivers/mtd/hisilicon/sfc/hrd_sflash_driver.c @@ -74,8 +74,8 @@ static int sflash_block_markbad(struct mtd_info *mtd, loff_t ofs); struct mtd_info *sflash_probe(struct map_info *map, struct resource *sfc_regres) { - struct mtd_info *mtd; - struct SFC_SFLASH_INFO *sflash; + struct mtd_info *mtd = NULL; + struct SFC_SFLASH_INFO *sflash = NULL; unsigned long flags = 0, sflash_in_irq = 0; DB_LOCAL(pr_info("[SFC] INFO: entering %s\n", __func__)); diff --git a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c index e56a8ee81b14fd0995b0ba8ec31456a6fa9e2e8f..4b68b4745220792b84b7dfdbcc5d29027e7042a8 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c +++ b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c @@ -690,6 +690,22 @@ s32 SFC_ClearInt(u64 reg_addr) return 0; } +/*Judging sfc whether something is wrong */ +static bool SFC_IsOpErr(u64 reg_addr) +{ + u32 IntStatus; + + IntStatus = SFC_RegisterRead(reg_addr + (u32) INTRAWSTATUS); + + if ((0 != (IntStatus & SFC_OP_ERR_MASK))) { + pr_err("[SFC_IsOpErr] ERROR: Int status=%x not cleared, clear\r\n", IntStatus); + SFC_RegisterWrite(reg_addr + INTCLEAR, INT_MASK); + return true; + } + + return false; +} + s32 SFC_WaitInt(u64 reg_addr) { u32 ulRegValue; @@ -947,6 +963,11 @@ s32 SFC_BlockErase(struct SFC_SFLASH_INFO *sflash, u32 ulAddr, u32 ErCmd) goto rel; } + if (SFC_IsOpErr(sflash->sfc_reg_base)) { + ulRet = HRD_ERR; + goto rel; + } + ulRet = SFC_CheckBusy(sflash, WAIT_MAX_COUNT); if (HRD_OK != ulRet) { @@ -956,7 +977,7 @@ s32 SFC_BlockErase(struct SFC_SFLASH_INFO *sflash, u32 ulAddr, u32 ErCmd) rel: SFC_FlashUnlock(sflash); - return HRD_OK; + return ulRet; } @@ -998,6 +1019,9 @@ static s32 SFC_RegWordAlignRead(struct SFC_SFLASH_INFO *sflash, return ulRet; } + if (SFC_IsOpErr(sflash->sfc_reg_base)) + return HRD_ERR; + for (i = 0; i < ulDataCnt; i++) { pulData[i] = SFC_RegisterRead(sflash->sfc_reg_base + DATABUFFER1 + (u32)(4*i)); } @@ -1036,6 +1060,9 @@ static s32 SFC_RegByteRead(struct SFC_SFLASH_INFO *sflash, return ulRet; } + if (SFC_IsOpErr(sflash->sfc_reg_base)) + return HRD_ERR; + *pucData = SFC_RegisterRead(sflash->sfc_reg_base + DATABUFFER1) & 0xff; return ulRet; @@ -1090,6 +1117,11 @@ static s32 SFC_RegWordAlignWrite(struct SFC_SFLASH_INFO *sflash, goto rel; } + if (SFC_IsOpErr(sflash->sfc_reg_base)) { + ulRet = HRD_ERR; + goto rel; + } + SFC_RegisterWrite(sflash->sfc_reg_base + CMD_INS, sflash->sflash_dev_params.ucOpcodeRDSR); @@ -1138,6 +1170,11 @@ static s32 SFC_RegByteWrite(struct SFC_SFLASH_INFO *sflash, goto rel; } + if (SFC_IsOpErr(sflash->sfc_reg_base)) { + ulRet = HRD_ERR; + goto rel; + } + SFC_RegisterWrite(sflash->sfc_reg_base + CMD_INS, sflash->sflash_dev_params.ucOpcodeRDSR); @@ -1214,6 +1251,9 @@ s32 SFC_RegModeWrite(struct SFC_SFLASH_INFO *sflash, } } + if (SFC_IsOpErr(sflash->sfc_reg_base)) + return HRD_ERR; + return HRD_OK; } @@ -1223,6 +1263,7 @@ s32 SFC_RegModeRead(struct SFC_SFLASH_INFO *sflash, u32 i; u32 ulRemain; u32 ulAlignLen; + s32 ret = HRD_OK; /* pr_info("SFC_RegModeRead call\n"); */ @@ -1242,22 +1283,22 @@ s32 SFC_RegModeRead(struct SFC_SFLASH_INFO *sflash, ulAlignLen = ulReadLen - ulRemain; for (i = 0; i < ulAlignLen; i += SFC_HARD_BUF_LEN) { - (void)SFC_RegWordAlignRead(sflash, offset + i, + ret = SFC_RegWordAlignRead(sflash, offset + i, (u32 *) (pucDest + i), SFC_HARD_BUF_LEN); } if (ulRemain >= 4) { - (void)SFC_RegWordAlignRead(sflash, offset + i, + ret = SFC_RegWordAlignRead(sflash, offset + i, (u32 *) (pucDest + i), ulRemain&(~0x3)); i += ulRemain&(~0x3); } for (; i < ulReadLen; i++) { - (void)SFC_RegByteRead(sflash, offset + i, pucDest + i); + ret = SFC_RegByteRead(sflash, offset + i, pucDest + i); } - return HRD_OK; + return ret; } s32 SFC_CheckCmdExcStatus(struct SFC_SFLASH_INFO *sflash) diff --git a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.h b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.h index 61fb4eaa96361bf8cdd8b19e0184f5a71940963e..a05f91edfb2e0b7e749e980100c222c7f4a8cec5 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.h +++ b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.h @@ -89,6 +89,8 @@ #define SPI_FLASH_DEV_SIZE 0x2000000 #define SPI_REG_END_ADDR (0x500) +#define SFC_OP_ERR_MASK (0x1EC) + /* SFC REG */ #define GLOBAL_CONFIG (0x0100) #define TIMING (0x0110)