| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * R-Car MSTP clocks |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Copyright (C) 2015 Glider bvba |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 11 | | - * the Free Software Foundation; version 2 of the License. |
|---|
| 12 | 9 | */ |
|---|
| 13 | 10 | |
|---|
| 14 | 11 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 33 | 30 | /** |
|---|
| 34 | 31 | * struct mstp_clock_group - MSTP gating clocks group |
|---|
| 35 | 32 | * |
|---|
| 36 | | - * @data: clocks in this group |
|---|
| 33 | + * @data: clock specifier translation for clocks in this group |
|---|
| 37 | 34 | * @smstpcr: module stop control register |
|---|
| 38 | 35 | * @mstpsr: module stop status register (optional) |
|---|
| 39 | 36 | * @lock: protects writes to SMSTPCR |
|---|
| 40 | 37 | * @width_8bit: registers are 8-bit, not 32-bit |
|---|
| 38 | + * @clks: clocks in this group |
|---|
| 41 | 39 | */ |
|---|
| 42 | 40 | struct mstp_clock_group { |
|---|
| 43 | 41 | struct clk_onecell_data data; |
|---|
| .. | .. |
|---|
| 45 | 43 | void __iomem *mstpsr; |
|---|
| 46 | 44 | spinlock_t lock; |
|---|
| 47 | 45 | bool width_8bit; |
|---|
| 46 | + struct clk *clks[]; |
|---|
| 48 | 47 | }; |
|---|
| 49 | 48 | |
|---|
| 50 | 49 | /** |
|---|
| .. | .. |
|---|
| 151 | 150 | const char *parent_name, unsigned int index, |
|---|
| 152 | 151 | struct mstp_clock_group *group) |
|---|
| 153 | 152 | { |
|---|
| 154 | | - struct clk_init_data init = {}; |
|---|
| 153 | + struct clk_init_data init; |
|---|
| 155 | 154 | struct mstp_clock *clock; |
|---|
| 156 | 155 | struct clk *clk; |
|---|
| 157 | 156 | |
|---|
| .. | .. |
|---|
| 161 | 160 | |
|---|
| 162 | 161 | init.name = name; |
|---|
| 163 | 162 | init.ops = &cpg_mstp_clock_ops; |
|---|
| 164 | | - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; |
|---|
| 163 | + init.flags = CLK_SET_RATE_PARENT; |
|---|
| 165 | 164 | /* INTC-SYS is the module clock of the GIC, and must not be disabled */ |
|---|
| 166 | 165 | if (!strcmp(name, "intc-sys")) { |
|---|
| 167 | 166 | pr_debug("MSTP %s setting CLK_IS_CRITICAL\n", name); |
|---|
| .. | .. |
|---|
| 189 | 188 | struct clk **clks; |
|---|
| 190 | 189 | unsigned int i; |
|---|
| 191 | 190 | |
|---|
| 192 | | - group = kzalloc(sizeof(*group), GFP_KERNEL); |
|---|
| 193 | | - clks = kmalloc_array(MSTP_MAX_CLOCKS, sizeof(*clks), GFP_KERNEL); |
|---|
| 194 | | - if (group == NULL || clks == NULL) { |
|---|
| 195 | | - kfree(group); |
|---|
| 196 | | - kfree(clks); |
|---|
| 191 | + group = kzalloc(struct_size(group, clks, MSTP_MAX_CLOCKS), GFP_KERNEL); |
|---|
| 192 | + if (!group) |
|---|
| 197 | 193 | return; |
|---|
| 198 | | - } |
|---|
| 199 | 194 | |
|---|
| 195 | + clks = group->clks; |
|---|
| 200 | 196 | spin_lock_init(&group->lock); |
|---|
| 201 | 197 | group->data.clks = clks; |
|---|
| 202 | 198 | |
|---|
| .. | .. |
|---|
| 206 | 202 | if (group->smstpcr == NULL) { |
|---|
| 207 | 203 | pr_err("%s: failed to remap SMSTPCR\n", __func__); |
|---|
| 208 | 204 | kfree(group); |
|---|
| 209 | | - kfree(clks); |
|---|
| 210 | 205 | return; |
|---|
| 211 | 206 | } |
|---|
| 212 | 207 | |
|---|
| .. | .. |
|---|
| 239 | 234 | break; |
|---|
| 240 | 235 | |
|---|
| 241 | 236 | if (clkidx >= MSTP_MAX_CLOCKS) { |
|---|
| 242 | | - pr_err("%s: invalid clock %s %s index %u\n", |
|---|
| 243 | | - __func__, np->name, name, clkidx); |
|---|
| 237 | + pr_err("%s: invalid clock %pOFn %s index %u\n", |
|---|
| 238 | + __func__, np, name, clkidx); |
|---|
| 244 | 239 | continue; |
|---|
| 245 | 240 | } |
|---|
| 246 | 241 | |
|---|
| .. | .. |
|---|
| 259 | 254 | */ |
|---|
| 260 | 255 | clk_register_clkdev(clks[clkidx], name, NULL); |
|---|
| 261 | 256 | } else { |
|---|
| 262 | | - pr_err("%s: failed to register %s %s clock (%ld)\n", |
|---|
| 263 | | - __func__, np->name, name, PTR_ERR(clks[clkidx])); |
|---|
| 257 | + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", |
|---|
| 258 | + __func__, np, name, PTR_ERR(clks[clkidx])); |
|---|
| 264 | 259 | } |
|---|
| 265 | 260 | } |
|---|
| 266 | 261 | |
|---|
| .. | .. |
|---|
| 283 | 278 | goto found; |
|---|
| 284 | 279 | |
|---|
| 285 | 280 | /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */ |
|---|
| 286 | | - if (!strcmp(clkspec.np->name, "zb_clk")) |
|---|
| 281 | + if (of_node_name_eq(clkspec.np, "zb_clk")) |
|---|
| 287 | 282 | goto found; |
|---|
| 288 | 283 | |
|---|
| 289 | 284 | of_node_put(clkspec.np); |
|---|
| .. | .. |
|---|
| 300 | 295 | return PTR_ERR(clk); |
|---|
| 301 | 296 | |
|---|
| 302 | 297 | error = pm_clk_create(dev); |
|---|
| 303 | | - if (error) { |
|---|
| 304 | | - dev_err(dev, "pm_clk_create failed %d\n", error); |
|---|
| 298 | + if (error) |
|---|
| 305 | 299 | goto fail_put; |
|---|
| 306 | | - } |
|---|
| 307 | 300 | |
|---|
| 308 | 301 | error = pm_clk_add_clk(dev, clk); |
|---|
| 309 | | - if (error) { |
|---|
| 310 | | - dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); |
|---|
| 302 | + if (error) |
|---|
| 311 | 303 | goto fail_destroy; |
|---|
| 312 | | - } |
|---|
| 313 | 304 | |
|---|
| 314 | 305 | return 0; |
|---|
| 315 | 306 | |
|---|