Browse Source

Merge tag 'ux500-dt-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/fixes-non-critical

From Linus Walleij <linus.walleij@linaro.org>:

Ux500 Device Tree fixes
All are necessary to make a proper DT boot on the v3.9
series:
- IRQ edges.
- Register defines.
- FSMC clock.
- Ethernet clk fixup (one patch to drivers/net ACKed by
  David Miller)
- Proper IOS and regulator voltages for MMCI.
- AB8500 GPIOs restored after they were fixed in the v3.9
  merge window from the pinctrl tree.
- There is also a minor cleanup in the platform code, but it
  is strongly connected to the other patches.

* tag 'ux500-dt-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
  ARM: ux500: allow Snowball access to the AB8500 GPIO pins
  ARM: ux500: enable AB8500 GPIO for HREF
  ARM: ux500: Remove traces of the ios_handler from platform code
  ARM: ux500: Use the GPIO regulator framework for SDI0's 'en' and 'vsel'
  ARM: ux500: Setup correct settling time for the MMCI regulator
  ARM: ux500: Use the correct name when supplying a GPIO enable pin
  ARM: ux500: Specify which IOS regulator to use for MMCI
  ARM: ux500: Specify the ux5x0 MMCI regulator's on/off GPIO as high-enable
  ARM: ux500: Set correct MMCI regulator voltages in the ux5x0 Device Tree
  mmc: mmci: Move ios_handler functionality into the driver
  net/smsc911x: Provide common clock functionality
  clk: ux500: Provide an alias for the SMSC911x Ethernet chip
  clk: ux500: Ensure the FMSC clock is obtainable
  ARM: ux500: Provide a means to obtain the SMSC9115 clock when DT is enabled
  ARM: ux500: Include the PRCMU's Secure Registers in DB8500's DT
  ARM: ux500: Change IRQ from low-to-high edge triggered to high-to-low

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Arnd Bergmann 12 years ago
parent
commit
831bbbeb2b

+ 5 - 2
arch/arm/boot/dts/dbx5x0.dtsi

