int nvhost_syncpt_init(struct platform_device *dev, struct nvhost_syncpt *sp) { int i; struct nvhost_master *host = syncpt_to_dev(sp); int err = 0; /* Allocate structs for min, max and base values */ sp->min_val = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->max_val = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->base_val = kzalloc(sizeof(u32) * nvhost_syncpt_nb_bases(sp), GFP_KERNEL); sp->lock_counts = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_mlocks(sp), GFP_KERNEL); sp->caps_nodes = kzalloc(sizeof(struct nvhost_capability_node) * 3, GFP_KERNEL); #if CONFIG_TEGRA_GRHOST_SYNC sp->timeline = kzalloc(sizeof(struct nvhost_sync_timeline *) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); if (!sp->timeline) { err = -ENOMEM; goto fail; } #endif if (!(sp->min_val && sp->max_val && sp->base_val && sp->lock_counts && sp->caps_nodes)) { /* frees happen in the deinit */ err = -ENOMEM; goto fail; } sp->kobj = kobject_create_and_add("syncpt", &dev->dev.kobj); if (!sp->kobj) { err = -EIO; goto fail; } sp->caps_kobj = kobject_create_and_add("capabilities", &dev->dev.kobj); if (!sp->caps_kobj) { err = -EIO; goto fail; } if (nvhost_syncpt_set_sysfs_capability_node(sp, num_syncpts_name, sp->caps_nodes, &nvhost_syncpt_nb_pts)) { err = -EIO; goto fail; } if (nvhost_syncpt_set_sysfs_capability_node(sp, num_waitbases_name, sp->caps_nodes + 1, &nvhost_syncpt_nb_bases)) { err = -EIO; goto fail; } if (nvhost_syncpt_set_sysfs_capability_node(sp, num_mutexes_name, sp->caps_nodes + 2, &nvhost_syncpt_nb_mlocks)) { err = -EIO; goto fail; } /* Allocate two attributes for each sync point: min and max */ sp->syncpt_attrs = kzalloc(sizeof(*sp->syncpt_attrs) * nvhost_syncpt_nb_pts(sp) * 2, GFP_KERNEL); if (!sp->syncpt_attrs) { err = -ENOMEM; goto fail; } /* Fill in the attributes */ for (i = 0; i < nvhost_syncpt_nb_pts(sp); i++) { struct nvhost_syncpt_attr *min = &sp->syncpt_attrs[i*2]; struct nvhost_syncpt_attr *max = &sp->syncpt_attrs[i*2+1]; err = nvhost_syncpt_timeline_attr(host, sp, min, max, i); if (err) goto fail; #if CONFIG_TEGRA_GRHOST_SYNC sp->timeline[i] = nvhost_sync_timeline_create(sp, i); if (!sp->timeline[i]) { err = -ENOMEM; goto fail; } #endif } err = nvhost_syncpt_timeline_attr(host, sp, &sp->invalid_min_attr, &sp->invalid_max_attr, NVSYNCPT_INVALID); if (err) goto fail; sp->timeline_invalid = nvhost_sync_timeline_create(sp, NVSYNCPT_INVALID); if (!sp->timeline_invalid) { err = -ENOMEM; goto fail; } return err; fail: nvhost_syncpt_deinit(sp); return err; }
int nvhost_syncpt_init(struct platform_device *dev, struct nvhost_syncpt *sp) { int i; struct nvhost_master *host = syncpt_to_dev(sp); int err = 0; /* Allocate structs for min, max and base values */ sp->assigned = kzalloc(sizeof(bool) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->client_managed = kzalloc(sizeof(bool) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->syncpt_names = kzalloc(sizeof(char *) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->min_val = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->max_val = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); sp->base_val = kzalloc(sizeof(u32) * nvhost_syncpt_nb_bases(sp), GFP_KERNEL); sp->lock_counts = kzalloc(sizeof(atomic_t) * nvhost_syncpt_nb_mlocks(sp), GFP_KERNEL); #ifdef CONFIG_TEGRA_GRHOST_SYNC sp->timeline = kzalloc(sizeof(struct nvhost_sync_timeline *) * nvhost_syncpt_nb_pts(sp), GFP_KERNEL); if (!sp->timeline) { err = -ENOMEM; goto fail; } #endif if (!(sp->assigned && sp->client_managed && sp->min_val && sp->max_val && sp->base_val && sp->lock_counts)) { /* frees happen in the deinit */ err = -ENOMEM; goto fail; } sp->kobj = kobject_create_and_add("syncpt", &dev->dev.kobj); if (!sp->kobj) { err = -EIO; goto fail; } mutex_init(&sp->syncpt_mutex); /* Allocate two attributes for each sync point: min and max */ sp->syncpt_attrs = kzalloc(sizeof(*sp->syncpt_attrs) * nvhost_syncpt_nb_pts(sp) * NUM_SYSFS_ENTRY, GFP_KERNEL); if (!sp->syncpt_attrs) { err = -ENOMEM; goto fail; } /* Fill in the attributes */ for (i = 0; i < nvhost_syncpt_nb_pts(sp); i++) { struct nvhost_syncpt_attr *min = &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY]; struct nvhost_syncpt_attr *max = &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY+1]; struct nvhost_syncpt_attr *name = &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY+2]; struct nvhost_syncpt_attr *syncpt_type = &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY+3]; struct nvhost_syncpt_attr *syncpt_assigned = &sp->syncpt_attrs[i*NUM_SYSFS_ENTRY+4]; err = nvhost_syncpt_timeline_attr(host, sp, min, max, name, syncpt_type, syncpt_assigned, i); if (err) goto fail; /* initialize syncpt status */ sp->assigned[i] = false; sp->client_managed[i] = false; #ifdef CONFIG_TEGRA_GRHOST_SYNC sp->timeline[i] = nvhost_sync_timeline_create(sp, i); if (!sp->timeline[i]) { err = -ENOMEM; goto fail; } #endif } #ifdef CONFIG_TEGRA_GRHOST_SYNC err = nvhost_syncpt_timeline_attr(host, sp, &sp->invalid_min_attr, &sp->invalid_max_attr, &sp->invalid_name_attr, &sp->invalid_syncpt_type_attr, &sp->invalid_assigned_attr, NVSYNCPT_INVALID); if (err) goto fail; sp->timeline_invalid = nvhost_sync_timeline_create(sp, NVSYNCPT_INVALID); if (!sp->timeline_invalid) { err = -ENOMEM; goto fail; } #endif /* * some syncpts need to be reserved (hard-coded) because of * external dependencies / constraints */ nvhost_reserve_syncpts(sp); return err; fail: nvhost_syncpt_deinit(sp); return err; }