Re-hi, On Mon, Apr 11, 2022 at 6:16 PM Chan Kim <ckim@etri.re.kr> wrote:
What bus type is your driver written for?
That sounds very logical. In my case I added it to system bus.
What exactly do you mean by "system bus"?
I meant 'sysbus' in qemu code that I showed in the qemu code. And I think it's the CPU bus.
Where is your kernel code?
This is the init function of my char driver. I thought if the struct cdev contains struct device, maybe I could use the struct device's of_node to call of_irq_get but it doesn't. And I remember I've seen the cdev in usually contained in the driver data of platform driver(?). Can I implement platform driver in kernel module form? Below is the char driver init code. Currently it's request_irq(6, ... ) but I want to know out the number 6 using program. If you have any advice, please tell me.
static int __init chr_driver_init(void) { int ret; /* Allocating Major number */ if ((alloc_chrdev_region(&dev, 0, 1, "axpu_Dev")) < 0) { printk(KERN_INFO"Cannot allocate the major number..\n"); return -1; }
printk(KERN_INFO"Major = %d Minor = %d..\n",MAJOR(dev),MINOR(dev));
/* creating cdev structure */ cdev_init(&axpu_cdev, &fops); axpu_cdev.owner = THIS_MODULE;
/* Adding character device to the system */ if ((cdev_add(&axpu_cdev,dev,1)) < 0) { printk(KERN_INFO "Cannot add the device to the system...\n"); goto r_class; }
I guess you got address 0x80000 randomly also may have this code from stackoverflow but it wont work for you. as written stackoverflow, device_create must be a character device and an address under /sys/dev/char before getting NULL. So did you create a char device with use mknod command? Actually register_chrdev will do this for you but you can do it with mknod if you wish. /* creating struct class */
if ((dev_class = class_create(THIS_MODULE, "axpu_class")) == NULL) { printk(KERN_INFO "cannot create the struct class...\n"); goto r_class; }
/* for interrupt test !! */ /* for vanilla work-around.. already made by mkdev */ if ((device_create(dev_class, NULL, dev, NULL, "axpu_device")) == NULL) { printk(KERN_INFO "cannot create the device ..\n"); goto r_device; } else { printk(KERN_INFO "axpu_device created..\n"); } /**/
vaddr = ioremap(AXPU_BASE, 0x80000); \
Please first read Documentation/devices.txt because kernel can do dynamic allocation I think. * https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch03s02... * https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch03.ht...
if(!vaddr) { printk(KERN_INFO"Failed to map the address.\n"); release_mem_region(AXPU_BASE,AXPU_SIZE); return 1; } printk("----- AXPU_BASE mapped at vaddr = %px\n", vaddr);
ret = request_irq(6, axpu_irq_handler, IRQF_SHARED, "axpu_irq", &axpu_cdev); printk("request_irq returned %d\n", ret); // -EINVAL printk(KERN_INFO "Device driver inserted ..done properly..\n"); return 0;
You dont need to call manual, because it is defined in cdev.h. * https://embeddedguruji.blogspot.com/2019/01/automatically-creating-device-no... in example for example device_destroy already destroys class.
r_device : class_destroy(dev_class);
r_class : unregister_chrdev_region(dev,1); return -1; }
it will be great that i will recommend three books to you again. * Understanding the Linux Kernel * Linux Device Drivers * Linux Kernel Development
Thank you. Chan Kim