The separation layering concept of Linux drives

Source: Internet
Author: User

Bus_drv_dev Model: function Rewriting just change the dev hardware code, DRV does not need to be rewritten.

LED Example

Here is an example of this separation using a light LED example:

LED_DEV.C defines the resources for this platform device:

Static struct resource led_resource[] = {

[0] = {

. Start = 0x56000010,  Physical address of//gpfcon

. end = 0x56000010 + 8-1,

. Flags = Ioresource_mem,

},

[1] = {

. Start = 6,//F6 pin

. end = 6,

. Flags = IORESOURCE_IRQ,

},

};

Define a platform device:

struct Platform_device device_led = {

. Name = "Myled",

    . id =-1,

. num_resources = Array_size (Led_resource),

. resource = Led_resource,

. dev={

. Release = Led_release,

},

};

Register this "platform device" in the entry function

static int led_dev_init (void)

{

Platform_device_register (&device_led);

   return 0;
}

Exit function is to unload this platform device

static void Led_dev_exit (void)

{

Platform_device_unregister (&device_led);

}

led_drv.c Define a platform driver static struct platform_driver led_drv = {

. Probe = Led_probe,

. remove = Led_remove,

. Driver = {

. Name = "Myled",

}

};

It is important to note that the name of the platform and the platform device of Dev are identical. This led_driver function is called if the platform device and platform driver match.

/* Assign/Set/register a platform_driver */

#include <linux/module.h>
#include <linux/version.h>

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>

static int major;


static struct class *cls;
Static volatile unsigned long *gpio_con;
Static volatile unsigned long *gpio_dat;
static int pin;

static int Led_open (struct inode *inode, struct file *file)
{
PRINTK ("first_drv_open\n");
/* Configured as OUTPUT */
*gpio_con &= ~ (0x3<< (pin*2));
*gpio_con |= (0x1<< (pin*2));
return 0;
}

Static ssize_t led_write (struct file *file, const char __user *buf, size_t count, loff_t * PPOs)
{
int Val;

Copy_from_user (&val, buf, Count); Copy_to_user ();

if (val = = 1)
{
Lighting
*gpio_dat &= ~ (1<<pin);
}
Else
{
Extinguishing lamp
*gpio_dat |= (1<<pin);
}

return 0;
}


static struct File_operations Led_fops = {
. Owner = This_module,/* This is a macro that pushes the __this_module variable created automatically when the module is compiled */
. open = Led_open,
. Write=led_write,
};

static int led_probe (struct platform_device *pdev)
{
struct resource*res;

/* Ioremap According to Platform_device's resources */
res = Platform_get_resource (Pdev, Ioresource_mem, 0);
Gpio_con = Ioremap (Res->start, Res->end-res->start + 1);
Gpio_dat = Gpio_con + 1;

res = Platform_get_resource (Pdev, IORESOURCE_IRQ, 0);
Pin = res->start;

/* Register character device drivers */

PRINTK ("Led_probe, found led\n");

Major = Register_chrdev (0, "myled", &led_fops);

CLS = Class_create (This_module, "myled");

Class_device_create (CLS, NULL, MKDEV (major, 0), NULL, "led"); /*/dev/led */

return 0;
}

static int led_remove (struct platform_device *pdev)
{
/* Uninstall character device drivers */
/* Iounmap */
PRINTK ("Led_remove, remove led\n");

class_device_destroy (CLS, MKDEV (major, 0));
class_destroy (CLS);
unregister_chrdev (Major, "myled");
iounmap (Gpio_con);

return 0;
"


struct Platform_driver led_drv = {
. probe= Led_probe,
. remove= Led_remove,
. driver= {
. Name= "Myled",
}
};


static int led_drv_init (void)
{
Platform_driver_register (&LED_DRV);
return 0;
}

static void Led_drv_exit (void)
{
Platform_driver_unregister (&LED_DRV);
}

Module_init (Led_drv_init);
Module_exit (Led_drv_exit);

Module_license ("GPL");

This driver is divided into the left and right sides, that is, Dev and DRV, in Led_dev. Assign, set, register a platform_device, assign in Led_drv, set, register a platform_driver.

The separation layering concept of Linux drives

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.