spi flash启动执行reboot命令无法重启

在使用spi flash时,执行reboot命令,有时会无法重启,这里追查下原因

原因

是使用了32M flash,在重启的时候,没有退出4-byte地址模式导致。(因为板子上没有PMU,没有对flash进行复位)

在 m25p_shutdown 函数中退出4-byte地址模式即可。

static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
                                    const struct flash_info *info)
{
        /* Do some manufacturer fixups first */
        switch (JEDEC_MFR(info)) {
        case SNOR_MFR_SPANSION:
                /* No small sector erase for 4-byte command set */
                nor->erase_opcode = SPINOR_OP_SE;
                nor->mtd.erasesize = info->sector_size;
                break;

        default:
                break;
        }

        nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
        nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
        nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
}

/* Enable/disable 4-byte addressing mode. */
static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
                            int enable)
{
        int status;
        bool need_wren = false;
        u8 cmd;

        switch (JEDEC_MFR(info)) {
        case SNOR_MFR_MICRON:
                /* Some Micron need WREN command; all will accept it */
                need_wren = true;
        case SNOR_MFR_MACRONIX:
        case SNOR_MFR_WINBOND:
                if (need_wren)
                        write_enable(nor);   //nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);

                cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
                status = nor->write_reg(nor, cmd, NULL, 0);
                if (need_wren)
                        write_disable(nor);

                return status;
        default:
                /* Spansion style */
                nor->cmd_buf[0] = enable << 7;
                return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1);
        }
}
struct m25p {
        struct spi_device       *spi;
        struct spi_nor          spi_nor;
        u8                      command[MAX_CMD_SIZE];
};
static int m25p_remove(struct spi_device *spi)
{
        struct m25p     *flash = spi_get_drvdata(spi);
//add to exit 4-byte address mode

        /* Clean up MTD stuff. */
        return mtd_device_unregister(&flash->spi_nor.mtd);
}

新增关机接口
static void m25p_shutdown(struct spi_device *spi)
{
        struct m25p     *flash = spi_get_drvdata(spi);
        struct spi_nor nor = flash->spi_nor;
int status;
//add to exit 4-byte address mode
nor.write_reg(&nor, SPINOR_OP_WREN, NULL, 0);
status = nor.write_reg(&nor, SPINOR_OP_EX4B, NULL, 0);
printk("remove spi flash!\n");
        /* Clean up MTD stuff. */
        mtd_device_unregister(&flash->spi_nor.mtd);
        return;
}
static struct spi_driver m25p80_driver = {
        .driver = {
                .name   = "m25p80",
                .of_match_table = m25p_of_table,
        },
        .id_table       = m25p_ids,
        .probe  = m25p_probe,
        .remove = m25p_remove,
        .shutdown = m25p_shutdown,
        /* REVISIT: many of these chips have deep power-down modes, which
        * should clearly be entered on suspend() to minimize power use.
        * And also when they're otherwise idle...
        */
};

CONFIG_SPI_FLASH_BAR

参考资料

http://www.wowotech.net/linux_kenrel/reboot.html

http://blog.csdn.net/manfeel/article/details/43530817

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值