cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pinctrl-utils.c (3805B)


      1/*
      2 * Utils functions to implement the pincontrol driver.
      3 *
      4 * Copyright (c) 2013, NVIDIA Corporation.
      5 *
      6 * Author: Laxman Dewangan <ldewangan@nvidia.com>
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License as
     10 * published by the Free Software Foundation version 2.
     11 *
     12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
     13 * whether express or implied; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     20 * 02111-1307, USA
     21 */
     22#include <linux/device.h>
     23#include <linux/export.h>
     24#include <linux/kernel.h>
     25#include <linux/pinctrl/pinctrl.h>
     26#include <linux/of.h>
     27#include <linux/slab.h>
     28#include "core.h"
     29#include "pinctrl-utils.h"
     30
     31int pinctrl_utils_reserve_map(struct pinctrl_dev *pctldev,
     32		struct pinctrl_map **map, unsigned *reserved_maps,
     33		unsigned *num_maps, unsigned reserve)
     34{
     35	unsigned old_num = *reserved_maps;
     36	unsigned new_num = *num_maps + reserve;
     37	struct pinctrl_map *new_map;
     38
     39	if (old_num >= new_num)
     40		return 0;
     41
     42	new_map = krealloc_array(*map, new_num, sizeof(*new_map), GFP_KERNEL);
     43	if (!new_map) {
     44		dev_err(pctldev->dev, "krealloc(map) failed\n");
     45		return -ENOMEM;
     46	}
     47
     48	memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
     49
     50	*map = new_map;
     51	*reserved_maps = new_num;
     52	return 0;
     53}
     54EXPORT_SYMBOL_GPL(pinctrl_utils_reserve_map);
     55
     56int pinctrl_utils_add_map_mux(struct pinctrl_dev *pctldev,
     57		struct pinctrl_map **map, unsigned *reserved_maps,
     58		unsigned *num_maps, const char *group,
     59		const char *function)
     60{
     61	if (WARN_ON(*num_maps == *reserved_maps))
     62		return -ENOSPC;
     63
     64	(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
     65	(*map)[*num_maps].data.mux.group = group;
     66	(*map)[*num_maps].data.mux.function = function;
     67	(*num_maps)++;
     68
     69	return 0;
     70}
     71EXPORT_SYMBOL_GPL(pinctrl_utils_add_map_mux);
     72
     73int pinctrl_utils_add_map_configs(struct pinctrl_dev *pctldev,
     74		struct pinctrl_map **map, unsigned *reserved_maps,
     75		unsigned *num_maps, const char *group,
     76		unsigned long *configs, unsigned num_configs,
     77		enum pinctrl_map_type type)
     78{
     79	unsigned long *dup_configs;
     80
     81	if (WARN_ON(*num_maps == *reserved_maps))
     82		return -ENOSPC;
     83
     84	dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
     85			      GFP_KERNEL);
     86	if (!dup_configs)
     87		return -ENOMEM;
     88
     89	(*map)[*num_maps].type = type;
     90	(*map)[*num_maps].data.configs.group_or_pin = group;
     91	(*map)[*num_maps].data.configs.configs = dup_configs;
     92	(*map)[*num_maps].data.configs.num_configs = num_configs;
     93	(*num_maps)++;
     94
     95	return 0;
     96}
     97EXPORT_SYMBOL_GPL(pinctrl_utils_add_map_configs);
     98
     99int pinctrl_utils_add_config(struct pinctrl_dev *pctldev,
    100		unsigned long **configs, unsigned *num_configs,
    101		unsigned long config)
    102{
    103	unsigned old_num = *num_configs;
    104	unsigned new_num = old_num + 1;
    105	unsigned long *new_configs;
    106
    107	new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
    108			       GFP_KERNEL);
    109	if (!new_configs) {
    110		dev_err(pctldev->dev, "krealloc(configs) failed\n");
    111		return -ENOMEM;
    112	}
    113
    114	new_configs[old_num] = config;
    115
    116	*configs = new_configs;
    117	*num_configs = new_num;
    118
    119	return 0;
    120}
    121EXPORT_SYMBOL_GPL(pinctrl_utils_add_config);
    122
    123void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
    124	      struct pinctrl_map *map, unsigned num_maps)
    125{
    126	int i;
    127
    128	for (i = 0; i < num_maps; i++) {
    129		switch (map[i].type) {
    130		case PIN_MAP_TYPE_CONFIGS_GROUP:
    131		case PIN_MAP_TYPE_CONFIGS_PIN:
    132			kfree(map[i].data.configs.configs);
    133			break;
    134		default:
    135			break;
    136		}
    137	}
    138	kfree(map);
    139}
    140EXPORT_SYMBOL_GPL(pinctrl_utils_free_map);