lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1495717952-9762-2-git-send-email-david.wu@rock-chips.com>
Date:   Thu, 25 May 2017 21:12:29 +0800
From:   David Wu <david.wu@...k-chips.com>
To:     heiko@...ech.de, linus.walleij@...aro.org
Cc:     huangtao@...k-chips.com, dianders@...omium.org,
        linux-rockchip@...ts.infradead.org, linux-gpio@...r.kernel.org,
        linux-kernel@...r.kernel.org, David Wu <david.wu@...k-chips.com>
Subject: [PATCH 1/4] pinctrl: rockchip: Add iomux-route switching support

On the some rockchip soc, some things like one specific uart can use
multiple pins, but control of that seems to be split. Somewhere between
the pin io-cells and the uart it seems to have some sort of switch to
decide to which pin to actually route the data.

+-------+    +--------+  /- GPIO4_B0 (pinmux 2)

| uart2 | -- | switch | --- GPIO4_C0 (pinmux 2)

+-------+    +--------+  \- GPIO4_C3 (pinmux 2)
(switch selects one of the 3 pins base on the GRF_SOC_CON7[BIT0, BIT1])

The routing switch is determined by one pin of a specific group to be set
to its special pinmux function. If the pinmux setting is wrong for that
pin the ip block won't work correctly anyway.

Signed-off-by: David Wu <david.wu@...k-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f141aa0..f5dd1c3 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -146,6 +146,7 @@ struct rockchip_drv {
  * @irq_lock: bus lock for irq chip
  * @new_irqs: newly configured irqs which must be muxed as GPIOs in
  *	irq_bus_sync_unlock()
+ * @route_mask: bits describing the routing pins of per bank
  */
 struct rockchip_pin_bank {
 	void __iomem			*reg_base;
@@ -170,6 +171,7 @@ struct rockchip_pin_bank {
 	u32				toggle_edge_mode;
 	struct mutex			irq_lock;
 	u32				new_irqs;
+	u32				route_mask;
 };
 
 #define PIN_BANK(id, pins, label)			\
@@ -316,6 +318,8 @@ struct rockchip_pin_ctrl {
 	int	(*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
 				    int pin_num, struct regmap **regmap,
 				    int *reg, u8 *bit);
+	bool	(*iomux_route)(u8 bank_num, int pin, int mux,
+			       u32 *reg, u32 *value);
 };
 
 struct rockchip_pin_config {
@@ -383,6 +387,22 @@ struct rockchip_mux_recalced_data {
 	u8 mask;
 };
 
+/**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @bank: bank number.
+ * @pin: index at register or used to calc index.
+ * @func: the min pin.
+ * @route_offset: the max pin.
+ * @route_val: the register offset.
+ */
+struct rockchip_mux_route_data {
+	u8 bank;
+	u8 pin;
+	u8 func;
+	u32 route_offset;
+	u32 route_val;
+};
+
 static struct regmap_config rockchip_regmap_config = {
 	.reg_bits = 32,
 	.val_bits = 32,
@@ -683,7 +703,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, rmask;
+	u32 data, rmask, route_reg, route_val;
 
 	ret = rockchip_verify_mux(bank, pin, mux);
 	if (ret < 0)
@@ -719,6 +739,15 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
 		ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);
 
+	if (ctrl->iomux_route && (bank->route_mask & BIT(pin))) {
+		if (ctrl->iomux_route(bank->bank_num, pin, mux,
+				      &route_reg, &route_val)) {
+			ret = regmap_write(regmap, route_reg, route_val);
+			if (ret)
+				return ret;
+		}
+	}
+
 	data = (mask << (bit + 16));
 	rmask = data | (data >> 16);
 	data |= (mux & mask) << bit;
-- 
1.9.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