.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
7 | | - * (at your option) any later version. |
---|
8 | | - * |
---|
9 | 4 | */ |
---|
10 | 5 | |
---|
11 | 6 | #include <linux/clk-provider.h> |
---|
.. | .. |
---|
18 | 13 | #include <linux/syscore_ops.h> |
---|
19 | 14 | |
---|
20 | 15 | #include <asm/proc-fns.h> |
---|
| 16 | + |
---|
| 17 | +#include <dt-bindings/clock/at91.h> |
---|
21 | 18 | |
---|
22 | 19 | #include "pmc.h" |
---|
23 | 20 | |
---|
.. | .. |
---|
46 | 43 | return 0; |
---|
47 | 44 | } |
---|
48 | 45 | EXPORT_SYMBOL_GPL(of_at91_get_clk_range); |
---|
| 46 | + |
---|
| 47 | +struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data) |
---|
| 48 | +{ |
---|
| 49 | + unsigned int type = clkspec->args[0]; |
---|
| 50 | + unsigned int idx = clkspec->args[1]; |
---|
| 51 | + struct pmc_data *pmc_data = data; |
---|
| 52 | + |
---|
| 53 | + switch (type) { |
---|
| 54 | + case PMC_TYPE_CORE: |
---|
| 55 | + if (idx < pmc_data->ncore) |
---|
| 56 | + return pmc_data->chws[idx]; |
---|
| 57 | + break; |
---|
| 58 | + case PMC_TYPE_SYSTEM: |
---|
| 59 | + if (idx < pmc_data->nsystem) |
---|
| 60 | + return pmc_data->shws[idx]; |
---|
| 61 | + break; |
---|
| 62 | + case PMC_TYPE_PERIPHERAL: |
---|
| 63 | + if (idx < pmc_data->nperiph) |
---|
| 64 | + return pmc_data->phws[idx]; |
---|
| 65 | + break; |
---|
| 66 | + case PMC_TYPE_GCK: |
---|
| 67 | + if (idx < pmc_data->ngck) |
---|
| 68 | + return pmc_data->ghws[idx]; |
---|
| 69 | + break; |
---|
| 70 | + case PMC_TYPE_PROGRAMMABLE: |
---|
| 71 | + if (idx < pmc_data->npck) |
---|
| 72 | + return pmc_data->pchws[idx]; |
---|
| 73 | + break; |
---|
| 74 | + default: |
---|
| 75 | + break; |
---|
| 76 | + } |
---|
| 77 | + |
---|
| 78 | + pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx); |
---|
| 79 | + |
---|
| 80 | + return ERR_PTR(-EINVAL); |
---|
| 81 | +} |
---|
| 82 | + |
---|
| 83 | +struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, |
---|
| 84 | + unsigned int nperiph, unsigned int ngck, |
---|
| 85 | + unsigned int npck) |
---|
| 86 | +{ |
---|
| 87 | + unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck; |
---|
| 88 | + struct pmc_data *pmc_data; |
---|
| 89 | + |
---|
| 90 | + pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks), |
---|
| 91 | + GFP_KERNEL); |
---|
| 92 | + if (!pmc_data) |
---|
| 93 | + return NULL; |
---|
| 94 | + |
---|
| 95 | + pmc_data->ncore = ncore; |
---|
| 96 | + pmc_data->chws = pmc_data->hwtable; |
---|
| 97 | + |
---|
| 98 | + pmc_data->nsystem = nsystem; |
---|
| 99 | + pmc_data->shws = pmc_data->chws + ncore; |
---|
| 100 | + |
---|
| 101 | + pmc_data->nperiph = nperiph; |
---|
| 102 | + pmc_data->phws = pmc_data->shws + nsystem; |
---|
| 103 | + |
---|
| 104 | + pmc_data->ngck = ngck; |
---|
| 105 | + pmc_data->ghws = pmc_data->phws + nperiph; |
---|
| 106 | + |
---|
| 107 | + pmc_data->npck = npck; |
---|
| 108 | + pmc_data->pchws = pmc_data->ghws + ngck; |
---|
| 109 | + |
---|
| 110 | + return pmc_data; |
---|
| 111 | +} |
---|
49 | 112 | |
---|
50 | 113 | #ifdef CONFIG_PM |
---|
51 | 114 | static struct regmap *pmcreg; |
---|
.. | .. |
---|
201 | 264 | struct device_node *np; |
---|
202 | 265 | |
---|
203 | 266 | np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); |
---|
| 267 | + if (!np) |
---|
| 268 | + return -ENODEV; |
---|
204 | 269 | |
---|
205 | | - pmcreg = syscon_node_to_regmap(np); |
---|
| 270 | + if (!of_device_is_available(np)) { |
---|
| 271 | + of_node_put(np); |
---|
| 272 | + return -ENODEV; |
---|
| 273 | + } |
---|
| 274 | + |
---|
| 275 | + pmcreg = device_node_to_regmap(np); |
---|
| 276 | + of_node_put(np); |
---|
206 | 277 | if (IS_ERR(pmcreg)) |
---|
207 | 278 | return PTR_ERR(pmcreg); |
---|
208 | 279 | |
---|