QSPI nor flash相關驅動程式碼
1. drivers/spi/spi.c: 是linux spi通用框架程式碼, 向下適配ti mcspi以及ti qspi控制器驅動.
2. drivers/spi/spi-ti-qspi.c: TI qspi主控器驅動, 不同平臺使用不同的主控驅動
3. drivers/mtd/devices/m25p80.c: m25p80.c和spi-nor.c都是linux spi nor驅動框架的一部分
4. drivers/mtd/spi/spi-nor/spi-nor.c: m25p80.c和spi-nor.c都是linux spi nor驅動框架的一部分
系統架構
從架構圖可以看出spi-nor是簡單的粘合層, 把mtd呼叫轉換為m25p80介面. spi-nor還包含了qspi晶片檢測, 通過晶片ID, 確定spi nor的引數:sector size, nsectors, pagesize, flags.
spi-nor驅動適配多種spi nor flash, 這些flash的驅動層程式碼差異, 由flash_info的幾個引數表示.
spi-nor.c為mtd子系統服務, 為mtd層提供如下幾個介面:
- spi_nor_write
- spi_nor_erase
- spi_nor_read
spi_nor_scan呼叫spi_nor_read_id從chip獲取ID, 根據chip ID得到該晶片的flash_info
1. 設定mtd_info的type, writesize, size等引數
2. 設定mtd_info的_erase, _read, _write回撥函式
3. 設定mtd_info 的erasesize
m25p80.c
這個驅動最初為M25Pxx系列使用, 現在已經成為一個通用的spi nor實現, 實際上完全可以和spi-nor.c合二為一.
m25p80.c主要實現瞭如下幾個函式:
- m25p80_read, 實現資料讀
- m25p80_write, 實現資料寫
- m25p80_erase, 實現資料擦除
- m25p80_write_reg, 寫opcode到nor flash, 比如write_enable, erase chip
- m25p80_read_reg, 設定QSPI特定暫存器, 比如讀取chip ID, status register等
m25p80.c底層介面為common的spi呼叫介面, common spi介面會呼叫qspi master.
驅動初始化流程
Linux spi子系統中, 存在兩個角色
- spi master, 比如TI平臺的mcspi, 和ti_qspi
- spi device, 比如掛在mcspi上的spi裝置, 以及掛在ti_qspi上的qspi nor flash
spi master
系統要訪問spi device, 必須通過spi master裝置訪問, 通常spi master和spi device是一對多的關係, 一個spi master上掛載多個spi device, 通過chip select選取操作哪個spi device
一個spi master對應一個spi bus num, 系統有幾個spi master就有幾條spi bus. 參見spi_register_master
Linux作業系統會為每一個spi master建立相應的裝置節點, 比如ti mcspi對應/dev/spi1, ti qspi對應/dev/spi32766
在spi_register_master的最後階段, 會掃描device tree中master的子節點(master子節點就是掛在它下面的spi device).
spi bus
spi_init首先初始化註冊spi_bus_type, 這是所有spi初始化的起點, 沒有spi_bus_type就無法就進行spi device和spi bus的匹配.
spi bus使用spi_match_device作為driver和device的匹配函式
1. 首先嚐試匹配driver的of_match_table
2. 然後是id_table
3. 最後會嘗試匹配spi device的modalias和driver->name
spi device
m25p80.c定義了一個spi driver m25p80_driver.
在系統初始化階段module_spi_driver(m25p80_driver)會註冊一個spi driver, 在註冊過程中, kernel會檢視spi_bus上的spi device是否match這個m25p80_driver, 如果match則呼叫m25p80_dirver的probe函式.