/** This is here because all those casts made for some ugly code. It doesn't * exist in newer driver versions. */ static void u8_or(u8 *dest, u8 *target1, u8 *target2, int nbits) { bitmap_or((long unsigned int *) dest, (long unsigned int *) target1, (long unsigned int *) target2, nbits); }
static unsigned int matrix_alloc_area(struct irq_matrix *m, struct cpumap *cm, unsigned int num, bool managed) { unsigned int area, start = m->alloc_start; unsigned int end = m->alloc_end; bitmap_or(m->scratch_map, cm->managed_map, m->system_map, end); bitmap_or(m->scratch_map, m->scratch_map, cm->alloc_map, end); area = bitmap_find_next_zero_area(m->scratch_map, end, start, num, 0); if (area >= end) return area; if (managed) bitmap_set(cm->managed_map, area, num); else bitmap_set(cm->alloc_map, area, num); return area; }
/* For each queue, from the most- to least-constrained: * find an LSB that can be assigned to the queue. If there are N queues that * can only use M LSBs, where N > M, fail; otherwise, every queue will get a * dedicated LSB. Remaining LSB regions become a shared resource. * If we have fewer LSBs than queues, all LSB regions become shared resources. */ static int ccp_assign_lsbs(struct ccp_device *ccp) { DECLARE_BITMAP(lsb_pub, MAX_LSB_CNT); DECLARE_BITMAP(qlsb, MAX_LSB_CNT); int n_lsbs = 0; int bitno; int i, lsb_cnt; int rc = 0; bitmap_zero(lsb_pub, MAX_LSB_CNT); /* Create an aggregate bitmap to get a total count of available LSBs */ for (i = 0; i < ccp->cmd_q_count; i++) bitmap_or(lsb_pub, lsb_pub, ccp->cmd_q[i].lsbmask, MAX_LSB_CNT); n_lsbs = bitmap_weight(lsb_pub, MAX_LSB_CNT); if (n_lsbs >= ccp->cmd_q_count) { /* We have enough LSBS to give every queue a private LSB. * Brute force search to start with the queues that are more * constrained in LSB choice. When an LSB is privately * assigned, it is removed from the public mask. * This is an ugly N squared algorithm with some optimization. */ for (lsb_cnt = 1; n_lsbs && (lsb_cnt <= MAX_LSB_CNT); lsb_cnt++) { rc = ccp_find_and_assign_lsb_to_q(ccp, lsb_cnt, n_lsbs, lsb_pub); if (rc < 0) return -EINVAL; n_lsbs = rc; } } rc = 0; /* What's left of the LSBs, according to the public mask, now become * shared. Any zero bits in the lsb_pub mask represent an LSB region * that can't be used as a shared resource, so mark the LSB slots for * them as "in use". */ bitmap_copy(qlsb, lsb_pub, MAX_LSB_CNT); bitno = find_first_zero_bit(qlsb, MAX_LSB_CNT); while (bitno < MAX_LSB_CNT) { bitmap_set(ccp->lsbmap, bitno * LSB_SIZE, LSB_SIZE); bitmap_set(qlsb, bitno, 1); bitno = find_first_zero_bit(qlsb, MAX_LSB_CNT); } return rc; }
void input_key_get_status(unsigned long *keys, int bits) { struct input_device *idev; bitmap_zero(keys, bits); if (bits > KEY_MAX) bits = KEY_MAX; list_for_each_entry(idev, &input_devices, list) bitmap_or(keys, keys, idev->keys, bits); }
static void set_feature_group(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { S390FeatGroup group = (S390FeatGroup) opaque; const S390FeatGroupDef *def = s390_feat_group_def(group); DeviceState *dev = DEVICE(obj); S390CPU *cpu = S390_CPU(obj); bool value; if (dev->realized) { error_setg(errp, "Attempt to set property '%s' on '%s' after " "it was realized", name, object_get_typename(obj)); return; } else if (!cpu->model) { error_setg(errp, "Details about the host CPU model are not available, " "features cannot be changed."); return; } visit_type_bool(v, name, &value, errp); if (*errp) { return; } if (value) { /* groups are added in one shot, so an intersect is sufficient */ if (!bitmap_intersects(def->feat, cpu->model->def->full_feat, S390_FEAT_MAX)) { error_setg(errp, "Group '%s' is not available for CPU model '%s'," " it was introduced with later models.", name, cpu->model->def->name); return; } bitmap_or(cpu->model->features, cpu->model->features, def->feat, S390_FEAT_MAX); } else { bitmap_andnot(cpu->model->features, cpu->model->features, def->feat, S390_FEAT_MAX); } }
int tricam_process(int argc, char *argv[]) { int i, j, w, h, bpp; bytemap_t *up_image, *mid_image, *dn_image; bytemap_t *gray, *se; bitmap_t *up_roi, *mid_roi, *dn_roi; bitmap_t *bin, *roi, *tmp; char *fn, *ptr; real_t value; FILE *fd; label_info_t *label_info; dwordmap_t *labelmap; point_t *centroid; int label, area; uint8_t vmin, vmax; real_t vmean; bytemap_t *op1, *op2, *op3; char *path; int next_option; char *token1, *token2, *token3; real_t cutup = -2550000, cutdown = -4748; program_name = argv[0]; do { next_option = getopt_long(argc, argv, short_options, long_options, NULL); switch (next_option) { case 'h': print_usage(stdout, 0); break; case 'o': token1 = strdup(optarg); break; case 's': token2 = strdup(optarg); break; case 'd': token3 = strdup(optarg); break; case 'f': cutup = strtod(optarg, NULL); break; case 't': cutdown = strtod(optarg, NULL); break; case 'v': verbose = 1; break; case 'n': path = strdup(optarg); break; case '?': print_usage(stderr, 1); break; case -1: break; default: abort(); } } while (next_option != -1); // printf("(%s - %s) / %s, %lf, %lf, %s\n", token1, token2, token3, cutup, cutdown, path); w = WIDTH; h = HEIGHT; bpp = BPP; initialize_screen(w, h, bpp); up_image = bytemap_new(w, h); mid_image = bytemap_new(w, h); dn_image = bytemap_new(w, h); gray = bytemap_new(w, h); up_roi = bitmap_new(w, h); mid_roi = bitmap_new(w, h); dn_roi = bitmap_new(w, h); bin = bitmap_new(w, h); tmp = bitmap_new(w, h); roi = bitmap_new(w, h); se = bytemap_new(3, 3); bytemap_fill(se, 0, 0, 3, 3, 1); labelmap = dwordmap_new(w, h); path = (char *)malloc(256 * sizeof(char)); // Up display image //////////////////// strcpy(path, argv[1]); strcat(path, "_up.bmp"); fn = strrchr(path, '/') + 1; printf("Filename: %s\n", fn); printf("Display image\n"); load_and_display_BMP(path); read_bytemap_in_screen(up_image, NULL, NULL); bytemap_clear(gray); bytemap_copy(gray, UP_DX, UP_DY, up_image, 0, 0, w, h); write_bytemap_to_screen(gray, gray, gray); wait_keyhit(); printf("Mean filtering \n"); mean_smooth(up_image, gray, 3); write_bytemap_to_screen(up_image, up_image, up_image); wait_keyhit(); //////////////////////////////////////// // MID display image /////////////////// strcpy(path, argv[1]); strcat(path, "_mid.bmp"); fn = strrchr(path, '/') + 1; printf("Filename: %s\n", fn); printf("Display image\n"); load_and_display_BMP(path); read_bytemap_in_screen(mid_image, NULL, NULL); bytemap_clear(gray); bytemap_copy(gray, MID_DX, MID_DY, mid_image, 0, 0, w, h); write_bytemap_to_screen(gray, gray, gray); wait_keyhit(); printf("Mean filtering \n"); mean_smooth(mid_image, gray, 3); write_bytemap_to_screen(mid_image, mid_image, mid_image); wait_keyhit(); ///////////////////////////////////////// // DN display image ///////////////////// strcpy(path, argv[1]); strcat(path, "_dn.bmp"); fn = strrchr(path, '/') + 1; printf("filename: %s\n", fn); printf("Display image\n"); load_and_display_BMP(path); read_bytemap_in_screen(dn_image, NULL, NULL); bytemap_clear(gray); bytemap_copy(gray, DN_DX, DN_DY, dn_image, 0, 0, w, h); write_bytemap_to_screen(gray, gray, gray); wait_keyhit(); printf("Mean filtering \n"); mean_smooth(dn_image, gray, 3); write_bytemap_to_screen(dn_image, dn_image, dn_image); wait_keyhit(); /////////////////////////////////////// printf("Up Image thresholding\n"); bytemap_threshold(bin, up_image, UP_FROM, UP_TO); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Big blobs greping\n"); bitmap_clear(roi); label_info = label_info_new(); labeling(labelmap, label_info, bin, NEIGHBOR_8); for (label = 0; label < label_info_get_count(label_info); label++) { label_info_glimpse(&area, label, label_info); //printf("area:%d\n", area); if (area > 3000) { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (dwordmap_get_value(labelmap, j, i) == label) { bitmap_set_value(roi, j, i); } } } } } label_info_destroy(label_info); write_bitmap_to_screen(roi, roi, roi); wait_keyhit(); printf("Fill holes\n"); bitmap_complement(bin, roi); labeling_grep_big_blob(roi, bin); bitmap_complement(bin, roi); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Image Morphology\n"); binary_closing(tmp, bin, se); binary_opening(up_roi, tmp, se); write_bitmap_to_screen(up_roi, up_roi, up_roi); wait_keyhit(); /////////////////////////////////////// printf("Mid Image thresholding\n"); bytemap_threshold(bin, mid_image, MID_FROM, MID_TO); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Big blobs greping\n"); bitmap_clear(roi); label_info = label_info_new(); labeling(labelmap, label_info, bin, NEIGHBOR_8); for (label = 0; label < label_info_get_count(label_info); label++) { label_info_glimpse(&area, label, label_info); //printf("area:%d\n", area); if (area > 3000) { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (dwordmap_get_value(labelmap, j, i) == label) { bitmap_set_value(roi, j, i); } } } } } label_info_destroy(label_info); write_bitmap_to_screen(roi, roi, roi); wait_keyhit(); printf("Fill holes\n"); bitmap_complement(bin, roi); labeling_grep_big_blob(roi, bin); bitmap_complement(bin, roi); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Image Morphology\n"); binary_closing(tmp, bin, se); binary_opening(mid_roi, tmp, se); write_bitmap_to_screen(mid_roi, mid_roi, mid_roi); wait_keyhit(); /////////////////////////////////////////////////// printf("Dn Image thresholding\n"); bytemap_threshold(bin, dn_image, DN_FROM, DN_TO); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Big blobs greping\n"); bitmap_clear(roi); label_info = label_info_new(); labeling(labelmap, label_info, bin, NEIGHBOR_8); for (label = 0; label < label_info_get_count(label_info); label++) { label_info_glimpse(&area, label, label_info); //printf("area:%d\n", area); if (area > 3000) { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (dwordmap_get_value(labelmap, j, i) == label) { bitmap_set_value(roi, j, i); } } } } } label_info_destroy(label_info); write_bitmap_to_screen(roi, roi, roi); wait_keyhit(); printf("Fill holes\n"); bitmap_complement(bin, roi); labeling_grep_big_blob(roi, bin); bitmap_complement(bin, roi); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Image Morphology\n"); binary_closing(tmp, bin, se); binary_opening(dn_roi, tmp, se); write_bitmap_to_screen(dn_roi, dn_roi, dn_roi); wait_keyhit(); /////////////////////////////////////////////// bitmap_clear(roi); bitmap_or(roi, up_roi); bitmap_or(roi, mid_roi); bitmap_or(roi, dn_roi); write_bitmap_to_screen(up_roi, mid_roi, dn_roi); wait_keyhit(); write_bitmap_to_screen(roi, roi, roi); wait_keyhit(); /* //write_bitmap_to_screen(up_roi, mid_roi, dn_roi); //read_bytemap_in_screen(up_image, mid_image, dn_image); strcpy(path, argv[1]); strcat(path, "_up_roi.bmp"); save_bytemap_as_BMP(up_image, path); strcpy(path, argv[1]); strcat(path, "_mid_roi.bmp"); save_bytemap_as_BMP(mid_image, path); strcpy(path, argv[1]); strcat(path, "_dn_roi.bmp"); save_bytemap_as_BMP(dn_image, path); read_bytemap_in_screen(gray, NULL, NULL); strcpy(path, argv[1]); strcat(path, "_roi.bmp"); save_bytemap_as_BMP(gray, path); */ #if 0 // up image statistic ///////////////////////// bytemap_get_min_max_on_roi(&vmin, &vmax, up_image, roi); bytemap_get_mean_on_roi(&vmean, up_image, roi); printf("Up image statistics are min: %d, mean: %lf, max: %d\n", vmin, vmean, vmax); fd = fopen("up_stat.txt", "a+"); fprintf(fd, "%d, %lf, %d\n", vmin, vmean, vmax); fclose(fd); //////////////////////////////////////////////// // mid image statistic ///////////////////////// bytemap_get_min_max_on_roi(&vmin, &vmax, mid_image, roi); bytemap_get_mean_on_roi(&vmean, mid_image, roi); printf("Mid image statistics are min: %d, mean: %lf, max: %d\n", vmin, vmean, vmax); fd = fopen("mid_stat.txt", "a+"); fprintf(fd, "%d, %lf, %d\n", vmin, vmean, vmax); fclose(fd); ///////////////////////////////////////////////// // dn image statistic /////////////////////////// bytemap_get_min_max_on_roi(&vmin, &vmax, dn_image, roi); bytemap_get_mean_on_roi(&vmean, dn_image, roi); printf("Dn image statistics are min: %d, mean: %lf, max: %d\n", vmin, vmean, vmax); fd = fopen("dn_stat.txt", "a+"); fprintf(fd, "%d, %lf, %d\n", vmin, vmean, vmax); fclose(fd); ///////////////////////////////////////////////// return 0; #endif #if 1 // Up image normalization printf("Up-Image global normalization\n"); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (bitmap_isset(roi, j, i)) { value = bytemap_get_value(up_image, j, i); if (value < UP_MEAN) { value = round(128.0 / (UP_MEAN - UP_MIN) * (value - UP_MIN)); } else { value = round(128.0 / (UP_MAX - UP_MEAN) * (value - UP_MEAN) + 128.0); } if (value < 0) value = 0; if (value > 255) value = 255; bytemap_put_value(value, up_image, j, i); } else { bytemap_put_value(0, up_image, j, i); } } } write_bytemap_to_screen(up_image, up_image, up_image); strcpy(path, argv[1]); strcat(path, "_up_normal.bmp"); save_bytemap_as_gray_BMP(up_image, path); wait_keyhit(); ////////////////////////////////////////// // Mid image normalization printf("MID-Image global normalization\n"); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (bitmap_isset(roi, j, i)) { value = bytemap_get_value(mid_image, j, i); if (value < MID_MEAN) { value = round(128.0 / (MID_MEAN - MID_MIN) * (value - MID_MIN)); } else { value = round(128.0 / (MID_MAX - MID_MEAN) * (value - MID_MEAN) + 128.0); } if (value < 0) value = 0; if (value > 255) value = 255; bytemap_put_value(value, mid_image, j, i); } else { bytemap_put_value(0, mid_image, j, i); } } } write_bytemap_to_screen(mid_image, mid_image, mid_image); strcpy(path, argv[1]); strcat(path, "_mid_normal.bmp"); save_bytemap_as_gray_BMP(mid_image, path); wait_keyhit(); /////////////////////////////////////////////// // Dn image normalization printf("Dn image global normalization\n"); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (bitmap_isset(roi, j, i)) { value = bytemap_get_value(dn_image, j, i); if (value < DN_MEAN) { value = round(128.0 / (DN_MEAN - DN_MIN) * (value - DN_MIN)); } else { value = round(128.0 / (DN_MAX - DN_MEAN) * (value - DN_MEAN) + 128.0); } if (value < 0) value = 0; if (value > 255) value = 255; bytemap_put_value(value, dn_image, j, i); } else { bytemap_put_value(0, dn_image, j, i); } } } write_bytemap_to_screen(dn_image, dn_image, dn_image); strcpy(path, argv[1]); strcat(path, "_dn_normal.bmp"); save_bytemap_as_gray_BMP(dn_image, path); wait_keyhit(); //////////////////////////////////////////// return 0; #endif #if 0 printf("Image subtraction between DN and MID for bruise-detection\n"); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (bitmap_isset(roi, j, i)) { value = ((real_t)bytemap_get_value(dn_image, j, i) - (real_t)bytemap_get_value(mid_image, j, i) + 255.0) / 2.0; if (value < 0) value = 0; if (value > 255) value = 255; bytemap_put_value(value, gray, j, i); } else { bytemap_put_value(0, gray, j, i); } } } write_bytemap_to_screen(gray, gray, gray); wait_keyhit(); bytemap_threshold(bin, gray, 142, 255); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); printf("Image subtraction between UP and MID for spot-detection\n"); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (bitmap_isset(roi, j, i)) { value = ((real_t)bytemap_get_value(up_image, j, i) - (real_t)bytemap_get_value(mid_imageb, j, i) + 255.0) / 2.0; if (value < 0) value = 0; if (value > 255) value = 255; bytemap_put_value(value, gray, j, i); } else { bytemap_put_value(0, gray, j, i); } } } write_bytemap_to_screen(gray, gray, gray); wait_keyhit(); bytemap_threshold(bin, gray, 1, 110); write_bitmap_to_screen(bin, bin, bin); wait_keyhit(); #endif dwordmap_destroy(labelmap); bytemap_destroy(se); return 0; bitmap_destroy(roi); bitmap_destroy(tmp); bitmap_destroy(bin); bitmap_destroy(dn_roi); bitmap_destroy(mid_roi); bitmap_destroy(up_roi); bytemap_destroy(gray); bytemap_destroy(dn_image); bytemap_destroy(mid_image); bytemap_destroy(up_image); return 0; }
int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *available, struct uwb_mas_bm *result) { struct uwb_rsv_alloc_info *ai; int interval; int bit_index; ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL); if (!ai) return UWB_RSV_ALLOC_NOT_FOUND; ai->min_mas = rsv->min_mas; ai->max_mas = rsv->max_mas; ai->max_interval = rsv->max_interval; /* */ for_each_clear_bit(bit_index, available->bm, UWB_NUM_MAS) ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL; if (ai->max_interval == 1) { get_row_descriptors(ai); if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND) goto alloc_found; else goto alloc_not_found; } get_column_descriptors(ai); for (interval = 16; interval >= 2; interval>>=1) { if (interval > ai->max_interval) continue; if (uwb_rsv_find_best_col_alloc(ai, interval) == UWB_RSV_ALLOC_FOUND) goto alloc_found; } /* */ get_row_descriptors(ai); if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND) goto alloc_found; else goto alloc_not_found; alloc_found: bitmap_zero(result->bm, UWB_NUM_MAS); bitmap_zero(result->unsafe_bm, UWB_NUM_MAS); /* */ for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) { if (ai->bm[bit_index] == UWB_RSV_MAS_SAFE) set_bit(bit_index, result->bm); else if (ai->bm[bit_index] == UWB_RSV_MAS_UNSAFE) set_bit(bit_index, result->unsafe_bm); } bitmap_or(result->bm, result->bm, result->unsafe_bm, UWB_NUM_MAS); result->safe = ai->safe_allocated_mases; result->unsafe = ai->unsafe_allocated_mases; kfree(ai); return UWB_RSV_ALLOC_FOUND; alloc_not_found: kfree(ai); return UWB_RSV_ALLOC_NOT_FOUND; }
static irqreturn_t sh_keysc_isr(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct sh_keysc_priv *priv = platform_get_drvdata(pdev); struct sh_keysc_info *pdata = &priv->pdata; int keyout_nr = sh_keysc_mode[pdata->mode].keyout; int keyin_nr = sh_keysc_mode[pdata->mode].keyin; DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); unsigned char keyin_set, tmp; int i, k, n; dev_dbg(&pdev->dev, "isr!\n"); bitmap_fill(keys1, SH_KEYSC_MAXKEYS); bitmap_zero(keys0, SH_KEYSC_MAXKEYS); do { bitmap_zero(keys, SH_KEYSC_MAXKEYS); keyin_set = 0; sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); for (i = 0; i < keyout_nr; i++) { n = keyin_nr * i; /* drive one KEYOUT pin low, read KEYIN pins */ sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); udelay(pdata->delay); tmp = sh_keysc_read(priv, KYINDR); /* set bit if key press has been detected */ for (k = 0; k < keyin_nr; k++) { if (tmp & (1 << k)) __set_bit(n + k, keys); } /* keep track of which KEYIN bits that have been set */ keyin_set |= tmp ^ ((1 << keyin_nr) - 1); } sh_keysc_level_mode(priv, keyin_set); bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); sh_keysc_map_dbg(&pdev->dev, keys, "keys"); } while (sh_keysc_read(priv, KYCR2) & 0x01); sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { k = pdata->keycodes[i]; if (!k) continue; if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) continue; if (test_bit(i, keys1) || test_bit(i, keys0)) { input_event(priv->input, EV_KEY, k, 1); __set_bit(i, priv->last_keys); } if (!test_bit(i, keys1)) { input_event(priv->input, EV_KEY, k, 0); __clear_bit(i, priv->last_keys); } } input_sync(priv->input); return IRQ_HANDLED; }
static inline void linkmode_or(unsigned long *dst, const unsigned long *a, const unsigned long *b) { bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS); }
/** * media_entity_pipeline_start - Mark a pipeline as streaming * @entity: Starting entity * @pipe: Media pipeline to be assigned to all entities in the pipeline. * * Mark all entities connected to a given entity through enabled links, either * directly or indirectly, as streaming. The given pipeline object is assigned to * every entity in the pipeline and stored in the media_entity pipe field. * * Calls to this function can be nested, in which case the same number of * media_entity_pipeline_stop() calls will be required to stop streaming. The * pipeline pointer must be identical for all nested calls to * media_entity_pipeline_start(). */ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe) { struct media_device *mdev = entity->parent; struct media_entity_graph graph; struct media_entity *entity_err = entity; int ret; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { DECLARE_BITMAP(active, entity->num_pads); DECLARE_BITMAP(has_no_links, entity->num_pads); unsigned int i; entity->stream_count++; WARN_ON(entity->pipe && entity->pipe != pipe); entity->pipe = pipe; /* Already streaming --- no need to check. */ if (entity->stream_count > 1) continue; if (!entity->ops || !entity->ops->link_validate) continue; bitmap_zero(active, entity->num_pads); bitmap_fill(has_no_links, entity->num_pads); for (i = 0; i < entity->num_links; i++) { struct media_link *link = &entity->links[i]; struct media_pad *pad = link->sink->entity == entity ? link->sink : link->source; /* Mark that a pad is connected by a link. */ bitmap_clear(has_no_links, pad->index, 1); /* * Pads that either do not need to connect or * are connected through an enabled link are * fine. */ if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || link->flags & MEDIA_LNK_FL_ENABLED) bitmap_set(active, pad->index, 1); /* * Link validation will only take place for * sink ends of the link that are enabled. */ if (link->sink != pad || !(link->flags & MEDIA_LNK_FL_ENABLED)) continue; ret = entity->ops->link_validate(link); if (ret < 0 && ret != -ENOIOCTLCMD) goto error; } /* Either no links or validated links are fine. */ bitmap_or(active, active, has_no_links, entity->num_pads); if (!bitmap_full(active, entity->num_pads)) { ret = -EPIPE; goto error; } } mutex_unlock(&mdev->graph_mutex); return 0; error: /* * Link validation on graph failed. We revert what we did and * return the error. */ media_entity_graph_walk_start(&graph, entity_err); while ((entity_err = media_entity_graph_walk_next(&graph))) { entity_err->stream_count--; if (entity_err->stream_count == 0) entity_err->pipe = NULL; /* * We haven't increased stream_count further than this * so we quit here. */ if (entity_err == entity) break; } mutex_unlock(&mdev->graph_mutex); return ret; }
void idset_add_set(struct idset *to, struct idset *from) { int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); }