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-spear.c (10052B)


      1/*
      2 * Driver for the ST Microelectronics SPEAr pinmux
      3 *
      4 * Copyright (C) 2012 ST Microelectronics
      5 * Viresh Kumar <vireshk@kernel.org>
      6 *
      7 * Inspired from:
      8 * - U300 Pinctl drivers
      9 * - Tegra Pinctl drivers
     10 *
     11 * This file is licensed under the terms of the GNU General Public
     12 * License version 2. This program is licensed "as is" without any
     13 * warranty of any kind, whether express or implied.
     14 */
     15
     16#include <linux/err.h>
     17#include <linux/mfd/syscon.h>
     18#include <linux/module.h>
     19#include <linux/of.h>
     20#include <linux/of_address.h>
     21#include <linux/of_gpio.h>
     22#include <linux/pinctrl/machine.h>
     23#include <linux/pinctrl/pinctrl.h>
     24#include <linux/pinctrl/pinmux.h>
     25#include <linux/platform_device.h>
     26#include <linux/slab.h>
     27
     28#include "pinctrl-spear.h"
     29
     30#define DRIVER_NAME "spear-pinmux"
     31
     32static void muxregs_endisable(struct spear_pmx *pmx,
     33		struct spear_muxreg *muxregs, u8 count, bool enable)
     34{
     35	struct spear_muxreg *muxreg;
     36	u32 val, temp, j;
     37
     38	for (j = 0; j < count; j++) {
     39		muxreg = &muxregs[j];
     40
     41		val = pmx_readl(pmx, muxreg->reg);
     42		val &= ~muxreg->mask;
     43
     44		if (enable)
     45			temp = muxreg->val;
     46		else
     47			temp = ~muxreg->val;
     48
     49		val |= muxreg->mask & temp;
     50		pmx_writel(pmx, val, muxreg->reg);
     51	}
     52}
     53
     54static int set_mode(struct spear_pmx *pmx, int mode)
     55{
     56	struct spear_pmx_mode *pmx_mode = NULL;
     57	int i;
     58	u32 val;
     59
     60	if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
     61		return -EINVAL;
     62
     63	for (i = 0; i < pmx->machdata->npmx_modes; i++) {
     64		if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
     65			pmx_mode = pmx->machdata->pmx_modes[i];
     66			break;
     67		}
     68	}
     69
     70	if (!pmx_mode)
     71		return -EINVAL;
     72
     73	val = pmx_readl(pmx, pmx_mode->reg);
     74	val &= ~pmx_mode->mask;
     75	val |= pmx_mode->val;
     76	pmx_writel(pmx, val, pmx_mode->reg);
     77
     78	pmx->machdata->mode = pmx_mode->mode;
     79	dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
     80			pmx_mode->name ? pmx_mode->name : "no_name",
     81			pmx_mode->reg);
     82
     83	return 0;
     84}
     85
     86void pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
     87				 unsigned count, u16 reg)
     88{
     89	int i, j;
     90
     91	for (i = 0; i < count; i++)
     92		for (j = 0; j < gpio_pingroup[i].nmuxregs; j++)
     93			gpio_pingroup[i].muxregs[j].reg = reg;
     94}
     95
     96void pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
     97{
     98	struct spear_pingroup *pgroup;
     99	struct spear_modemux *modemux;
    100	int i, j, group;
    101
    102	for (group = 0; group < machdata->ngroups; group++) {
    103		pgroup = machdata->groups[group];
    104
    105		for (i = 0; i < pgroup->nmodemuxs; i++) {
    106			modemux = &pgroup->modemuxs[i];
    107
    108			for (j = 0; j < modemux->nmuxregs; j++)
    109				if (modemux->muxregs[j].reg == 0xFFFF)
    110					modemux->muxregs[j].reg = reg;
    111		}
    112	}
    113}
    114
    115static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
    116{
    117	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    118
    119	return pmx->machdata->ngroups;
    120}
    121
    122static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
    123		unsigned group)
    124{
    125	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    126
    127	return pmx->machdata->groups[group]->name;
    128}
    129
    130static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
    131		unsigned group, const unsigned **pins, unsigned *num_pins)
    132{
    133	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    134
    135	*pins = pmx->machdata->groups[group]->pins;
    136	*num_pins = pmx->machdata->groups[group]->npins;
    137
    138	return 0;
    139}
    140
    141static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
    142		struct seq_file *s, unsigned offset)
    143{
    144	seq_printf(s, " " DRIVER_NAME);
    145}
    146
    147static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
    148					struct device_node *np_config,
    149					struct pinctrl_map **map,
    150					unsigned *num_maps)
    151{
    152	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    153	struct device_node *np;
    154	struct property *prop;
    155	const char *function, *group;
    156	int ret, index = 0, count = 0;
    157
    158	/* calculate number of maps required */
    159	for_each_child_of_node(np_config, np) {
    160		ret = of_property_read_string(np, "st,function", &function);
    161		if (ret < 0) {
    162			of_node_put(np);
    163			return ret;
    164		}
    165
    166		ret = of_property_count_strings(np, "st,pins");
    167		if (ret < 0) {
    168			of_node_put(np);
    169			return ret;
    170		}
    171
    172		count += ret;
    173	}
    174
    175	if (!count) {
    176		dev_err(pmx->dev, "No child nodes passed via DT\n");
    177		return -ENODEV;
    178	}
    179
    180	*map = kcalloc(count, sizeof(**map), GFP_KERNEL);
    181	if (!*map)
    182		return -ENOMEM;
    183
    184	for_each_child_of_node(np_config, np) {
    185		of_property_read_string(np, "st,function", &function);
    186		of_property_for_each_string(np, "st,pins", prop, group) {
    187			(*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
    188			(*map)[index].data.mux.group = group;
    189			(*map)[index].data.mux.function = function;
    190			index++;
    191		}
    192	}
    193
    194	*num_maps = count;
    195
    196	return 0;
    197}
    198
    199static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
    200				      struct pinctrl_map *map,
    201				      unsigned num_maps)
    202{
    203	kfree(map);
    204}
    205
    206static const struct pinctrl_ops spear_pinctrl_ops = {
    207	.get_groups_count = spear_pinctrl_get_groups_cnt,
    208	.get_group_name = spear_pinctrl_get_group_name,
    209	.get_group_pins = spear_pinctrl_get_group_pins,
    210	.pin_dbg_show = spear_pinctrl_pin_dbg_show,
    211	.dt_node_to_map = spear_pinctrl_dt_node_to_map,
    212	.dt_free_map = spear_pinctrl_dt_free_map,
    213};
    214
    215static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
    216{
    217	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    218
    219	return pmx->machdata->nfunctions;
    220}
    221
    222static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
    223		unsigned function)
    224{
    225	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    226
    227	return pmx->machdata->functions[function]->name;
    228}
    229
    230static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
    231		unsigned function, const char *const **groups,
    232		unsigned * const ngroups)
    233{
    234	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    235
    236	*groups = pmx->machdata->functions[function]->groups;
    237	*ngroups = pmx->machdata->functions[function]->ngroups;
    238
    239	return 0;
    240}
    241
    242static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
    243		unsigned function, unsigned group, bool enable)
    244{
    245	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    246	const struct spear_pingroup *pgroup;
    247	const struct spear_modemux *modemux;
    248	int i;
    249	bool found = false;
    250
    251	pgroup = pmx->machdata->groups[group];
    252
    253	for (i = 0; i < pgroup->nmodemuxs; i++) {
    254		modemux = &pgroup->modemuxs[i];
    255
    256		/* SoC have any modes */
    257		if (pmx->machdata->modes_supported) {
    258			if (!(pmx->machdata->mode & modemux->modes))
    259				continue;
    260		}
    261
    262		found = true;
    263		muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs,
    264				enable);
    265	}
    266
    267	if (!found) {
    268		dev_err(pmx->dev, "pinmux group: %s not supported\n",
    269				pgroup->name);
    270		return -ENODEV;
    271	}
    272
    273	return 0;
    274}
    275
    276static int spear_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned function,
    277		unsigned group)
    278{
    279	return spear_pinctrl_endisable(pctldev, function, group, true);
    280}
    281
    282/* gpio with pinmux */
    283static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
    284		unsigned pin)
    285{
    286	struct spear_gpio_pingroup *gpio_pingroup;
    287	int i, j;
    288
    289	if (!pmx->machdata->gpio_pingroups)
    290		return NULL;
    291
    292	for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) {
    293		gpio_pingroup = &pmx->machdata->gpio_pingroups[i];
    294
    295		for (j = 0; j < gpio_pingroup->npins; j++) {
    296			if (gpio_pingroup->pins[j] == pin)
    297				return gpio_pingroup;
    298		}
    299	}
    300
    301	return NULL;
    302}
    303
    304static int gpio_request_endisable(struct pinctrl_dev *pctldev,
    305		struct pinctrl_gpio_range *range, unsigned offset, bool enable)
    306{
    307	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
    308	struct spear_pinctrl_machdata *machdata = pmx->machdata;
    309	struct spear_gpio_pingroup *gpio_pingroup;
    310
    311	/*
    312	 * Some SoC have configuration options applicable to group of pins,
    313	 * rather than a single pin.
    314	 */
    315	gpio_pingroup = get_gpio_pingroup(pmx, offset);
    316	if (gpio_pingroup)
    317		muxregs_endisable(pmx, gpio_pingroup->muxregs,
    318				gpio_pingroup->nmuxregs, enable);
    319
    320	/*
    321	 * SoC may need some extra configurations, or configurations for single
    322	 * pin
    323	 */
    324	if (machdata->gpio_request_endisable)
    325		machdata->gpio_request_endisable(pmx, offset, enable);
    326
    327	return 0;
    328}
    329
    330static int gpio_request_enable(struct pinctrl_dev *pctldev,
    331		struct pinctrl_gpio_range *range, unsigned offset)
    332{
    333	return gpio_request_endisable(pctldev, range, offset, true);
    334}
    335
    336static void gpio_disable_free(struct pinctrl_dev *pctldev,
    337		struct pinctrl_gpio_range *range, unsigned offset)
    338{
    339	gpio_request_endisable(pctldev, range, offset, false);
    340}
    341
    342static const struct pinmux_ops spear_pinmux_ops = {
    343	.get_functions_count = spear_pinctrl_get_funcs_count,
    344	.get_function_name = spear_pinctrl_get_func_name,
    345	.get_function_groups = spear_pinctrl_get_func_groups,
    346	.set_mux = spear_pinctrl_set_mux,
    347	.gpio_request_enable = gpio_request_enable,
    348	.gpio_disable_free = gpio_disable_free,
    349};
    350
    351static struct pinctrl_desc spear_pinctrl_desc = {
    352	.name = DRIVER_NAME,
    353	.pctlops = &spear_pinctrl_ops,
    354	.pmxops = &spear_pinmux_ops,
    355	.owner = THIS_MODULE,
    356};
    357
    358int spear_pinctrl_probe(struct platform_device *pdev,
    359			struct spear_pinctrl_machdata *machdata)
    360{
    361	struct device_node *np = pdev->dev.of_node;
    362	struct spear_pmx *pmx;
    363
    364	if (!machdata)
    365		return -ENODEV;
    366
    367	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
    368	if (!pmx)
    369		return -ENOMEM;
    370
    371	pmx->regmap = device_node_to_regmap(np);
    372	if (IS_ERR(pmx->regmap)) {
    373		dev_err(&pdev->dev, "Init regmap failed (%pe).\n",
    374			pmx->regmap);
    375		return PTR_ERR(pmx->regmap);
    376	}
    377
    378	pmx->dev = &pdev->dev;
    379	pmx->machdata = machdata;
    380
    381	/* configure mode, if supported by SoC */
    382	if (machdata->modes_supported) {
    383		int mode = 0;
    384
    385		if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
    386			dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
    387			return -EINVAL;
    388		}
    389
    390		if (set_mode(pmx, mode)) {
    391			dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
    392					mode);
    393			return -EINVAL;
    394		}
    395	}
    396
    397	platform_set_drvdata(pdev, pmx);
    398
    399	spear_pinctrl_desc.pins = machdata->pins;
    400	spear_pinctrl_desc.npins = machdata->npins;
    401
    402	pmx->pctl = devm_pinctrl_register(&pdev->dev, &spear_pinctrl_desc, pmx);
    403	if (IS_ERR(pmx->pctl)) {
    404		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
    405		return PTR_ERR(pmx->pctl);
    406	}
    407
    408	return 0;
    409}