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 ---