diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt b/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt index 2e3781cf7072..423c86012d7b 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt +++ b/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt @@ -8,6 +8,9 @@ Required properties: - size-cells: must be set to 1. - clocks: Must contain an entry for each entry in clock-names. - clock-names: Should be "clk_opt", "pclk_otp" and "pclk_otp_phy". + - resets: Must contain an entry for each entry in reset-names. + See ../../reset/reset.txt for details. + - reset-names: Should be "otp_phy". See nvmem.txt for more information. diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c index 940529898de5..42afd0c93dae 100644 --- a/drivers/nvmem/rockchip-otp.c +++ b/drivers/nvmem/rockchip-otp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -67,12 +68,34 @@ struct rockchip_otp { struct clk *clk; struct clk *pclk; struct clk *pclk_phy; + struct reset_control *rst; }; struct rockchip_data { int size; }; +static int rockchip_otp_reset(struct rockchip_otp *otp) +{ + int ret; + + ret = reset_control_assert(otp->rst); + if (ret) { + dev_err(otp->dev, "failed to assert otp phy %d\n", ret); + return ret; + } + + udelay(2); + + ret = reset_control_deassert(otp->rst); + if (ret) { + dev_err(otp->dev, "failed to deassert otp phy %d\n", ret); + return ret; + } + + return 0; +} + static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag) { u32 status = 0; @@ -138,6 +161,12 @@ static int rockchip_otp_read(void *context, unsigned int offset, goto opt_pclk; } + ret = rockchip_otp_reset(otp); + if (ret) { + dev_err(otp->dev, "failed to reset otp phy\n"); + goto opt_pclk_phy; + } + ret = rockchip_otp_ecc_enable(otp, false); if (ret < 0) { dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); @@ -232,6 +261,10 @@ static int __init rockchip_otp_probe(struct platform_device *pdev) if (IS_ERR(otp->pclk_phy)) return PTR_ERR(otp->pclk_phy); + otp->rst = devm_reset_control_get(dev, "otp_phy"); + if (IS_ERR(otp->rst)) + return PTR_ERR(otp->rst); + otp_config.size = data->size; otp_config.priv = otp; otp_config.dev = dev;