Subject: Re: Which is the read interface to GPIO?
To: None <garrett_damore@tadpole.com>
From: KIYOHARA Takashi <kiyohara@kk.iij4u.or.jp>
List: port-evbmips
Date: 03/24/2006 09:53:35
----Next_Part(Fri_Mar_24_09:53:35_2006_814)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi! Garrett,
The reply apologizes ..slowly... ;-<
From: "Garrett D'Amore" <garrett_damore@tadpole.com>
Date: Tue, 21 Mar 2006 21:53:22 -0800
> The reason for this is that there are "ordering constraints" otherwise
> -- how do you augpio has attached before aupcmcia? This is something
> that I think autoconf lacks support for expressing (at least where the
> dependency is not implied as a result of child-parent relationship.)
Is it a problem in the following methods? For instance, it can fake attach
it earlier more temporarily than augpio. Please call augpio_attach_fake()
if you operate augpio earlier than attach of augpio.
The prototype of the function is assumed to put it in a suitable header
file.
Thanks,
--
kiyohara
----Next_Part(Fri_Mar_24_09:53:35_2006_814)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="augpio.c.diff"
Index: dev/augpio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/augpio.c,v
retrieving revision 1.3
diff -u -r1.3 augpio.c
--- dev/augpio.c 18 Feb 2006 23:21:06 -0000 1.3
+++ dev/augpio.c 24 Mar 2006 00:30:56 -0000
@@ -41,6 +41,7 @@
#include <sys/device.h>
#include <sys/gpio.h>
#include <sys/kernel.h>
+#include <sys/malloc.h>
#include <dev/gpio/gpiovar.h>
@@ -62,6 +63,11 @@
const char *sc_name;
int (*sc_getctl)(void *, int);
};
+enum {
+ primary = 0,
+ secondary = 1,
+ ngpio = 2
+};
static int augpio_read(void *, int);
static void augpio_write(void *, int, int);
@@ -73,6 +79,12 @@
static void augpio2_ctl(void *, int, int);
static int augpio2_getctl(void *, int);
+int augpio_attach_fake(int);
+int augpioread(int, int);
+void augpiowrite(int, int, int);
+int augpiogetctl(int, int);
+void augpioctl(int, int, int);
+
static int augpio_match(struct device *, struct cfdata *, void *);
static void augpio_attach(struct device *, struct device *, void *);
@@ -85,6 +97,7 @@
((*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(x)) = (v))
static int augpio_found = 0;
+static struct augpio_softc *softces[ngpio];
int
augpio_match(struct device *parent, struct cfdata *match, void *aux)
@@ -105,7 +118,7 @@
{
int pin;
- struct augpio_softc *sc = (struct augpio_softc *)self;
+ struct augpio_softc *sc = (struct augpio_softc *)self, *fakesc;
struct aubus_attach_args *aa = aux;
struct gpiobus_attach_args gba;
@@ -114,6 +127,12 @@
sc->sc_gc.gp_cookie = sc;
if (aa->aa_addrs[0] == GPIO_BASE) {
+ if (softces[primary] != NULL) {
+ fakesc = softces[primary];
+ bus_space_unmap(fakesc->sc_bst,
+ fakesc->sc_bsh, AUGPIO_SIZE);
+ free(fakesc, M_TEMP);
+ }
if (bus_space_map(sc->sc_bst, aa->aa_addrs[0],
AUGPIO_SIZE, 0, &sc->sc_bsh) != 0) {
@@ -128,6 +147,7 @@
sc->sc_getctl = augpio_getctl;
sc->sc_name = "primary block";
+ softces[primary] = sc;
} else if (aa->aa_addrs[0] == GPIO2_BASE) {
/*
* We rely on firmware (or platform init code) to initialize
@@ -135,6 +155,12 @@
* resetting the GPIO2 block can have nasty effects (e.g.
* reset PCI bus...)
*/
+ if (softces[secondary] != NULL) {
+ fakesc = softces[secondary];
+ bus_space_unmap(fakesc->sc_bst,
+ fakesc->sc_bsh, AUGPIO2_SIZE);
+ free(fakesc, M_TEMP);
+ }
if (bus_space_map(sc->sc_bst, aa->aa_addrs[0],
AUGPIO2_SIZE, 0, &sc->sc_bsh) != 0) {
printf(": cannot map registers!\n");
@@ -147,6 +173,7 @@
sc->sc_getctl = augpio2_getctl;
sc->sc_name = "secondary block";
+ softces[secondary] = sc;
} else {
printf(": unidentified block\n");
return;
@@ -287,3 +314,71 @@
}
}
+int
+augpio_attach_fake(int gpio)
+{
+ struct augpio_softc *fakesc;
+ bus_addr_t address;
+ bus_size_t size;
+
+ if (softces[gpio] == NULL)
+ return 0;
+
+ fakesc = malloc(sizeof (struct augpio_softc), M_TEMP, M_NOWAIT);
+ fakesc->sc_bst = aubus_st;
+ if (gpio == primary) {
+ fakesc->sc_gc.gp_pin_read = augpio_read;
+ fakesc->sc_gc.gp_pin_write = augpio_write;
+ fakesc->sc_gc.gp_pin_ctl = augpio_ctl;
+ fakesc->sc_getctl = augpio_getctl;
+ address = GPIO_BASE;
+ size = AUGPIO_SIZE;
+ } else if (gpio == secondary) {
+ fakesc->sc_gc.gp_pin_read = augpio2_read;
+ fakesc->sc_gc.gp_pin_write = augpio2_write;
+ fakesc->sc_gc.gp_pin_ctl = augpio2_ctl;
+ fakesc->sc_getctl = augpio2_getctl;
+ address = GPIO2_BASE;
+ size = AUGPIO2_SIZE;
+ } else
+ return ~0;
+
+ if (bus_space_map(fakesc->sc_bst,
+ address, size, 0, &fakesc->sc_bsh) != 0)
+ return ~0;
+ softces[gpio] = fakesc;
+
+ return 0;
+}
+
+int
+augpioread(int gpio, int pin)
+{
+
+ KASSERT(softces[gpio] != NULL);
+ return softces[gpio]->sc_gc.gp_pin_read(softces[gpio], pin);
+}
+
+void
+augpiowrite(int gpio, int pin, int value)
+{
+
+ KASSERT(softces[gpio] != NULL);
+ return softces[gpio]->sc_gc.gp_pin_write(softces[gpio], pin, value);
+}
+
+void
+augpioctl(int gpio, int pin, int flags)
+{
+
+ KASSERT(softces[gpio] != NULL);
+ return softces[gpio]->sc_gc.gp_pin_ctl(softces[gpio], pin, flags);
+}
+
+int
+augpiogetctl(int gpio, int pin)
+{
+
+ KASSERT(softces[gpio] != NULL);
+ return softces[gpio]->sc_getctl(softces[gpio], pin);
+}
----Next_Part(Fri_Mar_24_09:53:35_2006_814)----