From patchwork Wed Mar 22 18:15:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 742262 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vpHsl6QMCz9ryr for ; Thu, 23 Mar 2017 05:15:23 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="P/gwYjec"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935279AbdCVSPX (ORCPT ); Wed, 22 Mar 2017 14:15:23 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:33140 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934813AbdCVSPW (ORCPT ); Wed, 22 Mar 2017 14:15:22 -0400 Received: by mail-wm0-f66.google.com with SMTP id n11so11975354wma.0 for ; Wed, 22 Mar 2017 11:15:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=H6yj8CSR6W3mx/1WFHdks1547XPhMOb71LsDcGkxp4w=; b=P/gwYjecxhphZ0TWOFvECEtIw0MhFK9FxaXdjpr23TdVGF8zi6tcTncOpwba/uTquT mBzZk/CFA5ayDl6w04N6gHcPomEU0iUqm9VVLaMjX4Xgb3V0vH/1FyIaFyoWuY90qYEX IVX+TBC5nYVI6zlijPMglx/JFHHdKc0rx6znIYAseI1M0wOoOf3S6tgFyjepFoW2low2 gYTqQA0GXN9Q/L5Op16qKxpvGkOd8rwyFmy/NY5P5G0EwM/4jjVrtqaiIlJ3b/AJA3Zu /AGe7dkOlGM4tDnhaDcOjoi491JZkfxstSV+XJEijpi4JDGwkxOmFipxANzgNlgKJUjL A7Ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=H6yj8CSR6W3mx/1WFHdks1547XPhMOb71LsDcGkxp4w=; b=JpaMPmVugtRfR2jzWPNtRc24r2kKKeHF3c90XdlCVvdCEtbyWaboPO/+B3kbw+M6L/ cEIXXzv7uM7DMekK71Oog+/9h3meSbVnqko2nAzoXQ8bfRBTSedv2ZS4JJJKhgJkbPXr 9q9RYJdkCSjw86GYn3HIPnGoaIt5ZkeVUBjbXbFhd+NBI6M8ZaEnS+6y3pHqTc4j9CSg KD/1MvipESiWdUCPsCPOrgU0HkZnFYaC4cyimbOhW1BrXR7H/0mwJFDvXr6WDs1LXHgw d6n+IYUWSYo7+RyhEeoObZE/7BVsvp3L8IN1jVJxzl11o+rrqehsHg8/2MxwVsVsnKMb PcNA== X-Gm-Message-State: AFeK/H05qzi7mSv8owQLJVdvU6qixLjOHF8XjnG1J/MD12vKnSK3xegXJ3poCPFgMp6W7g== X-Received: by 10.28.146.12 with SMTP id u12mr9656320wmd.142.1490206520417; Wed, 22 Mar 2017 11:15:20 -0700 (PDT) Received: from localhost (port-56532.pppoe.wtnet.de. [46.59.221.138]) by smtp.gmail.com with ESMTPSA id 60sm2706484wrg.60.2017.03.22.11.15.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 22 Mar 2017 11:15:19 -0700 (PDT) From: Thierry Reding To: Thierry Reding Cc: dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org Subject: [PATCH] gpu: host1x: Fix host1x driver shutdown Date: Wed, 22 Mar 2017 19:15:18 +0100 Message-Id: <20170322181518.17880-1-thierry.reding@gmail.com> X-Mailer: git-send-email 2.12.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org From: Thierry Reding Shutting down a host1x device currently crashes if the device has failed to probe. The root cause is that the host1x shutdown is implemented as a struct bus_type callback, but in turn relies on the driver bound to the device. On failure to probe, no driver will be bound and cause the code to crash. Fix this by moving the ->probe(), ->remove() and ->shutdown() callbacks to the driver rather than the bus. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/bus.c | 68 ++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 0438f98d0e3b..0c7ed03c235b 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -291,37 +291,6 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv) return strcmp(dev_name(dev), drv->name) == 0; } -static int host1x_device_probe(struct device *dev) -{ - struct host1x_driver *driver = to_host1x_driver(dev->driver); - struct host1x_device *device = to_host1x_device(dev); - - if (driver->probe) - return driver->probe(device); - - return 0; -} - -static int host1x_device_remove(struct device *dev) -{ - struct host1x_driver *driver = to_host1x_driver(dev->driver); - struct host1x_device *device = to_host1x_device(dev); - - if (driver->remove) - return driver->remove(device); - - return 0; -} - -static void host1x_device_shutdown(struct device *dev) -{ - struct host1x_driver *driver = to_host1x_driver(dev->driver); - struct host1x_device *device = to_host1x_device(dev); - - if (driver->shutdown) - driver->shutdown(device); -} - static const struct dev_pm_ops host1x_device_pm_ops = { .suspend = pm_generic_suspend, .resume = pm_generic_resume, @@ -334,9 +303,6 @@ static const struct dev_pm_ops host1x_device_pm_ops = { struct bus_type host1x_bus_type = { .name = "host1x", .match = host1x_device_match, - .probe = host1x_device_probe, - .remove = host1x_device_remove, - .shutdown = host1x_device_shutdown, .pm = &host1x_device_pm_ops, }; @@ -540,6 +506,37 @@ int host1x_unregister(struct host1x *host1x) return 0; } +static int host1x_device_probe(struct device *dev) +{ + struct host1x_driver *driver = to_host1x_driver(dev->driver); + struct host1x_device *device = to_host1x_device(dev); + + if (driver->probe) + return driver->probe(device); + + return 0; +} + +static int host1x_device_remove(struct device *dev) +{ + struct host1x_driver *driver = to_host1x_driver(dev->driver); + struct host1x_device *device = to_host1x_device(dev); + + if (driver->remove) + return driver->remove(device); + + return 0; +} + +static void host1x_device_shutdown(struct device *dev) +{ + struct host1x_driver *driver = to_host1x_driver(dev->driver); + struct host1x_device *device = to_host1x_device(dev); + + if (driver->shutdown) + driver->shutdown(device); +} + int host1x_driver_register_full(struct host1x_driver *driver, struct module *owner) { @@ -560,6 +557,9 @@ int host1x_driver_register_full(struct host1x_driver *driver, driver->driver.bus = &host1x_bus_type; driver->driver.owner = owner; + driver->driver.probe = host1x_device_probe; + driver->driver.remove = host1x_device_remove; + driver->driver.shutdown = host1x_device_shutdown; return driver_register(&driver->driver); }