LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 02-23-2012, 08:31 AM   #1
dennisdd
Member
 
Registered: Oct 2011
Posts: 37

Rep: Reputation: Disabled
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,
	},
};

Last edited by dennisdd; 02-23-2012 at 09:36 AM.
 
Old 02-23-2012, 10:25 AM   #2
dennisdd
Member
 
Registered: Oct 2011
Posts: 37

Original Poster
Rep: Reputation: Disabled
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 )
 
Old 01-14-2014, 01:49 AM   #3
georgewhr
Member
 
Registered: Nov 2012
Location: SF Bay Area
Posts: 45

Rep: Reputation: Disabled
Quote:
Originally Posted by dennisdd View Post
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?
 
  


Reply

Tags
kernel, linux


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Kernel module null pointer error when a function is *moved* to another file. marquisdesade Linux - Kernel 4 03-03-2009 01:26 AM
Non superuser process predictably crashes RH9 with Kernel Null Pointer error Pandamatak Red Hat 1 09-29-2005 09:03 PM
Kernel Null Pointer Dereference Error Another Round of Issues Smillie Slackware 6 08-04-2005 04:55 PM
Kernel Null Pointer Dereference Error Smillie Slackware 3 04-27-2005 05:21 PM
Strange kernel error: "Unable to handle kernel NULL pointer dereference..." EcceVery Debian 4 04-12-2004 06:34 AM


All times are GMT -5. The time now is 01:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration