i2c(9): Nix smbus intr API.

It was introduced in 2007 for some Xbox thing which was removed in
2011.  The API and the threads it spawned have been sitting around
idly for over a decade serving no purpose -- sometimes causing kernel
lock spinouts in the event of panic.

Add ic_tag_private to obviate need for future ABI changes.  Not
currently used, but we can privately allocate memory in iic_tag_init
for the purpose later if need be without changing ABI.

XXX kernel revbump -- changes struct i2c_controller
This commit is contained in:
riastradh 2022-10-24 10:17:27 +00:00
parent 7a37aab670
commit c12151368a
4 changed files with 8 additions and 157 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: smbus_acpi.c,v 1.17 2021/08/07 16:19:09 thorpej Exp $ */ /* $NetBSD: smbus_acpi.c,v 1.18 2022/10/24 10:17:27 riastradh Exp $ */
/*- /*-
* Copyright (c) 2009 The NetBSD Foundation, Inc. * Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: smbus_acpi.c,v 1.17 2021/08/07 16:19:09 thorpej Exp $"); __KERNEL_RCSID(0, "$NetBSD: smbus_acpi.c,v 1.18 2022/10/24 10:17:27 riastradh Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/device.h> #include <sys/device.h>
@ -496,8 +496,6 @@ acpi_smbus_alerts(struct acpi_smbus_softc *sc)
aprint_debug_dev(sc->sc_dv, aprint_debug_dev(sc->sc_dv,
"alert for 0x%x\n", addr); "alert for 0x%x\n", addr);
(void)iic_smbus_intr(&sc->sc_i2c_tag);
} }
} }
done: done:

View File

@ -1,4 +1,4 @@
/* $NetBSD: i2c.c,v 1.88 2022/07/23 03:05:27 thorpej Exp $ */ /* $NetBSD: i2c.c,v 1.89 2022/10/24 10:17:27 riastradh Exp $ */
/* /*
* Copyright (c) 2003 Wasabi Systems, Inc. * Copyright (c) 2003 Wasabi Systems, Inc.
@ -53,7 +53,7 @@
#endif /* _KERNEL_OPT */ #endif /* _KERNEL_OPT */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.88 2022/07/23 03:05:27 thorpej Exp $"); __KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.89 2022/10/24 10:17:27 riastradh Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -119,7 +119,6 @@ const struct cdevsw iic_cdevsw = {
.d_flag = D_OTHER .d_flag = D_OTHER
}; };
static void iic_smbus_intr_thread(void *);
static void iic_fill_compat(struct i2c_attach_args*, const char*, static void iic_fill_compat(struct i2c_attach_args*, const char*,
size_t, char **); size_t, char **);
@ -426,7 +425,6 @@ iic_attach(device_t parent, device_t self, void *aux)
prop_dictionary_t props; prop_dictionary_t props;
char *buf; char *buf;
i2c_tag_t ic; i2c_tag_t ic;
int rv;
bool no_indirect_config = false; bool no_indirect_config = false;
aprint_naive("\n"); aprint_naive("\n");
@ -435,16 +433,6 @@ iic_attach(device_t parent, device_t self, void *aux)
sc->sc_dev = self; sc->sc_dev = self;
sc->sc_tag = iba->iba_tag; sc->sc_tag = iba->iba_tag;
ic = sc->sc_tag; ic = sc->sc_tag;
ic->ic_devname = device_xname(self);
LIST_INIT(&(sc->sc_tag->ic_list));
LIST_INIT(&(sc->sc_tag->ic_proc_list));
rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
iic_smbus_intr_thread, ic, &ic->ic_intr_thread,
"%s", ic->ic_devname);
if (rv)
aprint_error_dev(self, "unable to create intr thread\n");
if (!pmf_device_register(self, NULL, NULL)) if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n"); aprint_error_dev(self, "couldn't establish power handler\n");
@ -556,9 +544,7 @@ static int
iic_detach(device_t self, int flags) iic_detach(device_t self, int flags)
{ {
struct iic_softc *sc = device_private(self); struct iic_softc *sc = device_private(self);
i2c_tag_t ic = sc->sc_tag;
int i, error; int i, error;
void *hdl;
for (i = 0; i <= I2C_MAX_ADDR; i++) { for (i = 0; i <= I2C_MAX_ADDR; i++) {
if (sc->sc_devices[i]) { if (sc->sc_devices[i]) {
@ -568,131 +554,11 @@ iic_detach(device_t self, int flags)
} }
} }
if (ic->ic_running) {
ic->ic_running = 0;
wakeup(ic);
kthread_join(ic->ic_intr_thread);
}
if (!LIST_EMPTY(&ic->ic_list)) {
device_printf(self, "WARNING: intr handler list not empty\n");
while (!LIST_EMPTY(&ic->ic_list)) {
hdl = LIST_FIRST(&ic->ic_list);
iic_smbus_intr_disestablish(ic, hdl);
}
}
if (!LIST_EMPTY(&ic->ic_proc_list)) {
device_printf(self, "WARNING: proc handler list not empty\n");
while (!LIST_EMPTY(&ic->ic_proc_list)) {
hdl = LIST_FIRST(&ic->ic_proc_list);
iic_smbus_intr_disestablish_proc(ic, hdl);
}
}
pmf_device_deregister(self); pmf_device_deregister(self);
return 0; return 0;
} }
static void
iic_smbus_intr_thread(void *aux)
{
i2c_tag_t ic;
struct ic_intr_list *il;
ic = (i2c_tag_t)aux;
ic->ic_running = 1;
ic->ic_pending = 0;
while (ic->ic_running) {
if (ic->ic_pending == 0)
tsleep(ic, PZERO, "iicintr", hz);
if (ic->ic_pending > 0) {
LIST_FOREACH(il, &(ic->ic_proc_list), il_next) {
(*il->il_intr)(il->il_intrarg);
}
ic->ic_pending--;
}
}
kthread_exit(0);
}
void *
iic_smbus_intr_establish(i2c_tag_t ic, int (*intr)(void *), void *intrarg)
{
struct ic_intr_list *il;
il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK);
if (il == NULL)
return NULL;
il->il_intr = intr;
il->il_intrarg = intrarg;
LIST_INSERT_HEAD(&(ic->ic_list), il, il_next);
return il;
}
void
iic_smbus_intr_disestablish(i2c_tag_t ic, void *hdl)
{
struct ic_intr_list *il;
il = (struct ic_intr_list *)hdl;
LIST_REMOVE(il, il_next);
free(il, M_DEVBUF);
return;
}
void *
iic_smbus_intr_establish_proc(i2c_tag_t ic, int (*intr)(void *), void *intrarg)
{
struct ic_intr_list *il;
il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK);
if (il == NULL)
return NULL;
il->il_intr = intr;
il->il_intrarg = intrarg;
LIST_INSERT_HEAD(&(ic->ic_proc_list), il, il_next);
return il;
}
void
iic_smbus_intr_disestablish_proc(i2c_tag_t ic, void *hdl)
{
struct ic_intr_list *il;
il = (struct ic_intr_list *)hdl;
LIST_REMOVE(il, il_next);
free(il, M_DEVBUF);
return;
}
int
iic_smbus_intr(i2c_tag_t ic)
{
struct ic_intr_list *il;
LIST_FOREACH(il, &(ic->ic_list), il_next) {
(*il->il_intr)(il->il_intrarg);
}
ic->ic_pending++;
wakeup(ic);
return 1;
}
static void static void
iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len, iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len,
char **buffer) char **buffer)

