From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jun Nie Subject: Re: [PATCH v2 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family Date: Mon, 16 Jan 2017 22:28:41 +0800 Message-ID: <95ebb6fd-540b-f6d5-e039-2cd718ff35d8@linaro.org> References: <1484564194-18530-1-git-send-email-baoyou.xie@linaro.org> <1484564194-18530-3-git-send-email-baoyou.xie@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1484564194-18530-3-git-send-email-baoyou.xie@linaro.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Baoyou Xie , p.zabel@pengutronix.de, robh+dt@kernel.org, mark.rutland@arm.com Cc: devicetree@vger.kernel.org, xie.baoyou@zte.com.cn, linux-kernel@vger.kernel.org, chen.chaokai@zte.com.cn, wang.qiang01@zte.com.cn, shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org T24gMjAxN+W5tDAx5pyIMTbml6UgMTg6NTYsIEJhb3lvdSBYaWUgd3JvdGU6Cj4gVGhpcyBwYXRj aCBhZGRzIHJlc2V0IGNvbnRyb2xsZXIgZHJpdmVyIGZvciBaVEUncyB6eDI5NjcgZmFtaWx5Lgo+ Cj4gU2lnbmVkLW9mZi1ieTogQmFveW91IFhpZSA8YmFveW91LnhpZUBsaW5hcm8ub3JnPgo+IC0t LQo+ICBkcml2ZXJzL3Jlc2V0L0tjb25maWcgICAgICAgIHwgICA2ICsrKwo+ICBkcml2ZXJzL3Jl c2V0L01ha2VmaWxlICAgICAgIHwgICAxICsKPiAgZHJpdmVycy9yZXNldC9yZXNldC16eDI5Njcu YyB8IDEyNSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIDMg ZmlsZXMgY2hhbmdlZCwgMTMyIGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRy aXZlcnMvcmVzZXQvcmVzZXQtengyOTY3LmMKPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Jlc2V0 L0tjb25maWcgYi9kcml2ZXJzL3Jlc2V0L0tjb25maWcKPiBpbmRleCAxNzJkYzk2Li5mNGNkZmU5 IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvcmVzZXQvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvcmVz ZXQvS2NvbmZpZwo+IEBAIC04Niw2ICs4NiwxMiBAQCBjb25maWcgUkVTRVRfVU5JUEhJRVIKPiAg CSAgU2F5IFkgaWYgeW91IHdhbnQgdG8gY29udHJvbCByZXNldCBzaWduYWxzIHByb3ZpZGVkIGJ5 IFN5c3RlbSBDb250cm9sCj4gIAkgIGJsb2NrLCBNZWRpYSBJL08gYmxvY2ssIFBlcmlwaGVyYWwg QmxvY2suCj4KPiArY29uZmlnIFJFU0VUX1pYMjk2Nwo+ICsJYm9vbCAiWlRFIFpYMjk2NyBSZXNl dCBEcml2ZXIiCj4gKwlkZXBlbmRzIG9uIEFSQ0hfWlggfHwgQ09NUElMRV9URVNUCj4gKwloZWxw Cj4gKwkgIFRoaXMgZW5hYmxlcyB0aGUgcmVzZXQgY29udHJvbGxlciBkcml2ZXIgZm9yIFpURSdz IHp4Mjk2NyBmYW1pbHkuCj4gKwo+ICBjb25maWcgUkVTRVRfWllOUQo+ICAJYm9vbCAiWllOUSBS ZXNldCBEcml2ZXIiIGlmIENPTVBJTEVfVEVTVAo+ICAJZGVmYXVsdCBBUkNIX1pZTlEKPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9yZXNldC9NYWtlZmlsZSBiL2RyaXZlcnMvcmVzZXQvTWFrZWZpbGUK PiBpbmRleCAxM2IzNDZlLi4yY2QzZjZjIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvcmVzZXQvTWFr ZWZpbGUKPiArKysgYi9kcml2ZXJzL3Jlc2V0L01ha2VmaWxlCj4gQEAgLTEzLDQgKzEzLDUgQEAg b2JqLSQoQ09ORklHX1JFU0VUX1NUTTMyKSArPSByZXNldC1zdG0zMi5vCj4gIG9iai0kKENPTkZJ R19SRVNFVF9TVU5YSSkgKz0gcmVzZXQtc3VueGkubwo+ICBvYmotJChDT05GSUdfVElfU1lTQ09O X1JFU0VUKSArPSByZXNldC10aS1zeXNjb24ubwo+ICBvYmotJChDT05GSUdfUkVTRVRfVU5JUEhJ RVIpICs9IHJlc2V0LXVuaXBoaWVyLm8KPiArb2JqLSQoQ09ORklHX1JFU0VUX1pYMjk2NykgKz0g cmVzZXQtengyOTY3Lm8KPiAgb2JqLSQoQ09ORklHX1JFU0VUX1pZTlEpICs9IHJlc2V0LXp5bnEu bwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Jlc2V0L3Jlc2V0LXp4Mjk2Ny5jIGIvZHJpdmVycy9y ZXNldC9yZXNldC16eDI5NjcuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAw MC4uYmM5NTI2MQo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL3Jlc2V0L3Jlc2V0LXp4 Mjk2Ny5jCj4gQEAgLTAsMCArMSwxMjUgQEAKPiArLyoKPiArICogWlRFJ3MgengyOTY3IGZhbWls eSByZXNldCBjb250cm9sbGVyIGRyaXZlcgo+ICsgKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTcg WlRFIEx0ZC4KPiArICoKPiArICogQXV0aG9yOiBCYW95b3UgWGllIDxiYW95b3UueGllQGxpbmFy by5vcmc+Cj4gKyAqCj4gKyAqIExpY2Vuc2UgdGVybXM6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl bnNlIChHUEwpIHZlcnNpb24gMgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPiArI2luY2x1ZGUgPGxpbnV4L29mX2FkZHJlc3MuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Bs YXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvcmVzZXQtY29udHJvbGxlci5oPgo+ ICsKPiArc3RydWN0IHp4Mjk2N19yZXNldCB7Cj4gKwl2b2lkIF9faW9tZW0JCQkqcmVnX2Jhc2U7 Cj4gKwlzcGlubG9ja190CQkJbG9jazsKPiArCXN0cnVjdCByZXNldF9jb250cm9sbGVyX2Rldgly Y2RldjsKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgengyOTY3X3Jlc2V0X2FjdChzdHJ1Y3QgcmVz ZXRfY29udHJvbGxlcl9kZXYgKnJjZGV2LAo+ICsJCQkgICAgdW5zaWduZWQgbG9uZyBpZCwgYm9v bCBhc3NlcnQpCj4gK3sKPiArCXN0cnVjdCB6eDI5NjdfcmVzZXQgKnJlc2V0ID0gTlVMTDsKPiAr CXUzMiBiYW5rID0gaWQgLyAzMjsKPiArCXUzMiBvZmZzZXQgPSBpZCAlIDMyOwo+ICsJdTMyIHJl ZzsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsJcmVzZXQgPSBjb250YWluZXJfb2Yo cmNkZXYsIHN0cnVjdCB6eDI5NjdfcmVzZXQsIHJjZGV2KTsKPiArCj4gKwlzcGluX2xvY2tfaXJx c2F2ZSgmcmVzZXQtPmxvY2ssIGZsYWdzKTsKPiArCj4gKwlyZWcgPSByZWFkbChyZXNldC0+cmVn X2Jhc2UgKyAoYmFuayAqIDQpKTsKCnJlYWRsX3JlbGF4ZWQgaXMgcmVjb21tZW5kZWQuCgo+ICsJ aWYgKGFzc2VydCkKPiArCQlyZWcgJj0gfkJJVChvZmZzZXQpOwo+ICsJZWxzZQo+ICsJCXJlZyB8 PSBCSVQob2Zmc2V0KTsKPiArCXdyaXRlbChyZWcsIHJlc2V0LT5yZWdfYmFzZSArIChiYW5rICog NCkpOwoKd3JpdGVsX3JlbGF4ZWQgaXMgcmVjb21tZW5kZWQuCgo+ICsKPiArCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJnJlc2V0LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgengyOTY3X3Jlc2V0X2Fzc2VydChzdHJ1Y3QgcmVzZXRfY29udHJv bGxlcl9kZXYgKnJjZGV2LAo+ICsJCQkgICAgICAgdW5zaWduZWQgbG9uZyBpZCkKPiArewo+ICsJ cmV0dXJuIHp4Mjk2N19yZXNldF9hY3QocmNkZXYsIGlkLCB0cnVlKTsKPiArfQo+ICsKPiArc3Rh dGljIGludCB6eDI5NjdfcmVzZXRfZGVhc3NlcnQoc3RydWN0IHJlc2V0X2NvbnRyb2xsZXJfZGV2 ICpyY2RldiwKPiArCQkJCSB1bnNpZ25lZCBsb25nIGlkKQo+ICt7Cj4gKwlyZXR1cm4gengyOTY3 X3Jlc2V0X2FjdChyY2RldiwgaWQsIGZhbHNlKTsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBy ZXNldF9jb250cm9sX29wcyB6eDI5NjdfcmVzZXRfb3BzID0gewo+ICsJLmFzc2VydAkJPSB6eDI5 NjdfcmVzZXRfYXNzZXJ0LAo+ICsJLmRlYXNzZXJ0CT0gengyOTY3X3Jlc2V0X2RlYXNzZXJ0LAo+ ICt9Owo+ICsKPiArc3RhdGljIGludCB6eDI5NjdfcmVzZXRfcHJvYmUoc3RydWN0IHBsYXRmb3Jt X2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IHp4Mjk2N19yZXNldCAqcmVzZXQ7Cj4gKwlz dHJ1Y3QgcmVzb3VyY2UgKnJlczsKPiArCj4gKwlyZXNldCA9IGRldm1fa3phbGxvYygmcGRldi0+ ZGV2LCBzaXplb2YoKnJlc2V0KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXJlc2V0KQo+ICsJCXJl dHVybiAtRU5PTUVNOwo+ICsKPiArCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJ T1JFU09VUkNFX01FTSwgMCk7Cj4gKwlyZXNldC0+cmVnX2Jhc2UgPSBkZXZtX2lvcmVtYXBfcmVz b3VyY2UoJnBkZXYtPmRldiwgcmVzKTsKPiArCWlmIChJU19FUlIocmVzZXQtPnJlZ19iYXNlKSkK PiArCQlyZXR1cm4gUFRSX0VSUihyZXNldC0+cmVnX2Jhc2UpOwo+ICsKPiArCXNwaW5fbG9ja19p bml0KCZyZXNldC0+bG9jayk7Cj4gKwo+ICsJcmVzZXQtPnJjZGV2Lm93bmVyID0gVEhJU19NT0RV TEU7Cj4gKwlyZXNldC0+cmNkZXYubnJfcmVzZXRzID0gcmVzb3VyY2Vfc2l6ZShyZXMpICogODsK PiArCXJlc2V0LT5yY2Rldi5vcHMgPSAmengyOTY3X3Jlc2V0X29wczsKPiArCXJlc2V0LT5yY2Rl di5vZl9ub2RlID0gcGRldi0+ZGV2Lm9mX25vZGU7Cj4gKwo+ICsJZGV2X2luZm8oJnBkZXYtPmRl diwgInJlc2V0IGNvbnRyb2xsZXIgY250OiVkIiwKPiArCQkgIHJlc2V0LT5yY2Rldi5ucl9yZXNl dHMpOwo+ICsKPiArCXJldHVybiBkZXZtX3Jlc2V0X2NvbnRyb2xsZXJfcmVnaXN0ZXIoJnBkZXYt PmRldiwgJnJlc2V0LT5yY2Rldik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgengyOTY3X3Jlc2V0 X3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgengyOTY3X3Jlc2V0 X2R0X2lkc1tdID0gewo+ICsJIHsgLmNvbXBhdGlibGUgPSAienRlLHp4Mjk2NzE4LXJlc2V0Iiwg fSwKPiArCSB7fSwKPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgengyOTY3X3Jlc2V0 X2R0X2lkcyk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciB6eDI5NjdfcmVz ZXRfZHJpdmVyID0gewo+ICsJLnByb2JlCT0gengyOTY3X3Jlc2V0X3Byb2JlLAo+ICsJLnJlbW92 ZQk9IHp4Mjk2N19yZXNldF9yZW1vdmUsCj4gKwkuZHJpdmVyID0gewo+ICsJCS5uYW1lCQk9ICJ6 eDI5NjctcmVzZXQiLAo+ICsJCS5vZl9tYXRjaF90YWJsZQk9IHp4Mjk2N19yZXNldF9kdF9pZHMs Cj4gKwl9LAo+ICt9OwoKVGhpcyBsaW5lIGNhbiByZXBsYWNlIGFsbCBiZWxvdyBjb2RlIGlmIHlv dSBkbyBub3QgaGF2ZSBhbnkgb3RoZXIgCmRlcGVuZGVuY3kgaW4gZWFybGllciBzdGFnZS4KCmJ1 aWx0aW5fcGxhdGZvcm1fZHJpdmVyKHp4Mjk2N19yZXNldF9kcml2ZXIpOwoKPiArCj4gK3N0YXRp YyBpbnQgX19pbml0IHp4Mjk2N19yZXNldF9pbml0KHZvaWQpCj4gK3sKPiArCXJldHVybiBwbGF0 Zm9ybV9kcml2ZXJfcmVnaXN0ZXIoJnp4Mjk2N19yZXNldF9kcml2ZXIpOwo+ICt9Cj4gK2FyY2hf aW5pdGNhbGwoengyOTY3X3Jlc2V0X2luaXQpOwo+ICsKPiArc3RhdGljIHZvaWQgX19leGl0IHp4 Mjk2N19yZXNldF9leGl0KHZvaWQpCj4gK3sKPiArCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVy KCZ6eDI5NjdfcmVzZXRfZHJpdmVyKTsKPiArfQo+ICttb2R1bGVfZXhpdCh6eDI5NjdfcmVzZXRf ZXhpdCk7Cj4gKwo+ICtNT0RVTEVfQVVUSE9SKCJCYW95b3UgWGllIDxiYW95b3UueGllQGxpbmFy by5vcmc+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiWlRFIHp4Mjk2NyBSZXNldCBDb250cm9s bGVyIERyaXZlciIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7Cj4KCgpfX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxp bmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3Rz LmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: jun.nie@linaro.org (Jun Nie) Date: Mon, 16 Jan 2017 22:28:41 +0800 Subject: [PATCH v2 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family In-Reply-To: <1484564194-18530-3-git-send-email-baoyou.xie@linaro.org> References: <1484564194-18530-1-git-send-email-baoyou.xie@linaro.org> <1484564194-18530-3-git-send-email-baoyou.xie@linaro.org> Message-ID: <95ebb6fd-540b-f6d5-e039-2cd718ff35d8@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 2017?01?16? 18:56, Baoyou Xie wrote: > This patch adds reset controller driver for ZTE's zx2967 family. > > Signed-off-by: Baoyou Xie > --- > drivers/reset/Kconfig | 6 +++ > drivers/reset/Makefile | 1 + > drivers/reset/reset-zx2967.c | 125 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 132 insertions(+) > create mode 100644 drivers/reset/reset-zx2967.c > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > index 172dc96..f4cdfe9 100644 > --- a/drivers/reset/Kconfig > +++ b/drivers/reset/Kconfig > @@ -86,6 +86,12 @@ config RESET_UNIPHIER > Say Y if you want to control reset signals provided by System Control > block, Media I/O block, Peripheral Block. > > +config RESET_ZX2967 > + bool "ZTE ZX2967 Reset Driver" > + depends on ARCH_ZX || COMPILE_TEST > + help > + This enables the reset controller driver for ZTE's zx2967 family. > + > config RESET_ZYNQ > bool "ZYNQ Reset Driver" if COMPILE_TEST > default ARCH_ZYNQ > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile > index 13b346e..2cd3f6c 100644 > --- a/drivers/reset/Makefile > +++ b/drivers/reset/Makefile > @@ -13,4 +13,5 @@ obj-$(CONFIG_RESET_STM32) += reset-stm32.o > obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o > obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o > obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o > +obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o > obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o > diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c > new file mode 100644 > index 0000000..bc95261 > --- /dev/null > +++ b/drivers/reset/reset-zx2967.c > @@ -0,0 +1,125 @@ > +/* > + * ZTE's zx2967 family reset controller driver > + * > + * Copyright (C) 2017 ZTE Ltd. > + * > + * Author: Baoyou Xie > + * > + * License terms: GNU General Public License (GPL) version 2 > + */ > + > +#include > +#include > +#include > +#include > + > +struct zx2967_reset { > + void __iomem *reg_base; > + spinlock_t lock; > + struct reset_controller_dev rcdev; > +}; > + > +static int zx2967_reset_act(struct reset_controller_dev *rcdev, > + unsigned long id, bool assert) > +{ > + struct zx2967_reset *reset = NULL; > + u32 bank = id / 32; > + u32 offset = id % 32; > + u32 reg; > + unsigned long flags; > + > + reset = container_of(rcdev, struct zx2967_reset, rcdev); > + > + spin_lock_irqsave(&reset->lock, flags); > + > + reg = readl(reset->reg_base + (bank * 4)); readl_relaxed is recommended. > + if (assert) > + reg &= ~BIT(offset); > + else > + reg |= BIT(offset); > + writel(reg, reset->reg_base + (bank * 4)); writel_relaxed is recommended. > + > + spin_unlock_irqrestore(&reset->lock, flags); > + > + return 0; > +} > + > +static int zx2967_reset_assert(struct reset_controller_dev *rcdev, > + unsigned long id) > +{ > + return zx2967_reset_act(rcdev, id, true); > +} > + > +static int zx2967_reset_deassert(struct reset_controller_dev *rcdev, > + unsigned long id) > +{ > + return zx2967_reset_act(rcdev, id, false); > +} > + > +static struct reset_control_ops zx2967_reset_ops = { > + .assert = zx2967_reset_assert, > + .deassert = zx2967_reset_deassert, > +}; > + > +static int zx2967_reset_probe(struct platform_device *pdev) > +{ > + struct zx2967_reset *reset; > + struct resource *res; > + > + reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); > + if (!reset) > + return -ENOMEM; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + reset->reg_base = devm_ioremap_resource(&pdev->dev, res); > + if (IS_ERR(reset->reg_base)) > + return PTR_ERR(reset->reg_base); > + > + spin_lock_init(&reset->lock); > + > + reset->rcdev.owner = THIS_MODULE; > + reset->rcdev.nr_resets = resource_size(res) * 8; > + reset->rcdev.ops = &zx2967_reset_ops; > + reset->rcdev.of_node = pdev->dev.of_node; > + > + dev_info(&pdev->dev, "reset controller cnt:%d", > + reset->rcdev.nr_resets); > + > + return devm_reset_controller_register(&pdev->dev, &reset->rcdev); > +} > + > +static int zx2967_reset_remove(struct platform_device *pdev) > +{ > + return 0; > +} > + > +static const struct of_device_id zx2967_reset_dt_ids[] = { > + { .compatible = "zte,zx296718-reset", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids); > + > +static struct platform_driver zx2967_reset_driver = { > + .probe = zx2967_reset_probe, > + .remove = zx2967_reset_remove, > + .driver = { > + .name = "zx2967-reset", > + .of_match_table = zx2967_reset_dt_ids, > + }, > +}; This line can replace all below code if you do not have any other dependency in earlier stage. builtin_platform_driver(zx2967_reset_driver); > + > +static int __init zx2967_reset_init(void) > +{ > + return platform_driver_register(&zx2967_reset_driver); > +} > +arch_initcall(zx2967_reset_init); > + > +static void __exit zx2967_reset_exit(void) > +{ > + platform_driver_unregister(&zx2967_reset_driver); > +} > +module_exit(zx2967_reset_exit); > + > +MODULE_AUTHOR("Baoyou Xie "); > +MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver"); > +MODULE_LICENSE("GPL"); >