1,324
社区成员




struct led_dev_t
{
const char * dev_name;
unsigned long major;
struct class * cls;
struct device * dev;
void * reg_virt_base;
int led_gpio_bit;
};
static struct led_dev_t * led_dev;
int led_dev_release(struct inode *inode, struct file *filp)
{
return 0;
}
int pdrv_probe(struct platform_device * pdev)
{
struct resource * rsc;
int ret;
unsigned int gpio_base_addr;
unsigned int gpio_base_addr_size;
unsigned int gpio_conf_val;
// Apply resources
printk("------------%s------------\n", __FUNCTION__);
// malloc memory for led description
led_dev = (struct led_dev_t *)kzalloc(sizeof(struct led_dev_t), GFP_KERNEL);
// get resource from device
rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio_base_addr = (unsigned int)rsc->start;
gpio_base_addr_size = (unsigned int)resource_size(rsc);
led_dev->led_gpio_bit = *((int *)pdev->dev.platform_data);
led_dev->dev_name = pdev->dev.kobj.name;
// register device number
led_dev->major = register_chrdev(0,led_dev->dev_name, &dev_fops);
led_dev->cls = led_cls;
// create device node
led_dev->dev = device_create(led_dev->cls, NULL, MKDEV(led_dev->major, 1), NULL, led_dev->dev_name);
// io remap
led_dev->reg_virt_base = ioremap(gpio_base_addr, gpio_base_addr_size);
// config gpio as output
gpio_conf_val = readl(led_dev->reg_virt_base);
gpio_conf_val &= ~(0xf<<(led_dev->led_gpio_bit*4));
gpio_conf_val |= (0x1<<(led_dev->led_gpio_bit*4));
writel(gpio_conf_val, led_dev->reg_virt_base);
return 0;
}
int pdrv_remove(struct platform_device * pdev)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
device_destroy(led_dev->cls, MKDEV(led_dev->major, 1));
printk("devie destroyed!\n");
unregister_chrdev(led_dev->major, led_dev->dev_name);
printk("char dev unregistered!\n");
kfree(led_dev);
return 0;
}
struct platform_device_id led_id_table[] = {
{"4412-led", 1},
};
struct platform_driver pdrv = {
.probe = pdrv_probe,
.remove = pdrv_remove,
.driver = {
.name = "4412_led_driver",
},
.id_table = led_id_table,
};
static int __init led_drv_init(void)
{
int ret;
printk("-----------------------%s---------------------\n", __FUNCTION__);
// construct /sys/bus/mybus/devices/...
ret = platform_driver_register(&pdrv);
if(ret != 0) {
printk("device register error!\n");
return ret;
}
// create device class
led_cls = class_create(THIS_MODULE, "led");
if (IS_ERR(led_dev->cls))
{
printk(KERN_ERR "create class error\n");
kfree(led_dev);
return PTR_ERR(led_dev->cls);
}
return 0;
}
static void __exit led_drv_exit(void)
{
printk("-----------------------%s---------------------\n", __FUNCTION__);
class_destroy(led_dev->cls);
platform_driver_unregister(&pdrv);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");