1// SPDX-License-Identifier: GPL-2.0 2/* 3 * OMAP2+ PRM driver 4 * 5 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ 6 * Tero Kristo <t-kristo@ti.com> 7 */ 8 9#include <linux/kernel.h> 10#include <linux/device.h> 11#include <linux/io.h> 12#include <linux/iopoll.h> 13#include <linux/module.h> 14#include <linux/of.h> 15#include <linux/of_device.h> 16#include <linux/platform_device.h> 17#include <linux/pm_domain.h> 18#include <linux/reset-controller.h> 19#include <linux/delay.h> 20 21#include <linux/platform_data/ti-prm.h> 22 23enum omap_prm_domain_mode { 24 OMAP_PRMD_OFF, 25 OMAP_PRMD_RETENTION, 26 OMAP_PRMD_ON_INACTIVE, 27 OMAP_PRMD_ON_ACTIVE, 28}; 29 30struct omap_prm_domain_map { 31 unsigned int usable_modes; /* Mask of hardware supported modes */ 32 unsigned long statechange:1; /* Optional low-power state change */ 33 unsigned long logicretstate:1; /* Optional logic off mode */ 34}; 35 36struct omap_prm_domain { 37 struct device *dev; 38 struct omap_prm *prm; 39 struct generic_pm_domain pd; 40 u16 pwrstctrl; 41 u16 pwrstst; 42 const struct omap_prm_domain_map *cap; 43 u32 pwrstctrl_saved; 44}; 45 46struct omap_rst_map { 47 s8 rst; 48 s8 st; 49}; 50 51struct omap_prm_data { 52 u32 base; 53 const char *name; 54 const char *clkdm_name; 55 u16 pwrstctrl; 56 u16 pwrstst; 57 const struct omap_prm_domain_map *dmap; 58 u16 rstctrl; 59 u16 rstst; 60 const struct omap_rst_map *rstmap; 61 u8 flags; 62}; 63 64struct omap_prm { 65 const struct omap_prm_data *data; 66 void __iomem *base; 67 struct omap_prm_domain *prmd; 68}; 69 70struct omap_reset_data { 71 struct reset_controller_dev rcdev; 72 struct omap_prm *prm; 73 u32 mask; 74 spinlock_t lock; 75 struct clockdomain *clkdm; 76 struct device *dev; 77}; 78 79#define genpd_to_prm_domain(gpd) container_of(gpd, struct omap_prm_domain, pd) 80#define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev) 81 82#define OMAP_MAX_RESETS 8 83#define OMAP_RESET_MAX_WAIT 10000 84 85#define OMAP_PRM_HAS_RSTCTRL BIT(0) 86#define OMAP_PRM_HAS_RSTST BIT(1) 87#define OMAP_PRM_HAS_NO_CLKDM BIT(2) 88 89#define OMAP_PRM_HAS_RESETS (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST) 90 91#define PRM_STATE_MAX_WAIT 10000 92#define PRM_LOGICRETSTATE BIT(2) 93#define PRM_LOWPOWERSTATECHANGE BIT(4) 94#define PRM_POWERSTATE_MASK OMAP_PRMD_ON_ACTIVE 95 96#define PRM_ST_INTRANSITION BIT(20) 97 98static const struct omap_prm_domain_map omap_prm_all = { 99 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) | 100 BIT(OMAP_PRMD_RETENTION) | BIT(OMAP_PRMD_OFF), 101 .statechange = 1, 102 .logicretstate = 1, 103}; 104 105static const struct omap_prm_domain_map omap_prm_noinact = { 106 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION) | 107 BIT(OMAP_PRMD_OFF), 108 .statechange = 1, 109 .logicretstate = 1, 110}; 111 112static const struct omap_prm_domain_map omap_prm_nooff = { 113 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) | 114 BIT(OMAP_PRMD_RETENTION), 115 .statechange = 1, 116 .logicretstate = 1, 117}; 118 119static const struct omap_prm_domain_map omap_prm_onoff_noauto = { 120 .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_OFF), 121 .statechange = 1, 122}; 123 124static const struct omap_rst_map rst_map_0[] = { 125 { .rst = 0, .st = 0 }, 126 { .rst = -1 }, 127}; 128 129static const struct omap_rst_map rst_map_01[] = { 130 { .rst = 0, .st = 0 }, 131 { .rst = 1, .st = 1 }, 132 { .rst = -1 }, 133}; 134 135static const struct omap_rst_map rst_map_012[] = { 136 { .rst = 0, .st = 0 }, 137 { .rst = 1, .st = 1 }, 138 { .rst = 2, .st = 2 }, 139 { .rst = -1 }, 140}; 141 142static const struct omap_prm_data omap4_prm_data[] = { 143 { .name = "tesla", .base = 0x4a306400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 144 { 145 .name = "abe", .base = 0x4a306500, 146 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_all, 147 }, 148 { .name = "core", .base = 0x4a306700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati", .rstmap = rst_map_012 }, 149 { .name = "ivahd", .base = 0x4a306f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 }, 150 { .name = "device", .base = 0x4a307b00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM }, 151 { }, 152}; 153 154static const struct omap_prm_data omap5_prm_data[] = { 155 { .name = "dsp", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 156 { 157 .name = "abe", .base = 0x4ae06500, 158 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_nooff, 159 }, 160 { .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu", .rstmap = rst_map_012 }, 161 { .name = "iva", .base = 0x4ae07200, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 }, 162 { .name = "device", .base = 0x4ae07c00, .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM }, 163 { }, 164}; 165 166static const struct omap_prm_data dra7_prm_data[] = { 167 { .name = "dsp1", .base = 0x4ae06400, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 168 { .name = "ipu", .base = 0x4ae06500, .rstctrl = 0x10, .rstst = 0x14, .clkdm_name = "ipu1", .rstmap = rst_map_012 }, 169 { .name = "core", .base = 0x4ae06700, .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu2", .rstmap = rst_map_012 }, 170 { .name = "iva", .base = 0x4ae06f00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012 }, 171 { .name = "dsp2", .base = 0x4ae07b00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 172 { .name = "eve1", .base = 0x4ae07b40, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 173 { .name = "eve2", .base = 0x4ae07b80, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 174 { .name = "eve3", .base = 0x4ae07bc0, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 175 { .name = "eve4", .base = 0x4ae07c00, .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01 }, 176 { }, 177}; 178 179static const struct omap_rst_map am3_per_rst_map[] = { 180 { .rst = 1 }, 181 { .rst = -1 }, 182}; 183 184static const struct omap_rst_map am3_wkup_rst_map[] = { 185 { .rst = 3, .st = 5 }, 186 { .rst = -1 }, 187}; 188 189static const struct omap_prm_data am3_prm_data[] = { 190 { .name = "per", .base = 0x44e00c00, .rstctrl = 0x0, .rstmap = am3_per_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp" }, 191 { .name = "wkup", .base = 0x44e00d00, .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM }, 192 { .name = "device", .base = 0x44e00f00, .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM }, 193 { 194 .name = "gfx", .base = 0x44e01100, 195 .pwrstctrl = 0, .pwrstst = 0x10, .dmap = &omap_prm_noinact, 196 .rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3", 197 }, 198 { }, 199}; 200 201static const struct omap_rst_map am4_per_rst_map[] = { 202 { .rst = 1, .st = 0 }, 203 { .rst = -1 }, 204}; 205 206static const struct omap_rst_map am4_device_rst_map[] = { 207 { .rst = 0, .st = 1 }, 208 { .rst = 1, .st = 0 }, 209 { .rst = -1 }, 210}; 211 212static const struct omap_prm_data am4_prm_data[] = { 213 { 214 .name = "gfx", .base = 0x44df0400, 215 .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto, 216 .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3", 217 }, 218 { .name = "per", .base = 0x44df0800, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am4_per_rst_map, .clkdm_name = "pruss_ocp" }, 219 { .name = "wkup", .base = 0x44df2000, .rstctrl = 0x10, .rstst = 0x14, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_NO_CLKDM }, 220 { .name = "device", .base = 0x44df4000, .rstctrl = 0x0, .rstst = 0x4, .rstmap = am4_device_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM }, 221 { }, 222}; 223 224static const struct of_device_id omap_prm_id_table[] = { 225 { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data }, 226 { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data }, 227 { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data }, 228 { .compatible = "ti,am3-prm-inst", .data = am3_prm_data }, 229 { .compatible = "ti,am4-prm-inst", .data = am4_prm_data }, 230 { }, 231}; 232 233#ifdef DEBUG 234static void omap_prm_domain_show_state(struct omap_prm_domain *prmd, 235 const char *desc) 236{ 237 dev_dbg(prmd->dev, "%s %s: %08x/%08x\n", 238 prmd->pd.name, desc, 239 readl_relaxed(prmd->prm->base + prmd->pwrstctrl), 240 readl_relaxed(prmd->prm->base + prmd->pwrstst)); 241} 242#else 243static inline void omap_prm_domain_show_state(struct omap_prm_domain *prmd, 244 const char *desc) 245{ 246} 247#endif 248 249static int omap_prm_domain_power_on(struct generic_pm_domain *domain) 250{ 251 struct omap_prm_domain *prmd; 252 int ret; 253 u32 v; 254 255 prmd = genpd_to_prm_domain(domain); 256 if (!prmd->cap) 257 return 0; 258 259 omap_prm_domain_show_state(prmd, "on: previous state"); 260 261 if (prmd->pwrstctrl_saved) 262 v = prmd->pwrstctrl_saved; 263 else 264 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); 265 266 writel_relaxed(v | OMAP_PRMD_ON_ACTIVE, 267 prmd->prm->base + prmd->pwrstctrl); 268 269 /* wait for the transition bit to get cleared */ 270 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, 271 v, !(v & PRM_ST_INTRANSITION), 1, 272 PRM_STATE_MAX_WAIT); 273 if (ret) 274 dev_err(prmd->dev, "%s: %s timed out\n", 275 prmd->pd.name, __func__); 276 277 omap_prm_domain_show_state(prmd, "on: new state"); 278 279 return ret; 280} 281 282/* No need to check for holes in the mask for the lowest mode */ 283static int omap_prm_domain_find_lowest(struct omap_prm_domain *prmd) 284{ 285 return __ffs(prmd->cap->usable_modes); 286} 287 288static int omap_prm_domain_power_off(struct generic_pm_domain *domain) 289{ 290 struct omap_prm_domain *prmd; 291 int ret; 292 u32 v; 293 294 prmd = genpd_to_prm_domain(domain); 295 if (!prmd->cap) 296 return 0; 297 298 omap_prm_domain_show_state(prmd, "off: previous state"); 299 300 v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl); 301 prmd->pwrstctrl_saved = v; 302 303 v &= ~PRM_POWERSTATE_MASK; 304 v |= omap_prm_domain_find_lowest(prmd); 305 306 if (prmd->cap->statechange) 307 v |= PRM_LOWPOWERSTATECHANGE; 308 if (prmd->cap->logicretstate) 309 v &= ~PRM_LOGICRETSTATE; 310 else 311 v |= PRM_LOGICRETSTATE; 312 313 writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl); 314 315 /* wait for the transition bit to get cleared */ 316 ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst, 317 v, !(v & PRM_ST_INTRANSITION), 1, 318 PRM_STATE_MAX_WAIT); 319 if (ret) 320 dev_warn(prmd->dev, "%s: %s timed out\n", 321 __func__, prmd->pd.name); 322 323 omap_prm_domain_show_state(prmd, "off: new state"); 324 325 return 0; 326} 327 328static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain, 329 struct device *dev) 330{ 331 struct generic_pm_domain_data *genpd_data; 332 struct of_phandle_args pd_args; 333 struct omap_prm_domain *prmd; 334 struct device_node *np; 335 int ret; 336 337 prmd = genpd_to_prm_domain(domain); 338 np = dev->of_node; 339 340 ret = of_parse_phandle_with_args(np, "power-domains", 341 "#power-domain-cells", 0, &pd_args); 342 if (ret < 0) 343 return ret; 344 345 if (pd_args.args_count != 0) 346 dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n", 347 prmd->pd.name, pd_args.args_count); 348 349 genpd_data = dev_gpd_data(dev); 350 genpd_data->data = NULL; 351 352 return 0; 353} 354 355static void omap_prm_domain_detach_dev(struct generic_pm_domain *domain, 356 struct device *dev) 357{ 358 struct generic_pm_domain_data *genpd_data; 359 360 genpd_data = dev_gpd_data(dev); 361 genpd_data->data = NULL; 362} 363 364static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm) 365{ 366 struct omap_prm_domain *prmd; 367 struct device_node *np = dev->of_node; 368 const struct omap_prm_data *data; 369 const char *name; 370 int error; 371 372 if (!of_find_property(dev->of_node, "#power-domain-cells", NULL)) 373 return 0; 374 375 of_node_put(dev->of_node); 376 377 prmd = devm_kzalloc(dev, sizeof(*prmd), GFP_KERNEL); 378 if (!prmd) 379 return -ENOMEM; 380 381 data = prm->data; 382 name = devm_kasprintf(dev, GFP_KERNEL, "prm_%s", 383 data->name); 384 385 prmd->dev = dev; 386 prmd->prm = prm; 387 prmd->cap = prmd->prm->data->dmap; 388 prmd->pwrstctrl = prmd->prm->data->pwrstctrl; 389 prmd->pwrstst = prmd->prm->data->pwrstst; 390 391 prmd->pd.name = name; 392 prmd->pd.power_on = omap_prm_domain_power_on; 393 prmd->pd.power_off = omap_prm_domain_power_off; 394 prmd->pd.attach_dev = omap_prm_domain_attach_dev; 395 prmd->pd.detach_dev = omap_prm_domain_detach_dev; 396 397 pm_genpd_init(&prmd->pd, NULL, true); 398 error = of_genpd_add_provider_simple(np, &prmd->pd); 399 if (error) 400 pm_genpd_remove(&prmd->pd); 401 else 402 prm->prmd = prmd; 403 404 return error; 405} 406 407static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id) 408{ 409 if (reset->mask & BIT(id)) 410 return true; 411 412 return false; 413} 414 415static int omap_reset_get_st_bit(struct omap_reset_data *reset, 416 unsigned long id) 417{ 418 const struct omap_rst_map *map = reset->prm->data->rstmap; 419 420 while (map->rst >= 0) { 421 if (map->rst == id) 422 return map->st; 423 424 map++; 425 } 426 427 return id; 428} 429 430static int omap_reset_status(struct reset_controller_dev *rcdev, 431 unsigned long id) 432{ 433 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 434 u32 v; 435 int st_bit = omap_reset_get_st_bit(reset, id); 436 bool has_rstst = reset->prm->data->rstst || 437 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); 438 439 /* Check if we have rstst */ 440 if (!has_rstst) 441 return -ENOTSUPP; 442 443 /* Check if hw reset line is asserted */ 444 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 445 if (v & BIT(id)) 446 return 1; 447 448 /* 449 * Check reset status, high value means reset sequence has been 450 * completed successfully so we can return 0 here (reset deasserted) 451 */ 452 v = readl_relaxed(reset->prm->base + reset->prm->data->rstst); 453 v >>= st_bit; 454 v &= 1; 455 456 return !v; 457} 458 459static int omap_reset_assert(struct reset_controller_dev *rcdev, 460 unsigned long id) 461{ 462 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 463 u32 v; 464 unsigned long flags; 465 466 /* assert the reset control line */ 467 spin_lock_irqsave(&reset->lock, flags); 468 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 469 v |= 1 << id; 470 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); 471 spin_unlock_irqrestore(&reset->lock, flags); 472 473 return 0; 474} 475 476static int omap_reset_deassert(struct reset_controller_dev *rcdev, 477 unsigned long id) 478{ 479 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 480 u32 v; 481 int st_bit; 482 bool has_rstst; 483 unsigned long flags; 484 struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev); 485 int ret = 0; 486 487 /* Nothing to do if the reset is already deasserted */ 488 if (!omap_reset_status(rcdev, id)) 489 return 0; 490 491 has_rstst = reset->prm->data->rstst || 492 (reset->prm->data->flags & OMAP_PRM_HAS_RSTST); 493 494 if (has_rstst) { 495 st_bit = omap_reset_get_st_bit(reset, id); 496 497 /* Clear the reset status by writing 1 to the status bit */ 498 v = 1 << st_bit; 499 writel_relaxed(v, reset->prm->base + reset->prm->data->rstst); 500 } 501 502 if (reset->clkdm) 503 pdata->clkdm_deny_idle(reset->clkdm); 504 505 /* de-assert the reset control line */ 506 spin_lock_irqsave(&reset->lock, flags); 507 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 508 v &= ~(1 << id); 509 writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); 510 spin_unlock_irqrestore(&reset->lock, flags); 511 512 /* wait for the reset bit to clear */ 513 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + 514 reset->prm->data->rstctrl, 515 v, !(v & BIT(id)), 1, 516 OMAP_RESET_MAX_WAIT); 517 if (ret) 518 pr_err("%s: timedout waiting for %s:%lu\n", __func__, 519 reset->prm->data->name, id); 520 521 /* wait for the status to be set */ 522 if (has_rstst) { 523 ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + 524 reset->prm->data->rstst, 525 v, v & BIT(st_bit), 1, 526 OMAP_RESET_MAX_WAIT); 527 if (ret) 528 pr_err("%s: timedout waiting for %s:%lu\n", __func__, 529 reset->prm->data->name, id); 530 } 531 532 if (reset->clkdm) 533 pdata->clkdm_allow_idle(reset->clkdm); 534 535 return ret; 536} 537 538static const struct reset_control_ops omap_reset_ops = { 539 .assert = omap_reset_assert, 540 .deassert = omap_reset_deassert, 541 .status = omap_reset_status, 542}; 543 544static int omap_prm_reset_xlate(struct reset_controller_dev *rcdev, 545 const struct of_phandle_args *reset_spec) 546{ 547 struct omap_reset_data *reset = to_omap_reset_data(rcdev); 548 549 if (!_is_valid_reset(reset, reset_spec->args[0])) 550 return -EINVAL; 551 552 return reset_spec->args[0]; 553} 554 555static int omap_prm_reset_init(struct platform_device *pdev, 556 struct omap_prm *prm) 557{ 558 struct omap_reset_data *reset; 559 const struct omap_rst_map *map; 560 struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); 561 char buf[32]; 562 u32 v; 563 564 /* 565 * Check if we have controllable resets. If either rstctrl is non-zero 566 * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register 567 * for the domain. 568 */ 569 if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL)) 570 return 0; 571 572 /* Check if we have the pdata callbacks in place */ 573 if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle || 574 !pdata->clkdm_allow_idle) 575 return -EINVAL; 576 577 map = prm->data->rstmap; 578 if (!map) 579 return -EINVAL; 580 581 reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); 582 if (!reset) 583 return -ENOMEM; 584 585 reset->rcdev.owner = THIS_MODULE; 586 reset->rcdev.ops = &omap_reset_ops; 587 reset->rcdev.of_node = pdev->dev.of_node; 588 reset->rcdev.nr_resets = OMAP_MAX_RESETS; 589 reset->rcdev.of_xlate = omap_prm_reset_xlate; 590 reset->rcdev.of_reset_n_cells = 1; 591 reset->dev = &pdev->dev; 592 spin_lock_init(&reset->lock); 593 594 reset->prm = prm; 595 596 sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name : 597 prm->data->name); 598 599 if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) { 600 reset->clkdm = pdata->clkdm_lookup(buf); 601 if (!reset->clkdm) 602 return -EINVAL; 603 } 604 605 while (map->rst >= 0) { 606 reset->mask |= BIT(map->rst); 607 map++; 608 } 609 610 /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */ 611 if (prm->data->rstmap == rst_map_012) { 612 v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); 613 if ((v & reset->mask) != reset->mask) { 614 dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); 615 writel_relaxed(reset->mask, reset->prm->base + 616 reset->prm->data->rstctrl); 617 } 618 } 619 620 return devm_reset_controller_register(&pdev->dev, &reset->rcdev); 621} 622 623static int omap_prm_probe(struct platform_device *pdev) 624{ 625 struct resource *res; 626 const struct omap_prm_data *data; 627 struct omap_prm *prm; 628 const struct of_device_id *match; 629 int ret; 630 631 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 632 if (!res) 633 return -ENODEV; 634 635 match = of_match_device(omap_prm_id_table, &pdev->dev); 636 if (!match) 637 return -ENOTSUPP; 638 639 prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL); 640 if (!prm) 641 return -ENOMEM; 642 643 data = match->data; 644 645 while (data->base != res->start) { 646 if (!data->base) 647 return -EINVAL; 648 data++; 649 } 650 651 prm->data = data; 652 653 prm->base = devm_ioremap_resource(&pdev->dev, res); 654 if (IS_ERR(prm->base)) 655 return PTR_ERR(prm->base); 656 657 ret = omap_prm_domain_init(&pdev->dev, prm); 658 if (ret) 659 return ret; 660 661 ret = omap_prm_reset_init(pdev, prm); 662 if (ret) 663 goto err_domain; 664 665 return 0; 666 667err_domain: 668 of_genpd_del_provider(pdev->dev.of_node); 669 pm_genpd_remove(&prm->prmd->pd); 670 671 return ret; 672} 673 674static struct platform_driver omap_prm_driver = { 675 .probe = omap_prm_probe, 676 .driver = { 677 .name = KBUILD_MODNAME, 678 .of_match_table = omap_prm_id_table, 679 }, 680}; 681builtin_platform_driver(omap_prm_driver); 682