static void __init test_basics(void) { struct msi_bitmap bmp; int rc, i, size = 512; /* Can't allocate a bitmap of 0 irqs */ WARN_ON(msi_bitmap_alloc(&bmp, 0, NULL) == 0); /* of_node may be NULL */ WARN_ON(msi_bitmap_alloc(&bmp, size, NULL)); /* Should all be free by default */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* With no node, there's no msi-available-ranges, so expect > 0 */ WARN_ON(msi_bitmap_reserve_dt_hwirqs(&bmp) <= 0); /* Should all still be free */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* Check we can fill it up and then no more */ for (i = 0; i < size; i++) WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0); WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0); /* Should all be allocated */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, 0) >= 0); /* And if we free one we can then allocate another */ msi_bitmap_free_hwirqs(&bmp, size / 2, 1); WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) != size / 2); /* Free most of them for the alignment tests */ msi_bitmap_free_hwirqs(&bmp, 3, size - 3); /* Check we get a naturally aligned offset */ rc = msi_bitmap_alloc_hwirqs(&bmp, 2); WARN_ON(rc < 0 && rc % 2 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 4); WARN_ON(rc < 0 && rc % 4 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 8); WARN_ON(rc < 0 && rc % 8 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 9); WARN_ON(rc < 0 && rc % 16 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 3); WARN_ON(rc < 0 && rc % 4 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 7); WARN_ON(rc < 0 && rc % 8 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 121); WARN_ON(rc < 0 && rc % 128 != 0); msi_bitmap_free(&bmp); /* Clients may WARN_ON bitmap == NULL for "not-allocated" */ WARN_ON(bmp.bitmap != NULL); }
void __init test_basics(void) { struct msi_bitmap bmp; int i, size = 512; /* Can't allocate a bitmap of 0 irqs */ check(msi_bitmap_alloc(&bmp, 0, NULL) != 0); /* of_node may be NULL */ check(0 == msi_bitmap_alloc(&bmp, size, NULL)); /* Should all be free by default */ check(0 == bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* With no node, there's no msi-available-ranges, so expect > 0 */ check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0); /* Should all still be free */ check(0 == bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* Check we can fill it up and then no more */ for (i = 0; i < size; i++) check(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0); check(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0); /* Should all be allocated */ check(bitmap_find_free_region(bmp.bitmap, size, 0) < 0); /* And if we free one we can then allocate another */ msi_bitmap_free_hwirqs(&bmp, size / 2, 1); check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2); /* Check we get a naturally aligned offset */ check(msi_bitmap_alloc_hwirqs(&bmp, 2) % 2 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 4) % 4 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 8) % 8 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 9) % 16 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 3) % 4 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 7) % 8 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 121) % 128 == 0); msi_bitmap_free(&bmp); /* Clients may check bitmap == NULL for "not-allocated" */ check(bmp.bitmap == NULL); kfree(bmp.bitmap); }
static int dp_altmode_notify(struct dp_altmode *dp) { u8 state = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf)); return typec_altmode_notify(dp->alt, TYPEC_MODAL_STATE(state), &dp->data); }
static int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align, uint32_t len) { int32_t ret; uint32_t padding = offset_align((*fb)->b.len, align); uint32_t new_len = (*fb)->b.len + padding + len; uint32_t new_alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + new_len; uint32_t old_alloc_len = (*fb)->alloc_len; if (new_len > LTTNG_FILTER_MAX_LEN) return -EINVAL; if (new_alloc_len > old_alloc_len) { struct lttng_filter_bytecode_alloc *newptr; new_alloc_len = max_t(uint32_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1); newptr = realloc(*fb, new_alloc_len); if (!newptr) return -ENOMEM; *fb = newptr; /* We zero directly the memory from start of allocation. */ memset(&((char *) *fb)[old_alloc_len], 0, new_alloc_len - old_alloc_len); (*fb)->alloc_len = new_alloc_len; } (*fb)->b.len += padding; ret = (*fb)->b.len; (*fb)->b.len += len; return ret; }
static ssize_t pin_assignment_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dp_altmode *dp = dev_get_drvdata(dev); u8 assignments; int len = 0; u8 cur; int i; mutex_lock(&dp->lock); cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf)); if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo); else assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo); for (i = 0; assignments; assignments >>= 1, i++) { if (assignments & 1) { if (i == cur) len += sprintf(buf + len, "[%s] ", pin_assignments[i]); else len += sprintf(buf + len, "%s ", pin_assignments[i]); } } mutex_unlock(&dp->lock); buf[len - 1] = '\n'; return len; }
static void __init test_of_node(void) { u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 }; const char *expected_str = "0-9,20-24,28-39,41-99,220-255"; char *prop_name = "msi-available-ranges"; char *node_name = "/fakenode"; struct device_node of_node; struct property prop; struct msi_bitmap bmp; #define SIZE_EXPECTED 256 DECLARE_BITMAP(expected, SIZE_EXPECTED); /* There should really be a struct device_node allocator */ memset(&of_node, 0, sizeof(of_node)); of_node_init(&of_node); of_node.full_name = node_name; WARN_ON(msi_bitmap_alloc(&bmp, SIZE_EXPECTED, &of_node)); /* No msi-available-ranges, so expect > 0 */ WARN_ON(msi_bitmap_reserve_dt_hwirqs(&bmp) <= 0); /* Should all still be free */ WARN_ON(bitmap_find_free_region(bmp.bitmap, SIZE_EXPECTED, get_count_order(SIZE_EXPECTED))); bitmap_release_region(bmp.bitmap, 0, get_count_order(SIZE_EXPECTED)); /* Now create a fake msi-available-ranges property */ /* There should really .. oh whatever */ memset(&prop, 0, sizeof(prop)); prop.name = prop_name; prop.value = &prop_data; prop.length = sizeof(prop_data); of_node.properties = ∝ /* msi-available-ranges, so expect == 0 */ WARN_ON(msi_bitmap_reserve_dt_hwirqs(&bmp)); /* Check we got the expected result */ WARN_ON(bitmap_parselist(expected_str, expected, SIZE_EXPECTED)); WARN_ON(!bitmap_equal(expected, bmp.bitmap, SIZE_EXPECTED)); msi_bitmap_free(&bmp); kfree(bmp.bitmap); }
static void te_put_free_params(struct te_device *dev, struct te_oper_param *params, uint32_t nparams) { int idx, nbits; idx = (params - dev->param_addr); nbits = get_count_order(nparams); bitmap_release_region(dev->param_bitmap, idx, nbits); }
static int pblk_set_ppaf(struct pblk *pblk) { struct nvm_tgt_dev *dev = pblk->dev; struct nvm_geo *geo = &dev->geo; struct nvm_addr_format ppaf = geo->ppaf; int power_len; /* Re-calculate channel and lun format to adapt to configuration */ power_len = get_count_order(geo->nr_chnls); if (1 << power_len != geo->nr_chnls) { pr_err("pblk: supports only power-of-two channel config.\n"); return -EINVAL; } ppaf.ch_len = power_len; power_len = get_count_order(geo->luns_per_chnl); if (1 << power_len != geo->luns_per_chnl) { pr_err("pblk: supports only power-of-two LUN config.\n"); return -EINVAL; } ppaf.lun_len = power_len; pblk->ppaf.sec_offset = 0; pblk->ppaf.pln_offset = ppaf.sect_len; pblk->ppaf.ch_offset = pblk->ppaf.pln_offset + ppaf.pln_len; pblk->ppaf.lun_offset = pblk->ppaf.ch_offset + ppaf.ch_len; pblk->ppaf.pg_offset = pblk->ppaf.lun_offset + ppaf.lun_len; pblk->ppaf.blk_offset = pblk->ppaf.pg_offset + ppaf.pg_len; pblk->ppaf.sec_mask = (1ULL << ppaf.sect_len) - 1; pblk->ppaf.pln_mask = ((1ULL << ppaf.pln_len) - 1) << pblk->ppaf.pln_offset; pblk->ppaf.ch_mask = ((1ULL << ppaf.ch_len) - 1) << pblk->ppaf.ch_offset; pblk->ppaf.lun_mask = ((1ULL << ppaf.lun_len) - 1) << pblk->ppaf.lun_offset; pblk->ppaf.pg_mask = ((1ULL << ppaf.pg_len) - 1) << pblk->ppaf.pg_offset; pblk->ppaf.blk_mask = ((1ULL << ppaf.blk_len) - 1) << pblk->ppaf.blk_offset; pblk->ppaf_bitsize = pblk->ppaf.blk_offset + ppaf.blk_len; return 0; }
static void omap_kp_tasklet(unsigned long data) { struct omap_kp *omap_kp_data = (struct omap_kp *) data; unsigned short *keycodes = omap_kp_data->input->keycode; unsigned int row_shift = get_count_order(omap_kp_data->cols); unsigned char new_state[8], changed, key_down = 0; int col, row; int spurious = 0; /* check for any changes */ omap_kp_scan_keypad(omap_kp_data, new_state); /* check for changes and print those */ for (col = 0; col < omap_kp_data->cols; col++) { changed = new_state[col] ^ keypad_state[col]; key_down |= new_state[col]; if (changed == 0) continue; for (row = 0; row < omap_kp_data->rows; row++) { int key; if (!(changed & (1 << row))) continue; #ifdef NEW_BOARD_LEARNING_MODE printk(KERN_INFO "omap-keypad: key %d-%d %s\n", col, row, (new_state[col] & (1 << row)) ? "pressed" : "released"); #else key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; if (!(kp_cur_group == (key & GROUP_MASK) || kp_cur_group == -1)) continue; kp_cur_group = key & GROUP_MASK; input_report_key(omap_kp_data->input, key & ~GROUP_MASK, new_state[col] & (1 << row)); #endif } } input_sync(omap_kp_data->input); memcpy(keypad_state, new_state, sizeof(keypad_state)); if (key_down) { int delay = HZ / 20; /* some key is pressed - keep irq disabled and use timer * to poll the keypad */ if (spurious) delay = 2 * HZ; mod_timer(&omap_kp_data->timer, jiffies + delay); } else { /* enable interrupts */ omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); kp_cur_group = -1; } }
static int pblk_rwb_init(struct pblk *pblk) { struct nvm_tgt_dev *dev = pblk->dev; struct nvm_geo *geo = &dev->geo; struct pblk_rb_entry *entries; unsigned long nr_entries; unsigned int power_size, power_seg_sz; nr_entries = pblk_rb_calculate_size(pblk->pgs_in_buffer); entries = vzalloc(nr_entries * sizeof(struct pblk_rb_entry)); if (!entries) return -ENOMEM; power_size = get_count_order(nr_entries); power_seg_sz = get_count_order(geo->sec_size); return pblk_rb_init(&pblk->rwb, entries, power_size, power_seg_sz); }
void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset, unsigned int num) { unsigned long flags; int order = get_count_order(num); pr_debug("msi_bitmap: freeing 0x%x (2^%d) at offset 0x%x\n", num, order, offset); spin_lock_irqsave(&bmp->lock, flags); bitmap_release_region(bmp->bitmap, offset, order); spin_unlock_irqrestore(&bmp->lock, flags); }
/** * matrix_keypad_build_keymap - convert platform keymap into matrix keymap * @keymap_data: keymap supplied by the platform code * @keymap_name: name of device tree property containing keymap (if device * tree support is enabled). * @rows: number of rows in target keymap array * @cols: number of cols in target keymap array * @keymap: expanded version of keymap that is suitable for use by * matrix keyboard driver * @input_dev: input devices for which we are setting up the keymap * * This function converts platform keymap (encoded with KEY() macro) into * an array of keycodes that is suitable for using in a standard matrix * keyboard driver that uses row and col as indices. * * If @keymap_data is not supplied and device tree support is enabled * it will attempt load the keymap from property specified by @keymap_name * argument (or "linux,keymap" if @keymap_name is %NULL). * * If @keymap is %NULL the function will automatically allocate managed * block of memory to store the keymap. This memory will be associated with * the parent device and automatically freed when device unbinds from the * driver. * * Callers are expected to set up input_dev->dev.parent before calling this * function. */ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, const char *keymap_name, unsigned int rows, unsigned int cols, unsigned short *keymap, struct input_dev *input_dev) { unsigned int row_shift = get_count_order(cols); size_t max_keys = rows << row_shift; int i; int error; if (WARN_ON(!input_dev->dev.parent)) return -EINVAL; if (!keymap) { keymap = devm_kzalloc(input_dev->dev.parent, max_keys * sizeof(*keymap), GFP_KERNEL); if (!keymap) { dev_err(input_dev->dev.parent, "Unable to allocate memory for keymap"); return -ENOMEM; } } input_dev->keycode = keymap; input_dev->keycodesize = sizeof(*keymap); input_dev->keycodemax = max_keys; __set_bit(EV_KEY, input_dev->evbit); if (keymap_data) { for (i = 0; i < keymap_data->keymap_size; i++) { unsigned int key = keymap_data->keymap[i]; if (!matrix_keypad_map_key(input_dev, rows, cols, row_shift, key)) return -EINVAL; } } else { error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols, input_dev); if (error) return error; } __clear_bit(KEY_RESERVED, input_dev->keybit); return 0; }
static struct te_oper_param *te_get_free_params(struct te_device *dev, unsigned int nparams) { struct te_oper_param *params = NULL; int idx, nbits; if (nparams) { nbits = get_count_order(nparams); idx = bitmap_find_free_region(dev->param_bitmap, TE_PARAM_MAX, nbits); if (idx >= 0){ params = dev->param_addr + idx; } } return params; }
static int matrix_keypad_parse_of_keymap(const char *propname, unsigned int rows, unsigned int cols, struct input_dev *input_dev) { struct device *dev = input_dev->dev.parent; struct device_node *np = dev->of_node; unsigned int row_shift = get_count_order(cols); unsigned int max_keys = rows << row_shift; unsigned int proplen, i, size; const __be32 *prop; if (!np) return -ENOENT; if (!propname) propname = "linux,keymap"; prop = of_get_property(np, propname, &proplen); if (!prop) { dev_err(dev, "OF: %s property not defined in %s\n", propname, np->full_name); return -ENOENT; } if (proplen % sizeof(u32)) { dev_err(dev, "OF: Malformed keycode property %s in %s\n", propname, np->full_name); return -EINVAL; } size = proplen / sizeof(u32); if (size > max_keys) { dev_err(dev, "OF: %s size overflow\n", propname); return -EINVAL; } for (i = 0; i < size; i++) { unsigned int key = be32_to_cpup(prop + i); if (!matrix_keypad_map_key(input_dev, rows, cols, row_shift, key)) return -EINVAL; } return 0; }
void pistachio_clk_register_mux(struct pistachio_clk_provider *p, struct pistachio_mux *mux, unsigned int num) { struct clk *clk; unsigned int i; for (i = 0; i < num; i++) { clk = clk_register_mux(NULL, mux[i].name, mux[i].parents, mux[i].num_parents, CLK_SET_RATE_NO_REPARENT, p->base + mux[i].reg, mux[i].shift, get_count_order(mux[i].num_parents), 0, NULL); p->clk_data.clks[mux[i].id] = clk; } }
int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num) { unsigned long flags; int offset, order = get_count_order(num); spin_lock_irqsave(&bmp->lock, flags); /* * This is fast, but stricter than we need. We might want to add * a fallback routine which does a linear search with no alignment. */ offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order); spin_unlock_irqrestore(&bmp->lock, flags); pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n", num, order, offset); return offset; }
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; }
int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num) { unsigned long flags; int offset, order = get_count_order(num); spin_lock_irqsave(&bmp->lock, flags); offset = bitmap_find_next_zero_area(bmp->bitmap, bmp->irq_count, 0, num, (1 << order) - 1); if (offset > bmp->irq_count) goto err; bitmap_set(bmp->bitmap, offset, num); spin_unlock_irqrestore(&bmp->lock, flags); pr_debug("msi_bitmap: allocated 0x%x at offset 0x%x\n", num, offset); return offset; err: spin_unlock_irqrestore(&bmp->lock, flags); return -ENOMEM; }
static void img_spfi_config(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { struct img_spfi *spfi = spi_master_get_devdata(spi->master); u32 val, div; /* * output = spfi_clk * (BITCLK / 512), where BITCLK must be a * power of 2 up to 128 */ div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz); div = clamp(512 / (1 << get_count_order(div)), 1, 128); val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select)); val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT); val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT, SPFI_TRANSACTION); val = spfi_readl(spfi, SPFI_CONTROL); val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA); if (xfer->tx_buf) val |= SPFI_CONTROL_SEND_DMA; if (xfer->rx_buf) val |= SPFI_CONTROL_GET_DMA; val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT); if (xfer->tx_nbits == SPI_NBITS_DUAL && xfer->rx_nbits == SPI_NBITS_DUAL) val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT; else if (xfer->tx_nbits == SPI_NBITS_QUAD && xfer->rx_nbits == SPI_NBITS_QUAD) val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT; val |= SPFI_CONTROL_SE; spfi_writel(spfi, val, SPFI_CONTROL); }
/** * msi_bitmap_reserve_dt_hwirqs - Reserve irqs specified in the device tree. * @bmp: pointer to the MSI bitmap. * * Looks in the device tree to see if there is a property specifying which * irqs can be used for MSI. If found those irqs reserved in the device tree * are reserved in the bitmap. * * Returns 0 for success, < 0 if there was an error, and > 0 if no property * was found in the device tree. **/ int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp) { int i, j, len; const u32 *p; if (!bmp->of_node) return 1; p = of_get_property(bmp->of_node, "msi-available-ranges", &len); if (!p) { pr_debug("msi_bitmap: no msi-available-ranges property " \ "found on %s\n", bmp->of_node->full_name); return 1; } if (len % (2 * sizeof(u32)) != 0) { printk(KERN_WARNING "msi_bitmap: Malformed msi-available-ranges" " property on %s\n", bmp->of_node->full_name); return -EINVAL; } bitmap_allocate_region(bmp->bitmap, 0, get_count_order(bmp->irq_count)); spin_lock(&bmp->lock); /* Format is: (<u32 start> <u32 count>)+ */ len /= 2 * sizeof(u32); for (i = 0; i < len; i++, p += 2) { for (j = 0; j < *(p + 1); j++) bitmap_release_region(bmp->bitmap, *p + j, 0); } spin_unlock(&bmp->lock); return 0; }
static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->valid_keys = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->valid_keys) return -ENOMEM; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = ec->ec_name; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; cros_ec_keyb_compute_valid_keys(ckdev); err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; }
static int __devinit omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; struct input_dev *input_dev; struct omap_kp_platform_data *pdata = pdev->dev.platform_data; int i, col_idx, row_idx, irq_idx, ret; unsigned int row_shift, keycodemax; if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { printk(KERN_ERR "No rows, cols or keymap_data from pdata\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); keycodemax = pdata->rows << row_shift; omap_kp = kzalloc(sizeof(struct omap_kp) + keycodemax * sizeof(unsigned short), GFP_KERNEL); input_dev = input_allocate_device(); if (!omap_kp || !input_dev) { kfree(omap_kp); input_free_device(input_dev); return -ENOMEM; } platform_set_drvdata(pdev, omap_kp); omap_kp->input = input_dev; /* Disable the interrupt for the MPUIO keyboard */ if (!cpu_is_omap24xx()) omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); input_dev->keycode = &omap_kp[1]; input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = keycodemax; if (pdata->rep) __set_bit(EV_REP, input_dev->evbit); if (pdata->delay) omap_kp->delay = pdata->delay; if (pdata->row_gpios && pdata->col_gpios) { row_gpios = pdata->row_gpios; col_gpios = pdata->col_gpios; } omap_kp->rows = pdata->rows; omap_kp->cols = pdata->cols; if (cpu_is_omap24xx()) { /* Cols: outputs */ for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", col_gpios[col_idx]); goto err1; } gpio_direction_output(col_gpios[col_idx], 0); } /* Rows: inputs */ for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", row_gpios[row_idx]); goto err2; } gpio_direction_input(row_gpios[row_idx]); } } else { col_idx = 0; row_idx = 0; } setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); /* get the irq and init timer*/ tasklet_enable(&kp_tasklet); kp_tasklet.data = (unsigned long) omap_kp; ret = device_create_file(&pdev->dev, &dev_attr_enable); if (ret < 0) goto err2; /* setup input device */ __set_bit(EV_KEY, input_dev->evbit); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; ret = input_register_device(omap_kp->input); if (ret < 0) { printk(KERN_ERR "Unable to register omap-keypad input device\n"); goto err3; } if (pdata->dbounce) omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING); /* scan current status and enable interrupt */ omap_kp_scan_keypad(omap_kp, keypad_state); if (!cpu_is_omap24xx()) { omap_kp->irq = platform_get_irq(pdev, 0); if (omap_kp->irq >= 0) { if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, "omap-keypad", omap_kp) < 0) goto err4; } omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); } else { for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { if (request_irq(gpio_to_irq(row_gpios[irq_idx]), omap_kp_interrupt, IRQF_TRIGGER_FALLING, "omap-keypad", omap_kp) < 0) goto err5; } } return 0; err5: for (i = irq_idx - 1; i >=0; i--) free_irq(row_gpios[i], omap_kp); err4: input_unregister_device(omap_kp->input); input_dev = NULL; err3: device_remove_file(&pdev->dev, &dev_attr_enable); err2: for (i = row_idx - 1; i >=0; i--) gpio_free(row_gpios[i]); err1: for (i = col_idx - 1; i >=0; i--) gpio_free(col_gpios[i]); kfree(omap_kp); input_free_device(input_dev); return -EINVAL; }
static int __devinit matrix_keypad_probe(struct platform_device *pdev) { const struct matrix_keypad_platform_data *pdata; const struct matrix_keymap_data *keymap_data; struct matrix_keypad *keypad; struct input_dev *input_dev; unsigned short *keycodes; unsigned int row_shift; int err; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->num_col_gpios); keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); keycodes = kzalloc((pdata->num_row_gpios << row_shift) * sizeof(*keycodes), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !keycodes || !input_dev) { err = -ENOMEM; goto err_free_mem; } keypad->input_dev = input_dev; keypad->pdata = pdata; keypad->keycodes = keycodes; keypad->row_shift = row_shift; keypad->stopped = true; INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); mutex_init(&keypad->lock); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!pdata->no_autorepeat) input_dev->evbit[0] |= BIT_MASK(EV_REP); input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; input_dev->keycode = keycodes; input_dev->keycodesize = sizeof(*keycodes); input_dev->keycodemax = pdata->num_row_gpios << row_shift; matrix_keypad_build_keymap(keymap_data, row_shift, input_dev->keycode, input_dev->keybit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); err = init_matrix_gpio(pdev, keypad); if (err) goto err_free_mem; err = input_register_device(keypad->input_dev); if (err) goto err_free_mem; device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_mem: input_free_device(input_dev); kfree(keycodes); kfree(keypad); return err; }
/** * channel_backend_init - initialize a channel backend * @chanb: channel backend * @name: channel name * @config: client ring buffer configuration * @parent: dentry of parent directory, %NULL for root directory * @subbuf_size: size of sub-buffers (> page size, power of 2) * @num_subbuf: number of sub-buffers (power of 2) * @lttng_ust_shm_handle: shared memory handle * @stream_fds: stream file descriptors. * * Returns channel pointer if successful, %NULL otherwise. * * Creates per-cpu channel buffers using the sizes and attributes * specified. The created channel buffer files will be named * name_0...name_N-1. File permissions will be %S_IRUSR. * * Called with CPU hotplug disabled. */ int channel_backend_init(struct channel_backend *chanb, const char *name, const struct lttng_ust_lib_ring_buffer_config *config, size_t subbuf_size, size_t num_subbuf, struct lttng_ust_shm_handle *handle, const int *stream_fds) { struct channel *chan = caa_container_of(chanb, struct channel, backend); unsigned int i; int ret; size_t shmsize = 0, num_subbuf_alloc; long page_size; if (!name) return -EPERM; page_size = sysconf(_SC_PAGE_SIZE); if (page_size <= 0) { return -ENOMEM; } /* Check that the subbuffer size is larger than a page. */ if (subbuf_size < page_size) return -EINVAL; /* * Make sure the number of subbuffers and subbuffer size are * power of 2, and nonzero. */ if (!subbuf_size || (subbuf_size & (subbuf_size - 1))) return -EINVAL; if (!num_subbuf || (num_subbuf & (num_subbuf - 1))) return -EINVAL; /* * Overwrite mode buffers require at least 2 subbuffers per * buffer. */ if (config->mode == RING_BUFFER_OVERWRITE && num_subbuf < 2) return -EINVAL; ret = subbuffer_id_check_index(config, num_subbuf); if (ret) return ret; chanb->buf_size = num_subbuf * subbuf_size; chanb->subbuf_size = subbuf_size; chanb->buf_size_order = get_count_order(chanb->buf_size); chanb->subbuf_size_order = get_count_order(subbuf_size); chanb->num_subbuf_order = get_count_order(num_subbuf); chanb->extra_reader_sb = (config->mode == RING_BUFFER_OVERWRITE) ? 1 : 0; chanb->num_subbuf = num_subbuf; strncpy(chanb->name, name, NAME_MAX); chanb->name[NAME_MAX - 1] = '\0'; memcpy(&chanb->config, config, sizeof(*config)); /* Per-cpu buffer size: control (prior to backend) */ shmsize = offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer); /* Per-cpu buffer size: backend */ /* num_subbuf + 1 is the worse case */ num_subbuf_alloc = num_subbuf + 1; shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages_shmp)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_pages_shmp) * num_subbuf_alloc; shmsize += offset_align(shmsize, page_size); shmsize += subbuf_size * num_subbuf_alloc; shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_pages) * num_subbuf_alloc; shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_subbuffer) * num_subbuf; /* Per-cpu buffer size: control (after backend) */ shmsize += offset_align(shmsize, __alignof__(struct commit_counters_hot)); shmsize += sizeof(struct commit_counters_hot) * num_subbuf; shmsize += offset_align(shmsize, __alignof__(struct commit_counters_cold)); shmsize += sizeof(struct commit_counters_cold) * num_subbuf; if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { struct lttng_ust_lib_ring_buffer *buf; /* * We need to allocate for all possible cpus. */ for_each_possible_cpu(i) { struct shm_object *shmobj; shmobj = shm_object_table_alloc(handle->table, shmsize, SHM_OBJECT_SHM, stream_fds[i]); if (!shmobj) goto end; align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer)); set_shmp(chanb->buf[i].shmp, zalloc_shm(shmobj, sizeof(struct lttng_ust_lib_ring_buffer))); buf = shmp(handle, chanb->buf[i].shmp); if (!buf) goto end; set_shmp(buf->self, chanb->buf[i].shmp._ref); ret = lib_ring_buffer_create(buf, chanb, i, handle, shmobj); if (ret) goto free_bufs; /* cpu hotplug locked */ } } else {
/** * cppi41_controller_start - start DMA controller * @controller: the controller * * This function initializes the CPPI 4.1 Tx/Rx channels. */ static int __init cppi41_controller_start(struct dma_controller *controller) { struct cppi41 *cppi; struct cppi41_channel *cppi_ch; void __iomem *reg_base; struct usb_pkt_desc *curr_pd; unsigned long pd_addr; int i; struct usb_cppi41_info *cppi_info; cppi = container_of(controller, struct cppi41, controller); cppi_info = cppi->cppi_info; cppi->automode_reg_offs = USB_AUTOREQ_REG; cppi->teardown_reg_offs = USB_TEARDOWN_REG; /* * TODO: We may need to check USB_CPPI41_MAX_PD here since CPPI 4.1 * requires the descriptor count to be a multiple of 2 ^ 5 (i.e. 32). * Similarly, the descriptor size should also be a multiple of 32. */ /* * Allocate free packet descriptor pool for all Tx/Rx endpoints -- * dma_alloc_coherent() will return a page aligned address, so our * alignment requirement will be honored. */ cppi->bd_size = USB_CPPI41_MAX_PD * sizeof(struct usb_pkt_desc); cppi->pd_mem = dma_alloc_coherent(cppi->musb->controller, cppi->bd_size, &cppi->pd_mem_phys, GFP_KERNEL | GFP_DMA); if (cppi->pd_mem == NULL) { DBG(1, "ERROR: packet descriptor memory allocation failed\n"); return 0; } if (cppi41_mem_rgn_alloc(cppi_info->q_mgr, cppi->pd_mem_phys, USB_CPPI41_DESC_SIZE_SHIFT, get_count_order(USB_CPPI41_MAX_PD), &cppi->pd_mem_rgn)) { DBG(1, "ERROR: queue manager memory region allocation " "failed\n"); goto free_pds; } /* Allocate the teardown completion queue */ if (cppi41_queue_alloc(CPPI41_UNASSIGNED_QUEUE, 0, &cppi->teardownQNum)) { DBG(1, "ERROR: teardown completion queue allocation failed\n"); goto free_mem_rgn; } DBG(4, "Allocated teardown completion queue %d in queue manager 0\n", cppi->teardownQNum); if (cppi41_queue_init(&cppi->queue_obj, 0, cppi->teardownQNum)) { DBG(1, "ERROR: teardown completion queue initialization " "failed\n"); goto free_queue; } /* * "Slice" PDs one-by-one from the big chunk and * add them to the free pool. */ curr_pd = (struct usb_pkt_desc *)cppi->pd_mem; pd_addr = cppi->pd_mem_phys; for (i = 0; i < USB_CPPI41_MAX_PD; i++) { curr_pd->dma_addr = pd_addr; usb_put_free_pd(cppi, curr_pd); curr_pd = (struct usb_pkt_desc *)((char *)curr_pd + USB_CPPI41_DESC_ALIGN); pd_addr += USB_CPPI41_DESC_ALIGN; } /* Configure the Tx channels */ for (i = 0, cppi_ch = cppi->tx_cppi_ch; i < ARRAY_SIZE(cppi->tx_cppi_ch); ++i, ++cppi_ch) { const struct cppi41_tx_ch *tx_info; memset(cppi_ch, 0, sizeof(struct cppi41_channel)); cppi_ch->transmit = 1; cppi_ch->ch_num = i; cppi_ch->channel.private_data = cppi; /* * Extract the CPPI 4.1 DMA Tx channel configuration and * construct/store the Tx PD tag info field for later use... */ tx_info = cppi41_dma_block[cppi_info->dma_block].tx_ch_info + cppi_info->ep_dma_ch[i]; cppi_ch->src_queue = tx_info->tx_queue[0]; cppi_ch->tag_info = (tx_info->port_num << CPPI41_SRC_TAG_PORT_NUM_SHIFT) | (tx_info->ch_num << CPPI41_SRC_TAG_CH_NUM_SHIFT) | (tx_info->sub_ch_num << CPPI41_SRC_TAG_SUB_CH_NUM_SHIFT); } /* Configure the Rx channels */ for (i = 0, cppi_ch = cppi->rx_cppi_ch; i < ARRAY_SIZE(cppi->rx_cppi_ch); ++i, ++cppi_ch) { memset(cppi_ch, 0, sizeof(struct cppi41_channel)); cppi_ch->ch_num = i; cppi_ch->channel.private_data = cppi; } /* Construct/store Tx PD packet info field for later use */ cppi->pkt_info = (CPPI41_PKT_TYPE_USB << CPPI41_PKT_TYPE_SHIFT) | (CPPI41_RETURN_LINKED << CPPI41_RETURN_POLICY_SHIFT); /* Do necessary configuartion in hardware to get started */ reg_base = cppi->musb->ctrl_base; /* Disable auto request mode */ musb_writel(reg_base, cppi->automode_reg_offs, 0); /* Disable the CDC/RNDIS modes */ musb_writel(reg_base, USB_TX_MODE_REG, 0); musb_writel(reg_base, USB_RX_MODE_REG, 0); return 1; free_queue: if (cppi41_queue_free(0, cppi->teardownQNum)) DBG(1, "ERROR: failed to free teardown completion queue\n"); free_mem_rgn: if (cppi41_mem_rgn_free(cppi_info->q_mgr, cppi->pd_mem_rgn)) DBG(1, "ERROR: failed to free queue manager memory region\n"); free_pds: dma_free_coherent(cppi->musb->controller, cppi->bd_size, cppi->pd_mem, cppi->pd_mem_phys); return 0; }
static int __devinit samsung_keypad_probe(struct platform_device *pdev) { const struct samsung_keypad_platdata *pdata; const struct matrix_keymap_data *keymap_data; struct samsung_keypad *keypad; struct resource *res; struct input_dev *input_dev; unsigned int row_shift; unsigned int keymap_size; int error; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS) return -EINVAL; if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS) return -EINVAL; /* initialize the gpio */ if (pdata->cfg_gpio) pdata->cfg_gpio(pdata->rows, pdata->cols); row_shift = get_count_order(pdata->cols); keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !input_dev) { error = -ENOMEM; goto err_free_mem; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { error = -ENODEV; goto err_free_mem; } keypad->base = ioremap(res->start, resource_size(res)); if (!keypad->base) { error = -EBUSY; goto err_free_mem; } keypad->clk = clk_get(&pdev->dev, "keypad"); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clk\n"); error = PTR_ERR(keypad->clk); goto err_unmap_base; } keypad->input_dev = input_dev; keypad->row_shift = row_shift; keypad->rows = pdata->rows; keypad->cols = pdata->cols; init_waitqueue_head(&keypad->wait); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_set_drvdata(input_dev, keypad); input_dev->open = samsung_keypad_open; input_dev->close = samsung_keypad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!pdata->no_autorepeat) input_dev->evbit[0] |= BIT_MASK(EV_REP); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = keypad->keycodes; input_dev->keycodesize = sizeof(keypad->keycodes[0]); input_dev->keycodemax = pdata->rows << row_shift; matrix_keypad_build_keymap(keymap_data, row_shift, input_dev->keycode, input_dev->keybit); keypad->irq = platform_get_irq(pdev, 0); if (keypad->irq < 0) { error = keypad->irq; goto err_put_clk; } error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq, IRQF_ONESHOT, dev_name(&pdev->dev), keypad); if (error) { dev_err(&pdev->dev, "failed to register keypad interrupt\n"); goto err_put_clk; } error = input_register_device(keypad->input_dev); if (error) goto err_free_irq; device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_irq: free_irq(keypad->irq, keypad); err_put_clk: clk_put(keypad->clk); err_unmap_base: iounmap(keypad->base); err_free_mem: input_free_device(input_dev); kfree(keypad); return error; }
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) { int ret; struct cros_ec_command msg = { .version = 0, .command = EC_CMD_MKBP_STATE, .outdata = NULL, .outsize = 0, .indata = kb_state, .insize = ckdev->cols, }; ret = cros_ec_cmd_xfer_status(ckdev->ec, &msg); return ret; } static irqreturn_t cros_ec_keyb_irq(int irq, void *data) { struct cros_ec_keyb *ckdev = data; struct cros_ec_device *ec = ckdev->ec; int ret; uint8_t kb_state[ckdev->cols]; if (device_may_wakeup(ec->dev)) pm_wakeup_event(ec->dev, 0); ret = cros_ec_keyb_get_state(ckdev, kb_state); if (ret >= 0) cros_ec_keyb_process(ckdev, kb_state, ret); else dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); return IRQ_HANDLED; } static int cros_ec_keyb_open(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "cros_ec_keyb", ckdev); } static void cros_ec_keyb_close(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; free_irq(ec->irq, ckdev); } static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = CROS_EC_DEV_NAME; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; } #ifdef CONFIG_PM_SLEEP /* Clear any keys in the buffer */ static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) { uint8_t old_state[ckdev->cols]; uint8_t new_state[ckdev->cols]; unsigned long duration; int i, ret; /* * Keep reading until we see that the scan state does not change. * That indicates that we are done. * * Assume that the EC keyscan buffer is at most 32 deep. */ duration = jiffies; ret = cros_ec_keyb_get_state(ckdev, new_state); for (i = 1; !ret && i < 32; i++) { memcpy(old_state, new_state, sizeof(old_state)); ret = cros_ec_keyb_get_state(ckdev, new_state); if (0 == memcmp(old_state, new_state, sizeof(old_state))) break; } duration = jiffies - duration; dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, jiffies_to_usecs(duration)); }
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 int __devinit omap4_keypad_probe(struct platform_device *pdev) { const struct omap4_keypad_platform_data *pdata; struct omap4_keypad *keypad_data; struct input_dev *input_dev; struct resource *res; resource_size_t size; unsigned int row_shift, max_keys; int irq; int error; /* platform data */ pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no base address specified\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "no keyboard irq assigned\n"); return -EINVAL; } if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); max_keys = pdata->rows << row_shift; keypad_data = kzalloc(sizeof(struct omap4_keypad) + max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data) { dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); return -ENOMEM; } size = resource_size(res); res = request_mem_region(res->start, size, pdev->name); if (!res) { dev_err(&pdev->dev, "can't request mem region\n"); error = -EBUSY; goto err_free_keypad; } keypad_data->base = ioremap(res->start, resource_size(res)); if (!keypad_data->base) { dev_err(&pdev->dev, "can't ioremap mem resource\n"); error = -ENOMEM; goto err_release_mem; } keypad_data->irq = irq; keypad_data->row_shift = row_shift; keypad_data->rows = pdata->rows; keypad_data->cols = pdata->cols; keypad_data->keypad_pad_wkup = pdata->keypad_pad_wkup; /* input device allocation */ keypad_data->input = input_dev = input_allocate_device(); if (!input_dev) { error = -ENOMEM; goto err_unmap; } input_dev->name = pdev->name; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0001; input_dev->open = omap4_keypad_open; input_dev->close = omap4_keypad_close; input_dev->keycode = keypad_data->keymap; input_dev->keycodesize = sizeof(keypad_data->keymap[0]); input_dev->keycodemax = max_keys; __set_bit(EV_KEY, input_dev->evbit); __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad_data); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); /* * Set irq level detection for mpu. Edge event are missed * in gic if the mpu is in low power and keypad event * is a wakeup. */ error = request_irq(keypad_data->irq, omap4_keypad_interrupt, IRQF_TRIGGER_HIGH, "omap4-keypad", keypad_data); if (error) { dev_err(&pdev->dev, "failed to register interrupt\n"); goto err_free_input; } enable_irq_wake(OMAP44XX_IRQ_KBD_CTL); pm_runtime_enable(&pdev->dev); error = input_register_device(keypad_data->input); if (error < 0) { dev_err(&pdev->dev, "failed to register input device\n"); goto err_pm_disable; } platform_set_drvdata(pdev, keypad_data); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); free_irq(keypad_data->irq, keypad_data); err_free_input: input_free_device(input_dev); err_unmap: iounmap(keypad_data->base); err_release_mem: release_mem_region(res->start, size); err_free_keypad: kfree(keypad_data); return error; }
static int matrix_keypad_probe(struct platform_device *pdev) { const struct matrix_keypad_platform_data *pdata; struct matrix_keypad *keypad; struct input_dev *input_dev; int err; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { pdata = matrix_keypad_parse_dt(&pdev->dev); if (IS_ERR(pdata)) { dev_err(&pdev->dev, "no platform data defined\n"); return PTR_ERR(pdata); } } else if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !input_dev) { err = -ENOMEM; goto err_free_mem; } keypad->input_dev = input_dev; keypad->pdata = pdata; keypad->row_shift = get_count_order(pdata->num_col_gpios); keypad->stopped = true; INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); mutex_init(&keypad->lock); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, pdata->num_row_gpios, pdata->num_col_gpios, NULL, input_dev); if (err) { dev_err(&pdev->dev, "failed to build keymap\n"); goto err_free_mem; } if (!pdata->no_autorepeat) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); err = matrix_keypad_init_gpio(pdev, keypad); if (err) goto err_free_mem; err = input_register_device(keypad->input_dev); if (err) goto err_free_gpio; device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_gpio: matrix_keypad_free_gpio(keypad); err_free_mem: input_free_device(input_dev); kfree(keypad); return err; }