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