0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #undef DEBUG
0022
0023 #include <linux/kernel.h>
0024 #include <linux/platform_device.h>
0025 #include <linux/slab.h>
0026 #include <linux/err.h>
0027 #include <linux/io.h>
0028 #include <linux/clk.h>
0029 #include <linux/clkdev.h>
0030 #include <linux/pm_domain.h>
0031 #include <linux/pm_runtime.h>
0032 #include <linux/of.h>
0033 #include <linux/of_address.h>
0034 #include <linux/of_irq.h>
0035 #include <linux/notifier.h>
0036
0037 #include "common.h"
0038 #include "soc.h"
0039 #include "omap_device.h"
0040 #include "omap_hwmod.h"
0041
0042
0043
0044 static void _add_clkdev(struct omap_device *od, const char *clk_alias,
0045 const char *clk_name)
0046 {
0047 struct clk *r;
0048 int rc;
0049
0050 if (!clk_alias || !clk_name)
0051 return;
0052
0053 dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name);
0054
0055 r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias);
0056 if (!IS_ERR(r)) {
0057 dev_dbg(&od->pdev->dev,
0058 "alias %s already exists\n", clk_alias);
0059 clk_put(r);
0060 return;
0061 }
0062
0063 r = clk_get_sys(NULL, clk_name);
0064
0065 if (IS_ERR(r)) {
0066 struct of_phandle_args clkspec;
0067
0068 clkspec.np = of_find_node_by_name(NULL, clk_name);
0069
0070 r = of_clk_get_from_provider(&clkspec);
0071
0072 rc = clk_register_clkdev(r, clk_alias,
0073 dev_name(&od->pdev->dev));
0074 } else {
0075 rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev),
0076 clk_name, NULL);
0077 }
0078
0079 if (rc) {
0080 if (rc == -ENODEV || rc == -ENOMEM)
0081 dev_err(&od->pdev->dev,
0082 "clkdev_alloc for %s failed\n", clk_alias);
0083 else
0084 dev_err(&od->pdev->dev,
0085 "clk_get for %s failed\n", clk_name);
0086 }
0087 }
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 static void _add_hwmod_clocks_clkdev(struct omap_device *od,
0106 struct omap_hwmod *oh)
0107 {
0108 int i;
0109
0110 _add_clkdev(od, "fck", oh->main_clk);
0111
0112 for (i = 0; i < oh->opt_clks_cnt; i++)
0113 _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 static int omap_device_build_from_dt(struct platform_device *pdev)
0126 {
0127 struct omap_hwmod **hwmods;
0128 struct omap_device *od;
0129 struct omap_hwmod *oh;
0130 struct device_node *node = pdev->dev.of_node;
0131 struct resource res;
0132 const char *oh_name;
0133 int oh_cnt, i, ret = 0;
0134 bool device_active = false, skip_pm_domain = false;
0135
0136 oh_cnt = of_property_count_strings(node, "ti,hwmods");
0137 if (oh_cnt <= 0) {
0138 dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n");
0139 return -ENODEV;
0140 }
0141
0142
0143 ret = of_property_read_string_index(node, "ti,hwmods", 0, &oh_name);
0144 if (!ret && (!strncmp("dma_system", oh_name, 10) ||
0145 !strncmp("dma", oh_name, 3)))
0146 skip_pm_domain = true;
0147
0148
0149 if (!skip_pm_domain &&
0150 !omap_hwmod_parse_module_range(NULL, node, &res))
0151 return -ENODEV;
0152
0153 hwmods = kcalloc(oh_cnt, sizeof(struct omap_hwmod *), GFP_KERNEL);
0154 if (!hwmods) {
0155 ret = -ENOMEM;
0156 goto odbfd_exit;
0157 }
0158
0159 for (i = 0; i < oh_cnt; i++) {
0160 of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
0161 oh = omap_hwmod_lookup(oh_name);
0162 if (!oh) {
0163 dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
0164 oh_name);
0165 ret = -EINVAL;
0166 goto odbfd_exit1;
0167 }
0168 hwmods[i] = oh;
0169 if (oh->flags & HWMOD_INIT_NO_IDLE)
0170 device_active = true;
0171 }
0172
0173 od = omap_device_alloc(pdev, hwmods, oh_cnt);
0174 if (IS_ERR(od)) {
0175 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
0176 oh_name);
0177 ret = PTR_ERR(od);
0178 goto odbfd_exit1;
0179 }
0180
0181
0182 for (i = 0; i < pdev->num_resources; i++) {
0183 struct resource *r = &pdev->resource[i];
0184
0185 if (r->name == NULL)
0186 r->name = dev_name(&pdev->dev);
0187 }
0188
0189 if (!skip_pm_domain) {
0190 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
0191 if (device_active) {
0192 omap_device_enable(pdev);
0193 pm_runtime_set_active(&pdev->dev);
0194 }
0195 }
0196
0197 odbfd_exit1:
0198 kfree(hwmods);
0199 odbfd_exit:
0200
0201 if (ret)
0202 dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain);
0203
0204 return ret;
0205 }
0206
0207 static int _omap_device_notifier_call(struct notifier_block *nb,
0208 unsigned long event, void *dev)
0209 {
0210 struct platform_device *pdev = to_platform_device(dev);
0211 struct omap_device *od;
0212 int err;
0213
0214 switch (event) {
0215 case BUS_NOTIFY_REMOVED_DEVICE:
0216 if (pdev->archdata.od)
0217 omap_device_delete(pdev->archdata.od);
0218 break;
0219 case BUS_NOTIFY_UNBOUND_DRIVER:
0220 od = to_omap_device(pdev);
0221 if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) {
0222 dev_info(dev, "enabled after unload, idling\n");
0223 err = omap_device_idle(pdev);
0224 if (err)
0225 dev_err(dev, "failed to idle\n");
0226 }
0227 break;
0228 case BUS_NOTIFY_BIND_DRIVER:
0229 od = to_omap_device(pdev);
0230 if (od) {
0231 od->_driver_status = BUS_NOTIFY_BIND_DRIVER;
0232 if (od->_state == OMAP_DEVICE_STATE_ENABLED &&
0233 pm_runtime_status_suspended(dev)) {
0234 pm_runtime_set_active(dev);
0235 }
0236 }
0237 break;
0238 case BUS_NOTIFY_ADD_DEVICE:
0239 if (pdev->dev.of_node)
0240 omap_device_build_from_dt(pdev);
0241 omap_auxdata_legacy_init(dev);
0242 fallthrough;
0243 default:
0244 od = to_omap_device(pdev);
0245 if (od)
0246 od->_driver_status = event;
0247 }
0248
0249 return NOTIFY_DONE;
0250 }
0251
0252
0253
0254
0255
0256
0257
0258 static int _omap_device_enable_hwmods(struct omap_device *od)
0259 {
0260 int ret = 0;
0261 int i;
0262
0263 for (i = 0; i < od->hwmods_cnt; i++)
0264 ret |= omap_hwmod_enable(od->hwmods[i]);
0265
0266 return ret;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275 static int _omap_device_idle_hwmods(struct omap_device *od)
0276 {
0277 int ret = 0;
0278 int i;
0279
0280 for (i = 0; i < od->hwmods_cnt; i++)
0281 ret |= omap_hwmod_idle(od->hwmods[i]);
0282
0283 return ret;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 int omap_device_get_context_loss_count(struct platform_device *pdev)
0304 {
0305 struct omap_device *od;
0306 u32 ret = 0;
0307
0308 od = to_omap_device(pdev);
0309
0310 if (od->hwmods_cnt)
0311 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
0312
0313 return ret;
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 struct omap_device *omap_device_alloc(struct platform_device *pdev,
0328 struct omap_hwmod **ohs, int oh_cnt)
0329 {
0330 int ret = -ENOMEM;
0331 struct omap_device *od;
0332 int i;
0333 struct omap_hwmod **hwmods;
0334
0335 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
0336 if (!od)
0337 goto oda_exit1;
0338
0339 od->hwmods_cnt = oh_cnt;
0340
0341 hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
0342 if (!hwmods)
0343 goto oda_exit2;
0344
0345 od->hwmods = hwmods;
0346 od->pdev = pdev;
0347 pdev->archdata.od = od;
0348
0349 for (i = 0; i < oh_cnt; i++) {
0350 hwmods[i]->od = od;
0351 _add_hwmod_clocks_clkdev(od, hwmods[i]);
0352 }
0353
0354 return od;
0355
0356 oda_exit2:
0357 kfree(od);
0358 oda_exit1:
0359 dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
0360
0361 return ERR_PTR(ret);
0362 }
0363
0364 void omap_device_delete(struct omap_device *od)
0365 {
0366 if (!od)
0367 return;
0368
0369 od->pdev->archdata.od = NULL;
0370 kfree(od->hwmods);
0371 kfree(od);
0372 }
0373
0374 #ifdef CONFIG_PM
0375 static int _od_runtime_suspend(struct device *dev)
0376 {
0377 struct platform_device *pdev = to_platform_device(dev);
0378 int ret;
0379
0380 ret = pm_generic_runtime_suspend(dev);
0381 if (ret)
0382 return ret;
0383
0384 return omap_device_idle(pdev);
0385 }
0386
0387 static int _od_runtime_resume(struct device *dev)
0388 {
0389 struct platform_device *pdev = to_platform_device(dev);
0390 int ret;
0391
0392 ret = omap_device_enable(pdev);
0393 if (ret) {
0394 dev_err(dev, "use pm_runtime_put_sync_suspend() in driver?\n");
0395 return ret;
0396 }
0397
0398 return pm_generic_runtime_resume(dev);
0399 }
0400
0401 static int _od_fail_runtime_suspend(struct device *dev)
0402 {
0403 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
0404 return -ENODEV;
0405 }
0406
0407 static int _od_fail_runtime_resume(struct device *dev)
0408 {
0409 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
0410 return -ENODEV;
0411 }
0412
0413 #endif
0414
0415 #ifdef CONFIG_SUSPEND
0416 static int _od_suspend_noirq(struct device *dev)
0417 {
0418 struct platform_device *pdev = to_platform_device(dev);
0419 struct omap_device *od = to_omap_device(pdev);
0420 int ret;
0421
0422
0423 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER)
0424 return 0;
0425
0426 ret = pm_generic_suspend_noirq(dev);
0427
0428 if (!ret && !pm_runtime_status_suspended(dev)) {
0429 if (pm_generic_runtime_suspend(dev) == 0) {
0430 omap_device_idle(pdev);
0431 od->flags |= OMAP_DEVICE_SUSPENDED;
0432 }
0433 }
0434
0435 return ret;
0436 }
0437
0438 static int _od_resume_noirq(struct device *dev)
0439 {
0440 struct platform_device *pdev = to_platform_device(dev);
0441 struct omap_device *od = to_omap_device(pdev);
0442
0443 if (od->flags & OMAP_DEVICE_SUSPENDED) {
0444 od->flags &= ~OMAP_DEVICE_SUSPENDED;
0445 omap_device_enable(pdev);
0446 pm_generic_runtime_resume(dev);
0447 }
0448
0449 return pm_generic_resume_noirq(dev);
0450 }
0451 #else
0452 #define _od_suspend_noirq NULL
0453 #define _od_resume_noirq NULL
0454 #endif
0455
0456 struct dev_pm_domain omap_device_fail_pm_domain = {
0457 .ops = {
0458 SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend,
0459 _od_fail_runtime_resume, NULL)
0460 }
0461 };
0462
0463 struct dev_pm_domain omap_device_pm_domain = {
0464 .ops = {
0465 SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
0466 NULL)
0467 USE_PLATFORM_PM_SLEEP_OPS
0468 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq,
0469 _od_resume_noirq)
0470 }
0471 };
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 int omap_device_enable(struct platform_device *pdev)
0488 {
0489 int ret;
0490 struct omap_device *od;
0491
0492 od = to_omap_device(pdev);
0493
0494 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
0495 dev_warn(&pdev->dev,
0496 "omap_device: %s() called from invalid state %d\n",
0497 __func__, od->_state);
0498 return -EINVAL;
0499 }
0500
0501 ret = _omap_device_enable_hwmods(od);
0502
0503 if (ret == 0)
0504 od->_state = OMAP_DEVICE_STATE_ENABLED;
0505
0506 return ret;
0507 }
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518 int omap_device_idle(struct platform_device *pdev)
0519 {
0520 int ret;
0521 struct omap_device *od;
0522
0523 od = to_omap_device(pdev);
0524
0525 if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
0526 dev_warn(&pdev->dev,
0527 "omap_device: %s() called from invalid state %d\n",
0528 __func__, od->_state);
0529 return -EINVAL;
0530 }
0531
0532 ret = _omap_device_idle_hwmods(od);
0533
0534 if (ret == 0)
0535 od->_state = OMAP_DEVICE_STATE_IDLE;
0536
0537 return ret;
0538 }
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552 int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
0553 {
0554 struct omap_device *od = to_omap_device(pdev);
0555 int ret = 0;
0556 int i;
0557
0558 for (i = 0; i < od->hwmods_cnt; i++) {
0559 ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
0560 if (ret)
0561 break;
0562 }
0563
0564 return ret;
0565 }
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 int omap_device_deassert_hardreset(struct platform_device *pdev,
0580 const char *name)
0581 {
0582 struct omap_device *od = to_omap_device(pdev);
0583 int ret = 0;
0584 int i;
0585
0586 for (i = 0; i < od->hwmods_cnt; i++) {
0587 ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
0588 if (ret)
0589 break;
0590 }
0591
0592 return ret;
0593 }
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603 struct device *omap_device_get_by_hwmod_name(const char *oh_name)
0604 {
0605 struct omap_hwmod *oh;
0606
0607 if (!oh_name) {
0608 WARN(1, "%s: no hwmod name!\n", __func__);
0609 return ERR_PTR(-EINVAL);
0610 }
0611
0612 oh = omap_hwmod_lookup(oh_name);
0613 if (!oh) {
0614 WARN(1, "%s: no hwmod for %s\n", __func__,
0615 oh_name);
0616 return ERR_PTR(-ENODEV);
0617 }
0618 if (!oh->od) {
0619 WARN(1, "%s: no omap_device for %s\n", __func__,
0620 oh_name);
0621 return ERR_PTR(-ENODEV);
0622 }
0623
0624 return &oh->od->pdev->dev;
0625 }
0626
0627 static struct notifier_block platform_nb = {
0628 .notifier_call = _omap_device_notifier_call,
0629 };
0630
0631 static int __init omap_device_init(void)
0632 {
0633 bus_register_notifier(&platform_bus_type, &platform_nb);
0634 return 0;
0635 }
0636 omap_postcore_initcall(omap_device_init);
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646 static int __init omap_device_late_idle(struct device *dev, void *data)
0647 {
0648 struct platform_device *pdev = to_platform_device(dev);
0649 struct omap_device *od = to_omap_device(pdev);
0650 int i;
0651
0652 if (!od)
0653 return 0;
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 for (i = 0; i < od->hwmods_cnt; i++)
0665 if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
0666 return 0;
0667
0668 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
0669 od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
0670 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
0671 dev_warn(dev, "%s: enabled but no driver. Idling\n",
0672 __func__);
0673 omap_device_idle(pdev);
0674 }
0675 }
0676
0677 return 0;
0678 }
0679
0680 static int __init omap_device_late_init(void)
0681 {
0682 bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
0683
0684 return 0;
0685 }
0686 omap_late_initcall_sync(omap_device_late_init);