Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
14struct 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
31struct 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
50static 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
83void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
84{
85 return _msm_ioremap(pdev, name, false, NULL);
86}
87
88void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
89{
90 return _msm_ioremap(pdev, name, true, NULL);
91}
92
93void __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
99static 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
109void 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
116void 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}