<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:굴림;
        panose-1:2 11 6 0 0 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"맑은 고딕";
        panose-1:2 11 5 3 2 0 0 2 0 4;}
@font-face
        {font-family:"\@굴림";
        panose-1:2 11 6 0 0 1 1 1 1 1;}
@font-face
        {font-family:"\@맑은 고딕";
        panose-1:2 11 5 3 2 0 0 2 0 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:굴림;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"글자만 Char";
        margin:0cm;
        margin-bottom:.0001pt;
        text-autospace:none;
        word-break:break-hangul;
        font-size:10.0pt;
        font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:12.0pt;
        font-family:굴림;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"맑은 고딕";
        color:windowtext;}
span.EmailStyle19
        {mso-style-type:personal;
        font-family:"맑은 고딕";
        color:windowtext;}
span.Char
        {mso-style-name:"글자만 Char";
        mso-style-priority:99;
        mso-style-link:글자만;
        font-family:"Courier New";}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"맑은 고딕";}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:3.0cm 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=KO link=blue vlink=purple><div class=WordSection1><p class=MsoNormal style='word-break:break-hangul'><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'>Hi Ozgur, <o:p></o:p></span></p><p class=MsoNormal style='word-break:break-hangul'><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'>My replies in-line.<o:p></o:p></span></p><p class=MsoNormal style='word-break:break-hangul'><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'>Thanks!<o:p></o:p></span></p><p class=MsoNormal style='word-break:break-hangul'><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p><div style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'>From:</span></b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'> Ozgur Karatas <ozgurk@ieee.org> <br><b>Sent:</b> Monday, April 11, 2022 11:53 PM<br><b>To:</b> Chan Kim <ckim@etri.re.kr><br><b>Cc:</b> Greg KH <greg@kroah.com>; kernelnewbies@kernelnewbies.org; qemu-discuss <qemu-discuss@nongnu.org><br><b>Subject:</b> Re: Can't understand /proc/interrupts output for GICv3 case<o:p></o:p></span></p></div></div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><div><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><p class=MsoNormal><span lang=EN-US>Re-hi,<o:p></o:p></span></p><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><div><div><p class=MsoNormal><span lang=EN-US>On Mon, Apr 11, 2022 at 6:16 PM Chan Kim <<a href="mailto:ckim@etri.re.kr">ckim@etri.re.kr</a>> wrote:<o:p></o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal><span lang=EN-US><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>        }<o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>I guess you got address 0x80000 randomly also may have this code from stackoverflow but it wont work for you.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>as written stackoverflow, device_create must be a character device and an address under /sys/dev/char before getting NULL.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>So did you create a char device with use mknod command?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US> ==> (I don’t know how to remove this bar in the lefe when I add my in-line reply in outlook..) it’s the size of address range of my device. My question is, how I can get the io virtual address when 1. my driver is a kernel module and 2. It is a character driver. For platform driver I got it from the resource table, but I think it’s an old method now and we should ask the bus as Greg-KH said. The kernel already knows the addresses because it had processed the device table.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>Actually register_chrdev will do this for you but you can do it with mknod if you wish.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal><span lang=EN-US>        /* 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);   \<o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>Please first read Documentation/devices.txt because kernel can do dynamic allocation I think.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>* <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><o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>* <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><o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US> ==> I understand by using class_create and device_create, the device file is generated under /dev (without using mknod). I am using this method without problem and the app/driver runs ok on the virtual machine. <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal style='margin-bottom:12.0pt'><span lang=EN-US>        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;<o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>You dont need to call manual, because it is defined in cdev.h.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>* <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><o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'>==> your link doesn’t show do any io access or irq processing. I want to know how I can get the io virtual address and the virtual irq number from the driver. My driver is a character device driver and it’s a kernel module which is inserted after OS has booted. I thinks this should be possible.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>in example for example device_destroy already destroys class.<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US>  <o:p></o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal style='margin-bottom:12.0pt'><span lang=EN-US>r_device :<br>        class_destroy(dev_class);<br><br>r_class :<br>        unregister_chrdev_region(dev,1);<br>        return -1;<br>}<o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div><p class=MsoNormal><span lang=EN-US>it will be great that i will recommend three books to you again.<br><br>* Understanding the Linux Kernel<br>* Linux Device Drivers<o:p></o:p></span></p><div><p class=MsoNormal><span lang=EN-US>* Linux Kernel Development<o:p></o:p></span></p></div><div><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'>==> Yes I’ve read those books here and there in the past, but you know I’m not given that much time for this and my job isn’t always working with linux drivers. I will take some time to read those books thoroughly sometime later.  Thanks for the interest and advices.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"맑은 고딕"'><o:p> </o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal><span lang=EN-US>Thank you.<br>Chan Kim<o:p></o:p></span></p></blockquote></div></div></div></div></div></body></html>