aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-02-15 14:49:56 -0500
committerArnd Bergmann <arnd@arndb.de>2019-02-15 14:50:20 -0500
commit5aa8f495d6ef70dbb200093a31d995ba96fcccd6 (patch)
tree8febcc3bd28dcba6b2aa6f796b8325a5ac5c6310 /drivers
parent50b0225bf412df3cdeb2dc89b7e4b1119e30bedb (diff)
parented10a259faa1bbdf77b8c2153b274b70c90cbb35 (diff)
Merge tag 'qcom-drivers-for-5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux into arm/drivers
Qualcomm ARM Based Driver Updates for v5.1 - Part 2 * Fixups/Cleanup for Qualcomm LLCC * tag 'qcom-drivers-for-5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux: qcom: soc: llcc-slice: Consolidate some code qcom: soc: llcc-slice: Clear the global drv_data pointer on error Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/soc/qcom/llcc-sdm845.c6
-rw-r--r--drivers/soc/qcom/llcc-slice.c101
2 files changed, 74 insertions, 33 deletions
diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c
index 2e1e4f0a5db8..86600d97c36d 100644
--- a/drivers/soc/qcom/llcc-sdm845.c
+++ b/drivers/soc/qcom/llcc-sdm845.c
@@ -71,6 +71,11 @@ static struct llcc_slice_config sdm845_data[] = {
71 SCT_ENTRY(LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0), 71 SCT_ENTRY(LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0),
72}; 72};
73 73
74static int sdm845_qcom_llcc_remove(struct platform_device *pdev)
75{
76 return qcom_llcc_remove(pdev);
77}
78
74static int sdm845_qcom_llcc_probe(struct platform_device *pdev) 79static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
75{ 80{
76 return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data)); 81 return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
@@ -87,6 +92,7 @@ static struct platform_driver sdm845_qcom_llcc_driver = {
87 .of_match_table = sdm845_qcom_llcc_of_match, 92 .of_match_table = sdm845_qcom_llcc_of_match,
88 }, 93 },
89 .probe = sdm845_qcom_llcc_probe, 94 .probe = sdm845_qcom_llcc_probe,
95 .remove = sdm845_qcom_llcc_remove,
90}; 96};
91module_platform_driver(sdm845_qcom_llcc_driver); 97module_platform_driver(sdm845_qcom_llcc_driver);
92 98
diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c
index 80667f7be52c..83a263926a25 100644
--- a/drivers/soc/qcom/llcc-slice.c
+++ b/drivers/soc/qcom/llcc-slice.c
@@ -46,7 +46,7 @@
46 46
47#define BANK_OFFSET_STRIDE 0x80000 47#define BANK_OFFSET_STRIDE 0x80000
48 48
49static struct llcc_drv_data *drv_data; 49static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
50 50
51static const struct regmap_config llcc_regmap_config = { 51static const struct regmap_config llcc_regmap_config = {
52 .reg_bits = 32, 52 .reg_bits = 32,
@@ -68,6 +68,9 @@ struct llcc_slice_desc *llcc_slice_getd(u32 uid)
68 struct llcc_slice_desc *desc; 68 struct llcc_slice_desc *desc;
69 u32 sz, count; 69 u32 sz, count;
70 70
71 if (IS_ERR(drv_data))
72 return ERR_CAST(drv_data);
73
71 cfg = drv_data->cfg; 74 cfg = drv_data->cfg;
72 sz = drv_data->cfg_size; 75 sz = drv_data->cfg_size;
73 76
@@ -108,6 +111,9 @@ static int llcc_update_act_ctrl(u32 sid,
108 u32 slice_status; 111 u32 slice_status;
109 int ret; 112 int ret;
110 113
114 if (IS_ERR(drv_data))
115 return PTR_ERR(drv_data);
116
111 act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid); 117 act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
112 status_reg = LLCC_TRP_STATUSn(sid); 118 status_reg = LLCC_TRP_STATUSn(sid);
113 119
@@ -143,6 +149,9 @@ int llcc_slice_activate(struct llcc_slice_desc *desc)
143 int ret; 149 int ret;
144 u32 act_ctrl_val; 150 u32 act_ctrl_val;
145 151
152 If (IS_ERR(drv_data))
153 return PTR_ERR(drv_data);
154
146 if (IS_ERR_OR_NULL(desc)) 155 if (IS_ERR_OR_NULL(desc))
147 return -EINVAL; 156 return -EINVAL;
148 157
@@ -180,6 +189,9 @@ int llcc_slice_deactivate(struct llcc_slice_desc *desc)
180 u32 act_ctrl_val; 189 u32 act_ctrl_val;
181 int ret; 190 int ret;
182 191
192 If (IS_ERR(drv_data))
193 return PTR_ERR(drv_data);
194
183 if (IS_ERR_OR_NULL(desc)) 195 if (IS_ERR_OR_NULL(desc))
184 return -EINVAL; 196 return -EINVAL;
185 197
@@ -289,46 +301,62 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
289 return ret; 301 return ret;
290} 302}
291 303
304int qcom_llcc_remove(struct platform_device *pdev)
305{
306 /* Set the global pointer to a error code to avoid referencing it */
307 drv_data = ERR_PTR(-ENODEV);
308 return 0;
309}
310EXPORT_SYMBOL_GPL(qcom_llcc_remove);
311
312static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
313 const char *name)
314{
315 struct resource *res;
316 void __iomem *base;
317
318 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
319 if (!res)
320 return ERR_PTR(-ENODEV);
321
322 base = devm_ioremap_resource(&pdev->dev, res);
323 if (IS_ERR(base))
324 return ERR_CAST(base);
325
326 return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);
327}
328
292int qcom_llcc_probe(struct platform_device *pdev, 329int qcom_llcc_probe(struct platform_device *pdev,
293 const struct llcc_slice_config *llcc_cfg, u32 sz) 330 const struct llcc_slice_config *llcc_cfg, u32 sz)
294{ 331{
295 u32 num_banks; 332 u32 num_banks;
296 struct device *dev = &pdev->dev; 333 struct device *dev = &pdev->dev;
297 struct resource *llcc_banks_res, *llcc_bcast_res;
298 void __iomem *llcc_banks_base, *llcc_bcast_base;
299 int ret, i; 334 int ret, i;
300 struct platform_device *llcc_edac; 335 struct platform_device *llcc_edac;
301 336
302 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); 337 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
303 if (!drv_data) 338 if (!drv_data) {
304 return -ENOMEM; 339 ret = -ENOMEM;
305 340 goto err;
306 llcc_banks_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 341 }
307 "llcc_base"); 342
308 llcc_banks_base = devm_ioremap_resource(&pdev->dev, llcc_banks_res); 343 drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base");
309 if (IS_ERR(llcc_banks_base)) 344 if (IS_ERR(drv_data->regmap)) {
310 return PTR_ERR(llcc_banks_base); 345 ret = PTR_ERR(drv_data->regmap);
311 346 goto err;
312 drv_data->regmap = devm_regmap_init_mmio(dev, llcc_banks_base, 347 }
313 &llcc_regmap_config); 348
314 if (IS_ERR(drv_data->regmap)) 349 drv_data->bcast_regmap =
315 return PTR_ERR(drv_data->regmap); 350 qcom_llcc_init_mmio(pdev, "llcc_broadcast_base");
316 351 if (IS_ERR(drv_data->bcast_regmap)) {
317 llcc_bcast_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 352 ret = PTR_ERR(drv_data->bcast_regmap);
318 "llcc_broadcast_base"); 353 goto err;
319 llcc_bcast_base = devm_ioremap_resource(&pdev->dev, llcc_bcast_res); 354 }
320 if (IS_ERR(llcc_bcast_base))
321 return PTR_ERR(llcc_bcast_base);
322
323 drv_data->bcast_regmap = devm_regmap_init_mmio(dev, llcc_bcast_base,
324 &llcc_regmap_config);
325 if (IS_ERR(drv_data->bcast_regmap))
326 return PTR_ERR(drv_data->bcast_regmap);
327 355
328 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0, 356 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
329 &num_banks); 357 &num_banks);
330 if (ret) 358 if (ret)
331 return ret; 359 goto err;
332 360
333 num_banks &= LLCC_LB_CNT_MASK; 361 num_banks &= LLCC_LB_CNT_MASK;
334 num_banks >>= LLCC_LB_CNT_SHIFT; 362 num_banks >>= LLCC_LB_CNT_SHIFT;
@@ -340,8 +368,10 @@ int qcom_llcc_probe(struct platform_device *pdev,
340 368
341 drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32), 369 drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32),
342 GFP_KERNEL); 370 GFP_KERNEL);
343 if (!drv_data->offsets) 371 if (!drv_data->offsets) {
344 return -ENOMEM; 372 ret = -ENOMEM;
373 goto err;
374 }
345 375
346 for (i = 0; i < num_banks; i++) 376 for (i = 0; i < num_banks; i++)
347 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; 377 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
@@ -349,8 +379,10 @@ int qcom_llcc_probe(struct platform_device *pdev,
349 drv_data->bitmap = devm_kcalloc(dev, 379 drv_data->bitmap = devm_kcalloc(dev,
350 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long), 380 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
351 GFP_KERNEL); 381 GFP_KERNEL);
352 if (!drv_data->bitmap) 382 if (!drv_data->bitmap) {
353 return -ENOMEM; 383 ret = -ENOMEM;
384 goto err;
385 }
354 386
355 drv_data->cfg = llcc_cfg; 387 drv_data->cfg = llcc_cfg;
356 drv_data->cfg_size = sz; 388 drv_data->cfg_size = sz;
@@ -359,7 +391,7 @@ int qcom_llcc_probe(struct platform_device *pdev,
359 391
360 ret = qcom_llcc_cfg_program(pdev); 392 ret = qcom_llcc_cfg_program(pdev);
361 if (ret) 393 if (ret)
362 return ret; 394 goto err;
363 395
364 drv_data->ecc_irq = platform_get_irq(pdev, 0); 396 drv_data->ecc_irq = platform_get_irq(pdev, 0);
365 if (drv_data->ecc_irq >= 0) { 397 if (drv_data->ecc_irq >= 0) {
@@ -370,6 +402,9 @@ int qcom_llcc_probe(struct platform_device *pdev,
370 dev_err(dev, "Failed to register llcc edac driver\n"); 402 dev_err(dev, "Failed to register llcc edac driver\n");
371 } 403 }
372 404
405 return 0;
406err:
407 drv_data = ERR_PTR(-ENODEV);
373 return ret; 408 return ret;
374} 409}
375EXPORT_SYMBOL_GPL(qcom_llcc_probe); 410EXPORT_SYMBOL_GPL(qcom_llcc_probe);