subr_intr.c (15adccc6874c49592f8bcbef2f67232c7e2fd593) | subr_intr.c (cd642c88a1957179fdc6843a6c7bd04ca238d625) |
---|---|
1/*- 2 * Copyright (c) 2015-2016 Svatopluk Kraus 3 * Copyright (c) 2015-2016 Michal Meloun 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 114 unchanged lines hidden (view full) --- 123 * Note that each interrupt number from second space duplicates some number 124 * from first space at this moment. An interrupt number from first space can 125 * be duplicated even multiple times in second space. 126 */ 127struct intr_dev_data { 128 device_t idd_dev; 129 intptr_t idd_xref; 130 u_int idd_irq; | 1/*- 2 * Copyright (c) 2015-2016 Svatopluk Kraus 3 * Copyright (c) 2015-2016 Michal Meloun 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 114 unchanged lines hidden (view full) --- 123 * Note that each interrupt number from second space duplicates some number 124 * from first space at this moment. An interrupt number from first space can 125 * be duplicated even multiple times in second space. 126 */ 127struct intr_dev_data { 128 device_t idd_dev; 129 intptr_t idd_xref; 130 u_int idd_irq; |
131 struct intr_map_data idd_data; | 131 struct intr_map_data * idd_data; |
132 struct intr_irqsrc * idd_isrc; 133}; 134 135static struct intr_dev_data *intr_ddata_tab[2 * NIRQ]; 136static u_int intr_ddata_first_unused; 137 138#define IRQ_DDATA_BASE 10000 139CTASSERT(IRQ_DDATA_BASE > nitems(irq_sources)); --- 350 unchanged lines hidden (view full) --- 490 return (true); 491} 492#endif 493 494static struct intr_dev_data * 495intr_ddata_alloc(u_int extsize) 496{ 497 struct intr_dev_data *ddata; | 132 struct intr_irqsrc * idd_isrc; 133}; 134 135static struct intr_dev_data *intr_ddata_tab[2 * NIRQ]; 136static u_int intr_ddata_first_unused; 137 138#define IRQ_DDATA_BASE 10000 139CTASSERT(IRQ_DDATA_BASE > nitems(irq_sources)); --- 350 unchanged lines hidden (view full) --- 490 return (true); 491} 492#endif 493 494static struct intr_dev_data * 495intr_ddata_alloc(u_int extsize) 496{ 497 struct intr_dev_data *ddata; |
498 size_t size; |
|
498 | 499 |
499 ddata = malloc(sizeof(*ddata) + extsize, M_INTRNG, M_WAITOK | M_ZERO); | 500 size = sizeof(*ddata); 501 ddata = malloc(size + extsize, M_INTRNG, M_WAITOK | M_ZERO); |
500 501 mtx_lock(&isrc_table_lock); 502 if (intr_ddata_first_unused >= nitems(intr_ddata_tab)) { 503 mtx_unlock(&isrc_table_lock); 504 free(ddata, M_INTRNG); 505 return (NULL); 506 } 507 intr_ddata_tab[intr_ddata_first_unused] = ddata; 508 ddata->idd_irq = IRQ_DDATA_BASE + intr_ddata_first_unused++; 509 mtx_unlock(&isrc_table_lock); | 502 503 mtx_lock(&isrc_table_lock); 504 if (intr_ddata_first_unused >= nitems(intr_ddata_tab)) { 505 mtx_unlock(&isrc_table_lock); 506 free(ddata, M_INTRNG); 507 return (NULL); 508 } 509 intr_ddata_tab[intr_ddata_first_unused] = ddata; 510 ddata->idd_irq = IRQ_DDATA_BASE + intr_ddata_first_unused++; 511 mtx_unlock(&isrc_table_lock); |
512 513 ddata->idd_data = (struct intr_map_data *)((uintptr_t)ddata + size); 514 ddata->idd_data->size = size; |
|
510 return (ddata); 511} 512 513static struct intr_irqsrc * 514intr_ddata_lookup(u_int irq, struct intr_map_data **datap) 515{ 516 int error; 517 struct intr_irqsrc *isrc; --- 11 unchanged lines hidden (view full) --- 529 530 irq -= IRQ_DDATA_BASE; 531 if (irq >= nitems(intr_ddata_tab)) 532 return (NULL); 533 534 ddata = intr_ddata_tab[irq]; 535 if (ddata->idd_isrc == NULL) { 536 error = intr_map_irq(ddata->idd_dev, ddata->idd_xref, | 515 return (ddata); 516} 517 518static struct intr_irqsrc * 519intr_ddata_lookup(u_int irq, struct intr_map_data **datap) 520{ 521 int error; 522 struct intr_irqsrc *isrc; --- 11 unchanged lines hidden (view full) --- 534 535 irq -= IRQ_DDATA_BASE; 536 if (irq >= nitems(intr_ddata_tab)) 537 return (NULL); 538 539 ddata = intr_ddata_tab[irq]; 540 if (ddata->idd_isrc == NULL) { 541 error = intr_map_irq(ddata->idd_dev, ddata->idd_xref, |
537 &ddata->idd_data, &irq); | 542 ddata->idd_data, &irq); |
538 if (error != 0) 539 return (NULL); 540 ddata->idd_isrc = isrc_lookup(irq); 541 } 542 if (datap != NULL) | 543 if (error != 0) 544 return (NULL); 545 ddata->idd_isrc = isrc_lookup(irq); 546 } 547 if (datap != NULL) |
543 *datap = &ddata->idd_data; | 548 *datap = ddata->idd_data; |
544 return (ddata->idd_isrc); 545} 546 547#ifdef DEV_ACPI 548/* 549 * Map interrupt source according to ACPI info into framework. If such mapping 550 * does not exist, create it. Return unique interrupt number (resource handle) 551 * associated with mapped interrupt source. 552 */ 553u_int 554intr_acpi_map_irq(device_t dev, u_int irq, enum intr_polarity pol, 555 enum intr_trigger trig) 556{ | 549 return (ddata->idd_isrc); 550} 551 552#ifdef DEV_ACPI 553/* 554 * Map interrupt source according to ACPI info into framework. If such mapping 555 * does not exist, create it. Return unique interrupt number (resource handle) 556 * associated with mapped interrupt source. 557 */ 558u_int 559intr_acpi_map_irq(device_t dev, u_int irq, enum intr_polarity pol, 560 enum intr_trigger trig) 561{ |
562 struct intr_map_data_acpi *daa; |
|
557 struct intr_dev_data *ddata; 558 | 563 struct intr_dev_data *ddata; 564 |
559 ddata = intr_ddata_alloc(0); | 565 ddata = intr_ddata_alloc(sizeof(struct intr_map_data_acpi)); |
560 if (ddata == NULL) 561 return (INTR_IRQ_INVALID); /* no space left */ 562 563 ddata->idd_dev = dev; | 566 if (ddata == NULL) 567 return (INTR_IRQ_INVALID); /* no space left */ 568 569 ddata->idd_dev = dev; |
564 ddata->idd_data.type = INTR_MAP_DATA_ACPI; 565 ddata->idd_data.acpi.irq = irq; 566 ddata->idd_data.acpi.pol = pol; 567 ddata->idd_data.acpi.trig = trig; | 570 ddata->idd_data->type = INTR_MAP_DATA_ACPI; 571 572 daa = (struct intr_map_data_acpi *)ddata->idd_data; 573 daa->irq = irq; 574 daa->pol = pol; 575 daa->trig = trig; 576 |
568 return (ddata->idd_irq); 569} 570#endif 571#ifdef FDT 572/* 573 * Map interrupt source according to FDT data into framework. If such mapping 574 * does not exist, create it. Return unique interrupt number (resource handle) 575 * associated with mapped interrupt source. 576 */ 577u_int 578intr_fdt_map_irq(phandle_t node, pcell_t *cells, u_int ncells) 579{ | 577 return (ddata->idd_irq); 578} 579#endif 580#ifdef FDT 581/* 582 * Map interrupt source according to FDT data into framework. If such mapping 583 * does not exist, create it. Return unique interrupt number (resource handle) 584 * associated with mapped interrupt source. 585 */ 586u_int 587intr_fdt_map_irq(phandle_t node, pcell_t *cells, u_int ncells) 588{ |
589 size_t cellsize; |
|
580 struct intr_dev_data *ddata; | 590 struct intr_dev_data *ddata; |
581 u_int cellsize; | 591 struct intr_map_data_fdt *daf; |
582 583 cellsize = ncells * sizeof(*cells); | 592 593 cellsize = ncells * sizeof(*cells); |
584 ddata = intr_ddata_alloc(cellsize); | 594 ddata = intr_ddata_alloc(sizeof(struct intr_map_data_fdt) + cellsize); |
585 if (ddata == NULL) 586 return (INTR_IRQ_INVALID); /* no space left */ 587 588 ddata->idd_xref = (intptr_t)node; | 595 if (ddata == NULL) 596 return (INTR_IRQ_INVALID); /* no space left */ 597 598 ddata->idd_xref = (intptr_t)node; |
589 ddata->idd_data.type = INTR_MAP_DATA_FDT; 590 ddata->idd_data.fdt.ncells = ncells; 591 ddata->idd_data.fdt.cells = (pcell_t *)(ddata + 1); 592 memcpy(ddata->idd_data.fdt.cells, cells, cellsize); | 599 ddata->idd_data->type = INTR_MAP_DATA_FDT; 600 601 daf = (struct intr_map_data_fdt *)ddata->idd_data; 602 daf->ncells = ncells; 603 memcpy(daf->cells, cells, cellsize); |
593 return (ddata->idd_irq); 594} 595#endif 596 597/* 598 * Store GPIO interrupt decription in framework and return unique interrupt 599 * number (resource handle) associated with it. 600 */ 601u_int 602intr_gpio_map_irq(device_t dev, u_int pin_num, u_int pin_flags, u_int intr_mode) 603{ 604 struct intr_dev_data *ddata; | 604 return (ddata->idd_irq); 605} 606#endif 607 608/* 609 * Store GPIO interrupt decription in framework and return unique interrupt 610 * number (resource handle) associated with it. 611 */ 612u_int 613intr_gpio_map_irq(device_t dev, u_int pin_num, u_int pin_flags, u_int intr_mode) 614{ 615 struct intr_dev_data *ddata; |
616 struct intr_map_data_gpio *dag; |
|
605 | 617 |
606 ddata = intr_ddata_alloc(0); | 618 ddata = intr_ddata_alloc(sizeof(struct intr_map_data_gpio)); |
607 if (ddata == NULL) 608 return (INTR_IRQ_INVALID); /* no space left */ 609 610 ddata->idd_dev = dev; | 619 if (ddata == NULL) 620 return (INTR_IRQ_INVALID); /* no space left */ 621 622 ddata->idd_dev = dev; |
611 ddata->idd_data.type = INTR_MAP_DATA_GPIO; 612 ddata->idd_data.gpio.gpio_pin_num = pin_num; 613 ddata->idd_data.gpio.gpio_pin_flags = pin_flags; 614 ddata->idd_data.gpio.gpio_intr_mode = intr_mode; | 623 ddata->idd_data->type = INTR_MAP_DATA_GPIO; 624 625 dag = (struct intr_map_data_gpio *)ddata->idd_data; 626 dag->gpio_pin_num = pin_num; 627 dag->gpio_pin_flags = pin_flags; 628 dag->gpio_intr_mode = intr_mode; |
615 return (ddata->idd_irq); 616} 617 618#ifdef INTR_SOLO 619/* 620 * Setup filter into interrupt source. 621 */ 622static int --- 667 unchanged lines hidden --- | 629 return (ddata->idd_irq); 630} 631 632#ifdef INTR_SOLO 633/* 634 * Setup filter into interrupt source. 635 */ 636static int --- 667 unchanged lines hidden --- |