@@ -191,7 +191,7 @@
 
 		prcmu: prcmu@80157000 {
 			compatible = "stericsson,db8500-prcmu";
-			reg = <0x80157000 0x1000>;
+			reg = <0x80157000 0x2000>;
 			reg-names = "prcmu";
 			interrupts = <0 47 0x4>;
 			#address-cells = <1>;
@@ -675,10 +675,13 @@
 			compatible = "regulator-gpio";
 
 			regulator-min-microvolt = <1800000>;
-			regulator-max-microvolt = <2600000>;
+			regulator-max-microvolt = <2900000>;
 			regulator-name = "mmci-reg";
 			regulator-type = "voltage";
 
+			startup-delay-us = <100>;
+			enable-active-high;
+
 			states = <1800000 0x1
 				  2900000 0x0>;
 

+ 1 - 0
arch/arm/boot/dts/href.dtsi

@@ -87,6 +87,7 @@
 			mmc-cap-sd-highspeed;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+			vqmmc-supply = <&vmmci>;
 
 			cd-gpios  = <&tc3589x_gpio 3 0x4>;
 

+ 9 - 1
arch/arm/boot/dts/hrefprev60.dts

@@ -25,6 +25,14 @@
 	};
 
 	soc-u9500 {
+		prcmu@80157000 {
+			ab8500@5 {
+				ab8500-gpio {
+					compatible = "stericsson,ab8500-gpio";
+				};
+			};
+		};
+
 		i2c@80004000 {
 			tps61052@33 {
 				compatible = "tps61052";
@@ -40,7 +48,7 @@
 
 		vmmci: regulator-gpio {
 			gpios = <&tc3589x_gpio 18 0x4>;
-			gpio-enable = <&tc3589x_gpio 17 0x4>;
+			enable-gpio = <&tc3589x_gpio 17 0x4>;
 
 			status = "okay";
 		};

+ 4 - 0
arch/arm/boot/dts/snowball.dts

@@ -299,6 +299,10 @@
 			};
 
 			ab8500@5 {
+				ab8500-gpio {
+					compatible = "stericsson,ab8500-gpio";
+				};
+
 				ab8500-regulators {
 					ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
 						regulator-name = "V-DISPLAY";

+ 1 - 1
arch/arm/boot/dts/stuib.dtsi

@@ -15,7 +15,7 @@
 			stmpe1601: stmpe1601@40 {
 				compatible = "st,stmpe1601";
 				reg = <0x40>;
-				interrupts = <26 0x1>;
+				interrupts = <26 0x2>;
 				interrupt-parent = <&gpio6>;
 				interrupt-controller;
 

+ 14 - 0
arch/arm/mach-ux500/board-mop500-regulators.c

@@ -28,6 +28,20 @@ struct regulator_init_data gpio_en_3v3_regulator = {
        .consumer_supplies = gpio_en_3v3_consumers,
 };
 
+static struct regulator_consumer_supply sdi0_reg_consumers[] = {
+        REGULATOR_SUPPLY("vqmmc", "sdi0"),
+};
+
+struct regulator_init_data sdi0_reg_init_data = {
+        .constraints = {
+                .min_uV         = 1800000,
+                .max_uV         = 2900000,
+                .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE|REGULATOR_CHANGE_STATUS,
+        },
+        .num_consumer_supplies  = ARRAY_SIZE(sdi0_reg_consumers),
+        .consumer_supplies      = sdi0_reg_consumers,
+};
+
 /*
  * TPS61052 regulator
  */

+ 1 - 0
arch/arm/mach-ux500/board-mop500-regulators.h

@@ -19,5 +19,6 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS];
 extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS];
 extern struct regulator_init_data tps61052_regulator;
 extern struct regulator_init_data gpio_en_3v3_regulator;
+extern struct regulator_init_data sdi0_reg_init_data;
 
 #endif

+ 0 - 52
arch/arm/mach-ux500/board-mop500-sdi.c

@@ -31,35 +31,6 @@
  * SDI 0 (MicroSD slot)
  */
 
-/* GPIO pins used by the sdi0 level shifter */
-static int sdi0_en = -1;
-static int sdi0_vsel = -1;
-
-static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
-{
-	switch (ios->power_mode) {
-	case MMC_POWER_UP:
-	case MMC_POWER_ON:
-		/*
-		 * Level shifter voltage should depend on vdd to when deciding
-		 * on either 1.8V or 2.9V. Once the decision has been made the
-		 * level shifter must be disabled and re-enabled with a changed
-		 * select signal in order to switch the voltage. Since there is
-		 * no framework support yet for indicating 1.8V in vdd, use the
-		 * default 2.9V.
-		 */
-		gpio_direction_output(sdi0_vsel, 0);
-		gpio_direction_output(sdi0_en, 1);
-		break;
-	case MMC_POWER_OFF:
-		gpio_direction_output(sdi0_vsel, 0);
-		gpio_direction_output(sdi0_en, 0);
-		break;
-	}
-
-	return 0;
-}
-
 #ifdef CONFIG_STE_DMA40
 struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
@@ -81,7 +52,6 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
 #endif
 
 struct mmci_platform_data mop500_sdi0_data = {
-	.ios_handler	= mop500_sdi0_ios_handler,
 	.ocr_mask	= MMC_VDD_29_30,
 	.f_max		= 50000000,
 	.capabilities	= MMC_CAP_4_BIT_DATA |
@@ -101,22 +71,6 @@ struct mmci_platform_data mop500_sdi0_data = {
 
 static void sdi0_configure(struct device *parent)
 {
-	int ret;
-
-	ret = gpio_request(sdi0_en, "level shifter enable");
-	if (!ret)
-		ret = gpio_request(sdi0_vsel,
-				   "level shifter 1v8-3v select");
-
-	if (ret) {
-		pr_warning("unable to config sdi0 gpios for level shifter.\n");
-		return;
-	}
-
-	/* Select the default 2.9V and enable level shifter */
-	gpio_direction_output(sdi0_vsel, 0);
-	gpio_direction_output(sdi0_en, 1);
-
 	/* Add the device, force v2 to subrevision 1 */
 	db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
 }
@@ -124,8 +78,6 @@ static void sdi0_configure(struct device *parent)
 void mop500_sdi_tc35892_init(struct device *parent)
 {
 	mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
-	sdi0_en = GPIO_SDMMC_EN;
-	sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
 	sdi0_configure(parent);
 }
 
@@ -264,8 +216,6 @@ void __init snowball_sdi_init(struct device *parent)
 	/* External Micro SD slot */
 	mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
 	mop500_sdi0_data.cd_invert = true;
-	sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
-	sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
 	sdi0_configure(parent);
 }
 
@@ -277,8 +227,6 @@ void __init hrefv60_sdi_init(struct device *parent)
 	db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
 	/* External Micro SD slot */
 	mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
-	sdi0_en = HREFV60_SDMMC_EN_GPIO;
-	sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
 	sdi0_configure(parent);
 	/* WLAN SDIO channel */
 	db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);

+ 45 - 0
arch/arm/mach-ux500/board-mop500.c

@@ -24,6 +24,8 @@
 #include <linux/mfd/abx500/ab8500.h>
 #include <linux/regulator/ab8500.h>
 #include <linux/regulator/fixed.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
 #include <linux/mfd/tc3589x.h>
 #include <linux/mfd/tps6105x.h>
 #include <linux/mfd/abx500/ab8500-gpio.h>
@@ -89,6 +91,37 @@ static struct platform_device snowball_gpio_en_3v3_regulator_dev = {
        },
 };
 
+/* Dynamically populated. */
+static struct gpio sdi0_reg_gpios[] = {
+	{ 0, GPIOF_OUT_INIT_LOW, "mmci_vsel" },
+};
+
+static struct gpio_regulator_state sdi0_reg_states[] = {
+	{ .value = 2900000, .gpios = (0 << 0) },
+	{ .value = 1800000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config sdi0_reg_info = {
+	.supply_name		= "ext-mmc-level-shifter",
+	.gpios			= sdi0_reg_gpios,
+	.nr_gpios		= ARRAY_SIZE(sdi0_reg_gpios),
+	.states			= sdi0_reg_states,
+	.nr_states		= ARRAY_SIZE(sdi0_reg_states),
+	.type			= REGULATOR_VOLTAGE,
+	.enable_high		= 1,
+	.enabled_at_boot	= 0,
+	.init_data		= &sdi0_reg_init_data,
+	.startup_delay		= 100,
+};
+
+static struct platform_device sdi0_regulator = {
+	.name = "gpio-regulator",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &sdi0_reg_info,
+	},
+};
+
 static struct abx500_gpio_platform_data ab8500_gpio_pdata = {
 	.gpio_base		= MOP500_AB8500_PIN_GPIO(1),
 };
@@ -481,6 +514,7 @@ static struct hash_platform_data u8500_hash1_platform_data = {
 /* add any platform devices here - TODO */
 static struct platform_device *mop500_platform_devs[] __initdata = {
 	&mop500_gpio_keys_device,
+	&sdi0_regulator,
 };
 
 #ifdef CONFIG_STE_DMA40
@@ -624,6 +658,7 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
 	&snowball_gpio_en_3v3_regulator_dev,
 	&u8500_thsens_device,
 	&u8500_cpufreq_cooling_device,
+	&sdi0_regulator,
 };
 
 static void __init mop500_init_machine(void)
@@ -635,6 +670,9 @@ static void __init mop500_init_machine(void)
 	platform_device_register(&db8500_prcmu_device);
 	mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
 
+	sdi0_reg_info.enable_gpio = GPIO_SDMMC_EN;
+	sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL;
+
 	mop500_pinmaps_init();
 	parent = u8500_init_devices(&ab8500_platdata);
 
@@ -668,6 +706,10 @@ static void __init snowball_init_machine(void)
 	int i;
 
 	platform_device_register(&db8500_prcmu_device);
+
+	sdi0_reg_info.enable_gpio = SNOWBALL_SDMMC_EN_GPIO;
+	sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO;
+
 	snowball_pinmaps_init();
 	parent = u8500_init_devices(&ab8500_platdata);
 
@@ -701,6 +743,9 @@ static void __init hrefv60_init_machine(void)
 	 */
 	mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
 
+	sdi0_reg_info.enable_gpio = HREFV60_SDMMC_EN_GPIO;
+	sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO;
+
 	hrefv60_pinmaps_init();
 	parent = u8500_init_devices(&ab8500_platdata);
 

+ 1 - 0
arch/arm/mach-ux500/cpu-db8500.c

@@ -282,6 +282,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
 	OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
 			&db8500_prcmu_pdata),
+	OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x", NULL),
 	/* Requires device name bindings. */
 	OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
 		"pinctrl-db8500", NULL),

+ 2 - 1
drivers/clk/ux500/u8500_clk.c

@@ -324,7 +324,8 @@ void u8500_clk_init(void)
 
 	clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE,
 				BIT(0), 0);
