lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230708072835.3035398-3-quic_jprakash@quicinc.com>
Date:   Sat, 8 Jul 2023 12:58:26 +0530
From:   Jishnu Prakash <quic_jprakash@...cinc.com>
To:     <agross@...nel.org>, <devicetree@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>, <linus.walleij@...aro.org>,
        <Jonathan.Cameron@...wei.com>, <sboyd@...nel.org>,
        <dmitry.baryshkov@...aro.org>, <quic_subbaram@...cinc.com>,
        <quic_collinsd@...cinc.com>, <quic_kamalw@...cinc.com>,
        <quic_jestar@...cinc.com>, <marijn.suijten@...ainline.org>,
        <andriy.shevchenko@...ux.intel.com>,
        <krzysztof.kozlowski@...aro.org>,
        "Bjorn Andersson" <andersson@...nel.org>,
        Konrad Dybcio <konrad.dybcio@...aro.org>,
        Jonathan Cameron <jic23@...nel.org>,
        Lars-Peter Clausen <lars@...afoo.de>,
        Jishnu Prakash <quic_jprakash@...cinc.com>,
        <linux-arm-msm@...r.kernel.org>, <linux-iio@...r.kernel.org>
CC:     <linux-arm-msm-owner@...r.kernel.org>
Subject: [PATCH 02/11] iio: adc: Update driver files for ADC7 rename for QCOM PMICs

The correct name for this version of ADCs should be ADC5 Gen2
instead of ADC7. Update the driver files for this name change.

Signed-off-by: Jishnu Prakash <quic_jprakash@...cinc.com>
---
 drivers/iio/adc/qcom-spmi-adc5.c         | 93 +++++++++++++-----------
 drivers/iio/adc/qcom-vadc-common.c       | 36 ++++-----
 include/linux/iio/adc/qcom-vadc-common.h | 12 +--
 3 files changed, 73 insertions(+), 68 deletions(-)

diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index 0a4fd3a46113..3ac1ee500a67 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/bitops.h>
@@ -87,7 +88,7 @@
 /* For PMIC7 */
 #define ADC_APP_SID				0x40
 #define ADC_APP_SID_MASK			GENMASK(3, 0)
