diff options
Diffstat (limited to 'drivers/reset')
-rw-r--r-- | drivers/reset/Kconfig | 4 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/core.c | 37 | ||||
-rw-r--r-- | drivers/reset/reset-ath79.c | 3 | ||||
-rw-r--r-- | drivers/reset/reset-meson.c | 136 | ||||
-rw-r--r-- | drivers/reset/reset-oxnas.c | 12 | ||||
-rw-r--r-- | drivers/reset/reset-pistachio.c | 12 | ||||
-rw-r--r-- | drivers/reset/reset-socfpga.c | 12 | ||||
-rw-r--r-- | drivers/reset/reset-sunxi.c | 12 | ||||
-rw-r--r-- | drivers/reset/reset-zynq.c | 12 | ||||
-rw-r--r-- | drivers/reset/sti/Kconfig | 1 |
11 files changed, 184 insertions, 58 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0b2733db0e9e..ab37f4db9642 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -12,8 +12,12 @@ menuconfig RESET_CONTROLLER If unsure, say no. +if RESET_CONTROLLER + config RESET_OXNAS bool source "drivers/reset/sti/Kconfig" source "drivers/reset/hisilicon/Kconfig" + +endif diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index f173fc3847b4..03dc1bb7649e 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o obj-$(CONFIG_MACH_PISTACHIO) += reset-pistachio.o +obj-$(CONFIG_ARCH_MESON) += reset-meson.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o obj-$(CONFIG_ARCH_STI) += sti/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 72b32bd15549..395dc9ce492e 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -93,6 +93,43 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev) } EXPORT_SYMBOL_GPL(reset_controller_unregister); +static void devm_reset_controller_release(struct device *dev, void *res) +{ + reset_controller_unregister(*(struct reset_controller_dev **)res); +} + +/** + * devm_reset_controller_register - resource managed reset_controller_register() + * @dev: device that is registering this reset controller + * @rcdev: a pointer to the initialized reset controller device + * + * Managed reset_controller_register(). For reset controllers registered by + * this function, reset_controller_unregister() is automatically called on + * driver detach. See reset_controller_register() for more information. + */ +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev) +{ + struct reset_controller_dev **rcdevp; + int ret; + + rcdevp = devres_alloc(devm_reset_controller_release, sizeof(*rcdevp), + GFP_KERNEL); + if (!rcdevp) + return -ENOMEM; + + ret = reset_controller_register(rcdev); + if (!ret) { + *rcdevp = rcdev; + devres_add(dev, rcdevp); + } else { + devres_free(rcdevp); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_reset_controller_register); + /** * reset_control_reset - reset the controlled device * @rstc: reset controller diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index ccb940a8d9fb..16d410cd6146 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c @@ -112,7 +112,7 @@ static int ath79_reset_probe(struct platform_device *pdev) ath79_reset->rcdev.of_reset_n_cells = 1; ath79_reset->rcdev.nr_resets = 32; - err = reset_controller_register(&ath79_reset->rcdev); + err = devm_reset_controller_register(&pdev->dev, &ath79_reset->rcdev); if (err) return err; @@ -131,7 +131,6 @@ static int ath79_reset_remove(struct platform_device *pdev) struct ath79_reset *ath79_reset = platform_get_drvdata(pdev); unregister_restart_handler(&ath79_reset->restart_nb); - reset_controller_unregister(&ath79_reset->rcdev); return 0; } diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c new file mode 100644 index 000000000000..c32f11a30c5f --- /dev/null +++ b/drivers/reset/reset-meson.c @@ -0,0 +1,136 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <linux/err.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> +#include <linux/slab.h> +#include <linux/types.h> + +#define REG_COUNT 8 +#define BITS_PER_REG 32 + +struct meson_reset { + void __iomem *reg_base; + struct reset_controller_dev rcdev; +}; + +static int meson_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct meson_reset *data = + container_of(rcdev, struct meson_reset, rcdev); + unsigned int bank = id / BITS_PER_REG; + unsigned int offset = id % BITS_PER_REG; + void __iomem *reg_addr = data->reg_base + (bank << 2); + + if (bank >= REG_COUNT) + return -EINVAL; + + writel(BIT(offset), reg_addr); + + return 0; +} + +static const struct reset_control_ops meson_reset_ops = { + .reset = meson_reset_reset, +}; + +static const struct of_device_id meson_reset_dt_ids[] = { + { .compatible = "amlogic,meson8b-reset", }, + { .compatible = "amlogic,meson-gxbb-reset", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, meson_reset_dt_ids); + +static int meson_reset_probe(struct platform_device *pdev) +{ + struct meson_reset *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->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(data->reg_base)) + return PTR_ERR(data->reg_base); + + platform_set_drvdata(pdev, data); + + data->rcdev.owner = THIS_MODULE; + data->rcdev.nr_resets = REG_COUNT * BITS_PER_REG; + data->rcdev.ops = &meson_reset_ops; + data->rcdev.of_node = pdev->dev.of_node; + + return devm_reset_controller_register(&pdev->dev, &data->rcdev); +} + +static struct platform_driver meson_reset_driver = { + .probe = meson_reset_probe, + .driver = { + .name = "meson_reset", + .of_match_table = meson_reset_dt_ids, + }, +}; + +module_platform_driver(meson_reset_driver); + +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); +MODULE_DESCRIPTION("Amlogic Meson Reset Controller driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/reset/reset-oxnas.c b/drivers/reset/reset-oxnas.c index c60fb2dace3e..944980572f79 100644 --- a/drivers/reset/reset-oxnas.c +++ b/drivers/reset/reset-oxnas.c @@ -112,21 +112,11 @@ static int oxnas_reset_probe(struct platform_device *pdev) data->rcdev.ops = &oxnas_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int oxnas_reset_remove(struct platform_device *pdev) -{ - struct oxnas_reset *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &data->rcdev); } static struct platform_driver oxnas_reset_driver = { .probe = oxnas_reset_probe, - .remove = oxnas_reset_remove, .driver = { .name = "oxnas-reset", .of_match_table = oxnas_reset_dt_ids, diff --git a/drivers/reset/reset-pistachio.c b/drivers/reset/reset-pistachio.c index 72a97a15a4c8..bbc4c06dd33b 100644 --- a/drivers/reset/reset-pistachio.c +++ b/drivers/reset/reset-pistachio.c @@ -121,16 +121,7 @@ static int pistachio_reset_probe(struct platform_device *pdev) rd->rcdev.ops = &pistachio_reset_ops; rd->rcdev.of_node = np; - return reset_controller_register(&rd->rcdev); -} - -static int pistachio_reset_remove(struct platform_device *pdev) -{ - struct pistachio_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(dev, &rd->rcdev); } static const struct of_device_id pistachio_reset_dt_ids[] = { @@ -141,7 +132,6 @@ MODULE_DEVICE_TABLE(of, pistachio_reset_dt_ids); static struct platform_driver pistachio_reset_driver = { .probe = pistachio_reset_probe, - .remove = pistachio_reset_remove, .driver = { .name = "pistachio-reset", .of_match_table = pistachio_reset_dt_ids, diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index cd05a7032b17..12add9b0fa49 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -134,16 +134,7 @@ static int socfpga_reset_probe(struct platform_device *pdev) data->rcdev.ops = &socfpga_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int socfpga_reset_remove(struct platform_device *pdev) -{ - struct socfpga_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(dev, &data->rcdev); } static const struct of_device_id socfpga_reset_dt_ids[] = { @@ -153,7 +144,6 @@ static const struct of_device_id socfpga_reset_dt_ids[] = { static struct platform_driver socfpga_reset_driver = { .probe = socfpga_reset_probe, - .remove = socfpga_reset_remove, .driver = { .name = "socfpga-reset", .of_match_table = socfpga_reset_dt_ids, diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index 677f86555212..3080190b3f90 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -165,21 +165,11 @@ static int sunxi_reset_probe(struct platform_device *pdev) data->rcdev.ops = &sunxi_reset_ops; data->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&data->rcdev); -} - -static int sunxi_reset_remove(struct platform_device *pdev) -{ - struct sunxi_reset_data *data = platform_get_drvdata(pdev); - - reset_controller_unregister(&data->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &data->rcdev); } static struct platform_driver sunxi_reset_driver = { .probe = sunxi_reset_probe, - .remove = sunxi_reset_remove, .driver = { .name = "sunxi-reset", .of_match_table = sunxi_reset_dt_ids, diff --git a/drivers/reset/reset-zynq.c b/drivers/reset/reset-zynq.c index a7e87bc45885..138f2f205662 100644 --- a/drivers/reset/reset-zynq.c +++ b/drivers/reset/reset-zynq.c @@ -122,16 +122,7 @@ static int zynq_reset_probe(struct platform_device *pdev) priv->rcdev.ops = &zynq_reset_ops; priv->rcdev.of_node = pdev->dev.of_node; - return reset_controller_register(&priv->rcdev); -} - -static int zynq_reset_remove(struct platform_device *pdev) -{ - struct zynq_reset_data *priv = platform_get_drvdata(pdev); - - reset_controller_unregister(&priv->rcdev); - - return 0; + return devm_reset_controller_register(&pdev->dev, &priv->rcdev); } static const struct of_device_id zynq_reset_dt_ids[] = { @@ -141,7 +132,6 @@ static const struct of_device_id zynq_reset_dt_ids[] = { static struct platform_driver zynq_reset_driver = { .probe = zynq_reset_probe, - .remove = zynq_reset_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = zynq_reset_dt_ids, diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig index f8c15a37fb35..613178553612 100644 --- a/drivers/reset/sti/Kconfig +++ b/drivers/reset/sti/Kconfig @@ -2,7 +2,6 @@ if ARCH_STI config STI_RESET_SYSCFG bool - select RESET_CONTROLLER config STIH415_RESET bool |