Commit 6f5a4162 authored by Yong Wang's avatar Yong Wang Committed by Greg Kroah-Hartman
Browse files

staging: spectra: move all init logic into nand_pci_probe



Currently there are some driver initialization logic that
is not part of nand_pci_probe function. This will result in
that part of driver initialization code executing even on
platforms without the corresponding hardware which is always
dangerous.

Signed-off-by: default avatarChuanxiao Dong <chuanxiao.dong@intel.com>
Signed-off-by: default avatarYong Wang <yong.y.wang@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 237a1a1a
Loading
Loading
Loading
Loading
+30 −26
Original line number Diff line number Diff line
@@ -729,34 +729,16 @@ static void create_sysfs_entry(struct device *dev)
}
*/

static int GLOB_SBD_init(void)
int register_spectra_ftl()
{
	int i;

	/* Set debug output level (0~3) here. 3 is most verbose */
	printk(KERN_ALERT "Spectra: %s\n", GLOB_version);

	mutex_init(&spectra_lock);

	GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
	if (GLOB_SBD_majornum <= 0) {
		printk(KERN_ERR "Unable to get the major %d for Spectra",
		       GLOB_SBD_majornum);
		return -EBUSY;
	}

	if (PASS != GLOB_FTL_Flash_Init()) {
		printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
		       "Aborting\n");
		goto out_flash_register;
	}

	/* create_sysfs_entry(&dev->dev); */

	if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) {
		printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
		       "Aborting\n");
		goto out_flash_register;
		return -ENOMEM;
	} else {
		nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: "
			       "Num blocks=%d, pagesperblock=%d, "
@@ -775,24 +757,46 @@ static int GLOB_SBD_init(void)
	}
	printk(KERN_ALERT "Spectra: block table has been found.\n");

	GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
	if (GLOB_SBD_majornum <= 0) {
		printk(KERN_ERR "Unable to get the major %d for Spectra",
		       GLOB_SBD_majornum);
		goto out_ftl_flash_register;
	}

	for (i = 0; i < NUM_DEVICES; i++)
		if (SBD_setup_device(&nand_device[i], i) == -ENOMEM)
			goto out_ftl_flash_register;
			goto out_blk_register;

	nand_dbg_print(NAND_DBG_DEBUG,
		       "Spectra: module loaded with major number %d\n",
		       GLOB_SBD_majornum);

	return 0;
	return PASS;

out_blk_register:
	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
out_ftl_flash_register:
	GLOB_FTL_Cache_Release();
out_flash_register:
	GLOB_FTL_Flash_Release();
	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
	printk(KERN_ERR "Spectra: Module load failed.\n");

	return -ENOMEM;
	return FAIL;
}
EXPORT_SYMBOL_GPL(register_spectra_ftl);

static int GLOB_SBD_init(void)
{
	/* Set debug output level (0~3) here. 3 is most verbose */
	printk(KERN_ALERT "Spectra: %s\n", GLOB_version);

	mutex_init(&spectra_lock);

	if (PASS != GLOB_FTL_Flash_Init()) {
		printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
		       "Aborting\n");
		return -ENODEV;
	}
	return 0;
}

static void __exit GLOB_SBD_exit(void)
+1 −0
Original line number Diff line number Diff line
@@ -80,5 +80,6 @@ extern int nand_debug_level;
extern int GLOB_Calc_Used_Bits(u32 n);
extern u64 GLOB_u64_Div(u64 addr, u32 divisor);
extern u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type);
extern int register_spectra_ftl(void);

#endif /* _FFSPORT_ */
+1 −3
Original line number Diff line number Diff line
@@ -1258,9 +1258,7 @@ int GLOB_FTL_Flash_Init(void)

	g_SBDCmdIndex = 0;

	GLOB_LLD_Flash_Init();

	status = GLOB_LLD_Read_Device_ID();
	status = GLOB_LLD_Flash_Init();

	return status;
}
+95 −82
Original line number Diff line number Diff line
@@ -2395,14 +2395,94 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
	unsigned long csr_base;
	unsigned long csr_len;
	struct mrst_nand_info *pndev = &info;
	u32 int_mask;

	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE,
			GLOB_HWCTL_REG_SIZE);
	if (!FlashReg) {
		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
		return -ENOMEM;
	}
	nand_dbg_print(NAND_DBG_WARN,
		"Spectra: Remapped reg base address: "
		"0x%p, len: %d\n",
		FlashReg, GLOB_HWCTL_REG_SIZE);

	FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE,
			GLOB_HWCTL_MEM_SIZE);
	if (!FlashMem) {
		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
		iounmap(FlashReg);
		return -ENOMEM;
	}
	nand_dbg_print(NAND_DBG_WARN,
		"Spectra: Remapped flash base address: "
		"0x%p, len: %d\n",
		(void *)FlashMem, GLOB_HWCTL_MEM_SIZE);

	nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
			"acc_clks: %d, re_2_we: %d, we_2_re: %d,"
			"addr_2_data: %d, rdwr_en_lo_cnt: %d, "
			"rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
			ioread32(FlashReg + ACC_CLKS),
			ioread32(FlashReg + RE_2_WE),
			ioread32(FlashReg + WE_2_RE),
			ioread32(FlashReg + ADDR_2_DATA),
			ioread32(FlashReg + RDWR_EN_LO_CNT),
			ioread32(FlashReg + RDWR_EN_HI_CNT),
			ioread32(FlashReg + CS_SETUP_CNT));

	NAND_Flash_Reset();

	iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);

#if CMD_DMA
	info.pcmds_num = 0;
	info.flash_bank = 0;
	info.cdma_num = 0;
	int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
		DMA_INTR__DESC_COMP_CHANNEL1 |
		DMA_INTR__DESC_COMP_CHANNEL2 |
		DMA_INTR__DESC_COMP_CHANNEL3 |
		DMA_INTR__MEMCOPY_DESC_COMP);
	iowrite32(int_mask, FlashReg + DMA_INTR_EN);
	iowrite32(0xFFFF, FlashReg + DMA_INTR);

	int_mask = (INTR_STATUS0__ECC_ERR |
		INTR_STATUS0__PROGRAM_FAIL |
		INTR_STATUS0__ERASE_FAIL);
#else
	int_mask = INTR_STATUS0__DMA_CMD_COMP |
		INTR_STATUS0__ECC_TRANSACTION_DONE |
		INTR_STATUS0__ECC_ERR |
		INTR_STATUS0__PROGRAM_FAIL |
		INTR_STATUS0__ERASE_FAIL;
#endif
	iowrite32(int_mask, FlashReg + INTR_EN0);
	iowrite32(int_mask, FlashReg + INTR_EN1);
	iowrite32(int_mask, FlashReg + INTR_EN2);
	iowrite32(int_mask, FlashReg + INTR_EN3);

	/* Clear all status bits */
	iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS3);

	iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
	iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);

	/* Should set value for these registers when init */
	iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
	iowrite32(1, FlashReg + ECC_ENABLE);
	enable_ecc = 1;
	ret = pci_enable_device(dev);
	if (ret) {
		printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
		return ret;
		goto failed_req_csr;
	}

	pci_set_master(dev);
@@ -2461,12 +2541,26 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)

	pci_set_drvdata(dev, pndev);

	ret = GLOB_LLD_Read_Device_ID();
	if (ret) {
		iounmap(pndev->ioaddr);
		goto failed_remap_csr;
	}

	ret = register_spectra_ftl();
	if (ret) {
		iounmap(pndev->ioaddr);
		goto failed_remap_csr;
	}

	return 0;

failed_remap_csr:
	pci_release_regions(dev);
failed_req_csr:
	pci_disable_device(dev);
	iounmap(FlashMem);
	iounmap(FlashReg);

	return ret;
}
@@ -2498,91 +2592,10 @@ static struct pci_driver nand_pci_driver = {
int NAND_Flash_Init(void)
{
	int retval;
	u32 int_mask;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE,
			GLOB_HWCTL_REG_SIZE);
	if (!FlashReg) {
		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
		return -ENOMEM;
	}
	nand_dbg_print(NAND_DBG_WARN,
		"Spectra: Remapped reg base address: "
		"0x%p, len: %d\n",
		FlashReg, GLOB_HWCTL_REG_SIZE);

	FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE,
			GLOB_HWCTL_MEM_SIZE);
	if (!FlashMem) {
		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
		iounmap(FlashReg);
		return -ENOMEM;
	}
	nand_dbg_print(NAND_DBG_WARN,
		"Spectra: Remapped flash base address: "
		"0x%p, len: %d\n",
		(void *)FlashMem, GLOB_HWCTL_MEM_SIZE);

	nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
			"acc_clks: %d, re_2_we: %d, we_2_re: %d,"
			"addr_2_data: %d, rdwr_en_lo_cnt: %d, "
			"rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
			ioread32(FlashReg + ACC_CLKS),
			ioread32(FlashReg + RE_2_WE),
			ioread32(FlashReg + WE_2_RE),
			ioread32(FlashReg + ADDR_2_DATA),
			ioread32(FlashReg + RDWR_EN_LO_CNT),
			ioread32(FlashReg + RDWR_EN_HI_CNT),
			ioread32(FlashReg + CS_SETUP_CNT));

	NAND_Flash_Reset();

	iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);

#if CMD_DMA
	info.pcmds_num = 0;
	info.flash_bank = 0;
	info.cdma_num = 0;
	int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
		DMA_INTR__DESC_COMP_CHANNEL1 |
		DMA_INTR__DESC_COMP_CHANNEL2 |
		DMA_INTR__DESC_COMP_CHANNEL3 |
		DMA_INTR__MEMCOPY_DESC_COMP);
	iowrite32(int_mask, FlashReg + DMA_INTR_EN);
	iowrite32(0xFFFF, FlashReg + DMA_INTR);

	int_mask = (INTR_STATUS0__ECC_ERR |
		INTR_STATUS0__PROGRAM_FAIL |
		INTR_STATUS0__ERASE_FAIL);
#else
	int_mask = INTR_STATUS0__DMA_CMD_COMP |
		INTR_STATUS0__ECC_TRANSACTION_DONE |
		INTR_STATUS0__ECC_ERR |
		INTR_STATUS0__PROGRAM_FAIL |
		INTR_STATUS0__ERASE_FAIL;
#endif
	iowrite32(int_mask, FlashReg + INTR_EN0);
	iowrite32(int_mask, FlashReg + INTR_EN1);
	iowrite32(int_mask, FlashReg + INTR_EN2);
	iowrite32(int_mask, FlashReg + INTR_EN3);

	/* Clear all status bits */
	iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
	iowrite32(0xFFFF, FlashReg + INTR_STATUS3);

	iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
	iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);

	/* Should set value for these registers when init */
	iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
	iowrite32(1, FlashReg + ECC_ENABLE);
	enable_ecc = 1;

	retval = pci_register_driver(&nand_pci_driver);
	if (retval)
		return -ENOMEM;