linux驱动一个驱动如何匹配两种同样类型的设备获取不同资源。

#驱动drv.c

#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/cdev.h>
#include <linux/slab.h>

#include "led.h"

#define LED_NUM (2)
#define LED_CHRDEV_NAME ("led_chrdev")
#define LED_MAJOR (255)

struct led_dev{
    dev_t dev_no;
    unsigned int minor;
    struct cdev cdev;
    struct class *cls;
    struct device *dev;
    struct resource *res;
    unsigned int pin;
    char cls_name[20];
    char gpio_name[20];
};
struct led_dev *p_led_dev;

static int led_open(struct inode *inode, struct file *filp)
{
    struct led_dev *t_led_dev = container_of(inode->i_cdev, struct led_dev, cdev);
    filp->private_data = t_led_dev;

    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    return 0;
}

static int led_release(struct inode *inode, struct file *filp)
{
    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    return 0;
}

static long led_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{

    int  led_num;
    struct led_dev *t_led_dev = filp->private_data;

    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    if ( _IOC_TYPE(cmd) != LED_MAGIC)   // 判断幻数
    {
        printk("_IOC_TYPE err.\n");
        return -ENOTTY;
    }

    led_num = MINOR(t_led_dev->dev_no);
    switch(cmd)
    {
    case LEDON:
        if (led_num == 0)
        {

            printk("led%d on.\n", led_num);
            gpio_set_value(p_led_dev->pin, 1);
            printk("pin is %d on.\n", p_led_dev->pin);
        }
        else if(led_num == 1)
        {
            printk("led%d on.\n", led_num);
            gpio_set_value(p_led_dev->pin, 1);
            printk("pin is %d on.\n", p_led_dev->pin);
        }

        break;
    case LEDOFF:
        if (led_num == 0)
        {

            printk("led%d off.\n", led_num);
            gpio_set_value(p_led_dev->pin, 0);
            printk("pin is %d off.\n", p_led_dev->pin);
        }
        else if(led_num == 1)
        {
            printk("led%d off.\n", led_num);
            gpio_set_value(p_led_dev->pin, 0);
            printk("pin is %d off.\n", p_led_dev->pin);
        }
        break;
    default:
        printk("cmd id error.\n");
    }

    return 0;

}

static struct file_operations led_ops = {
    .owner = THIS_MODULE,
    .open = led_open,
    .release = led_release,
    .unlocked_ioctl = led_ioctl,
};

static int led_probe(struct platform_device *pdev)
{
    int ret;

    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    p_led_dev = kzalloc(sizeof(struct led_dev), GFP_KERNEL);
    if ( IS_ERR(p_led_dev) )
    {
        printk("kzalloc error.\n");
        ret = PTR_ERR(p_led_dev);
        goto kzalloc_err;
    }

    p_led_dev->dev_no = MKDEV(LED_MAJOR, pdev->id);
    ret = register_chrdev_region(p_led_dev->dev_no, 1, LED_CHRDEV_NAME);
    if ( ret < 0 )
    {
        printk("register_chrdev_region failed.\n");
        goto alloc_chrdev_region_err;
    }
    p_led_dev->minor = MINOR(p_led_dev->dev_no);    // 次设备号
    p_led_dev->pin = *(unsigned int *)(pdev->dev.platform_data);

    cdev_init(&p_led_dev->cdev, &led_ops);

    ret = cdev_add(&p_led_dev->cdev, p_led_dev->dev_no, LED_NUM);
    if ( ret < 0 )
    {
        printk("cdev_add error.\n");
        goto cdev_add_err;
    }

    sprintf(p_led_dev->cls_name, "led_cls%d", pdev->id);
    p_led_dev->cls = class_create(THIS_MODULE, p_led_dev->cls_name);
    if ( IS_ERR(p_led_dev->cls) )
    {
        printk("class_create failed.\n");
        ret = PTR_ERR(p_led_dev->cls);
        goto class_create_err;
    }

    p_led_dev->dev = device_create(p_led_dev->cls, NULL, p_led_dev->dev_no, NULL, "led_device%d", pdev->id);
    if ( IS_ERR(p_led_dev->dev) )
    {
        printk("device_create failed.\n");
        ret = PTR_ERR(p_led_dev->dev);
        goto device_create_err;
    }

    p_led_dev->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if ( IS_ERR(p_led_dev->res) )
    {
        printk("platform_set_drvdata failed.\n");
        ret = PTR_ERR(p_led_dev->res);
        goto platform_set_drvdata_err;
    }

    ret = gpio_is_valid(p_led_dev->pin);
    if (ret == 0)
    {
        printk("gpio is not valid.\n");
        goto gpio_is_valid_err;
    }

    sprintf(p_led_dev->gpio_name, "led_gpio%d", pdev->id);
    ret = gpio_request(p_led_dev->pin, p_led_dev->gpio_name);
    if (ret < 0)
    {
        printk("gpio_request failed.\n");
        goto gpio_request_err;
    }

    ret = gpio_direction_output(p_led_dev->pin, 0); // 将引脚设置为输出,并初始化为低电平
    if ( ret < 0 )
    {
        printk("gpio_direction_output failed.\n");
        goto gpio_direction_output_err;
    }

    platform_set_drvdata(pdev, (void *)p_led_dev);

    return 0;


gpio_direction_output_err:
    gpio_free(p_led_dev->pin);
gpio_request_err:
gpio_is_valid_err:
platform_set_drvdata_err:
    device_destroy(p_led_dev->cls, p_led_dev->dev_no);
device_create_err:
    class_destroy(p_led_dev->cls);
class_create_err:
    cdev_del(&p_led_dev->cdev);
cdev_add_err:
    unregister_chrdev_region(p_led_dev->dev_no, 1);
alloc_chrdev_region_err:
    kfree(p_led_dev);
kzalloc_err:
    return ret;
}

