请教一下,我正在学习i2c驱动,想尝试从添加i2c_adapter开始,写了个简单的i2c驱动模块,但是执行到第79行ret = i2c_add_adapter(&i2c->adap);就崩溃了,各位大神麻烦帮小弟看一下是怎么回事。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
static struct kaka_i2c_struct *i2c = NULL;
struct kaka_i2c_struct {
struct i2c_adapter adap;
struct device *dev;
};
static int ka_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct kaka_i2c_struct *i2c = (struct kaka_i2c_struct *)adap->algo_data;
printk("i2c is %p\n",i2c);
printk("going to ka_i2c_xfer()\n");
return 0;
}
/* i2c bus registration info */
static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.master_xfer = ka_i2c_xfer,
//.functionality = ka_i2c_func,
};
static int ka_i2c_probe(struct platform_device *pdev)
{
int ret;
printk("going to ka_i2c_probe()\n");
/* pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
}
*/
i2c = kzalloc(sizeof(struct kaka_i2c_struct), GFP_KERNEL);
if (!i2c) {
printk("no memory for state\n");
return -ENOMEM;
}
memset(i2c,0,sizeof(*i2c));
strlcpy(i2c->adap.name, "kakakakka-i2c", sizeof(i2c->adap.name));
i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &s3c24xx_i2c_algorithm;
i2c->adap.retries = 2;
i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
/* find the clock and enable it */
i2c->dev = &pdev->dev;
/* setup info block for the i2c core */
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &pdev->dev;
//i2c->adap.nr = pdata->bus_num;
i2c->adap.nr = 1;
printk("1\n");
printk("%p\n",&i2c->adap);
ret = i2c_add_adapter(&i2c->adap);
printk("1.5\n");
if (ret < 0) {
printk("failed to add bus to i2c core\n");
}
printk("2\n");
platform_set_drvdata(pdev, i2c);
return 0;
}
static int ka_i2c_remove(struct platform_device *pdev)
{
struct kaka_i2c_struct *i2c = platform_get_drvdata(pdev);
printk("going to ka_i2c_remove()\n");
i2c_del_adapter(&i2c->adap);
return 0;
}
/* device driver for platform bus bits */
static struct platform_device_id ka_driver_ids[] = {
{
.name = "ka-i2c",
}, { },
};
MODULE_DEVICE_TABLE(platform, ka_driver_ids);
static struct platform_driver ka_i2c_driver = {
.probe = ka_i2c_probe,
.remove = ka_i2c_remove,
.id_table = ka_driver_ids,
.driver = {
.owner = THIS_MODULE,
.name = "lizhe-i2c", //same with i2c_device
},
};
static void ka_device_release(struct device *dev)
{
printk("ka_device_release\n");
return ;
}
static struct platform_device i2c_device =
{
.name = "ka-i2c", //same with ka_i2c_driver
.id = -1,
//.dev.release = ka_device_release,
};
static int __init i2c_init(void)
{
int ret;
printk("i2c_device_init\n");
ret = platform_device_register(&i2c_device);
if(ret)
{
printk("platform_device_register fail\n");
return ret;
}
ret = platform_driver_register(&ka_i2c_driver);
if(ret)
{
printk("platform_driver_register fail\n");
platform_device_unregister(&i2c_device);
return ret;
}
return ret;
}
module_init(i2c_init);
static void __exit i2c_exit(void)
{
printk("i2c_exit\n");
platform_device_unregister(&i2c_device);
platform_driver_unregister(&ka_i2c_driver);
}
module_exit(i2c_exit);
MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
MODULE_AUTHOR("kaka");
MODULE_LICENSE("Dual BSD/GPL");