Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
v6.8
  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 <linux/interconnect.h>
  9#include <linux/io.h>
 10
 11#include "msm_drv.h"
 12
 13/*
 14 * Util/helpers:
 15 */
 16
 17struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
 18		const char *name)
 19{
 20	int i;
 21	char n[32];
 22
 23	snprintf(n, sizeof(n), "%s_clk", name);
 24
 25	for (i = 0; bulk && i < count; i++) {
 26		if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
 27			return bulk[i].clk;
 28	}
 29
 30
 31	return NULL;
 32}
 33
 34struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
 35{
 36	struct clk *clk;
 37	char name2[32];
 38
 39	clk = devm_clk_get(&pdev->dev, name);
 40	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
 41		return clk;
 42
 43	snprintf(name2, sizeof(name2), "%s_clk", name);
 44
 45	clk = devm_clk_get(&pdev->dev, name2);
 46	if (!IS_ERR(clk))
 47		dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
 48				"\"%s\" instead of \"%s\"\n", name, name2);
 49
 50	return clk;
 51}
 52
 53static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
 54				  bool quiet, phys_addr_t *psize)
 55{
 56	struct resource *res;
 57	unsigned long size;
 58	void __iomem *ptr;
 59
 60	if (name)
 61		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 62	else
 63		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 64
 65	if (!res) {
 66		if (!quiet)
 67			DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
 68		return ERR_PTR(-EINVAL);
 69	}
 70
 71	size = resource_size(res);
 72
 73	ptr = devm_ioremap(&pdev->dev, res->start, size);
 74	if (!ptr) {
 75		if (!quiet)
 76			DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
 77		return ERR_PTR(-ENOMEM);
 78	}
 79
 80	if (psize)
 81		*psize = size;
 82
 83	return ptr;
 84}
 85
 86void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
 87{
 88	return _msm_ioremap(pdev, name, false, NULL);
 89}
 90
 91void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
 92{
 93	return _msm_ioremap(pdev, name, true, NULL);
 94}
 95
 96void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
 97			  phys_addr_t *psize)
 98{
 99	return _msm_ioremap(pdev, name, false, psize);
100}
101
102static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
103{
104	struct msm_hrtimer_work *work = container_of(t,
105			struct msm_hrtimer_work, timer);
106
107	kthread_queue_work(work->worker, &work->work);
108
109	return HRTIMER_NORESTART;
110}
111
112void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
113			    ktime_t wakeup_time,
114			    enum hrtimer_mode mode)
115{
116	hrtimer_start(&work->timer, wakeup_time, mode);
117}
118
119void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
120			   struct kthread_worker *worker,
121			   kthread_work_func_t fn,
122			   clockid_t clock_id,
123			   enum hrtimer_mode mode)
124{
125	hrtimer_init(&work->timer, clock_id, mode);
126	work->timer.function = msm_hrtimer_worktimer;
127	work->worker = worker;
128	kthread_init_work(&work->work, fn);
129}
130
131struct icc_path *msm_icc_get(struct device *dev, const char *name)
132{
133	struct device *mdss_dev = dev->parent;
134	struct icc_path *path;
135
136	path = of_icc_get(dev, name);
137	if (path)
138		return path;
139
140	/*
141	 * If there are no interconnects attached to the corresponding device
142	 * node, of_icc_get() will return NULL.
143	 *
144	 * If the MDP5/DPU device node doesn't have interconnects, lookup the
145	 * path in the parent (MDSS) device.
146	 */
147	return of_icc_get(mdss_dev, name);
148
149}
v6.2
  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 <linux/interconnect.h>
 
  9
 10#include "msm_drv.h"
 11
 12/*
 13 * Util/helpers:
 14 */
 15
 16struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
 17		const char *name)
 18{
 19	int i;
 20	char n[32];
 21
 22	snprintf(n, sizeof(n), "%s_clk", name);
 23
 24	for (i = 0; bulk && i < count; i++) {
 25		if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
 26			return bulk[i].clk;
 27	}
 28
 29
 30	return NULL;
 31}
 32
 33struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
 34{
 35	struct clk *clk;
 36	char name2[32];
 37
 38	clk = devm_clk_get(&pdev->dev, name);
 39	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
 40		return clk;
 41
 42	snprintf(name2, sizeof(name2), "%s_clk", name);
 43
 44	clk = devm_clk_get(&pdev->dev, name2);
 45	if (!IS_ERR(clk))
 46		dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
 47				"\"%s\" instead of \"%s\"\n", name, name2);
 48
 49	return clk;
 50}
 51
 52static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
 53				  bool quiet, phys_addr_t *psize)
 54{
 55	struct resource *res;
 56	unsigned long size;
 57	void __iomem *ptr;
 58
 59	if (name)
 60		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 61	else
 62		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 63
 64	if (!res) {
 65		if (!quiet)
 66			DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
 67		return ERR_PTR(-EINVAL);
 68	}
 69
 70	size = resource_size(res);
 71
 72	ptr = devm_ioremap(&pdev->dev, res->start, size);
 73	if (!ptr) {
 74		if (!quiet)
 75			DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
 76		return ERR_PTR(-ENOMEM);
 77	}
 78
 79	if (psize)
 80		*psize = size;
 81
 82	return ptr;
 83}
 84
 85void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
 86{
 87	return _msm_ioremap(pdev, name, false, NULL);
 88}
 89
 90void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
 91{
 92	return _msm_ioremap(pdev, name, true, NULL);
 93}
 94
 95void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
 96			  phys_addr_t *psize)
 97{
 98	return _msm_ioremap(pdev, name, false, psize);
 99}
100
101static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
102{
103	struct msm_hrtimer_work *work = container_of(t,
104			struct msm_hrtimer_work, timer);
105
106	kthread_queue_work(work->worker, &work->work);
107
108	return HRTIMER_NORESTART;
109}
110
111void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
112			    ktime_t wakeup_time,
113			    enum hrtimer_mode mode)
114{
115	hrtimer_start(&work->timer, wakeup_time, mode);
116}
117
118void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
119			   struct kthread_worker *worker,
120			   kthread_work_func_t fn,
121			   clockid_t clock_id,
122			   enum hrtimer_mode mode)
123{
124	hrtimer_init(&work->timer, clock_id, mode);
125	work->timer.function = msm_hrtimer_worktimer;
126	work->worker = worker;
127	kthread_init_work(&work->work, fn);
128}
129
130struct icc_path *msm_icc_get(struct device *dev, const char *name)
131{
132	struct device *mdss_dev = dev->parent;
133	struct icc_path *path;
134
135	path = of_icc_get(dev, name);
136	if (path)
137		return path;
138
139	/*
140	 * If there are no interconnects attached to the corresponding device
141	 * node, of_icc_get() will return NULL.
142	 *
143	 * If the MDP5/DPU device node doesn't have interconnects, lookup the
144	 * path in the parent (MDSS) device.
145	 */
146	return of_icc_get(mdss_dev, name);
147
148}