pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
{
	int ret, i;
	int reserve_cpu;

	/* some sanity checks */
	if (hdl == NULL || hdl->handler == NULL) return -EINVAL;

	/* do the easy test first */
	if (pfm_alt_intr_handler) return -EBUSY;

	/* one at a time in the install or remove, just fail the others */
	if (!spin_trylock(&pfm_alt_install_check)) {
		return -EBUSY;
	}

	/* reserve our session */
	for_each_online_cpu(reserve_cpu) {
		ret = pfm_reserve_session(NULL, 1, reserve_cpu);
		if (ret) goto cleanup_reserve;
	}

	/* save the current system wide pmu states */
	ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
	if (ret) {
		DPRINT(("on_each_cpu() failed: %d\n", ret));
		goto cleanup_reserve;
	}

	/* officially change to the alternate interrupt handler */
	pfm_alt_intr_handler = hdl;

	spin_unlock(&pfm_alt_install_check);

	return 0;

cleanup_reserve:
	for_each_online_cpu(i) {
		/* don't unreserve more than we reserved */
		if (i >= reserve_cpu) break;

		pfm_unreserve_session(NULL, 1, i);
	}

	spin_unlock(&pfm_alt_install_check);

	return ret;
}
pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
{
	int ret, i;
	int reserve_cpu;

	 
	if (hdl == NULL || hdl->handler == NULL) return -EINVAL;

	 
	if (pfm_alt_intr_handler) return -EBUSY;

	 
	if (!spin_trylock(&pfm_alt_install_check)) {
		return -EBUSY;
	}

	 
	for_each_online_cpu(reserve_cpu) {
		ret = pfm_reserve_session(NULL, 1, reserve_cpu);
		if (ret) goto cleanup_reserve;
	}

	 
	ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
	if (ret) {
		DPRINT(("on_each_cpu() failed: %d\n", ret));
		goto cleanup_reserve;
	}

	 
	pfm_alt_intr_handler = hdl;

	spin_unlock(&pfm_alt_install_check);

	return 0;

cleanup_reserve:
	for_each_online_cpu(i) {
		 
		if (i >= reserve_cpu) break;

		pfm_unreserve_session(NULL, 1, i);
	}

	spin_unlock(&pfm_alt_install_check);

	return ret;
}