Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1466902 > unrolled thread

[PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC

Started byChen-Yu Tsai <wens@csie.org>
First post2016-08-21 05:10 +0200
Last post2016-08-21 09:20 +0200
Articles 10 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
    [PATCH 8/9] ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and regulators Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
    [PATCH 9/9] ARM: dts: sun9i: a80-optimus: Disable EHCI1 Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
    [PATCH 4/9] regulator: axp20x: support AXP806 variant Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
      Re: [PATCH 4/9] regulator: axp20x: support AXP806 variant Mark Brown <broonie@kernel.org> - 2016-08-22 19:00 +0200
    [PATCH 5/9] ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
    [PATCH 7/9] ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and regulators Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
    [PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC Chen-Yu Tsai <wens@csie.org> - 2016-08-21 05:10 +0200
      Re: [linux-sunxi] [PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC Julian Calaby <julian.calaby@gmail.com> - 2016-08-21 06:20 +0200
    Re: [linux-sunxi] [PATCH 0/9] mfd: axp20x: Add support for AXP809  PMIC Priit Laes <plaes@plaes.org> - 2016-08-21 09:20 +0200

#1466902 — [PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC
Message-ID<s8rj4-3iz-3@gated-at.bofh.it>
Hi everyone,

This series adds support for X-Powers' AXP806 PMIC. This is the secondary
PMIC accompanying Allwinner's A80 SoC. For now, only the regulators are
supported. While the AXP806 supports standalone operation, no hardware
exists, so this will not be supported.

Patch 1 adds AXP806 to the axp20x bindings.

Patch 2 adds AXP806 support to the axp20x mfd driver.

Patch 3 fixes regulator output adjustment during regulator registration
so it doesn't fail if the higher or lower bounds of its voltage constraints
don't match up with the regulator's voltage granularity.

Patch 4 adds AXP806 support to the axp20x regulator driver.

Patch 5 adds the unused SW switch output of the AXP809 PMIC on the A80
Optimus board. This was accidentally left out of the AXP809 series.

Patch 6 adds the unused SW switch output of the AXP809 PMIC on the
Cubieboard 4. This was accidentally left out of the AXP809 series.

Patch 7 enables AXP809 support on the A80 Optimus board.

Patch 8 enables AXP809 support on the Cubieboard 4.

Patch 9 disables EHCI1 on the A80 Optimus board.


Regards
ChenYu

Chen-Yu Tsai (9):
  mfd: axp20x: Add bindings for AXP806 PMIC
  mfd: axp20x: Add support for AXP806 PMIC
  regulator: core: Try full range when adjusting regulators to
    constraints
  regulator: axp20x: support AXP806 variant
  ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused
  ARM: dts: sun9i: cubieboard4: Declare AXP809 SW regulator as unused
  ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and
    regulators
  ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and
    regulators
  ARM: dts: sun9i: a80-optimus: Disable EHCI1

 Documentation/devicetree/bindings/mfd/axp20x.txt |  28 +++++-
 arch/arm/boot/dts/sun9i-a80-cubieboard4.dts      | 116 +++++++++++++++++++++
 arch/arm/boot/dts/sun9i-a80-optimus.dts          | 123 ++++++++++++++++++++++-
 drivers/mfd/axp20x-rsb.c                         |   1 +
 drivers/mfd/axp20x.c                             |  72 +++++++++++++
 drivers/regulator/axp20x-regulator.c             | 117 +++++++++++++++++++--
 drivers/regulator/core.c                         |   8 +-
 include/linux/mfd/axp20x.h                       |  60 +++++++++++
 8 files changed, 508 insertions(+), 17 deletions(-)

-- 
2.9.3

[toc] | [next] | [standalone]


#1466903 — [PATCH 8/9] ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and regulators

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 8/9] ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and regulators
Message-ID<s8rj4-3iz-9@gated-at.bofh.it>
In reply to#1466902
The AXP806 PMIC is the secondary PMIC. It provides various supply
voltages for the SoC and other peripherals. The PMIC's interrupt
line is connected to NMI pin of the SoC.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80-cubieboard4.dts | 112 ++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
index 910b29f0f0b5..e38ac4fec10c 100644
--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
@@ -260,6 +260,118 @@
 		};
 	};
 
