1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 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.
*
*/
#ifndef __ARCH_ARM_MSM_CLOCK_CONTROLLER_H
#define __ARCH_ARM_MSM_CLOCK_CONTROLLER_H
#include <linux/list.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#define dt_err(np, fmt, ...) \
pr_err("%s: " fmt, np->name, ##__VA_ARGS__)
#define dt_prop_err(np, str, fmt, ...) \
dt_err(np, "%s: " fmt, str, ##__VA_ARGS__)
/**
* struct msmclk_parser
* @compatible
* matches compatible property from devicetree
* @parsedt
* constructs & returns an instance of the appropriate obj based on
* the data from devicetree.
*/
struct msmclk_parser {
struct list_head list;
char *compatible;
void * (*parsedt)(struct device *dev, struct device_node *of);
};
#define MSMCLK_PARSER(fn, str, id) \
static struct msmclk_parser _msmclk_##fn##id = { \
.list = LIST_HEAD_INIT(_msmclk_##fn##id.list), \
.compatible = str, \
.parsedt = fn, \
}; \
static int __init _msmclk_init_##fn##id(void) \
{ \
msmclk_parser_register(&_msmclk_##fn##id); \
return 0; \
} \
early_initcall(_msmclk_init_##fn##id)
/*
* struct msmclk_data
* @base
* ioremapped region for sub_devices
* @list
* tracks all registered driver instances
* @htable
* tracks all registered child clocks
* @clk_tbl
* array of clk_lookup to be registered with the clock framework
*/
#define HASHTABLE_SIZE 200
struct msmclk_data {
void __iomem *base;
struct device *dev;
struct list_head list;
struct hlist_head htable[HASHTABLE_SIZE];
struct clk_lookup *clk_tbl;
int clk_tbl_size;
int max_clk_tbl_size;
};
#if defined(CONFIG_MSM_CLK_CONTROLLER_V2)
/* Utility functions */
int of_property_count_phandles(struct device_node *np, char *propname);
int of_property_read_phandle_index(struct device_node *np, char *propname,
int index, phandle *p);
void *msmclk_generic_clk_init(struct device *dev, struct device_node *np,
struct clk *c);
/*
* msmclk_parser_register
* Registers a parser which will be matched with a node from dt
* according to the compatible string.
*/
void msmclk_parser_register(struct msmclk_parser *);
/*
* msmclk_parse_phandle
* On hashtable miss, the corresponding entry will be retrieved from
* devicetree, and added to the hashtable.
*/
void *msmclk_parse_phandle(struct device *dev, phandle key);
/*
* msmclk_lookup_phandle
* Straightforward hashtable lookup
*/
void *msmclk_lookup_phandle(struct device *dev, phandle key);
int __init msmclk_init(void);
#else
static inline int of_property_count_phandles(struct device_node *np,
char *propname)
{
return 0;
}
static inline int of_property_read_phandle_index(struct device_node *np,
char *propname, int index, phandle *p)
{
return 0;
}
static inline void *msmclk_generic_clk_init(struct device *dev,
struct device_node *np, struct clk *c)
{
return ERR_PTR(-EINVAL);
}
static inline void msmclk_parser_register(struct msmclk_parser *p) {};
static inline void *msmclk_parse_phandle(struct device *dev, phandle key)
{
return ERR_PTR(-EINVAL);
}
static inline void *msmclk_lookup_phandle(struct device *dev, phandle key)
{
return ERR_PTR(-EINVAL);
}
static inline int __init msmclk_init(void)
{
return 0;
}
#endif /* CONFIG_MSM_CLK_CONTROLLER_V2 */
#endif /* __ARCH_ARM_MSM_CLOCK_CONTROLLER_H */
|