drm/tegra: Changes for v5.3-rc1 This contains a couple of small improvements and cleanups for the Tegra DRM driver. Signed-off-by: Dave Airlie <airlied@redhat.com>
Unified · Split
| @@ -485,11 +485,16 @@ static int tegra_dpaux_probe(struct platform_device *pdev) · 484 unmodified lines | ||
| 485 | 485 | return err; |
| 486 | 486 | } |
| 487 | 487 | |
| 488 | − dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd"); | |
| 488 | + dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); | |
| 489 | 489 | if (IS_ERR(dpaux->vdd)) { |
| 490 | − dev_err(&pdev->dev, "failed to get VDD supply: %ld\n", | |
| 491 | − PTR_ERR(dpaux->vdd)); | |
| 492 | − return PTR_ERR(dpaux->vdd); | |
| 490 | + if (PTR_ERR(dpaux->vdd) != -ENODEV) { | |
| 491 | + if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER) | |
| 492 | + dev_err(&pdev->dev, | |
| 493 | + "failed to get VDD supply: %ld\n", | |
| 494 | + PTR_ERR(dpaux->vdd)); | |
| 495 | + | |
| 496 | + return PTR_ERR(dpaux->vdd); | |
| 497 | + } | |
| 493 | 498 | } |
| 494 | 499 | |
| 495 | 500 | platform_set_drvdata(pdev, dpaux); |
| @@ -127,8 +127,7 @@ struct tegra_output { · 126 unmodified lines | ||
| 127 | 127 | const struct edid *edid; |
| 128 | 128 | struct cec_notifier *cec; |
| 129 | 129 | unsigned int hpd_irq; |
| 130 | − int hpd_gpio; | |
| 131 | − enum of_gpio_flags hpd_gpio_flags; | |
| 130 | + struct gpio_desc *hpd_gpio; | |
| 132 | 131 | |
| 133 | 132 | struct drm_encoder encoder; |
| 134 | 133 | struct drm_connector connector; |
| @@ -53,18 +53,11 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force) · 52 unmodified lines | ||
| 53 | 53 | struct tegra_output *output = connector_to_output(connector); |
| 54 | 54 | enum drm_connector_status status = connector_status_unknown; |
| 55 | 55 | |
| 56 | − if (gpio_is_valid(output->hpd_gpio)) { | |
| 57 | − if (output->hpd_gpio_flags & OF_GPIO_ACTIVE_LOW) { | |
| 58 | − if (gpio_get_value(output->hpd_gpio) != 0) | |
| 59 | − status = connector_status_disconnected; | |
| 60 | − else | |
| 61 | − status = connector_status_connected; | |
| 62 | − } else { | |
| 63 | − if (gpio_get_value(output->hpd_gpio) == 0) | |
| 64 | − status = connector_status_disconnected; | |
| 65 | − else | |
| 66 | − status = connector_status_connected; | |
| 67 | − } | |
| 56 | + if (output->hpd_gpio) { | |
| 57 | + if (gpiod_get_value(output->hpd_gpio) == 0) | |
| 58 | + status = connector_status_disconnected; | |
| 59 | + else | |
| 60 | + status = connector_status_connected; | |
| 68 | 61 | } else { |
| 69 | 62 | if (!output->panel) |
| 70 | 63 | status = connector_status_disconnected; |
| @@ -102,6 +95,7 @@ static irqreturn_t hpd_irq(int irq, void *data) · 31 unmodified lines | ||
| 102 | 95 | int tegra_output_probe(struct tegra_output *output) |
| 103 | 96 | { |
| 104 | 97 | struct device_node *ddc, *panel; |
| 98 | + unsigned long flags; | |
| 105 | 99 | int err, size; |
| 106 | 100 | |
| 107 | 101 | if (!output->of_node) |
| @@ -130,23 +124,18 @@ int tegra_output_probe(struct tegra_output *output) · 22 unmodified lines | ||
| 130 | 124 | of_node_put(ddc); |
| 131 | 125 | } |
| 132 | 126 | |
| 133 | − output->hpd_gpio = of_get_named_gpio_flags(output->of_node, | |
| 134 | − "nvidia,hpd-gpio", 0, | |
| 135 | − &output->hpd_gpio_flags); | |
| 136 | − if (gpio_is_valid(output->hpd_gpio)) { | |
| 137 | − unsigned long flags; | |
| 127 | + output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev, | |
| 128 | + output->of_node, | |
| 129 | + "nvidia,hpd-gpio", 0, | |
| 130 | + GPIOD_IN, | |
| 131 | + "HDMI hotplug detect"); | |
| 132 | + if (IS_ERR(output->hpd_gpio)) | |
| 133 | + return PTR_ERR(output->hpd_gpio); | |
| 138 | 134 | |
| 139 | − err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN, | |
| 140 | − "HDMI hotplug detect"); | |
| 135 | + if (output->hpd_gpio) { | |
| 136 | + err = gpiod_to_irq(output->hpd_gpio); | |
| 141 | 137 | if (err < 0) { |
| 142 | − dev_err(output->dev, "gpio_request_one(): %d\n", err); | |
| 143 | − return err; | |
| 144 | − } | |
| 145 | − | |
| 146 | − err = gpio_to_irq(output->hpd_gpio); | |
| 147 | − if (err < 0) { | |
| 148 | − dev_err(output->dev, "gpio_to_irq(): %d\n", err); | |
| 149 | − gpio_free(output->hpd_gpio); | |
| 138 | + dev_err(output->dev, "gpiod_to_irq(): %d\n", err); | |
| 150 | 139 | return err; |
| 151 | 140 | } |
| 152 | 141 | |
| @@ -160,7 +149,6 @@ int tegra_output_probe(struct tegra_output *output) · 7 unmodified lines | ||
| 160 | 149 | if (err < 0) { |
| 161 | 150 | dev_err(output->dev, "failed to request IRQ#%u: %d\n", |
| 162 | 151 | output->hpd_irq, err); |
| 163 | − gpio_free(output->hpd_gpio); | |
| 164 | 152 | return err; |
| 165 | 153 | } |
| 166 | 154 | |
| @@ -186,10 +174,8 @@ void tegra_output_remove(struct tegra_output *output) · 19 unmodified lines | ||
| 186 | 174 | if (output->cec) |
| 187 | 175 | cec_notifier_put(output->cec); |
| 188 | 176 | |
| 189 | − if (gpio_is_valid(output->hpd_gpio)) { | |
| 177 | + if (output->hpd_gpio) | |
| 190 | 178 | free_irq(output->hpd_irq, output); |
| 191 | − gpio_free(output->hpd_gpio); | |
| 192 | − } | |
| 193 | 179 | |
| 194 | 180 | if (output->ddc) |
| 195 | 181 | put_device(&output->ddc->dev); |
| @@ -209,7 +195,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) · 13 unmodified lines | ||
| 209 | 195 | * The connector is now registered and ready to receive hotplug events |
| 210 | 196 | * so the hotplug interrupt can be enabled. |
| 211 | 197 | */ |
| 212 | − if (gpio_is_valid(output->hpd_gpio)) | |
| 198 | + if (output->hpd_gpio) | |
| 213 | 199 | enable_irq(output->hpd_irq); |
| 214 | 200 | |
| 215 | 201 | return 0; |
| @@ -221,7 +207,7 @@ void tegra_output_exit(struct tegra_output *output) · 5 unmodified lines | ||
| 221 | 207 | * The connector is going away, so the interrupt must be disabled to |
| 222 | 208 | * prevent the hotplug interrupt handler from potentially crashing. |
| 223 | 209 | */ |
| 224 | − if (gpio_is_valid(output->hpd_gpio)) | |
| 210 | + if (output->hpd_gpio) | |
| 225 | 211 | disable_irq(output->hpd_irq); |
| 226 | 212 | |
| 227 | 213 | if (output->panel) |
| @@ -305,6 +305,36 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv) · 304 unmodified lines | ||
| 305 | 305 | return strcmp(dev_name(dev), drv->name) == 0; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | +static int host1x_device_uevent(struct device *dev, | |
| 309 | + struct kobj_uevent_env *env) | |
| 310 | +{ | |
| 311 | + struct device_node *np = dev->parent->of_node; | |
| 312 | + unsigned int count = 0; | |
| 313 | + struct property *p; | |
| 314 | + const char *compat; | |
| 315 | + | |
| 316 | + /* | |
| 317 | + * This duplicates most of of_device_uevent(), but the latter cannot | |
| 318 | + * be called from modules and operates on dev->of_node, which is not | |
| 319 | + * available in this case. | |
| 320 | + * | |
| 321 | + * Note that this is really only needed for backwards compatibility | |
| 322 | + * with libdrm, which parses this information from sysfs and will | |
| 323 | + * fail if it can't find the OF_FULLNAME, specifically. | |
| 324 | + */ | |
| 325 | + add_uevent_var(env, "OF_NAME=%pOFn", np); | |
| 326 | + add_uevent_var(env, "OF_FULLNAME=%pOF", np); | |
| 327 | + | |
| 328 | + of_property_for_each_string(np, "compatible", p, compat) { | |
| 329 | + add_uevent_var(env, "OF_COMPATIBLE_%u=%s", count, compat); | |
| 330 | + count++; | |
| 331 | + } | |
| 332 | + | |
| 333 | + add_uevent_var(env, "OF_COMPATIBLE_N=%u", count); | |
| 334 | + | |
| 335 | + return 0; | |
| 336 | +} | |
| 337 | + | |
| 308 | 338 | static int host1x_dma_configure(struct device *dev) |
| 309 | 339 | { |
| 310 | 340 | return of_dma_configure(dev, dev->of_node, true); |
| @@ -322,6 +352,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = { · 11 unmodified lines | ||
| 322 | 352 | struct bus_type host1x_bus_type = { |
| 323 | 353 | .name = "host1x", |
| 324 | 354 | .match = host1x_device_match, |
| 355 | + .uevent = host1x_device_uevent, | |
| 325 | 356 | .dma_configure = host1x_dma_configure, |
| 326 | 357 | .pm = &host1x_device_pm_ops, |
| 327 | 358 | }; |
| @@ -408,12 +439,14 @@ static int host1x_device_add(struct host1x *host1x, · 80 unmodified lines | ||
| 408 | 439 | device->dev.dma_mask = &device->dev.coherent_dma_mask; |
| 409 | 440 | dev_set_name(&device->dev, "%s", driver->driver.name); |
| 410 | 441 | device->dev.release = host1x_device_release; |
| 411 | − device->dev.of_node = host1x->dev->of_node; | |
| 412 | 442 | device->dev.bus = &host1x_bus_type; |
| 413 | 443 | device->dev.parent = host1x->dev; |
| 414 | 444 | |
| 415 | 445 | of_dma_configure(&device->dev, host1x->dev->of_node, true); |
| 416 | 446 | |
| 447 | + device->dev.dma_parms = &device->dma_parms; | |
| 448 | + dma_set_max_seg_size(&device->dev, SZ_4M); | |
| 449 | + | |
| 417 | 450 | err = host1x_device_parse_dt(device, driver); |
| 418 | 451 | if (err < 0) { |
| 419 | 452 | kfree(device); |
| @@ -162,9 +162,6 @@ static void host1x_debugfs_init(struct host1x *host1x) · 161 unmodified lines | ||
| 162 | 162 | { |
| 163 | 163 | struct dentry *de = debugfs_create_dir("tegra-host1x", NULL); |
| 164 | 164 | |
| 165 | − if (!de) | |
| 166 | − return; | |
| 167 | − | |
| 168 | 165 | /* Store the created entry */ |
| 169 | 166 | host1x->debugfs = de; |
| 170 | 167 | |
| @@ -247,8 +247,11 @@ static int host1x_probe(struct platform_device *pdev) · 246 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | host->clk = devm_clk_get(&pdev->dev, NULL); |
| 249 | 249 | if (IS_ERR(host->clk)) { |
| 250 | − dev_err(&pdev->dev, "failed to get clock\n"); | |
| 251 | 250 | err = PTR_ERR(host->clk); |
| 251 | + | |
| 252 | + if (err != -EPROBE_DEFER) | |
| 253 | + dev_err(&pdev->dev, "failed to get clock: %d\n", err); | |
| 254 | + | |
| 252 | 255 | return err; |
| 253 | 256 | } |
| 254 | 257 | |
| @@ -297,6 +297,8 @@ struct host1x_device { · 296 unmodified lines | ||
| 297 | 297 | struct list_head clients; |
| 298 | 298 | |
| 299 | 299 | bool registered; |
| 300 | + | |
| 301 | + struct device_dma_parameters dma_parms; | |
| 300 | 302 | }; |
| 301 | 303 | |
| 302 | 304 | static inline struct host1x_device *to_host1x_device(struct device *dev) |