Example #1
0
static int __init get_cpu_nominal_mv_index(
	int speedo_id, int process_id, struct dvfs **cpu_dvfs)
{
	int i, j, mv;
	struct dvfs *d;
	struct clk *c;

	/*
	 * Find maximum cpu voltage that satisfies cpu_to_core dependency for
	 * nominal core voltage ("solve from cpu to core at nominal"). Clip
	 * result to the nominal cpu level for the chips with this speedo_id.
	 */
	mv = tegra3_dvfs_rail_vdd_core.nominal_millivolts;
	for (i = 0; i < MAX_DVFS_FREQS; i++) {
		if ((cpu_millivolts[i] == 0) ||
		    tegra3_get_core_floor_mv(cpu_millivolts[i]) > mv)
			break;
	}
	BUG_ON(i == 0);
	mv = cpu_millivolts[i - 1];
	BUG_ON(mv < tegra3_dvfs_rail_vdd_cpu.min_millivolts);
	mv = min(mv, tegra_cpu_speedo_mv());

	/*
	 * Find matching cpu dvfs entry, and use it to determine index to the
	 * final nominal voltage, that satisfies the following requirements:
	 * - allows CPU to run at minimum of the maximum rates specified in
	 *   the dvfs entry and clock tree
	 * - does not violate cpu_to_core dependency as determined above
	 */
	for (i = 0, j = 0; j <  ARRAY_SIZE(cpu_dvfs_table); j++) {
		d = &cpu_dvfs_table[j];
		if (match_dvfs_one(d, speedo_id, process_id)) {
			c = tegra_get_clock_by_name(d->clk_name);
			BUG_ON(!c);

			for (; i < MAX_DVFS_FREQS; i++) {
				if ((d->freqs[i] == 0) ||
				    (cpu_millivolts[i] == 0) ||
				    (mv < cpu_millivolts[i]))
					break;

				if (c->max_rate <= d->freqs[i]*d->freqs_mult) {
					i++;
					break;
				}
			}
			break;
		}
	}


	BUG_ON(i == 0);
	if (j == (ARRAY_SIZE(cpu_dvfs_table) - 1))
		pr_err("tegra3_dvfs: WARNING!!!\n"
		       "tegra3_dvfs: no cpu dvfs table found for chip speedo_id"
		       " %d and process_id %d: set CPU rate limit at %lu\n"
		       "tegra3_dvfs: WARNING!!!\n",
		       speedo_id, process_id, d->freqs[i-1] * d->freqs_mult);

	*cpu_dvfs = d;
	return (i - 1);
}
Example #2
0
int uart_console_debug_init(int default_debug_port)
{
	int debug_port_id;

	debug_port_id = get_tegra_uart_debug_port_id();
	if (debug_port_id < 0)
		debug_port_id = default_debug_port;

	if (debug_port_id < 0) {
		pr_warn("No debug console channel\n");
		return -EINVAL;
	}

	switch (debug_port_id) {
	case 0:
		/* UARTA is the debug port. */
		pr_info("Selecting UARTA as the debug console\n");
		debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uarta_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uarta_device;
		break;

	case 1:
		/* UARTB is the debug port. */
		pr_info("Selecting UARTB as the debug console\n");
		debug_uart_clk =  clk_get_sys("serial8250.0", "uartb");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uartb_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uartb_device;
		break;

	case 2:
		/* UARTC is the debug port. */
		pr_info("Selecting UARTC as the debug console\n");
		debug_uart_clk =  clk_get_sys("serial8250.0", "uartc");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uartc_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uartc_device;
		break;

	case 3:
		/* UARTD is the debug port. */
		pr_info("Selecting UARTD as the debug console\n");
		debug_uart_clk =  clk_get_sys("serial8250.0", "uartd");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uartd_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uartd_device;
		break;

#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
	case 4:
		/* UARTE is the debug port. */
		pr_info("Selecting UARTE as the debug console\n");
		debug_uart_clk =  clk_get_sys("serial8250.0", "uarte");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uarte_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uarte_device;
		break;
#endif

	default:
		pr_info("The debug console id %d is invalid, Assuming UARTA", debug_port_id);
		debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uarta_device.dev.platform_data))->mapbase;
		uart_console_debug_device = &debug_uarta_device;
		break;
	}

	if (!IS_ERR_OR_NULL(debug_uart_clk)) {
		struct clk *c;
		pr_info("The debug console clock name is %s\n",
						debug_uart_clk->name);
		c = tegra_get_clock_by_name("pll_p");
		if (IS_ERR_OR_NULL(c))
			pr_err("Not getting the parent clock pll_p\n");
		else
			clk_set_parent(debug_uart_clk, c);

		tegra_clk_prepare_enable(debug_uart_clk);
		clk_set_rate(debug_uart_clk, clk_get_rate(c));
	} else {
		pr_err("Not getting the clock for debug consolei %d\n",
			debug_port_id);
	}
	return debug_port_id;
}
static ssize_t sysfscluster_store(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	ClusterAttr type;
	ssize_t ret = count--;
	unsigned request;
	int e;
	int tmp;
	int cnt;
	struct clk *cpu_clk = tegra_get_clock_by_name("cpu");
	struct clk *cpu_g_clk = tegra_get_clock_by_name("cpu_g");
	struct clk *cpu_lp_clk = tegra_get_clock_by_name("cpu_lp");
	struct clk *new_parent = NULL;

	if (!cpu_clk || !cpu_g_clk || !cpu_lp_clk) {
		ret = -ENOSYS;
		goto fail;
	}

	TRACE_CLUSTER(("+sysfscluster_store: %p, %d\n", buf, count));

	/* The count includes data bytes follow by a line feed character. */
	if (!buf || (count < 1)) {
		ret = -EINVAL;
		goto fail;
	}

	type = GetClusterAttr(attr->attr.name);

	spin_lock(&cluster_lock);

	switch (type) {
	case ClusterAttr_Active:
		if (!strncasecmp(buf, "g", count)) {
			flags &= ~TEGRA_POWER_CLUSTER_MASK;
			flags |= TEGRA_POWER_CLUSTER_G;
		} else if (!strncasecmp(buf, "lp", count)) {
			flags &= ~TEGRA_POWER_CLUSTER_MASK;
			flags |= TEGRA_POWER_CLUSTER_LP;
		} else if (!strncasecmp(buf, "toggle", count)) {
			flags &= ~TEGRA_POWER_CLUSTER_MASK;
			if (is_lp_cluster())
				flags |= TEGRA_POWER_CLUSTER_G;
			else
				flags |= TEGRA_POWER_CLUSTER_LP;
		} else {
			PRINT_CLUSTER(("cluster/active: '%*.*s' invalid, "
				" must be g, lp, or toggle\n",
				count, count, buf));
			ret = -EINVAL;
			break;
		}
		PRINT_CLUSTER(("cluster/active -> %s\n",
			(flags & TEGRA_POWER_CLUSTER_G) ? "G" : "LP"));

		request = flags;
#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
		if (power_mode == 1) {
			request |= TEGRA_POWER_SDRAM_SELFREFRESH;
		}
#endif
		tegra_cluster_switch_set_parameters(wake_ms * 1000, request);
		new_parent = (flags & TEGRA_POWER_CLUSTER_LP) ?
			cpu_lp_clk : cpu_g_clk;
		break;

	case ClusterAttr_Immediate:
		if ((count == 1) && (*buf == '0'))
			flags &= ~TEGRA_POWER_CLUSTER_IMMEDIATE;
		else if ((count == 1) && *buf == '1')
			flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
		else {
			PRINT_CLUSTER(("cluster/immediate: '%*.*s' invalid, "
				"must be 0 or 1\n", count, count, buf));
			ret = -EINVAL;
			break;
		}
		PRINT_CLUSTER(("cluster/immediate -> %c\n",
			(flags & TEGRA_POWER_CLUSTER_IMMEDIATE) ? '1' : '0'));
		break;

	case ClusterAttr_Force:
		if ((count == 1) && (*buf == '0'))
			flags &= ~TEGRA_POWER_CLUSTER_FORCE;
		else if ((count == 1) && (*buf == '1'))
			flags |= TEGRA_POWER_CLUSTER_FORCE;
		else {
			PRINT_CLUSTER(("cluster/force: '%*.*s' invalid, "
				"must be 0 or 1\n", count, count, buf));
			ret = -EINVAL;
			break;
		}
		PRINT_CLUSTER(("cluster/force -> %c\n",
			(flags & TEGRA_POWER_CLUSTER_FORCE) ? '1' : '0'));
		break;

	case ClusterAttr_WakeMs:
		tmp = 0;
		cnt = sscanf(buf, "%d\n", &tmp);
		if ((cnt != 1) || (tmp < 0)) {
			PRINT_CLUSTER(("cluster/wake_ms: '%*.*s' is invalid\n",
				count, count, buf));
			ret = -EINVAL;
			break;
		}
		wake_ms = tmp;
		PRINT_CLUSTER(("cluster/wake_ms -> %d\n", wake_ms));
		break;

#if defined(CONFIG_PM_SLEEP) && SYSFS_CLUSTER_POWER_MODE
	case ClusterAttr_PowerMode:
		if ((count == 1) && (*buf == '2'))
			power_mode = 2;
		else if ((count == 1) && *buf == '1')
			power_mode = 1;
		else {
			PRINT_CLUSTER(("cluster/power_mode: '%*.*s' invalid, "
				"must be 2 or 1\n", count, count, buf));
			ret = -EINVAL;
			break;
		}
		PRINT_CLUSTER(("cluster/power_mode -> %d\n", power_mode));
		break;
#endif

#if DEBUG_CLUSTER_SWITCH
	case ClusterAttr_Debug:
		if ((count == 1) && (*buf == '0'))
			tegra_cluster_debug = 0;
		else if ((count == 1) && (*buf == '1'))
			tegra_cluster_debug = 1;
		else {
			PRINT_CLUSTER(("cluster/debug: '%*.*s' invalid, "
				"must be 0 or 1\n", count, count, buf));
			ret = -EINVAL;
			break;
		}
		PRINT_CLUSTER(("cluster/debug -> %d\n",tegra_cluster_debug));
		break;
#endif

	default:
		ret = -ENOENT;
		break;
	}

	spin_unlock(&cluster_lock);

	if (new_parent) {
		e = clk_set_parent(cpu_clk, new_parent);
		if (e) {
			PRINT_CLUSTER(("cluster/active: request failed (%d)\n",
				       e));
			ret = e;
		}
	}
fail:
	TRACE_CLUSTER(("-sysfscluster_store: %d\n", count));
	return ret;
}
static void __init cardhu_uart_init(void)
{
	struct clk *c;
	int i;
	struct board_info board_info;

	tegra_get_board_info(&board_info);

	for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
		c = tegra_get_clock_by_name(uart_parent_clk[i].name);
		if (IS_ERR_OR_NULL(c)) {
			pr_err("Not able to get the clock for %s\n",
						uart_parent_clk[i].name);
			continue;
		}
		uart_parent_clk[i].parent_clk = c;
		uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
	}
	cardhu_uart_pdata.parent_clk_list = uart_parent_clk;
	cardhu_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
	cardhu_loopback_uart_pdata.parent_clk_list = uart_parent_clk;
	cardhu_loopback_uart_pdata.parent_clk_count =
						ARRAY_SIZE(uart_parent_clk);
	cardhu_loopback_uart_pdata.is_loopback = true;
	tegra_uarta_device.dev.platform_data = &cardhu_uart_pdata;
	tegra_uartb_device.dev.platform_data = &cardhu_uart_pdata;
	tegra_uartc_device.dev.platform_data = &cardhu_uart_pdata;
	tegra_uartd_device.dev.platform_data = &cardhu_uart_pdata;
	/* UARTE is used for loopback test purpose */
	tegra_uarte_device.dev.platform_data = &cardhu_loopback_uart_pdata;

	/* Register low speed only if it is selected */
	if (!is_tegra_debug_uartport_hs()) {
		uart_debug_init();
		/* Clock enable for the debug channel */
		if (!IS_ERR_OR_NULL(debug_uart_clk)) {
			pr_info("The debug console clock name is %s\n",
						debug_uart_clk->name);
			c = tegra_get_clock_by_name("pll_p");
			if (IS_ERR_OR_NULL(c))
				pr_err("Not getting the parent clock pll_p\n");
			else
				clk_set_parent(debug_uart_clk, c);

			clk_enable(debug_uart_clk);
			clk_set_rate(debug_uart_clk, clk_get_rate(c));
		} else {
			pr_err("Not getting the clock %s for debug console\n",
					debug_uart_clk->name);
		}
	}

