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:
parent
7a37aab670
commit
c12151368a
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
Loading…
Reference in New Issue