linux中probe函数传递参数的寻找(下)
點擊打開鏈接
linux中probe函數(shù)傳遞參數(shù)的尋找(下)
???????? 通過追尋driver的腳步,我們有了努力的方向:只有找到spi_bus_type的填充device即可,下面該從device去打通,當(dāng)兩個連通之日,也是任督二脈打通之時。先從設(shè)備定義去查看,在mach-smdk6410.c中定義了硬件設(shè)備信息,從這作為突破口。
/* for mx25lx*/
static void?cs_set_level(unsigned line_id, int lvl) {
???gpio_direction_output(line_id, lvl);
};
static struct s3c64xx_spi_csinfos3c64xx_spi1_csinfo = {
? ???? .fb_delay=0x3,
? ???? .line=S3C64XX_GPC(7),
?????? .set_level=cs_set_level,
};
?
static int mx25lx_ioSetup(struct spi_device*spi)
{
???????? printk(KERN_INFO"mx25lx: setup gpio pins CS and External Int\n");
???????? s3c_gpio_setpull(S3C64XX_GPL(8),S3C_GPIO_PULL_UP);????????????? //External interrupt from CAN controller
???????? s3c_gpio_cfgpin(S3C64XX_GPL(8),S3C_GPIO_SFN(3)); ????????????????? //External interrupt from CAN controller (hopefully external interrupt)
???????? //s3c_gpio_cfgpin(S3C64XX_GPL(8),S3C_GPIO_INPUT);???????????????? //External interrupt from CAN controller
???????? s3c_gpio_setpull(S3C64XX_GPC(7),S3C_GPIO_PULL_NONE);?????? // Manual chipselect pin as used in 6410_set_cs
???????? s3c_gpio_cfgpin(S3C64XX_GPC(7),S3C_GPIO_OUTPUT);??????????????? // Manualchip select pin as used in 6410_set_cs
???????? return0;
}
?
static?struct mx25lx_platform_datamx25lx_info?=
{
???????? .oscillator_frequency= 8000000,
???????? .board_specific_setup= mx25lx_ioSetup,
???????? .transceiver_enable= NULL,
???????? .power_enable= NULL,
};
?
static struct spi_board_info __initdataforlinx6410_mc251x_info[]? =
{
???????? {
?????????????????? .modalias= "mcp2515",
???????????????????.platform_data = &mx25lx_info,
?????????????????? .irq= IRQ_EINT(16),
?????????????????? .max_speed_hz= 10*1000*1000,?
?????????????????? .bus_num= 1,
?????????????????? .chip_select= 0,
?????????????????? .mode= SPI_MODE_0,???
?????????????????? .controller_data=&s3c64xx_spi1_csinfo,
???????? },
};
?
struct platform_device s3c64xx_device_spi0= {
???????? .name??????????????? ?= "s3c64xx-spi",
???????? .id????????????? ?= 0,
???????? .num_resources?????? ? =ARRAY_SIZE(s3c64xx_spi0_resource),
???????? .resource ? =s3c64xx_spi0_resource,
???????? .dev= {
?????????????????? .dma_mask?????????????? = &spi_dmamask,
?????????????????? .coherent_dma_mask???? = DMA_BIT_MASK(32),
?????????????????? .platform_data= &s3c64xx_spi0_pdata,
???????? },
};
?
static struct platform_device*smdk6410_devices[] __initdata =
{
???????? ……
???????? /*addby fatfish*/
???????? &s3c64xx_device_spi0,
???????? &s3c64xx_device_spi1,
};
?
???????? 其中platform_device定義為:
struct platform_device {
???????? constchar??????? * name;
???????? int????????????? id;
???????? structdevice??? dev;
???????? u32??????????? num_resources;
???????? structresource??????? * resource;
?
???????? conststruct platform_device_id???? *id_entry;
?
???????? /*MFD cell pointer */
???????? structmfd_cell *mfd_cell;
?
???????? /*arch specific additions */
???????? structpdev_archdata????? archdata;
};
?
???????? 初始化函數(shù)如下:
static void __initsmdk6410_machine_init(void)
{
???????? ……
???????? s3c64xx_spi_set_info(0,0,1);
???????? s3c64xx_spi_set_info(1,0,1);
???????? spi_register_board_info(forlinx6410_mc251x_info,ARRAY_SIZE(forlinx6410_mc251x_info));
???????? ……
}
?????? 其中的注冊板信息的函數(shù)如下,后項參數(shù)為1,其中board_list為spi.c中定義的全局變量,即:static LIST_HEAD(board_list);。
int __init
spi_register_board_info(structspi_board_info const *info, unsigned n)
{
???????? structboardinfo *bi;
???????? inti;
?
???????? bi= kzalloc(n * sizeof(*bi), GFP_KERNEL);
???????? if(!bi)
?????????????????? return-ENOMEM;
?
???????? for(i = 0; i < n; i++, bi++, info++) {
?????????????????? structspi_master *master;
?
?????????????????? memcpy(&bi->board_info,info, sizeof(*info));
?????????????????? mutex_lock(&board_lock);
?????????????????? list_add_tail(&bi->list,&board_list);
?????????????????? list_for_each_entry(master,&spi_master_list, list)
??????????????????????????? spi_match_master_to_boardinfo(master,&bi->board_info);
?????????????????? mutex_unlock(&board_lock);
???????? }
?
???????? return0;
}
???????? 其中結(jié)果成員如下:
???????? 先加鎖,然后將board_list加入鏈接中,在遍歷設(shè)備,最關(guān)鍵的函數(shù)是:
static voidspi_match_master_to_boardinfo(struct spi_master *master,
???????????????????????????????????? structspi_board_info *bi)
{
???????? structspi_device *dev;
?
???????? if(master->bus_num != bi->bus_num)
?????????????????? return;
?
???????? dev= spi_new_device(master, bi);
???????? if(!dev)
?????????????????? dev_err(master->dev.parent,"can't create new device for %s\n",
??????????????????????????? bi->modalias);
}
???????? spi_new_device作用是實例化一個新設(shè)備,定義如下:
struct spi_device *spi_new_device(structspi_master *master,
???????????????????????????????????? ? struct spi_board_info *chip)
{
???????? structspi_device???? *proxy;
???????? int?????????????????????? status;
?
?
???????? proxy= spi_alloc_device(master);
???????? if(!proxy)
?????????????????? returnNULL;
?
……
???????? strlcpy(proxy->modalias,chip->modalias, sizeof(proxy->modalias));
?????????proxy->dev.platform_data = (void *)chip->platform_data;
???????? proxy->controller_data= chip->controller_data;
???????? proxy->controller_state= NULL;
?
???????? status= spi_add_device(proxy);
???????? if(status < 0) {
?????????????????? spi_dev_put(proxy);
?????????????????? returnNULL;
???????? }
?
???????? returnproxy;
}
?
???????? 拷貝了platform_data,即mx25lx_info。其中的spi_alloc_device函數(shù)定義如下:
struct spi_device *spi_alloc_device(structspi_master *master)
{
???????? structspi_device???? *spi;
???????? structdevice???????????? *dev =master->dev.parent;
?
???????? if(!spi_master_get(master))
?????????????????? returnNULL;
?
???????? spi= kzalloc(sizeof *spi, GFP_KERNEL);
???????? if(!spi) {
?????????????????? dev_err(dev,"cannot alloc spi_device\n");
?????????????????? spi_master_put(master);
?????????????????? returnNULL;
???????? }
?
???????? spi->master= master;
???????? spi->dev.parent= dev;
???????? spi->dev.bus= &spi_bus_type;
???????? spi->dev.release= spidev_release;
???????? device_initialize(&spi->dev);
???????? returnspi;
}
???????? 在這個定義中將spi_bus_type和dev聯(lián)系起來,不過此時還沒有我們定義的設(shè)備信息,設(shè)備信息在接下來的賦值中完成。
???????? 最后是spi_add_device,將設(shè)備信息提交。
int spi_add_device(struct spi_device *spi)
{
???????? staticDEFINE_MUTEX(spi_add_lock);
???????? structdevice *dev = spi->master->dev.parent;
???????? structdevice *d;
???????? intstatus;
?
……
???????? mutex_lock(&spi_add_lock);
?
???????? d= bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
???????? ……
???????? status= spi_setup(spi);
???????? if(status < 0) {
?????????????????? dev_err(dev,"can't setup %s, status %d\n",
???????????????????????????????????? dev_name(&spi->dev),status);
?????????????????? gotodone;
???????? }
……
done:
???????? mutex_unlock(&spi_add_lock);
???????? returnstatus;
}
???????? 最終完成將spi_bus_type與定義的device信息聯(lián)系起來。由于本人才疏學(xué)淺,不正確的地方,懇求大牛指正,在此表示感謝
總結(jié)
以上是生活随笔為你收集整理的linux中probe函数传递参数的寻找(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux中probe函数中传递的参数来
- 下一篇: Android------Android