+	axp806: pmic@745 {
+		compatible = "x-powers,axp806";
+		reg = <0x745>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bldoin-supply = <&reg_dcdce>;
+
+		regulators {
+			reg_s_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "avcc";
+			};
+
+			aldo2 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo2";
+			};
+
+			aldo3 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo3";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-name = "vcc18-efuse-adc-display-csi";
+			};
+
+			reg_bldo2: bldo2 {
+				regulator-always-on;
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-name =
+					"vdd18-drampll-vcc18-pll-cpvdd";
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			reg_bldo4: bldo4 {
+				regulator-min-microvolt = <1080000>;
+				regulator-max-microvolt = <1320000>;
+				regulator-name = "vcc12-hsic";
+			};
+
+			reg_cldo1: cldo1 {
+				/*
+				 * This was 3V in the original design, but
+				 * 3.3V is the recommended supply voltage
+				 * for the Ethernet PHY.
+				 */
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-gmac-phy";
+			};
+
+			reg_cldo2: cldo2 {
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-name = "afvcc-cam";
+			};
+
+			reg_cldo3: cldo3 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc-io-wifi-codec-io2";
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpub";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-vpu";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-always-on;
+				regulator-min-microvolt = <2100000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-name = "vcc-bldo-codec-ldoin";
+			};
+
+			sw {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's sw
+				 */
+				regulator-name = "s_sw";
+			};
+		};
+	};
+
 	ac100: codec@e89 {
 		compatible = "x-powers,ac100";
 		reg = <0xe89>;
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1466904 — [PATCH 9/9] ARM: dts: sun9i: a80-optimus: Disable EHCI1

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 9/9] ARM: dts: sun9i: a80-optimus: Disable EHCI1
Message-ID<s8rj4-3iz-13@gated-at.bofh.it>
In reply to#1466902
EHCI1 provides an HSIC interface. This interface is exposed on the
board through two pins among the GPIO header.

With the PHY now powered up and responding, enabling the interface when
nothing is connected results in a lot of error messages:

	usb 2-1: device descriptor read/64, error -71
	usb 2-1: device descriptor read/64, error -71
	usb 2-1: new high-speed USB device number 3 using ehci-platform
	usb 2-1: device descriptor read/64, error -71
	usb 2-1: device descriptor read/64, error -71
	usb 2-1: new high-speed USB device number 4 using ehci-platform
	usb 2-1: device not accepting address 4, error -71
	usb 2-1: new high-speed USB device number 5 using ehci-platform
	usb 2-1: device not accepting address 5, error -71
	usb usb2-port1: unable to enumerate USB device

Disable it by default, but leave the entries in the board DTS.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80-optimus.dts | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index aeb4037c8768..536a7d1d678b 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -112,7 +112,8 @@
 };
 
 &ehci1 {
-	status = "okay";
+	/* Enable if HSIC peripheral is connected */
+	status = "disabled";
 };
 
 &ehci2 {
@@ -484,7 +485,8 @@
 
 &usbphy2 {
 	phy-supply = <&reg_bldo4>;
-	status = "okay";
+	/* Enable if HSIC peripheral is connected */
+	status = "disabled";
 };
 
 &usbphy3 {
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1466905 — [PATCH 4/9] regulator: axp20x: support AXP806 variant

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 4/9] regulator: axp20x: support AXP806 variant
Message-ID<s8rj4-3iz-11@gated-at.bofh.it>
In reply to#1466902
The X-Powers AXP806 PMIC has a new set of buck and LDO regulators, and
also a switch. The buck regulators support teaming into multi-phase
groups, with A+B, A+B+C, D+E groupings.

Some registers controlling DCDC converter work settings are at different
offsets. Deal with them as well.

Add support for this new variant.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/regulator/axp20x-regulator.c | 117 ++++++++++++++++++++++++++++++++---
 1 file changed, 110 insertions(+), 7 deletions(-)

diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 6d9ac76a772f..ac5d97b78dce 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -244,16 +244,64 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
 	.ops		= &axp20x_ops_sw,
 };
 
