cregit-Linux how code gets into the kernel

Release 4.11 drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c

/*
 * Copyright (C) 2015 Texas Instruments
 * Author: Jyri Sarha <jsarha@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 */

/*
 * To support the old "ti,tilcdc,slave" binding the binding has to be
 * transformed to the new external encoder binding.
 */

#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_fdt.h>
#include <linux/slab.h>
#include <linux/list.h>

#include "tilcdc_slave_compat.h"


struct kfree_table {
	
int total;
	
int num;
	
void **table;
};


static int __init kfree_table_init(struct kfree_table *kft) { kft->total = 32; kft->num = 0; kft->table = kmalloc(kft->total * sizeof(*kft->table), GFP_KERNEL); if (!kft->table) return -ENOMEM; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha59100.00%1100.00%
Total59100.00%1100.00%


static int __init kfree_table_add(struct kfree_table *kft, void *p) { if (kft->num == kft->total) { void **old = kft->table; kft->total *= 2; kft->table = krealloc(old, kft->total * sizeof(*kft->table), GFP_KERNEL); if (!kft->table) { kft->table = old; kfree(p); return -ENOMEM; } } kft->table[kft->num++] = p; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha105100.00%1100.00%
Total105100.00%1100.00%


static void __init kfree_table_free(struct kfree_table *kft) { int i; for (i = 0; i < kft->num; i++) kfree(kft->table[i]); kfree(kft->table); }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha47100.00%1100.00%
Total47100.00%1100.00%


static struct property * __init tilcdc_prop_dup(const struct property *prop, struct kfree_table *kft) { struct property *nprop; nprop = kzalloc(sizeof(*nprop), GFP_KERNEL); if (!nprop || kfree_table_add(kft, nprop)) return NULL; nprop->name = kstrdup(prop->name, GFP_KERNEL); if (!nprop->name || kfree_table_add(kft, nprop->name)) return NULL; nprop->value = kmemdup(prop->value, prop->length, GFP_KERNEL); if (!nprop->value || kfree_table_add(kft, nprop->value)) return NULL; nprop->length = prop->length; return nprop; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha132100.00%1100.00%
Total132100.00%1100.00%


static void __init tilcdc_copy_props(struct device_node *from, struct device_node *to, const char * const props[], struct kfree_table *kft) { struct property *prop; int i; for (i = 0; props[i]; i++) { prop = of_find_property(from, props[i], NULL); if (!prop) continue; prop = tilcdc_prop_dup(prop, kft); if (!prop) continue; prop->next = to->properties; to->properties = prop; } }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha102100.00%1100.00%
Total102100.00%1100.00%


static int __init tilcdc_prop_str_update(struct property *prop, const char *str, struct kfree_table *kft) { prop->value = kstrdup(str, GFP_KERNEL); if (kfree_table_add(kft, prop->value) || !prop->value) return -ENOMEM; prop->length = strlen(str)+1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha67100.00%1100.00%
Total67100.00%1100.00%


static void __init tilcdc_node_disable(struct device_node *node) { struct property *prop; prop = kzalloc(sizeof(*prop), GFP_KERNEL); if (!prop) return; prop->name = "status"; prop->value = "disabled"; prop->length = strlen((char *)prop->value)+1; of_update_property(node, prop); }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha72100.00%1100.00%
Total72100.00%1100.00%


static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft) { const int size = __dtb_tilcdc_slave_compat_end - __dtb_tilcdc_slave_compat_begin; static void *overlay_data; struct device_node *overlay; int ret; if (!size) { pr_warn("%s: No overlay data\n", __func__); return NULL; } overlay_data = kmemdup(__dtb_tilcdc_slave_compat_begin, size, GFP_KERNEL); if (!overlay_data || kfree_table_add(kft, overlay_data)) return NULL; of_fdt_unflatten_tree(overlay_data, NULL, &overlay); if (!overlay) { pr_warn("%s: Unfattening overlay tree failed\n", __func__); return NULL; } of_node_set_flag(overlay, OF_DETACHED); ret = of_resolve_phandles(overlay); if (ret) { pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret); return NULL; } return overlay; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha13797.86%133.33%
Gavin Shan21.43%133.33%
Baoyou Xie10.71%133.33%
Total140100.00%3100.00%

static const struct of_device_id tilcdc_slave_of_match[] __initconst = { { .compatible = "ti,tilcdc,slave", }, {}, }; static const struct of_device_id tilcdc_of_match[] __initconst = { { .compatible = "ti,am33xx-tilcdc", }, {}, }; static const struct of_device_id tilcdc_tda998x_of_match[] __initconst = { { .compatible = "nxp,tda998x", }, {}, }; static const char * const tilcdc_slave_props[] __initconst = { "pinctrl-names", "pinctrl-0", "pinctrl-1", NULL };
static void __init tilcdc_convert_slave_node(void) { struct device_node *slave = NULL, *lcdc = NULL; struct device_node *i2c = NULL, *fragment = NULL; struct device_node *overlay, *encoder; struct property *prop; /* For all memory needed for the overlay tree. This memory can be freed after the overlay has been applied. */ struct kfree_table kft; int ret; if (kfree_table_init(&kft)) return; lcdc = of_find_matching_node(NULL, tilcdc_of_match); slave = of_find_matching_node(NULL, tilcdc_slave_of_match); if (!slave || !of_device_is_available(lcdc)) goto out; i2c = of_parse_phandle(slave, "i2c", 0); if (!i2c) { pr_err("%s: Can't find i2c node trough phandle\n", __func__); goto out; } overlay = tilcdc_get_overlay(&kft); if (!overlay) goto out; encoder = of_find_matching_node(overlay, tilcdc_tda998x_of_match); if (!encoder) { pr_err("%s: Failed to find tda998x node\n", __func__); goto out; } tilcdc_copy_props(slave, encoder, tilcdc_slave_props, &kft); for_each_child_of_node(overlay, fragment) { prop = of_find_property(fragment, "target-path", NULL); if (!prop) continue; if (!strncmp("i2c", (char *)prop->value, prop->length)) if (tilcdc_prop_str_update(prop, i2c->full_name, &kft)) goto out; if (!strncmp("lcdc", (char *)prop->value, prop->length)) if (tilcdc_prop_str_update(prop, lcdc->full_name, &kft)) goto out; } tilcdc_node_disable(slave); ret = of_overlay_create(overlay); if (ret) pr_err("%s: Creating overlay failed: %d\n", __func__, ret); else pr_info("%s: ti,tilcdc,slave node successfully converted\n", __func__); out: kfree_table_free(&kft); of_node_put(i2c); of_node_put(slave); of_node_put(lcdc); of_node_put(fragment); }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha33599.41%133.33%
SF Markus Elfring10.30%133.33%
Baoyou Xie10.30%133.33%
Total337100.00%3100.00%


static int __init tilcdc_slave_compat_init(void) { tilcdc_convert_slave_node(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha1493.33%150.00%
Baoyou Xie16.67%150.00%
Total15100.00%2100.00%

subsys_initcall(tilcdc_slave_compat_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
Jyri Sarha119099.50%125.00%
Baoyou Xie30.25%125.00%
Gavin Shan20.17%125.00%
SF Markus Elfring10.08%125.00%
Total1196100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.