Firefly开源社区

打印 上一主题 下一主题

[Android] rk3399 gpio驱动移植

791

积分

0

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
791

rk3399 gpio驱动移植

发表于 2019-1-21 16:17:14      浏览:5370 | 回复:3        打印      只看该作者   [复制链接] 楼主
之前开发了rk3288,移植了gpio驱动,并能成功移植。现在我用同样的gpio驱动源码,移植到rk3399里,发现一调用ioctl就会造成安卓死机重启,这是什么原因?
二楼附上gpio驱动源码:
回复

使用道具 举报

791

积分

0

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
791
发表于 2019-1-21 16:19:23        只看该作者  沙发
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include<linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#include <asm/delay.h>


#define ENBLK 149
#define DEFAULT_VALUE 255









#define GPIO_IOC_MAGIC                                        'G'
#define IOCTL_GPIO_SETOUTPUT                        _IOW(GPIO_IOC_MAGIC, 0, int)                  
#define IOCTL_GPIO_SETINPUT                                _IOW(GPIO_IOC_MAGIC, 1, int)
#define IOCTL_GPIO_SETVALUE                                _IOW(GPIO_IOC_MAGIC, 2, int)
#define IOCTL_GPIO_GETVALUE                                _IOR(GPIO_IOC_MAGIC, 3, int)
//#define IOCTL_GPIO_BKLTENABLE           _IOR(GPIO_IOC_MAGIC, 4, int)
#define GPIO_IOC_MAXNR                                        3







struct rk_gpio_arg{
        int pin;
        int data;
};

struct rk_gpio_node{
        int pin;
        struct rk_gpio_node *next;
};

static int gpio_major = 0;
static int gpio_minor = 0;
static struct class *gpio_class;
static struct device *rk_dev;
static struct cdev gpio_cdev;
static struct rk_gpio_node *head;

static int is_required(int pinnum)
{       
        struct rk_gpio_node *pnode = head->next;
        struct rk_gpio_node *rnode = head;

        while(pnode != NULL)
        {
                if(pnode->pin == pinnum)
                        return 0;
                else
                {
                        rnode = pnode;
                        pnode = pnode->next;
                }
        }
        printk("New GPIO Registered!\n");
        pnode = (struct rk_gpio_node *)kmalloc(sizeof(struct rk_gpio_node), GFP_KERNEL);
        if(pnode != NULL)
        {
                rnode->next = pnode;
                pnode->pin = pinnum;
                pnode->next = NULL;
        }
        else
                printk("Can't Kmalloc...\n");
       
        return 1;

}

static int gpio_open(struct inode *inode,struct file *filp)
{
        return 0;
}

static int gpio_release(struct inode *inode,struct file *filp)
{
        return 0;
}


static long gpio_ioctl(struct file *filp,  unsigned int cmd,  unsigned long arg)
{
        int err = 0;

       
        struct rk_gpio_arg *parg = (struct rk_gpio_arg *)arg;  
       

        if(is_required(parg->pin))
        {
                err = gpio_request(parg->pin, "rk_gpio");
                if(err != 0)
                {       
                        printk("Can't request this gpio!\n");
                        gpio_free(parg->pin);
                }                               
        }
        switch (cmd) {
        case IOCTL_GPIO_SETOUTPUT:
                       
                        gpio_direction_output(parg->pin, parg->data);
                break;       
        case IOCTL_GPIO_SETINPUT:

                        gpio_direction_input(parg->pin);
                break;
        case IOCTL_GPIO_SETVALUE:

                        gpio_set_value(parg->pin, parg->data);
                break;
        case IOCTL_GPIO_GETVALUE:

                        parg->data = gpio_get_value(parg->pin) ? 1 : 0;
                break;
        default :
                        printk(KERN_WARNING "Unsuported Ioctl Cmd\n");
        }
       
        return 0;
       
}

struct file_operations gpio_fops = {
        .owner =    THIS_MODULE,
        .open =     gpio_open,
        //change by louhn
        .unlocked_ioctl =    gpio_ioctl,
        //.compat_ioctl =    gpio_ioctl,
        .release =  gpio_release,
};


static int __init rk_gpio_init(void)
{
        int result;
        dev_t dev = 0;


        result = alloc_chrdev_region(&dev, gpio_minor, 1,"rk_gpio");
        gpio_major = MAJOR(dev);
        if (result < 0) {
                printk(KERN_WARNING "Can't get major %d\n", gpio_major);
                return result;
        }
        printk(" GPIO Driver Registered.\n");

        cdev_init(&gpio_cdev, &gpio_fops);
        gpio_cdev.owner = THIS_MODULE;
        gpio_cdev.ops = &gpio_fops;
        result = cdev_add (&gpio_cdev, dev, 1);

        gpio_class = class_create(THIS_MODULE, "rk_gpio");
        if (IS_ERR(gpio_class)) {
                printk(KERN_WARNING "Class_create faild\n");
                cdev_del(&gpio_cdev);
                unregister_chrdev_region(dev, 0);
                return result;
        }
        rk_dev = device_create(gpio_class, NULL, dev, 0, "rk_gpio");

        head = (struct rk_gpio_node *)kmalloc(sizeof(struct rk_gpio_node), GFP_KERNEL);
        if(head == NULL)
        {
                return -1;
        }
        else  
    {  
        head->pin = 0;  
        head->next = NULL;   
    }  
        return 0;
}

static void __exit rk_gpio_exit(void)
{
        dev_t dev = 0;
        struct rk_gpio_node *pnode = head->next;
        struct rk_gpio_node *rnode = NULL;
       
        while(pnode != NULL )
    {
                rnode = pnode->next;
        kfree(pnode);
        pnode = rnode;
    }
        kfree(head);
       
        dev = MKDEV(gpio_major, gpio_minor);

        class_unregister(gpio_class);
        class_destroy(gpio_class);
        unregister_chrdev_region(dev, 0);
        cdev_del(&gpio_cdev);
}


module_init(rk_gpio_init);
module_exit(rk_gpio_exit);


MODULE_DESCRIPTION("Driver for rockchip GPIO");
MODULE_AUTHOR("hzmct.com");
MODULE_LICENSE("GPL");




回复

使用道具 举报

791

积分

0

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
791
发表于 2019-1-21 16:22:19        只看该作者  板凳
我如果使用.compat_ioctl =    gpio_ioctl,就会造成安卓四级重启
回复

使用道具 举报

791

积分

0

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
791
发表于 2019-3-4 17:24:11        只看该作者  地板
找到原因了,估计是4.4的内核添加了防护的机制在 struct rk_gpio_arg *parg = (struct rk_gpio_arg *)arg;  这里不能直接赋值,而是应该使用copy_from_user函数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表