#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
struct data
{
struct platform_device *pdev;
struct miscdevice miscdevice;
bool miscdevice_registered;
};
static int hello_remove(struct platform_device *pdev);
static int hello_open(struct inode *inode, struct file *file)
{
int ret;
struct miscdevice *miscdevice = file->private_data;
struct data *data = container_of(miscdevice, struct data, miscdevice);
printk("%s\n", __func__);
ret = pm_runtime_get_sync(&data->pdev->dev);
if (ret != 0) {
dev_err(&data->pdev->dev, "pm_runtime_get_sync() failed: ret=%d\n", ret);
return ret;
}
return 0;
}
static ssize_t hello_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
printk("%s\n", __func__);
return count;
}
static ssize_t hello_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
printk("%s\n", __func__);
return count;
}
static int hello_release(struct inode *inode, struct file *file)
{
struct miscdevice *miscdevice = file->private_data;
struct data *data = container_of(miscdevice, struct data, miscdevice);
printk("%s\n", __func__);
pm_runtime_put_sync(&data->pdev->dev);
return 0;
}
static const struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.read = hello_read,
.write = hello_write,
.release = hello_release
};
static int hello_probe(struct platform_device *pdev)
{
int ret;
struct data *data;
printk("%s\n", __func__);
data = devm_kzalloc(&pdev->dev, sizeof(struct data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data->pdev = pdev;
platform_set_drvdata(pdev, data);
data->miscdevice.minor = MISC_DYNAMIC_MINOR;
data->miscdevice.name = "hello_file";
data->miscdevice.fops = &hello_fops;
data->miscdevice.mode = 0666;
ret = misc_register(&data->miscdevice);
if (ret != 0) {
dev_err(&pdev->dev, "failed to register miscdevice\n");
hello_remove(pdev);
return ret;
}
data->miscdevice_registered = true;
//pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
return 0;
}
static int hello_remove(struct platform_device *pdev)
{
struct data *data = platform_get_drvdata(pdev);
printk("%s\n", __func__);
if (data->miscdevice_registered) {
misc_deregister(&data->miscdevice);
data->miscdevice_registered = false;
}
printk("---disable begin---\n");
pm_runtime_disable(&pdev->dev);
printk("---disable end---\n");
return 0;
}
static int hello_suspend(struct device *dev)
{
printk("%s\n", __func__);
return 0;
}
static int hello_resume(struct device *dev)
{
printk("%s\n", __func__);
return 0;
}
static UNIVERSAL_DEV_PM_OPS(hello_pm, hello_suspend, hello_resume, NULL);
static struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.driver = {
.name = "my_hello",
.pm = &hello_pm
}
};
static void hello_device_release(struct device *dev)
{
printk("%s\n", __func__);
}
static struct platform_device hello_device = {
.name = "my_hello",
.id = -1,
.dev = {
.release = hello_device_release
}
};
static int __init hello_init(void)
{
printk("%s\n", __func__);
platform_driver_register(&hello_driver);
platform_device_register(&hello_device);
return 0;
}
static void __exit hello_exit(void)
{
printk("%s\n", __func__);
platform_device_unregister(&hello_device);
platform_driver_unregister(&hello_driver);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Oct1158");
MODULE_LICENSE("GPL");