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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.19-rc4 125 lines 3.3 kB view raw
1/* 2 * drivers/reset/reset-oxnas.c 3 * 4 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> 5 * Copyright (C) 2014 Ma Haijun <mahaijuns@gmail.com> 6 * Copyright (C) 2009 Oxford Semiconductor Ltd 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20#include <linux/err.h> 21#include <linux/init.h> 22#include <linux/of.h> 23#include <linux/platform_device.h> 24#include <linux/reset-controller.h> 25#include <linux/slab.h> 26#include <linux/delay.h> 27#include <linux/types.h> 28#include <linux/regmap.h> 29#include <linux/mfd/syscon.h> 30 31/* Regmap offsets */ 32#define RST_SET_REGOFFSET 0x34 33#define RST_CLR_REGOFFSET 0x38 34 35struct oxnas_reset { 36 struct regmap *regmap; 37 struct reset_controller_dev rcdev; 38}; 39 40static int oxnas_reset_reset(struct reset_controller_dev *rcdev, 41 unsigned long id) 42{ 43 struct oxnas_reset *data = 44 container_of(rcdev, struct oxnas_reset, rcdev); 45 46 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id)); 47 msleep(50); 48 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id)); 49 50 return 0; 51} 52 53static int oxnas_reset_assert(struct reset_controller_dev *rcdev, 54 unsigned long id) 55{ 56 struct oxnas_reset *data = 57 container_of(rcdev, struct oxnas_reset, rcdev); 58 59 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id)); 60 61 return 0; 62} 63 64static int oxnas_reset_deassert(struct reset_controller_dev *rcdev, 65 unsigned long id) 66{ 67 struct oxnas_reset *data = 68 container_of(rcdev, struct oxnas_reset, rcdev); 69 70 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id)); 71 72 return 0; 73} 74 75static const struct reset_control_ops oxnas_reset_ops = { 76 .reset = oxnas_reset_reset, 77 .assert = oxnas_reset_assert, 78 .deassert = oxnas_reset_deassert, 79}; 80 81static const struct of_device_id oxnas_reset_dt_ids[] = { 82 { .compatible = "oxsemi,ox810se-reset", }, 83 { .compatible = "oxsemi,ox820-reset", }, 84 { /* sentinel */ }, 85}; 86 87static int oxnas_reset_probe(struct platform_device *pdev) 88{ 89 struct oxnas_reset *data; 90 struct device *parent; 91 92 parent = pdev->dev.parent; 93 if (!parent) { 94 dev_err(&pdev->dev, "no parent\n"); 95 return -ENODEV; 96 } 97 98 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 99 if (!data) 100 return -ENOMEM; 101 102 data->regmap = syscon_node_to_regmap(parent->of_node); 103 if (IS_ERR(data->regmap)) { 104 dev_err(&pdev->dev, "failed to get parent regmap\n"); 105 return PTR_ERR(data->regmap); 106 } 107 108 platform_set_drvdata(pdev, data); 109 110 data->rcdev.owner = THIS_MODULE; 111 data->rcdev.nr_resets = 32; 112 data->rcdev.ops = &oxnas_reset_ops; 113 data->rcdev.of_node = pdev->dev.of_node; 114 115 return devm_reset_controller_register(&pdev->dev, &data->rcdev); 116} 117 118static struct platform_driver oxnas_reset_driver = { 119 .probe = oxnas_reset_probe, 120 .driver = { 121 .name = "oxnas-reset", 122 .of_match_table = oxnas_reset_dt_ids, 123 }, 124}; 125builtin_platform_driver(oxnas_reset_driver);