brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · ded7e39 Raw
101 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/slab.h>3#include <linux/io.h>4#include <linux/of.h>5#include <linux/of_address.h>6#include <linux/reset-controller.h>7 8#include "reset.h"9 10#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)11 12static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,13			  const struct of_phandle_args *reset_spec)14{15	struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);16	struct mmp_clk_reset_cell *cell;17	int i;18 19	if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))20		return -EINVAL;21 22	for (i = 0; i < rcdev->nr_resets; i++) {23		cell = &unit->cells[i];24		if (cell->clk_id == reset_spec->args[0])25			break;26	}27 28	if (i == rcdev->nr_resets)29		return -EINVAL;30 31	return i;32}33 34static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,35				unsigned long id)36{37	struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);38	struct mmp_clk_reset_cell *cell;39	unsigned long flags = 0;40	u32 val;41 42	cell = &unit->cells[id];43	if (cell->lock)44		spin_lock_irqsave(cell->lock, flags);45 46	val = readl(cell->reg);47	val |= cell->bits;48	writel(val, cell->reg);49 50	if (cell->lock)51		spin_unlock_irqrestore(cell->lock, flags);52 53	return 0;54}55 56static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,57				unsigned long id)58{59	struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);60	struct mmp_clk_reset_cell *cell;61	unsigned long flags = 0;62	u32 val;63 64	cell = &unit->cells[id];65	if (cell->lock)66		spin_lock_irqsave(cell->lock, flags);67 68	val = readl(cell->reg);69	val &= ~cell->bits;70	writel(val, cell->reg);71 72	if (cell->lock)73		spin_unlock_irqrestore(cell->lock, flags);74 75	return 0;76}77 78static const struct reset_control_ops mmp_clk_reset_ops = {79	.assert		= mmp_clk_reset_assert,80	.deassert	= mmp_clk_reset_deassert,81};82 83void mmp_clk_reset_register(struct device_node *np,84			struct mmp_clk_reset_cell *cells, int nr_resets)85{86	struct mmp_clk_reset_unit *unit;87 88	unit = kzalloc(sizeof(*unit), GFP_KERNEL);89	if (!unit)90		return;91 92	unit->cells = cells;93	unit->rcdev.of_reset_n_cells = 1;94	unit->rcdev.nr_resets = nr_resets;95	unit->rcdev.ops = &mmp_clk_reset_ops;96	unit->rcdev.of_node = np;97	unit->rcdev.of_xlate = mmp_of_reset_xlate;98 99	reset_controller_register(&unit->rcdev);100}101