mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
msm: kgsl: Fixup the RGMU probe
Fix the RGMU probe to use standard helper functions and do proper reference counting. Change-Id: Ic0dedbadf5af14338de83cd9041674cc6f1ea304 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
05fb678662
commit
76f54bf67f
2 changed files with 55 additions and 101 deletions
|
|
@ -23,88 +23,65 @@ static int rgmu_irq_probe(struct kgsl_device *device)
|
|||
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
|
||||
int ret;
|
||||
|
||||
rgmu->oob_interrupt_num = platform_get_irq_byname(rgmu->pdev,
|
||||
"kgsl_oob");
|
||||
|
||||
ret = devm_request_irq(&rgmu->pdev->dev,
|
||||
rgmu->oob_interrupt_num,
|
||||
oob_irq_handler, IRQF_TRIGGER_HIGH,
|
||||
"kgsl-oob", device);
|
||||
if (ret) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Request kgsl-oob interrupt failed:%d\n", ret);
|
||||
ret = kgsl_request_irq(rgmu->pdev, "kgsl_oob", oob_irq_handler, device);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rgmu->rgmu_interrupt_num = platform_get_irq_byname(rgmu->pdev,
|
||||
"kgsl_rgmu");
|
||||
rgmu->oob_interrupt_num = ret;
|
||||
|
||||
ret = devm_request_irq(&rgmu->pdev->dev,
|
||||
rgmu->rgmu_interrupt_num,
|
||||
rgmu_irq_handler, IRQF_TRIGGER_HIGH,
|
||||
"kgsl-rgmu", device);
|
||||
if (ret)
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Request kgsl-rgmu interrupt failed:%d\n", ret);
|
||||
ret = kgsl_request_irq(rgmu->pdev,
|
||||
"kgsl_rgmu", rgmu_irq_handler, device);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
rgmu->rgmu_interrupt_num = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rgmu_regulators_probe(struct rgmu_device *rgmu,
|
||||
struct device_node *node)
|
||||
static int rgmu_regulators_probe(struct rgmu_device *rgmu)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
rgmu->cx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vddcx");
|
||||
if (IS_ERR_OR_NULL(rgmu->cx_gdsc)) {
|
||||
if (IS_ERR(rgmu->cx_gdsc)) {
|
||||
ret = PTR_ERR(rgmu->cx_gdsc);
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Couldn't get CX gdsc error:%d\n", ret);
|
||||
rgmu->cx_gdsc = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
rgmu->gx_gdsc = devm_regulator_get(&rgmu->pdev->dev, "vdd");
|
||||
if (IS_ERR_OR_NULL(rgmu->gx_gdsc)) {
|
||||
if (IS_ERR(rgmu->gx_gdsc)) {
|
||||
ret = PTR_ERR(rgmu->gx_gdsc);
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Couldn't get GX gdsc error:%d\n", ret);
|
||||
rgmu->gx_gdsc = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rgmu_clocks_probe(struct rgmu_device *rgmu, struct device_node *node)
|
||||
{
|
||||
const char *cname;
|
||||
struct property *prop;
|
||||
struct clk *c;
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
of_property_for_each_string(node, "clock-names", prop, cname) {
|
||||
ret = devm_clk_bulk_get_all(&rgmu->pdev->dev, &rgmu->clks);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (i >= ARRAY_SIZE(rgmu->clks)) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"dt: too many RGMU clocks defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rgmu->num_clks = ret;
|
||||
|
||||
c = devm_clk_get(&rgmu->pdev->dev, cname);
|
||||
if (IS_ERR_OR_NULL(c)) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"dt: Couldn't get clock: %s\n", cname);
|
||||
return PTR_ERR(c);
|
||||
}
|
||||
rgmu->gpu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "core");
|
||||
if (!rgmu->gpu_clk) {
|
||||
dev_err(&rgmu->pdev->dev, "The GPU clock isn't defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Remember the key clocks that we need to control later */
|
||||
if (!strcmp(cname, "core"))
|
||||
rgmu->gpu_clk = c;
|
||||
else if (!strcmp(cname, "gmu"))
|
||||
rgmu->rgmu_clk = c;
|
||||
|
||||
rgmu->clks[i++] = c;
|
||||
rgmu->rgmu_clk = kgsl_of_clk_by_name(rgmu->clks, ret, "gmu");
|
||||
if (!rgmu->rgmu_clk) {
|
||||
dev_err(&rgmu->pdev->dev, "The RGMU clock isn't defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -114,7 +91,7 @@ static void rgmu_disable_clks(struct kgsl_device *device)
|
|||
{
|
||||
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
|
||||
struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
|
||||
int j = 0, ret;
|
||||
int ret;
|
||||
|
||||
/* Check GX GDSC is status */
|
||||
if (gmu_dev_ops->gx_is_on(device)) {
|
||||
|
|
@ -141,22 +118,17 @@ static void rgmu_disable_clks(struct kgsl_device *device)
|
|||
dev_err(&rgmu->pdev->dev, "gx is stuck on\n");
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++)
|
||||
clk_disable_unprepare(rgmu->clks[j]);
|
||||
clk_bulk_disable_unprepare(rgmu->num_clks, rgmu->clks);
|
||||
|
||||
clear_bit(GMU_CLK_ON, &device->gmu_core.flags);
|
||||
}
|
||||
|
||||
static int rgmu_enable_clks(struct kgsl_device *device)
|
||||
{
|
||||
int ret, j = 0;
|
||||
int ret;
|
||||
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
|
||||
if (IS_ERR_OR_NULL(rgmu->rgmu_clk) ||
|
||||
IS_ERR_OR_NULL(rgmu->gpu_clk))
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_set_rate(rgmu->rgmu_clk, RGMU_CLK_FREQ);
|
||||
if (ret) {
|
||||
dev_err(&rgmu->pdev->dev, "Couldn't set the RGMU clock\n");
|
||||
|
|
@ -170,14 +142,10 @@ static int rgmu_enable_clks(struct kgsl_device *device)
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(rgmu->clks); j++) {
|
||||
ret = clk_prepare_enable(rgmu->clks[j]);
|
||||
if (ret) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Fail(%d) to enable gpucc clk idx %d\n",
|
||||
ret, j);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_bulk_prepare_enable(rgmu->num_clks, rgmu->clks);
|
||||
if (ret) {
|
||||
dev_err(&rgmu->pdev->dev, "Failed to enable RGMU clocks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
set_bit(GMU_CLK_ON, &device->gmu_core.flags);
|
||||
|
|
@ -289,42 +257,31 @@ static int rgmu_probe(struct kgsl_device *device, struct platform_device *pdev)
|
|||
rgmu->pdev = pdev;
|
||||
|
||||
/* Set up RGMU regulators */
|
||||
ret = rgmu_regulators_probe(rgmu, pdev->dev.of_node);
|
||||
ret = rgmu_regulators_probe(rgmu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set up RGMU clocks */
|
||||
ret = rgmu_clocks_probe(rgmu, pdev->dev.of_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Map and reserve RGMU CSRs registers */
|
||||
res = platform_get_resource_byname(rgmu->pdev,
|
||||
IORESOURCE_MEM, "kgsl_rgmu");
|
||||
if (res == NULL) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"platform_get_resource failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (res->start == 0 || resource_size(res) == 0) {
|
||||
dev_err(&rgmu->pdev->dev,
|
||||
"Register region is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rgmu->reg_phys = res->start;
|
||||
rgmu->reg_len = resource_size(res);
|
||||
device->gmu_core.reg_virt = devm_ioremap(&rgmu->pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
|
||||
if (device->gmu_core.reg_virt == NULL) {
|
||||
dev_err(&rgmu->pdev->dev, "Unable to remap rgmu registers\n");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "kgsl_rgmu");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "The RGMU register region isn't defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
device->gmu_core.gmu2gpu_offset =
|
||||
(rgmu->reg_phys - device->reg_phys) >> 2;
|
||||
device->gmu_core.reg_len = rgmu->reg_len;
|
||||
device->gmu_core.gmu2gpu_offset = (res->start - device->reg_phys) >> 2;
|
||||
device->gmu_core.reg_len = resource_size(res);
|
||||
device->gmu_core.reg_virt = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
||||
if (IS_ERR(device->gmu_core.reg_virt)) {
|
||||
dev_err(&pdev->dev, "Unable to map the RGMU registers\n");
|
||||
return PTR_ERR(device->gmu_core.reg_virt);
|
||||
}
|
||||
|
||||
device->gmu_core.ptr = (void *)rgmu;
|
||||
|
||||
/* Initialize OOB and RGMU interrupts */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef __KGSL_RGMU_H
|
||||
#define __KGSL_RGMU_H
|
||||
|
|
@ -18,9 +18,6 @@
|
|||
/**
|
||||
* struct rgmu_device - rGMU device structure
|
||||
* @ver: RGMU firmware version
|
||||
* @reg_phys: RGMU CSR physical address
|
||||
* @reg_virt: RGMU CSR virtual address
|
||||
* @reg_len: RGMU CSR range
|
||||
* @rgmu_interrupt_num: RGMU interrupt number
|
||||
* @oob_interrupt_num: number of RGMU asserted OOB interrupt
|
||||
* @fw_hostptr: Buffer which holds the RGMU firmware
|
||||
|
|
@ -37,15 +34,15 @@
|
|||
struct rgmu_device {
|
||||
u32 ver;
|
||||
struct platform_device *pdev;
|
||||
unsigned long reg_phys;
|
||||
unsigned int reg_len;
|
||||
unsigned int rgmu_interrupt_num;
|
||||
unsigned int oob_interrupt_num;
|
||||
unsigned int *fw_hostptr;
|
||||
uint32_t fw_size;
|
||||
struct regulator *cx_gdsc;
|
||||
struct regulator *gx_gdsc;
|
||||
struct clk *clks[MAX_RGMU_CLKS];
|
||||
struct clk_bulk_data *clks;
|
||||
/** @num_clks: Number of clocks in @clks */
|
||||
int num_clks;
|
||||
struct clk *gpu_clk;
|
||||
struct clk *rgmu_clk;
|
||||
unsigned int idle_level;
|
||||
|
|
|
|||
Loading…
Reference in a new issue