forked from Ivasoft/openwrt
ath79: add support for reset key on MikroTik RB912UAG-2HPnD
On MikroTik RB91x board series a reset key shares SoC gpio line #15 with NAND ALE and NAND IO7. So we need a custom gpio driver to manage this non-trivial connection schema. Also rb91x-nand needs to have an ability to disable a polling of the key while it works with NAND. While we've been integrating rb91x-key into a firmware, we've figured out that: * In the gpio-latch driver we need to add a "cansleep" suffix to several gpiolib calls, * When gpio-latch and rb91x-nand fail to get a gpio and an error is -EPROBE_DEFER, they shouldn't report about this, since this actually is not an error and occurs when the gpio-latch probe function is called before the rb91x-key probe. We fix these related things here too. Signed-off-by: Denis Kalashnikov <denis281089@gmail.com> Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
This commit is contained in:
committed by
Koen Vandeputte
parent
522e414dcb
commit
ec85e48a11
@@ -40,6 +40,7 @@ enum rb91x_nand_gpios {
|
||||
RB91X_NAND_ALE, /* Address Latch Enable */
|
||||
RB91X_NAND_NRW, /* Read/Write. Active low */
|
||||
RB91X_NAND_NLE, /* Latch Enable. Active low */
|
||||
RB91X_NAND_PDIS, /* Reset Key Poll Disable. Active high */
|
||||
|
||||
RB91X_NAND_GPIOS,
|
||||
};
|
||||
@@ -57,6 +58,12 @@ static inline void rb91x_nand_latch_lock(struct rb91x_nand_drvdata *drvdata,
|
||||
gpiod_set_value_cansleep(drvdata->gpio[RB91X_NAND_NLE], lock);
|
||||
}
|
||||
|
||||
static inline void rb91x_nand_rst_key_poll_disable(struct rb91x_nand_drvdata *drvdata,
|
||||
int disable)
|
||||
{
|
||||
gpiod_set_value_cansleep(drvdata->gpio[RB91X_NAND_PDIS], disable);
|
||||
}
|
||||
|
||||
static int rb91x_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *oobregion)
|
||||
{
|
||||
@@ -115,6 +122,7 @@ static void rb91x_nand_write(struct rb91x_nand_drvdata *drvdata,
|
||||
unsigned i;
|
||||
|
||||
rb91x_nand_latch_lock(drvdata, 1);
|
||||
rb91x_nand_rst_key_poll_disable(drvdata, 1);
|
||||
|
||||
oe_reg = __raw_readl(base + AR71XX_GPIO_REG_OE);
|
||||
out_reg = __raw_readl(base + AR71XX_GPIO_REG_OUT);
|
||||
@@ -146,6 +154,7 @@ static void rb91x_nand_write(struct rb91x_nand_drvdata *drvdata,
|
||||
/* Flush write */
|
||||
__raw_readl(base + AR71XX_GPIO_REG_OUT);
|
||||
|
||||
rb91x_nand_rst_key_poll_disable(drvdata, 0);
|
||||
rb91x_nand_latch_lock(drvdata, 0);
|
||||
}
|
||||
|
||||
@@ -162,6 +171,7 @@ static void rb91x_nand_read(struct rb91x_nand_drvdata *drvdata,
|
||||
gpiod_set_value_cansleep(drvdata->gpio[RB91X_NAND_READ], 1);
|
||||
|
||||
rb91x_nand_latch_lock(drvdata, 1);
|
||||
rb91x_nand_rst_key_poll_disable(drvdata, 1);
|
||||
|
||||
/* Save registers */
|
||||
oe_reg = __raw_readl(base + AR71XX_GPIO_REG_OE);
|
||||
@@ -199,6 +209,7 @@ static void rb91x_nand_read(struct rb91x_nand_drvdata *drvdata,
|
||||
/* Flush write */
|
||||
__raw_readl(base + AR71XX_GPIO_REG_OUT);
|
||||
|
||||
rb91x_nand_rst_key_poll_disable(drvdata, 0);
|
||||
rb91x_nand_latch_lock(drvdata, 0);
|
||||
|
||||
/* Disable read mode */
|
||||
@@ -274,8 +285,11 @@ static int rb91x_nand_probe(struct platform_device *pdev)
|
||||
|
||||
gpios = gpiod_get_array(dev, NULL, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpios)) {
|
||||
dev_err(dev, "failed to get gpios: %d\n", (int)gpios);
|
||||
return -EINVAL;
|
||||
if (PTR_ERR(gpios) != -EPROBE_DEFER) {
|
||||
dev_err(dev, "failed to get gpios: %d\n",
|
||||
PTR_ERR(gpios));
|
||||
}
|
||||
return PTR_ERR(gpios);
|
||||
}
|
||||
|
||||
if (gpios->ndescs != RB91X_NAND_GPIOS) {
|
||||
|
||||
Reference in New Issue
Block a user