diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index cc951d471590..6ce495e7b47c 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -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 diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 73f95b44b036..2f1dacad7b1c 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -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; diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 8941a899cfa8..c53e82983cec 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -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; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 454123e4af0f..ee0fe53cf3fb 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -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; } diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 6659a47fe690..738ef59feac1 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -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 @@ -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; } /**