From: Laurence Rochfort <laurence.rochfort@gmail.com>
To: kernelnewbies@kernelnewbies.org
Cc: laurence.rochfort@gmail.com
Subject: Platform driver probe() not being called when device-tree overlaid
Date: Fri, 15 Feb 2019 19:38:59 +0000 [thread overview]
Message-ID: <20190215193859.53p6u32ds3ihd47i@raspberrypi> (raw)
Hi all,
I'm attempting to write a platform device driver that gets loaded when
a compatible device-tree overlay is loaded by dtoverlay.
This is just a learning exercise at the moment, so I'm trying to write
the simplest platform device I can, rather than extending one of the device drivers that extend platform device (terminology?). I'm trying to get just enough to get the driver's probe() function called when the device-tree overlay is applied, and then create a misc device.
My module seems to init just fine, and the device-tree overlay seems
to also load without issue, but for some reason probe() is never
called.
Am I correct in using probe() with platform devices? I understand
platform devices can't be enumerated/detected, but I thought that probe() would be called when there was a compatibility match between the driver and the device-tree overlay.
Any pointers would be much appreciated.
Cheers,
Laurence.
Here's what /sys shows:
$ cat /sys/devices/platform/gde060f3/uevent
OF_NAME=gde060f3
OF_FULLNAME=/gde060f3
OF_COMPATIBLE_0=gde060f3
OF_COMPATIBLE_N=1
MODALIAS=of:Ngde060f3T<NULL>Cgde060f3
$ cat /sys/firmware/devicetree/base/gde060f3/compatible
gde060f3
$ cat /sys/firmware/devicetree/base/gde060f3/name
gde060f3
$ cat /sys/firmware/devicetree/base/gde060f3/status
okay
Here's the loaded device-tree:
$ dtc -I fs /proc/device-tree
/dts-v1/;
/ {
compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
serial-number = "00000000427625f0";
model = "Raspberry Pi 3 Model B Plus Rev 1.3";
memreserve = <0x3b400000 0x4c00000>;
interrupt-parent = <0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
clocks {
*** SNIPPED ***
};
__overrides__ {
*** SNIPPED ***
};
gde060f3 {
compatible = "gde060f3";
status = "okay";
phandle = <0x7b>;
linux,phandle = <0x7b>;
};
system {
linux,serial = <0x0 0x427625f0>;
linux,revision = <0xa020d3>;
};
*** SNIPPED ***
};
module file:
#define DEBUG
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
struct gde060f3_struct {
struct platform_device *pdev;
struct miscdevice mdev;
};
static inline struct gde060f3_struct *to_gde060f3_struct(struct file *file)
{
struct miscdevice *miscdev = file->private_data;
return container_of(miscdev, struct gde060f3_struct, mdev);
}
static ssize_t gde060f3_read(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
struct gde060f3_struct *gde060f3 = to_gde060f3_struct(file); /* just for example */
(void)gde060f3; /* unused */
return simple_read_from_buffer(buf, count, pos, "gde060f3 text", 14);
}
static const struct file_operations gde060f3_fops = {
.owner = THIS_MODULE,
.read = gde060f3_read,
};
static const struct of_device_id gde060f3_match[] = {
{ .compatible = "gde060f3" },
{},
};
MODULE_DEVICE_TABLE(of, gde060f3_match);
static int gde060f3_probe(struct platform_device *pdev)
{
struct gde060f3_struct *gde060f3;
int ret;
pr_info("gde060f3_probe()\n");
gde060f3 = kmalloc(sizeof(*gde060f3), GFP_KERNEL);
if (!gde060f3)
return -ENOMEM;
platform_set_drvdata(pdev, gde060f3);
gde060f3->pdev = pdev;
gde060f3->mdev.minor = MISC_DYNAMIC_MINOR;
gde060f3->mdev.name = "gde060f3";
gde060f3->mdev.fops = &gde060f3_fops;
gde060f3->mdev.parent = NULL;
ret = misc_register(&gde060f3->mdev);
if (ret) {
dev_err(&pdev->dev, "Failed to register miscdev\n");
return ret;
}
dev_info(&pdev->dev, "Registered\n");
pr_info("Registered\n");
return 0;
}
static int gde060f3_remove(struct platform_device *pdev)
{
struct gde060f3_struct *gde060f3 = platform_get_drvdata(pdev);
misc_deregister(&gde060f3->mdev);
kfree(gde060f3);
dev_info(&pdev->dev, "Unregistered\n");
pr_info("Unregistered\n");
return 0;
}
static struct platform_driver gde060f3_driver = {
.probe = gde060f3_probe,
.remove = gde060f3_remove,
.driver = {
.name = "gde060f3",
.of_match_table = gde060f3_match,
},
};
module_platform_driver_probe(gde060f3_driver, gde060f3_probe);
MODULE_AUTHOR("Laurence Rochfort <laurence.rochfort@gmail.com>");
MODULE_DESCRIPTION("GPIO driver for Good Display GDE060F3 ePaper Display");
MODULE_LICENSE("GPL");
overlay file:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
// target or target-path?
target-path = "/";
__overlay__ {
gde060f3: gde060f3 {
compatible = "gde060f3";
status = "okay";
};
};
};
};
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
next reply other threads:[~2019-02-15 19:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-15 19:38 Laurence Rochfort [this message]
2019-02-16 16:45 ` Platform driver probe() not being called when device-tree overlaid Laurence Rochfort
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=20190215193859.53p6u32ds3ihd47i@raspberrypi \
--to=laurence.rochfort@gmail.com \
--cc=kernelnewbies@kernelnewbies.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;
as well as URLs for NNTP newsgroup(s).