-static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
-	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000),
-	REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000),
+static const struct regulator_linear_range axp806_dcdca_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
+	REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
+};
+
+static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2d, 20000),
+	REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000),
 };
 
-static const struct regulator_linear_range axp809_dldo1_ranges[] = {
+static const struct regulator_linear_range axp806_cldo2_ranges[] = {
 	REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
 	REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
 };
 
+static const struct regulator_desc axp806_regulators[] = {
+	AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges,
+			72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
+			BIT(0)),
+	AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50,
+		 AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(1)),
+	AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges,
+			72, AXP806_DCDCC_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
+			BIT(2)),
+	AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind", axp806_dcdcd_ranges,
+			64, AXP806_DCDCD_V_CTRL, 0x3f, AXP806_PWR_OUT_CTRL1,
+			BIT(3)),
+	AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100,
+		 AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(4)),
+	AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
+		 AXP806_ALDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(5)),
+	AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100,
+		 AXP806_ALDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(6)),
+	AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
+		 AXP806_ALDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(7)),
+	AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100,
+		 AXP806_BLDO1_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(0)),
+	AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100,
+		 AXP806_BLDO2_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(1)),
+	AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100,
+		 AXP806_BLDO3_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(2)),
+	AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100,
+		 AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)),
+	AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
+		 AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)),
+	AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp806_cldo2_ranges,
+			32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2,
+			BIT(5)),
+	AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
+		 AXP806_CLDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(6)),
+	AXP_DESC_SW(AXP806, SW, "sw", "swin", AXP806_PWR_OUT_CTRL2, BIT(7)),
+};
+
+static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000),
+	REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000),
+};
+
 static const struct regulator_desc axp809_regulators[] = {
 	AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
 		 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
@@ -278,7 +326,7 @@ static const struct regulator_desc axp809_regulators[] = {
 		 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
 	AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
 		 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
-	AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp809_dldo1_ranges,
+	AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp806_cldo2_ranges,
 			32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
 			BIT(3)),
 	AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
@@ -302,6 +350,7 @@ static const struct regulator_desc axp809_regulators[] = {
 static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
 {
 	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	unsigned int reg = AXP20X_DCDC_FREQ;
 	u32 min, max, def, step;
 
 	switch (axp20x->variant) {
@@ -312,6 +361,14 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
 		def = 1500;
 		step = 75;
 		break;
+	case AXP806_ID:
+		/*
+		 * AXP806 DCDC work frequency setting has the same range and
+		 * step as AXP22X, but at a different register.
+		 * Fall through to the check below.
+		 * (See include/linux/mfd/axp20x.h)
+		 */
+		reg = AXP806_DCDC_FREQ_CTRL;
 	case AXP221_ID:
 	case AXP223_ID:
 	case AXP809_ID:
@@ -343,7 +400,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
 
 	dcdcfreq = (dcdcfreq - min) / step;
 
-	return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
+	return regmap_update_bits(axp20x->regmap, reg,
 				  AXP20X_FREQ_DCDC_MASK, dcdcfreq);
 }
 
@@ -377,6 +434,7 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
 static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
 {
 	struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
+	unsigned int reg = AXP20X_DCDC_MODE;
 	unsigned int mask;
 
 	switch (axp20x->variant) {
@@ -392,6 +450,13 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
 		workmode <<= ffs(mask) - 1;
 		break;
 
+	case AXP806_ID:
+		reg = AXP806_DCDC_MODE_CTRL2;
+		/*
+		 * AXP806 DCDC regulator IDs have the same range as AXP22X.
+		 * Fall through to the check below.
+		 * (See include/linux/mfd/axp20x.h)
+		 */
 	case AXP221_ID:
 	case AXP223_ID:
 	case AXP809_ID:
@@ -408,7 +473,33 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
 		return -EINVAL;
 	}
 
-	return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
+	return regmap_update_bits(rdev->regmap, reg, mask, workmode);
+}
+
+/*
+ * This function checks whether a regulator is part of a poly-phase
+ * output setup based on the registers settings. Returns true if it is.
+ */
+static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
+{
+	u32 reg = 0;
+
+	/* Only AXP806 has poly-phase outputs */
+	if (axp20x->variant != AXP806_ID)
+		return false;
+
+	regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
+
+	if (id == AXP806_DCDCB) {
+		return (((reg & GENMASK(7, 6)) == BIT(6)) ||
+			((reg & GENMASK(7, 6)) == BIT(7)));
+	} else if (id == AXP806_DCDCC) {
+		return ((reg & GENMASK(7, 6)) == BIT(7));
+	} else if (id == AXP806_DCDCE) {
+		return !!(reg & BIT(5));
+	}
+
+	return false;
 }
 
 static int axp20x_regulator_probe(struct platform_device *pdev)
@@ -440,6 +531,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
 		drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
 						  "x-powers,drive-vbus-en");
 		break;
+	case AXP806_ID:
+		regulators = axp806_regulators;
+		nregulators = AXP806_REG_ID_MAX;
+		break;
 	case AXP809_ID:
 		regulators = axp809_regulators;
 		nregulators = AXP809_REG_ID_MAX;
@@ -458,6 +553,14 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
 		struct regulator_desc *new_desc;
 
 		/*
+		 * If this regulator is a slave in a poly-phase setup,
+		 * skip it, as its controls are bound to the master
+		 * regulator and won't work.
+		 */
+		if (axp20x_is_polyphase_slave(axp20x, i))
+			continue;
+
+		/*
 		 * Regulators DC1SW and DC5LDO are connected internally,
 		 * so we have to handle their supply names separately.
 		 *
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1467811 — Re: [PATCH 4/9] regulator: axp20x: support AXP806 variant

FromMark Brown <broonie@kernel.org>
Date2016-08-22 19:00 +0200
SubjectRe: [PATCH 4/9] regulator: axp20x: support AXP806 variant
Message-ID<s90JP-my-13@gated-at.bofh.it>
In reply to#1466905

[Multipart message — attachments visible in raw view] — view raw

On Sun, Aug 21, 2016 at 10:11:20AM +0800, Chen-Yu Tsai wrote:

> +	if (id == AXP806_DCDCB) {
> +		return (((reg & GENMASK(7, 6)) == BIT(6)) ||
> +			((reg & GENMASK(7, 6)) == BIT(7)));
> +	} else if (id == AXP806_DCDCC) {
> +		return ((reg & GENMASK(7, 6)) == BIT(7));
> +	} else if (id == AXP806_DCDCE) {
> +		return !!(reg & BIT(5));
> +	}

This looks like you're trying to write a switch statement, please do
that.

[toc] | [prev] | [next] | [standalone]


#1466906 — [PATCH 5/9] ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 5/9] ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused
Message-ID<s8rj4-3iz-17@gated-at.bofh.it>
In reply to#1466902
The AXP809's SW (switch) regulator is unused on the A80 Optimus.
Add an empty node for it so that the OS can generate constraints.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80-optimus.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index fd874ded890e..caf0091e71ba 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -325,6 +325,10 @@
 			reg_rtc_ldo: rtc_ldo {
 				regulator-name = "vcc-rtc-vdd1v8-io";
 			};
+
+			sw {
+				/* unused */
+			};
 		};
 	};
 
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1466907 — [PATCH 7/9] ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and regulators

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 7/9] ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and regulators
Message-ID<s8rj4-3iz-19@gated-at.bofh.it>
In reply to#1466902
The AXP806 PMIC is the secondary PMIC. It provides various supply
voltages for the SoC and other peripherals. The PMIC's interrupt
line is connected to NMI pin of the SoC.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun9i-a80-optimus.dts | 113 ++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index caf0091e71ba..aeb4037c8768 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -332,6 +332,118 @@
 		};
 	};
 
