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

pinmux-aspeed.c (3330B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* Copyright (C) 2019 IBM Corp. */
      3
      4/* Pieces to enable drivers to implement the .set callback */
      5
      6#include "pinmux-aspeed.h"
      7
      8static const char *const aspeed_pinmux_ips[] = {
      9	[ASPEED_IP_SCU] = "SCU",
     10	[ASPEED_IP_GFX] = "GFX",
     11	[ASPEED_IP_LPC] = "LPC",
     12};
     13
     14static inline void aspeed_sig_desc_print_val(
     15		const struct aspeed_sig_desc *desc, bool enable, u32 rv)
     16{
     17	pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
     18			aspeed_pinmux_ips[desc->ip], desc->reg,
     19			desc->mask, enable ? desc->enable : desc->disable,
     20			(rv & desc->mask) >> __ffs(desc->mask), rv);
     21}
     22
     23/**
     24 * aspeed_sig_desc_eval() - Query the enabled or disabled state of a signal
     25 * descriptor.
     26 *
     27 * @desc: The signal descriptor of interest
     28 * @enabled: True to query the enabled state, false to query disabled state
     29 * @map: The IP block's regmap instance
     30 *
     31 * Return: 1 if the descriptor's bitfield is configured to the state
     32 * selected by @enabled, 0 if not, and less than zero if an unrecoverable
     33 * failure occurred
     34 *
     35 * Evaluation of descriptor state is non-trivial in that it is not a binary
     36 * outcome: The bitfields can be greater than one bit in size and thus can take
     37 * a value that is neither the enabled nor disabled state recorded in the
     38 * descriptor (typically this means a different function to the one of interest
     39 * is enabled). Thus we must explicitly test for either condition as required.
     40 */
     41int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
     42			 bool enabled, struct regmap *map)
     43{
     44	int ret;
     45	unsigned int raw;
     46	u32 want;
     47
     48	if (!map)
     49		return -ENODEV;
     50
     51	ret = regmap_read(map, desc->reg, &raw);
     52	if (ret)
     53		return ret;
     54
     55	aspeed_sig_desc_print_val(desc, enabled, raw);
     56	want = enabled ? desc->enable : desc->disable;
     57
     58	return ((raw & desc->mask) >> __ffs(desc->mask)) == want;
     59}
     60
     61/**
     62 * aspeed_sig_expr_eval - Query the enabled or disabled state for a
     63 * mux function's signal on a pin
     64 *
     65 * @ctx: The driver context for the pinctrl IP
     66 * @expr: An expression controlling the signal for a mux function on a pin
     67 * @enabled: True to query the enabled state, false to query disabled state
     68 *
     69 * Return: 1 if the expression composed by @enabled evaluates true, 0 if not,
     70 * and less than zero if an unrecoverable failure occurred.
     71 *
     72 * A mux function is enabled or disabled if the function's signal expression
     73 * for each pin in the function's pin group evaluates true for the desired
     74 * state. An signal expression evaluates true if all of its associated signal
     75 * descriptors evaluate true for the desired state.
     76 *
     77 * If an expression's state is described by more than one bit, either through
     78 * multi-bit bitfields in a single signal descriptor or through multiple signal
     79 * descriptors of a single bit then it is possible for the expression to be in
     80 * neither the enabled nor disabled state. Thus we must explicitly test for
     81 * either condition as required.
     82 */
     83int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
     84			 const struct aspeed_sig_expr *expr, bool enabled)
     85{
     86	int ret;
     87	int i;
     88
     89	if (ctx->ops->eval)
     90		return ctx->ops->eval(ctx, expr, enabled);
     91
     92	for (i = 0; i < expr->ndescs; i++) {
     93		const struct aspeed_sig_desc *desc = &expr->descs[i];
     94
     95		ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);
     96		if (ret <= 0)
     97			return ret;
     98	}
     99
    100	return 1;
    101}