return err;
}
- dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd");
+ dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
if (IS_ERR(dpaux->vdd)) {
- dev_err(&pdev->dev, "failed to get VDD supply: %ld\n",
- PTR_ERR(dpaux->vdd));
- return PTR_ERR(dpaux->vdd);
+ if (PTR_ERR(dpaux->vdd) != -ENODEV) {
+ if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to get VDD supply: %ld\n",
+ PTR_ERR(dpaux->vdd));
+
+ return PTR_ERR(dpaux->vdd);
+ }
}
platform_set_drvdata(pdev, dpaux);
const struct edid *edid;
struct cec_notifier *cec;
unsigned int hpd_irq;
- int hpd_gpio;
- enum of_gpio_flags hpd_gpio_flags;
+ struct gpio_desc *hpd_gpio;
struct drm_encoder encoder;
struct drm_connector connector;
struct tegra_output *output = connector_to_output(connector);
enum drm_connector_status status = connector_status_unknown;
- if (gpio_is_valid(output->hpd_gpio)) {
- if (output->hpd_gpio_flags & OF_GPIO_ACTIVE_LOW) {
- if (gpio_get_value(output->hpd_gpio) != 0)
- status = connector_status_disconnected;
- else
- status = connector_status_connected;
- } else {
- if (gpio_get_value(output->hpd_gpio) == 0)
- status = connector_status_disconnected;
- else
- status = connector_status_connected;
- }
+ if (output->hpd_gpio) {
+ if (gpiod_get_value(output->hpd_gpio) == 0)
+ status = connector_status_disconnected;
+ else
+ status = connector_status_connected;
} else {
if (!output->panel)
status = connector_status_disconnected;
int tegra_output_probe(struct tegra_output *output)
{
struct device_node *ddc, *panel;
+ unsigned long flags;
int err, size;
if (!output->of_node)
of_node_put(ddc);
}
- output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
- "nvidia,hpd-gpio", 0,
- &output->hpd_gpio_flags);
- if (gpio_is_valid(output->hpd_gpio)) {
- unsigned long flags;
+ output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev,
+ output->of_node,
+ "nvidia,hpd-gpio", 0,
+ GPIOD_IN,
+ "HDMI hotplug detect");
+ if (IS_ERR(output->hpd_gpio))
+ return PTR_ERR(output->hpd_gpio);
- err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN,
- "HDMI hotplug detect");
+ if (output->hpd_gpio) {
+ err = gpiod_to_irq(output->hpd_gpio);
if (err < 0) {
- dev_err(output->dev, "gpio_request_one(): %d\n", err);
- return err;
- }
-
- err = gpio_to_irq(output->hpd_gpio);
- if (err < 0) {
- dev_err(output->dev, "gpio_to_irq(): %d\n", err);
- gpio_free(output->hpd_gpio);
+ dev_err(output->dev, "gpiod_to_irq(): %d\n", err);
return err;
}
if (err < 0) {
dev_err(output->dev, "failed to request IRQ#%u: %d\n",
output->hpd_irq, err);
- gpio_free(output->hpd_gpio);
return err;
}
if (output->cec)
cec_notifier_put(output->cec);
- if (gpio_is_valid(output->hpd_gpio)) {
+ if (output->hpd_gpio)
free_irq(output->hpd_irq, output);
- gpio_free(output->hpd_gpio);
- }
if (output->ddc)
put_device(&output->ddc->dev);
* The connector is now registered and ready to receive hotplug events
* so the hotplug interrupt can be enabled.
*/
- if (gpio_is_valid(output->hpd_gpio))
+ if (output->hpd_gpio)
enable_irq(output->hpd_irq);
return 0;
* The connector is going away, so the interrupt must be disabled to
* prevent the hotplug interrupt handler from potentially crashing.
*/
- if (gpio_is_valid(output->hpd_gpio))
+ if (output->hpd_gpio)
disable_irq(output->hpd_irq);
if (output->panel)
return strcmp(dev_name(dev), drv->name) == 0;
}
+static int host1x_device_uevent(struct device *dev,
+ struct kobj_uevent_env *env)
+{
+ struct device_node *np = dev->parent->of_node;
+ unsigned int count = 0;
+ struct property *p;
+ const char *compat;
+
+ /*
+ * This duplicates most of of_device_uevent(), but the latter cannot
+ * be called from modules and operates on dev->of_node, which is not
+ * available in this case.
+ *
+ * Note that this is really only needed for backwards compatibility
+ * with libdrm, which parses this information from sysfs and will
+ * fail if it can't find the OF_FULLNAME, specifically.
+ */
+ add_uevent_var(env, "OF_NAME=%pOFn", np);
+ add_uevent_var(env, "OF_FULLNAME=%pOF", np);
+
+ of_property_for_each_string(np, "compatible", p, compat) {
+ add_uevent_var(env, "OF_COMPATIBLE_%u=%s", count, compat);
+ count++;
+ }
+
+ add_uevent_var(env, "OF_COMPATIBLE_N=%u", count);
+
+ return 0;
+}
+
static int host1x_dma_configure(struct device *dev)
{
return of_dma_configure(dev, dev->of_node, true);
struct bus_type host1x_bus_type = {
.name = "host1x",
.match = host1x_device_match,
+ .uevent = host1x_device_uevent,
.dma_configure = host1x_dma_configure,
.pm = &host1x_device_pm_ops,
};
device->dev.dma_mask = &device->dev.coherent_dma_mask;
dev_set_name(&device->dev, "%s", driver->driver.name);
device->dev.release = host1x_device_release;
- device->dev.of_node = host1x->dev->of_node;
device->dev.bus = &host1x_bus_type;
device->dev.parent = host1x->dev;
of_dma_configure(&device->dev, host1x->dev->of_node, true);
+ device->dev.dma_parms = &device->dma_parms;
+ dma_set_max_seg_size(&device->dev, SZ_4M);
+
err = host1x_device_parse_dt(device, driver);
if (err < 0) {
kfree(device);
{
struct dentry *de = debugfs_create_dir("tegra-host1x", NULL);
- if (!de)
- return;
-
/* Store the created entry */
host1x->debugfs = de;
host->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) {
- dev_err(&pdev->dev, "failed to get clock\n");
err = PTR_ERR(host->clk);
+
+ if (err != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "failed to get clock: %d\n", err);
+
return err;
}
struct list_head clients;
bool registered;
+
+ struct device_dma_parameters dma_parms;
};
static inline struct host1x_device *to_host1x_device(struct device *dev)