Hello Peter Ujfalusi: we do not call irq_free_descs when quit, although called irq_alloc_descs.
is it suitable to call irq_free_descs when quit ? it seems need additional analysing, please see drivers/mfd/twl6030-irq.c:441 (after finish calling twl6030_init_irq, the twl6030_irq_base is non-zero) (when twl6030_init_irq fail, also need consider whether call irq_free_descs) thanks. :-) gchen. 350 int twl6030_init_irq(struct device *dev, int irq_num) 351 { 352 struct device_node *node = dev->of_node; 353 int nr_irqs, irq_base, irq_end; 354 struct task_struct *task; 355 static struct irq_chip twl6030_irq_chip; 356 int status = 0; 357 int i; 358 u8 mask[3]; 359 360 nr_irqs = TWL6030_NR_IRQS; 361 362 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); 363 if (IS_ERR_VALUE(irq_base)) { 364 dev_err(dev, "Fail to allocate IRQ descs\n"); 365 return irq_base; 366 } 367 368 irq_domain_add_legacy(node, nr_irqs, irq_base, 0, 369 &irq_domain_simple_ops, NULL); 370 371 irq_end = irq_base + nr_irqs; 372 373 mask[0] = 0xFF; 374 mask[1] = 0xFF; 375 mask[2] = 0xFF; 376 377 /* mask all int lines */ 378 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); 379 /* mask all int sts */ 380 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); 381 /* clear INT_STS_A,B,C */ 382 twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); 383 384 twl6030_irq_base = irq_base; 385 386 /* 387 * install an irq handler for each of the modules; 388 * clone dummy irq_chip since PIH can't *do* anything 389 */ 390 twl6030_irq_chip = dummy_irq_chip; 391 twl6030_irq_chip.name = "twl6030"; 392 twl6030_irq_chip.irq_set_type = NULL; 393 twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; 394 395 for (i = irq_base; i < irq_end; i++) { 396 irq_set_chip_and_handler(i, &twl6030_irq_chip, 397 handle_simple_irq); 398 irq_set_chip_data(i, (void *)irq_num); 399 activate_irq(i); 400 } 401 402 dev_info(dev, "PIH (irq %d) chaining IRQs %d..%d\n", 403 irq_num, irq_base, irq_end); 404 405 /* install an irq handler to demultiplex the TWL6030 interrupt */ 406 init_completion(&irq_event); 407 408 status = request_irq(irq_num, handle_twl6030_pih, 0, "TWL6030-PIH", 409 &irq_event); 410 if (status < 0) { 411 dev_err(dev, "could not claim irq %d: %d\n", irq_num, status); 412 goto fail_irq; 413 } 414 415 task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); 416 if (IS_ERR(task)) { 417 dev_err(dev, "could not create irq %d thread!\n", irq_num); 418 status = PTR_ERR(task); 419 goto fail_kthread; 420 } 421 422 twl_irq = irq_num; 423 register_pm_notifier(&twl6030_irq_pm_notifier_block); 424 return irq_base; 425 426 fail_kthread: 427 free_irq(irq_num, &irq_event); 428 429 fail_irq: 430 for (i = irq_base; i < irq_end; i++) 431 irq_set_chip_and_handler(i, NULL, NULL); 432 433 return status; 434 } 435 436 int twl6030_exit_irq(void) 437 { 438 unregister_pm_notifier(&twl6030_irq_pm_notifier_block); 439 440 if (twl6030_irq_base) { 441 pr_err("twl6030: can't yet clean up IRQs?\n"); 442 return -ENOSYS; 443 } 444 return 0; 445 } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/