-#define ADC7_CONV_TIMEOUT			msecs_to_jiffies(10)
+#define ADC5_GEN2_CONV_TIMEOUT		msecs_to_jiffies(10)
 
 enum adc5_cal_method {
 	ADC5_NO_CAL = 0,
@@ -270,7 +271,7 @@ static int adc5_configure(struct adc5_chip *adc,
 	return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
 }
 
-static int adc7_configure(struct adc5_chip *adc,
+static int adc5_gen2_configure(struct adc5_chip *adc,
 			struct adc5_channel_prop *prop)
 {
 	int ret;
@@ -352,7 +353,7 @@ static int adc5_do_conversion(struct adc5_chip *adc,
 	return ret;
 }
 
-static int adc7_do_conversion(struct adc5_chip *adc,
+static int adc5_gen2_do_conversion(struct adc5_chip *adc,
 			struct adc5_channel_prop *prop,
 			struct iio_chan_spec const *chan,
 			u16 *data_volt, u16 *data_cur)
@@ -362,14 +363,14 @@ static int adc7_do_conversion(struct adc5_chip *adc,
 
 	mutex_lock(&adc->lock);
 
-	ret = adc7_configure(adc, prop);
+	ret = adc5_gen2_configure(adc, prop);
 	if (ret) {
 		dev_err(adc->dev, "ADC configure failed with %d\n", ret);
 		goto unlock;
 	}
 
 	/* No support for polling mode at present */
-	wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
+	wait_for_completion_timeout(&adc->complete, ADC5_GEN2_CONV_TIMEOUT);
 
 	ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
 	if (ret)
@@ -416,7 +417,7 @@ static int adc5_fwnode_xlate(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
-static int adc7_fwnode_xlate(struct iio_dev *indio_dev,
+static int adc5_gen2_fwnode_xlate(struct iio_dev *indio_dev,
 			     const struct fwnode_reference_args *iiospec)
 {
 	struct adc5_chip *adc = iio_priv(indio_dev);
@@ -471,12 +472,12 @@ static int adc5_read_raw(struct iio_dev *indio_dev,
 				mask, adc5_do_conversion);
 }
 
-static int adc7_read_raw(struct iio_dev *indio_dev,
+static int adc5_gen2_read_raw(struct iio_dev *indio_dev,
 			 struct iio_chan_spec const *chan, int *val, int *val2,
 			 long mask)
 {
 	return adc_read_raw_common(indio_dev, chan, val, val2,
-				mask, adc7_do_conversion);
+				mask, adc5_gen2_do_conversion);
 }
 
 static const struct iio_info adc5_info = {
@@ -484,9 +485,9 @@ static const struct iio_info adc5_info = {
 	.fwnode_xlate = adc5_fwnode_xlate,
 };
 
-static const struct iio_info adc7_info = {
-	.read_raw = adc7_read_raw,
-	.fwnode_xlate = adc7_fwnode_xlate,
+static const struct iio_info adc5_gen2_info = {
+	.read_raw = adc5_gen2_read_raw,
+	.fwnode_xlate = adc5_gen2_fwnode_xlate,
 };
 
 struct adc5_channels {
@@ -561,37 +562,37 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
 					SCALE_HW_CALIB_THERM_100K_PULLUP)
 };
 
-static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
-	[ADC7_REF_GND]		= ADC5_CHAN_VOLT("ref_gnd", 0,
+static const struct adc5_channels adc5_gen2_chans_pmic[ADC5_MAX_CHANNEL] = {
+	[ADC5_GEN2_REF_GND]		= ADC5_CHAN_VOLT("ref_gnd", 0,
 					SCALE_HW_CALIB_DEFAULT)
-	[ADC7_1P25VREF]		= ADC5_CHAN_VOLT("vref_1p25", 0,
+	[ADC5_GEN2_1P25VREF]		= ADC5_CHAN_VOLT("vref_1p25", 0,
 					SCALE_HW_CALIB_DEFAULT)
-	[ADC7_VPH_PWR]		= ADC5_CHAN_VOLT("vph_pwr", 1,
+	[ADC5_GEN2_VPH_PWR]		= ADC5_CHAN_VOLT("vph_pwr", 1,
 					SCALE_HW_CALIB_DEFAULT)
-	[ADC7_VBAT_SNS]		= ADC5_CHAN_VOLT("vbat_sns", 3,
+	[ADC5_GEN2_VBAT_SNS]		= ADC5_CHAN_VOLT("vbat_sns", 3,
 					SCALE_HW_CALIB_DEFAULT)
-	[ADC7_DIE_TEMP]		= ADC5_CHAN_TEMP("die_temp", 0,
-					SCALE_HW_CALIB_PMIC_THERM_PM7)
-	[ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_GPIO1_100K_PU]	= ADC5_CHAN_TEMP("gpio1_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_GPIO2_100K_PU]	= ADC5_CHAN_TEMP("gpio2_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_GPIO3_100K_PU]	= ADC5_CHAN_TEMP("gpio3_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
-	[ADC7_GPIO4_100K_PU]	= ADC5_CHAN_TEMP("gpio4_pu2", 0,
-					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN2_DIE_TEMP]		= ADC5_CHAN_TEMP("die_temp", 0,
+					SCALE_HW_CALIB_PMIC_THERM_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_GPIO1_100K_PU]	= ADC5_CHAN_TEMP("gpio1_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_GPIO2_100K_PU]	= ADC5_CHAN_TEMP("gpio2_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_GPIO3_100K_PU]	= ADC5_CHAN_TEMP("gpio3_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
+	[ADC5_GEN2_GPIO4_100K_PU]	= ADC5_CHAN_TEMP("gpio4_pu2", 0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2)
 };
 
 static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = {
@@ -652,7 +653,7 @@ static int adc5_get_fw_channel_data(struct adc5_chip *adc,
 
 	/* virtual channel number = sid << 8 | channel number */
 
-	if (adc->data->info == &adc7_info) {
+	if (adc->data->info == &adc5_gen2_info) {
 		sid = chan >> ADC_CHANNEL_OFFSET;
 		chan = chan & ADC_CHANNEL_MASK;
 	}
@@ -715,7 +716,7 @@ static int adc5_get_fw_channel_data(struct adc5_chip *adc,
 		/* Digital controller >= 5.3 have hw_settle_2 option */
 		if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
 			dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) ||
-			adc->data->info == &adc7_info)
+			adc->data->info == &adc5_gen2_info)
 			ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_2);
 		else
 			ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_1);
@@ -774,10 +775,10 @@ static const struct adc5_data adc5_data_pmic = {
 				1, 2, 4, 8, 16, 32, 64, 128},
 };
 
-static const struct adc5_data adc7_data_pmic = {
+static const struct adc5_data adc5_gen2_data_pmic = {
 	.full_scale_code_volt = 0x70e4,
-	.adc_chans = adc7_chans_pmic,
-	.info = &adc7_info,
+	.adc_chans = adc5_gen2_chans_pmic,
+	.info = &adc5_gen2_info,
 	.decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
 				{85, 340, 1360},
 	.hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
@@ -808,7 +809,11 @@ static const struct of_device_id adc5_match_table[] = {
 	},
 	{
 		.compatible = "qcom,spmi-adc7",
-		.data = &adc7_data_pmic,
+		.data = &adc5_gen2_data_pmic,
+	},
+	{
+		.compatible = "qcom,spmi-adc5-gen2",
+		.data = &adc5_gen2_data_pmic,
 	},
 	{
 		.compatible = "qcom,spmi-adc-rev2",
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index d5209f32adb3..1f4cd3be68fa 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -100,7 +100,7 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
 	{ 46,	125000 },
 };
 
-static const struct vadc_map_pt adcmap7_die_temp[] = {
+static const struct vadc_map_pt adcmap5_gen2_die_temp[] = {
 	{ 857300, 160000 },
 	{ 820100, 140000 },
 	{ 782500, 120000 },
@@ -118,7 +118,7 @@ static const struct vadc_map_pt adcmap7_die_temp[] = {
 /*
  * Resistance to temperature table for 100k pull up for NTCG104EF104.
  */
-static const struct vadc_map_pt adcmap7_100k[] = {
+static const struct vadc_map_pt adcmap5_gen2_100k[] = {
 	{ 4250657, -40960 },
 	{ 3962085, -39936 },
 	{ 3694875, -38912 },
@@ -309,7 +309,7 @@ static int qcom_vadc_scale_hw_calib_therm(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec);
-static int qcom_vadc7_scale_hw_calib_therm(
+static int qcom_vadc5_gen2_scale_hw_calib_therm(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec);
@@ -325,7 +325,7 @@ static int qcom_vadc_scale_hw_calib_die_temp(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec);
-static int qcom_vadc7_scale_hw_calib_die_temp(
+static int qcom_vadc5_gen2_scale_hw_calib_die_temp(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec);
@@ -334,11 +334,11 @@ static struct qcom_adc5_scale_type scale_adc5_fn[] = {
 	[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
 	[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
 	[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
-	[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
-					qcom_vadc7_scale_hw_calib_therm},
+	[SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2] = {
+					qcom_vadc5_gen2_scale_hw_calib_therm},
 	[SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
-	[SCALE_HW_CALIB_PMIC_THERM_PM7] = {
-					qcom_vadc7_scale_hw_calib_die_temp},
+	[SCALE_HW_CALIB_PMIC_THERM_PM5_GEN2] = {
+					qcom_vadc5_gen2_scale_hw_calib_die_temp},
 	[SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
 	[SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
 };
@@ -530,7 +530,7 @@ static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
 	return (int) voltage;
 }
 
-static int qcom_vadc7_scale_hw_calib_therm(
+static int qcom_vadc5_gen2_scale_hw_calib_therm(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec)
@@ -538,15 +538,15 @@ static int qcom_vadc7_scale_hw_calib_therm(
 	s64 resistance = adc_code;
 	int ret, result;
 
-	if (adc_code >= RATIO_MAX_ADC7)
+	if (adc_code >= RATIO_MAX_ADC5_GEN2)
 		return -EINVAL;
 
 	/* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
 	resistance *= R_PU_100K;
-	resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code);
+	resistance = div64_s64(resistance, RATIO_MAX_ADC5_GEN2 - adc_code);
 
-	ret = qcom_vadc_map_voltage_temp(adcmap7_100k,
-				 ARRAY_SIZE(adcmap7_100k),
+	ret = qcom_vadc_map_voltage_temp(adcmap5_gen2_100k,
+				 ARRAY_SIZE(adcmap5_gen2_100k),
 				 resistance, &result);
 	if (ret)
 		return ret;
@@ -595,7 +595,7 @@ static int qcom_vadc_scale_hw_calib_die_temp(
 	return 0;
 }
 
-static int qcom_vadc7_scale_hw_calib_die_temp(
+static int qcom_vadc5_gen2_scale_hw_calib_die_temp(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec)
@@ -606,7 +606,7 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
 	voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
 				prescale, data, 1);
 
-	return qcom_vadc_map_voltage_temp(adcmap7_die_temp, ARRAY_SIZE(adcmap7_die_temp),
+	return qcom_vadc_map_voltage_temp(adcmap5_gen2_die_temp, ARRAY_SIZE(adcmap5_gen2_die_temp),
 			voltage, result_mdec);
 }
 
@@ -681,10 +681,10 @@ u16 qcom_adc_tm5_gen2_temp_res_scale(int temp)
 {
 	int64_t resistance;
 
-	resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
-		ARRAY_SIZE(adcmap7_100k), temp);
+	resistance = qcom_vadc_map_temp_voltage(adcmap5_gen2_100k,
+		ARRAY_SIZE(adcmap5_gen2_100k), temp);
 
-	return div64_s64(resistance * RATIO_MAX_ADC7, resistance + R_PU_100K);
+	return div64_s64(resistance * RATIO_MAX_ADC5_GEN2, resistance + R_PU_100K);
 }
 EXPORT_SYMBOL(qcom_adc_tm5_gen2_temp_res_scale);
 
diff --git a/include/linux/iio/adc/qcom-vadc-common.h b/include/linux/iio/adc/qcom-vadc-common.h
index aa21b032e861..a926e369a3ca 100644
--- a/include/linux/iio/adc/qcom-vadc-common.h
+++ b/include/linux/iio/adc/qcom-vadc-common.h
@@ -53,7 +53,7 @@
 #define ADC5_USR_DATA_CHECK			0x8000
 
 #define R_PU_100K				100000
-#define RATIO_MAX_ADC7				BIT(14)
+#define RATIO_MAX_ADC5_GEN2			BIT(14)
 
 /*
  * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
@@ -95,12 +95,12 @@ struct vadc_linear_graph {
  *	lookup table. The hardware applies offset/slope to adc code.
  * SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
  *	100k pullup. The hardware applies offset/slope to adc code.
- * SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using
- *	lookup table for PMIC7. The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2: Returns temperature in millidegC using
+ *	lookup table for PMIC5 Gen2. The hardware applies offset/slope to adc code.
  * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
  *	The hardware applies offset/slope to adc code.
  * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
- *	The hardware applies offset/slope to adc code. This is for PMIC7.
+ *	The hardware applies offset/slope to adc code. This is for PMIC5 Gen2.
  * SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
  *	charger temperature.
  * SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
@@ -115,9 +115,9 @@ enum vadc_scale_fn_type {
 	SCALE_HW_CALIB_DEFAULT,
 	SCALE_HW_CALIB_THERM_100K_PULLUP,
 	SCALE_HW_CALIB_XOTHERM,
-	SCALE_HW_CALIB_THERM_100K_PU_PM7,
+	SCALE_HW_CALIB_THERM_100K_PU_PM5_GEN2,
 	SCALE_HW_CALIB_PMIC_THERM,
-	SCALE_HW_CALIB_PMIC_THERM_PM7,
+	SCALE_HW_CALIB_PMIC_THERM_PM5_GEN2,
 	SCALE_HW_CALIB_PM5_CHG_TEMP,
 	SCALE_HW_CALIB_PM5_SMB_TEMP,
 	SCALE_HW_CALIB_INVALID,
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