Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved.
0004  * Copyright (C) 2013 Red Hat
0005  * Author: Rob Clark <robdclark@gmail.com>
0006  */
0007 
0008 #include "msm_drv.h"
0009 
0010 /*
0011  * Util/helpers:
0012  */
0013 
0014 struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
0015         const char *name)
0016 {
0017     int i;
0018     char n[32];
0019 
0020     snprintf(n, sizeof(n), "%s_clk", name);
0021 
0022     for (i = 0; bulk && i < count; i++) {
0023         if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
0024             return bulk[i].clk;
0025     }
0026 
0027 
0028     return NULL;
0029 }
0030 
0031 struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
0032 {
0033     struct clk *clk;
0034     char name2[32];
0035 
0036     clk = devm_clk_get(&pdev->dev, name);
0037     if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
0038         return clk;
0039 
0040     snprintf(name2, sizeof(name2), "%s_clk", name);
0041 
0042     clk = devm_clk_get(&pdev->dev, name2);
0043     if (!IS_ERR(clk))
0044         dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
0045                 "\"%s\" instead of \"%s\"\n", name, name2);
0046 
0047     return clk;
0048 }
0049 
0050 static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
0051                   bool quiet, phys_addr_t *psize)
0052 {
0053     struct resource *res;
0054     unsigned long size;
0055     void __iomem *ptr;
0056 
0057     if (name)
0058         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
0059     else
0060         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0061 
0062     if (!res) {
0063         if (!quiet)
0064             DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
0065         return ERR_PTR(-EINVAL);
0066     }
0067 
0068     size = resource_size(res);
0069 
0070     ptr = devm_ioremap(&pdev->dev, res->start, size);
0071     if (!ptr) {
0072         if (!quiet)
0073             DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
0074         return ERR_PTR(-ENOMEM);
0075     }
0076 
0077     if (psize)
0078         *psize = size;
0079 
0080     return ptr;
0081 }
0082 
0083 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
0084 {
0085     return _msm_ioremap(pdev, name, false, NULL);
0086 }
0087 
0088 void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
0089 {
0090     return _msm_ioremap(pdev, name, true, NULL);
0091 }
0092 
0093 void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
0094               phys_addr_t *psize)
0095 {
0096     return _msm_ioremap(pdev, name, false, psize);
0097 }
0098 
0099 static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
0100 {
0101     struct msm_hrtimer_work *work = container_of(t,
0102             struct msm_hrtimer_work, timer);
0103 
0104     kthread_queue_work(work->worker, &work->work);
0105 
0106     return HRTIMER_NORESTART;
0107 }
0108 
0109 void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
0110                 ktime_t wakeup_time,
0111                 enum hrtimer_mode mode)
0112 {
0113     hrtimer_start(&work->timer, wakeup_time, mode);
0114 }
0115 
0116 void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
0117                struct kthread_worker *worker,
0118                kthread_work_func_t fn,
0119                clockid_t clock_id,
0120                enum hrtimer_mode mode)
0121 {
0122     hrtimer_init(&work->timer, clock_id, mode);
0123     work->timer.function = msm_hrtimer_worktimer;
0124     work->worker = worker;
0125     kthread_init_work(&work->work, fn);
0126 }