Can't understand /proc/interrupts output for GICv3 case
Chan Kim
ckim at etri.re.kr
Mon Apr 11 22:18:03 EDT 2022
Hi, Greg KH,
Thanks for the advices.
Some questions inline.
> -----Original Message-----
> From: 'Greg KH' <greg at kroah.com>
> Sent: Monday, April 11, 2022 11:26 PM
> To: Chan Kim <ckim at etri.re.kr>
> Cc: 'qemu-discuss' <qemu-discuss at nongnu.org>;
> kernelnewbies at kernelnewbies.org
> Subject: Re: Can't understand /proc/interrupts output for GICv3 case
>
> On Mon, Apr 11, 2022 at 11:15:57PM +0900, Chan Kim 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;
> > }
> >
> > /* 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"); }
> > /**/
>
> You can replace all of the above code by just using the miscdevice
> interface instead. Please use that, it ensures that you do everything
> properly and simplifies it all.
>
> >
> > vaddr = ioremap(AXPU_BASE, 0x80000);
>
> Wait, where are you picking those random values from?
Yes, it now looks weird to me. I have passed the register address
information in the device tree and the kernel already knows my device's
address range. Then, how should I get this virtual io address in this
driver? I need it to access some registers. How can I ask the system bus?
And my driver is a kernel module because I want to use it in ubuntu-20.04 on
a virtual machine, I want it to be a kernel module that I can insmod or
rmmod.(actually my job is to provide this virtual machine to some folks).
And I cannot build the ubuntu image even if I change it to a platform device
driver and add it in the kernel tree.
> That's not how drivers work in the kernel. You have to have a bus pass
> you a device. Please register your driver with the proper bus type and go
> from there. The probe callback should be the place you set things up
> based on the device and resources given to you by the bus.
>
> You can't just randomly pick memory locations and think things will work.
>
> > 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);
>
> Same for that, just picking 6 will not work, sorry.
>
Yes, that was my original question. How can I get my irq number (I know it's
hwirq 47) and I peeked into kernel that irq 6 was assigned for the irq_desc.
So I changed my driver to request irq 6 for my device and I found at least
it works for now, all the register access and interrupts. I know this is not
the solution and I'm curious how I should get the irq number of io virtual
address in this situation.
> Perhaps take a look at the book, Linux Device Drivers, 3rd edition.
> It's free online and should help you out a lot.
>
> > printk("request_irq returned %d\n", ret); // -EINVAL
> > printk(KERN_INFO "Device driver inserted ..done properly..\n");
> > return 0;
> >
> > r_device :
> > class_destroy(dev_class);
> >
> > r_class :
> > unregister_chrdev_region(dev,1);
> > return -1;
>
> One final comment, don't make up error values like this, use real ERROR
> codes.
>
> thanks,
>
> greg k-h
Yes, I've read the book sometimes (not the whole part) but if I read it now,
I'll be able to more understand it. It's a bit outdated though. Why don't
you update your book? :)
Thank you again for the advices.
Best regards,
Chan Kim
More information about the Kernelnewbies
mailing list