Search code examples
clinuxkerneldriverporting

How to add a new device to board init code linux kernel


Hi im am customizing linux kernel with version 2.22.19 and it do not support device tree. So i must use board init code to describe the peripheral. I have check the "spi node" in the board init code as below:

   static struct resource c300v2evm_spi0_resources[] = {
    {
        .start  = COMCERTO_SPI0_BASE,
        .end    = COMCERTO_SPI0_BASE + SZ_4K - 1,
        .flags  = IORESOURCE_MEM,
    },
    {
        .start  = IRQ_SPI0,
        .flags  = IORESOURCE_IRQ,
    },
};
static struct platform_device c300v2evm_spi0 = {
    .name = "comcerto_spi",
    .id = 0,
    .num_resources = ARRAY_SIZE(c300v2evm_spi0_resources),
    .resource = c300v2evm_spi0_resources,
};

And the spi bus has match with controller driver:

static int __init comcerto_spi_probe(struct platform_device *pdev)
{
...// probe function code
}
static struct platform_driver comcerto_spi_driver = {
    .driver = {
        .name   = "comcerto_spi",
        .owner  = THIS_MODULE,
    },
    .probe  = comcerto_spi_probe,
    .remove = __devexit_p(comcerto_spi_remove),
};

And now i have the protocol driver for my device (eeprom on spi bus):

static int at25_probe(struct spi_device *spi)
{
... // probe function code
}
static struct spi_driver at25_driver = {
    .driver = {
        .name       = "at25",
        .owner      = THIS_MODULE,
    },
    .probe      = at25_probe,
    .remove     = __devexit_p(at25_remove),
};

static int __init at25_init(void)
{
    return spi_register_driver(&at25_driver);
}

I have check log and see that the protocol is loaded to kernel with init function, but i do not know how to add a node in board init code to match with the protocol driver probe function.


Solution

  • I have resolved the issue by doing as below: First, i define a struct which describe my spi device in board init code file:

    static struct legerity_platform_data c300v2evm_legerity0_platform_data = {
    .type = 5,
    .dummy = 0,
    };
    
    static struct spi_board_info spi0_info[] = {
    {
        .modalias = "spi0",
        .chip_select = 1,
        .max_speed_hz = 1000*1000,
        .bus_num = 0,
        .irq = -1,
        .mode = SPI_MODE_3,
        .platform_data = &c300v2evm_legerity0_platform_data,
        },
    };
    

    With the field ".bus_num = 0", kernel will understand this spi device is belonged to spi0 bus, which has "id = 0". Then i use this function to register the device with kernel:

    spi_register_board_info(spi0_info, 1);
    

    I have test with my board and the protocol driver matched with my device, the "probe" function is called. This method is a basic method to register a new device in linux kernel version 2.x.x and i have checked that i can use this method with the newer version. Hope this will help people who have to work with old version of linux kernel.