以设置GPIO1_IO0为例子
方法一:
在DTS中设置
interrupt-parent = <&gpio1>;
interrupts = <0 0>;/*第一个0位IO0*/
在C代码中
irq = irq_of_parse_and_map(dev->of_node, 0);
ret = request_threaded_irq(pData->irq, NULL,
gpio_test, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING |IRQF_ONESHOT, "test_int",
pData);
方法二:
在DTS文件中
test_int = <&gpio1 0 0>; /*GPIO1_IO0*/
在C代码中
gpio_int = of_get_named_gpio(dev->of_node, "test_int", 0);
if (!gpio_is_valid(pData->gpio_int))
{
printk(KERN_ERR"of_get_named_gpio error\n");
goto ERROR;
}
ret = devm_gpio_request_one(dev,pData->gpio_int, GPIOF_IN, "test_int");
if (ret) {
printk(KERN_ERR"devm_gpio_request_one error\n");
goto ERROR;
}
ret = request_threaded_irq(gpio_to_irq(pData->gpio_int), NULL,
gpio_test, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING | IRQF_ONESHOT, "test_int",
pData);
下面是测试代码:
在DTS文件中
gpiotest:gpiotest@0 {
compatible = "fsl,test-gpio-int";
pinctrl-names = "default";
interrupt-parent = <&gpio1>;
interrupts = <0 0>;
test_int = <&gpio1 0 0>;
source_int = <&gpio5 22 0>;
};
在C代码中
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/power_supply.h>
#include <linux/platform_device.h>
#include <linux/power/sabresd_battery.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
typedef struct
{
int gpio_int;
int gpio_out;
int irq;
}st_test_gpio;
static struct proc_dir_entry * test_entry = NULL;
static ssize_t test_write(struct file * file,const char __user* data,size_t len,loff_t *off)
{
st_test_gpio * pData=PDE_DATA(file_inode(file));
char cmd;
if(pData==NULL)
{
printk(KERN_ERR"can't get proc file data \n" );
}
if(copy_from_user(&cmd ,data ,1) == 0 )
{
if(cmd=='0')
{
gpio_set_value_cansleep(pData->gpio_out, 0);
}
else
{
gpio_set_value_cansleep(pData->gpio_out, 1);
}
}
return len;
}
static struct file_operations test_proc_ops = {
.owner = THIS_MODULE,
.write = test_write
};
static int proc_init(void * data)
{
test_entry = proc_create_data("gpio-test",0666,NULL,&test_proc_ops ,data );
if(!test_entry){
printk(KERN_ERR"can't create proc file \n" );
return -EFAULT;
}
return 0;
}
static void proc_exit(void)
{
if(test_entry )
{
remove_proc_entry("gpio-test",NULL);
}
}
static irqreturn_t gpio_test(int irq, void *_data)
{
st_test_gpio * pData=(st_test_gpio *)_data;
#if 0
if(gpio_get_value(pData->gpio_int))
{
printk("gpio int raising edge is reached\n");
}
else
{
printk("gpio int failing edge is reached\n");
}
#else
printk("gpio int is reached\n");
#endif
return IRQ_HANDLED;
}
static int test_gpio_probe(struct platform_device *pdev)
{
st_test_gpio *pData;
struct device *dev = &pdev->dev;
int ret;
pData = devm_kzalloc(dev, sizeof(st_test_gpio), GFP_KERNEL);
if (!pData)
return -ENOMEM;
platform_set_drvdata(pdev, pData);
pData->gpio_out = of_get_named_gpio(dev->of_node, "source_int", 0);
if (!gpio_is_valid(pData->gpio_out))
{
printk(KERN_ERR"of_get_named_gpio gpio_out error\n");
goto ERROR;
}
ret = devm_gpio_request_one(dev,pData->gpio_out, GPIOF_OUT_INIT_HIGH, "test_int_source");
if (ret) {
printk(KERN_ERR"devm_gpio_request_one gpio_out error\n");
goto ERROR;
}
#if 0
pData->gpio_int = of_get_named_gpio(dev->of_node, "test_int", 0);
if (!gpio_is_valid(pData->gpio_int))
{
printk(KERN_ERR"of_get_named_gpio error\n");
goto ERROR;
}
ret = devm_gpio_request_one(dev,pData->gpio_int, GPIOF_IN, "test_int");
if (ret) {
printk(KERN_ERR"devm_gpio_request_one error\n");
goto ERROR;
}
ret = request_threaded_irq(gpio_to_irq(pData->gpio_int), NULL,
gpio_test, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING | IRQF_ONESHOT, "test_int",
pData);
#else
pData->irq = irq_of_parse_and_map(dev->of_node, 0);
ret = request_threaded_irq(pData->irq, NULL,
gpio_test, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING |IRQF_ONESHOT, "test_int",
pData);
#endif
if(ret!=0)
{
printk(KERN_ERR"request_threaded_irq error ret=%d\n",ret);
gpio_free(pData->gpio_int);
goto ERROR;
}
proc_init(pData);
printk(KERN_ERR"gpio int probe sucess\n");
return 0;
ERROR:
kfree(pData);
platform_set_drvdata(pdev, NULL);
printk(KERN_ERR"gpio int probe failed\n");
return -ENOMEM;
}
static int test_gpio_remove(struct platform_device *pdev)
{
st_test_gpio *pData = platform_get_drvdata(pdev);
if(pData)
{
free_irq(gpio_to_irq(pData->gpio_int), NULL);
gpio_free(pData->gpio_int);
kfree(pData);
platform_set_drvdata(pdev, NULL);
}
proc_exit();
printk(KERN_ERR"gpio int remove sucess\n");
return 0;
}
static const struct of_device_id test_gpio_dt_ids[] = {
{ .compatible = "fsl,test-gpio-int", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, test_gpio_dt_ids);
static struct platform_driver test_gpio_driver = {
.probe = test_gpio_probe,
.remove = test_gpio_remove,
.driver = {
.name = "test-gpio-int",
.owner = THIS_MODULE,
.of_match_table = test_gpio_dt_ids,
},
};
module_platform_driver(test_gpio_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("Gpio int Driver");
MODULE_ALIAS("gpio_test_int");
编译好后,将GPIO1_IO0和GPIO5_IO22
运行echo "1">/proc/gpio-test 或echo "0">/proc/gpio-test
就可以看到串口信息“gpio int is reached”