1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved. 4 * Copyright (C) 2013 Red Hat 5 * Author: Rob Clark <robdclark@gmail.com> 6 */ 7 8 #include "msm_drv.h" 9 10 /* 11 * Util/helpers: 12 */ 13 14 struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, 15 const char *name) 16 { 17 int i; 18 char n[32]; 19 20 snprintf(n, sizeof(n), "%s_clk", name); 21 22 for (i = 0; bulk && i < count; i++) { 23 if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n)) 24 return bulk[i].clk; 25 } 26 27 28 return NULL; 29 } 30 31 struct clk *msm_clk_get(struct platform_device *pdev, const char *name) 32 { 33 struct clk *clk; 34 char name2[32]; 35 36 clk = devm_clk_get(&pdev->dev, name); 37 if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 38 return clk; 39 40 snprintf(name2, sizeof(name2), "%s_clk", name); 41 42 clk = devm_clk_get(&pdev->dev, name2); 43 if (!IS_ERR(clk)) 44 dev_warn(&pdev->dev, "Using legacy clk name binding. Use " 45 "\"%s\" instead of \"%s\"\n", name, name2); 46 47 return clk; 48 } 49 50 static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, 51 bool quiet, phys_addr_t *psize) 52 { 53 struct resource *res; 54 unsigned long size; 55 void __iomem *ptr; 56 57 if (name) 58 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 59 else 60 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 61 62 if (!res) { 63 if (!quiet) 64 DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); 65 return ERR_PTR(-EINVAL); 66 } 67 68 size = resource_size(res); 69 70 ptr = devm_ioremap(&pdev->dev, res->start, size); 71 if (!ptr) { 72 if (!quiet) 73 DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); 74 return ERR_PTR(-ENOMEM); 75 } 76 77 if (psize) 78 *psize = size; 79 80 return ptr; 81 } 82 83 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name) 84 { 85 return _msm_ioremap(pdev, name, false, NULL); 86 } 87 88 void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name) 89 { 90 return _msm_ioremap(pdev, name, true, NULL); 91 } 92 93 void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, 94 phys_addr_t *psize) 95 { 96 return _msm_ioremap(pdev, name, false, psize); 97 } 98 99 static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) 100 { 101 struct msm_hrtimer_work *work = container_of(t, 102 struct msm_hrtimer_work, timer); 103 104 kthread_queue_work(work->worker, &work->work); 105 106 return HRTIMER_NORESTART; 107 } 108 109 void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, 110 ktime_t wakeup_time, 111 enum hrtimer_mode mode) 112 { 113 hrtimer_start(&work->timer, wakeup_time, mode); 114 } 115 116 void msm_hrtimer_work_init(struct msm_hrtimer_work *work, 117 struct kthread_worker *worker, 118 kthread_work_func_t fn, 119 clockid_t clock_id, 120 enum hrtimer_mode mode) 121 { 122 hrtimer_init(&work->timer, clock_id, mode); 123 work->timer.function = msm_hrtimer_worktimer; 124 work->worker = worker; 125 kthread_init_work(&work->work, fn); 126 } 127