#ifdef CONFIG_TEGRA_IRDA
	if (((board_info.board_id == BOARD_E1186) ||
		(board_info.board_id == BOARD_E1198)) &&
			cardhu_irda_pdata.is_irda) {
		cardhu_irda_pdata.parent_clk_list = uart_parent_clk;
		cardhu_irda_pdata.parent_clk_count =
					ARRAY_SIZE(uart_parent_clk);

		tegra_uartb_device.dev.platform_data = &cardhu_irda_pdata;
	}
#endif

	platform_add_devices(cardhu_uart_devices,
				ARRAY_SIZE(cardhu_uart_devices));
}
Example #5
0
static int init_cpu_edp_limits_calculated(void)
{
	unsigned int max_nr_cpus = num_possible_cpus();
	unsigned int temp_idx, n_cores_idx, pwr_idx;
	unsigned int cpu_g_minf, cpu_g_maxf;
	unsigned int iddq_mA;
	unsigned int cpu_speedo_idx;
	unsigned int cap, limit;
	struct tegra_edp_limits *edp_calculated_limits;
	struct tegra_system_edp_entry *power_edp_calc_limits;
	struct tegra_edp_cpu_leakage_params *params;
	int ret;
	struct clk *clk_cpu_g = tegra_get_clock_by_name("cpu_g");
	int cpu_speedo_id = tegra_cpu_speedo_id();

	/* Determine all inputs to EDP formula */
	iddq_mA = tegra_get_cpu_iddq_value();
	ret = edp_find_speedo_idx(cpu_speedo_id, &cpu_speedo_idx);
	if (ret)
		return ret;

	switch (tegra_chip_id) {
	case TEGRA_CHIPID_TEGRA11:
		params = tegra11x_get_leakage_params(cpu_speedo_idx, NULL);
		break;
	case TEGRA_CHIPID_TEGRA3:
	case TEGRA_CHIPID_TEGRA2:
	default:
		return -EINVAL;
	}

	edp_calculated_limits = kmalloc(sizeof(struct tegra_edp_limits)
					* ARRAY_SIZE(temperatures), GFP_KERNEL);
	BUG_ON(!edp_calculated_limits);

	power_edp_calc_limits = kmalloc(sizeof(struct tegra_system_edp_entry)
				* ARRAY_SIZE(power_cap_levels), GFP_KERNEL);
	BUG_ON(!power_edp_calc_limits);

	cpu_g_minf = 0;
	cpu_g_maxf = clk_get_max_rate(clk_cpu_g);
	freq_voltage_lut_size = (cpu_g_maxf - cpu_g_minf) / FREQ_STEP + 1;
	freq_voltage_lut = kmalloc(sizeof(struct tegra_edp_freq_voltage_table)
				   * freq_voltage_lut_size, GFP_KERNEL);
	if (!freq_voltage_lut) {
		pr_err("%s: failed alloc mem for freq/voltage LUT\n", __func__);
		return -ENOMEM;
	}

	ret = edp_relate_freq_voltage(clk_cpu_g, cpu_speedo_idx,
				freq_voltage_lut_size, freq_voltage_lut);
	if (ret) {
		kfree(freq_voltage_lut);
		return ret;
	}

	if (freq_voltage_lut_size != freq_voltage_lut_size_saved) {
		/* release previous table if present */
		kfree(freq_voltage_lut_saved);
		/* create table to save */
		freq_voltage_lut_saved =
			kmalloc(sizeof(struct tegra_edp_freq_voltage_table) *
			freq_voltage_lut_size, GFP_KERNEL);
		if (!freq_voltage_lut_saved) {
			pr_err("%s: failed alloc mem for freq/voltage LUT\n",
				__func__);
			kfree(freq_voltage_lut);
			return -ENOMEM;
		}
		freq_voltage_lut_size_saved = freq_voltage_lut_size;
	}
	memcpy(freq_voltage_lut_saved,
		freq_voltage_lut,
		sizeof(struct tegra_edp_freq_voltage_table) *
			freq_voltage_lut_size);

	/* Calculate EDP table */
	for (n_cores_idx = 0; n_cores_idx < max_nr_cpus; n_cores_idx++) {
		for (temp_idx = 0;
		     temp_idx < ARRAY_SIZE(temperatures); temp_idx++) {
			edp_calculated_limits[temp_idx].temperature =
				temperatures[temp_idx];
			limit = edp_calculate_maxf(params,
						   temperatures[temp_idx],
						   -1,
						   iddq_mA,
						   n_cores_idx);
			if (limit == -EINVAL)
				return -EINVAL;
			/* apply safety cap if it is specified */
			if (n_cores_idx < 4) {
				cap = params->safety_cap[n_cores_idx];
				if (cap && cap < limit)
					limit = cap;
			}
			edp_calculated_limits[temp_idx].
				freq_limits[n_cores_idx] = limit;
		}

		for (pwr_idx = 0;
		     pwr_idx < ARRAY_SIZE(power_cap_levels); pwr_idx++) {
			power_edp_calc_limits[pwr_idx].power_limit_100mW =
				power_cap_levels[pwr_idx] / 100;
			limit = edp_calculate_maxf(params,
						   50,
						   power_cap_levels[pwr_idx],
						   iddq_mA,
						   n_cores_idx);
			if (limit == -EINVAL)
				return -EINVAL;
			power_edp_calc_limits[pwr_idx].
				freq_limits[n_cores_idx] = limit;
		}
	}

	/*
	 * If this is an EDP table update, need to overwrite old table.
	 * The old table's address must remain valid.
	 */
	if (edp_limits != edp_default_limits) {
		memcpy(edp_limits, edp_calculated_limits,
		       sizeof(struct tegra_edp_limits)
		       * ARRAY_SIZE(temperatures));
		kfree(edp_calculated_limits);
	}
	else {
		edp_limits = edp_calculated_limits;
		edp_limits_size = ARRAY_SIZE(temperatures);
	}

	if (power_edp_limits != power_edp_default_limits) {
		memcpy(power_edp_limits, power_edp_calc_limits,
		       sizeof(struct tegra_system_edp_entry)
		       * ARRAY_SIZE(power_cap_levels));
		kfree(power_edp_calc_limits);
	} else {
		power_edp_limits = power_edp_calc_limits;
		power_edp_limits_size = ARRAY_SIZE(power_cap_levels);
	}

	kfree(freq_voltage_lut);
	return 0;
}
static struct clk *isa1200_vibrator_get_clk(void)
{
	return tegra_get_clock_by_name("clk_dev2");
}
static int __init cardhu_touch_init(void)
{
	struct board_info BoardInfo, DisplayBoardInfo;
	int ret;

	tegra_get_board_info(&BoardInfo);
	tegra_get_display_board_info(&DisplayBoardInfo);
	if ((DisplayBoardInfo.board_id == BOARD_DISPLAY_PM313)
						|| CARDHU_DT_PLATFORM) {
		tegra_clk_init_from_table(spi_clk_init_table);
		tegra_clk_init_from_table(touch_clk_init_table);
		tegra_clk_prepare_enable(tegra_get_clock_by_name("clk_out_3"));
		rm31080a_cardhu_spi_board[0].irq = gpio_to_irq(TOUCH_GPIO_IRQ_RAYDIUM_SPI);
		touch_init_raydium(TOUCH_GPIO_IRQ_RAYDIUM_SPI,
					TOUCH_GPIO_RST_RAYDIUM_SPI,
					&rm31080ts_cardhu_data,
					&rm31080a_cardhu_spi_board[0],
					ARRAY_SIZE(rm31080a_cardhu_spi_board));
	} else {
		ret = gpio_request(TEGRA_GPIO_PH4, "atmel-irq");
		if (ret < 0) {
			pr_err("%s() Error in gpio_request() for gpio %d\n",
					__func__, ret);
		}
		ret = gpio_direction_input(TEGRA_GPIO_PH4);
		if (ret < 0) {
			pr_err("%s() Error in setting gpio %d to in/out\n",
					 __func__, ret);
			gpio_free(TEGRA_GPIO_PH4);
		}
		ret = gpio_request(TEGRA_GPIO_PH6, "atmel-reset");
		if (ret < 0) {
			pr_err("%s() Error in gpio_request() for gpio %d\n",
					__func__, ret);
		}
		ret = gpio_direction_output(TEGRA_GPIO_PH6, 0);
		if (ret < 0) {
			pr_err("%s() Error in setting gpio %d to in/out\n",
					 __func__, ret);
			gpio_free(TEGRA_GPIO_PH6);
		}
		msleep(1);
		gpio_set_value(TEGRA_GPIO_PH6, 1);
		msleep(100);

		tegra_get_board_info(&BoardInfo);
		if ((BoardInfo.sku & SKU_TOUCH_MASK) == SKU_TOUCH_2000)
			strncpy(atmel_mxt_info.mxt_cfg_name,
				"Android_Cardhu_SKU2000_2012-12-18.cfg",
				CFG_NAME_SIZE);

		if (DisplayBoardInfo.board_id == BOARD_DISPLAY_E1506) {
			strncpy(atmel_mxt_info.mxt_cfg_name,
			"Android_Cardhu_Verbier_E1506_2012-12-18.cfg",
			CFG_NAME_SIZE);
			e1506_atmel_i2c_info[0].irq = gpio_to_irq(TEGRA_GPIO_PH4);
			i2c_register_board_info(1, e1506_atmel_i2c_info, 1);
		} else {
			atmel_i2c_info[0].irq = gpio_to_irq(TEGRA_GPIO_PH4);
			i2c_register_board_info(1, atmel_i2c_info, 1);
		}
	}

	return 0;
}
Example #8
0
int boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	int status;

	/* Avoid timer calibration on slave cpus. Use the value calibrated
	 * on master cpu. This reduces the bringup time for each slave cpu
	 * by around 260ms.
	 */
	preset_lpj = loops_per_jiffy;
	if (is_lp_cluster()) {
		struct clk *cpu_clk, *cpu_g_clk;

		/* The G CPU may not be available for a variety of reasons. */
		status = is_g_cluster_available(cpu);
		if (status)
			goto done;

		cpu_clk = tegra_get_clock_by_name("cpu");
		cpu_g_clk = tegra_get_clock_by_name("cpu_g");

		/* Switch to G CPU before continuing. */
		if (!cpu_clk || !cpu_g_clk) {
			/* Early boot, clock infrastructure is not initialized
			   - CPU mode switch is not allowed */
			status = -EINVAL;
		} else {
#ifdef CONFIG_CPU_FREQ
			/* set cpu rate is within g-mode range before switch */
			unsigned int speed = max(
				(unsigned long)tegra_getspeed(0),
				clk_get_min_rate(cpu_g_clk) / 1000);
			tegra_update_cpu_speed(speed);
#endif
			status = clk_set_parent(cpu_clk, cpu_g_clk);
		}

		if (status)
			goto done;
	}

	smp_wmb();

	/* Force the CPU into reset. The CPU must remain in reset when the
	   flow controller state is cleared (which will cause the flow
	   controller to stop driving reset if the CPU has been power-gated
	   via the flow controller). This will have no effect on first boot
	   of the CPU since it should already be in reset. */
	writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
	dmb();

	/* Unhalt the CPU. If the flow controller was used to power-gate the
	   CPU this will cause the flow controller to stop driving reset.
	   The CPU will remain in reset because the clock and reset block
	   is now driving reset. */
	flowctrl_writel(0, FLOW_CTRL_HALT_CPU(cpu));

	status = power_up_cpu(cpu);
	if (status)
		goto done;

	/* Take the CPU out of reset. */
	writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
	wmb();
