加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

让MT7620完美支持32M SPI Flash(W25Q256) — 兼谈设备驱动中的sh

发布时间:2020-12-15 19:51:17 所属栏目:百科 来源:网络整理
导读:前言 OpenWrt的最新kernel(3.14.28)已经能够支持32M SPI Flash的读写以及擦除操作.然而,可能是系统考虑不周,亦或是MT7620系统的BUG,在配置了W25Q256的MT7620开发板系统上,无法soft reset!经过查阅相关资料,发现,MT7620默认支持24bit(3byte)的spi地址模式,而

前言

OpenWrt的最新kernel(3.14.28)已经能够支持32M SPI Flash的读写以及擦除操作.然而,可能是系统考虑不周,亦或是MT7620系统的BUG,在配置了W25Q256的MT7620开发板系统上,无法soft reset!经过查阅相关资料,发现,MT7620默认支持24bit(3byte)的spi地址模式,而要支持32M以上的spi flash,则必须切换到32bit(4byte)地址模式.在soft reset的时候,spi停留在了32bit模式,没有切换回默认的24bit模式,导致reset后,MT7620在默认的24bit模式,无法和32bit模式的spi通讯,系统死机.那么问题来了:如何在soft reset时刻,让spi flash切换回24bit模式呢?本文通过设备驱动中的一个shutdown方法来解决这个问题.


背景知识

在linux源代码kernel目录下,有一个reboot.c文件,里面暴露了一个register_reboot_notifier方法,可以让kernel中的代码有机会获得reboot的通知,当我们继续分析reboot.c的代码时,会发现更有意思的东西:

[cpp]? view plain ?copy
?print ?
  1. /**?
  2. ?*??kernel_restart?-?reboot?the?system?
  3. ?*??@cmd:?pointer?to?buffer?containing?command?to?execute?for?restart?
  4. ?*??????or?%NULL?
  5. ?*?
  6. ?*??Shutdown?everything?and?perform?a?clean?reboot.?
  7. ?*??This?is?not?safe?to?call?in?interrupt?context.?
  8. ?*/??
  9. void?kernel_restart(char?*cmd)??
  10. {??
  11. ????kernel_restart_prepare(cmd);??
  12. ????migrate_to_reboot_cpu();??
  13. ????syscore_shutdown();??
  14. ????if?(!cmd)??
  15. ????????pr_emerg("Restarting?systemn");??
  16. ????else??
  17. ????????pr_emerg("Restarting?system?with?command?'%s'n",?cmd);??
  18. ????kmsg_dump(KMSG_DUMP_RESTART);??
  19. ????machine_restart(cmd);??
  20. }??
在kernel_restart中,又调用了kernel_restart_prepare方法:

device_shutdown在drivers/base/core.c中实现:

?

  • ?????????*?prevent?it?from?being?freed?because?parent's?
  • ?????????*?lock?is?to?be?held?
  • ?????????*/??
  • ????????parent?=?get_device(dev->parent);??
  • ????????get_device(dev);??
  • ?????????????????*?Make?sure?the?device?is?off?the?kset?list,?in?the?
  • ?????????*?event?that?dev->*->shutdown()?doesn't?remove?it.?
  • ????????list_del_init(&dev->kobj.entry);??
  • ????????spin_unlock(&devices_kset->list_lock);??
  • /*?hold?lock?to?avoid?race?with?probe/release?*/??
  • ????????if?(parent)??
  • ????????????device_lock(parent);??
  • ????????device_lock(dev);??
  • ??
  • /*?Don't?allow?any?more?runtime?suspends?*/??
  • ????????pm_runtime_get_noresume(dev);??
  • ????????pm_runtime_barrier(dev);??
  • //?manfeel,?add?debug?info??
  • //dev_info(dev,"search?shutdown?method...n");??
  • ??????????
  • ????????if?(dev->bus?&&?dev->bus->shutdown)?{??
  • ????????????//if?(initcall_debug)?manfeel??
  • ????????????????dev_info(dev,?"shutdownn");??
  • ????????????dev->bus->shutdown(dev);??
  • ????????}?else?if?(dev->driver?&&?dev->driver->shutdown)?{??
  • ????????????dev->driver->shutdown(dev);??
  • ????????}??
  • ????????device_unlock(dev);??
  • ????????????device_unlock(parent);??
  • ????????put_device(dev);??
  • ????????put_device(parent);??
  • ????????spin_lock(&devices_kset->list_lock);??
  • ????}??
  • ????spin_unlock(&devices_kset->list_lock);??
  • ????async_synchronize_full();??
  • 通过阅读代码,我们不难发现,在device_shutdown中,枚举了设备的shutdown方法,如果存在该方法,则会调用之.

    于是,32M spi flash的reset方法喷薄而出.

    解决办法

    转到drivers/mtd/devices/m25p80.c

    修改如下代码:

    ?

  • };??


  • 总结

    通过注册设备的shutdown方法,让我们有机会在系统重启的时刻,做一些deinit的操作.通过此种方法来复位spi flash,优雅而简洁.

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读