SMALL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /******************************************************************** * * elv210_keybutton.c * ELV210 key button device driver * * EINT1 (GPH0_1) : KEY 1 * EINT2 (GPH0_2) : KEY 2 * * 2015-01-20 : eLayer System GBH. ********************************************************************/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <asm/io.h> #include <asm/irq.h> #include <mach/hardware.h> #include <mach/irqs.h> static irqreturn_t key1_isr(int irq, void *dev_id) { printk("KEY1 pressed.. irq[%d]\n",irq); return IRQ_HANDLED; }ㅌㅌㅂ static irqreturn_t key2_isr(int irq, void *dev_id) { printk("KEY2 pressed.. irq[%d]\n",irq); return IRQ_HANDLED; } static int __init elv210_keybutton_probe(struct platform_device *pdev) { int ret; printk("eLV210 external key button probe!!\n"); //requeeset_irq 함수 //이 친구를 이용해서 interrupt를 편하게 컨트롤 할 수 있음 ret = request_irq(IRQ_EINT(1), //INTERRUPT 번호 key1_isr, //Service routin IRQF_DISABLED|IRQF_TRIGGER_FALLING, //IRQF_DISABLED : 중첩 인터럽트 방지 isr 처리 루틴 //TRIGGER_FALLING : Falling edge가 발생할 때 인터럽트가 발생했다고 생각 "KEY1", //Keyword Description NULL //Parameter ); //requeeset_irq 함수 //이 친구를 이용해서 interrupt를 편하게 컨트롤 할 수 있음 ret = request_irq(IRQ_EINT(2), //INTERRUPT 번호 key2_isr, //Service routin IRQF_DISABLED|IRQF_TRIGGER_FALLING, //IRQF_DISABLED : 중첩 인터럽트 방지 isr 처리 루틴 //TRIGGER_FALLING : Falling edge가 발생할 때 인터럽트가 발생했다고 생각 "KEY2", //Keyword Description NULL //Parameter ); if (ret) { printk("eLV210 keybutton: request IRQ failed!!\n"); return ret; } return 0; } static int elv210_keybutton_remove(struct platform_device *pdev) { printk("eLV210 external key button remove!!\n"); free_irq(IRQ_EINT(1), NULL); return 0; } static int elv210_keybutton_suspend(struct platform_device *dev, pm_message_t state) { printk("elv210_keybutton_suspend!!\n"); return 0; } static int elv210_keybutton_resume(struct platform_device *pdev) { printk("elv210_keybutton_resume!!\n"); return 0; } static struct platform_driver elv210keybtn_driver = { .probe = elv210_keybutton_probe, .remove = elv210_keybutton_remove, .suspend = elv210_keybutton_suspend, .resume = elv210_keybutton_resume, .driver = { .owner = THIS_MODULE, .name = "elv210-keybutton", }, }; int __init elv210_keybutton_init(void) { return platform_driver_register(&elv210keybtn_driver); } void __exit elv210_keybutton_exit(void) { platform_driver_unregister(&elv210keybtn_driver); } module_init(elv210_keybutton_init); module_exit(elv210_keybutton_exit); MODULE_LICENSE("GPL"); | cs |
플랫폼 디바이스 드라이버 [platform device driver]
플랫폼 드라이버의 스타팅 포인트는 PnP 를 지원하기 위해서
운영체제가 올라가면 PnP에서 인식해서 동작하도록 하는 목적이었지만,
버스 드라이버를 관리하는 하나의 형태로 발전 함.
플램폼 디바이스 드라이버는 k object에 소속되어 있음.
구성에서 함수 포인터
특징
최소한 4개의 함수 포인터는 반드시 구성해놓아야 함.
사용하지 않더라도 4개는 구성해야함
.probe
.remove
.suspend
.resume
이러한 접근을 통해서 디바이스 트리로 넘어가는 것임
platfrom_driver_register 함수로 등록 함.
LIST
'학부_대학원 > 임베디드 리눅스' 카테고리의 다른 글
[임베디드 정리] (0) | 2017.07.17 |
---|---|
(임베디드)리눅스 커널 모듈 - IOCTL (0) | 2017.07.14 |
Platform Device Driver Built In[플랫폼 디바이스 드라이버 빌트인] (0) | 2017.07.13 |
(임베디드)리눅스 커널 모듈 - User, Kernel 통신 (0) | 2017.07.13 |
Mango Board 정리 (0) | 2017.07.12 |