mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 21:54:34 -04:00
msm: kgsl: Finish up probe cleanups
Do the last bits needed to make the probes defer capable. Fix a few more device_node reference counts and fix up the probe failure unwind paths. Change-Id: Ic0dedbadd6f4c9b46a02e9b6ea0b145c81b50520 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
fb77ada179
commit
0f9ebd5579
5 changed files with 80 additions and 90 deletions
|
|
@ -908,11 +908,9 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void adreno_of_get_initial_pwrlevel(struct adreno_device *adreno_dev,
|
||||
static void adreno_of_get_initial_pwrlevel(struct kgsl_pwrctrl *pwr,
|
||||
struct device_node *node)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int init_level = 1;
|
||||
|
||||
of_property_read_u32(node, "qcom,initial-pwrlevel", &init_level);
|
||||
|
|
@ -959,14 +957,14 @@ static int adreno_of_get_legacy_pwrlevels(struct adreno_device *adreno_dev,
|
|||
}
|
||||
|
||||
ret = adreno_of_parse_pwrlevels(adreno_dev, node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
adreno_of_get_initial_pwrlevel(adreno_dev, parent);
|
||||
if (!ret) {
|
||||
adreno_of_get_initial_pwrlevel(&device->pwrctrl, parent);
|
||||
adreno_of_get_limits(adreno_dev, parent);
|
||||
}
|
||||
|
||||
adreno_of_get_limits(adreno_dev, parent);
|
||||
|
||||
return 0;
|
||||
of_node_put(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
|
||||
|
|
@ -989,10 +987,12 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
|
|||
int ret;
|
||||
|
||||
ret = adreno_of_parse_pwrlevels(adreno_dev, child);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
adreno_of_get_initial_pwrlevel(adreno_dev, child);
|
||||
adreno_of_get_initial_pwrlevel(&device->pwrctrl, child);
|
||||
|
||||
/*
|
||||
* Check for global throttle-pwrlevel first and override
|
||||
|
|
@ -1001,6 +1001,7 @@ static int adreno_of_get_pwrlevels(struct adreno_device *adreno_dev,
|
|||
adreno_of_get_limits(adreno_dev, parent);
|
||||
adreno_of_get_limits(adreno_dev, child);
|
||||
|
||||
of_node_put(child);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1032,26 +1033,23 @@ l3_pwrlevel_probe(struct kgsl_device *device, struct device_node *node)
|
|||
if (index >= device->num_l3_pwrlevels)
|
||||
device->num_l3_pwrlevels = index + 1;
|
||||
|
||||
if (of_property_read_u32(child, "qcom,l3-freq",
|
||||
&device->l3_freq[index]))
|
||||
continue;
|
||||
of_property_read_u32(child, "qcom,l3-freq",
|
||||
&device->l3_freq[index]);
|
||||
}
|
||||
|
||||
device->l3_clk = devm_clk_get(&device->pdev->dev, "l3_vote");
|
||||
|
||||
if (IS_ERR_OR_NULL(device->l3_clk)) {
|
||||
if (IS_ERR_OR_NULL(device->l3_clk))
|
||||
dev_err(&device->pdev->dev,
|
||||
"Unable to get the l3_vote clock\n");
|
||||
device->l3_clk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int adreno_of_get_power(struct adreno_device *adreno_dev,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
/* Get starting physical address of device registers */
|
||||
res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
|
||||
|
|
@ -1071,10 +1069,11 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
|
|||
device->reg_phys = res->start;
|
||||
device->reg_len = resource_size(res);
|
||||
|
||||
if (adreno_of_get_pwrlevels(adreno_dev, node))
|
||||
return -EINVAL;
|
||||
ret = adreno_of_get_pwrlevels(adreno_dev, pdev->dev.of_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
l3_pwrlevel_probe(device, node);
|
||||
l3_pwrlevel_probe(device, pdev->dev.of_node);
|
||||
|
||||
/* Default timeout is 80 ms across all targets */
|
||||
device->pwrctrl.interval_timeout = msecs_to_jiffies(80);
|
||||
|
|
@ -1082,8 +1081,9 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
|
|||
/* Set default bus control to true on all targets */
|
||||
device->pwrctrl.bus_control = true;
|
||||
|
||||
device->pwrctrl.input_disable = of_property_read_bool(node,
|
||||
"qcom,disable-wake-on-touch");
|
||||
device->pwrctrl.input_disable =
|
||||
of_property_read_bool(pdev->dev.of_node,
|
||||
"qcom,disable-wake-on-touch");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1267,7 +1267,7 @@ static int adreno_read_speed_bin(struct platform_device *pdev)
|
|||
return val;
|
||||
}
|
||||
|
||||
static void adreno_probe_llcc(struct adreno_device *adreno_dev,
|
||||
static int adreno_probe_llcc(struct adreno_device *adreno_dev,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1275,16 +1275,32 @@ static void adreno_probe_llcc(struct adreno_device *adreno_dev,
|
|||
/* Get the system cache slice descriptor for GPU */
|
||||
adreno_dev->gpu_llc_slice = llcc_slice_getd(LLCC_GPU);
|
||||
ret = PTR_ERR_OR_ZERO(adreno_dev->gpu_llc_slice);
|
||||
if (ret && ret != -ENOENT)
|
||||
dev_warn(&pdev->dev, "Unable to get the GPU LLC slice: %d\n",
|
||||
ret);
|
||||
|
||||
if (ret) {
|
||||
/* Propagate EPROBE_DEFER back to the probe function */
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
|
||||
if (ret != -ENOENT)
|
||||
dev_warn(&pdev->dev,
|
||||
"Unable to get the GPU LLC slice: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Get the system cache slice descriptor for GPU pagetables */
|
||||
adreno_dev->gpuhtw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
|
||||
ret = PTR_ERR_OR_ZERO(adreno_dev->gpuhtw_llc_slice);
|
||||
if (ret && ret != -ENOENT)
|
||||
dev_warn(&pdev->dev, "Unable to get GPU HTW LLC slice: %d\n",
|
||||
ret);
|
||||
if (ret) {
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
llcc_slice_putd(adreno_dev->gpu_llc_slice);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret != -ENOENT)
|
||||
dev_warn(&pdev->dev,
|
||||
"Unable to get GPU HTW LLC slice: %d\n", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct kgsl_functable adreno_functable;
|
||||
|
|
@ -1318,10 +1334,6 @@ static void adreno_setup_device(struct adreno_device *adreno_dev)
|
|||
INIT_LIST_HEAD(&adreno_dev->active_list);
|
||||
spin_lock_init(&adreno_dev->active_list_lock);
|
||||
|
||||
/* Enable use of the LLC slices where applicable */
|
||||
adreno_dev->gpu_llc_slice_enable = true;
|
||||
adreno_dev->gpuhtw_llc_slice_enable = true;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(adreno_dev->ringbuffers); i++) {
|
||||
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffers[i];
|
||||
|
||||
|
|
@ -1375,10 +1387,8 @@ static int adreno_bind(struct device *dev)
|
|||
return -ENODEV;
|
||||
|
||||
status = adreno_of_get_power(adreno_dev, pdev);
|
||||
if (status) {
|
||||
device->pdev = NULL;
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = kgsl_bus_init(device, pdev);
|
||||
if (status)
|
||||
|
|
@ -1407,8 +1417,10 @@ static int adreno_bind(struct device *dev)
|
|||
device->mmu.secured = (IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) &&
|
||||
ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION));
|
||||
|
||||
/* Probe the LLCC */
|
||||
adreno_probe_llcc(adreno_dev, pdev);
|
||||
/* Probe the LLCC - this could return -EPROBE_DEFER */
|
||||
status = adreno_probe_llcc(adreno_dev, pdev);
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* IF the GPU HTW slice was successsful set the MMU feature so the
|
||||
|
|
|
|||
|
|
@ -2286,6 +2286,9 @@ static void a6xx_platform_setup(struct adreno_device *adreno_dev)
|
|||
adreno_dev->preempt.skipsaverestore = true;
|
||||
adreno_dev->preempt.usesgmem = true;
|
||||
|
||||
adreno_dev->gpu_llc_slice_enable = true;
|
||||
adreno_dev->gpuhtw_llc_slice_enable = true;
|
||||
|
||||
if (adreno_has_gbif(adreno_dev)) {
|
||||
a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].regs =
|
||||
a6xx_perfcounters_gbif;
|
||||
|
|
|
|||
|
|
@ -324,32 +324,6 @@ static void adreno_preemption_timer(struct timer_list *t)
|
|||
queue_work(system_unbound_wq, &adreno_dev->preempt.work);
|
||||
}
|
||||
|
||||
static void adreno_preemption_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
int ret;
|
||||
|
||||
if (!ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
|
||||
return;
|
||||
|
||||
timer_setup(&preempt->timer, adreno_preemption_timer, 0);
|
||||
|
||||
ret = gpudev->preemption_init(adreno_dev);
|
||||
|
||||
WARN(ret, "adreno GPU preemption is disabled\n");
|
||||
}
|
||||
|
||||
static void adreno_preemption_close(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
if (!ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
|
||||
return;
|
||||
|
||||
del_timer(&preempt->timer);
|
||||
}
|
||||
|
||||
int adreno_ringbuffer_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
|
@ -386,15 +360,30 @@ int adreno_ringbuffer_init(struct adreno_device *adreno_dev)
|
|||
}
|
||||
}
|
||||
|
||||
adreno_preemption_init(adreno_dev);
|
||||
|
||||
adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]);
|
||||
|
||||
if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) {
|
||||
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
int ret;
|
||||
|
||||
timer_setup(&preempt->timer, adreno_preemption_timer, 0);
|
||||
|
||||
ret = gpudev->preemption_init(adreno_dev);
|
||||
WARN(ret, "adreno GPU preemption is disabled\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adreno_ringbuffer_close(struct adreno_device *adreno_dev)
|
||||
{
|
||||
adreno_preemption_close(adreno_dev);
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
if (!ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
|
||||
return;
|
||||
|
||||
del_timer(&preempt->timer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -791,7 +780,7 @@ static void adreno_ringbuffer_set_constraint(struct kgsl_device *device,
|
|||
((context->flags & KGSL_CONTEXT_PWR_CONSTRAINT) ||
|
||||
(flags & KGSL_CONTEXT_PWR_CONSTRAINT))) {
|
||||
|
||||
if (!device->l3_clk) {
|
||||
if (IS_ERR_OR_NULL(device->l3_clk)) {
|
||||
dev_err_once(device->dev,
|
||||
"l3_vote clk not available\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -4835,8 +4835,7 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
|
|||
/* Disable the sparse ioctl invocation as they are not used */
|
||||
device->flags &= ~KGSL_FLAG_SPARSE;
|
||||
|
||||
kgsl_device_debugfs_init(device);
|
||||
|
||||
/* Can return -EPROBE_DEFER */
|
||||
status = kgsl_pwrctrl_init(device);
|
||||
if (status)
|
||||
goto error;
|
||||
|
|
@ -4873,10 +4872,9 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
|
|||
rwlock_init(&device->context_lock);
|
||||
spin_lock_init(&device->submit_lock);
|
||||
|
||||
/* Check to see if our device can perform DMA correctly */
|
||||
status = dma_set_coherent_mask(&pdev->dev, KGSL_DMA_BIT_MASK);
|
||||
if (status)
|
||||
goto error_close_mmu;
|
||||
kgsl_device_debugfs_init(device);
|
||||
|
||||
dma_set_coherent_mask(&pdev->dev, KGSL_DMA_BIT_MASK);
|
||||
|
||||
/* Set up the GPU events for the device */
|
||||
kgsl_device_events_probe(device);
|
||||
|
|
@ -4889,13 +4887,9 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
|
|||
|
||||
return 0;
|
||||
|
||||
error_close_mmu:
|
||||
kgsl_mmu_close(device);
|
||||
kgsl_free_globals(device);
|
||||
error_pwrctrl_close:
|
||||
kgsl_pwrctrl_close(device);
|
||||
error:
|
||||
kgsl_device_debugfs_close(device);
|
||||
_unregister_device(device);
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
|
@ -1107,8 +1107,8 @@ void kgsl_device_snapshot_probe(struct kgsl_device *device, u32 size)
|
|||
{
|
||||
device->snapshot_memory.size = size;
|
||||
|
||||
device->snapshot_memory.ptr = kzalloc(device->snapshot_memory.size,
|
||||
GFP_KERNEL);
|
||||
device->snapshot_memory.ptr = devm_kzalloc(&device->pdev->dev,
|
||||
device->snapshot_memory.size, GFP_KERNEL);
|
||||
|
||||
if (!device->snapshot_memory.ptr)
|
||||
return;
|
||||
|
|
@ -1147,14 +1147,6 @@ void kgsl_device_snapshot_close(struct kgsl_device *device)
|
|||
sysfs_remove_files(&device->snapshot_kobj, snapshot_attrs);
|
||||
|
||||
kobject_put(&device->snapshot_kobj);
|
||||
|
||||
kfree(device->snapshot_memory.ptr);
|
||||
|
||||
device->snapshot_memory.ptr = NULL;
|
||||
device->snapshot_memory.size = 0;
|
||||
device->snapshot_faultcount = 0;
|
||||
device->force_panic = false;
|
||||
device->snapshot_crashdumper = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue