Home | History | Annotate | Line # | Download | only in dev
      1 /*/* $NetBSD: tadpmu.c,v 1.6 2023/12/20 05:33:58 thorpej Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2018 Michael Lorenz <macallan (at) netbsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /* a driver for the PMU found in Tadpole Viper and SPARCle laptops */
     30 
     31 #include "opt_tadpmu.h"
     32 #ifdef HAVE_TADPMU
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/kernel.h>
     36 #include <sys/device.h>
     37 #include <sys/proc.h>
     38 #include <sys/bus.h>
     39 #include <sys/intr.h>
     40 #include <sys/kthread.h>
     41 #include <sys/mutex.h>
     42 
     43 #include <dev/sysmon/sysmonvar.h>
     44 #include <dev/sysmon/sysmon_taskq.h>
     45 
     46 #include <sparc64/dev/tadpmureg.h>
     47 #include <sparc64/dev/tadpmuvar.h>
     48 
     49 #ifdef TADPMU_DEBUG
     50 #define DPRINTF printf
     51 #else
     52 #define DPRINTF while (0) printf
     53 #endif
     54 
     55 static bus_space_tag_t tadpmu_iot;
     56 static bus_space_handle_t tadpmu_hcmd;
     57 static bus_space_handle_t tadpmu_hdata;
     58 static struct sysmon_envsys *tadpmu_sens_sme;
     59 static struct sysmon_envsys *tadpmu_acad_sme;
     60 static struct sysmon_envsys *tadpmu_batt_sme;
     61 static envsys_data_t tadpmu_sensors[8];
     62 static uint8_t idata = 0xff;
     63 static uint8_t ivalid = 0;
     64 static uint8_t ev_data = 0;
     65 static wchan_t tadpmu, tadpmuev;
     66 static struct sysmon_pswitch tadpmu_pbutton, tadpmu_lidswitch, tadpmu_dcpower;
     67 static kmutex_t tadpmu_lock, data_lock;
     68 static lwp_t *tadpmu_thread;
     69 static int tadpmu_dying = 0;
     70 
     71 static inline void
     72 tadpmu_cmd(uint8_t d)
     73 {
     74 	bus_space_write_1(tadpmu_iot, tadpmu_hcmd, 0, d);
     75 }
     76 
     77 static inline void
     78 tadpmu_wdata(uint8_t d)
     79 {
     80 	bus_space_write_1(tadpmu_iot, tadpmu_hdata, 0, d);
     81 }
     82 
     83 static inline uint8_t
     84 tadpmu_status(void)
     85 {
     86 	return bus_space_read_1(tadpmu_iot, tadpmu_hcmd, 0);
     87 }
     88 
     89 static inline uint8_t
     90 tadpmu_data(void)
     91 {
     92 	return bus_space_read_1(tadpmu_iot, tadpmu_hdata, 0);
     93 }
     94 
     95 static void
     96 tadpmu_flush(void)
     97 {
     98 	volatile uint8_t junk, d;
     99 	int bail = 0;
    100 
    101 	d = tadpmu_status();
    102 	while (d & STATUS_HAVE_DATA) {
    103 		junk = tadpmu_data();
    104 		__USE(junk);
    105 		delay(10);
    106 		bail++;
    107 		if (bail > 100) {
    108 			printf("%s: timeout waiting for data out to clear %2x\n",
    109 			    __func__, d);
    110 			break;
    111 		}
    112 		d = tadpmu_status();
    113 	}
    114 	bail = 0;
    115 	d = tadpmu_status();
    116 	while (d & STATUS_SEND_DATA) {
    117 		bus_space_write_1(tadpmu_iot, tadpmu_hdata, 0, 0);
    118 		delay(10);
    119 		bail++;
    120 		if (bail > 100) {
    121 			printf("%s: timeout waiting for data in to clear %02x\n",
    122 			    __func__, d);
    123 			break;
    124 		}
    125 		d = tadpmu_status();
    126 	}
    127 }
    128 
    129 static void
    130 tadpmu_send_cmd(uint8_t cmd)
    131 {
    132 	int bail = 0;
    133 	uint8_t d;
    134 
    135 	ivalid = 0;
    136 	tadpmu_cmd(cmd);
    137 
    138 	d = tadpmu_status();
    139 	while ((d & STATUS_CMD_IN_PROGRESS) == 0) {
    140 		delay(10);
    141 		bail++;
    142 		if (bail > 100) {
    143 			printf("%s: timeout waiting for command to start\n",
    144 			    __func__);
    145 			break;
    146 		}
    147 		d = tadpmu_status();
    148 	}
    149 }
    150 
    151 static uint8_t
    152 tadpmu_recv(void)
    153 {
    154 	int bail = 0;
    155 	uint8_t d;
    156 
    157 	if (cold) {
    158 		d = tadpmu_status();
    159 		while ((d & STATUS_HAVE_DATA) == 0) {
    160 			delay(10);
    161 			bail++;
    162 			if (bail > 1000) {
    163 				printf("%s: timeout waiting for data %02x\n",
    164 				    __func__, d);
    165 				break;
    166 			}
    167 			d = tadpmu_status();
    168 		}
    169 		return bus_space_read_1(tadpmu_iot, tadpmu_hdata, 0);
    170 	} else {
    171 		while (ivalid == 0)
    172 			tsleep(tadpmu, 0, "pmucmd", 1);
    173 		return idata;
    174 	}
    175 }
    176 
    177 static void
    178 tadpmu_send(uint8_t v)
    179 {
    180 	int bail = 0;
    181 	uint8_t d;
    182 
    183 	d = tadpmu_status();
    184 	while ((d & STATUS_SEND_DATA) == 0) {
    185 		delay(10);
    186 		bail++;
    187 		if (bail > 1000) {
    188 			printf("%s: timeout waiting for PMU ready %02x\n", __func__, d);
    189 			break;
    190 		}
    191 		d = tadpmu_status();
    192 	}
    193 
    194 	tadpmu_wdata(v);
    195 
    196 	while ((d & STATUS_SEND_DATA) != 0) {
    197 		delay(10);
    198 		bail++;
    199 		if (bail > 1000) {
    200 			printf("%s: timeout waiting for accept data %02x\n", __func__, d);
    201 			break;
    202 		}
    203 		d = tadpmu_status();
    204 	}
    205 }
    206 
    207 static uint32_t
    208 tadpmu_battery_capacity(uint8_t gstat)
    209 {
    210 	uint8_t res;
    211 
    212 	if (gstat == GENSTAT_STATE_BATTERY_FULL) {
    213 		return ENVSYS_BATTERY_CAPACITY_NORMAL;
    214 	}
    215 
    216 	mutex_enter(&tadpmu_lock);
    217 	tadpmu_flush();
    218 	tadpmu_send_cmd(CMD_READ_VBATT);
    219 	res = tadpmu_recv();
    220 	mutex_exit(&tadpmu_lock);
    221 
    222 	if (gstat & GENSTAT_STATE_BATTERY_DISCHARGE) {
    223 		if (res < TADPMU_BATT_DIS_CAP_CRIT)
    224 			return ENVSYS_BATTERY_CAPACITY_CRITICAL;
    225 		if (res < TADPMU_BATT_DIS_CAP_WARN)
    226 			return ENVSYS_BATTERY_CAPACITY_WARNING;
    227 		if (res < TADPMU_BATT_DIS_CAP_LOW)
    228 			return ENVSYS_BATTERY_CAPACITY_LOW;
    229 		else
    230 			return ENVSYS_BATTERY_CAPACITY_NORMAL;
    231 	} else if (gstat == GENSTAT_STATE_BATTERY_CHARGE) {
    232 		if (res < TADPMU_BATT_CHG_CAP_CRIT)
    233 			return ENVSYS_BATTERY_CAPACITY_CRITICAL;
    234 		else if (res < TADPMU_BATT_CHG_CAP_WARN)
    235 			return ENVSYS_BATTERY_CAPACITY_WARNING;
    236 		else if (res < TADPMU_BATT_CHG_CAP_LOW)
    237 			return ENVSYS_BATTERY_CAPACITY_LOW;
    238 		else
    239 			return ENVSYS_BATTERY_CAPACITY_NORMAL;
    240 	} else {
    241 		DPRINTF("%s unknown battery state %02x\n",
    242 		    __func__, gstat);
    243 		return ENVSYS_BATTERY_CAPACITY_NORMAL;
    244 	}
    245 }
    246 
    247 /* The data to read is calculated from the command and the units */
    248 static void
    249 tadpmu_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    250 {
    251 	int res;
    252 
    253 	if (edata->private > 0) {
    254 		mutex_enter(&tadpmu_lock);
    255 		tadpmu_flush();
    256 		tadpmu_send_cmd(edata->private);
    257 		res = tadpmu_recv();
    258 		mutex_exit(&tadpmu_lock);
    259 		if (edata->units == ENVSYS_STEMP) {
    260 			edata->value_cur = res * 1000000 + 273150000;
    261 		} else if (edata->units == ENVSYS_SVOLTS_DC) {
    262 			edata->value_cur = res * 100000;
    263 		} else if (edata->units == ENVSYS_BATTERY_CHARGE) {
    264 			if (res & GENSTAT_BATTERY_CHARGING)
    265 				edata->value_cur = ENVSYS_INDICATOR_TRUE;
    266 			else
    267 				edata->value_cur = ENVSYS_INDICATOR_FALSE;
    268 		} else if (edata->units == ENVSYS_BATTERY_CAPACITY) {
    269 			edata->value_cur = tadpmu_battery_capacity(res);
    270 		} else {
    271 			if (edata->units == ENVSYS_INDICATOR &&
    272 			    edata->private == CMD_READ_GENSTAT) {
    273 				if (res & GENSTAT_DC_PRESENT)
    274 					edata->value_cur =
    275 					    ENVSYS_INDICATOR_TRUE;
    276 				else
    277 					edata->value_cur =
    278 					    ENVSYS_INDICATOR_FALSE;
    279 			} else {
    280 				edata->value_cur = res;
    281 			}
    282 		}
    283 		edata->state = ENVSYS_SVALID;
    284 	} else {
    285 		edata->state = ENVSYS_SINVALID;
    286 	}
    287 }
    288 
    289 static void
    290 tadpmu_events(void *cookie)
    291 {
    292 	uint8_t events, gs, vb;
    293 
    294 	while (!tadpmu_dying) {
    295 		mutex_enter(&tadpmu_lock);
    296 		tadpmu_flush();
    297 		tadpmu_send_cmd(CMD_READ_GENSTAT);
    298 		gs = tadpmu_recv();
    299 		tadpmu_send_cmd(CMD_READ_VBATT);
    300 		vb = tadpmu_recv();
    301 		mutex_exit(&tadpmu_lock);
    302 
    303 		mutex_enter(&data_lock);
    304 		events = ev_data;
    305 		mutex_exit(&data_lock);
    306 		DPRINTF("%s event %02x, status %02x/%02x\n", __func__,
    307 		    events, gs, vb);
    308 
    309 		if (events & TADPMU_EV_PWRBUTT) {
    310 			mutex_enter(&data_lock);
    311 			ev_data &= ~TADPMU_EV_PWRBUTT;
    312 			mutex_exit(&data_lock);
    313 			sysmon_pswitch_event(&tadpmu_pbutton,
    314 			    PSWITCH_EVENT_PRESSED);
    315 		}
    316 
    317 		if (events & TADPMU_EV_LID) {
    318 			mutex_enter(&data_lock);
    319 			ev_data &= ~TADPMU_EV_LID;
    320 			mutex_exit(&data_lock);
    321 			sysmon_pswitch_event(&tadpmu_lidswitch,
    322 			    gs & GENSTAT_LID_CLOSED ?
    323 		            PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
    324 		}
    325 
    326 		if (events & TADPMU_EV_DCPOWER) {
    327 			mutex_enter(&data_lock);
    328 			ev_data &= ~TADPMU_EV_DCPOWER;
    329 			mutex_exit(&data_lock);
    330 			sysmon_pswitch_event(&tadpmu_dcpower,
    331 			    gs & GENSTAT_DC_PRESENT ?
    332 		            PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
    333 		}
    334 
    335 		if (events & TADPMU_EV_BATTCHANGE) {
    336 			mutex_enter(&data_lock);
    337 			ev_data &= ~TADPMU_EV_BATTCHANGE;
    338 			mutex_exit(&data_lock);
    339 			if (gs == GENSTAT_STATE_BATTERY_DISCHARGE) {
    340 				if (vb < TADPMU_BATT_DIS_CAP_CRIT)
    341 					printf("Battery critical!\n");
    342 				else if (vb < TADPMU_BATT_DIS_CAP_WARN)
    343 					printf("Battery warning!\n");
    344 			}
    345 		}
    346 
    347 		if (events & TADPMU_EV_BATTCHARGED) {
    348 			mutex_enter(&data_lock);
    349 			ev_data &= ~TADPMU_EV_BATTCHARGED;
    350 			mutex_exit(&data_lock);
    351 			printf("Battery charged\n");
    352 		}
    353 
    354 		tsleep(tadpmuev, 0, "tadpmuev", hz);
    355 	}
    356 	kthread_exit(0);
    357 }
    358 
    359 int
    360 tadpmu_intr(void *cookie)
    361 {
    362 	uint8_t s = tadpmu_status(), d;
    363 	if (s & STATUS_INTR) {
    364 		/* interrupt message */
    365 		d = tadpmu_data();
    366 		DPRINTF("%s status change %02x\n", __func__, d);
    367 
    368 		switch (d) {
    369 			case TADPMU_INTR_POWERBUTTON:
    370 				mutex_enter(&data_lock);
    371 				ev_data |= TADPMU_EV_PWRBUTT;;
    372 				mutex_exit(&data_lock);
    373 				break;
    374 			case TADPMU_INTR_LID:
    375 				mutex_enter(&data_lock);
    376 				ev_data |= TADPMU_EV_LID;
    377 				mutex_exit(&data_lock);
    378 				break;
    379 			case TADPMU_INTR_DCPOWER:
    380 				mutex_enter(&data_lock);
    381 				ev_data |= TADPMU_EV_DCPOWER;
    382 				mutex_exit(&data_lock);
    383 				break;
    384 			case TADPMU_INTR_BATTERY_STATE:
    385 				mutex_enter(&data_lock);
    386 				ev_data |= TADPMU_EV_BATTCHANGE;
    387 				mutex_exit(&data_lock);
    388 				break;
    389 			case TADPMU_INTR_BATTERY_CHARGED:
    390 				mutex_enter(&data_lock);
    391 				ev_data |= TADPMU_EV_BATTCHARGED;
    392 				mutex_exit(&data_lock);
    393 				break;
    394 		}
    395 		/* Report events */
    396 		if (ev_data)
    397 			wakeup(tadpmuev);
    398 	}
    399 	s = tadpmu_status();
    400 	if (s & STATUS_HAVE_DATA) {
    401 		idata = tadpmu_data();
    402 		ivalid = 1;
    403 		wakeup(tadpmu);
    404 		DPRINTF("%s data %02x\n", __func__, idata);
    405 	}
    406 
    407 	return 1;
    408 }
    409 
    410 int
    411 tadpmu_init(bus_space_tag_t t, bus_space_handle_t hcmd, bus_space_handle_t hdata)
    412 {
    413 	uint8_t ver;
    414 
    415 	tadpmu_iot = t;
    416 	tadpmu_hcmd = hcmd;
    417 	tadpmu_hdata = hdata;
    418 
    419 	tadpmu_flush();
    420 	delay(1000);
    421 
    422 	tadpmu_send_cmd(CMD_READ_VERSION);
    423 	ver = tadpmu_recv();
    424 	printf("Tadpole PMU Version 1.%d\n", ver);
    425 
    426 	tadpmu_send_cmd(CMD_SET_OPMODE);
    427 	tadpmu_send(OPMODE_UNIX);
    428 
    429 #ifdef TADPMU_DEBUG
    430 	tadpmu_send_cmd(CMD_READ_SYSTEMP);
    431 	ver = tadpmu_recv();
    432 	printf("Temperature 0x%02x\n", ver);
    433 
    434 	tadpmu_send_cmd(CMD_READ_VBATT);
    435 	ver = tadpmu_recv();
    436 	printf("Battery voltage 0x%02x\n", ver);
    437 
    438 	tadpmu_send_cmd(CMD_READ_GENSTAT);
    439 	ver = tadpmu_recv();
    440 	printf("status 0x%02x\n", ver);
    441 #endif
    442 
    443 	mutex_init(&tadpmu_lock, MUTEX_DEFAULT, IPL_NONE);
    444 	mutex_init(&data_lock, MUTEX_DEFAULT, IPL_HIGH);
    445 
    446 	tadpmu_sens_sme = sysmon_envsys_create();
    447 	tadpmu_sens_sme->sme_name = "tadpmu";
    448 	tadpmu_sens_sme->sme_cookie = NULL;
    449 	tadpmu_sens_sme->sme_refresh = tadpmu_sensors_refresh;
    450 
    451 	tadpmu_acad_sme = sysmon_envsys_create();
    452 	tadpmu_acad_sme->sme_name = "ac adapter";
    453 	tadpmu_acad_sme->sme_cookie = NULL;
    454 	tadpmu_acad_sme->sme_refresh = tadpmu_sensors_refresh;
    455 	tadpmu_acad_sme->sme_class = SME_CLASS_ACADAPTER;
    456 
    457 	tadpmu_batt_sme = sysmon_envsys_create();
    458 	tadpmu_batt_sme->sme_name = "battery";
    459 	tadpmu_batt_sme->sme_cookie = NULL;
    460 	tadpmu_batt_sme->sme_refresh = tadpmu_sensors_refresh;
    461 	tadpmu_batt_sme->sme_class = SME_CLASS_BATTERY;
    462 
    463 	tadpmu_sensors[0].state = ENVSYS_SINVALID;
    464 	tadpmu_sensors[0].units = ENVSYS_STEMP;
    465 	tadpmu_sensors[0].private = CMD_READ_SYSTEMP;
    466 	strcpy(tadpmu_sensors[0].desc, "systemp");
    467 	sysmon_envsys_sensor_attach(tadpmu_sens_sme, &tadpmu_sensors[0]);
    468 
    469 	tadpmu_sensors[1].state = ENVSYS_SINVALID;
    470 	tadpmu_sensors[1].units = ENVSYS_INDICATOR;
    471 	tadpmu_sensors[1].private = CMD_READ_FAN_EN;
    472 	strcpy(tadpmu_sensors[1].desc, "fan on");
    473 	sysmon_envsys_sensor_attach(tadpmu_sens_sme, &tadpmu_sensors[1]);
    474 
    475 	tadpmu_sensors[2].state = ENVSYS_SINVALID;
    476 	tadpmu_sensors[2].units = ENVSYS_INDICATOR;
    477 	tadpmu_sensors[2].private = CMD_READ_GENSTAT;
    478 	strcpy(tadpmu_sensors[2].desc, "DC power");
    479 	sysmon_envsys_sensor_attach(tadpmu_acad_sme, &tadpmu_sensors[2]);
    480 
    481 	tadpmu_sensors[3].state = ENVSYS_SINVALID;
    482 	tadpmu_sensors[3].units = ENVSYS_SVOLTS_DC;
    483 	tadpmu_sensors[3].private = CMD_READ_VBATT;
    484 	strcpy(tadpmu_sensors[3].desc, "Vbatt");
    485 	sysmon_envsys_sensor_attach(tadpmu_batt_sme, &tadpmu_sensors[3]);
    486 
    487 	tadpmu_sensors[4].state = ENVSYS_SINVALID;
    488 	tadpmu_sensors[4].units = ENVSYS_BATTERY_CAPACITY;
    489 	tadpmu_sensors[4].private = CMD_READ_GENSTAT;
    490 	/* We must provide an initial value for battery capacity */
    491 	tadpmu_sensors[4].value_cur = ENVSYS_BATTERY_CAPACITY_NORMAL;
    492 	strcpy(tadpmu_sensors[4].desc, "capacity");
    493 	sysmon_envsys_sensor_attach(tadpmu_batt_sme, &tadpmu_sensors[4]);
    494 
    495 	tadpmu_sensors[5].state = ENVSYS_SINVALID;
    496 	tadpmu_sensors[5].units = ENVSYS_BATTERY_CHARGE;
    497 	tadpmu_sensors[5].private = CMD_READ_GENSTAT;
    498 	strcpy(tadpmu_sensors[5].desc, "charging");
    499 	sysmon_envsys_sensor_attach(tadpmu_batt_sme, &tadpmu_sensors[5]);
    500 
    501 #ifdef TADPMU_DEBUG
    502 	tadpmu_sensors[6].state = ENVSYS_SINVALID;
    503 	tadpmu_sensors[6].units = ENVSYS_INTEGER;
    504 	tadpmu_sensors[6].private = CMD_READ_GENSTAT;
    505 	strcpy(tadpmu_sensors[6].desc, "genstat");
    506 	sysmon_envsys_sensor_attach(tadpmu_sens_sme, &tadpmu_sensors[6]);
    507 #endif
    508 
    509 	sysmon_envsys_register(tadpmu_sens_sme);
    510 	sysmon_envsys_register(tadpmu_acad_sme);
    511 	sysmon_envsys_register(tadpmu_batt_sme);
    512 
    513 	sysmon_task_queue_init();
    514 	memset(&tadpmu_pbutton, 0, sizeof(struct sysmon_pswitch));
    515 	tadpmu_pbutton.smpsw_name = "power";
    516 	tadpmu_pbutton.smpsw_type = PSWITCH_TYPE_POWER;
    517 	if (sysmon_pswitch_register(&tadpmu_pbutton) != 0)
    518 		aprint_error(
    519 		    "unable to register power button with sysmon\n");
    520 
    521 	memset(&tadpmu_lidswitch, 0, sizeof(struct sysmon_pswitch));
    522 	tadpmu_lidswitch.smpsw_name = "lid";
    523 	tadpmu_lidswitch.smpsw_type = PSWITCH_TYPE_LID;
    524 	if (sysmon_pswitch_register(&tadpmu_lidswitch) != 0)
    525 		aprint_error(
    526 		    "unable to register lid switch with sysmon\n");
    527 
    528 	memset(&tadpmu_dcpower, 0, sizeof(struct sysmon_pswitch));
    529 	tadpmu_dcpower.smpsw_name = "AC adapter";
    530 	tadpmu_dcpower.smpsw_type = PSWITCH_TYPE_ACADAPTER;
    531 	if (sysmon_pswitch_register(&tadpmu_dcpower) != 0)
    532 		aprint_error(
    533 		    "unable to register AC adapter with sysmon\n");
    534 
    535 	kthread_create(PRI_NONE, 0, curcpu(), tadpmu_events, NULL,
    536 	    &tadpmu_thread, "tadpmu_events");
    537 
    538 	return 0;
    539 }
    540 #endif /* HAVE_TADPMU */
    541