From: Thomas Zimmermann <tzimmermann@suse.de>
To: maarten.lankhorst@linux.intel.com, mripard@kernel.org,
airlied@linux.ie, daniel@ffwll.ch, kraxel@redhat.com,
lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org,
sam@ravnborg.org, emil.l.velikov@gmail.com, noralf@tronnes.org,
geert+renesas@glider.be, hdegoede@redhat.com
Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org
Subject: [PATCH 7/9] drm/simplekms: Acquire regulators from DT device node
Date: Thu, 25 Jun 2020 14:00:09 +0200 [thread overview]
Message-ID: <20200625120011.16168-8-tzimmermann@suse.de> (raw)
In-Reply-To: <20200625120011.16168-1-tzimmermann@suse.de>
Make sure required hardware regulators are enabled while the firmware
framebuffer is in use.
The basic code has been taken from the simplefb driver and adapted
to DRM. Regulators are released automatically via devres helpers.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simplekms.c | 128 +++++++++++++++++++++++++++++++
1 file changed, 128 insertions(+)
diff --git a/drivers/gpu/drm/tiny/simplekms.c b/drivers/gpu/drm/tiny/simplekms.c
index aca186decb48..ae5d3cbadbe8 100644
--- a/drivers/gpu/drm/tiny/simplekms.c
+++ b/drivers/gpu/drm/tiny/simplekms.c
@@ -4,6 +4,7 @@
#include <linux/of_clk.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_connector.h>
@@ -198,6 +199,11 @@ struct simplekms_device {
unsigned int clk_count;
struct clk **clks;
#endif
+ /* regulators */
+#if defined CONFIG_OF && defined CONFIG_REGULATOR
+ unsigned int regulator_count;
+ struct regulator **regulators;
+#endif
/* simplefb settings */
struct drm_display_mode mode;
@@ -315,6 +321,125 @@ static int simplekms_device_init_clocks(struct simplekms_device *sdev)
}
#endif
+#if defined CONFIG_OF && defined CONFIG_REGULATOR
+
+#define SUPPLY_SUFFIX "-supply"
+
+/*
+ * Regulator handling code.
+ *
+ * Here we handle the num-supplies and vin*-supply properties of our
+ * "simple-framebuffer" dt node. This is necessary so that we can make sure
+ * that any regulators needed by the display hardware that the bootloader
+ * set up for us (and for which it provided a simplefb dt node), stay up,
+ * for the life of the simplefb driver.
+ *
+ * When the driver unloads, we cleanly disable, and then release the
+ * regulators.
+ *
+ * We only complain about errors here, no action is taken as the most likely
+ * error can only happen due to a mismatch between the bootloader which set
+ * up simplefb, and the regulator definitions in the device tree. Chances are
+ * that there are no adverse effects, and if there are, a clean teardown of
+ * the fb probe will not help us much either. So just complain and carry on,
+ * and hope that the user actually gets a working fb at the end of things.
+ */
+
+static void simplekms_device_release_regulators(void *res)
+{
+ struct simplekms_device *sdev = simplekms_device_of_dev(res);
+ unsigned int i;
+
+ for (i = 0; i < sdev->regulator_count; ++i) {
+ if (sdev->regulators[i]) {
+ regulator_disable(sdev->regulators[i]);
+ regulator_put(sdev->regulators[i]);
+ }
+ }
+}
+
+static int simplekms_device_init_regulators(struct simplekms_device *sdev)
+{
+ struct drm_device *dev = &sdev->dev;
+ struct platform_device *pdev = sdev->pdev;
+ struct device_node *of_node = pdev->dev.of_node;
+ struct property *prop;
+ struct regulator *regulator;
+ const char *p;
+ unsigned int count = 0, i = 0;
+ int ret;
+
+ if (dev_get_platdata(&pdev->dev) || !of_node)
+ return 0;
+
+ /* Count the number of regulator supplies */
+ for_each_property_of_node(of_node, prop) {
+ p = strstr(prop->name, SUPPLY_SUFFIX);
+ if (p && p != prop->name)
+ ++count;
+ }
+
+ if (!count)
+ return 0;
+
+ sdev->regulators = drmm_kzalloc(dev,
+ count * sizeof(sdev->regulators[0]),
+ GFP_KERNEL);
+ if (!sdev->regulators)
+ return -ENOMEM;
+
+ for_each_property_of_node(of_node, prop) {
+ char name[32]; /* 32 is max size of property name */
+ size_t len;
+
+ p = strstr(prop->name, SUPPLY_SUFFIX);
+ if (!p || p == prop->name)
+ continue;
+ len = strlen(prop->name) - strlen(SUPPLY_SUFFIX) + 1;
+ strlcpy(name, prop->name, len);
+
+ regulator = regulator_get_optional(&pdev->dev, name);
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ if (ret == -EPROBE_DEFER)
+ goto err;
+ drm_err(dev, "regulator %s not found: %d\n",
+ name, ret);
+ continue;
+ }
+
+ ret = regulator_enable(regulator);
+ if (ret) {
+ drm_err(dev, "failed to enable regulator %u: %d\n",
+ i, ret);
+ regulator_put(regulator);
+ }
+
+ sdev->regulators[i++] = regulator;
+ }
+ sdev->regulator_count = i;
+
+ return devm_add_action_or_reset(&pdev->dev,
+ simplekms_device_release_regulators,
+ sdev);
+
+err:
+ while (i) {
+ --i;
+ if (sdev->regulators[i]) {
+ regulator_disable(sdev->regulators[i]);
+ regulator_put(sdev->regulators[i]);
+ }
+ }
+ return ret;
+}
+#else
+static int simplekms_device_init_regulators(struct simplekms_device *sdev)
+{
+ return 0;
+}
+#endif
+
/*
* Simplefb settings
*/
@@ -611,6 +736,9 @@ simplekms_device_create(struct drm_driver *drv, struct platform_device *pdev)
sdev->pdev = pdev;
ret = simplekms_device_init_clocks(sdev);
+ if (ret)
+ return ERR_PTR(ret);
+ ret = simplekms_device_init_regulators(sdev);
if (ret)
return ERR_PTR(ret);
ret = simplekms_device_init_fb(sdev);
--
2.27.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2020-06-25 12:00 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-25 12:00 [RFC][PATCH 0/9] drm: Support simple-framebuffer devices and firmware fbs Thomas Zimmermann
2020-06-25 12:00 ` [PATCH 1/9] drm/format-helper: Pass destination pitch to drm_fb_memcpy_dstclip() Thomas Zimmermann
2020-06-29 8:40 ` Daniel Vetter
2020-09-25 14:55 ` Thomas Zimmermann
2020-09-26 16:42 ` Daniel Vetter
2020-09-28 7:22 ` Thomas Zimmermann
2020-09-28 8:53 ` Daniel Vetter
2020-09-28 9:13 ` Thomas Zimmermann
2020-09-29 9:19 ` Daniel Vetter
2020-09-29 9:39 ` Thomas Zimmermann
2020-09-29 11:32 ` Daniel Vetter
2020-09-28 10:24 ` Gerd Hoffmann
2020-09-28 13:42 ` Pekka Paalanen
2020-06-25 12:00 ` [PATCH 2/9] drm/format-helper: Add blitter functions Thomas Zimmermann
2020-06-29 8:46 ` Daniel Vetter
2020-06-25 12:00 ` [PATCH 3/9] drm: Add simplekms driver Thomas Zimmermann
2020-06-29 9:06 ` Daniel Vetter
2020-09-25 15:01 ` Thomas Zimmermann
2020-09-25 15:14 ` Maxime Ripard
2020-09-28 7:25 ` Thomas Zimmermann
2021-02-10 16:14 ` Thomas Zimmermann
2020-06-25 12:00 ` [PATCH 4/9] drm/simplekms: Add fbdev emulation Thomas Zimmermann
2020-06-29 9:11 ` Daniel Vetter
2020-06-25 12:00 ` [PATCH 5/9] drm/simplekms: Initialize framebuffer data from device-tree node Thomas Zimmermann
2020-06-30 2:36 ` Rob Herring
2020-06-25 12:00 ` [PATCH 6/9] drm/simplekms: Acquire clocks from DT device node Thomas Zimmermann
2020-06-25 13:34 ` Geert Uytterhoeven
2020-06-29 9:07 ` Daniel Vetter
2020-06-25 12:00 ` Thomas Zimmermann [this message]
2020-06-25 13:36 ` [PATCH 7/9] drm/simplekms: Acquire regulators " Geert Uytterhoeven
2020-06-25 12:00 ` [PATCH 8/9] drm: Add infrastructure for platform devices Thomas Zimmermann
2020-06-29 9:27 ` Daniel Vetter
2020-09-28 8:40 ` Thomas Zimmermann
2020-09-28 8:50 ` Daniel Vetter
2020-09-28 9:14 ` Thomas Zimmermann
2020-09-29 8:59 ` Thomas Zimmermann
2020-09-29 9:20 ` Daniel Vetter
2020-06-30 9:11 ` Daniel Vetter
2020-06-25 12:00 ` [PATCH 9/9] drm/simplekms: Acquire memory aperture for framebuffer Thomas Zimmermann
2020-06-29 9:22 ` Daniel Vetter
2020-06-29 16:04 ` Greg KH
2020-06-29 16:23 ` Mark Brown
2020-06-29 16:57 ` Greg KH
2020-06-30 2:13 ` Rob Herring
2020-06-30 8:50 ` Greg KH
2020-06-29 9:38 ` [RFC][PATCH 0/9] drm: Support simple-framebuffer devices and firmware fbs Hans de Goede
2020-06-30 9:06 ` Daniel Vetter
2020-06-30 9:13 ` Hans de Goede
2020-07-01 14:10 ` Thomas Zimmermann
2020-07-03 10:55 ` Hans de Goede
2020-07-03 11:42 ` Thomas Zimmermann
2020-07-03 12:58 ` Daniel Vetter
2020-07-03 14:11 ` Hans de Goede
2020-07-01 13:48 ` Thomas Zimmermann
2020-07-03 10:44 ` Hans de Goede
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200625120011.16168-8-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@linux.ie \
--cc=broonie@kernel.org \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=emil.l.velikov@gmail.com \
--cc=geert+renesas@glider.be \
--cc=hdegoede@redhat.com \
--cc=kraxel@redhat.com \
--cc=lgirdwood@gmail.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=noralf@tronnes.org \
--cc=robh@kernel.org \
--cc=sam@ravnborg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox