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

drm/armada: permit CRTCs to be registered as separate devices

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

+122 -14
+104 -9
drivers/gpu/drm/armada/armada_crtc.c
··· 7 7 * published by the Free Software Foundation. 8 8 */ 9 9 #include <linux/clk.h> 10 + #include <linux/component.h> 11 + #include <linux/of_device.h> 12 + #include <linux/platform_device.h> 10 13 #include <drm/drmP.h> 11 14 #include <drm/drm_crtc_helper.h> 12 15 #include "armada_crtc.h" ··· 1049 1046 return 0; 1050 1047 } 1051 1048 1052 - int armada_drm_crtc_create(struct drm_device *dev, struct resource *res, 1053 - int irq, const struct armada_variant *variant) 1049 + int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, 1050 + struct resource *res, int irq, const struct armada_variant *variant) 1054 1051 { 1055 - struct armada_private *priv = dev->dev_private; 1052 + struct armada_private *priv = drm->dev_private; 1056 1053 struct armada_crtc *dcrtc; 1057 1054 void __iomem *base; 1058 1055 int ret; 1059 1056 1060 - ret = armada_drm_crtc_create_properties(dev); 1057 + ret = armada_drm_crtc_create_properties(drm); 1061 1058 if (ret) 1062 1059 return ret; 1063 1060 1064 - base = devm_request_and_ioremap(dev->dev, res); 1061 + base = devm_request_and_ioremap(dev, res); 1065 1062 if (!base) { 1066 1063 DRM_ERROR("failed to ioremap register\n"); 1067 1064 return -ENOMEM; ··· 1073 1070 return -ENOMEM; 1074 1071 } 1075 1072 1073 + if (dev != drm->dev) 1074 + dev_set_drvdata(dev, dcrtc); 1075 + 1076 1076 dcrtc->variant = variant; 1077 1077 dcrtc->base = base; 1078 - dcrtc->num = dev->mode_config.num_crtc; 1078 + dcrtc->num = drm->mode_config.num_crtc; 1079 1079 dcrtc->clk = ERR_PTR(-EINVAL); 1080 1080 dcrtc->csc_yuv_mode = CSC_AUTO; 1081 1081 dcrtc->csc_rgb_mode = CSC_AUTO; ··· 1111 1105 } 1112 1106 1113 1107 if (dcrtc->variant->init) { 1114 - ret = dcrtc->variant->init(dcrtc, dev->dev); 1108 + ret = dcrtc->variant->init(dcrtc, dev); 1115 1109 if (ret) { 1116 1110 kfree(dcrtc); 1117 1111 return ret; ··· 1123 1117 1124 1118 priv->dcrtc[dcrtc->num] = dcrtc; 1125 1119 1126 - drm_crtc_init(dev, &dcrtc->crtc, &armada_crtc_funcs); 1120 + drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs); 1127 1121 drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs); 1128 1122 1129 1123 drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop, ··· 1131 1125 drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop, 1132 1126 dcrtc->csc_rgb_mode); 1133 1127 1134 - return armada_overlay_plane_create(dev, 1 << dcrtc->num); 1128 + return armada_overlay_plane_create(drm, 1 << dcrtc->num); 1135 1129 } 1130 + 1131 + static int 1132 + armada_lcd_bind(struct device *dev, struct device *master, void *data) 1133 + { 1134 + struct platform_device *pdev = to_platform_device(dev); 1135 + struct drm_device *drm = data; 1136 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1137 + int irq = platform_get_irq(pdev, 0); 1138 + const struct armada_variant *variant; 1139 + 1140 + if (irq < 0) 1141 + return irq; 1142 + 1143 + if (!dev->of_node) { 1144 + const struct platform_device_id *id; 1145 + 1146 + id = platform_get_device_id(pdev); 1147 + if (!id) 1148 + return -ENXIO; 1149 + 1150 + variant = (const struct armada_variant *)id->driver_data; 1151 + } else { 1152 + const struct of_device_id *match; 1153 + 1154 + match = of_match_device(dev->driver->of_match_table, dev); 1155 + if (!match) 1156 + return -ENXIO; 1157 + 1158 + variant = match->data; 1159 + } 1160 + 1161 + return armada_drm_crtc_create(drm, dev, res, irq, variant); 1162 + } 1163 + 1164 + static void 1165 + armada_lcd_unbind(struct device *dev, struct device *master, void *data) 1166 + { 1167 + struct armada_crtc *dcrtc = dev_get_drvdata(dev); 1168 + 1169 + armada_drm_crtc_destroy(&dcrtc->crtc); 1170 + } 1171 + 1172 + static const struct component_ops armada_lcd_ops = { 1173 + .bind = armada_lcd_bind, 1174 + .unbind = armada_lcd_unbind, 1175 + }; 1176 + 1177 + static int armada_lcd_probe(struct platform_device *pdev) 1178 + { 1179 + return component_add(&pdev->dev, &armada_lcd_ops); 1180 + } 1181 + 1182 + static int armada_lcd_remove(struct platform_device *pdev) 1183 + { 1184 + component_del(&pdev->dev, &armada_lcd_ops); 1185 + return 0; 1186 + } 1187 + 1188 + static struct of_device_id armada_lcd_of_match[] = { 1189 + { 1190 + .compatible = "marvell,dove-lcd", 1191 + .data = &armada510_ops, 1192 + }, 1193 + {} 1194 + }; 1195 + MODULE_DEVICE_TABLE(of, armada_lcd_of_match); 1196 + 1197 + static const struct platform_device_id armada_lcd_platform_ids[] = { 1198 + { 1199 + .name = "armada-lcd", 1200 + .driver_data = (unsigned long)&armada510_ops, 1201 + }, { 1202 + .name = "armada-510-lcd", 1203 + .driver_data = (unsigned long)&armada510_ops, 1204 + }, 1205 + { }, 1206 + }; 1207 + MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids); 1208 + 1209 + struct platform_driver armada_lcd_platform_driver = { 1210 + .probe = armada_lcd_probe, 1211 + .remove = armada_lcd_remove, 1212 + .driver = { 1213 + .name = "armada-lcd", 1214 + .owner = THIS_MODULE, 1215 + .of_match_table = armada_lcd_of_match, 1216 + }, 1217 + .id_table = armada_lcd_platform_ids, 1218 + };
+4 -2
drivers/gpu/drm/armada/armada_crtc.h
··· 75 75 }; 76 76 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc) 77 77 78 - int armada_drm_crtc_create(struct drm_device *, struct resource *, int, 79 - const struct armada_variant *); 78 + int armada_drm_crtc_create(struct drm_device *, struct device *, 79 + struct resource *, int, const struct armada_variant *); 80 80 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int); 81 81 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int); 82 82 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32); 83 83 void armada_drm_crtc_enable_irq(struct armada_crtc *, u32); 84 84 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *); 85 + 86 + extern struct platform_driver armada_lcd_platform_driver; 85 87 86 88 #endif
+14 -3
drivers/gpu/drm/armada/armada_drv.c
··· 115 115 return -EINVAL; 116 116 } 117 117 118 - if (!res[0] || !mem) 118 + if (!mem) 119 119 return -ENXIO; 120 120 121 121 if (!devm_request_mem_region(dev->dev, mem->start, ··· 168 168 if (irq < 0) 169 169 goto err_kms; 170 170 171 - ret = armada_drm_crtc_create(dev, res[n], irq, variant); 171 + ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq, 172 + variant); 172 173 if (ret) 173 174 goto err_kms; 174 175 } ··· 491 490 492 491 static int __init armada_drm_init(void) 493 492 { 493 + int ret; 494 + 494 495 armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls); 495 - return platform_driver_register(&armada_drm_platform_driver); 496 + 497 + ret = platform_driver_register(&armada_lcd_platform_driver); 498 + if (ret) 499 + return ret; 500 + ret = platform_driver_register(&armada_drm_platform_driver); 501 + if (ret) 502 + platform_driver_unregister(&armada_lcd_platform_driver); 503 + return ret; 496 504 } 497 505 module_init(armada_drm_init); 498 506 499 507 static void __exit armada_drm_exit(void) 500 508 { 501 509 platform_driver_unregister(&armada_drm_platform_driver); 510 + platform_driver_unregister(&armada_lcd_platform_driver); 502 511 } 503 512 module_exit(armada_drm_exit); 504 513