linux/drivers/reset/reset-imx7.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2017, Impinj, Inc.
   4 *
   5 * i.MX7 System Reset Controller (SRC) driver
   6 *
   7 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
   8 */
   9
  10#include <linux/mfd/syscon.h>
  11#include <linux/module.h>
  12#include <linux/of_device.h>
  13#include <linux/platform_device.h>
  14#include <linux/reset-controller.h>
  15#include <linux/regmap.h>
  16#include <dt-bindings/reset/imx7-reset.h>
  17#include <dt-bindings/reset/imx8mq-reset.h>
  18#include <dt-bindings/reset/imx8mp-reset.h>
  19
  20struct imx7_src_signal {
  21        unsigned int offset, bit;
  22};
  23
  24struct imx7_src_variant {
  25        const struct imx7_src_signal *signals;
  26        unsigned int signals_num;
  27        struct reset_control_ops ops;
  28};
  29
  30struct imx7_src {
  31        struct reset_controller_dev rcdev;
  32        struct regmap *regmap;
  33        const struct imx7_src_signal *signals;
  34};
  35
  36enum imx7_src_registers {
  37        SRC_A7RCR0              = 0x0004,
  38        SRC_M4RCR               = 0x000c,
  39        SRC_ERCR                = 0x0014,
  40        SRC_HSICPHY_RCR         = 0x001c,
  41        SRC_USBOPHY1_RCR        = 0x0020,
  42        SRC_USBOPHY2_RCR        = 0x0024,
  43        SRC_MIPIPHY_RCR         = 0x0028,
  44        SRC_PCIEPHY_RCR         = 0x002c,
  45        SRC_DDRC_RCR            = 0x1000,
  46};
  47
  48static int imx7_reset_update(struct imx7_src *imx7src,
  49                             unsigned long id, unsigned int value)
  50{
  51        const struct imx7_src_signal *signal = &imx7src->signals[id];
  52
  53        return regmap_update_bits(imx7src->regmap,
  54                                  signal->offset, signal->bit, value);
  55}
  56
  57static const struct imx7_src_signal imx7_src_signals[IMX7_RESET_NUM] = {
  58        [IMX7_RESET_A7_CORE_POR_RESET0] = { SRC_A7RCR0, BIT(0) },
  59        [IMX7_RESET_A7_CORE_POR_RESET1] = { SRC_A7RCR0, BIT(1) },
  60        [IMX7_RESET_A7_CORE_RESET0]     = { SRC_A7RCR0, BIT(4) },
  61        [IMX7_RESET_A7_CORE_RESET1]     = { SRC_A7RCR0, BIT(5) },
  62        [IMX7_RESET_A7_DBG_RESET0]      = { SRC_A7RCR0, BIT(8) },
  63        [IMX7_RESET_A7_DBG_RESET1]      = { SRC_A7RCR0, BIT(9) },
  64        [IMX7_RESET_A7_ETM_RESET0]      = { SRC_A7RCR0, BIT(12) },
  65        [IMX7_RESET_A7_ETM_RESET1]      = { SRC_A7RCR0, BIT(13) },
  66        [IMX7_RESET_A7_SOC_DBG_RESET]   = { SRC_A7RCR0, BIT(20) },
  67        [IMX7_RESET_A7_L2RESET]         = { SRC_A7RCR0, BIT(21) },
  68        [IMX7_RESET_SW_M4C_RST]         = { SRC_M4RCR, BIT(1) },
  69        [IMX7_RESET_SW_M4P_RST]         = { SRC_M4RCR, BIT(2) },
  70        [IMX7_RESET_EIM_RST]            = { SRC_ERCR, BIT(0) },
  71        [IMX7_RESET_HSICPHY_PORT_RST]   = { SRC_HSICPHY_RCR, BIT(1) },
  72        [IMX7_RESET_USBPHY1_POR]        = { SRC_USBOPHY1_RCR, BIT(0) },
  73        [IMX7_RESET_USBPHY1_PORT_RST]   = { SRC_USBOPHY1_RCR, BIT(1) },
  74        [IMX7_RESET_USBPHY2_POR]        = { SRC_USBOPHY2_RCR, BIT(0) },
  75        [IMX7_RESET_USBPHY2_PORT_RST]   = { SRC_USBOPHY2_RCR, BIT(1) },
  76        [IMX7_RESET_MIPI_PHY_MRST]      = { SRC_MIPIPHY_RCR, BIT(1) },
  77        [IMX7_RESET_MIPI_PHY_SRST]      = { SRC_MIPIPHY_RCR, BIT(2) },
  78        [IMX7_RESET_PCIEPHY]            = { SRC_PCIEPHY_RCR, BIT(2) | BIT(1) },
  79        [IMX7_RESET_PCIEPHY_PERST]      = { SRC_PCIEPHY_RCR, BIT(3) },
  80        [IMX7_RESET_PCIE_CTRL_APPS_EN]  = { SRC_PCIEPHY_RCR, BIT(6) },
  81        [IMX7_RESET_PCIE_CTRL_APPS_TURNOFF] = { SRC_PCIEPHY_RCR, BIT(11) },
  82        [IMX7_RESET_DDRC_PRST]          = { SRC_DDRC_RCR, BIT(0) },
  83        [IMX7_RESET_DDRC_CORE_RST]      = { SRC_DDRC_RCR, BIT(1) },
  84};
  85
  86static struct imx7_src *to_imx7_src(struct reset_controller_dev *rcdev)
  87{
  88        return container_of(rcdev, struct imx7_src, rcdev);
  89}
  90
  91static int imx7_reset_set(struct reset_controller_dev *rcdev,
  92                          unsigned long id, bool assert)
  93{
  94        struct imx7_src *imx7src = to_imx7_src(rcdev);
  95        const unsigned int bit = imx7src->signals[id].bit;
  96        unsigned int value = assert ? bit : 0;
  97
  98        switch (id) {
  99        case IMX7_RESET_PCIEPHY:
 100                /*
 101                 * wait for more than 10us to release phy g_rst and
 102                 * btnrst
 103                 */
 104                if (!assert)
 105                        udelay(10);
 106                break;
 107
 108        case IMX7_RESET_PCIE_CTRL_APPS_EN:
 109                value = assert ? 0 : bit;
 110                break;
 111        }
 112
 113        return imx7_reset_update(imx7src, id, value);
 114}
 115
 116static int imx7_reset_assert(struct reset_controller_dev *rcdev,
 117                             unsigned long id)
 118{
 119        return imx7_reset_set(rcdev, id, true);
 120}
 121
 122static int imx7_reset_deassert(struct reset_controller_dev *rcdev,
 123                               unsigned long id)
 124{
 125        return imx7_reset_set(rcdev, id, false);
 126}
 127
 128static const struct imx7_src_variant variant_imx7 = {
 129        .signals = imx7_src_signals,
 130        .signals_num = ARRAY_SIZE(imx7_src_signals),
 131        .ops = {
 132                .assert   = imx7_reset_assert,
 133                .deassert = imx7_reset_deassert,
 134        },
 135};
 136
 137enum imx8mq_src_registers {
 138        SRC_A53RCR0             = 0x0004,
 139        SRC_HDMI_RCR            = 0x0030,
 140        SRC_DISP_RCR            = 0x0034,
 141        SRC_GPU_RCR             = 0x0040,
 142        SRC_VPU_RCR             = 0x0044,
 143        SRC_PCIE2_RCR           = 0x0048,
 144        SRC_MIPIPHY1_RCR        = 0x004c,
 145        SRC_MIPIPHY2_RCR        = 0x0050,
 146        SRC_DDRC2_RCR           = 0x1004,
 147};
 148
 149enum imx8mp_src_registers {
 150        SRC_SUPERMIX_RCR        = 0x0018,
 151        SRC_AUDIOMIX_RCR        = 0x001c,
 152        SRC_MLMIX_RCR           = 0x0028,
 153        SRC_GPU2D_RCR           = 0x0038,
 154        SRC_GPU3D_RCR           = 0x003c,
 155        SRC_VPU_G1_RCR          = 0x0048,
 156        SRC_VPU_G2_RCR          = 0x004c,
 157        SRC_VPUVC8KE_RCR        = 0x0050,
 158        SRC_NOC_RCR             = 0x0054,
 159};
 160
 161static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
 162        [IMX8MQ_RESET_A53_CORE_POR_RESET0]      = { SRC_A53RCR0, BIT(0) },
 163        [IMX8MQ_RESET_A53_CORE_POR_RESET1]      = { SRC_A53RCR0, BIT(1) },
 164        [IMX8MQ_RESET_A53_CORE_POR_RESET2]      = { SRC_A53RCR0, BIT(2) },
 165        [IMX8MQ_RESET_A53_CORE_POR_RESET3]      = { SRC_A53RCR0, BIT(3) },
 166        [IMX8MQ_RESET_A53_CORE_RESET0]          = { SRC_A53RCR0, BIT(4) },
 167        [IMX8MQ_RESET_A53_CORE_RESET1]          = { SRC_A53RCR0, BIT(5) },
 168        [IMX8MQ_RESET_A53_CORE_RESET2]          = { SRC_A53RCR0, BIT(6) },
 169        [IMX8MQ_RESET_A53_CORE_RESET3]          = { SRC_A53RCR0, BIT(7) },
 170        [IMX8MQ_RESET_A53_DBG_RESET0]           = { SRC_A53RCR0, BIT(8) },
 171        [IMX8MQ_RESET_A53_DBG_RESET1]           = { SRC_A53RCR0, BIT(9) },
 172        [IMX8MQ_RESET_A53_DBG_RESET2]           = { SRC_A53RCR0, BIT(10) },
 173        [IMX8MQ_RESET_A53_DBG_RESET3]           = { SRC_A53RCR0, BIT(11) },
 174        [IMX8MQ_RESET_A53_ETM_RESET0]           = { SRC_A53RCR0, BIT(12) },
 175        [IMX8MQ_RESET_A53_ETM_RESET1]           = { SRC_A53RCR0, BIT(13) },
 176        [IMX8MQ_RESET_A53_ETM_RESET2]           = { SRC_A53RCR0, BIT(14) },
 177        [IMX8MQ_RESET_A53_ETM_RESET3]           = { SRC_A53RCR0, BIT(15) },
 178        [IMX8MQ_RESET_A53_SOC_DBG_RESET]        = { SRC_A53RCR0, BIT(20) },
 179        [IMX8MQ_RESET_A53_L2RESET]              = { SRC_A53RCR0, BIT(21) },
 180        [IMX8MQ_RESET_SW_NON_SCLR_M4C_RST]      = { SRC_M4RCR, BIT(0) },
 181        [IMX8MQ_RESET_SW_M4C_RST]               = { SRC_M4RCR, BIT(1) },
 182        [IMX8MQ_RESET_SW_M4P_RST]               = { SRC_M4RCR, BIT(2) },
 183        [IMX8MQ_RESET_M4_ENABLE]                = { SRC_M4RCR, BIT(3) },
 184        [IMX8MQ_RESET_OTG1_PHY_RESET]           = { SRC_USBOPHY1_RCR, BIT(0) },
 185        [IMX8MQ_RESET_OTG2_PHY_RESET]           = { SRC_USBOPHY2_RCR, BIT(0) },
 186        [IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N]    = { SRC_MIPIPHY_RCR, BIT(1) },
 187        [IMX8MQ_RESET_MIPI_DSI_RESET_N]         = { SRC_MIPIPHY_RCR, BIT(2) },
 188        [IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(3) },
 189        [IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(4) },
 190        [IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N]    = { SRC_MIPIPHY_RCR, BIT(5) },
 191        [IMX8MQ_RESET_PCIEPHY]                  = { SRC_PCIEPHY_RCR,
 192                                                    BIT(2) | BIT(1) },
 193        [IMX8MQ_RESET_PCIEPHY_PERST]            = { SRC_PCIEPHY_RCR, BIT(3) },
 194        [IMX8MQ_RESET_PCIE_CTRL_APPS_EN]        = { SRC_PCIEPHY_RCR, BIT(6) },
 195        [IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF]   = { SRC_PCIEPHY_RCR, BIT(11) },
 196        [IMX8MQ_RESET_HDMI_PHY_APB_RESET]       = { SRC_HDMI_RCR, BIT(0) },
 197        [IMX8MQ_RESET_DISP_RESET]               = { SRC_DISP_RCR, BIT(0) },
 198        [IMX8MQ_RESET_GPU_RESET]                = { SRC_GPU_RCR, BIT(0) },
 199        [IMX8MQ_RESET_VPU_RESET]                = { SRC_VPU_RCR, BIT(0) },
 200        [IMX8MQ_RESET_PCIEPHY2]                 = { SRC_PCIE2_RCR,
 201                                                    BIT(2) | BIT(1) },
 202        [IMX8MQ_RESET_PCIEPHY2_PERST]           = { SRC_PCIE2_RCR, BIT(3) },
 203        [IMX8MQ_RESET_PCIE2_CTRL_APPS_EN]       = { SRC_PCIE2_RCR, BIT(6) },
 204        [IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF]  = { SRC_PCIE2_RCR, BIT(11) },
 205        [IMX8MQ_RESET_MIPI_CSI1_CORE_RESET]     = { SRC_MIPIPHY1_RCR, BIT(0) },
 206        [IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET]  = { SRC_MIPIPHY1_RCR, BIT(1) },
 207        [IMX8MQ_RESET_MIPI_CSI1_ESC_RESET]      = { SRC_MIPIPHY1_RCR, BIT(2) },
 208        [IMX8MQ_RESET_MIPI_CSI2_CORE_RESET]     = { SRC_MIPIPHY2_RCR, BIT(0) },
 209        [IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET]  = { SRC_MIPIPHY2_RCR, BIT(1) },
 210        [IMX8MQ_RESET_MIPI_CSI2_ESC_RESET]      = { SRC_MIPIPHY2_RCR, BIT(2) },
 211        [IMX8MQ_RESET_DDRC1_PRST]               = { SRC_DDRC_RCR, BIT(0) },
 212        [IMX8MQ_RESET_DDRC1_CORE_RESET]         = { SRC_DDRC_RCR, BIT(1) },
 213        [IMX8MQ_RESET_DDRC1_PHY_RESET]          = { SRC_DDRC_RCR, BIT(2) },
 214        [IMX8MQ_RESET_DDRC2_PHY_RESET]          = { SRC_DDRC2_RCR, BIT(0) },
 215        [IMX8MQ_RESET_DDRC2_CORE_RESET]         = { SRC_DDRC2_RCR, BIT(1) },
 216        [IMX8MQ_RESET_DDRC2_PRST]               = { SRC_DDRC2_RCR, BIT(2) },
 217};
 218
 219static int imx8mq_reset_set(struct reset_controller_dev *rcdev,
 220                            unsigned long id, bool assert)
 221{
 222        struct imx7_src *imx7src = to_imx7_src(rcdev);
 223        const unsigned int bit = imx7src->signals[id].bit;
 224        unsigned int value = assert ? bit : 0;
 225
 226        switch (id) {
 227        case IMX8MQ_RESET_PCIEPHY:
 228        case IMX8MQ_RESET_PCIEPHY2:
 229                /*
 230                 * wait for more than 10us to release phy g_rst and
 231                 * btnrst
 232                 */
 233                if (!assert)
 234                        udelay(10);
 235                break;
 236
 237        case IMX8MQ_RESET_PCIE_CTRL_APPS_EN:
 238        case IMX8MQ_RESET_PCIE2_CTRL_APPS_EN:
 239        case IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N:
 240        case IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N:
 241        case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N:
 242        case IMX8MQ_RESET_MIPI_DSI_RESET_N:
 243        case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N:
 244        case IMX8MQ_RESET_M4_ENABLE:
 245                value = assert ? 0 : bit;
 246                break;
 247        }
 248
 249        return imx7_reset_update(imx7src, id, value);
 250}
 251
 252static int imx8mq_reset_assert(struct reset_controller_dev *rcdev,
 253                               unsigned long id)
 254{
 255        return imx8mq_reset_set(rcdev, id, true);
 256}
 257
 258static int imx8mq_reset_deassert(struct reset_controller_dev *rcdev,
 259                                 unsigned long id)
 260{
 261        return imx8mq_reset_set(rcdev, id, false);
 262}
 263
 264static const struct imx7_src_variant variant_imx8mq = {
 265        .signals = imx8mq_src_signals,
 266        .signals_num = ARRAY_SIZE(imx8mq_src_signals),
 267        .ops = {
 268                .assert   = imx8mq_reset_assert,
 269                .deassert = imx8mq_reset_deassert,
 270        },
 271};
 272
 273static const struct imx7_src_signal imx8mp_src_signals[IMX8MP_RESET_NUM] = {
 274        [IMX8MP_RESET_A53_CORE_POR_RESET0]      = { SRC_A53RCR0, BIT(0) },
 275        [IMX8MP_RESET_A53_CORE_POR_RESET1]      = { SRC_A53RCR0, BIT(1) },
 276        [IMX8MP_RESET_A53_CORE_POR_RESET2]      = { SRC_A53RCR0, BIT(2) },
 277        [IMX8MP_RESET_A53_CORE_POR_RESET3]      = { SRC_A53RCR0, BIT(3) },
 278        [IMX8MP_RESET_A53_CORE_RESET0]          = { SRC_A53RCR0, BIT(4) },
 279        [IMX8MP_RESET_A53_CORE_RESET1]          = { SRC_A53RCR0, BIT(5) },
 280        [IMX8MP_RESET_A53_CORE_RESET2]          = { SRC_A53RCR0, BIT(6) },
 281        [IMX8MP_RESET_A53_CORE_RESET3]          = { SRC_A53RCR0, BIT(7) },
 282        [IMX8MP_RESET_A53_DBG_RESET0]           = { SRC_A53RCR0, BIT(8) },
 283        [IMX8MP_RESET_A53_DBG_RESET1]           = { SRC_A53RCR0, BIT(9) },
 284        [IMX8MP_RESET_A53_DBG_RESET2]           = { SRC_A53RCR0, BIT(10) },
 285        [IMX8MP_RESET_A53_DBG_RESET3]           = { SRC_A53RCR0, BIT(11) },
 286        [IMX8MP_RESET_A53_ETM_RESET0]           = { SRC_A53RCR0, BIT(12) },
 287        [IMX8MP_RESET_A53_ETM_RESET1]           = { SRC_A53RCR0, BIT(13) },
 288        [IMX8MP_RESET_A53_ETM_RESET2]           = { SRC_A53RCR0, BIT(14) },
 289        [IMX8MP_RESET_A53_ETM_RESET3]           = { SRC_A53RCR0, BIT(15) },
 290        [IMX8MP_RESET_A53_SOC_DBG_RESET]        = { SRC_A53RCR0, BIT(20) },
 291        [IMX8MP_RESET_A53_L2RESET]              = { SRC_A53RCR0, BIT(21) },
 292        [IMX8MP_RESET_SW_NON_SCLR_M7C_RST]      = { SRC_M4RCR, BIT(0) },
 293        [IMX8MP_RESET_OTG1_PHY_RESET]           = { SRC_USBOPHY1_RCR, BIT(0) },
 294        [IMX8MP_RESET_OTG2_PHY_RESET]           = { SRC_USBOPHY2_RCR, BIT(0) },
 295        [IMX8MP_RESET_SUPERMIX_RESET]           = { SRC_SUPERMIX_RCR, BIT(0) },
 296        [IMX8MP_RESET_AUDIOMIX_RESET]           = { SRC_AUDIOMIX_RCR, BIT(0) },
 297        [IMX8MP_RESET_MLMIX_RESET]              = { SRC_MLMIX_RCR, BIT(0) },
 298        [IMX8MP_RESET_PCIEPHY]                  = { SRC_PCIEPHY_RCR, BIT(2) },
 299        [IMX8MP_RESET_PCIEPHY_PERST]            = { SRC_PCIEPHY_RCR, BIT(3) },
 300        [IMX8MP_RESET_PCIE_CTRL_APPS_EN]        = { SRC_PCIEPHY_RCR, BIT(6) },
 301        [IMX8MP_RESET_PCIE_CTRL_APPS_TURNOFF]   = { SRC_PCIEPHY_RCR, BIT(11) },
 302        [IMX8MP_RESET_HDMI_PHY_APB_RESET]       = { SRC_HDMI_RCR, BIT(0) },
 303        [IMX8MP_RESET_MEDIA_RESET]              = { SRC_DISP_RCR, BIT(0) },
 304        [IMX8MP_RESET_GPU2D_RESET]              = { SRC_GPU2D_RCR, BIT(0) },
 305        [IMX8MP_RESET_GPU3D_RESET]              = { SRC_GPU3D_RCR, BIT(0) },
 306        [IMX8MP_RESET_GPU_RESET]                = { SRC_GPU_RCR, BIT(0) },
 307        [IMX8MP_RESET_VPU_RESET]                = { SRC_VPU_RCR, BIT(0) },
 308        [IMX8MP_RESET_VPU_G1_RESET]             = { SRC_VPU_G1_RCR, BIT(0) },
 309        [IMX8MP_RESET_VPU_G2_RESET]             = { SRC_VPU_G2_RCR, BIT(0) },
 310        [IMX8MP_RESET_VPUVC8KE_RESET]           = { SRC_VPUVC8KE_RCR, BIT(0) },
 311        [IMX8MP_RESET_NOC_RESET]                = { SRC_NOC_RCR, BIT(0) },
 312};
 313
 314static int imx8mp_reset_set(struct reset_controller_dev *rcdev,
 315                            unsigned long id, bool assert)
 316{
 317        struct imx7_src *imx7src = to_imx7_src(rcdev);
 318        const unsigned int bit = imx7src->signals[id].bit;
 319        unsigned int value = assert ? bit : 0;
 320
 321        switch (id) {
 322        case IMX8MP_RESET_PCIEPHY:
 323                /*
 324                 * wait for more than 10us to release phy g_rst and
 325                 * btnrst
 326                 */
 327                if (!assert)
 328                        udelay(10);
 329                break;
 330
 331        case IMX8MP_RESET_PCIE_CTRL_APPS_EN:
 332                value = assert ? 0 : bit;
 333                break;
 334        }
 335
 336        return imx7_reset_update(imx7src, id, value);
 337}
 338
 339static int imx8mp_reset_assert(struct reset_controller_dev *rcdev,
 340                               unsigned long id)
 341{
 342        return imx8mp_reset_set(rcdev, id, true);
 343}
 344
 345static int imx8mp_reset_deassert(struct reset_controller_dev *rcdev,
 346                                 unsigned long id)
 347{
 348        return imx8mp_reset_set(rcdev, id, false);
 349}
 350
 351static const struct imx7_src_variant variant_imx8mp = {
 352        .signals = imx8mp_src_signals,
 353        .signals_num = ARRAY_SIZE(imx8mp_src_signals),
 354        .ops = {
 355                .assert   = imx8mp_reset_assert,
 356                .deassert = imx8mp_reset_deassert,
 357        },
 358};
 359
 360static int imx7_reset_probe(struct platform_device *pdev)
 361{
 362        struct imx7_src *imx7src;
 363        struct device *dev = &pdev->dev;
 364        struct regmap_config config = { .name = "src" };
 365        const struct imx7_src_variant *variant = of_device_get_match_data(dev);
 366
 367        imx7src = devm_kzalloc(dev, sizeof(*imx7src), GFP_KERNEL);
 368        if (!imx7src)
 369                return -ENOMEM;
 370
 371        imx7src->signals = variant->signals;
 372        imx7src->regmap = syscon_node_to_regmap(dev->of_node);
 373        if (IS_ERR(imx7src->regmap)) {
 374                dev_err(dev, "Unable to get imx7-src regmap");
 375                return PTR_ERR(imx7src->regmap);
 376        }
 377        regmap_attach_dev(dev, imx7src->regmap, &config);
 378
 379        imx7src->rcdev.owner     = THIS_MODULE;
 380        imx7src->rcdev.nr_resets = variant->signals_num;
 381        imx7src->rcdev.ops       = &variant->ops;
 382        imx7src->rcdev.of_node   = dev->of_node;
 383
 384        return devm_reset_controller_register(dev, &imx7src->rcdev);
 385}
 386
 387static const struct of_device_id imx7_reset_dt_ids[] = {
 388        { .compatible = "fsl,imx7d-src", .data = &variant_imx7 },
 389        { .compatible = "fsl,imx8mq-src", .data = &variant_imx8mq },
 390        { .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp },
 391        { /* sentinel */ },
 392};
 393MODULE_DEVICE_TABLE(of, imx7_reset_dt_ids);
 394
 395static struct platform_driver imx7_reset_driver = {
 396        .probe  = imx7_reset_probe,
 397        .driver = {
 398                .name           = KBUILD_MODNAME,
 399                .of_match_table = imx7_reset_dt_ids,
 400        },
 401};
 402module_platform_driver(imx7_reset_driver);
 403
 404MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
 405MODULE_DESCRIPTION("NXP i.MX7 reset driver");
 406MODULE_LICENSE("GPL v2");
 407