-	clk_register_clkdev(clk, NULL, "fsmc");
+	clk_register_clkdev(clk, "fsmc", NULL);
+	clk_register_clkdev(clk, NULL, "smsc911x");
 
 	clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE,
 				BIT(1), 0);

+ 9 - 0
drivers/mmc/host/mmci.c

@@ -1141,6 +1141,11 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	case MMC_POWER_OFF:
 		if (!IS_ERR(mmc->supply.vmmc))
 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
+		if (!IS_ERR(mmc->supply.vqmmc) &&
+		    regulator_is_enabled(mmc->supply.vqmmc))
+			regulator_disable(mmc->supply.vqmmc);
+
 		break;
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc))
@@ -1155,6 +1160,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 		break;
 	case MMC_POWER_ON:
+		if (!IS_ERR(mmc->supply.vqmmc) &&
+		    !regulator_is_enabled(mmc->supply.vqmmc))
+			regulator_enable(mmc->supply.vqmmc);
+
 		pwr |= MCI_PWR_ON;
 		break;
 	}

+ 28 - 1
drivers/net/ethernet/smsc/smsc911x.c

@@ -33,6 +33,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/crc32.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
@@ -144,6 +145,9 @@ struct smsc911x_data {
 
 	/* regulators */
 	struct regulator_bulk_data supplies[SMSC911X_NUM_SUPPLIES];
+
+	/* clock */
+	struct clk *clk;
 };
 
 /* Easy access to information */
