Can't understand /proc/interrupts output for GICv3 case

'Greg KH' greg at kroah.com
Mon Apr 11 10:26:05 EDT 2022


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?

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.

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



More information about the Kernelnewbies mailing list