+	axp806: pmic@745 {
+		compatible = "x-powers,axp806";
+		reg = <0x745>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bldoin-supply = <&reg_dcdce>;
+
+		regulators {
+			reg_s_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "avcc";
+			};
+
+			aldo2 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo2";
+			};
+
+			aldo3 {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's aldo's
+				 */
+				regulator-name = "s_aldo3";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-name = "vcc18-efuse-adc-display-csi";
+			};
+
+			reg_bldo2: bldo2 {
+				regulator-always-on;
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-name =
+					"vdd18-drampll-vcc18-pll-cpvdd";
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			reg_bldo4: bldo4 {
+				regulator-min-microvolt = <1080000>;
+				regulator-max-microvolt = <1320000>;
+				regulator-name = "vcc12-hsic";
+			};
+
+			reg_cldo1: cldo1 {
+				/*
+				 * This was 3V in the original design, but
+				 * 3.3V is the recommended supply voltage
+				 * for the Ethernet PHY.
+				 */
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-gmac-phy";
+			};
+
+			reg_cldo2: cldo2 {
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-name = "afvcc-cam";
+			};
+
+			reg_cldo3: cldo3 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc-io-wifi-codec-io2";
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpub";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-vpu";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-always-on;
+				regulator-min-microvolt = <2100000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-name = "vcc-bldo-codec-ldoin";
+			};
+
+			sw {
+				/*
+				 * unused, but use a different name to
+				 * avoid name clash with axp809's sw
+				 */
+				regulator-name = "s_sw";
+			};
+		};
+	};
+
 	ac100: codec@e89 {
 		compatible = "x-powers,ac100";
 		reg = <0xe89>;
@@ -371,6 +483,7 @@
 };
 
 &usbphy2 {
+	phy-supply = <&reg_bldo4>;
 	status = "okay";
 };
 
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1466908 — [PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC

FromChen-Yu Tsai <wens@csie.org>
Date2016-08-21 05:10 +0200
Subject[PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC
Message-ID<s8rj4-3iz-7@gated-at.bofh.it>
In reply to#1466902
The X-Powers AXP809 is a new PMIC that is paired with Allwinner's A80
SoC, along with a master AXP809 PMIC.

This PMIC has a new register layout, and supports some functions not
seen in other X-Powers PMICs, such as master-slave mode, or having
multiple AXP806 PMICs on the same bus with address space extension,
or supporting both I2C and RSB mode. I2C has not been tested.

This patch adds support for the interrupts of the PMIC. A regulator
sub-device is enabled, but actual regulator support will come in a
later patch.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/mfd/axp20x-rsb.c   |  1 +
 drivers/mfd/axp20x.c       | 72 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h | 60 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)

diff --git a/drivers/mfd/axp20x-rsb.c b/drivers/mfd/axp20x-rsb.c
index a407527bcd09..a732cb50bcff 100644
--- a/drivers/mfd/axp20x-rsb.c
+++ b/drivers/mfd/axp20x-rsb.c
@@ -61,6 +61,7 @@ static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
 
 static const struct of_device_id axp20x_rsb_of_match[] = {
 	{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+	{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
 	{ .compatible = "x-powers,axp809", .data = (void *)AXP809_ID },
 	{ },
 };
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index fd80b0981f0f..96102753847f 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -38,6 +38,7 @@ static const char * const axp20x_model_names[] = {
 	"AXP221",
 	"AXP223",
 	"AXP288",
+	"AXP806",
 	"AXP809",
 };
 
@@ -129,6 +130,27 @@ static const struct regmap_access_table axp288_volatile_table = {
 	.n_yes_ranges	= ARRAY_SIZE(axp288_volatile_ranges),
 };
 
+static const struct regmap_range axp806_writeable_ranges[] = {
+	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
+	regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
+	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
+	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
+};
+
+static const struct regmap_range axp806_volatile_ranges[] = {
+	regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
+};
+
+static const struct regmap_access_table axp806_writeable_table = {
+	.yes_ranges	= axp806_writeable_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp806_writeable_ranges),
+};
+
+static const struct regmap_access_table axp806_volatile_table = {
+	.yes_ranges	= axp806_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
+};
+
 static struct resource axp152_pek_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -278,6 +300,15 @@ static const struct regmap_config axp288_regmap_config = {
 	.cache_type	= REGCACHE_RBTREE,
 };
 
+static const struct regmap_config axp806_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.wr_table	= &axp806_writeable_table,
+	.volatile_table	= &axp806_volatile_table,
+	.max_register	= AXP806_VREF_TEMP_WARN_L,
+	.cache_type	= REGCACHE_RBTREE,
+};
+
 #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask)			\
 	[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
 
@@ -409,6 +440,21 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
 	INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG,            5, 1),
 };
 
