summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/loongson/conf/GENERIC3
-rw-r--r--sys/arch/loongson/conf/files.loongson6
-rw-r--r--sys/arch/loongson/dev/glxclk.c396
-rw-r--r--sys/arch/loongson/dev/mainbus.c8
-rw-r--r--sys/arch/loongson/loongson/machdep.c7
-rw-r--r--sys/arch/loongson/loongson/yeeloong_machdep.c11
-rw-r--r--sys/arch/mips64/mips64/mips64_machdep.c5
-rw-r--r--sys/dev/pci/files.pci4
-rw-r--r--sys/dev/pci/glxpcib.c49
-rw-r--r--sys/dev/pci/glxvar.h10
10 files changed, 483 insertions, 16 deletions
diff --git a/sys/arch/loongson/conf/GENERIC b/sys/arch/loongson/conf/GENERIC
index 4a959035546..7b3e943d238 100644
--- a/sys/arch/loongson/conf/GENERIC
+++ b/sys/arch/loongson/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.37 2012/09/27 14:01:35 jsg Exp $
+# $OpenBSD: GENERIC,v 1.38 2013/01/14 21:18:47 pirofti Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -40,6 +40,7 @@ pci* at bonito?
glxpcib* at pci?
gpio* at glxpcib?
isa0 at glxpcib?
+glxclk* at glxpcib?
mcclock0 at isa? port 0x70
pckbc0 at isa? # Yeeloong only
pckbd* at pckbc? # Yeeloong only
diff --git a/sys/arch/loongson/conf/files.loongson b/sys/arch/loongson/conf/files.loongson
index 12844557fae..6b9a3dfa95c 100644
--- a/sys/arch/loongson/conf/files.loongson
+++ b/sys/arch/loongson/conf/files.loongson
@@ -1,4 +1,4 @@
-# $OpenBSD: files.loongson,v 1.13 2010/10/14 21:23:04 pirofti Exp $
+# $OpenBSD: files.loongson,v 1.14 2013/01/14 21:18:47 pirofti Exp $
# Standard stanzas config(8) can't run without
maxpartitions 16
@@ -119,3 +119,7 @@ file arch/loongson/dev/sisfb.c sisfb needs-flag
device apm
attach apm at mainbus
file arch/loongson/dev/apm.c apm needs-flag
+
+device glxclk
+attach glxclk at glxpcib
+file arch/loongson/dev/glxclk.c glxclk
diff --git a/sys/arch/loongson/dev/glxclk.c b/sys/arch/loongson/dev/glxclk.c
new file mode 100644
index 00000000000..a8c1a19f271
--- /dev/null
+++ b/sys/arch/loongson/dev/glxclk.c
@@ -0,0 +1,396 @@
+/* $OpenBSD: glxclk.c,v 1.1 2013/01/14 21:18:47 pirofti Exp $ */
+
+/*
+ * Copyright (c) 2013 Paul Irofti.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+
+#include <machine/bus.h>
+#include <machine/autoconf.h>
+
+#include <dev/isa/isavar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/glxreg.h>
+#include <dev/pci/glxvar.h>
+
+struct glxclk_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+};
+
+struct cfdriver glxclk_cd = {
+ NULL, "glxclk", DV_DULL
+};
+
+int glxclk_match(struct device *, void *, void *);
+void glxclk_attach(struct device *, struct device *, void *);
+int glxclk_intr(void *);
+void glxclk_startclock(struct cpu_info *);
+
+struct cfattach glxclk_ca = {
+ sizeof(struct glxclk_softc), glxclk_match, glxclk_attach,
+};
+
+#define MSR_LBAR_ENABLE 0x100000000ULL
+#define MSR_LBAR_MFGPT DIVIL_LBAR_MFGPT
+#define MSR_MFGPT_SIZE 0x40
+#define MSR_MFGPT_ADDR_MASK 0xffc0
+
+#define AMD5536_MFGPT1_CMP2 0x0000000a /* Compare value for CMP2 */
+#define AMD5536_MFGPT1_CNT 0x0000000c /* Up counter */
+#define AMD5536_MFGPT1_SETUP 0x0000000e /* Setup register */
+
+#define AMD5536_MFGPT_CNT_EN (1 << 15) /* Enable counting */
+#define AMD5536_MFGPT_CMP2 (1 << 14) /* Compare 2 output */
+#define AMD5536_MFGPT_CMP1 (1 << 13) /* Compare 1 output */
+#define AMD5536_MFGPT_SETUP (1 << 12) /* Set to 1 after 1st write */
+#define AMD5536_MFGPT_STOP_EN (1 << 11) /* Stop enable */
+#define AMD5536_MFGPT_CMP2MODE (1 << 9)|(1 << 8)/* Set to GE + activate IRQ */
+#define AMD5536_MFGPT_SCALE 0x7 /* Set to 128 */
+#define AMD5536_MFGPT_CLKSEL (1 << 4) /* Clock select 14MHz */
+
+#define AMD5536_MFGPT1_C2_NMIM (1 << 9) /* Enable NMIs for MFGPT1 */
+#define AMD5536_MFGPT1_C2_RSTEN 0x02000000
+#define AMD5536_MFGPT1_C2_IRQM 0x00000200
+#define AMD5536_MFGPT5_C2_IRQM 0x00002000
+
+struct glxclk_softc *glxclk_sc;
+
+int
+glxclk_match(struct device *parent, void *match, void *aux)
+{
+ struct glxpcib_attach_args *gaa = aux;
+ struct cfdata *cf = match;
+
+ if (gaa->gaa_name == NULL || strcmp(gaa->gaa_name,
+ cf->cf_driver->cd_name) != 0)
+ return 0;
+
+ return 1;
+}
+
+void
+glxclk_attach(struct device *parent, struct device *self, void *aux)
+{
+ glxclk_sc = (struct glxclk_softc *)self;
+ struct glxpcib_attach_args *gaa = aux;
+ u_int64_t wa;
+
+ glxclk_sc->sc_iot = gaa->gaa_iot;
+ glxclk_sc->sc_ioh = gaa->gaa_ioh;
+
+ wa = rdmsr(MSR_LBAR_MFGPT);
+
+ if ((wa & MSR_LBAR_ENABLE) == 0) {
+ printf(" not configured\n");
+ return;
+ }
+
+ if (bus_space_map(glxclk_sc->sc_iot, wa & MSR_MFGPT_ADDR_MASK,
+ MSR_MFGPT_SIZE, 0, &glxclk_sc->sc_ioh)) {
+ printf(" not configured\n");
+ return;
+ }
+
+ /* Set comparator 2 */
+ bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_CMP2, 1);
+
+ /* Reset counter to 0 */
+ bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_CNT, 0);
+
+ /*
+ * All the bits in the range 11:0 have to be written at once.
+ * After they're set the first time all further writes are
+ * ignored.
+ */
+ uint16_t setup = (AMD5536_MFGPT_SCALE | AMD5536_MFGPT_CMP2MODE |
+ AMD5536_MFGPT_CMP1 | AMD5536_MFGPT_CMP2 |
+ AMD5536_MFGPT_CNT_EN);
+
+ bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_SETUP, setup);
+
+ /* Check to see if the MFGPT_SETUP bit was set */
+ setup = bus_space_read_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_SETUP);
+ if ((setup & AMD5536_MFGPT_SETUP) == 0) {
+ printf(" not configured\n");
+ }
+
+ /* Enable MFGPT1 Comparator 2 Output to the Interrupt Mapper */
+ wa = rdmsr(MFGPT_IRQ);
+ wa |= AMD5536_MFGPT1_C2_IRQM;
+ wrmsr(MFGPT_IRQ, wa);
+
+ /*
+ * Tie PIC input 5 to IG7 for glxclk(4).
+ */
+ wa = rdmsr(PIC_ZSEL_LOW);
+ wa &= ~(0xfUL << 20);
+ wa |= 7 << 20;
+ wrmsr(PIC_ZSEL_LOW, wa);
+
+ /* Start the counter */
+ setup = (AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2);
+ bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_SETUP, setup);
+
+ /*
+ * The interrupt argument is NULL in order to notify the dispatcher
+ * to pass the clock frame as argument. This trick also forces keeping
+ * the soft state global because during the interrupt we need to clear
+ * the comp2 event in the MFGPT setup register.
+ */
+ isa_intr_establish(sys_platform->isa_chipset, 7, IST_PULSE, IPL_CLOCK,
+ glxclk_intr, NULL, self->dv_xname);
+
+ md_startclock = glxclk_startclock;
+
+ printf(": MFGPT1\n");
+}
+
+void
+glxclk_startclock(struct cpu_info *ci)
+{
+ /* Start the clock. */
+ int s = splclock();
+ ci->ci_clock_started++;
+ splx(s);
+}
+
+int
+glxclk_intr(void *arg)
+{
+ struct clockframe *frame = arg;
+ uint16_t setup = 0;
+ struct cpu_info *ci = curcpu();
+
+ /* Clear the current event */
+ setup = bus_space_read_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_SETUP);
+ setup |= AMD5536_MFGPT_CMP2;
+ bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh,
+ AMD5536_MFGPT1_SETUP, setup);
+
+ if (ci->ci_clock_started == 0)
+ return 1;
+
+ hardclock(frame);
+
+ return 1;
+}
+/* $OpenBSD: glxclk.c,v 1.1 2013/01/14 21:18:47 pirofti Exp $ */
+
+/*
+ * Copyright (c) 2010 Paul Irofti.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/autoconf.h>
+
+#include <dev/isa/isavar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/glxreg.h>
+#include <dev/pci/glxvar.h>
+
+struct glxclk_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+};
+
+struct cfdriver glxclk_cd = {
+ NULL, "glxclk", DV_DULL
+};
+
+int glxclk_match(struct device *, void *, void *);
+void glxclk_attach(struct device *, struct device *, void *);
+int glxclk_activate(struct device *, int);
+int glxclk_intr(void *);
+
+struct cfattach glxclk_ca = {
+ sizeof(struct glxclk_softc), glxclk_match, glxclk_attach,
+ NULL, glxclk_activate
+};
+
+#define MSR_LBAR_ENABLE 0x100000000ULL
+#define MSR_LBAR_MFGPT DIVIL_LBAR_MFGPT
+#define MSR_MFGPT_SIZE 0x40
+#define MSR_MFGPT_ADDR_MASK 0xffc0
+
+#define AMD5536_MFGPT1_CMP2 0x0000000a /* Compare value for CMP2 */
+#define AMD5536_MFGPT1_CNT 0x0000000c /* Up counter */
+#define AMD5536_MFGPT1_SETUP 0x0000000e /* Setup register */
+
+#define AMD5536_MFGPT_CNT_EN (1 << 15) /* Enable counting */
+#define AMD5536_MFGPT_CMP2 (1 << 14) /* Compare 2 output */
+#define AMD5536_MFGPT_CMP1 (1 << 13) /* Compare 1 output */
+#define AMD5536_MFGPT_SETUP (1 << 12) /* Set to 1 after 1st write */
+#define AMD5536_MFGPT_STOP_EN (1 << 11) /* Stop enable */
+#define AMD5536_MFGPT_CMP2MODE (1 << 9)|(1 << 8)/* Set to GE + activate IRQ */
+#define AMD5536_MFGPT_SCALE 0x0f /* Set to 32768 */
+#define AMD5536_MFGPT_CLKSEL (1 << 4) /* Clock select 14MHz */
+
+#define AMD5536_MFGPT1_C2_NMIM (1 << 9) /* Enable NMIs for MFGPT1 */
+#define AMD5536_MFGPT1_C2_RSTEN 0x02000000
+#define AMD5536_MFGPT1_C2_IRQM 0x00000200
+#define AMD5536_MFGPT5_C2_IRQM 0x00002000
+
+/* XXX: overflow */
+#define MFGPT_TICK 14318000
+#define COMP2 ((MFGPT_TICK + HZ / 2) / HZ)
+
+int
+glxclk_match(struct device *parent, void *match, void *aux)
+{
+ struct glxpcib_attach_args *gaa = aux;
+ struct cfdata *cf = match;
+
+ if (gaa->gaa_name == NULL || strcmp(gaa->gaa_name,
+ cf->cf_driver->cd_name) != 0)
+ return 0;
+
+ return 1;
+}
+
+void
+glxclk_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct glxclk_softc *sc = (struct glxclk_softc *)self;
+ struct glxpcib_attach_args *gaa = aux;
+ u_int64_t wa;
+
+ sc->sc_iot = gaa->gaa_iot;
+ sc->sc_ioh = gaa->gaa_ioh;
+
+ wa = rdmsr(MSR_LBAR_MFGPT);
+
+ if ((wa & MSR_LBAR_ENABLE) == 0) {
+ printf(" not configured\n");
+ return;
+ }
+
+ if (bus_space_map(sc->sc_iot, wa & MSR_MFGPT_ADDR_MASK,
+ MSR_MFGPT_SIZE, 0, &sc->sc_ioh)) {
+ printf(" not configured\n");
+ return;
+ }
+
+ /* Set comparator 2 */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_CMP2, 0xffff);
+
+ /* Reset counter to 0 */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_CNT, 0);
+
+ /* count in seconds (as upper level desires) */
+
+ /*
+ * All the bits in the range 11:0 have to be written at once.
+ * After they're set the first time all further writes are
+ * ignored.
+ */
+ uint16_t setup = (AMD5536_MFGPT_CLKSEL | AMD5536_MFGPT_CMP2MODE |
+ AMD5536_MFGPT_CMP1 | AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_CNT_EN);
+
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup);
+
+ /* Check to see if the MFGPT_SETUP bit was set */
+ setup = bus_space_read_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP);
+ if ((setup & AMD5536_MFGPT_SETUP) == 0) {
+ printf(" not configured\n");
+ }
+
+#if 0
+ /* Enable NMI's for MFGPT1 */
+ wa = rdmsr(MFGPT_NR);
+ wa |= AMD5536_MFGPT1_C2_RSTEN;
+ wrmsr(MFGPT_NR, wa);
+#endif
+
+ /* Enable MFGPT1 Comparator 2 Output to the Interrupt Mapper */
+ wa = rdmsr(MFGPT_IRQ);
+ wa |= AMD5536_MFGPT1_C2_IRQM;
+ wrmsr(MFGPT_IRQ, wa);
+
+ /*
+ * Tie PIC input 5 to IG5 for glxclk(4).
+ */
+ wa = rdmsr(PIC_ZSEL_LOW);
+ wa &= ~(0xfUL << 20);
+ wa |= 7 << 20;
+ wrmsr(PIC_ZSEL_LOW, wa);
+
+ /* Start the counter */
+ setup = (AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup);
+
+ isa_intr_establish(sys_platform->isa_chipset, 7, IST_PULSE, IPL_CLOCK,
+ glxclk_intr, sc, self->dv_xname);
+
+ printf(": MFGPT1\n");
+}
+
+int
+glxclk_intr(void *arg)
+{
+ struct glxclk_softc *sc = (struct glxclk_softc *)arg;
+ uint16_t setup = 0;
+
+ /* Clear the current event */
+ setup = bus_space_read_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP);
+ setup |= AMD5536_MFGPT_CMP2;
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup);
+
+ return 1;
+}
+
+int
+glxclk_activate(struct device *self, int act)
+{
+ return 0;
+}
diff --git a/sys/arch/loongson/dev/mainbus.c b/sys/arch/loongson/dev/mainbus.c
index f9d2cd1903b..b423aef7051 100644
--- a/sys/arch/loongson/dev/mainbus.c
+++ b/sys/arch/loongson/dev/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.6 2010/09/23 14:12:05 pirofti Exp $ */
+/* $OpenBSD: mainbus.c,v 1.7 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -71,8 +71,10 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
caa.caa_maa.maa_name = "bonito";
config_found(self, &caa.caa_maa, mainbus_print);
- caa.caa_maa.maa_name = "clock";
- config_found(self, &caa.caa_maa, mainbus_print);
+ if (md_startclock == NULL) {
+ caa.caa_maa.maa_name = "clock";
+ config_found(self, &caa.caa_maa, mainbus_print);
+ }
caa.caa_maa.maa_name = "apm";
config_found(self, &caa.caa_maa, mainbus_print);
diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c
index 5c2afe19934..82f228b4855 100644
--- a/sys/arch/loongson/loongson/machdep.c
+++ b/sys/arch/loongson/loongson/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.39 2012/10/08 21:47:48 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.40 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -419,6 +419,11 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv,
bootcpu_hwinfo.clock = cpuspeed;
/*
+ * MFGPT runs on powers of two, adjust the hz value accordingly.
+ */
+ hz = 128;
+
+ /*
* Look at arguments passed to us and compute boothowto.
*/
diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c
index dba75f0c4c3..6f426fe9a61 100644
--- a/sys/arch/loongson/loongson/yeeloong_machdep.c
+++ b/sys/arch/loongson/loongson/yeeloong_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: yeeloong_machdep.c,v 1.20 2012/10/03 21:44:51 miod Exp $ */
+/* $OpenBSD: yeeloong_machdep.c,v 1.21 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -389,8 +389,15 @@ lemote_isa_intr(uint32_t hwpend, struct trap_frame *frame)
rc = 0;
for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)];
ih != NULL; ih = ih->ih_next) {
+ void *arg;
+
splraise(ih->ih_level);
- ret = (*ih->ih_fun)(ih->ih_arg);
+ if (ih->ih_arg != NULL)
+ arg = ih->ih_arg;
+ else
+ /* clock interrupt */
+ arg = frame;
+ ret = (*ih->ih_fun)(arg);
if (ret) {
rc = 1;
ih->ih_count.ec_count++;
diff --git a/sys/arch/mips64/mips64/mips64_machdep.c b/sys/arch/mips64/mips64/mips64_machdep.c
index 17eb0386186..47cf4a77431 100644
--- a/sys/arch/mips64/mips64/mips64_machdep.c
+++ b/sys/arch/mips64/mips64/mips64_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mips64_machdep.c,v 1.8 2012/10/03 11:18:23 miod Exp $ */
+/* $OpenBSD: mips64_machdep.c,v 1.9 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2009, 2010, 2012 Miodrag Vallat.
@@ -326,8 +326,7 @@ cpu_initclocks()
{
struct cpu_info *ci = curcpu();
- hz = 100;
- profhz = 100;
+ profhz = hz;
stathz = 0; /* XXX no stat clock yet */
tick = 1000000 / hz; /* number of micro-seconds between interrupts */
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index b4af38167a9..a9359be20c1 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.291 2013/01/12 13:02:22 sf Exp $
+# $OpenBSD: files.pci,v 1.292 2013/01/14 21:18:47 pirofti Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -819,7 +819,7 @@ attach itherm at pci
file dev/pci/itherm.c itherm
# AMD Geode CS5536 PCI-ISA bridge
-device glxpcib: isabus, gpiobus, i2cbus
+device glxpcib{}: isabus, gpiobus, i2cbus
attach glxpcib at pci
file dev/pci/glxpcib.c glxpcib
diff --git a/sys/dev/pci/glxpcib.c b/sys/dev/pci/glxpcib.c
index 9f89180cde7..5ae0ef9978e 100644
--- a/sys/dev/pci/glxpcib.c
+++ b/sys/dev/pci/glxpcib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: glxpcib.c,v 1.7 2012/10/17 22:32:01 deraadt Exp $ */
+/* $OpenBSD: glxpcib.c,v 1.8 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org>
@@ -211,6 +211,8 @@ struct cfdriver glxpcib_cd = {
int glxpcib_match(struct device *, void *, void *);
void glxpcib_attach(struct device *, struct device *, void *);
int glxpcib_activate(struct device *, int);
+int glxpcib_search(struct device *, void *, void *);
+int glxpcib_print(void *, const char *);
struct cfattach glxpcib_ca = {
sizeof(struct glxpcib_softc), glxpcib_match, glxpcib_attach,
@@ -300,7 +302,8 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux)
/* count in seconds (as upper level desires) */
bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_SETUP,
AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2EV |
- AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_DIV_MASK);
+ AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_DIV_MASK |
+ AMD5536_MFGPT_STOP_EN);
wdog_register(glxpcib_wdogctl_cb, sc);
sc->sc_wdog = 1;
printf(", watchdog");
@@ -396,6 +399,8 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux)
if (i2c)
config_found(&sc->sc_dev, &iba, iicbus_print);
#endif
+
+ config_search(glxpcib_search, self, pa);
}
int
@@ -684,6 +689,46 @@ glxpcib_smb_read_byte(void *arg, uint8_t *bytep, int flags)
}
int
+glxpcib_print(void *args, const char *parentname)
+{
+ struct glxpcib_attach_args *gaa = (struct glxpcib_attach_args *)args;
+
+ if (parentname != NULL)
+ printf("%s at %s", gaa->gaa_name, parentname);
+
+ return UNCONF;
+}
+
+int
+glxpcib_search(struct device *parent, void *gcf, void *args)
+{
+ struct glxpcib_softc *sc = (struct glxpcib_softc *)parent;
+ struct cfdata *cf = (struct cfdata *)gcf;
+ struct pci_attach_args *pa = (struct pci_attach_args *)args;
+ struct glxpcib_attach_args gaa;
+
+ gaa.gaa_name = cf->cf_driver->cd_name;
+ gaa.gaa_pa = pa;
+ gaa.gaa_iot = sc->sc_iot;
+ gaa.gaa_ioh = sc->sc_ioh;
+
+ /*
+ * These devices are attached directly, either from
+ * glxpcib_attach() or later in time from pcib_callback().
+ */
+ if (strcmp(cf->cf_driver->cd_name, "gpio") == 0 ||
+ strcmp(cf->cf_driver->cd_name, "iic") == 0 ||
+ strcmp(cf->cf_driver->cd_name, "isa") == 0)
+ return 0;
+
+ if (cf->cf_attach->ca_match(parent, cf, &gaa) == 0)
+ return 0;
+
+ config_attach(parent, cf, &gaa, glxpcib_print);
+ return 1;
+}
+
+int
glxpcib_smb_write_byte(void *arg, uint8_t byte, int flags)
{
struct glxpcib_softc *sc = arg;
diff --git a/sys/dev/pci/glxvar.h b/sys/dev/pci/glxvar.h
index 93c80a7ccba..2eef5ced737 100644
--- a/sys/dev/pci/glxvar.h
+++ b/sys/dev/pci/glxvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: glxvar.h,v 1.1 2010/10/14 21:23:05 pirofti Exp $ */
+/* $OpenBSD: glxvar.h,v 1.2 2013/01/14 21:18:47 pirofti Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -20,3 +20,11 @@ void glx_init(pci_chipset_tag_t, pcitag_t, int);
uint64_t rdmsr(uint);
void wrmsr(uint, uint64_t);
+
+struct glxpcib_attach_args {
+ const char *gaa_name;
+
+ struct pci_attach_args *gaa_pa;
+ bus_space_tag_t gaa_iot;
+ bus_space_handle_t gaa_ioh;
+};