Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752567AbdHPUrD (ORCPT ); Wed, 16 Aug 2017 16:47:03 -0400 Received: from mail-co1nam03on0063.outbound.protection.outlook.com ([104.47.40.63]:47057 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752138AbdHPUrB (ORCPT ); Wed, 16 Aug 2017 16:47:01 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=alex.g@adaptrum.com; Subject: Re: [PATCH v3 1/5] reset: add reset-simple to unify socfpga, stm32, sunxi, and zx2967 To: Philipp Zabel , linux-kernel@vger.kernel.org References: <20170816094701.30678-1-p.zabel@pengutronix.de> <20170816094701.30678-2-p.zabel@pengutronix.de> Cc: Andre Przywara , Maxime Coquelin , Alexandre Torgue , Maxime Ripard , Chen-Yu Tsai , Baoyou Xie , Eugeniy Paltsev , Steffen Trumtrar , Dinh Nguyen , =?UTF-8?Q?Andreas_F=c3=a4rber?= , linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de From: Alexandru Gagniuc Message-ID: <59f82342-5e1d-2e22-a170-8c010b5db9b8@adaptrum.com> Date: Wed, 16 Aug 2017 13:46:53 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20170816094701.30678-2-p.zabel@pengutronix.de> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [198.0.218.81] X-ClientProxiedBy: MWHPR13CA0038.namprd13.prod.outlook.com (10.173.117.152) To BN6PR04MB0837.namprd04.prod.outlook.com (10.172.199.18) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 45b327c5-c29f-49c9-8498-08d4e4e7f08d X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(2017082002075)(300000503095)(300135400095)(201703131423075)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);SRVR:BN6PR04MB0837; X-Microsoft-Exchange-Diagnostics: 1;BN6PR04MB0837;3:k7quVx53lT9ux3iOBp32Gbmubmn354cObO3z8ogOcPHi6+YcabPWDGY+yvAvLa4/KtvvIOy0SFyiqB5Ps3Sl6bgNTThu01uYRYA/YYnuYXJglUtGPa7IETCkFba33sowHp1x8LF1H1NVh47uvVrZcMwcESpTZSz4AdKidoq0+oc2voa2bgJ3uOa8OyZB30qbMMNLvAplb0+66FCK48MKNjDI9NkEKchl6acInINQkzSqLWeo8CZscWGaybfUotCm;25:Gfjg5YsYC9sCsgvpdzRZ09j+GU0Dxwa4FL1+6xl/h6R7ErMw1wzWH/rybsx7sRTJLJ1A8T/VzWQObyWdh+WjtppLzgL3xADWWtEcshpBYTvYU6ovz+8rb2NxMIXFhAOvxkyn/YTGklcg0TIaDsShveoGrSTAceOS6wOz68O9c4raA91kPEE6FdmfM4kVcpHVVnisYKDyxAtQRfS6Ex8Bj2Fv/jLeQenCG2sk+4jMPXIwIcQHslFz2YATSpk/F6/VX+FujlSoEMo93LYZ4hPbU8hx2O88+Vw6hV/BmSkdOxrXO6JyMRqNP4VLU9oStel2Xl62PJ5vKMVgRqSj4mLC9Q==;31:6WdfARIwi5PP9C3xykl5qOmSmWGZ1OI6+RfDGao937TblHHQ8GiUPNZ9iwz3h7Pi2+yZvNwlPbyGqLh6a5qVh7Z+GPlSROmYMmrltxLyWql6n2nwWwP73JzvBAGGCf+06/0WhSaA+T8fBWtNnQbANWfdccTo23fHWeYnU41zv+KKP7PwoijI701Mz+V+wHafEex5Dp2CXOld76iks2XWSE4M5LDjCt6e09fK+kQQlgY= X-MS-TrafficTypeDiagnostic: BN6PR04MB0837: X-Exchange-Antispam-Report-Test: UriScan:(788757137089)(58145275503218); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(93006095)(93001095)(100000703101)(100105400095)(6041248)(20161123564025)(2016111802025)(20161123562025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123560025)(20161123555025)(6072148)(6043046)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:BN6PR04MB0837;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:BN6PR04MB0837; X-Microsoft-Exchange-Diagnostics: 1;BN6PR04MB0837;4:DTnzZYKo5ZGVn+8kwvowOrhhROCsqRjYC4n6vRSc0SfvlabNNqQPkdotg/bm5a8K6UitrkmcbWEqyxy4v/G0oXjIFoC33U08YZmT2w8l/AjxRbh511yd7GsFu0ujun9KN4qC6aESyjV04Fg9xQ2lef/n8xKCI9zBkxIbNEEohbHfQ/YPxA8gefUX+kV5wkT3J8vjoj7CxWeenc5wib5i6kipzr+OXSTraFdCzibXtw4qmju+t1qjwFLAuck2VsEhocxsy5PsIRZ3qKpZqrlSY+AhPtTEVC8W2O1ZhwqZb5ueb5URtRV3yiieF6aaoWSikgRYixWSiv4Ut/gFxdRQeQ== X-Forefront-PRVS: 0401647B7F X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(7370300001)(6009001)(189002)(24454002)(199003)(377454003)(305945005)(53936002)(5660300001)(33646002)(106356001)(42186005)(105586002)(7350300001)(110136004)(53546010)(4326008)(6246003)(7416002)(8676002)(7736002)(81156014)(25786009)(6512007)(68736007)(54356999)(65826007)(81166006)(6486002)(50986999)(101416001)(76176999)(6506006)(54906002)(50466002)(6666003)(66066001)(229853002)(2950100002)(65806001)(65956001)(47776003)(83506001)(189998001)(23746002)(4001350100001)(64126003)(31686004)(97736004)(2906002)(230700001)(86362001)(478600001)(31696002)(3846002)(6116002)(36756003)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BN6PR04MB0837;H:dev2.adaptrum;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?Windows-1252?Q?1;BN6PR04MB0837;23:r9B6X6NMV4lG5hbyEbHoisWLeDtdUS6wyX6Ny?= =?Windows-1252?Q?tSv2E1wHgG/h668HHTwWpNO9dCoxtEFjrN57PyqKmVFCSwF0rdB7wVsZ?= =?Windows-1252?Q?tC87ed09NRycWyV/oQ6JRnfJ4on6Akkk98tEcxy4Jz8masYLmzIgnIS7?= =?Windows-1252?Q?dPgVxUiylTVw5C6YgtP92wr7niCxrGdSgr9D/7Xcl/VufWoRvnYJnbR9?= =?Windows-1252?Q?4O2e0a9DpLMLw1SD/wN/AKucNhDEEYh5PmHPB0S6TuCWTHonMQaiNhK8?= =?Windows-1252?Q?3BwmcG383oEfs0Mbdz3iSzrxA3B1/KtR3fS9Mw0GEAGqLjGg/woYrflX?= =?Windows-1252?Q?T2BbyasTH3n7bKD5WZydGWwpU2aM39VYbgjg5aJo28iSveN+XVkgf6/K?= =?Windows-1252?Q?ubuWPTnF+X9It3oCtOBEkMCHp1Zp68ytrjb6DVynvLAlcA3LyU4MKHrg?= =?Windows-1252?Q?8t/abYMk651i/PdlLKwLrvxDthVtNaPFja955V5iBen9u+5fjunVkEg+?= =?Windows-1252?Q?CYwSk8o7ZX+Vj35hf7P/TKUmFPTx/jZ1SAwhi64iNh2AvYIPLUp51eRv?= =?Windows-1252?Q?bgx00rC8Z/QOpNT3XjqBFjHUtyJgjHQC02QsWblERwqYehppv4wPZwCg?= =?Windows-1252?Q?oR50tkQDUSSaSkoE9bcdGmI7rKjHSuh0SV/YLbrxjEuXWePpdi6StRQ+?= =?Windows-1252?Q?Bgm95tzrPqEVfhohgaA1gnu+9LXeOcH4evJUFm2KPL6Sxw4gARggpjCe?= =?Windows-1252?Q?BDII8ZofPcr+/wZR52fHwHY1cffyD7+lpHDFpUnZ5EiyHXipnSIyWwiC?= =?Windows-1252?Q?F8Enz5Hq1zT9fOzFi+cHsF8Cn8lDcmz0nWU+PD5EDbKiGcE0YC3/V3jt?= =?Windows-1252?Q?oFS7542OJzRoYsVUlrip0ME/ArauAv2pSF0fYAShatnhiqK9riBu8B1D?= =?Windows-1252?Q?q7Kcf1VBhV+fzSDft6TQs4wNcIlLkMkZwEnPz0mzxE5yDNZ3dJiIt23V?= =?Windows-1252?Q?K7Lajkuy1cryzNz6qrchabB37paLd1N90qgkpyfZqqWOCkFyrEyuAdqg?= =?Windows-1252?Q?Ef9Z/2tY9tPJFBz+/49Vismnarh9HKPkC/h/Ja/RxyvDouWY90u7Q9Wk?= =?Windows-1252?Q?yfWAf8IATAjD/8i0/xtsasOGigXBOex9TvVHusZqz+JHZuOyI/t+fTnJ?= =?Windows-1252?Q?icF/TB3W4aNb1neEOAFxGVOnYhGIcQlfUKm9530nfuhwiC7HilH76s3X?= =?Windows-1252?Q?TuJGtSVg6MR7M2jeIPqmB5C9FDWsn/DzN59gmkFnYzbJP04t47IVWGHd?= =?Windows-1252?Q?JKwLoVEcldmtLZi5LBsmFx6fsy2LNgyhGuqM2ng5jiazxW6TuEKDG0VV?= =?Windows-1252?Q?Wjb3AM3Dh79TS1NbllpRXUmafSwjR3cfCvvug4l1bVYhMZupBqyCQ7zd?= =?Windows-1252?Q?kO66wIOmFRy8veUlHP9J68x4UiNZiwjLN30knyapkzMuBhy3bne5isMY?= =?Windows-1252?Q?ScwIBTjl4MJXuOEHErYQ2PvZHaC?= X-Microsoft-Exchange-Diagnostics: 1;BN6PR04MB0837;6:w3yQdFlbM9UlDtjAZRlbUhIUC/1vTwCXkvVIS1AixxUBKYg06CLJYCVU+ij1p9E074LFHIa5QKOCQRgo4Gisb/Q4wshMJlfBnsD9/a2Ose+8fzt78sL7IFLPAFOAw2SUorHlTTooZWOg7//xgMo0mka7/2fwBQKdTlKLUiN2xbYzekfV78ByqmW3A5UHGejC9Xm2hn2iH10GhsG1h1cOc+pbnQtzTuo+g51Erwni4UzRYXeRrWHx/4nhEuL8wa/viRmpcwjW854mliUAlbWCS0dtKHblyyKliEEmqF5Et5984MZEZYFQtZJYj6i7ktOSRhAb9eM/I52J6Z3U9m8qMw==;5:mt8aU71olA1X2q7CWS3fak8dxDHIxuMJxv2SK4yfIuU47U0I5EgOy//TNBTNqmdKMI2QpcQfy7X3JnpkDxEYwhe3hQU3n5Vl2wtxuzhwf89YVk/sew6vAk9MfUtItum6fNv4dmO4oj5eDWBZlBnJhA==;24:PE4Y0hRxZX912clV4wuP7/gFqjQOSs4mNgC0ZZ1c1X3nqi7Msi/ih3CMHdhev3/fHM2rIuY2bXsRAZARlD1UuGVdLPFaPSog8doH4hITwis=;7:qYxPU4agAZbQiqyAJgtVM2Pv/ZdK4scsrGCshzFl0qVULeQ+3VV6RXiRH+hkC5uL0nIvjZ2vHxh03vUl4iKT4WZu6KJZiXjXZXPm8ruC5vLA3M+EmGmYLYdTghbCDpkkWV2jMkaaE0MgGhIeIuJSOBAeaBskWp5pUGbEM9Ai6g+k4ABEtz0sgPasL4GzIB0/bZN465eARIbiicyUq6KGsXTXyGgJoXE1wEu+NmQqtSw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: adaptrum.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Aug 2017 20:46:57.2654 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR04MB0837 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12892 Lines: 399 On 08/16/2017 02:46 AM, Philipp Zabel wrote: > Split reusable parts out of the sunxi driver, to add a driver for simple > reset controllers with reset lines that can be controlled by toggling > bits in exclusive, contiguous register ranges using read-modify-write > cycles under a spinlock. The separate sunxi driver still remains to > register the early reset controllers, but it reuses the reset-simple > ops. > > The following patches will replace compatible reset drivers with > reset-simple, extending it where necessary. > > Signed-off-by: Philipp Zabel Reviewed-by: Alexandru Gagniuc > --- > Changes since v2: > - Add kerneldoc comment for struct reset_simple_devdata and struct > reset_simple_data. > - Rename "inverted" properties to "active_low". > - Use of_device_get_match_data instead of of_match_device. > --- > drivers/reset/Kconfig | 11 ++++ > drivers/reset/Makefile | 1 + > drivers/reset/reset-simple.c | 134 +++++++++++++++++++++++++++++++++++++++++++ > drivers/reset/reset-simple.h | 41 +++++++++++++ > drivers/reset/reset-sunxi.c | 104 ++------------------------------- > 5 files changed, 193 insertions(+), 98 deletions(-) > create mode 100644 drivers/reset/reset-simple.c > create mode 100644 drivers/reset/reset-simple.h > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > index 52d5251660b9b..f7ba01a71daee 100644 > --- a/drivers/reset/Kconfig > +++ b/drivers/reset/Kconfig > @@ -68,6 +68,16 @@ config RESET_PISTACHIO > help > This enables the reset driver for ImgTec Pistachio SoCs. > > +config RESET_SIMPLE > + bool "Simple Reset Controller Driver" if COMPILE_TEST > + default ARCH_SUNXI > + help > + This enables a simple reset controller driver for reset lines that > + that can be asserted and deasserted by toggling bits in a contiguous, > + exclusive register space. > + > + Currently this driver supports Allwinner SoCs. > + > config RESET_SOCFPGA > bool "SoCFPGA Reset Driver" if COMPILE_TEST > default ARCH_SOCFPGA > @@ -83,6 +93,7 @@ config RESET_STM32 > config RESET_SUNXI > bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI > default ARCH_SUNXI > + select RESET_SIMPLE > help > This enables the reset driver for Allwinner SoCs. > > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile > index b62783f50fe5b..ab4af99c3dfdc 100644 > --- a/drivers/reset/Makefile > +++ b/drivers/reset/Makefile > @@ -11,6 +11,7 @@ obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o > obj-$(CONFIG_RESET_MESON) += reset-meson.o > obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o > obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o > +obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o > obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o > obj-$(CONFIG_RESET_STM32) += reset-stm32.o > obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o > diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c > new file mode 100644 > index 0000000000000..70c57c0758c39 > --- /dev/null > +++ b/drivers/reset/reset-simple.c > @@ -0,0 +1,134 @@ > +/* > + * Simple Reset Controller Driver > + * > + * Copyright (C) 2017 Pengutronix, Philipp Zabel > + * > + * Based on Allwinner SoCs Reset Controller driver > + * > + * Copyright 2013 Maxime Ripard > + * > + * Maxime Ripard > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "reset-simple.h" > + > +static inline struct reset_simple_data * > +to_reset_simple_data(struct reset_controller_dev *rcdev) > +{ > + return container_of(rcdev, struct reset_simple_data, rcdev); > +} > + > +static int reset_simple_set(struct reset_controller_dev *rcdev, > + unsigned long id, bool assert) > +{ > + struct reset_simple_data *data = to_reset_simple_data(rcdev); > + int reg_width = sizeof(u32); > + int bank = id / (reg_width * BITS_PER_BYTE); > + int offset = id % (reg_width * BITS_PER_BYTE); > + unsigned long flags; > + u32 reg; > + > + spin_lock_irqsave(&data->lock, flags); > + > + reg = readl(data->membase + (bank * reg_width)); > + if (assert ^ data->active_low) > + reg |= BIT(offset); > + else > + reg &= ~BIT(offset); > + writel(reg, data->membase + (bank * reg_width)); > + > + spin_unlock_irqrestore(&data->lock, flags); > + > + return 0; > +} > + > +static int reset_simple_assert(struct reset_controller_dev *rcdev, > + unsigned long id) > +{ > + return reset_simple_set(rcdev, id, true); > +} > + > +static int reset_simple_deassert(struct reset_controller_dev *rcdev, > + unsigned long id) > +{ > + return reset_simple_set(rcdev, id, false); > +} > + > +const struct reset_control_ops reset_simple_ops = { > + .assert = reset_simple_assert, > + .deassert = reset_simple_deassert, > +}; > + > +/** > + * struct reset_simple_devdata - simple reset controller properties > + * @active_low: if true, bits are cleared to assert the reset. Otherwise, bits > + * are set to assert the reset. > + */ > +struct reset_simple_devdata { > + bool active_low; > +}; > + > +static const struct reset_simple_devdata reset_simple_active_low = { > + .active_low = true, > +}; > + > +static const struct of_device_id reset_simple_dt_ids[] = { > + { .compatible = "allwinner,sun6i-a31-clock-reset", > + .data = &reset_simple_active_low }, > + { /* sentinel */ }, > +}; > + > +static int reset_simple_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + const struct reset_simple_devdata *devdata; > + struct reset_simple_data *data; > + void __iomem *membase; > + struct resource *res; > + > + devdata = of_device_get_match_data(dev); > + > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + membase = devm_ioremap_resource(dev, res); > + if (IS_ERR(membase)) > + return PTR_ERR(membase); > + > + spin_lock_init(&data->lock); > + data->membase = membase; > + data->rcdev.owner = THIS_MODULE; > + data->rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE; > + data->rcdev.ops = &reset_simple_ops; > + data->rcdev.of_node = dev->of_node; > + > + if (devdata) > + data->active_low = devdata->active_low; > + > + return devm_reset_controller_register(dev, &data->rcdev); > +} > + > +static struct platform_driver reset_simple_driver = { > + .probe = reset_simple_probe, > + .driver = { > + .name = "simple-reset", > + .of_match_table = reset_simple_dt_ids, > + }, > +}; > +builtin_platform_driver(reset_simple_driver); > diff --git a/drivers/reset/reset-simple.h b/drivers/reset/reset-simple.h > new file mode 100644 > index 0000000000000..39af2014b5f12 > --- /dev/null > +++ b/drivers/reset/reset-simple.h > @@ -0,0 +1,41 @@ > +/* > + * Simple Reset Controller ops > + * > + * Based on Allwinner SoCs Reset Controller driver > + * > + * Copyright 2013 Maxime Ripard > + * > + * Maxime Ripard > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef __RESET_SIMPLE_H__ > +#define __RESET_SIMPLE_H__ > + > +#include > +#include > +#include > + > +/** > + * struct reset_simple_data - driver data for simple reset controllers > + * @lock: spinlock to protect registers during read-modify-write cycles > + * @membase: memory mapped I/O register range > + * @rcdev: reset controller device base structure > + * @active_low: if true, bits are cleared to assert the reset. Otherwise, bits > + * are set to assert the reset. Note that this says nothing about > + * the voltage level of the actual reset line. > + */ > +struct reset_simple_data { > + spinlock_t lock; > + void __iomem *membase; > + struct reset_controller_dev rcdev; > + bool active_low; > +}; > + > +extern const struct reset_control_ops reset_simple_ops; > + > +#endif /* __RESET_SIMPLE_H__ */ > diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c > index 2c7dd1fd08df6..db9a1a75523f4 100644 > --- a/drivers/reset/reset-sunxi.c > +++ b/drivers/reset/reset-sunxi.c > @@ -22,64 +22,11 @@ > #include > #include > > -struct sunxi_reset_data { > - spinlock_t lock; > - void __iomem *membase; > - struct reset_controller_dev rcdev; > -}; > - > -static int sunxi_reset_assert(struct reset_controller_dev *rcdev, > - unsigned long id) > -{ > - struct sunxi_reset_data *data = container_of(rcdev, > - struct sunxi_reset_data, > - rcdev); > - int reg_width = sizeof(u32); > - int bank = id / (reg_width * BITS_PER_BYTE); > - int offset = id % (reg_width * BITS_PER_BYTE); > - unsigned long flags; > - u32 reg; > - > - spin_lock_irqsave(&data->lock, flags); > - > - reg = readl(data->membase + (bank * reg_width)); > - writel(reg & ~BIT(offset), data->membase + (bank * reg_width)); > - > - spin_unlock_irqrestore(&data->lock, flags); > - > - return 0; > -} > - > -static int sunxi_reset_deassert(struct reset_controller_dev *rcdev, > - unsigned long id) > -{ > - struct sunxi_reset_data *data = container_of(rcdev, > - struct sunxi_reset_data, > - rcdev); > - int reg_width = sizeof(u32); > - int bank = id / (reg_width * BITS_PER_BYTE); > - int offset = id % (reg_width * BITS_PER_BYTE); > - unsigned long flags; > - u32 reg; > - > - spin_lock_irqsave(&data->lock, flags); > - > - reg = readl(data->membase + (bank * reg_width)); > - writel(reg | BIT(offset), data->membase + (bank * reg_width)); > - > - spin_unlock_irqrestore(&data->lock, flags); > - > - return 0; > -} > - > -static const struct reset_control_ops sunxi_reset_ops = { > - .assert = sunxi_reset_assert, > - .deassert = sunxi_reset_deassert, > -}; > +#include "reset-simple.h" > > static int sunxi_reset_init(struct device_node *np) > { > - struct sunxi_reset_data *data; > + struct reset_simple_data *data; > struct resource res; > resource_size_t size; > int ret; > @@ -108,8 +55,9 @@ static int sunxi_reset_init(struct device_node *np) > > data->rcdev.owner = THIS_MODULE; > data->rcdev.nr_resets = size * 8; > - data->rcdev.ops = &sunxi_reset_ops; > + data->rcdev.ops = &reset_simple_ops; > data->rcdev.of_node = np; > + data->active_low = true; > > return reset_controller_register(&data->rcdev); > > @@ -122,6 +70,8 @@ static int sunxi_reset_init(struct device_node *np) > * These are the reset controller we need to initialize early on in > * our system, before we can even think of using a regular device > * driver for it. > + * The controllers that we can register through the regular device > + * model are handled by the simple reset driver directly. > */ > static const struct of_device_id sunxi_early_reset_dt_ids[] __initconst = { > { .compatible = "allwinner,sun6i-a31-ahb1-reset", }, > @@ -135,45 +85,3 @@ void __init sun6i_reset_init(void) > for_each_matching_node(np, sunxi_early_reset_dt_ids) > sunxi_reset_init(np); > } > - > -/* > - * And these are the controllers we can register through the regular > - * device model. > - */ > -static const struct of_device_id sunxi_reset_dt_ids[] = { > - { .compatible = "allwinner,sun6i-a31-clock-reset", }, > - { /* sentinel */ }, > -}; > - > -static int sunxi_reset_probe(struct platform_device *pdev) > -{ > - struct sunxi_reset_data *data; > - struct resource *res; > - > - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > - if (!data) > - return -ENOMEM; > - > - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - data->membase = devm_ioremap_resource(&pdev->dev, res); > - if (IS_ERR(data->membase)) > - return PTR_ERR(data->membase); > - > - spin_lock_init(&data->lock); > - > - data->rcdev.owner = THIS_MODULE; > - data->rcdev.nr_resets = resource_size(res) * 8; > - data->rcdev.ops = &sunxi_reset_ops; > - data->rcdev.of_node = pdev->dev.of_node; > - > - return devm_reset_controller_register(&pdev->dev, &data->rcdev); > -} > - > -static struct platform_driver sunxi_reset_driver = { > - .probe = sunxi_reset_probe, > - .driver = { > - .name = "sunxi-reset", > - .of_match_table = sunxi_reset_dt_ids, > - }, > -}; > -builtin_platform_driver(sunxi_reset_driver); >