
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h>
#define CNAME "platform_irq_led"
unsigned int condition=0;
irqreturn_t irq_led_handle(int irq, void *dev)
status = gpiod_get_value(desc);
gpiod_set_value(desc,status);
wake_up_interruptible(&wq);
int irq_led_open(struct inode *inode, struct file *file)
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
ssize_t irq_led_read(struct file *file,
char __user *ubuf, size_t size, loff_t *offs)
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
if(file->f_flags & O_NONBLOCK){
ret = wait_event_interruptible(wq,condition);
printk("receive signal....\n");
if(size > sizeof(status)) size = sizeof(status);
ret = copy_to_user(ubuf,(void *)&status,size);
printk("copy data to user error\n");
int irq_led_close(struct inode *inode, struct file *file)
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
struct file_operations fops = {
.release = irq_led_close,
int pdrv_probe(struct platform_device* pdev) //在进入probe函数的时候节点已经被放在pdev->dev.of_node中了
major = register_chrdev(0,CNAME,&fops);
printk("register char device driver error\n");
cls = class_create(THIS_MODULE,CNAME);
printk("class create error\n");
dev = device_create(cls,NULL,MKDEV(major,0),NULL,CNAME);
printk("device create error\n");
init_waitqueue_head(&wq);
desc = gpiod_get_from_of_node(pdev->dev.of_node,"led1",0,GPIOD_OUT_LOW,NULL);
printk("get gpiod error\n");
irqno = platform_get_irq(pdev,0); //获取中断的信息
printk("get irq resource error\n");
ret = request_irq(irqno,irq_led_handle,IRQF_TRIGGER_FALLING,CNAME,NULL);
printk("request irq error\n");
device_destroy(cls,MKDEV(major,0));
unregister_chrdev(major,CNAME);
int pdrv_remove(struct platform_device* pdev)
printk("%s:%d\n", __func__, __LINE__);
device_destroy(cls,MKDEV(major,0));
unregister_chrdev(major,CNAME);
struct of_device_id oftable[] = {
{.compatible = "hqyj,platform",},
struct platform_driver pdrv = {
.of_match_table = oftable,
module_platform_driver(pdrv);

int main(int argc, const char* argv[])
if ((fd = open("/dev/platform_irq_led", O_RDWR)) == -1) {
read(fd, &status, sizeof(status));
printf("status = %d\n", status);