Skip to content

Commit 186100f

Browse files
committed
gpio: make gpioc a child of gpiobus
With gpioc being a direct child of the GPIO controller, it can't allocate interrupts properly. It currently allocates interrupts using it's parent dev (gpioX). This causes problems since the call never goes through gpiobus. Instead, make gpioc a child of gpiobus and allocate interrupts using our own dev. Also don't misuse pin->flags, it's not meant to store the flags from sys/gpio.h Reported by: Evgenii Ivanov <[email protected]> Reviewed by: mmel Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D51932
1 parent 4fd32b1 commit 186100f

File tree

4 files changed

+118
-70
lines changed

4 files changed

+118
-70
lines changed

sys/dev/gpio/gpiobus.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,6 @@ gpiobus_add_bus(device_t dev)
319319
busdev = device_add_child(dev, "gpiobus", DEVICE_UNIT_ANY);
320320
if (busdev == NULL)
321321
return (NULL);
322-
if (device_add_child(dev, "gpioc", DEVICE_UNIT_ANY) == NULL) {
323-
device_delete_child(dev, busdev);
324-
return (NULL);
325-
}
326322
#ifdef FDT
327323
ofw_gpiobus_register_provider(dev);
328324
#endif
@@ -371,6 +367,37 @@ gpiobus_init_softc(device_t dev)
371367
return (0);
372368
}
373369

370+
int
371+
gpiobus_add_gpioc(device_t dev)
372+
{
373+
struct gpiobus_ivar *devi;
374+
struct gpiobus_softc *sc;
375+
device_t gpioc;
376+
int err;
377+
378+
gpioc = BUS_ADD_CHILD(dev, 0, "gpioc", DEVICE_UNIT_ANY);
379+
if (gpioc == NULL)
380+
return (ENXIO);
381+
382+
sc = device_get_softc(dev);
383+
devi = device_get_ivars(gpioc);
384+
385+
devi->npins = sc->sc_npins;
386+
err = gpiobus_alloc_ivars(devi);
387+
if (err != 0) {
388+
device_delete_child(dev, gpioc);
389+
return (err);
390+
}
391+
392+
err = GPIO_GET_PIN_LIST(sc->sc_dev, devi->pins);
393+
if (err != 0) {
394+
device_delete_child(dev, gpioc);
395+
gpiobus_free_ivars(devi);
396+
}
397+
398+
return (err);
399+
}
400+
374401
int
375402
gpiobus_alloc_ivars(struct gpiobus_ivar *devi)
376403
{
@@ -562,6 +589,10 @@ gpiobus_attach(device_t dev)
562589
if (err != 0)
563590
return (err);
564591

592+
err = gpiobus_add_gpioc(dev);
593+
if (err != 0)
594+
return (err);
595+
565596
/*
566597
* Get parent's pins and mark them as unmapped
567598
*/

sys/dev/gpio/gpiobus_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ int gpiobus_acquire_pin(device_t, uint32_t);
4444
void gpiobus_release_pin(device_t, uint32_t);
4545
int gpiobus_child_location(device_t, device_t, struct sbuf *);
4646
device_t gpiobus_add_child_common(device_t, u_int, const char *, int, size_t);
47+
int gpiobus_add_gpioc(device_t);
4748

4849
extern driver_t gpiobus_driver;
4950
#endif

0 commit comments

Comments
 (0)