diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 94 |
1 files changed, 45 insertions, 49 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9a5d87db5c23..26ee80db17af 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -181,7 +181,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags) | |||
| 181 | struct msm_kms *kms; | 181 | struct msm_kms *kms; |
| 182 | int ret; | 182 | int ret; |
| 183 | 183 | ||
| 184 | |||
| 185 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 184 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 186 | if (!priv) { | 185 | if (!priv) { |
| 187 | dev_err(dev->dev, "failed to allocate private data\n"); | 186 | dev_err(dev->dev, "failed to allocate private data\n"); |
| @@ -314,13 +313,15 @@ fail: | |||
| 314 | 313 | ||
| 315 | static void load_gpu(struct drm_device *dev) | 314 | static void load_gpu(struct drm_device *dev) |
| 316 | { | 315 | { |
| 316 | static DEFINE_MUTEX(init_lock); | ||
| 317 | struct msm_drm_private *priv = dev->dev_private; | 317 | struct msm_drm_private *priv = dev->dev_private; |
| 318 | struct msm_gpu *gpu; | 318 | struct msm_gpu *gpu; |
| 319 | 319 | ||
| 320 | mutex_lock(&init_lock); | ||
| 321 | |||
| 320 | if (priv->gpu) | 322 | if (priv->gpu) |
| 321 | return; | 323 | goto out; |
| 322 | 324 | ||
| 323 | mutex_lock(&dev->struct_mutex); | ||
| 324 | gpu = a3xx_gpu_init(dev); | 325 | gpu = a3xx_gpu_init(dev); |
| 325 | if (IS_ERR(gpu)) { | 326 | if (IS_ERR(gpu)) { |
| 326 | dev_warn(dev->dev, "failed to load a3xx gpu\n"); | 327 | dev_warn(dev->dev, "failed to load a3xx gpu\n"); |
| @@ -330,7 +331,9 @@ static void load_gpu(struct drm_device *dev) | |||
| 330 | 331 | ||
| 331 | if (gpu) { | 332 | if (gpu) { |
| 332 | int ret; | 333 | int ret; |
| 334 | mutex_lock(&dev->struct_mutex); | ||
| 333 | gpu->funcs->pm_resume(gpu); | 335 | gpu->funcs->pm_resume(gpu); |
| 336 | mutex_unlock(&dev->struct_mutex); | ||
| 334 | ret = gpu->funcs->hw_init(gpu); | 337 | ret = gpu->funcs->hw_init(gpu); |
| 335 | if (ret) { | 338 | if (ret) { |
| 336 | dev_err(dev->dev, "gpu hw init failed: %d\n", ret); | 339 | dev_err(dev->dev, "gpu hw init failed: %d\n", ret); |
| @@ -340,12 +343,12 @@ static void load_gpu(struct drm_device *dev) | |||
| 340 | /* give inactive pm a chance to kick in: */ | 343 | /* give inactive pm a chance to kick in: */ |
| 341 | msm_gpu_retire(gpu); | 344 | msm_gpu_retire(gpu); |
| 342 | } | 345 | } |
| 343 | |||
| 344 | } | 346 | } |
| 345 | 347 | ||
| 346 | priv->gpu = gpu; | 348 | priv->gpu = gpu; |
| 347 | 349 | ||
| 348 | mutex_unlock(&dev->struct_mutex); | 350 | out: |
| 351 | mutex_unlock(&init_lock); | ||
| 349 | } | 352 | } |
| 350 | 353 | ||
| 351 | static int msm_open(struct drm_device *dev, struct drm_file *file) | 354 | static int msm_open(struct drm_device *dev, struct drm_file *file) |
| @@ -906,25 +909,22 @@ static int compare_of(struct device *dev, void *data) | |||
| 906 | return dev->of_node == data; | 909 | return dev->of_node == data; |
| 907 | } | 910 | } |
| 908 | 911 | ||
| 909 | static int msm_drm_add_components(struct device *master, struct master *m) | 912 | static int add_components(struct device *dev, struct component_match **matchptr, |
| 913 | const char *name) | ||
| 910 | { | 914 | { |
| 911 | struct device_node *np = master->of_node; | 915 | struct device_node *np = dev->of_node; |
| 912 | unsigned i; | 916 | unsigned i; |
| 913 | int ret; | ||
| 914 | 917 | ||
| 915 | for (i = 0; ; i++) { | 918 | for (i = 0; ; i++) { |
| 916 | struct device_node *node; | 919 | struct device_node *node; |
| 917 | 920 | ||
| 918 | node = of_parse_phandle(np, "connectors", i); | 921 | node = of_parse_phandle(np, name, i); |
| 919 | if (!node) | 922 | if (!node) |
| 920 | break; | 923 | break; |
| 921 | 924 | ||
| 922 | ret = component_master_add_child(m, compare_of, node); | 925 | component_match_add(dev, matchptr, compare_of, node); |
| 923 | of_node_put(node); | ||
| 924 | |||
| 925 | if (ret) | ||
| 926 | return ret; | ||
| 927 | } | 926 | } |
| 927 | |||
| 928 | return 0; | 928 | return 0; |
| 929 | } | 929 | } |
| 930 | #else | 930 | #else |
| @@ -932,9 +932,34 @@ static int compare_dev(struct device *dev, void *data) | |||
| 932 | { | 932 | { |
| 933 | return dev == data; | 933 | return dev == data; |
| 934 | } | 934 | } |
| 935 | #endif | ||
| 935 | 936 | ||
| 936 | static int msm_drm_add_components(struct device *master, struct master *m) | 937 | static int msm_drm_bind(struct device *dev) |
| 937 | { | 938 | { |
| 939 | return drm_platform_init(&msm_driver, to_platform_device(dev)); | ||
| 940 | } | ||
| 941 | |||
| 942 | static void msm_drm_unbind(struct device *dev) | ||
| 943 | { | ||
| 944 | drm_put_dev(platform_get_drvdata(to_platform_device(dev))); | ||
| 945 | } | ||
| 946 | |||
| 947 | static const struct component_master_ops msm_drm_ops = { | ||
| 948 | .bind = msm_drm_bind, | ||
| 949 | .unbind = msm_drm_unbind, | ||
| 950 | }; | ||
| 951 | |||
| 952 | /* | ||
| 953 | * Platform driver: | ||
| 954 | */ | ||
| 955 | |||
| 956 | static int msm_pdev_probe(struct platform_device *pdev) | ||
| 957 | { | ||
| 958 | struct component_match *match = NULL; | ||
| 959 | #ifdef CONFIG_OF | ||
| 960 | add_components(&pdev->dev, &match, "connectors"); | ||
| 961 | add_components(&pdev->dev, &match, "gpus"); | ||
| 962 | #else | ||
| 938 | /* For non-DT case, it kinda sucks. We don't actually have a way | 963 | /* For non-DT case, it kinda sucks. We don't actually have a way |
| 939 | * to know whether or not we are waiting for certain devices (or if | 964 | * to know whether or not we are waiting for certain devices (or if |
| 940 | * they are simply not present). But for non-DT we only need to | 965 | * they are simply not present). But for non-DT we only need to |
| @@ -949,50 +974,20 @@ static int msm_drm_add_components(struct device *master, struct master *m) | |||
| 949 | 974 | ||
| 950 | for (i = 0; i < ARRAY_SIZE(devnames); i++) { | 975 | for (i = 0; i < ARRAY_SIZE(devnames); i++) { |
| 951 | struct device *dev; | 976 | struct device *dev; |
| 952 | int ret; | ||
| 953 | 977 | ||
| 954 | dev = bus_find_device_by_name(&platform_bus_type, | 978 | dev = bus_find_device_by_name(&platform_bus_type, |
| 955 | NULL, devnames[i]); | 979 | NULL, devnames[i]); |
| 956 | if (!dev) { | 980 | if (!dev) { |
| 957 | dev_info(master, "still waiting for %s\n", devnames[i]); | 981 | dev_info(&pdev->dev, "still waiting for %s\n", devnames[i]); |
| 958 | return -EPROBE_DEFER; | 982 | return -EPROBE_DEFER; |
| 959 | } | 983 | } |
| 960 | 984 | ||
| 961 | ret = component_master_add_child(m, compare_dev, dev); | 985 | component_match_add(&pdev->dev, &match, compare_dev, dev); |
| 962 | if (ret) { | ||
| 963 | DBG("could not add child: %d", ret); | ||
| 964 | return ret; | ||
| 965 | } | ||
| 966 | } | 986 | } |
| 967 | |||
| 968 | return 0; | ||
| 969 | } | ||
| 970 | #endif | 987 | #endif |
| 971 | 988 | ||
| 972 | static int msm_drm_bind(struct device *dev) | ||
| 973 | { | ||
| 974 | return drm_platform_init(&msm_driver, to_platform_device(dev)); | ||
| 975 | } | ||
| 976 | |||
| 977 | static void msm_drm_unbind(struct device *dev) | ||
| 978 | { | ||
| 979 | drm_put_dev(platform_get_drvdata(to_platform_device(dev))); | ||
| 980 | } | ||
| 981 | |||
| 982 | static const struct component_master_ops msm_drm_ops = { | ||
| 983 | .add_components = msm_drm_add_components, | ||
| 984 | .bind = msm_drm_bind, | ||
| 985 | .unbind = msm_drm_unbind, | ||
| 986 | }; | ||
| 987 | |||
| 988 | /* | ||
| 989 | * Platform driver: | ||
| 990 | */ | ||
| 991 | |||
| 992 | static int msm_pdev_probe(struct platform_device *pdev) | ||
| 993 | { | ||
| 994 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 989 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
| 995 | return component_master_add(&pdev->dev, &msm_drm_ops); | 990 | return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match); |
| 996 | } | 991 | } |
| 997 | 992 | ||
| 998 | static int msm_pdev_remove(struct platform_device *pdev) | 993 | static int msm_pdev_remove(struct platform_device *pdev) |
| @@ -1008,7 +1003,8 @@ static const struct platform_device_id msm_id[] = { | |||
| 1008 | }; | 1003 | }; |
| 1009 | 1004 | ||
| 1010 | static const struct of_device_id dt_match[] = { | 1005 | static const struct of_device_id dt_match[] = { |
| 1011 | { .compatible = "qcom,mdss_mdp" }, | 1006 | { .compatible = "qcom,mdp" }, /* mdp4 */ |
| 1007 | { .compatible = "qcom,mdss_mdp" }, /* mdp5 */ | ||
| 1012 | {} | 1008 | {} |
| 1013 | }; | 1009 | }; |
| 1014 | MODULE_DEVICE_TABLE(of, dt_match); | 1010 | MODULE_DEVICE_TABLE(of, dt_match); |