static int led_remove(struct platform_device *pdev)
{
    struct led_dev *t_led_dev = platform_get_drvdata(pdev);

    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    gpio_free(t_led_dev->pin);

    device_destroy(t_led_dev->cls, t_led_dev->dev_no);
    class_destroy(t_led_dev->cls);
    cdev_del(&t_led_dev->cdev);
    unregister_chrdev_region(t_led_dev->dev_no, 1);
    kfree(t_led_dev);

    return 0;
}

static struct platform_driver led_driver = {
    .probe = led_probe,
    .remove = led_remove,
    .driver = {
        .name = "335x_led",
        .owner = THIS_MODULE,
    },
};

module_platform_driver(led_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("使用平台设备的LED驱动");

#设备dev.c

#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>

unsigned int led1_pin = (1*32+0);   // GPIO1_7
unsigned int led2_pin = (1*32+1);   // GPIO1_6


void led_dev_release(struct device *dev)
{
    printk("%s -- %d.\n", __FUNCTION__, __LINE__);
}

// LED1 GPIO1_7
struct resource led1_resource[] = {
    [0] = DEFINE_RES_MEM(0x44E1081C, 4),    // CONF_GPMC_AD7
    [1] = DEFINE_RES_MEM(0x4804C134, 4),    // GPIO1_OE 
    [2] = DEFINE_RES_MEM(0x4804C13C, 4),    // GPIO1_DATAOUT
};

// LED2 GPIO1_6
struct resource led2_resource[] = {
    [0] = DEFINE_RES_MEM(0x44E10818, 4),    // CONF_GPMC_AD6
    [1] = DEFINE_RES_MEM(0x4804C134, 4),    // GPIO1_OE 
    [2] = DEFINE_RES_MEM(0x4804C13C, 4),    // GPIO1_DATAOUT
};



struct platform_device led1_dev = 
{
    .name = "335x_led",
    .id = 0,
    .num_resources = ARRAY_SIZE(led1_resource),
    .resource = led1_resource,
    .dev = {
        .release = led_dev_release,
        .platform_data = &led1_pin,     // void *型,用来向驱动传递更多的信息,这里传递的是管脚号
    },
};

struct platform_device led2_dev = 
{
    .name = "335x_led",
    .id = 1,
    .num_resources = ARRAY_SIZE(led2_resource),
    .resource = led2_resource,
    .dev = {
        .release = led_dev_release,
        .platform_data = &led2_pin,
    },
};


static int __init led_dev_init(void)
{
    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    platform_device_register(&led1_dev);
    platform_device_register(&led2_dev);


    return 0;
}

static void __exit led_dev_exit(void)
{
    printk("%s -- %d.\n", __FUNCTION__, __LINE__);

    platform_device_unregister(&led1_dev);
    platform_device_unregister(&led2_dev);

}

module_init(led_dev_init);
module_exit(led_dev_exit);
MODULE_LICENSE("GPL");

#led.h

#ifndef _LED_H_
#define _LED_H_

typedef struct led_node
{
    int which;
    int status;
}led_node_t;

#define LED_MAGIC 'q'
#define LEDON  _IOW(LED_MAGIC, 0, struct led_node)
#define LEDOFF _IOW(LED_MAGIC, 1, struct led_node)

#endif /* led.h */

#test.c


#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "led.h"

#define LED_NUM (2)

const char *led_pathname[LED_NUM] = {
    "/dev/led_device0",
    "/dev/led_device1",
};

int main()
{
    int i, fd_led[LED_NUM];

    for (i=0; i<LED_NUM; i++)
    {
        fd_led[i] = open(led_pathname[i], O_RDWR, 0666);
        if (fd_led[i] < 0)
        {
            printf("open led%d failed\n", i);
            return -1;
        }
    }

    for(i=0; i<LED_NUM; i++)
    {
        ioctl(fd_led[i], LEDON);  // 点亮LED
        sleep(1);

        ioctl(fd_led[i], LEDOFF); // 关闭LED
        sleep(1);
    }   

    for(i=0; i<LED_NUM; i++)
    {
        close(fd_led[i]);
    }

    return 0;
}

#运行结果

/mnt # insmod drv.ko
/mnt # insmod dev.ko
led_dev_init -- 57.
led_probe -- 115.
led_probe -- 115.
/mnt # ./app
led_open -- 36.
led_open -- 36.
led_ioctl -- 54.
led0 on.
pin is 33 on.
led_ioctl -- 54.
led0 off.
pin is 33 off.
led_ioctl -- 54.
led1 on.
pin is 33 on.
led_ioctl -- 54.
led1 off.
pin is 33 off.
led_release -- 43.
led_release -- 43.

为什么运行结果都是33号led亮,是资源被覆盖了吗?求解,如果使设备0获取32,设备1获取33.

https://blog.csdn.net/sinat_30545941/article/details/85943787