Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: qcgpio(4) X1E support based on ACPI tables
To:
Marcus Glocker <marcus@nazgul.ch>
Cc:
tech@openbsd.org
Date:
Sun, 22 Dec 2024 18:21:45 +0100

Download raw body.

Thread
  • Kirill A. Korinsky:

    qcgpio(4) X1E support based on ACPI tables

  • Mark Kettenis:

    qcgpio(4) X1E support based on ACPI tables

  • > Date: Sun, 22 Dec 2024 10:51:35 +0100
    > From: Marcus Glocker <marcus@nazgul.ch>
    > 
    > patrick@ found a NetBSD commit which figured out how to map the GPIO
    > pins based on the ACPI tables for X1E devices:
    > 
    > https://github.com/NetBSD/src/commit/575554bd388d93cfff9174abadf2aab93fbfdf8e
    > 
    > Currently we're only using hard coded mapping in qcgpio(4), which
    > might not do the correct mapping, or miss some mappings.
    > 
    > Following a diff which tries to adapt the NetBSD implementation in
    > qcpgio(4) for X1E devices.
    > 
    > Before I throw this diff in my attic, maybe some X1E users want to
    > regression test it, or see if it even fixes some GPIO mappings.
    > 
    > On my Samsung Galaxy Book4 Edge it causes no regression (keyboard and
    > touch-pad still work).  Unfortunately the touch-screen still doesn't
    > work.  I guess there is another issue with that.
    
    I think this is useful to have.  Tested this on my x13s (no change)
    and my vivobook (no change apart from debug output).
    
    ok kettenis@
    
    
    --- dmesg.acpi.before	Sun Dec 22 17:58:49 2024
    +++ dmesg.acpi.after	Sun Dec 22 18:16:37 2024
    @@ -1,5 +1,5 @@
    -OpenBSD 7.6-current (GENERIC.MP) #266: Fri Dec 20 22:58:05 MST 2024
    -    deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
    +OpenBSD 7.6-current (GENERIC.MP) #1: Sun Dec 22 18:14:20 CET 2024
    +    kettenis@massenet.sibelius.xs4all.nl:/home/kettenis/src/acpi/sys/arch/arm64/compile/GENERIC.MP
     real mem  = 16449925120 (15687MB)
     avail mem = 15806259200 (15074MB)
     random: good seed from bootblocks
    @@ -100,7 +100,131 @@ qciic0 at acpi0 I2C6 addr 0xb94000/0x4000
     iic0 at qciic0
     ### AML PARSE ERROR (0x3077d): Undefined name: OSYS
     error evaluating: \\_SB_.WMIT._STA
    -qcgpio0 at acpi0 GIO0 addr 0xf100000/0xf00000 irq 240
    +qcgpio0 at acpi0 GIO0 addr 0xf100000/0xf00000
    +qcgpio_acpi_attach: npdcmap=14
    +qcgpio_get_irqs: irq index 0: irq 240
    +qcgpio_get_irqs: irq index 1: irq 240
    +qcgpio_get_irqs: irq index 2: irq 240
    +qcgpio_get_irqs: irq index 3: irq 240
    +qcgpio_get_irqs: irq index 4: irq 598
    +qcgpio_get_irqs: irq index 5: irq 760
    +qcgpio_get_irqs: irq index 6: irq 595
    +qcgpio_get_irqs: irq index 7: irq 659
    +qcgpio_get_irqs: irq index 8: irq 602
    +qcgpio_get_irqs: irq index 9: irq 604
    +qcgpio_get_irqs: irq index 10: irq 645
    +qcgpio_get_irqs: irq index 11: irq 642
    +qcgpio_get_irqs: irq index 12: irq 649
    +qcgpio_get_irqs: irq index 13: irq 756
    +qcgpio_fill_pdcmap: pdc index 0: probing irq 655, pin 38
    +qcgpio_fill_pdcmap: pdc index 1: probing irq 654, pin 166
    +qcgpio_fill_pdcmap: pdc index 2: probing irq 653, pin 221
    +qcgpio_fill_pdcmap: pdc index 3: probing irq 652, pin 220
    +qcgpio_fill_pdcmap: pdc index 4: probing irq 651, pin 217
    +qcgpio_fill_pdcmap: pdc index 5: probing irq 650, pin 196
    +qcgpio_fill_pdcmap: pdc index 6: probing irq 649, pin 157
    +qcgpio_fill_pdcmap: pdc index 7: probing irq 648, pin 65
    +qcgpio_fill_pdcmap: pdc index 8: probing irq 647, pin 156
    +qcgpio_fill_pdcmap: pdc index 9: probing irq 646, pin 153
    +qcgpio_fill_pdcmap: pdc index 10: probing irq 645, pin 151
    +qcgpio_fill_pdcmap: pdc index 11: probing irq 644, pin 150
    +qcgpio_fill_pdcmap: pdc index 12: probing irq 643, pin 181
    +qcgpio_fill_pdcmap: pdc index 13: probing irq 642, pin 154
    +qcgpio_fill_pdcmap: pdc index 14: probing irq 641, pin 172
    +qcgpio_fill_pdcmap: pdc index 15: probing irq 605, pin 163
    +qcgpio_fill_pdcmap: pdc index 16: probing irq 604, pin 148
    +qcgpio_fill_pdcmap: pdc index 17: probing irq 603, pin 147
    +qcgpio_fill_pdcmap: pdc index 18: probing irq 602, pin 145
    +qcgpio_fill_pdcmap: pdc index 19: probing irq 601, pin 144
    +qcgpio_fill_pdcmap: pdc index 20: probing irq 600, pin 141
    +qcgpio_fill_pdcmap: pdc index 21: probing irq 599, pin 30
    +qcgpio_fill_pdcmap: pdc index 22: probing irq 598, pin 71
    +qcgpio_fill_pdcmap: pdc index 23: probing irq 597, pin 64
    +qcgpio_fill_pdcmap: pdc index 24: probing irq 596, pin 53
    +qcgpio_fill_pdcmap: pdc index 25: probing irq 595, pin 67
    +qcgpio_fill_pdcmap: pdc index 26: probing irq 594, pin 59
    +qcgpio_fill_pdcmap: pdc index 27: probing irq 593, pin 13
    +qcgpio_fill_pdcmap: pdc index 28: probing irq 592, pin 11
    +qcgpio_fill_pdcmap: pdc index 29: probing irq 591, pin 113
    +qcgpio_fill_pdcmap: pdc index 30: probing irq 590, pin 134
    +qcgpio_fill_pdcmap: pdc index 31: probing irq 589, pin 131
    +qcgpio_fill_pdcmap: pdc index 32: probing irq 588, pin 55
    +qcgpio_fill_pdcmap: pdc index 33: probing irq 587, pin 39
    +qcgpio_fill_pdcmap: pdc index 34: probing irq 586, pin 51
    +qcgpio_fill_pdcmap: pdc index 35: probing irq 585, pin 29
    +qcgpio_fill_pdcmap: pdc index 36: probing irq 584, pin 28
    +qcgpio_fill_pdcmap: pdc index 37: probing irq 583, pin 129
    +qcgpio_fill_pdcmap: pdc index 38: probing irq 582, pin 125
    +qcgpio_fill_pdcmap: pdc index 39: probing irq 581, pin 123
    +qcgpio_fill_pdcmap: pdc index 40: probing irq 580, pin 121
    +qcgpio_fill_pdcmap: pdc index 41: probing irq 579, pin 0
    +qcgpio_fill_pdcmap: pdc index 42: probing irq 578, pin 3
    +qcgpio_fill_pdcmap: pdc index 43: probing irq 577, pin 2
    +qcgpio_fill_pdcmap: pdc index 44: probing irq 576, pin 19
    +qcgpio_fill_pdcmap: pdc index 45: probing irq 575, pin 15
    +qcgpio_fill_pdcmap: pdc index 46: probing irq 574, pin 7
    +qcgpio_fill_pdcmap: pdc index 47: probing irq 850, pin 32
    +qcgpio_fill_pdcmap: pdc index 48: probing irq 849, pin 27
    +qcgpio_fill_pdcmap: pdc index 49: probing irq 848, pin 23
    +qcgpio_fill_pdcmap: pdc index 50: probing irq 760, pin 66
    +qcgpio_fill_pdcmap: pdc index 51: probing irq 759, pin 95
    +qcgpio_fill_pdcmap: pdc index 52: probing irq 758, pin 94
    +qcgpio_fill_pdcmap: pdc index 53: probing irq 757, pin 93
    +qcgpio_fill_pdcmap: pdc index 54: probing irq 756, pin 92
    +qcgpio_fill_pdcmap: pdc index 55: probing irq 755, pin 84
    +qcgpio_fill_pdcmap: pdc index 56: probing irq 754, pin 230
    +qcgpio_fill_pdcmap: pdc index 57: probing irq 753, pin 228
    +qcgpio_fill_pdcmap: pdc index 58: probing irq 752, pin 208
    +qcgpio_fill_pdcmap: pdc index 59: probing irq 751, pin 203
    +qcgpio_fill_pdcmap: pdc index 60: probing irq 750, pin 225
    +qcgpio_fill_pdcmap: pdc index 61: probing irq 749, pin 224
    +qcgpio_fill_pdcmap: pdc index 62: probing irq 672, pin 34
    +qcgpio_fill_pdcmap: pdc index 63: probing irq 671, pin 26
    +qcgpio_fill_pdcmap: pdc index 64: probing irq 670, pin 81
    +qcgpio_fill_pdcmap: pdc index 65: probing irq 668, pin 24
    +qcgpio_fill_pdcmap: pdc index 66: probing irq 667, pin 80
    +qcgpio_fill_pdcmap: pdc index 67: probing irq 666, pin 222
    +qcgpio_fill_pdcmap: pdc index 68: probing irq 665, pin 6
    +qcgpio_fill_pdcmap: pdc index 69: probing irq 664, pin 18
    +qcgpio_fill_pdcmap: pdc index 70: probing irq 663, pin 214
    +qcgpio_fill_pdcmap: pdc index 71: probing irq 662, pin 212
    +qcgpio_fill_pdcmap: pdc index 72: probing irq 661, pin 219
    +qcgpio_fill_pdcmap: pdc index 73: probing irq 660, pin 215
    +qcgpio_fill_pdcmap: pdc index 74: probing irq 659, pin 193
    +qcgpio_fill_pdcmap: pdc index 75: probing irq 658, pin 184
    +qcgpio_fill_pdcmap: pdc index 76: probing irq 657, pin 33
    +qcgpio_fill_pdcmap: pdc index 77: probing irq 656, pin 175
    +qcgpio_fill_pdcmap: pdc index 78: probing irq 862, pin 91
    +qcgpio_fill_pdcmap: pdc index 79: probing irq 861, pin 87
    +qcgpio_fill_pdcmap: pdc index 80: probing irq 860, pin 85
    +qcgpio_fill_pdcmap: pdc index 81: probing irq 859, pin 83
    +qcgpio_fill_pdcmap: pdc index 82: probing irq 858, pin 79
    +qcgpio_fill_pdcmap: pdc index 83: probing irq 857, pin 75
    +qcgpio_fill_pdcmap: pdc index 84: probing irq 856, pin 68
    +qcgpio_fill_pdcmap: pdc index 85: probing irq 855, pin 213
    +qcgpio_fill_pdcmap: pdc index 86: probing irq 854, pin 47
    +qcgpio_fill_pdcmap: pdc index 87: probing irq 853, pin 43
    +qcgpio_fill_pdcmap: pdc index 88: probing irq 852, pin 36
    +qcgpio_fill_pdcmap: pdc index 89: probing irq 851, pin 35
    +qcgpio_fill_pdcmap: pdc index 90: probing irq 867, pin 232
    +qcgpio_fill_pdcmap: pdc index 91: probing irq 864, pin 31
    +qcgpio_fill_pdcmap: pdc index 92: probing irq 863, pin 21
    +qcgpio_fill_pdcmap: irq index 0: irq=240, pin=-1
    +qcgpio_fill_pdcmap: irq index 1: irq=240, pin=-1
    +qcgpio_fill_pdcmap: irq index 2: irq=240, pin=-1
    +qcgpio_fill_pdcmap: irq index 3: irq=240, pin=-1
    +qcgpio_fill_pdcmap: irq index 4: irq=598, pin=71
    +qcgpio_fill_pdcmap: irq index 5: irq=760, pin=66
    +qcgpio_fill_pdcmap: irq index 6: irq=595, pin=67
    +qcgpio_fill_pdcmap: irq index 7: irq=659, pin=193
    +qcgpio_fill_pdcmap: irq index 8: irq=602, pin=145
    +qcgpio_fill_pdcmap: irq index 9: irq=604, pin=148
    +qcgpio_fill_pdcmap: irq index 10: irq=645, pin=151
    +qcgpio_fill_pdcmap: irq index 11: irq=642, pin=154
    +qcgpio_fill_pdcmap: irq index 12: irq=649, pin=157
    +qcgpio_fill_pdcmap: irq index 13: irq=756, pin=92
    +qcgpio_acpi_attach: npins=238
    + irq 240
     ihidev0 at iic0 addr 0x3a gpio 384, vendor 0xb05 product 0x4543, QTEC0001
     ihidev0: 90 report ids
     hid at ihidev0 reportid 6 not configured
    
    
    > 
    > 
    > Index: sys/dev/acpi/qcgpio.c
    > ===================================================================
    > RCS file: /cvs/src/sys/dev/acpi/qcgpio.c,v
    > diff -u -p -u -p -r1.11 qcgpio.c
    > --- sys/dev/acpi/qcgpio.c	15 Jul 2024 15:33:54 -0000	1.11
    > +++ sys/dev/acpi/qcgpio.c	15 Dec 2024 19:03:25 -0000
    > @@ -25,6 +25,14 @@
    >  #include <dev/acpi/amltypes.h>
    >  #include <dev/acpi/dsdt.h>
    >  
    > +#define QCGPIO_DEBUG
    > +#ifdef QCGPIO_DEBUG
    > +int qcgpio_debug = 1;
    > +#define DPRINTF(l, x...) do { if ((l) <= qcgpio_debug) printf(x); } while (0)
    > +#else
    > +#define DPRINTF(l, x...)
    > +#endif
    > +
    >  /* Registers. */
    >  #define TLMM_GPIO_IN_OUT(pin)		(0x0004 + 0x1000 * (pin))
    >  #define  TLMM_GPIO_IN_OUT_GPIO_IN			(1 << 0)
    > @@ -62,6 +70,11 @@ struct qcgpio_intrhand {
    >  	void *ih_arg;
    >  };
    >  
    > +struct qcgpio_pdcmap {
    > +	int		pm_pin;
    > +	uint32_t	pm_irq;
    > +};
    > +
    >  struct qcgpio_softc {
    >  	struct device		sc_dev;
    >  	struct acpi_softc	*sc_acpi;
    > @@ -73,10 +86,15 @@ struct qcgpio_softc {
    >  	void			*sc_ih;
    >  
    >  	uint32_t		sc_npins;
    > -	int			(*sc_pin_map)(int, bus_size_t *);
    > +	int			(*sc_pin_map)(struct qcgpio_softc *, int,
    > +				    bus_size_t *);
    >  	struct qcgpio_intrhand	*sc_pin_ih;
    >  
    >  	struct acpi_gpio sc_gpio;
    > +
    > +	struct qcgpio_pdcmap	*sc_pdcmap;
    > +	uint32_t		 sc_npdcmap;
    > +	uint32_t		 sc_ipdcmap;
    >  };
    >  
    >  int	qcgpio_acpi_match(struct device *, void *, void *);
    > @@ -97,9 +115,29 @@ const char *qcgpio_hids[] = {
    >  	NULL
    >  };
    >  
    > -int	qcgpio_sc7180_pin_map(int, bus_size_t *);
    > -int	qcgpio_sc8280xp_pin_map(int, bus_size_t *);
    > -int	qcgpio_x1e80100_pin_map(int, bus_size_t *);
    > +/* 98b9b2a4-1663-4a5f-82f2-c6c99a394726 */
    > +static uint8_t qcgpio_gpio_dsm_uuid[] = {
    > +	0xa4, 0xb2, 0xb9, 0x98, 0x63, 0x16, 0x5f, 0x4a,
    > +	0x82, 0xf2, 0xc6, 0xc9, 0x9a, 0x39, 0x47, 0x26
    > +};
    > +#define QCGPIO_GPIO_DSM_REV		0
    > +#define QCGPIO_GPIO_DSM_FUNC_NUM_PINS	2
    > +
    > +/* 921b0fd4-567c-43a0-bb14-2648f7b2a18c */
    > +static uint8_t qcgpio_pdc_dsm_uuid[] = {
    > +	0xd4, 0x0f, 0x1b, 0x92, 0x7c, 0x56, 0xa0, 0x43,
    > +	0xbb, 0x14, 0x26, 0x48, 0xf7, 0xb2, 0xa1, 0x8c
    > +};
    > +#define QCGPIO_PDC_DSM_REV		0
    > +#define QCGPIO_PDC_DSM_FUNC_CIPR	2
    > +
    > +int	qcgpio_get_nirq(int, union acpi_resource *, void *);
    > +int	qcgpio_get_irqs(int, union acpi_resource *, void *);
    > +void	qcgpio_fill_pdcmap(struct qcgpio_softc *);
    > +int	qcgpio_get_pin_count(struct acpi_softc *, struct aml_node *);
    > +int	qcgpio_sc7180_pin_map(struct qcgpio_softc *, int, bus_size_t *);
    > +int	qcgpio_sc8280xp_pin_map(struct qcgpio_softc *, int, bus_size_t *);
    > +int	qcgpio_x1e80100_pin_map(struct qcgpio_softc *, int, bus_size_t *);
    >  
    >  int	qcgpio_read_pin(void *, int);
    >  void	qcgpio_write_pin(void *, int, int);
    > @@ -109,6 +147,137 @@ void	qcgpio_intr_disable(void *, int);
    >  int	qcgpio_intr(void *);
    >  
    >  int
    > +qcgpio_get_nirq(int crsidx, union acpi_resource *crs, void *arg)
    > +{
    > +	struct qcgpio_softc *sc = arg;
    > +	int typ;
    > +
    > +	typ = AML_CRSTYPE(crs);
    > +
    > +	switch (typ) {
    > +	case LR_EXTIRQ:
    > +		sc->sc_npdcmap++;
    > +		break;
    > +	}
    > +
    > +	return 0;
    > +}
    > +
    > +int
    > +qcgpio_get_irqs(int crsidx, union acpi_resource *crs, void *arg)
    > +{
    > +	struct qcgpio_softc *sc = arg;
    > +	int typ;
    > +
    > +	typ = AML_CRSTYPE(crs);
    > +
    > +	switch (typ) {
    > +	case LR_EXTIRQ:
    > +		sc->sc_pdcmap[sc->sc_ipdcmap].pm_irq = crs->lr_extirq.irq[0];
    > +		sc->sc_pdcmap[sc->sc_ipdcmap].pm_pin = -1;
    > +		DPRINTF(1, "%s: irq index %d: irq %d\n",
    > +		    __func__, sc->sc_ipdcmap,
    > +		    sc->sc_pdcmap[sc->sc_ipdcmap].pm_irq);
    > +		sc->sc_ipdcmap++;
    > +		break;
    > +	}
    > +
    > +	return 0;
    > +}
    > +
    > +void
    > +qcgpio_fill_pdcmap(struct qcgpio_softc *sc)
    > +{
    > +	struct aml_value cmd[4], res, *ref;
    > +	int i, j, pin;
    > +	uint32_t irq;
    > +
    > +	bzero(&cmd, sizeof(cmd));
    > +	cmd[0].type = AML_OBJTYPE_BUFFER;
    > +	cmd[0].v_buffer = (uint8_t *)&qcgpio_pdc_dsm_uuid;
    > +	cmd[0].length = sizeof(qcgpio_pdc_dsm_uuid);
    > +	/* rev */
    > +	cmd[1].type = AML_OBJTYPE_INTEGER;
    > +	cmd[1].v_integer = QCGPIO_PDC_DSM_REV;
    > +	cmd[1].length = 1;
    > +	/* func */
    > +	cmd[2].type = AML_OBJTYPE_INTEGER;
    > +	cmd[2].v_integer = QCGPIO_PDC_DSM_FUNC_CIPR;
    > +	cmd[2].length = 1;
    > +	/* not used */
    > +	cmd[3].type = AML_OBJTYPE_PACKAGE;
    > +	cmd[3].v_integer = 0;
    > +	cmd[3].length = 0;
    > +
    > +	if (aml_evalname(sc->sc_acpi, sc->sc_node, "_DSM", 4, cmd, &res)) {
    > +		printf("%s: PDC _DSM failed\n", __func__);
    > +		return;
    > +	}
    > +
    > +	for (i = 0; i < res.length; i++) {
    > +		ref = res.v_package[i];
    > +
    > +		if (ref->type != AML_OBJTYPE_PACKAGE ||
    > +		    ref->length < 3 ||
    > +		    ref->v_package[0]->type != AML_OBJTYPE_INTEGER ||
    > +		    ref->v_package[1]->type != AML_OBJTYPE_INTEGER ||
    > +		    ref->v_package[2]->type != AML_OBJTYPE_INTEGER) {
    > +			continue;
    > +		}
    > +
    > +		irq = ref->v_package[2]->v_integer;
    > +		pin = ref->v_package[1]->v_integer;
    > +		DPRINTF(1, "%s: pdc index %d: probing irq %d, pin %d\n",
    > +		    __func__, i, irq, pin);
    > +
    > +		for (j = 0; j < sc->sc_npdcmap; j++) {
    > +			if (sc->sc_pdcmap[j].pm_irq == irq) {
    > +				sc->sc_pdcmap[j].pm_pin = pin;
    > +				break;
    > +			}
    > +		}
    > +	}
    > +#ifdef QCGPIO_DEBUG
    > +	for (i = 0; i < sc->sc_npdcmap; i++) {
    > +		printf("%s: irq index %d: irq=%d, pin=%d\n",
    > +		    __func__, i, sc->sc_pdcmap[i].pm_irq,
    > +		    sc->sc_pdcmap[i].pm_pin);
    > +	}
    > +#endif
    > +}
    > +
    > +int
    > +qcgpio_get_pin_count(struct acpi_softc *sc, struct aml_node *node)
    > +{
    > +	struct aml_value cmd[4];
    > +	int64_t npins;
    > +
    > +	bzero(&cmd, sizeof(cmd));
    > +	cmd[0].type = AML_OBJTYPE_BUFFER;
    > +	cmd[0].v_buffer = (uint8_t *)&qcgpio_gpio_dsm_uuid;
    > +	cmd[0].length = sizeof(qcgpio_gpio_dsm_uuid);
    > +	/* rev */
    > +	cmd[1].type = AML_OBJTYPE_INTEGER;
    > +	cmd[1].v_integer = QCGPIO_GPIO_DSM_REV;
    > +	cmd[1].length = 1;
    > +	/* func */
    > +	cmd[2].type = AML_OBJTYPE_INTEGER;
    > +	cmd[2].v_integer = QCGPIO_GPIO_DSM_FUNC_NUM_PINS;
    > +	cmd[2].length = 1;
    > +	/* not used */
    > +	cmd[3].type = AML_OBJTYPE_PACKAGE;
    > +	cmd[3].v_integer = 0;
    > +	cmd[3].length = 0;
    > +
    > +	if (aml_evalinteger(sc, node, "_DSM", 4, cmd, &npins)) {
    > +		printf("%s: GPIO _DSM  failed\n", __func__);
    > +		return 0;
    > +	}
    > +
    > +	return (uint32_t)npins;
    > +}
    > +
    > +int
    >  qcgpio_acpi_match(struct device *parent, void *match, void *aux)
    >  {
    >  	struct acpi_attach_args *aaa = aux;
    > @@ -124,6 +293,7 @@ qcgpio_acpi_attach(struct device *parent
    >  {
    >  	struct acpi_attach_args *aaa = aux;
    >  	struct qcgpio_softc *sc = (struct qcgpio_softc *)self;
    > +	struct aml_value res;
    >  
    >  	sc->sc_acpi = (struct acpi_softc *)parent;
    >  	sc->sc_node = aaa->aaa_node;
    > @@ -145,7 +315,25 @@ qcgpio_acpi_attach(struct device *parent
    >  		sc->sc_npins = 228;
    >  		sc->sc_pin_map = qcgpio_sc8280xp_pin_map;
    >  	} else if (strcmp(aaa->aaa_dev, "QCOM0C0C") == 0) {
    > -		sc->sc_npins = 239;
    > +		if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL,
    > +		    &res)) {
    > +			printf("no _CRS method\n");
    > +			return;
    > +		}
    > +		if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
    > +			printf("invalid _CRS object\n");
    > +			aml_freevalue(&res);
    > +			return;
    > +		}
    > +		aml_parse_resource(&res, qcgpio_get_nirq, sc);
    > +		DPRINTF(1, "\n%s: npdcmap=%d\n", __func__, sc->sc_npdcmap);
    > +		sc->sc_pdcmap = mallocarray(sc->sc_npdcmap,
    > +		    sizeof(*sc->sc_pdcmap), M_DEVBUF, M_WAITOK | M_ZERO);
    > +		aml_parse_resource(&res, qcgpio_get_irqs, sc);
    > +		aml_freevalue(&res);
    > +		qcgpio_fill_pdcmap(sc);
    > +		sc->sc_npins = qcgpio_get_pin_count(sc->sc_acpi, sc->sc_node);
    > +		DPRINTF(1, "%s: npins=%d\n", __func__, sc->sc_npins);
    >  		sc->sc_pin_map = qcgpio_x1e80100_pin_map;
    >  	}
    >  	KASSERT(sc->sc_npins != 0);
    > @@ -180,11 +368,12 @@ unmap:
    >  	if (sc->sc_ih)
    >  		acpi_intr_disestablish(sc->sc_ih);
    >  	free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
    > +	free(sc->sc_pdcmap, M_DEVBUF, sc->sc_npdcmap * sizeof(*sc->sc_pdcmap));
    >  	bus_space_unmap(sc->sc_iot, sc->sc_ioh, aaa->aaa_size[0]);
    >  }
    >  
    >  int
    > -qcgpio_sc7180_pin_map(int pin, bus_size_t *off)
    > +qcgpio_sc7180_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
    >  {
    >  	switch (pin) {
    >  	case 30:
    > @@ -211,7 +400,7 @@ qcgpio_sc7180_pin_map(int pin, bus_size_
    >  }
    >  
    >  int
    > -qcgpio_sc8280xp_pin_map(int pin, bus_size_t *off)
    > +qcgpio_sc8280xp_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
    >  {
    >  	switch (pin) {
    >  	case 107:
    > @@ -229,21 +418,19 @@ qcgpio_sc8280xp_pin_map(int pin, bus_siz
    >  }
    >  
    >  int
    > -qcgpio_x1e80100_pin_map(int pin, bus_size_t *off)
    > +qcgpio_x1e80100_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
    >  {
    > -	switch (pin) {
    > -	case 3:
    > -	case 51:
    > -		return pin;
    > -	case 0x180:
    > -		return 67;
    > -	case 0x380:
    > -		return 33;
    > -	case 0x3c0:
    > -		return 3;
    > -	default:
    > -		return -1;
    > +	int real_pin = -1;
    > +
    > +	if (pin < sc->sc_npins) {
    > +		real_pin = pin;
    > +	} else if (pin / 64 < sc->sc_npdcmap) {
    > +		real_pin = sc->sc_pdcmap[pin / 64].pm_pin;
    >  	}
    > +
    > +	DPRINTF(2, "%s: map pin %d to real_pin %d\n", __func__, pin, real_pin);
    > +
    > +	return real_pin;
    >  }
    >  
    >  int
    > @@ -253,7 +440,7 @@ qcgpio_read_pin(void *cookie, int pin)
    >  	bus_size_t off = 0;
    >  	uint32_t reg;
    >  
    > -	pin = sc->sc_pin_map(pin, &off);
    > +	pin = sc->sc_pin_map(sc, pin, &off);
    >  	if (pin < 0 || pin >= sc->sc_npins)
    >  		return 0;
    >  
    > @@ -267,7 +454,7 @@ qcgpio_write_pin(void *cookie, int pin, 
    >  	struct qcgpio_softc *sc = cookie;
    >  	bus_size_t off = 0;
    >  
    > -	pin = sc->sc_pin_map(pin, &off);
    > +	pin = sc->sc_pin_map(sc, pin, &off);
    >  	if (pin < 0 || pin >= sc->sc_npins)
    >  		return;
    >  
    > @@ -288,7 +475,7 @@ qcgpio_intr_establish(void *cookie, int 
    >  	bus_size_t off = 0;
    >  	uint32_t reg;
    >  
    > -	pin = sc->sc_pin_map(pin, &off);
    > +	pin = sc->sc_pin_map(sc, pin, &off);
    >  	if (pin < 0 || pin >= sc->sc_npins)
    >  		return;
    >  
    > @@ -335,7 +522,7 @@ qcgpio_intr_enable(void *cookie, int pin
    >  	struct qcgpio_softc *sc = cookie;
    >  	bus_size_t off = 0;
    >  
    > -	pin = sc->sc_pin_map(pin, &off);
    > +	pin = sc->sc_pin_map(sc, pin, &off);
    >  	if (pin < 0 || pin >= sc->sc_npins)
    >  		return;
    >  
    > @@ -349,7 +536,7 @@ qcgpio_intr_disable(void *cookie, int pi
    >  	struct qcgpio_softc *sc = cookie;
    >  	bus_size_t off = 0;
    >  
    > -	pin = sc->sc_pin_map(pin, &off);
    > +	pin = sc->sc_pin_map(sc, pin, &off);
    >  	if (pin < 0 || pin >= sc->sc_npins)
    >  		return;
    >  
    > @@ -369,7 +556,7 @@ qcgpio_intr(void *arg)
    >  		if (sc->sc_pin_ih[pin].ih_func == NULL)
    >  			continue;
    >  
    > -		sc->sc_pin_map(pin, &off);
    > +		sc->sc_pin_map(sc, pin, &off);
    >  
    >  		stat = HREAD4(sc, off + TLMM_GPIO_INTR_STATUS(pin));
    >  		if (stat & TLMM_GPIO_INTR_STATUS_INTR_STATUS) {
    > 
    > 
    
    
    
  • Kirill A. Korinsky:

    qcgpio(4) X1E support based on ACPI tables

  • Mark Kettenis:

    qcgpio(4) X1E support based on ACPI tables