+static const struct regmap_irq axp806_regmap_irqs[] = {
+	INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1,	0, 0),
+	INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2,	0, 1),
+	INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW,		0, 3),
+	INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW,		0, 4),
+	INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW,		0, 5),
+	INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW,		0, 6),
+	INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW,		0, 7),
+	INIT_REGMAP_IRQ(AXP806, PWROK_LONG,		1, 0),
+	INIT_REGMAP_IRQ(AXP806, PWROK_SHORT,		1, 1),
+	INIT_REGMAP_IRQ(AXP806, WAKEUP,			1, 4),
+	INIT_REGMAP_IRQ(AXP806, PWROK_FALL,		1, 5),
+	INIT_REGMAP_IRQ(AXP806, PWROK_RISE,		1, 6),
+};
+
 static const struct regmap_irq axp809_regmap_irqs[] = {
 	INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V,		0, 7),
 	INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN,		0, 6),
@@ -494,6 +540,18 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
 
 };
 
+static const struct regmap_irq_chip axp806_regmap_irq_chip = {
+	.name			= "axp806",
+	.status_base		= AXP20X_IRQ1_STATE,
+	.ack_base		= AXP20X_IRQ1_STATE,
+	.mask_base		= AXP20X_IRQ1_EN,
+	.mask_invert		= true,
+	.init_ack_masked	= true,
+	.irqs			= axp806_regmap_irqs,
+	.num_irqs		= ARRAY_SIZE(axp806_regmap_irqs),
+	.num_regs		= 2,
+};
+
 static const struct regmap_irq_chip axp809_regmap_irq_chip = {
 	.name			= "axp809",
 	.status_base		= AXP20X_IRQ1_STATE,
@@ -660,12 +718,20 @@ static struct mfd_cell axp288_cells[] = {
 	},
 };
 
