Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

reset: hi6220: Reset driver for hisilicon hi6220 SoC

Add reset driver for hi6220-hikey board,this driver supply deassert
of IP on hi6220 SoC.

Signed-off-by: Chen Feng <puck.chen@hisilicon.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

authored by

Chen Feng and committed by
Philipp Zabel
f59d23c2 04d11269

+116
+1
drivers/reset/Kconfig
··· 13 13 If unsure, say no. 14 14 15 15 source "drivers/reset/sti/Kconfig" 16 + source "drivers/reset/hisilicon/Kconfig"
+1
drivers/reset/Makefile
··· 4 4 obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o 5 5 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o 6 6 obj-$(CONFIG_ARCH_STI) += sti/ 7 + obj-$(CONFIG_ARCH_HISI) += hisilicon/ 7 8 obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o 8 9 obj-$(CONFIG_ATH79) += reset-ath79.o
+5
drivers/reset/hisilicon/Kconfig
··· 1 + config COMMON_RESET_HI6220 2 + tristate "Hi6220 Reset Driver" 3 + depends on (ARCH_HISI && RESET_CONTROLLER) 4 + help 5 + Build the Hisilicon Hi6220 reset driver.
+1
drivers/reset/hisilicon/Makefile
··· 1 + obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o
+108
drivers/reset/hisilicon/hi6220_reset.c
··· 1 + /* 2 + * Hisilicon Hi6220 reset controller driver 3 + * 4 + * Copyright (c) 2015 Hisilicon Limited. 5 + * 6 + * Author: Feng Chen <puck.chen@hisilicon.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/io.h> 14 + #include <linux/init.h> 15 + #include <linux/bitops.h> 16 + #include <linux/of.h> 17 + #include <linux/reset-controller.h> 18 + #include <linux/reset.h> 19 + #include <linux/platform_device.h> 20 + 21 + #define ASSERT_OFFSET 0x300 22 + #define DEASSERT_OFFSET 0x304 23 + #define MAX_INDEX 0x509 24 + 25 + #define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev) 26 + 27 + struct hi6220_reset_data { 28 + void __iomem *assert_base; 29 + void __iomem *deassert_base; 30 + struct reset_controller_dev rc_dev; 31 + }; 32 + 33 + static int hi6220_reset_assert(struct reset_controller_dev *rc_dev, 34 + unsigned long idx) 35 + { 36 + struct hi6220_reset_data *data = to_reset_data(rc_dev); 37 + 38 + int bank = idx >> 8; 39 + int offset = idx & 0xff; 40 + 41 + writel(BIT(offset), data->assert_base + (bank * 0x10)); 42 + 43 + return 0; 44 + } 45 + 46 + static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, 47 + unsigned long idx) 48 + { 49 + struct hi6220_reset_data *data = to_reset_data(rc_dev); 50 + 51 + int bank = idx >> 8; 52 + int offset = idx & 0xff; 53 + 54 + writel(BIT(offset), data->deassert_base + (bank * 0x10)); 55 + 56 + return 0; 57 + } 58 + 59 + static struct reset_control_ops hi6220_reset_ops = { 60 + .assert = hi6220_reset_assert, 61 + .deassert = hi6220_reset_deassert, 62 + }; 63 + 64 + static int hi6220_reset_probe(struct platform_device *pdev) 65 + { 66 + struct hi6220_reset_data *data; 67 + struct resource *res; 68 + void __iomem *src_base; 69 + 70 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 71 + if (!data) 72 + return -ENOMEM; 73 + 74 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 75 + src_base = devm_ioremap_resource(&pdev->dev, res); 76 + if (IS_ERR(src_base)) 77 + return PTR_ERR(src_base); 78 + 79 + data->assert_base = src_base + ASSERT_OFFSET; 80 + data->deassert_base = src_base + DEASSERT_OFFSET; 81 + data->rc_dev.nr_resets = MAX_INDEX; 82 + data->rc_dev.ops = &hi6220_reset_ops; 83 + data->rc_dev.of_node = pdev->dev.of_node; 84 + 85 + reset_controller_register(&data->rc_dev); 86 + 87 + return 0; 88 + } 89 + 90 + static const struct of_device_id hi6220_reset_match[] = { 91 + { .compatible = "hisilicon,hi6220-sysctrl" }, 92 + { }, 93 + }; 94 + 95 + static struct platform_driver hi6220_reset_driver = { 96 + .probe = hi6220_reset_probe, 97 + .driver = { 98 + .name = "reset-hi6220", 99 + .of_match_table = hi6220_reset_match, 100 + }, 101 + }; 102 + 103 + static int __init hi6220_reset_init(void) 104 + { 105 + return platform_driver_register(&hi6220_reset_driver); 106 + } 107 + 108 + postcore_initcall(hi6220_reset_init);