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