LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   spi_sync cause kernel NULL pointer error (http://www.linuxquestions.org/questions/programming-9/spi_sync-cause-kernel-null-pointer-error-930874/)

dennisdd 02-23-2012 08:31 AM

spi_sync cause kernel NULL pointer error
 
I have problem when I do the following:

status = spi_sync(test_dev.spi_device, &test_ctl.msg);

I get the error:

"Unable to handle kernel NULL pointer dereference at virtual address 00000000"

It seem like the problem related to follow when the kernel* try to execute it, this is part of spi_sync() in spi.c

wait_for_completion(&done);

What could cause this issue? The following is my SPI driver code.

Code:


#define SPI_BUFF_SIZE        16
#define USER_BUFF_SIZE        128

#define SPI_BUS 1
#define SPI_BUS_CS1 1
#define SPI_BUS_SPEED 1000000


const char this_driver_name[] = "test";

struct test_control {
        struct spi_message msg;
        struct spi_transfer transfer;
        u8 *tx_buff;
        u8 *rx_buff;
};
static struct test_control test_ctl;

struct test_dev {
        struct semaphore spi_sem;
        struct semaphore fop_sem;
        dev_t devt;
        struct cdev cdev;
        struct class *class;
        struct spi_device *spi_device;
        char *user_buff;
        u8 test_data;
};
static struct test_dev test_dev;

static void test_prepare_spi_message(void)
{
        printk(KERN_ALERT "@test_prepare_spi_message\n");

        spi_message_init(&test_ctl.msg);

        printk(KERN_ALERT "@test_prepare_spi_message p1\n");

        /* put some changing values in tx_buff for testing */
        test_ctl.tx_buff[0] = test_dev.test_data++;
        test_ctl.tx_buff[1] = test_dev.test_data++;
        test_ctl.tx_buff[2] = test_dev.test_data++;
        test_ctl.tx_buff[3] = test_dev.test_data++;

        memset(test_ctl.rx_buff, 0, SPI_BUFF_SIZE);

        test_ctl.transfer.tx_buf = test_ctl.tx_buff;
        test_ctl.transfer.rx_buf = test_ctl.rx_buff;
        test_ctl.transfer.len = 4;

        printk(KERN_ALERT "@test_prepare_spi_message p2\n");
        spi_message_add_tail(&test_ctl.transfer, &test_ctl.msg);
}

static int test_do_one_message(void)
{
        int status;
        printk(KERN_ALERT "@test_do_one_message\n");

        if (down_interruptible(&test_dev.spi_sem))
        return -ERESTARTSYS;

        if (!test_dev.spi_device) {
                up(&test_dev.spi_sem);
                return -ENODEV;
        }

        test_prepare_spi_message();
        printk(KERN_ALERT "@test_do_one_message p1\n");

        if(&test_ctl.msg == NULL )
        {
                printk(KERN_ALERT "@test_do_one_message test_ctl.msg NULL\n");
                return -ENODEV;
        }

        if(test_dev.spi_device !=NULL)
        {
                status = spi_sync(test_dev.spi_device, &test_ctl.msg);
        }
        else
        {
                printk(KERN_ALERT "@test_do_one_message NULL\n");
                return -ENODEV;
        }
        printk(KERN_ALERT "@test_do_one_message p2\n");
        up(&test_dev.spi_sem);

        return status;
}

static ssize_t test_read(struct file *filp, char __user *buff, size_t count,
                        loff_t *offp)
{
        size_t len;
        ssize_t status = 0;

        printk(KERN_ALERT "@test_read\n");

        if (!buff)
                return -EFAULT;

        if (*offp > 0)
                return 0;

        if (down_interruptible(&test_dev.fop_sem))
                return -ERESTARTSYS;

        if (!test_dev.spi_device)
        {
                printk(KERN_ALERT "@test_read test_dev.spi_device is NULL\n");
        }
        else if (!test_dev.spi_device->master)
        {
                printk(KERN_ALERT "@test_read spi_device->master is NULL\n");
        }
        else
        {
                printk(KERN_ALERT "@test_read %s ready on SPI%d.%d\n",
                        this_driver_name,
                        test_dev.spi_device->master->bus_num,
                        test_dev.spi_device->chip_select);
        }

       
        //len = strlen(test_dev.user_buff);

        printk(KERN_ALERT "@test_read p1\n");

        status = test_do_one_message();

        if (status)
        {
                sprintf(test_dev.user_buff,
                "test_do_one_message failed : %d\n",
                status);
        }
        else
        {
                sprintf(test_dev.user_buff,
                "Status: %d\nTX: %d %d %d %d\nRX: %d %d %d %d\n",
                test_ctl.msg.status,
                test_ctl.tx_buff[0], test_ctl.tx_buff[1],
                test_ctl.tx_buff[2], test_ctl.tx_buff[3],
                test_ctl.rx_buff[0], test_ctl.rx_buff[1],
                test_ctl.rx_buff[2], test_ctl.rx_buff[3]);
        }

        len = strlen(test_dev.user_buff);

 
        if (len < count)
                count = len;

        if (copy_to_user(buff, test_dev.user_buff, count))  {
                printk(KERN_ALERT "test_readoned(): copy_to_user() failed\n");
                status = -EFAULT;
        } else {
                *offp += count;
                status = count;
        }

        up(&test_dev.fop_sem);

        return status;       
}



static int test_open(struct inode *inode, struct file *filp)
{       
        int status = 0;
        printk(KERN_ALERT "@test_open\n");
        if (down_interruptible(&test_dev.fop_sem))
                return -ERESTARTSYS;

        if (!test_dev.user_buff) {
                test_dev.user_buff = kmalloc(USER_BUFF_SIZE, GFP_KERNEL);
                if (!test_dev.user_buff)
                        status = -ENOMEM;
        }       

        up(&test_dev.fop_sem);

        return status;
}

static int __devinit test_probe(struct spi_device *spi_device)
{
        struct spi_master *spi_master;
        int status = 0;

        if (down_interruptible(&test_dev.spi_sem))
                return -EBUSY;

        printk(KERN_ALERT "@test_probe\n");

        spi_master = spi_busnum_to_master(SPI_BUS);
        if (!spi_master) {
                printk(KERN_ALERT "spi_busnum_to_master(%d) returned NULL\n",
                        SPI_BUS);
                printk(KERN_ALERT "Missing modprobe omap2_mcspi?\n");
                return -1;
        }

        spi_device = spi_alloc_device(spi_master);
        if (!spi_device) {
                put_device(&spi_master->dev);
                printk(KERN_ALERT "spi_alloc_device() failed\n");
                return -1;
        }

        spi_device->chip_select = SPI_BUS_CS1;

        spi_device->max_speed_hz = SPI_BUS_SPEED;
        spi_device->mode = SPI_MODE_0;
        spi_device->bits_per_word = 8;
        spi_device->irq = -1;
        spi_device->controller_state = NULL;
        spi_device->controller_data = NULL;
        strlcpy(spi_device->modalias, this_driver_name, SPI_NAME_SIZE);
        test_dev.spi_device = spi_device;

/*        status = spi_add_device(spi_device);

        if (status < 0)
        {
                spi_dev_put(spi_device);
                printk(KERN_ALERT "spi_add_device() failed: %d\n",
                status);
        }
        put_device(&spi_master->dev); */

        printk(KERN_ALERT "@test_probe test_dev.spi_device: (%d)\n",&test_dev.spi_device);

        up(&test_dev.spi_sem);

        return 0;
}

static int test_remove(struct spi_device *spi_device)
{
        if (down_interruptible(&test_dev.spi_sem))
                return -EBUSY;

        printk(KERN_ALERT "@test_remove\n");

        test_dev.spi_device = NULL;

        up(&test_dev.spi_sem);

        return 0;
}


static struct spi_driver test_driver = {
        .driver = {
                .name =        this_driver_name,
                .owner = THIS_MODULE,
        },
        .probe = test_probe,
        .remove = __devexit_p(test_remove),       
};

static int __init test_init_spi(void)
{
        int error;

        printk(KERN_ALERT "@test_init_spi\n");


        test_ctl.tx_buff = kmalloc(SPI_BUFF_SIZE, GFP_KERNEL | GFP_DMA);
        if (!test_ctl.tx_buff) {
                error = -ENOMEM;
                goto test_init_error;
        }

        test_ctl.rx_buff = kmalloc(SPI_BUFF_SIZE, GFP_KERNEL | GFP_DMA);
        if (!test_ctl.rx_buff) {
                error = -ENOMEM;
                goto test_init_error;
        }

        error = spi_register_driver(&test_driver);
        if (error < 0) {
                printk(KERN_ALERT "spi_register_driver() failed %d\n", error);
                goto test_init_error;
        }

        return 0;

test_init_error:

        if (test_ctl.tx_buff)
        {
                kfree(test_ctl.tx_buff);
                test_ctl.tx_buff = 0;
        }

        if (test_ctl.rx_buff)
        {
                kfree(test_ctl.rx_buff);
                test_ctl.rx_buff = 0;
        }
        return -1;
}

static const struct file_operations test_fops = {
        .owner =        THIS_MODULE,
        .read =        test_read,
        .open =                test_open,       
};

static int __init test_init_cdev(void)
{
        int error;

        printk(KERN_ALERT "@test_init_cdev\n");

        test_dev.devt = MKDEV(0, 0);

        error = alloc_chrdev_region(&test_dev.devt, 0, 1, this_driver_name);
        if (error < 0) {
                printk(KERN_ALERT "alloc_chrdev_region() failed: %d \n",
                        error);
                return -1;
        }

        cdev_init(&test_dev.cdev, &test_fops);
        test_dev.cdev.owner = THIS_MODULE;
       
        error = cdev_add(&test_dev.cdev, test_dev.devt, 1);
        if (error) {
                printk(KERN_ALERT "cdev_add() failed: %d\n", error);
                unregister_chrdev_region(test_dev.devt, 1);
                return -1;
        }       
        return 0;
}

static int __init test_init_class(void)
{

        printk(KERN_ALERT "@test_init_class\n");

        test_dev.class = class_create(THIS_MODULE, this_driver_name);

        if (!test_dev.class) {
                printk(KERN_ALERT "class_create() failed\n");
                return -1;
        }

        if (!device_create(test_dev.class, NULL, test_dev.devt, NULL,       
                        this_driver_name)) {
                printk(KERN_ALERT "device_create(..., %s) failed\n",
                        this_driver_name);
                class_destroy(test_dev.class);
                return -1;
        }

        return 0;
}

static int __init test_init(void)
{
        memset(&test_dev, 0, sizeof(test_dev));
        memset(&test_ctl, 0, sizeof(test_ctl));

        sema_init(&test_dev.spi_sem, 1);
        sema_init(&test_dev.fop_sem, 1);
       
        if (test_init_cdev() < 0)
                goto fail_1;
       
        if (test_init_class() < 0) 
                goto fail_2;

        if (test_init_spi() < 0)
                goto fail_3;

        return 0;

fail_3:
        device_destroy(test_dev.class, test_dev.devt);
        class_destroy(test_dev.class);
fail_2:
        cdev_del(&test_dev.cdev);
        unregister_chrdev_region(test_dev.devt, 1);
fail_1:
        return -1;
}
module_init(test_init);

static void __exit test_exit(void)
{
        spi_unregister_device(test_dev.spi_device);
        spi_unregister_driver(&test_driver);

        device_destroy(test_dev.class, test_dev.devt);
        class_destroy(test_dev.class);

        cdev_del(&test_dev.cdev);
        unregister_chrdev_region(test_dev.devt, 1);

        if (test_ctl.tx_buff)
                kfree(test_ctl.tx_buff);

        if (test_ctl.rx_buff)
                kfree(test_ctl.rx_buff);

        if (test_dev.user_buff)
                kfree(test_dev.user_buff);
}
module_exit(test_exit);

this is from my devkit8000_spi_board_info[

Code:

static struct spi_board_info devkit8000_spi_board_info[] __initdata = {
        {
                .modalias                = "ads7846",
                .bus_num                = 2,
                .chip_select                = 0,
                .max_speed_hz                = 1500000,
                .controller_data        = &ads7846_mcspi_config,
                .irq                        = OMAP_GPIO_IRQ(OMAP3_DEVKIT_TS_GPIO),
                .platform_data                = &ads7846_config,
        },
        {
                .modalias                = "test",
                .bus_num                = 1,
                .chip_select                = 1,
                .max_speed_hz                = 2500000, // 25MHz
                .mode                        = SPI_MODE_0,
        },
};


dennisdd 02-23-2012 10:25 AM

manage to get the kernel NULL pointer error fix with this, but sadly there is nothing come out from my SPI1 IO port ..no signal. what did I missed?

Code:

static int __devinit spike_probe(struct spi_device *spi_device)
{
        struct spi_master *spi_master;
        struct spike_dev *ts;
        int status = 0;

        //if (down_interruptible(&spike_dev.spi_sem))
        //        return -EBUSY;

        printk(KERN_ALERT "@spike_probe\n");

        spi_device->max_speed_hz = SPI_BUS_SPEED;
        spi_device->mode = SPI_MODE_0;
        spi_device->bits_per_word = 8;
        spi_device->irq = -1;
        spi_device->controller_state = NULL;
        spi_device->controller_data = NULL;
        strlcpy(spi_device->modalias, this_driver_name, SPI_NAME_SIZE);
        spike_dev.spi_device = spi_device;

        status = spi_setup(spi_device);
        if (status < 0)
        {        printk(KERN_ALERT "@spike_probe spi_setup failed\n");
                return status;
        }
        printk(KERN_ALERT "@spike_probe spike_dev.spi_device: (%d)\n",&spike_dev.spi_device);

        return 0;
}

board-devkit8000.c add the following too..
Code:

MUX_CFG_34XX("MCSPI1_CLK", 0x1c8,
            OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) // CLK must be input mode as per datasheet request
MUX_CFG_34XX("MCSPI1_SIMO", 0x1ca,
            OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT )
MUX_CFG_34XX("MCSPI1_SOMI", 0x1cc,
            OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT)
MUX_CFG_34XX("MCSPI1_CS1", 0x1d0,
            OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT )


georgewhr 01-14-2014 01:49 AM

Quote:

Originally Posted by dennisdd (Post 4610115)
I have problem when I do the following:

status = spi_sync(test_dev.spi_device, &test_ctl.msg);

I get the error:

"Unable to handle kernel NULL pointer dereference at virtual address 00000000"

It seem like the problem related to follow when the kernel* try to execute it, this is part of spi_sync() in spi.c

wait_for_completion(&done);

What could cause this issue? The following is my SPI driver code.

Code:


#define SPI_BUFF_SIZE        16
#define USER_BUFF_SIZE        128

#define SPI_BUS 1
#define SPI_BUS_CS1 1
#define SPI_BUS_SPEED 1000000


const char this_driver_name[] = "test";

struct test_control {
        struct spi_message msg;
        struct spi_transfer transfer;
        u8 *tx_buff;
        u8 *rx_buff;
};
static struct test_control test_ctl;

struct test_dev {
        struct semaphore spi_sem;
        struct semaphore fop_sem;
        dev_t devt;
        struct cdev cdev;
        struct class *class;
        struct spi_device *spi_device;
        char *user_buff;
        u8 test_data;
};
static struct test_dev test_dev;

static void test_prepare_spi_message(void)
{
        printk(KERN_ALERT "@test_prepare_spi_message\n");

        spi_message_init(&test_ctl.msg);

        printk(KERN_ALERT "@test_prepare_spi_message p1\n");

        /* put some changing values in tx_buff for testing */
        test_ctl.tx_buff[0] = test_dev.test_data++;
        test_ctl.tx_buff[1] = test_dev.test_data++;
        test_ctl.tx_buff[2] = test_dev.test_data++;
        test_ctl.tx_buff[3] = test_dev.test_data++;

        memset(test_ctl.rx_buff, 0, SPI_BUFF_SIZE);

        test_ctl.transfer.tx_buf = test_ctl.tx_buff;
        test_ctl.transfer.rx_buf = test_ctl.rx_buff;
        test_ctl.transfer.len = 4;

        printk(KERN_ALERT "@test_prepare_spi_message p2\n");
        spi_message_add_tail(&test_ctl.transfer, &test_ctl.msg);
}

static int test_do_one_message(void)
{
        int status;
        printk(KERN_ALERT "@test_do_one_message\n");

        if (down_interruptible(&test_dev.spi_sem))
        return -ERESTARTSYS;

        if (!test_dev.spi_device) {
                up(&test_dev.spi_sem);
                return -ENODEV;
        }

        test_prepare_spi_message();
        printk(KERN_ALERT "@test_do_one_message p1\n");

        if(&test_ctl.msg == NULL )
        {
                printk(KERN_ALERT "@test_do_one_message test_ctl.msg NULL\n");
                return -ENODEV;
        }

        if(test_dev.spi_device !=NULL)
        {
                status = spi_sync(test_dev.spi_device, &test_ctl.msg);
        }
        else
        {
                printk(KERN_ALERT "@test_do_one_message NULL\n");
                return -ENODEV;
        }
        printk(KERN_ALERT "@test_do_one_message p2\n");
        up(&test_dev.spi_sem);

        return status;
}

static ssize_t test_read(struct file *filp, char __user *buff, size_t count,
                        loff_t *offp)
{
        size_t len;
        ssize_t status = 0;

        printk(KERN_ALERT "@test_read\n");

        if (!buff)
                return -EFAULT;

        if (*offp > 0)
                return 0;

        if (down_interruptible(&test_dev.fop_sem))
                return -ERESTARTSYS;

        if (!test_dev.spi_device)
        {
                printk(KERN_ALERT "@test_read test_dev.spi_device is NULL\n");
        }
        else if (!test_dev.spi_device->master)
        {
                printk(KERN_ALERT "@test_read spi_device->master is NULL\n");
        }
        else
        {
                printk(KERN_ALERT "@test_read %s ready on SPI%d.%d\n",
                        this_driver_name,
                        test_dev.spi_device->master->bus_num,
                        test_dev.spi_device->chip_select);
        }

       
        //len = strlen(test_dev.user_buff);

        printk(KERN_ALERT "@test_read p1\n");

        status = test_do_one_message();

        if (status)
        {
                sprintf(test_dev.user_buff,
                "test_do_one_message failed : %d\n",
                status);
        }
        else
        {
                sprintf(test_dev.user_buff,
                "Status: %d\nTX: %d %d %d %d\nRX: %d %d %d %d\n",
                test_ctl.msg.status,
                test_ctl.tx_buff[0], test_ctl.tx_buff[1],
                test_ctl.tx_buff[2], test_ctl.tx_buff[3],
                test_ctl.rx_buff[0], test_ctl.rx_buff[1],
                test_ctl.rx_buff[2], test_ctl.rx_buff[3]);
        }

        len = strlen(test_dev.user_buff);

 
        if (len < count)
                count = len;

        if (copy_to_user(buff, test_dev.user_buff, count))  {
                printk(KERN_ALERT "test_readoned(): copy_to_user() failed\n");
                status = -EFAULT;
        } else {
                *offp += count;
                status = count;
        }

        up(&test_dev.fop_sem);

        return status;       
}



static int test_open(struct inode *inode, struct file *filp)
{       
        int status = 0;
        printk(KERN_ALERT "@test_open\n");
        if (down_interruptible(&test_dev.fop_sem))
                return -ERESTARTSYS;

        if (!test_dev.user_buff) {
                test_dev.user_buff = kmalloc(USER_BUFF_SIZE, GFP_KERNEL);
                if (!test_dev.user_buff)
                        status = -ENOMEM;
        }       

        up(&test_dev.fop_sem);

        return status;
}

static int __devinit test_probe(struct spi_device *spi_device)
{
        struct spi_master *spi_master;
        int status = 0;

        if (down_interruptible(&test_dev.spi_sem))
                return -EBUSY;

        printk(KERN_ALERT "@test_probe\n");

        spi_master = spi_busnum_to_master(SPI_BUS);
        if (!spi_master) {
                printk(KERN_ALERT "spi_busnum_to_master(%d) returned NULL\n",
                        SPI_BUS);
                printk(KERN_ALERT "Missing modprobe omap2_mcspi?\n");
                return -1;
        }

        spi_device = spi_alloc_device(spi_master);
        if (!spi_device) {
                put_device(&spi_master->dev);
                printk(KERN_ALERT "spi_alloc_device() failed\n");
                return -1;
        }

        spi_device->chip_select = SPI_BUS_CS1;

        spi_device->max_speed_hz = SPI_BUS_SPEED;
        spi_device->mode = SPI_MODE_0;
        spi_device->bits_per_word = 8;
        spi_device->irq = -1;
        spi_device->controller_state = NULL;
        spi_device->controller_data = NULL;
        strlcpy(spi_device->modalias, this_driver_name, SPI_NAME_SIZE);
        test_dev.spi_device = spi_device;

/*        status = spi_add_device(spi_device);

        if (status < 0)
        {
                spi_dev_put(spi_device);
                printk(KERN_ALERT "spi_add_device() failed: %d\n",
                status);
        }
        put_device(&spi_master->dev); */

        printk(KERN_ALERT "@test_probe test_dev.spi_device: (%d)\n",&test_dev.spi_device);

        up(&test_dev.spi_sem);

        return 0;
}

static int test_remove(struct spi_device *spi_device)
{
        if (down_interruptible(&test_dev.spi_sem))
                return -EBUSY;

        printk(KERN_ALERT "@test_remove\n");

        test_dev.spi_device = NULL;

        up(&test_dev.spi_sem);

        return 0;
}


static struct spi_driver test_driver = {
        .driver = {
                .name =        this_driver_name,
                .owner = THIS_MODULE,
        },
        .probe = test_probe,
        .remove = __devexit_p(test_remove),       
};

static int __init test_init_spi(void)
{
        int error;

        printk(KERN_ALERT "@test_init_spi\n");


        test_ctl.tx_buff = kmalloc(SPI_BUFF_SIZE, GFP_KERNEL | GFP_DMA);
        if (!test_ctl.tx_buff) {
                error = -ENOMEM;
                goto test_init_error;
        }

        test_ctl.rx_buff = kmalloc(SPI_BUFF_SIZE, GFP_KERNEL | GFP_DMA);
        if (!test_ctl.rx_buff) {
                error = -ENOMEM;
                goto test_init_error;
        }

        error = spi_register_driver(&test_driver);
        if (error < 0) {
                printk(KERN_ALERT "spi_register_driver() failed %d\n", error);
                goto test_init_error;
        }

        return 0;

test_init_error:

        if (test_ctl.tx_buff)
        {
                kfree(test_ctl.tx_buff);
                test_ctl.tx_buff = 0;
        }

        if (test_ctl.rx_buff)
        {
                kfree(test_ctl.rx_buff);
                test_ctl.rx_buff = 0;
        }
        return -1;
}

static const struct file_operations test_fops = {
        .owner =        THIS_MODULE,
        .read =        test_read,
        .open =                test_open,       
};

static int __init test_init_cdev(void)
{
        int error;

        printk(KERN_ALERT "@test_init_cdev\n");

        test_dev.devt = MKDEV(0, 0);

        error = alloc_chrdev_region(&test_dev.devt, 0, 1, this_driver_name);
        if (error < 0) {
                printk(KERN_ALERT "alloc_chrdev_region() failed: %d \n",
                        error);
                return -1;
        }

        cdev_init(&test_dev.cdev, &test_fops);
        test_dev.cdev.owner = THIS_MODULE;
       
        error = cdev_add(&test_dev.cdev, test_dev.devt, 1);
        if (error) {
                printk(KERN_ALERT "cdev_add() failed: %d\n", error);
                unregister_chrdev_region(test_dev.devt, 1);
                return -1;
        }       
        return 0;
}

static int __init test_init_class(void)
{

        printk(KERN_ALERT "@test_init_class\n");

        test_dev.class = class_create(THIS_MODULE, this_driver_name);

        if (!test_dev.class) {
                printk(KERN_ALERT "class_create() failed\n");
                return -1;
        }

        if (!device_create(test_dev.class, NULL, test_dev.devt, NULL,       
                        this_driver_name)) {
                printk(KERN_ALERT "device_create(..., %s) failed\n",
                        this_driver_name);
                class_destroy(test_dev.class);
                return -1;
        }

        return 0;
}

static int __init test_init(void)
{
        memset(&test_dev, 0, sizeof(test_dev));
        memset(&test_ctl, 0, sizeof(test_ctl));

        sema_init(&test_dev.spi_sem, 1);
        sema_init(&test_dev.fop_sem, 1);
       
        if (test_init_cdev() < 0)
                goto fail_1;
       
        if (test_init_class() < 0) 
                goto fail_2;

        if (test_init_spi() < 0)
                goto fail_3;

        return 0;

fail_3:
        device_destroy(test_dev.class, test_dev.devt);
        class_destroy(test_dev.class);
fail_2:
        cdev_del(&test_dev.cdev);
        unregister_chrdev_region(test_dev.devt, 1);
fail_1:
        return -1;
}
module_init(test_init);

static void __exit test_exit(void)
{
        spi_unregister_device(test_dev.spi_device);
        spi_unregister_driver(&test_driver);

        device_destroy(test_dev.class, test_dev.devt);
        class_destroy(test_dev.class);

        cdev_del(&test_dev.cdev);
        unregister_chrdev_region(test_dev.devt, 1);

        if (test_ctl.tx_buff)
                kfree(test_ctl.tx_buff);

        if (test_ctl.rx_buff)
                kfree(test_ctl.rx_buff);

        if (test_dev.user_buff)
                kfree(test_dev.user_buff);
}
module_exit(test_exit);

this is from my devkit8000_spi_board_info[

Code:

static struct spi_board_info devkit8000_spi_board_info[] __initdata = {
        {
                .modalias                = "ads7846",
                .bus_num                = 2,
                .chip_select                = 0,
                .max_speed_hz                = 1500000,
                .controller_data        = &ads7846_mcspi_config,
                .irq                        = OMAP_GPIO_IRQ(OMAP3_DEVKIT_TS_GPIO),
                .platform_data                = &ads7846_config,
        },
        {
                .modalias                = "test",
                .bus_num                = 1,
                .chip_select                = 1,
                .max_speed_hz                = 2500000, // 25MHz
                .mode                        = SPI_MODE_0,
        },
};


Check test_ctl.msg, did you sucessfully copy spi_transfer to message?


All times are GMT -5. The time now is 01:41 PM.