@@ -369,7 +373,7 @@ out:
 }
 
 /*
- * enable resources, currently just regulators.
+ * enable regulator and clock resources.
  */
 static int smsc911x_enable_resources(struct platform_device *pdev)
 {
@@ -382,6 +386,13 @@ static int smsc911x_enable_resources(struct platform_device *pdev)
 	if (ret)
 		netdev_err(ndev, "failed to enable regulators %d\n",
 				ret);
+
+	if (!IS_ERR(pdata->clk)) {
+		ret = clk_prepare_enable(pdata->clk);
+		if (ret < 0)
+			netdev_err(ndev, "failed to enable clock %d\n", ret);
+	}
+
 	return ret;
 }
 
@@ -396,6 +407,10 @@ static int smsc911x_disable_resources(struct platform_device *pdev)
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(pdata->supplies),
 			pdata->supplies);
+
+	if (!IS_ERR(pdata->clk))
+		clk_disable_unprepare(pdata->clk);
+
 	return ret;
 }
 
@@ -421,6 +436,12 @@ static int smsc911x_request_resources(struct platform_device *pdev)
 	if (ret)
 		netdev_err(ndev, "couldn't get regulators %d\n",
 				ret);
+
+	/* Request clock */
+	pdata->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pdata->clk))
+		netdev_warn(ndev, "couldn't get clock %li\n", PTR_ERR(pdata->clk));
+
 	return ret;
 }
 
@@ -436,6 +457,12 @@ static void smsc911x_free_resources(struct platform_device *pdev)
 	/* Free regulators */
 	regulator_bulk_free(ARRAY_SIZE(pdata->supplies),
 			pdata->supplies);
+
+	/* Free clock */
+	if (!IS_ERR(pdata->clk)) {
+		clk_put(pdata->clk);
+		pdata->clk = NULL;
+	}
 }
 
 /* waits for MAC not busy, with timeout.  Only called by smsc911x_mac_read