Kobox: key_wq.c-V2

Source: Internet
Author: User

Change the four work queue processing functions in kobox: key_wq.c-V1 to one work queue processing function.

Because multiple work queues can use the same work queue processing function


# Include "key. H "# define initi_addr_base0xf6000000 # define initi_addr (x) (cloud_addr_base + (x) # define s3c2410_pa_uart (0x50000000) # define s3c2410_pa_gpio (0x56000000) # define partition (0x01000000)/* UART */# define partition # define s3c24xx_va_gpio (s3c24xx_pa_gpio-s3c24xx_pa_uart) + s3c24xx_va_uart) # define S3c2410_gpioreg (x) + metrics) # define s3c2410_gpbcon s3c2410_gpioreg (0x10) # define kernel s3c2410_gpioreg (0x14) # define kernel s3c2410_gpioreg (0x18) # define kernel s3c2410_gpioreg (0x50) # define s3c2410_gpfdat s3c2410_gpioreg (0x54) # define kernel s3c2410_gpioreg (0x58) # define s3c2410_extint0 s3c2410_gpioreg (0x88) # define s3c2410_extint1 s3c2410_gpioreg (0x8c) # defi Ne s3c2410_extint2 s3c2410_gpioreg (0x90) # define s3c2410_cpuirq_offset (16) # define s3c2410_irq (x) + s3c2410_cpuirq_offset) /* main CPU interrupts */# define irq_eint0 s3c2410_irq (0)/* 16 */# define kernel s3c2410_irq (1)/* 17 */# define irq_eint2 s3c2410_irq (2) /* 18 */# define irq_eint4t7 s3c2410_irq (4)/* 20 */# define irq_eint4 s3c2410_irq (36)/* 52 */# define ir1__disabled0x00000020 # define irqf _ Shared0x00000080 # define sequence # DEFINE _ Sequence # define sequence # define ir1__oneshot0x00002000 # define sequence # define struct gpiores {int irqnum; /* interrupt Number */unsigned int CTRL Reg;/* control register, used to set to be reused as gpio */unsigned int ctrlbit;/* control register, used to reuse as gpio */unsigned int trigreg; /* interrupt mode register, set the trigger mode of the interrupt */unsigned int trigbit;/* the bit of the interrupt mode register, and set the trigger mode of the interrupt */unsigned int irqflag; /* share or not, register the interrupted flag */Char irqname [32];/* interrupt name */unsigned int gpfpin; /* Number of GPF pins */Char reserved [10];/* Reserved */} gpiores; # define array_size (ARR) (sizeof (ARR)/sizeof (ARR) [0]) gpiores key_gpio_res [4] = {irq_eint1, S Keys, 2, s3c2410_extint0, 5, null, "key1", 1},/* key1 */{irq_eint4, s3c2410_gpfcon, 8, s3c2410_extint0, 17, ir1__shared, "key2 ", 4},/* key2 */{irq_eint2, s3c2410_gpfcon, 4, s3c2410_extint0, 9, null, "key3", 2},/* key3 */{irq_eint0, s3c2410_gpfcon, 0, s3c2410_extint0, 1, null, "key4", 0},/* key4 */}; # define key_timer_delay1 (Hz/50) // press the button to shake down for a delay of 20 milliseconds # define key_timer_delay2 (Hz/10) // press the button to lift the shake down Delay 100 MS # define key_count 4 unsigned int presscnt [4] = {0, 0, 0};/* define a work_queue array */struct work_struct gpio_key_work [4]; static struct workqueue_struct * key_wq [4] = {null, null}; static int get_gpio_portf_value (unsigned int pin); static void set_gpio_as_gpio (void ); static void set_gpio_as_gpio (void); static void set_gpio_as_eint (void); # If 1 static void gpio_key_wq_handler (struct work_struc T * work); static void gpio_key_wq_handler (struct work_struct * Work) {int I = 0; int ret; unsigned int pin;/* ms after interruption, execute this function */printk ("I am at [% s] [% d] \ n", _ FUNCTION __, _ line _); msleep (100 ); /* set the pin by eintx to gpio */set_gpio_as_gpio (); for (I = 0; I <array_size (key_gpio_res); I ++) {pin = key_gpio_res [I]. gpfpin;/* read the gpio value of the corresponding PIN. If 0 is returned, the key is actually pressed, and 1 is returned, indicating jitter */ret = get_gpio_portf_value (PIN); If (0 = RET) {presscnt [I] ++; Printk ("key0 pressed: presscnt [% d]: % d \ n", I, presscnt [I]);} /* set the pin back to eintx */set_gpio_as_eint (); return;} # elsestatic void handle (struct work_struct * work); static void gpio_key_wq1_handler (struct work_struct * work ); static void gpio_key_wq2_handler (struct work_struct * work); static void worker (struct work_struct * work);/* defines a function pointer array to process the preceding four work_queue */INT (* gpio_key_wq_h Andler [4]) (struct work_struct * Work) = {struct, gpio_key_wq1_handler, gpio_key_wq2_handler, handler,}; static void trim (struct work_struct * Work) {int ret; unsigned int pin; /* this function is triggered ms after interruption. Execute this function */printk ("I am at [% s] [% d] \ n", _ FUNCTION __, _ line _); msleep (100); pin = key_gpio_res [0]. gpfpin;/* set the eintx pin to gpio */set_gpio_as_gpio ();/* read the gpio value of the corresponding PIN. If 0 is returned, the key is actually pressed and the return value is 1 indicates jitter */ret = get_gpio_portf_value (PIN); If (0 = RET) {presscnt [0] ++; printk ("key0 pressed: presscnt [0]: % d \ n ", presscnt [0]);}/* set the pin back to eintx */set_gpio_as_eint (); return;} static void gpio_key_wq1_handler (struct work_struct * Work) {int ret; unsigned int pin;/* will be triggered ms after interruption. Execute this function */printk ("I am at [% s] [% d] \ n ", _ FUNCTION __, _ line _); msleep (100); pin = key_gpio_res [1]. gpfpin;/* set the eintx pin to gpio */set_gpio_a S_gpio ();/* read the gpio value of the corresponding PIN. If 0 is returned, the key is actually pressed. If 1 is returned, the jitter is indicated. */ret = get_gpio_portf_value (PIN ); if (0 = RET) {presscnt [1] ++; printk ("key1 pressed: presscnt [1]: % d \ n", presscnt [1]);} /* set the pin back to eintx */set_gpio_as_eint (); return;} static void gpio_key_wq2_handler (struct work_struct * Work) {int ret; unsigned int pin; /* this function is triggered ms after interruption. Execute this function */printk ("I am at [% s] [% d] \ n", _ FUNCTION __, _ line _); msleep (100); pin = key_gpio_res [2]. Gpfpin;/* set the eintx pin to gpio */set_gpio_as_gpio ();/* read the gpio value of the corresponding PIN. If 0 is returned, the key is actually pressed, returns 1 to indicate jitter */ret = get_gpio_portf_value (PIN); If (0 = RET) {presscnt [2] ++; printk ("key2 pressed: presscnt [2]: % d \ n ", presscnt [2]);}/* set the pin back to eintx */set_gpio_as_eint (); return;} static void gpio_key_wq3_handler (struct work_struct * Work) {int ret; unsigned int pin;/* will be triggered ms after interruption. Execute this function */printk ("I am at [% s] [% d] \ n ", _ FUNCTION __, _ L INE _); msleep (100); pin = key_gpio_res [3]. gpfpin;/* set the eintx pin to gpio */set_gpio_as_gpio ();/* read the gpio value of the corresponding PIN. If 0 is returned, the key is actually pressed, returns 1 to indicate jitter */ret = get_gpio_portf_value (PIN); If (0 = RET) {presscnt [3] ++; printk ("key3 pressed: presscnt [3]: % d \ n ", presscnt [3]);}/* set the pin back to eintx */set_gpio_as_eint (); return;} # endifstatic int kobox_key_open (struct inode * inode, struct file * file) {return 0;} static int kobox_key_release (Str UCT inode * inode, struct file * file) {return 0;} static long kobox_key_ioctl (struct file * file, unsigned int cmd, unsigned long Arg) {return 0 ;} static int kobox_key_read (struct file * file, char _ User * buff, size_t count, loff_t * POS) {printk ("enter [% s] [% d] \ n ", _ FUNCTION __,__ line _); copy_to_user (buff, & presscnt [0], sizeof (presscnt); Return 0;}/* GPF related registers: gpfcon 0x56000050 R/W configures the pins of P Ort f 0x0gpfdat 0x56000054 R/W the data register for port f undef. gpfup 0x56000058 R/W pull-up disable register for port F 0x000k1: gpf1-eint1: gpf1 [3: 2] 00 = input01 = output 10 = Eint [1] 11 = reservedk2: gpf4-eint4: gpf4 [9: 8] 00 = input01 = output 10 = Eint [4] 11 = reservedk3: gpf2-eint2: gpf2 [5:4] 00 = input01 = output 10 = eint2] 11 = reservedk4: gpf0-eint0: gpf0 [1:0] 00 = input01 = ou Tput 10 = Eint [0] 11 = reserved */static void set_gpio_as_eint (void) {int I; unsigned uival = 0; for (I = 0; I <array_size (key_gpio_res ); I ++) {uival = readl (key_gpio_res [I]. ctrlreg); uival & = ~ (0x01 <key_gpio_res [I]. ctrlbit); uival | = (0x01 <(key_gpio_res [I]. ctrlbit + 1); writel (uival, key_gpio_res [I]. ctrlreg);} return;} static void set_gpio_as_gpio (void) {int I; unsigned uival = 0; for (I = 0; I <array_size (key_gpio_res); I ++) {uival = readl (key_gpio_res [I]. ctrlreg); uival & = ~ (0x01 <key_gpio_res [I]. ctrlbit); uival & = ~ (0x01 <(key_gpio_res [I]. ctrlbit + 1); writel (uival, key_gpio_res [I]. ctrlreg);} return;} static irqreturn_t kobox_gpio_irq_handle (int irq, void * dev_id) {int key; // disable_irq_nosync (IRQ); printk ("IRQ = % d \ n ", IRQ); If (dev_id) printk ("dev_id: % s \ n", dev_id); Switch (IRQ) {Case irq_eint1: Key = 0; break; Case irq_eint4: key = 1; break; Case irq_eint2: Key = 2; break; Case irq_eint0: Key = 3; break; default: printk ("inval Id IRQ: % d \ n ", IRQ); Return irq_handled;}/* deshake: after a delay of MS, read the key status in buttons_timer. If the key status is still pressed, it indicates that timer is used for normal press, and then the Kernel shared queue is used for processing in the working queue and tasklet, delayed scheduling * // schedule_delayed_work (& gpio_key_work [Key], key_timer_delay2); // oops/* use the Kernel shared queue for immediate scheduling, delay in the interrupt function */schedule_work (& gpio_key_work [Key]); // normal execution/* use a separate queue for delayed scheduling * // queue_delayed_work (& key_wq [Key], & gpio_key_work [Key], key_timer_delay2); // also collapsed! /* Use the Kernel shared queue to schedule the task immediately and put the delay in the interrupt function * // queue_work (& key_wq [Key], & gpio_key_work [Key]); // also collapsed! Return irq_retval (irq_handled);}/* GPF related registers: gpfcon 0x56000050 R/W configures the pins of port F 0x0gpfdat 0x56000054 R/W the data register for port f undef. gpfup 0x56000058 R/W pull-up disable register for port F 0x000k1: gpf1-eint1: gpf1 [3: 2] 00 = input01 = output 10 = Eint [1] 11 = reservedk2: gpf4-eint4: gpf4 [] 00 = input01 = output 10 = Eint [4] 11 = reservedk3: gpf2-eint2: gpf2 [] 00 = Input01 = output 10 = eint2] 11 = reservedk4: gpf0-eint0: gpf0 [1:0] 00 = input01 = output 10 = Eint [0] 11 = reserved * // * If this function returns 0, the key is pressed. If the return value is not 0, the key is not pressed again, this function returns 0, indicating that a key is pressed, and a non-0 value indicates jitter */static int get_gpio_portf_value (unsigned int pin) {int ret; unsigned int uival = 0; printk ("I am @ [% s] [% d], pin: % d \ n", _ FUNCTION __, __line __, pin); uival = readl (s3c2410_gpfdat); ret = (0x1 <pin) & uival; Printk ("I am @ [% s] [% d], RET: % d \ n", _ FUNCTION __,__ line __, RET); return ret ;} static int request_irq_for_gpio (void) {int I; int ret; unsigned uival; int nouse; for (I = 0; I <array_size (key_gpio_res); I ++) {/* set the interrupt trigger mode: The Descent edge is valid and the interrupt is triggered to determine whether to press */uival = readl (key_gpio_res [I] based on the gpio value. trigreg); uival | = (0x1 <(key_gpio_res [I]. trigbit); uival & = ~ (0x1 <(key_gpio_res [I]. trigbit + 1); writel (uival, key_gpio_res [I]. trigreg);/* Registration interrupted */ret = request_irq (key_gpio_res [I]. irqnum, kobox_gpio_irq_handle, key_gpio_res [I]. irqflag, key_gpio_res [I]. irqname, (void *) key_gpio_res [I]. irqname); If (RET) printk ("[FUNC: % s] [line: % d] request_irq failed, RET: % d! \ N ", _ FUNCTION __,__ line __, RET); elseprintk (" [FUNC: % s] [line: % d] request_irq OK, IRQ: % d! \ N ", _ FUNCTION __,__ line __, key_gpio_res [I]. irqnum); key_wq [I] = create_workqueue (key_gpio_res [I]. irqname); If (! Key_wq [I]) {printk ("create_workqueue key_wq [% d] failed! \ N ", I) ;}# if 1/* initializes the work queue, used to respond to the second half of the interrupt, ms of scheduling after interruption response for dejitters */init_work (& gpio_key_work [I], gpio_key_wq_handler); # else/* initializes the work queue, which is used to respond to the second half of the interruption, ms after the response is interrupted for jitters */init_work (& gpio_key_work [I], gpio_key_wq_handler [I]); # endif} return 0;} struct file_operations kobox_key_operations = {. owner = this_module ,. open = kobox_key_open ,. read = kobox_key_read ,. release = kobox_key_release ,. unlocked_ioctl = kobox_key_ioctl ,};/ /Gpb0int Major; int minor; struct cdev; struct class * kobox_key_class; struct device * pstdev = NULL; # define gpio_key_name "kobox_key" int _ init key_drv_init (void) {int error; dev_t dev; printk ("##### enter key_drv_init! \ N "); major = register_chrdev (0, gpio_key_name, & kobox_key_operations); If (Major <0) {printk (" can't register major number \ n "); return Major;}/* Create class */kobox_key_class = class_create (this_module, gpio_key_name); If (is_err (kobox_key_class) {printk ("class_create failed! \ N "); goto fail;}/* Create/dev/kobox_gpio */pstdev = device_create (kobox_key_class, null, mkdev (Major, 0), null, gpio_key_name ); if (! Pstdev) {printk ("device_create failed! \ N "); goto fail1;}/* Set gpf0/1/2/4 as extern interrupt pins */set_gpio_as_eint (); request_irq_for_gpio (); printk ("##### key_drv_init OK! \ N "); Return 0; fail1: class_destroy (kobox_key_class); fail: unregister_chrdev (Major, gpio_key_name); Return-1;} void _ exit key_drv_exit (void) {printk ("Exit gpio DRV! \ N "); device_destroy (kobox_key_class, mkdev (Major, 0); class_destroy (TRIM); trim (Major, gpio_key_name); return;} module_init (key_drv_init ); module_exit (key_drv_exit); module_license ("GPL ");


Kobox: key_wq.c-V2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.