static int check_key_down(struct sci_keypad_t *sci_kpd, int key_status, int key_value) { int col, row, key; unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); if((key_status & 0xff) != 0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; if(key == key_value) return 1; } if((key_status & 0xff00) != 0) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; if(key == key_value) return 1; } return 0; }
static irqreturn_t sci_keypad_isr(int irq, void *dev_id) { unsigned short key = 0; unsigned long value; struct sci_keypad_t *sci_kpd = dev_id; unsigned long int_status = __raw_readl(KPD_INT_MASK_STATUS); unsigned long key_status = __raw_readl(KPD_KEY_STATUS); unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); int col, row; value = __raw_readl(KPD_INT_CLR); value |= KPD_INT_ALL; __raw_writel(value, KPD_INT_CLR); if ((int_status & KPD_PRESS_INT0)) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dD\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dU\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if ((int_status & KPD_PRESS_INT1)) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dD\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT1) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dU\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if ((int_status & KPD_PRESS_INT2)) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT2) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if (int_status & KPD_PRESS_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } return IRQ_HANDLED; }
static irqreturn_t sci_keypad_isr(int irq, void *dev_id) { unsigned short key = 0; unsigned long value; struct sci_keypad_t *sci_kpd = dev_id; unsigned long int_status = keypad_readl(KPD_INT_MASK_STATUS); unsigned long key_status = keypad_readl(KPD_KEY_STATUS); unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); int col, row; value = keypad_readl(KPD_INT_CLR); value |= KPD_INT_ALL; keypad_writel(KPD_INT_CLR, value); if ((int_status & KPD_PRESS_INT0)) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT1)) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT1) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT2)) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT2) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_PRESS_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } #ifdef CONFIG_MAGIC_SYSRQ { static unsigned long key_status_prev = 0; if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) && check_key_down(sci_kpd, key_status, SPRD_VOL_DOWN_KEY) && key_status != key_status_prev) { key_status_prev = key_status; panic("!!!! Combine key: vol_down + camera !!!!\n"); } if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) && check_key_down(sci_kpd, key_status, SPRD_VOL_UP_KEY) && key_status != key_status_prev) { unsigned long flags; static int rebooted = 0; key_status_prev = key_status; local_irq_save(flags); if (rebooted == 0) { rebooted = 1; pr_warn("!!!!!! Combine Key : vol_up + camera is Down !!!!!!\n"); /* handle_sysrq('t'); */ handle_sysrq('m'); handle_sysrq('w'); handle_sysrq('b'); pr_warn("!!!!!! /proc/sys/kernel/sysrq is disabled !!!!!!\n"); rebooted = 0; } local_irq_restore(flags); } } #endif return IRQ_HANDLED; }
static irqreturn_t sci_keypad_isr(int irq, void *dev_id) { unsigned short key = 0; unsigned long value; struct sci_keypad_t *sci_kpd = dev_id; unsigned long int_status = __raw_readl(KPD_INT_MASK_STATUS); unsigned long key_status = __raw_readl(KPD_KEY_STATUS); unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); int col, row; value = __raw_readl(KPD_INT_CLR); value |= KPD_INT_ALL; __raw_writel(value, KPD_INT_CLR); if ((int_status & KPD_PRESS_INT0)) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT1)) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT1) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT2)) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT2) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_PRESS_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } #ifdef CONFIG_MAGIC_SYSRQ { static unsigned long key_status_prev = 0; static unsigned long key_panic_check_times = 0; struct task_struct *g, *p; int i; if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) && check_key_down(sci_kpd, key_status, SPRD_VOL_DOWN_KEY) && key_status != key_status_prev) { if(!key_panic_check_times) { printk("!!!! Combine key: vol_down + camera !!!! first dump important task\n"); printk("current\n"); printk("PID %d is %s\n",task_pid_nr(current),current->comm); show_stack(current,NULL); do_each_thread(g, p) { for(i=0; i<(sizeof(tasks)/sizeof(tasks[0])); i++) { if (!strncmp(p->comm,tasks[i].name,tasks[i].name_len)) { printk("PID %d is %s\n",task_pid_nr(p),p->comm); show_stack(p, NULL); } } } while_each_thread(g, p); } else { } key_panic_check_times++; }