+static struct mfd_cell axp806_cells[] = {
+	{
+		.id			= 2,
+		.name			= "axp20x-regulator",
+	},
+};
+
 static struct mfd_cell axp809_cells[] = {
 	{
 		.name			= "axp20x-pek",
 		.num_resources		= ARRAY_SIZE(axp809_pek_resources),
 		.resources		= axp809_pek_resources,
 	}, {
+		.id			= 1,
 		.name			= "axp20x-regulator",
 	},
 };
@@ -732,6 +798,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
 		axp20x->regmap_cfg = &axp288_regmap_config;
 		axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
 		break;
+	case AXP806_ID:
+		axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
+		axp20x->cells = axp806_cells;
+		axp20x->regmap_cfg = &axp806_regmap_config;
+		axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
+		break;
 	case AXP809_ID:
 		axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
 		axp20x->cells = axp809_cells;
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 0be4982f08fe..fec597fb34cb 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -20,6 +20,7 @@ enum {
 	AXP221_ID,
 	AXP223_ID,
 	AXP288_ID,
+	AXP806_ID,
 	AXP809_ID,
 	NR_AXP20X_VARIANTS,
 };
@@ -91,6 +92,30 @@ enum {
 #define AXP22X_ALDO3_V_OUT		0x2a
 #define AXP22X_CHRG_CTRL3		0x35
 
+#define AXP806_STARTUP_SRC		0x00
+#define AXP806_CHIP_ID			0x03
+#define AXP806_PWR_OUT_CTRL1		0x10
+#define AXP806_PWR_OUT_CTRL2		0x11
+#define AXP806_DCDCA_V_CTRL		0x12
+#define AXP806_DCDCB_V_CTRL		0x13
+#define AXP806_DCDCC_V_CTRL		0x14
+#define AXP806_DCDCD_V_CTRL		0x15
+#define AXP806_DCDCE_V_CTRL		0x16
+#define AXP806_ALDO1_V_CTRL		0x17
+#define AXP806_ALDO2_V_CTRL		0x18
+#define AXP806_ALDO3_V_CTRL		0x19
+#define AXP806_DCDC_MODE_CTRL1		0x1a
+#define AXP806_DCDC_MODE_CTRL2		0x1b
+#define AXP806_DCDC_FREQ_CTRL		0x1c
+#define AXP806_BLDO1_V_CTRL		0x20
+#define AXP806_BLDO2_V_CTRL		0x21
+#define AXP806_BLDO3_V_CTRL		0x22
+#define AXP806_BLDO4_V_CTRL		0x23
+#define AXP806_CLDO1_V_CTRL		0x24
+#define AXP806_CLDO2_V_CTRL		0x25
+#define AXP806_CLDO3_V_CTRL		0x26
+#define AXP806_VREF_TEMP_WARN_L		0xf3
+
 /* Interrupt */
 #define AXP152_IRQ1_EN			0x40
 #define AXP152_IRQ2_EN			0x41
@@ -266,6 +291,26 @@ enum {
 };
 
 enum {
+	AXP806_DCDCA = 0,
+	AXP806_DCDCB,
+	AXP806_DCDCC,
+	AXP806_DCDCD,
+	AXP806_DCDCE,
+	AXP806_ALDO1,
+	AXP806_ALDO2,
+	AXP806_ALDO3,
+	AXP806_BLDO1,
+	AXP806_BLDO2,
+	AXP806_BLDO3,
+	AXP806_BLDO4,
+	AXP806_CLDO1,
+	AXP806_CLDO2,
+	AXP806_CLDO3,
+	AXP806_SW,
+	AXP806_REG_ID_MAX,
+};
+
+enum {
 	AXP809_DCDC1 = 0,
 	AXP809_DCDC2,
 	AXP809_DCDC3,
@@ -414,6 +459,21 @@ enum axp288_irqs {
 	AXP288_IRQ_BC_USB_CHNG,
 };
 
+enum axp806_irqs {
+	AXP806_IRQ_DIE_TEMP_HIGH_LV1,
+	AXP806_IRQ_DIE_TEMP_HIGH_LV2,
+	AXP806_IRQ_DCDCA_V_LOW,
+	AXP806_IRQ_DCDCB_V_LOW,
+	AXP806_IRQ_DCDCC_V_LOW,
+	AXP806_IRQ_DCDCD_V_LOW,
+	AXP806_IRQ_DCDCE_V_LOW,
+	AXP806_IRQ_PWROK_LONG,
+	AXP806_IRQ_PWROK_SHORT,
+	AXP806_IRQ_WAKEUP,
+	AXP806_IRQ_PWROK_FALL,
+	AXP806_IRQ_PWROK_RISE,
+};
+
 enum axp809_irqs {
 	AXP809_IRQ_ACIN_OVER_V = 1,
 	AXP809_IRQ_ACIN_PLUGIN,
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1466914 — Re: [linux-sunxi] [PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC

FromJulian Calaby <julian.calaby@gmail.com>
Date2016-08-21 06:20 +0200
SubjectRe: [linux-sunxi] [PATCH 2/9] mfd: axp20x: Add support for AXP806 PMIC
Message-ID<s8soN-3Vy-5@gated-at.bofh.it>
In reply to#1466908
Hi Chen-Yu,

On Sun, Aug 21, 2016 at 12:11 PM, Chen-Yu Tsai <wens@csie.org> wrote:
> The X-Powers AXP809 is a new PMIC that is paired with Allwinner's A80
> SoC, along with a master AXP809 PMIC.

The first "AXP809" should be "AXP806".

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

[toc] | [prev] | [next] | [standalone]


#1466927 — Re: [linux-sunxi] [PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC

FromPriit Laes <plaes@plaes.org>
Date2016-08-21 09:20 +0200
SubjectRe: [linux-sunxi] [PATCH 0/9] mfd: axp20x: Add support for AXP809 PMIC
Message-ID<s8vd0-5ID-5@gated-at.bofh.it>
In reply to#1466902
On Sun, 2016-08-21 at 10:11 +0800, Chen-Yu Tsai wrote:
> Hi everyone,
> 
> This series adds support for X-Powers' AXP806 PMIC. This is the
> secondary
> PMIC accompanying Allwinner's A80 SoC. For now, only the regulators
> are
> supported. While the AXP806 supports standalone operation, no
> hardware
> exists, so this will not be supported.

Title says AXP809, but in text and in subsequent patches there's also
806/809 confusion.

> 
> Patch 1 adds AXP806 to the axp20x bindings.
> 
> Patch 2 adds AXP806 support to the axp20x mfd driver.
> 
> Patch 3 fixes regulator output adjustment during regulator
> registration
> so it doesn't fail if the higher or lower bounds of its voltage
> constraints
> don't match up with the regulator's voltage granularity.
> 
> Patch 4 adds AXP806 support to the axp20x regulator driver.
> 
> Patch 5 adds the unused SW switch output of the AXP809 PMIC on the
> A80
> Optimus board. This was accidentally left out of the AXP809 series.
> 
> Patch 6 adds the unused SW switch output of the AXP809 PMIC on the
> Cubieboard 4. This was accidentally left out of the AXP809 series.
> 
> Patch 7 enables AXP809 support on the A80 Optimus board.
> 
> Patch 8 enables AXP809 support on the Cubieboard 4.
> 
> Patch 9 disables EHCI1 on the A80 Optimus board.
> 
> 
> Regards
> ChenYu
> 
> Chen-Yu Tsai (9):
>   mfd: axp20x: Add bindings for AXP806 PMIC
>   mfd: axp20x: Add support for AXP806 PMIC
>   regulator: core: Try full range when adjusting regulators to
>     constraints
>   regulator: axp20x: support AXP806 variant
>   ARM: dts: sun9i: a80-optimus: Declare AXP809 SW regulator as unused
>   ARM: dts: sun9i: cubieboard4: Declare AXP809 SW regulator as unused
>   ARM: dts: sun9i: a80-optimus: Add AXP806 PMIC device node and
>     regulators
>   ARM: dts: sun9i: cubieboard4: Add AXP806 PMIC device node and
>     regulators
>   ARM: dts: sun9i: a80-optimus: Disable EHCI1
> 
>  Documentation/devicetree/bindings/mfd/axp20x.txt |  28 +++++-
>  arch/arm/boot/dts/sun9i-a80-cubieboard4.dts      | 116
> +++++++++++++++++++++
>  arch/arm/boot/dts/sun9i-a80-optimus.dts          | 123
> ++++++++++++++++++++++-
>  drivers/mfd/axp20x-rsb.c                         |   1 +
>  drivers/mfd/axp20x.c                             |  72 +++++++++++++
>  drivers/regulator/axp20x-regulator.c             | 117
> +++++++++++++++++++--
>  drivers/regulator/core.c                         |   8 +-
>  include/linux/mfd/axp20x.h                       |  60 +++++++++++
>  8 files changed, 508 insertions(+), 17 deletions(-)
> 
> -- 
> 2.9.3
> 

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web