Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm: use componentised device support

Signed-off-by: Rob Clark <robdclark@gmail.com>

Rob Clark 060530f1 4e1cbaa3

+176 -33
+34 -15
drivers/gpu/drm/msm/adreno/a3xx_gpu.c
··· 41 41 module_param_named(hang_debug, hang_debug, bool, 0600); 42 42 static void a3xx_dump(struct msm_gpu *gpu); 43 43 44 - static struct platform_device *a3xx_pdev; 45 - 46 44 static void a3xx_me_init(struct msm_gpu *gpu) 47 45 { 48 46 struct msm_ringbuffer *ring = gpu->rb; ··· 318 320 ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); 319 321 #endif 320 322 321 - put_device(&a3xx_gpu->pdev->dev); 322 323 kfree(a3xx_gpu); 323 324 } 324 325 ··· 470 473 struct a3xx_gpu *a3xx_gpu = NULL; 471 474 struct adreno_gpu *adreno_gpu; 472 475 struct msm_gpu *gpu; 473 - struct platform_device *pdev = a3xx_pdev; 476 + struct msm_drm_private *priv = dev->dev_private; 477 + struct platform_device *pdev = priv->gpu_pdev; 474 478 struct adreno_platform_config *config; 475 479 int ret; 476 480 ··· 492 494 adreno_gpu = &a3xx_gpu->base; 493 495 gpu = &adreno_gpu->base; 494 496 495 - get_device(&pdev->dev); 496 497 a3xx_gpu->pdev = pdev; 497 498 498 499 gpu->fast_rate = config->fast_rate; ··· 553 556 # include <mach/kgsl.h> 554 557 #endif 555 558 556 - static int a3xx_probe(struct platform_device *pdev) 559 + static void set_gpu_pdev(struct drm_device *dev, 560 + struct platform_device *pdev) 561 + { 562 + struct msm_drm_private *priv = dev->dev_private; 563 + priv->gpu_pdev = pdev; 564 + } 565 + 566 + static int a3xx_bind(struct device *dev, struct device *master, void *data) 557 567 { 558 568 static struct adreno_platform_config config = {}; 559 569 #ifdef CONFIG_OF 560 - struct device_node *child, *node = pdev->dev.of_node; 570 + struct device_node *child, *node = dev->of_node; 561 571 u32 val; 562 572 int ret; 563 573 564 574 ret = of_property_read_u32(node, "qcom,chipid", &val); 565 575 if (ret) { 566 - dev_err(&pdev->dev, "could not find chipid: %d\n", ret); 576 + dev_err(dev, "could not find chipid: %d\n", ret); 567 577 return ret; 568 578 } 569 579 ··· 586 582 for_each_child_of_node(child, pwrlvl) { 587 583 ret = of_property_read_u32(pwrlvl, "qcom,gpu-freq", &val); 588 584 if (ret) { 589 - dev_err(&pdev->dev, "could not find gpu-freq: %d\n", ret); 585 + dev_err(dev, "could not find gpu-freq: %d\n", ret); 590 586 return ret; 591 587 } 592 588 config.fast_rate = max(config.fast_rate, val); ··· 596 592 } 597 593 598 594 if (!config.fast_rate) { 599 - dev_err(&pdev->dev, "could not find clk rates\n"); 595 + dev_err(dev, "could not find clk rates\n"); 600 596 return -ENXIO; 601 597 } 602 598 603 599 #else 604 - struct kgsl_device_platform_data *pdata = pdev->dev.platform_data; 600 + struct kgsl_device_platform_data *pdata = dev->platform_data; 605 601 uint32_t version = socinfo_get_version(); 606 602 if (cpu_is_apq8064ab()) { 607 603 config.fast_rate = 450000000; ··· 647 643 config.bus_scale_table = pdata->bus_scale_table; 648 644 # endif 649 645 #endif 650 - pdev->dev.platform_data = &config; 651 - a3xx_pdev = pdev; 646 + dev->platform_data = &config; 647 + set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev)); 652 648 return 0; 649 + } 650 + 651 + static void a3xx_unbind(struct device *dev, struct device *master, 652 + void *data) 653 + { 654 + set_gpu_pdev(dev_get_drvdata(master), NULL); 655 + } 656 + 657 + static const struct component_ops a3xx_ops = { 658 + .bind = a3xx_bind, 659 + .unbind = a3xx_unbind, 660 + }; 661 + 662 + static int a3xx_probe(struct platform_device *pdev) 663 + { 664 + return component_add(&pdev->dev, &a3xx_ops); 653 665 } 654 666 655 667 static int a3xx_remove(struct platform_device *pdev) 656 668 { 657 - a3xx_pdev = NULL; 669 + component_del(&pdev->dev, &a3xx_ops); 658 670 return 0; 659 671 } 660 672 ··· 678 658 { .compatible = "qcom,kgsl-3d0" }, 679 659 {} 680 660 }; 681 - MODULE_DEVICE_TABLE(of, dt_match); 682 661 683 662 static struct platform_driver a3xx_driver = { 684 663 .probe = a3xx_probe,
+30 -14
drivers/gpu/drm/msm/hdmi/hdmi.c
··· 17 17 18 18 #include "hdmi.h" 19 19 20 - static struct platform_device *hdmi_pdev; 21 - 22 20 void hdmi_set_mode(struct hdmi *hdmi, bool power_on) 23 21 { 24 22 uint32_t ctrl = 0; ··· 66 68 hdmi_i2c_destroy(hdmi->i2c); 67 69 68 70 platform_set_drvdata(hdmi->pdev, NULL); 69 - 70 - put_device(&hdmi->pdev->dev); 71 71 } 72 72 73 73 /* initialize connector */ ··· 73 77 { 74 78 struct hdmi *hdmi = NULL; 75 79 struct msm_drm_private *priv = dev->dev_private; 76 - struct platform_device *pdev = hdmi_pdev; 80 + struct platform_device *pdev = priv->hdmi_pdev; 77 81 struct hdmi_platform_config *config; 78 82 int i, ret; 79 83 ··· 92 96 } 93 97 94 98 kref_init(&hdmi->refcount); 95 - 96 - get_device(&pdev->dev); 97 99 98 100 hdmi->dev = dev; 99 101 hdmi->pdev = pdev; ··· 249 255 250 256 #include <linux/of_gpio.h> 251 257 252 - static int hdmi_dev_probe(struct platform_device *pdev) 258 + static void set_hdmi_pdev(struct drm_device *dev, 259 + struct platform_device *pdev) 260 + { 261 + struct msm_drm_private *priv = dev->dev_private; 262 + priv->hdmi_pdev = pdev; 263 + } 264 + 265 + static int hdmi_bind(struct device *dev, struct device *master, void *data) 253 266 { 254 267 static struct hdmi_platform_config config = {}; 255 268 #ifdef CONFIG_OF 256 - struct device_node *of_node = pdev->dev.of_node; 269 + struct device_node *of_node = dev->of_node; 257 270 258 271 int get_gpio(const char *name) 259 272 { 260 273 int gpio = of_get_named_gpio(of_node, name, 0); 261 274 if (gpio < 0) { 262 - dev_err(&pdev->dev, "failed to get gpio: %s (%d)\n", 275 + dev_err(dev, "failed to get gpio: %s (%d)\n", 263 276 name, gpio); 264 277 gpio = -1; 265 278 } ··· 343 342 config.mux_sel_gpio = -1; 344 343 } 345 344 #endif 346 - pdev->dev.platform_data = &config; 347 - hdmi_pdev = pdev; 345 + dev->platform_data = &config; 346 + set_hdmi_pdev(dev_get_drvdata(master), to_platform_device(dev)); 348 347 return 0; 348 + } 349 + 350 + static void hdmi_unbind(struct device *dev, struct device *master, 351 + void *data) 352 + { 353 + set_hdmi_pdev(dev_get_drvdata(master), NULL); 354 + } 355 + 356 + static const struct component_ops hdmi_ops = { 357 + .bind = hdmi_bind, 358 + .unbind = hdmi_unbind, 359 + }; 360 + 361 + static int hdmi_dev_probe(struct platform_device *pdev) 362 + { 363 + return component_add(&pdev->dev, &hdmi_ops); 349 364 } 350 365 351 366 static int hdmi_dev_remove(struct platform_device *pdev) 352 367 { 353 - hdmi_pdev = NULL; 368 + component_del(&pdev->dev, &hdmi_ops); 354 369 return 0; 355 370 } 356 371 ··· 374 357 { .compatible = "qcom,hdmi-tx" }, 375 358 {} 376 359 }; 377 - MODULE_DEVICE_TABLE(of, dt_match); 378 360 379 361 static struct platform_driver hdmi_driver = { 380 362 .probe = hdmi_dev_probe,
+108 -4
drivers/gpu/drm/msm/msm_drv.c
··· 56 56 MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); 57 57 module_param(vram, charp, 0); 58 58 59 + /* 60 + * Util/helpers: 61 + */ 62 + 59 63 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 60 64 const char *dbgname) 61 65 { ··· 147 143 priv->vram.paddr, &attrs); 148 144 } 149 145 146 + component_unbind_all(dev->dev, dev); 147 + 150 148 dev->dev_private = NULL; 151 149 152 150 kfree(priv); ··· 180 174 struct msm_drm_private *priv; 181 175 struct msm_kms *kms; 182 176 int ret; 177 + 183 178 184 179 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 185 180 if (!priv) { ··· 232 225 (uint32_t)priv->vram.paddr, 233 226 (uint32_t)(priv->vram.paddr + size)); 234 227 } 228 + 229 + platform_set_drvdata(pdev, dev); 230 + 231 + /* Bind all our sub-components: */ 232 + ret = component_bind_all(dev->dev, dev); 233 + if (ret) 234 + return ret; 235 235 236 236 switch (get_mdp_ver(pdev)) { 237 237 case 4: ··· 294 280 dev_err(dev->dev, "failed to install IRQ handler\n"); 295 281 goto fail; 296 282 } 297 - 298 - platform_set_drvdata(pdev, dev); 299 283 300 284 #ifdef CONFIG_DRM_MSM_FBDEV 301 285 priv->fbdev = msm_fbdev_init(dev); ··· 836 824 }; 837 825 838 826 /* 827 + * Componentized driver support: 828 + */ 829 + 830 + #ifdef CONFIG_OF 831 + /* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx 832 + * (or probably any other).. so probably some room for some helpers 833 + */ 834 + static int compare_of(struct device *dev, void *data) 835 + { 836 + return dev->of_node == data; 837 + } 838 + 839 + static int msm_drm_add_components(struct device *master, struct master *m) 840 + { 841 + struct device_node *np = master->of_node; 842 + unsigned i; 843 + int ret; 844 + 845 + for (i = 0; ; i++) { 846 + struct device_node *node; 847 + 848 + node = of_parse_phandle(np, "connectors", i); 849 + if (!node) 850 + break; 851 + 852 + ret = component_master_add_child(m, compare_of, node); 853 + of_node_put(node); 854 + 855 + if (ret) 856 + return ret; 857 + } 858 + return 0; 859 + } 860 + #else 861 + static int compare_dev(struct device *dev, void *data) 862 + { 863 + return dev == data; 864 + } 865 + 866 + static int msm_drm_add_components(struct device *master, struct master *m) 867 + { 868 + /* For non-DT case, it kinda sucks. We don't actually have a way 869 + * to know whether or not we are waiting for certain devices (or if 870 + * they are simply not present). But for non-DT we only need to 871 + * care about apq8064/apq8060/etc (all mdp4/a3xx): 872 + */ 873 + static const char *devnames[] = { 874 + "hdmi_msm.0", "kgsl-3d0.0", 875 + }; 876 + int i; 877 + 878 + DBG("Adding components.."); 879 + 880 + for (i = 0; i < ARRAY_SIZE(devnames); i++) { 881 + struct device *dev; 882 + int ret; 883 + 884 + dev = bus_find_device_by_name(&platform_bus_type, 885 + NULL, devnames[i]); 886 + if (!dev) { 887 + dev_info(master, "still waiting for %s\n", devnames[i]); 888 + return -EPROBE_DEFER; 889 + } 890 + 891 + ret = component_master_add_child(m, compare_dev, dev); 892 + if (ret) { 893 + DBG("could not add child: %d", ret); 894 + return ret; 895 + } 896 + } 897 + 898 + return 0; 899 + } 900 + #endif 901 + 902 + static int msm_drm_bind(struct device *dev) 903 + { 904 + return drm_platform_init(&msm_driver, to_platform_device(dev)); 905 + } 906 + 907 + static void msm_drm_unbind(struct device *dev) 908 + { 909 + drm_put_dev(platform_get_drvdata(to_platform_device(dev))); 910 + } 911 + 912 + static const struct component_master_ops msm_drm_ops = { 913 + .add_components = msm_drm_add_components, 914 + .bind = msm_drm_bind, 915 + .unbind = msm_drm_unbind, 916 + }; 917 + 918 + /* 839 919 * Platform driver: 840 920 */ 841 921 842 922 static int msm_pdev_probe(struct platform_device *pdev) 843 923 { 844 924 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 845 - return drm_platform_init(&msm_driver, pdev); 925 + return component_master_add(&pdev->dev, &msm_drm_ops); 846 926 } 847 927 848 928 static int msm_pdev_remove(struct platform_device *pdev) 849 929 { 850 - drm_put_dev(platform_get_drvdata(pdev)); 930 + component_master_del(&pdev->dev, &msm_drm_ops); 851 931 852 932 return 0; 853 933 }
+4
drivers/gpu/drm/msm/msm_drv.h
··· 22 22 #include <linux/clk.h> 23 23 #include <linux/cpufreq.h> 24 24 #include <linux/module.h> 25 + #include <linux/component.h> 25 26 #include <linux/platform_device.h> 26 27 #include <linux/pm.h> 27 28 #include <linux/pm_runtime.h> ··· 69 68 struct msm_drm_private { 70 69 71 70 struct msm_kms *kms; 71 + 72 + /* subordinate devices, if present: */ 73 + struct platform_device *hdmi_pdev, *gpu_pdev; 72 74 73 75 /* when we have more than one 'msm_gpu' these need to be an array: */ 74 76 struct msm_gpu *gpu;