done:
	return status;
}
static void __init uart_debug_init(void)
{
	unsigned long rate;
	struct clk *debug_uart_clk;
	struct clk *c;
	int modem_id = tegra_get_modem_id();

	if (modem_id == 0x1) {
		/* UARTB is the debug port. */
		pr_info("Selecting UARTB as the debug console\n");
		whistler_uart_devices[1] = &debug_uartb_device;
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uartb_device.dev.platform_data))->mapbase;
		debug_uart_clk = clk_get_sys("serial8250.0", "uartb");

		/* Clock enable for the debug channel */
		if (!IS_ERR_OR_NULL(debug_uart_clk)) {
			rate = ((struct plat_serial8250_port *)(
			debug_uartb_device.dev.platform_data))->uartclk;
			pr_info("The debug console clock name is %s\n",
						debug_uart_clk->name);
			c = tegra_get_clock_by_name("pll_p");
			if (IS_ERR_OR_NULL(c))
				pr_err("Not getting the parent clock pll_p\n");
			else
				clk_set_parent(debug_uart_clk, c);

			clk_enable(debug_uart_clk);
			clk_set_rate(debug_uart_clk, rate);
		} else {
			pr_err("Not getting the clock %s for debug console\n",
						debug_uart_clk->name);
		}
	} else {
		/* UARTA is the debug port. */
		pr_info("Selecting UARTA as the debug console\n");
		whistler_uart_devices[0] = &debug_uarta_device;
		debug_uart_port_base = ((struct plat_serial8250_port *)(
			debug_uarta_device.dev.platform_data))->mapbase;
		debug_uart_clk = clk_get_sys("serial8250.0", "uarta");

		/* Clock enable for the debug channel */
		if (!IS_ERR_OR_NULL(debug_uart_clk)) {
			rate = ((struct plat_serial8250_port *)(
			debug_uarta_device.dev.platform_data))->uartclk;
			pr_info("The debug console clock name is %s\n",
						debug_uart_clk->name);
			c = tegra_get_clock_by_name("pll_p");
			if (IS_ERR_OR_NULL(c))
				pr_err("Not getting the parent clock pll_p\n");
			else
				clk_set_parent(debug_uart_clk, c);

			clk_enable(debug_uart_clk);
			clk_set_rate(debug_uart_clk, rate);
		} else {
			pr_err("Not getting the clock %s for debug console\n",
						debug_uart_clk->name);
		}
	}
}