Date: Mon, 24 Jun 2002 14:59:21 +0200 From: Willem van Engen <wvengen@stack.nl> To: freebsd-hackers@freebsd.org Subject: smbalert# hook for smbus childs Message-ID: <20020624145921.463108fc.wvengen@stack.nl>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hello,
there already is some code for smbalert# handling on intpm
(ENABLE_ALART), but there is no support for handling it in a driver. O2
AudioDJ (OZ162) chips use this signal to indicate that a button was
pressed. So I need a way for a driver to be notified when smbalert#
occurs.
Of course I thought immediately about bus_(setup|teardown)_intr. I wrote
something like that for smbus: bus_(setup|teardown)_alart (see patch),
that works now. But is this The Right Way to do it? I do have some
thoughts on it, but maybe someone more knowledgeable than me could comment
on it.
It might be better to use bus_*_intr instead of bus_*_alart, but one
would need to bus_alloc_resource a slave address and pass that to
bus_setup_intr. But then it makes sense to use those slave address
resources to send smbus commands, right? But how would that fit into the
bus_space_* functions?
- Willem
p.s. I hope I'm clear, english isn't my native language.
[-- Attachment #2 --]
--- sys/dev/smbus/smbconf.c.orig Mon Jun 24 02:36:25 2002
+++ sys/dev/smbus/smbconf.c Mon Jun 24 11:00:11 2002
@@ -28,6 +28,9 @@
*/
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
#include <sys/module.h>
#include <sys/bus.h>
@@ -35,6 +38,12 @@
#include <dev/smbus/smbus.h>
#include "smbus_if.h"
+#ifdef ENABLE_ALART
+/* List for alart hooks per slave */
+extern SLIST_HEAD(alarthook_head, alarthook_entry) alarthooks;
+#endif
+
+
/*
* smbus_intr()
*/
@@ -174,3 +183,70 @@
return (0);
}
+
+#ifdef ENABLE_ALART
+
+MALLOC_DEFINE(M_SMBUS_ALART, "smbusalart", "SMBus alart hook list");
+
+/*
+ * smbus_setup_alart()
+ */
+int
+smbus_setup_alart(device_t dev, u_char slave, int flags,
+ driver_intr_t *handler, void *arg)
+{
+ struct alarthook_entry *entry;
+
+ /* Check if same hook already exists */
+ SLIST_FOREACH(entry, &alarthooks, entries)
+ if (entry->dev == dev && entry->slave == slave)
+ return (EADDRINUSE);
+
+ /* Add this one to the list */
+ MALLOC(entry, struct alarthook_entry*,
+ sizeof(struct alarthook_entry), M_SMBUS_ALART, M_WAITOK);
+ entry->dev=dev;
+ entry->slave=slave;
+ entry->handler=handler;
+ entry->arg=arg;
+ SLIST_INSERT_HEAD(&alarthooks, entry, entries);
+
+ return (0);
+}
+
+/*
+ * smbus_teardown_alart()
+ */
+int
+smbus_teardown_alart(device_t dev, u_char slave) {
+ struct alarthook_entry *curentry, *foundentry=NULL;
+
+ SLIST_FOREACH(curentry, &alarthooks, entries)
+ if (curentry->dev == dev && curentry->slave == slave)
+ foundentry=curentry;
+
+ if (!foundentry)
+ return (ENXIO);
+
+ SLIST_REMOVE(&alarthooks, foundentry, alarthook_entry, entries);
+ FREE(foundentry,M_SMBUS_ALART);
+
+ return (0);
+}
+
+/*
+ * smbus_alart_intr()
+ */
+void
+smbus_alart_intr(device_t dev, u_char devaddr)
+{
+ struct alarthook_entry *entry;
+
+ /* Call each childfunction with matching slave address */
+ SLIST_FOREACH(entry, &alarthooks, entries)
+ if (entry->slave==devaddr && entry->handler)
+ entry->handler(entry->arg);
+
+ return;
+}
+#endif /* ENABLE_ALART */
--- sys/dev/smbus/smbconf.h.orig Mon Jun 24 02:37:32 2002
+++ sys/dev/smbus/smbconf.h Mon Jun 24 03:43:58 2002
@@ -80,6 +80,12 @@
extern u_char smbus_get_addr(device_t);
+#ifdef ENABLE_ALART
+extern int smbus_setup_alart(device_t, u_char, int, driver_intr_t*, void*);
+extern int smbus_teardown_alart(device_t, u_char);
+extern void smbus_alart_intr(device_t, u_char);
+#endif
+
#define smbus_quick(bus,slave,how) \
(SMBUS_QUICK(device_get_parent(bus), slave, how))
#define smbus_sendb(bus,slave,byte) \
--- sys/dev/smbus/smbus.c.orig Mon Jun 24 02:17:55 2002
+++ sys/dev/smbus/smbus.c Mon Jun 24 13:13:33 2002
@@ -31,6 +31,7 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <sys/malloc.h>
#include <dev/smbus/smbconf.h>
#include <dev/smbus/smbus.h>
@@ -48,13 +49,14 @@
*/
static int smbus_probe(device_t);
static int smbus_attach(device_t);
+static int smbus_detach(device_t);
static int smbus_add_child(device_t dev, int order, const char *name, int unit);
static device_method_t smbus_methods[] = {
/* device interface */
DEVMETHOD(device_probe, smbus_probe),
DEVMETHOD(device_attach, smbus_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_detach, smbus_detach),
/* bus interface */
DEVMETHOD(bus_add_child, smbus_add_child),
@@ -69,6 +71,12 @@
sizeof(struct smbus_softc),
};
+#ifdef ENABLE_ALART
+/* List for alart hooks per slave */
+SLIST_HEAD(alarthook_head, alarthook_entry) alarthooks =
+ SLIST_HEAD_INITIALIZER(alarthooks);
+#endif
+
/*
* At 'probe' time, we add all the devices which we know about to the
* bus. The generic attach routine will probe and attach them if they
@@ -87,8 +95,30 @@
{
device_add_child(dev, NULL, -1);
bus_generic_attach(dev);
+
+#ifdef ENABLE_ALART
+ /* Init list for alart hooks */
+ SLIST_INIT(&alarthooks);
+#endif
return (0);
+}
+
+static int
+smbus_detach(device_t dev)
+{
+#ifdef ENABLE_ALART
+ struct alarthook_entry *entry;
+
+ /* Remove alart hook list */
+ while (!SLIST_EMPTY(&alarthooks)) {
+ entry = SLIST_FIRST(&alarthooks);
+ SLIST_REMOVE_HEAD(&alarthooks, entries);
+ FREE(entry, M_SMBUS_ALART);
+ }
+#endif
+
+ return bus_generic_detach(dev);
}
static int
--- sys/dev/smbus/smbus.h.orig Mon Jun 24 02:17:32 2002
+++ sys/dev/smbus/smbus.h Mon Jun 24 10:44:52 2002
@@ -38,4 +38,16 @@
extern void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high);
+#ifdef ENABLE_ALART
+struct alarthook_entry {
+ device_t dev;
+ u_char slave;
+ driver_intr_t *handler;
+ void *arg;
+ SLIST_ENTRY(alarthook_entry) entries;
+};
+
+MALLOC_DECLARE(M_SMBUS_ALART);
+#endif /* ENABLE_ALART */
+
#endif
--- sys/pci/intpm.c.orig Sat Jun 22 16:04:16 2002
+++ sys/pci/intpm.c Mon Jun 24 02:46:19 2002
@@ -297,10 +297,15 @@
u_int8_t addr;
addr=bus_space_read_1(sc->st,sc->sh,
PIIX4_SMBHSTDAT0);
+#ifdef ENABLE_ALART_VERBOSE
printf("ALART_RESPONSE: 0x%x\n", addr);
+#endif
+ smbus_alart_intr(dev, addr);
}
}else{
+#ifdef ENABLE_ALART_VERBOSE
printf("ERROR\n");
+#endif
}
/*Re-enable INTR from ALART*/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020624145921.463108fc.wvengen>
