Linux Audio

Check our new training course

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