View File

@ -1,4 +1,4 @@
/* $NetBSD: i2c_exec.c,v 1.17 2021/10/12 08:36:29 andvar Exp $ */ /* $NetBSD: i2c_exec.c,v 1.18 2022/10/24 10:17:27 riastradh Exp $ */
/* /*
* Copyright (c) 2003 Wasabi Systems, Inc. * Copyright (c) 2003 Wasabi Systems, Inc.
@ -36,7 +36,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i2c_exec.c,v 1.17 2021/10/12 08:36:29 andvar Exp $"); __KERNEL_RCSID(0, "$NetBSD: i2c_exec.c,v 1.18 2022/10/24 10:17:27 riastradh Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -73,8 +73,6 @@ iic_tag_init(i2c_tag_t tag)
memset(tag, 0, sizeof(*tag)); memset(tag, 0, sizeof(*tag));
mutex_init(&tag->ic_bus_lock, MUTEX_DEFAULT, IPL_NONE); mutex_init(&tag->ic_bus_lock, MUTEX_DEFAULT, IPL_NONE);
LIST_INIT(&tag->ic_list);
LIST_INIT(&tag->ic_proc_list);
} }
/* /*

View File

@ -1,4 +1,4 @@
/* $NetBSD: i2cvar.h,v 1.25 2022/05/28 22:16:43 andvar Exp $ */ /* $NetBSD: i2cvar.h,v 1.26 2022/10/24 10:17:27 riastradh Exp $ */
/* /*
* Copyright (c) 2003 Wasabi Systems, Inc. * Copyright (c) 2003 Wasabi Systems, Inc.
@ -120,12 +120,7 @@ typedef struct i2c_controller {
int (*ic_read_byte)(void *, uint8_t *, int); int (*ic_read_byte)(void *, uint8_t *, int);
int (*ic_write_byte)(void *, uint8_t, int); int (*ic_write_byte)(void *, uint8_t, int);
LIST_HEAD(, ic_intr_list) ic_list; struct i2c_tag_private *ic_tag_private;
LIST_HEAD(, ic_intr_list) ic_proc_list;
volatile int ic_running;
volatile int ic_pending;
struct lwp *ic_intr_thread;
const char *ic_devname;
} *i2c_tag_t; } *i2c_tag_t;
/* Used to attach the i2c framework to the controller. */ /* Used to attach the i2c framework to the controller. */
@ -243,10 +238,4 @@ int iic_smbus_block_read(i2c_tag_t, i2c_addr_t, uint8_t, uint8_t *,
int iic_smbus_block_write(i2c_tag_t, i2c_addr_t, uint8_t, uint8_t *, int iic_smbus_block_write(i2c_tag_t, i2c_addr_t, uint8_t, uint8_t *,
size_t, int); size_t, int);
void * iic_smbus_intr_establish(i2c_tag_t, int (*)(void *), void *);
void * iic_smbus_intr_establish_proc(i2c_tag_t, int (*)(void *), void *);
void iic_smbus_intr_disestablish(i2c_tag_t, void *);
void iic_smbus_intr_disestablish_proc(i2c_tag_t, void *);
int iic_smbus_intr(i2c_tag_t);
#endif /* _DEV_I2C_I2CVAR_H_ */ #endif /* _DEV_I2C_I2CVAR_H_ */