#include #include #include #include #include #include #include #include #include #include #include #define EN_DEBOUNCE #ifdef EN_DEBOUNCE #include extern unsigned long volatile jiffies; unsigned long old_jiffie = 0; unsigned long old_jiffie1 = 0; #endif #define MY_IOCTL_SET_PID _IOW('p', 1, pid_t) #define gpio_1 47 //GPIO3_IO15 #define gpio_2 48 //GPIO3_IO18 #define gpio1_gpio 79 #define gpio2_gpio 82 bool gpios_Int1 = false; bool gpios_Int2 = false; static char *HELLO_KEYS_NAMES[] = { "MY_BUTTON_gpio_1", "MY_BUTTON_gpio_2" }; static int gpio_nbs[] = {0, 1}; // GPIO numbers static int irq_nums[2]; // Array to store IRQ numbers static pid_t user_space_pid; //Below are irq handler functions : static irqreturn_t custom_isr(int irq, void *dev_id, int sig_num) { if (user_space_pid != 0) { struct pid *pid_struct; struct task_struct *task; pid_struct = find_get_pid(user_space_pid); if (pid_struct) { task = get_pid_task(pid_struct, PIDTYPE_PID); if (task) { send_sig(sig_num, task, 0); put_task_struct(task); } put_pid(pid_struct); } } //local_irq_restore(0); return IRQ_HANDLED; } static irqreturn_t gpio_int1(int irq, void *dev_id) { static unsigned long flags = 0; #ifdef EN_DEBOUNCE unsigned long diff = jiffies - old_jiffie; if (diff < 10) { return IRQ_HANDLED; } old_jiffie = jiffies; #endif local_irq_save(flags); if (gpio_get_value(gpio1_gpio) == 1) { pr_info("gpio1 Pressed"); //gpios_Int1 = false; //last_interrupt_time = now; // local_irq_enable(); local_irq_restore(flags); return custom_isr(irq, dev_id, 47); } else { pr_info("gpio1 Release"); //gpios_Int1 = false; //last_interrupt_time = now; // local_irq_enable(); local_irq_restore(flags); return custom_isr(irq, dev_id, 51); } } static irqreturn_t gpio_int2(int irq, void *dev_id) { static unsigned long flags = 0; #ifdef EN_DEBOUNCE unsigned long diff = jiffies - old_jiffie1; if (diff < 10) { return IRQ_HANDLED; } old_jiffie1 = jiffies; #endif local_irq_save(flags); if (gpio_get_value(gpio2_gpio) == 1) { pr_info("gpio2 Pressed"); local_irq_restore(flags); return custom_isr(irq, dev_id, 48); } else { pr_info("gpio2 Release"); local_irq_restore(flags); return custom_isr(irq, dev_id, 52); } } static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { if (cmd == MY_IOCTL_SET_PID) { pid_t *pid = (pid_t *)arg; user_space_pid = *pid; } return 0; } static int my_dev_open(struct inode *inode, struct file *file) { pr_info("my_devgpio_open() is called.\n"); return 0; } static int my_dev_close(struct inode *inode, struct file *file) { pr_info("my_devgpio_close() is called.\n"); return 0; } static const struct file_operations my_dev_fops = { .owner = THIS_MODULE, .open = my_dev_open, .release = my_dev_close, .unlocked_ioctl = my_ioctl, }; static struct miscdevice helloworld_miscdevice = { .minor = MISC_DYNAMIC_MINOR, .name = "mygpios", .fops = &my_dev_fops, }; static int my_probe(struct platform_device *pdev) { int ret_val; struct device *dev = &pdev->dev; int i; pr_info("madhuri gpio_Platform_probe enter\n"); for (i = 0; i < ARRAY_SIZE(gpio_nbs); i++) { int gpio_nb = of_get_gpio(pdev->dev.of_node, i); if (gpio_nb < 0) { pr_err("madhuri Failed to get gpio GPIO %d\n", i); ret_val = gpio_nb; goto error_gpio; } irq_nums[i] = gpio_to_irq(gpio_nb); if (irq_nums[i] < 0) { pr_err("madhuri IRQ is not available for gpio GPIO %d\n", gpio_nb); ret_val = irq_nums[i]; goto error_gpio; } pr_info("madhuri IRQ using gpio_to_irq for gpio GPIO %d: %d\n", gpio_nb, irq_nums[i]); } ret_val = devm_request_irq(dev, irq_nums[0], gpio_int1, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, HELLO_KEYS_NAMES[0], pdev->dev.of_node); if (ret_val) { pr_err("madhuri Failed to request gpio interrupt %d, error %d\n", irq_nums[0], ret_val); goto error_gpio; } ret_val = devm_request_irq(dev, irq_nums[1], gpio_int2, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, HELLO_KEYS_NAMES[1], pdev->dev.of_node); if (ret_val) { pr_err("madhuri Failed to request gpio interrupt %d, error %d\n", irq_nums[1], ret_val); goto error_gpio; } ret_val = misc_register(&helloworld_miscdevice); if (ret_val != 0) { pr_err("madhuri Could not register the misc device mydev\n"); goto error_gpio; } pr_info("madhuri mydev: got minor %i\n", helloworld_miscdevice.minor); return 0; error_gpio: for (i--; i >= 0; i--) { gpio_free(gpio_nbs[i]); // Free allocated GPIOs } return ret_val; } static int my_remove(struct platform_device *pdev) { int i; misc_deregister(&helloworld_miscdevice); pr_info("madhuri my_remove() function is called.\n"); for (i = 0; i < ARRAY_SIZE(gpio_nbs); i++) { gpio_free(gpio_nbs[i]); // Free allocated GPIOs } return 0; } static const struct of_device_id my_of_ids[] = { { .compatible = "wizcom,gpio" }, {}, }; MODULE_DEVICE_TABLE(of, my_of_ids); static struct platform_driver my_platform_driver = { .probe = my_probe, .remove = my_remove, .driver = { .name = "intkeygpio", .of_match_table = my_of_ids, .owner = THIS_MODULE, } }; module_platform_driver(my_platform_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("madhuri"); MODULE_DESCRIPTION("This is a SW INT platform driver");