diff options
Diffstat (limited to 'arch/arm/mach-omap2')
| -rw-r--r-- | arch/arm/mach-omap2/board-igep0020.c | 5 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clockdomains44xx_data.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/common-board-devices.c | 34 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/devices.c | 79 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 63 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 36 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/twl-common.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/vc.c | 2 | 
8 files changed, 193 insertions, 31 deletions
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41dfbf..37859069444 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)  	} else  		return; +	/* Make sure that the GPIO pins are muxed correctly */ +	omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); +  	err = gpio_request_array(igep_wlan_bt_gpios,  				 ARRAY_SIZE(igep_wlan_bt_gpios));  	if (err) { diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b4878..95192a062d5 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = {  	.clkdm_offs	  = OMAP4430_CM2_CAM_CAM_CDOFFS,  	.wkdep_srcs	  = iss_wkup_sleep_deps,  	.sleepdep_srcs	  = iss_wkup_sleep_deps, -	.flags		  = CLKDM_CAN_HWSUP_SWSUP, +	.flags		  = CLKDM_CAN_SWSUP,  };  static struct clockdomain l3_dss_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 48daac2581b..84551f205e4 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,  	struct spi_board_info *spi_bi = &ads7846_spi_board_info;  	int err; -	err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); -	if (err) { -		pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); -		return; -	} +	/* +	 * If a board defines get_pendown_state() function, request the pendown +	 * GPIO and set the GPIO debounce time. +	 * If a board does not define the get_pendown_state() function, then +	 * the ads7846 driver will setup the pendown GPIO itself. +	 */ +	if (board_pdata && board_pdata->get_pendown_state) { +		err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); +		if (err) { +			pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); +			return; +		} -	if (gpio_debounce) -		gpio_set_debounce(gpio_pendown, gpio_debounce); +		if (gpio_debounce) +			gpio_set_debounce(gpio_pendown, gpio_debounce); + +		gpio_export(gpio_pendown, 0); +	}  	spi_bi->bus_num	= bus_num;  	spi_bi->irq	= gpio_to_irq(gpio_pendown); +	ads7846_config.gpio_pendown = gpio_pendown; +  	if (board_pdata) {  		board_pdata->gpio_pendown = gpio_pendown; +		board_pdata->gpio_pendown_debounce = gpio_debounce;  		spi_bi->platform_data = board_pdata; -		if (board_pdata->get_pendown_state) -			gpio_export(gpio_pendown, 0); -	} else { -		ads7846_config.gpio_pendown = gpio_pendown;  	} -	if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) -		gpio_free(gpio_pendown); -  	spi_register_board_info(&ads7846_spi_board_info, 1);  }  #else diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index cba60e05e32..c72b5a72772 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@  #include <linux/of.h>  #include <linux/pinctrl/machine.h>  #include <linux/platform_data/omap4-keypad.h> +#include <linux/platform_data/omap_ocp2scp.h>  #include <asm/mach-types.h>  #include <asm/mach/map.h> @@ -613,6 +614,83 @@ static void omap_init_vout(void)  static inline void omap_init_vout(void) {}  #endif +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) +{ +	int cnt	= 0; + +	while (ocp2scp_dev->drv_name != NULL) { +		cnt++; +		ocp2scp_dev++; +	} + +	return cnt; +} + +static void omap_init_ocp2scp(void) +{ +	struct omap_hwmod	*oh; +	struct platform_device	*pdev; +	int			bus_id = -1, dev_cnt = 0, i; +	struct omap_ocp2scp_dev	*ocp2scp_dev; +	const char		*oh_name, *name; +	struct omap_ocp2scp_platform_data *pdata; + +	if (!cpu_is_omap44xx()) +		return; + +	oh_name = "ocp2scp_usb_phy"; +	name	= "omap-ocp2scp"; + +	oh = omap_hwmod_lookup(oh_name); +	if (!oh) { +		pr_err("%s: could not find omap_hwmod for %s\n", __func__, +								oh_name); +		return; +	} + +	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); +	if (!pdata) { +		pr_err("%s: No memory for ocp2scp pdata\n", __func__); +		return; +	} + +	ocp2scp_dev = oh->dev_attr; +	dev_cnt = count_ocp2scp_devices(ocp2scp_dev); + +	if (!dev_cnt) { +		pr_err("%s: No devices connected to ocp2scp\n", __func__); +		kfree(pdata); +		return; +	} + +	pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) +					* dev_cnt, GFP_KERNEL); +	if (!pdata->devices) { +		pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); +		kfree(pdata); +		return; +	} + +	for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) +		pdata->devices[i] = ocp2scp_dev; + +	pdata->dev_cnt	= dev_cnt; + +	pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, +								0, false); +	if (IS_ERR(pdev)) { +		pr_err("Could not build omap_device for %s %s\n", +						name, oh_name); +		kfree(pdata->devices); +		kfree(pdata); +		return; +	} +} +#else +static inline void omap_init_ocp2scp(void) { } +#endif +  /*-------------------------------------------------------------------------*/  static int __init omap2_init_devices(void) @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void)  	omap_init_sham();  	omap_init_aes();  	omap_init_vout(); +	omap_init_ocp2scp();  	return 0;  } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1d258..87cc6d058de 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)  }  /** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete.  This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC).  Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds.  Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ +	struct omap_hwmod_class_sysconfig *sysc; +	u32 softrst_mask; +	int c = 0; + +	sysc = oh->class->sysc; + +	if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) +		omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) +				   & SYSS_RESETDONE_MASK), +				  MAX_MODULE_SOFTRESET_WAIT, c); +	else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { +		softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); +		omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) +				    & softrst_mask), +				  MAX_MODULE_SOFTRESET_WAIT, c); +	} + +	return c; +} + +/**   * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v   * @oh: struct omap_hwmod *   * @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)  	if (!oh->class->sysc)  		return; +	/* +	 * Wait until reset has completed, this is needed as the IP +	 * block is reset automatically by hardware in some cases +	 * (off-mode for example), and the drivers require the +	 * IP to be ready when they access it +	 */ +	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) +		_enable_optional_clocks(oh); +	_wait_softreset_complete(oh); +	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) +		_disable_optional_clocks(oh); +  	v = oh->_sysc_cache;  	sf = oh->class->sysc->sysc_flags; @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)   */  static int _ocp_softreset(struct omap_hwmod *oh)  { -	u32 v, softrst_mask; +	u32 v;  	int c = 0;  	int ret = 0; @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)  	if (oh->class->sysc->srst_udelay)  		udelay(oh->class->sysc->srst_udelay); -	if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) -		omap_test_timeout((omap_hwmod_read(oh, -						    oh->class->sysc->syss_offs) -				   & SYSS_RESETDONE_MASK), -				  MAX_MODULE_SOFTRESET_WAIT, c); -	else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { -		softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); -		omap_test_timeout(!(omap_hwmod_read(oh, -						     oh->class->sysc->sysc_offs) -				   & softrst_mask), -				  MAX_MODULE_SOFTRESET_WAIT, c); -	} - +	c = _wait_softreset_complete(oh);  	if (c == MAX_MODULE_SOFTRESET_WAIT)  		pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",  			   oh->name, MAX_MODULE_SOFTRESET_WAIT); @@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)  	if (oh->_state != _HWMOD_STATE_INITIALIZED)  		return -EINVAL; +	if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) +		return -EPERM; +  	if (oh->rst_lines_cnt == 0) {  		r = _enable(oh);  		if (r) { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6..0b1249e0039 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@  #include <linux/io.h>  #include <linux/platform_data/gpio-omap.h>  #include <linux/power/smartreflex.h> +#include <linux/platform_data/omap_ocp2scp.h>  #include <plat/omap_hwmod.h>  #include <plat/i2c.h> @@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {  	.name		= "mcpdm",  	.class		= &omap44xx_mcpdm_hwmod_class,  	.clkdm_name	= "abe_clkdm", +	/* +	 * It's suspected that the McPDM requires an off-chip main +	 * functional clock, controlled via I2C.  This IP block is +	 * currently reset very early during boot, before I2C is +	 * available, so it doesn't seem that we have any choice in +	 * the kernel other than to avoid resetting it. +	 */ +	.flags		= HWMOD_EXT_OPT_MAIN_CLK,  	.mpu_irqs	= omap44xx_mcpdm_irqs,  	.sdma_reqs	= omap44xx_mcpdm_sdma_reqs,  	.main_clk	= "mcpdm_fck", @@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {  	.sysc	= &omap44xx_ocp2scp_sysc,  }; +/* ocp2scp dev_attr */ +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { +	{ +		.name		= "usb_phy", +		.start		= 0x4a0ad080, +		.end		= 0x4a0ae000, +		.flags		= IORESOURCE_MEM, +	}, +	{ +		/* XXX: Remove this once control module driver is in place */ +		.name		= "ctrl_dev", +		.start		= 0x4a002300, +		.end		= 0x4a002303, +		.flags		= IORESOURCE_MEM, +	}, +	{ } +}; + +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { +	{ +		.drv_name       = "omap-usb2", +		.res		= omap44xx_usb_phy_and_pll_addrs, +	}, +	{ } +}; +  /* ocp2scp_usb_phy */  static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {  	.name		= "ocp2scp_usb_phy", @@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {  			.modulemode   = MODULEMODE_HWCTRL,  		},  	}, +	.dev_attr	= ocp2scp_dev_attr,  };  /* diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109f5ad..a256135d8e4 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,  {  	/* PMIC part*/  	omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); +	omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);  	omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);  	/* Register additional devices on i2c1 bus if needed */ @@ -366,7 +367,7 @@ static struct regulator_init_data omap4_clk32kg_idata = {  };  static struct regulator_consumer_supply omap4_vdd1_supply[] = { -	REGULATOR_SUPPLY("vcc", "mpu.0"), +	REGULATOR_SUPPLY("vcc", "cpu0"),  };  static struct regulator_consumer_supply omap4_vdd2_supply[] = { diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b1701..75878c37959 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)  	if (initialized) {  		if (voltdm->pmic->i2c_high_speed != i2c_high_speed) -			pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", +			pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",  				__func__, voltdm->name, i2c_high_speed);  		return;  	}  |