Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Greg KH @ 2011-02-25  3:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8ya8vx4dcky.fsf@huya.qualcomm.com>

On Thu, Feb 24, 2011 at 07:20:45PM -0800, David Brown wrote:
> On Thu, Feb 24 2011, Dima Zavin wrote:
> 
> > On that note, should we have a "drivers/arm/msm" instead of just
> > "drivers/msm"? Other non-msm arm sub-arches probably have the same
> > problem and polluting drivers/ top-level for every arm-subarch maybe
> > undesirable.
> 
> I'm moving linux-kernel to the 'to' field, and adding Greg KH to CC.
> 
> This is about a new driver (ssbi) for the MSM chips, and where the
> driver for this should go.  The driver is specific to MSM chips (as far
> as I know, the bus is only supported there).  There are likely to be
> future msm-specific drivers, so the suggestion was to put this under
> drivers/msm, or possibly drivers/arm/msm.
> 
> Anyone other suggestions, or preferences for the location?

drivers/ssbi?  What's keeping this from later moving off of the msm
chips to run on others?  USB started out only on one processor, as did a
lot of other bus-specific drivers, before the hardware became present on
other architectures.  So no need to bury it under a msm specific
location.

Hope this helps,

greg k-h

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: David Brown @ 2011-02-25  3:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTikD1Ued=rit1QbMWwe3NGFz2iQ-KO7B=-N6Ok-2@mail.gmail.com>

On Thu, Feb 24 2011, Dima Zavin wrote:

> On that note, should we have a "drivers/arm/msm" instead of just
> "drivers/msm"? Other non-msm arm sub-arches probably have the same
> problem and polluting drivers/ top-level for every arm-subarch maybe
> undesirable.

I'm moving linux-kernel to the 'to' field, and adding Greg KH to CC.

This is about a new driver (ssbi) for the MSM chips, and where the
driver for this should go.  The driver is specific to MSM chips (as far
as I know, the bus is only supported there).  There are likely to be
future msm-specific drivers, so the suggestion was to put this under
drivers/msm, or possibly drivers/arm/msm.

Anyone other suggestions, or preferences for the location?

Thanks,
David Brown

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Dima Zavin @ 2011-02-25  2:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298601346.17118.29.camel@m0nster>

On that note, should we have a "drivers/arm/msm" instead of just
"drivers/msm"? Other non-msm arm sub-arches probably have the same
problem and polluting drivers/ top-level for every arm-subarch maybe
undesirable.

--Dima


On Thu, Feb 24, 2011 at 6:35 PM, Daniel Walker <dwalker@fifo99.com> wrote:
> On Thu, 2011-02-24 at 18:31 -0800, David Brown wrote:
>> On Thu, Feb 24 2011, Daniel Walker wrote:
>>
>> > You have some submission problems. one is that the subject should be
>> > "drivers: msm: ..." , this patch also shouldn't go to David.
>>
>> Subject needs to be fixed. ?Patch to add drivers/msm to the maintainers
>> file has been Acked, so this should be sent to the MSM maintainers.
>
> It was only acked by Nico, he's just the one who suggested it. I think
> Greg needs to be involved at some level ..
>
> Daniel
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at ?http://www.tux.org/lkml/
>

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Daniel Walker @ 2011-02-25  2:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8yad3mgdeut.fsf@huya.qualcomm.com>

On Thu, 2011-02-24 at 18:31 -0800, David Brown wrote:
> On Thu, Feb 24 2011, Daniel Walker wrote:
> 
> > You have some submission problems. one is that the subject should be
> > "drivers: msm: ..." , this patch also shouldn't go to David.
> 
> Subject needs to be fixed.  Patch to add drivers/msm to the maintainers
> file has been Acked, so this should be sent to the MSM maintainers.

It was only acked by Nico, he's just the one who suggested it. I think
Greg needs to be involved at some level ..

Daniel

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: David Brown @ 2011-02-25  2:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298600621.17118.27.camel@m0nster>

On Thu, Feb 24 2011, Daniel Walker wrote:

> You have some submission problems. one is that the subject should be
> "drivers: msm: ..." , this patch also shouldn't go to David.

Subject needs to be fixed.  Patch to add drivers/msm to the maintainers
file has been Acked, so this should be sent to the MSM maintainers.

David

^ permalink raw reply

* [PATCH] drivers: ld9040 amoled driver support
From: Donghwa Lee @ 2011-02-25  2:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224154250.266b2688.akpm@linux-foundation.org>

 On Fri, 25 Feb 2011 8:42 @t, Andrew Morton wrote:
> On Thu, 13 Jan 2011 13:40:28 +0900
> Donghwa Lee <dh09.lee@samsung.com> wrote:
>
>>  +#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
> This could and should be implemented as a regular lower-case C function.
>
Ok, I will change to lower-case.
>> +
>> +static const unsigned short SEQ_SWRESET[] = {
>> +	0x01, COMMAND_ONLY,
>> +	ENDDEF, 0x00
>> +};
> It's strange that all these tables have upper-case names.  Unless
> there's some special reason for doing it this way, please make them
> regular lower-case identifiers.
>
It means specific register setting tables, but, on second thoughts, it is meaningless. I will change it.
>> ...
>>
>> +static int ld9040_ldi_init(struct ld9040 *lcd)
>> +{
>> +	int ret, i;
>> +	const unsigned short *init_seq[] = {
>> +		SEQ_USER_SETTING,
>> +		SEQ_PANEL_CONDITION,
>> +		SEQ_DISPCTL,
>> +		SEQ_MANPWR,
>> +		SEQ_PWR_CTRL,
>> +		SEQ_ELVSS_ON,
>> +		SEQ_GTCON,
>> +		SEQ_GAMMA_SET1,
>> +		SEQ_GAMMA_CTRL,
>> +		SEQ_SLPOUT,
>> +	};
> Make this table static so the compiler doesn't rebuild it on the stack
> each time the function is called.  The compiler probably already
> performs that optimisation, but it doesn't hurt to be explicit.
>
Ok, I will modify it.
>  +static ssize_t ld9040_sysfs_show_gamma_mode(struct device *dev,
> +				      struct device_attribute *attr, char *buf)
> +{
> +	struct ld9040 *lcd = dev_get_drvdata(dev);
> +	char temp[10];
> +
> +	switch (lcd->gamma_mode) {
> +	case 0:
> +		sprintf(temp, "2.2 mode\n");
> +		strcat(buf, temp);
> Could do sprintf(buf + strlen(buf)) and eliminate temp[].
Current gamma table is only one, so I remove all about gamma mode.
>> +static ssize_t ld9040_sysfs_store_gamma_mode(struct device *dev,
>> +				       struct device_attribute *attr,
>> +				       const char *buf, size_t len)
>> +{
>> +	struct ld9040 *lcd = dev_get_drvdata(dev);
>> +	struct backlight_device *bd = NULL;
>> +	int brightness, rc;
>> +
>> +	rc = strict_strtoul(buf, 0, (unsigned long *)&lcd->gamma_mode);
> That's a bug.  gamma_mode has type int, which is 4 bytes, but you're
> telling strict_strtoul() to write eight bytes - it will corrupt *lcd on
> a 64-bit machine.  Use a temporary.
>
Current gamma table is only one, so I remove all about gamma mode.
>> +
>> +static DEVICE_ATTR(gamma_mode, 0644,
>> +		ld9040_sysfs_show_gamma_mode, ld9040_sysfs_store_gamma_mode);
>> +
>> +static ssize_t ld9040_sysfs_show_gamma_table(struct device *dev,
>> +				      struct device_attribute *attr, char *buf)
>> +{
>> +	struct ld9040 *lcd = dev_get_drvdata(dev);
>> +	char temp[3];
>> +
>> +	sprintf(temp, "%d\n", lcd->gamma_table_count);
>> +	strcpy(buf, temp);
> sprintf(buf + strlen(buf), remove temp[].
>
Current gamma table is only one, so I remove all about gamma mode.
>> +	return strlen(buf);
>> +}
>> +
>> +static DEVICE_ATTR(gamma_table, 0644,
>> +		ld9040_sysfs_show_gamma_table, NULL);
>> +
>> +static int ld9040_probe(struct spi_device *spi)
>> +{
>> +	int ret = 0;
>> +	struct ld9040 *lcd = NULL;
>> +	struct lcd_device *ld = NULL;
>> +	struct backlight_device *bd = NULL;
>> +
>> +	lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
>> +	if (!lcd)
>> +		return -ENOMEM;
>> +
>> +	/* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
>> +	spi->bits_per_word = 9;
>> +
>> +	ret = spi_setup(spi);
>> +	if (ret < 0) {
>> +		dev_err(&spi->dev, "spi setup failed.\n");
>> +		goto out_free_lcd;
>> +	}
>> +
>> +	lcd->spi = spi;
>> +	lcd->dev = &spi->dev;
>> +
>> +	lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data;
> Unneeded and undesirable typecast.
>
Ok, I will modify it.
>> +	/*
>> +	 * it gets gamma table count available so it gets user
>> +	 * know that.
>> +	 */
>> +	lcd->gamma_table_count =
>> +	    sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int));
>> +
>> +	ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode);
>> +	if (ret < 0)
>> +		dev_err(&(spi->dev), "failed to add sysfs entries\n");
>> +
>> +	ret = device_create_file(&(spi->dev), &dev_attr_gamma_table);
>> +	if (ret < 0)
>> +		dev_err(&(spi->dev), "failed to add sysfs entries\n");
> These errors are just ignored.  It would be better to perform cleanup
> and to then return the correct errno.
>
Above, creating sysfs node is unneeded. I will remove it.
>> +
>> +#if defined(CONFIG_PM)
>> +unsigned int beforepower;
> This should be static.
>
> Also, it shouldn't exist.  Its presence assumes that there will only be
> one device controlled by this driver.  It should be moved into the
> per-device data area.
>
Yes, you're right. beforepower variable is unneeded, I will remove it.
>> ...
>>
>> +struct ld9040_gamma {
>> +	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
>> +};
>> +
>> +static struct ld9040_gamma gamma_table = {
> Could do
>
> static struct ld9040_gamma {
> 	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
> } gamma_table = {
>
> here.
>
Ok, I will move it.
>> +	.gamma_22_table[0] = (unsigned int *)&ld9040_22_50,
>> +	.gamma_22_table[1] = (unsigned int *)&ld9040_22_70,
>> +	.gamma_22_table[2] = (unsigned int *)&ld9040_22_80,
>> +	.gamma_22_table[3] = (unsigned int *)&ld9040_22_90,
>> +	.gamma_22_table[4] = (unsigned int *)&ld9040_22_100,
>> +	.gamma_22_table[5] = (unsigned int *)&ld9040_22_110,
>> +	.gamma_22_table[6] = (unsigned int *)&ld9040_22_120,
>> +	.gamma_22_table[7] = (unsigned int *)&ld9040_22_130,
>> +	.gamma_22_table[8] = (unsigned int *)&ld9040_22_140,
>> +	.gamma_22_table[9] = (unsigned int *)&ld9040_22_150,
>> +	.gamma_22_table[10] = (unsigned int *)&ld9040_22_160,
>> +	.gamma_22_table[11] = (unsigned int *)&ld9040_22_170,
>> +	.gamma_22_table[12] = (unsigned int *)&ld9040_22_180,
>> +	.gamma_22_table[13] = (unsigned int *)&ld9040_22_190,
>> +	.gamma_22_table[14] = (unsigned int *)&ld9040_22_200,
>> +	.gamma_22_table[15] = (unsigned int *)&ld9040_22_210,
>> +	.gamma_22_table[16] = (unsigned int *)&ld9040_22_220,
>> +	.gamma_22_table[17] = (unsigned int *)&ld9040_22_230,
>> +	.gamma_22_table[18] = (unsigned int *)&ld9040_22_240,
>> +	.gamma_22_table[19] = (unsigned int *)&ld9040_22_250,
>> +	.gamma_22_table[20] = (unsigned int *)&ld9040_22_260,
>> +	.gamma_22_table[21] = (unsigned int *)&ld9040_22_270,
>> +	.gamma_22_table[22] = (unsigned int *)&ld9040_22_280,
>> +	.gamma_22_table[23] = (unsigned int *)&ld9040_22_290,
>> +	.gamma_22_table[24] = (unsigned int *)&ld9040_22_300,
>> +};
>> +
>> +#endif
> Defining static tables in a header file is strange.  It would be very
> wrong if that header was ever included by more than a single .c file,
> so why not just eliminate this file and move its contents into that .c
> file?
>
But, if its contents moved into that .c file, ld9040.c  becomes very long file.
Ld9040.c file already had many register set data variable, I think readability is less than
before.


I'm very grateful to you for your review.
Thank you.

Donghwa Lee

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Daniel Walker @ 2011-02-25  2:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298585954-22422-3-git-send-email-kheitke@codeaurora.org>


You have some submission problems. one is that the subject should be
"drivers: msm: ..." , this patch also shouldn't go to David.

On Thu, 2011-02-24 at 15:19 -0700, Kenneth Heitke wrote:
> SSBI is the Qualcomm single-wire serial bus interface used to connect
> the MSM devices to the PMIC and other devices.
> 
> Since SSBI only supports a single slave, the driver gets the name of the
> slave device passed in from the board file through the master device's
> platform data.
> 
> SSBI registers pretty early (postcore), so that the PMIC can come up
> before the board init. This is useful if the board init requires the
> use of gpios that are connected through the PMIC.
> 
> Based on a patch by Dima Zavin <dima@android.com> that can be found at:
> http://android.git.kernel.org/?p=kernel/msm.git;a=commitdiff;h=eb060bac4

I don't really like links in the commit text, cause as soon as Google
deletes this tree the link is worthless.

> This patch adds PMIC Arbiter support for the MSM8660. The PMIC Arbiter
> is a hardware wrapper around the SSBI 2.0 controller that is designed to
> overcome concurrency issues and security limitations.  A controller_type
> field is added to the platform data to specify the type of the SSBI
> controller (1.0, 2.0, or PMIC Arbiter).
> 
> Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
> ---
>  drivers/Kconfig          |    2 +
>  drivers/Makefile         |    1 +
>  drivers/msm/Kconfig      |   13 ++
>  drivers/msm/Makefile     |    4 +
>  drivers/msm/ssbi.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/msm_ssbi.h |   49 ++++++
>  6 files changed, 445 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/msm/Kconfig
>  create mode 100644 drivers/msm/Makefile
>  create mode 100644 drivers/msm/ssbi.c
>  create mode 100644 include/linux/msm_ssbi.h
> 
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index 9bfb71f..fceeb20 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -117,4 +117,6 @@ source "drivers/staging/Kconfig"
>  source "drivers/platform/Kconfig"
>  
>  source "drivers/clk/Kconfig"
> +
> +source "drivers/msm/Kconfig"
>  endmenu
> diff --git a/drivers/Makefile b/drivers/Makefile
> index b423bb1..14cb94b 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -117,3 +117,4 @@ obj-y				+= platform/
>  obj-y				+= ieee802154/
>  #common clk code
>  obj-y				+= clk/
> +obj-y				+= msm/
> diff --git a/drivers/msm/Kconfig b/drivers/msm/Kconfig
> new file mode 100644
> index 0000000..413bb65
> --- /dev/null
> +++ b/drivers/msm/Kconfig
> @@ -0,0 +1,13 @@
> +menu "Qualcomm MSM specific device drivers"
> +	depends on ARCH_MSM
> +
> +config MSM_SSBI
> +	bool "Qualcomm Single-wire Serial Bus Interface (SSBI)"
> +	help
> +	  If you say yes to this option, support will be included for the
> +	  built-in SSBI interface on Qualcomm MSM family processors.
> +
> +	  This is required for communicating with Qualcomm PMICs and
> +	  other devices that have the SSBI interface.
> +
> +endmenu
> diff --git a/drivers/msm/Makefile b/drivers/msm/Makefile
> new file mode 100644
> index 0000000..ea8c1e4
> --- /dev/null
> +++ b/drivers/msm/Makefile
> @@ -0,0 +1,4 @@
> +#
> +# Makefile for the MSM specific device drivers.
> +#
> +obj-$(CONFIG_MSM_SSBI) += ssbi.o
> diff --git a/drivers/msm/ssbi.c b/drivers/msm/ssbi.c
> new file mode 100644
> index 0000000..1fae443
> --- /dev/null
> +++ b/drivers/msm/ssbi.c
> @@ -0,0 +1,376 @@
> +/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
> + * Copyright (c) 2010, Google Inc.
> + *
> + * Original authors: Code Aurura Forum

Spelling problem.

> + * Author: Dima Zavin <dima@android.com>
> + *  - Largely rewritten from original to not be an i2c driver.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/msm_ssbi.h>
> +
> +/* SSBI 2.0 controller registers */
> +#define SSBI2_CMD			0x0008
> +#define SSBI2_RD			0x0010
> +#define SSBI2_STATUS			0x0014
> +#define SSBI2_MODE2			0x001C
> +
> +/* SSBI_CMD fields */
> +#define SSBI_CMD_RDWRN			(1 << 24)
> +
> +/* SSBI_STATUS fields */
> +#define SSBI_STATUS_RD_READY		(1 << 2)
> +#define SSBI_STATUS_READY		(1 << 1)
> +#define SSBI_STATUS_MCHN_BUSY		(1 << 0)
> +
> +/* SSBI_MODE2 fields */
> +#define SSBI_MODE2_REG_ADDR_15_8_SHFT	0x04
> +#define SSBI_MODE2_REG_ADDR_15_8_MASK	(0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
> +
> +#define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
> +	(((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
> +	SSBI_MODE2_REG_ADDR_15_8_MASK))
> +
> +/* SSBI PMIC Arbiter command registers */
> +#define SSBI_PA_CMD			0x0000
> +#define SSBI_PA_RD_STATUS		0x0004
> +
> +/* SSBI_PA_CMD fields */
> +#define SSBI_PA_CMD_RDWRN		(1 << 24)
> +
> +/* SSBI_PA_RD_STATUS fields */
> +#define SSBI_PA_RD_STATUS_TRANS_DONE	(1 << 27)
> +#define SSBI_PA_RD_STATUS_TRANS_DENIED	(1 << 26)
> +
> +#define SSBI_TIMEOUT_US			100
> +
> +struct msm_ssbi {
> +	struct device		*dev;
> +	struct device		*slave;
> +	void __iomem		*base;
> +	spinlock_t		lock;
> +	enum msm_ssbi_controller_type controller_type;
> +	int (*read)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
> +	int (*write)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
> +};
> +
> +#define to_msm_ssbi(dev)	platform_get_drvdata(to_platform_device(dev))
> +
> +static inline u32 ssbi_readl(struct msm_ssbi *ssbi, u32 reg)
> +{
> +	return readl(ssbi->base + reg);
> +}
> +
> +static inline void ssbi_writel(struct msm_ssbi *ssbi, u32 val, u32 reg)
> +{
> +	writel(val, ssbi->base + reg);
> +}
> +
> +static int ssbi_wait_mask(struct msm_ssbi *ssbi, u32 set_mask, u32 clr_mask)
> +{
> +	u32 timeout = SSBI_TIMEOUT_US;
> +	u32 val;
> +
> +	while (timeout--) {
> +		val = ssbi_readl(ssbi, SSBI2_STATUS);
> +		if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
> +			return 0;
> +		udelay(1);
> +	}
> +
> +	dev_err(ssbi->dev, "%s: timeout (status %x set_mask %x clr_mask %x)\n",
> +		__func__, ssbi_readl(ssbi, SSBI2_STATUS), set_mask, clr_mask);
> +	return -ETIMEDOUT;
> +}
> +
> +static int
> +msm_ssbi_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
> +{
> +	u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
> +	int ret = 0;
> +
> +	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
> +		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
> +		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
> +		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
> +	}
> +
> +	while (len) {
> +		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
> +		if (ret)
> +			goto err;
> +
> +		ssbi_writel(ssbi, cmd, SSBI2_CMD);
> +		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
> +		if (ret)
> +			goto err;
> +		*buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
> +		len--;
> +	}
> +
> +err:
> +	return ret;
> +}
> +
> +static int
> +msm_ssbi_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
> +{
> +	int ret = 0;
> +
> +	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
> +		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
> +		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
> +		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
> +	}
> +
> +	while (len) {
> +		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
> +		if (ret)
> +			goto err;
> +
> +		ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
> +		ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
> +		if (ret)
> +			goto err;
> +		buf++;
> +		len--;
> +	}
> +
> +err:
> +	return ret;
> +}
> +
> +static inline int
> +msm_ssbi_pa_transfer(struct msm_ssbi *ssbi, u32 cmd, u8 *data)
> +{
> +	u32 timeout = SSBI_TIMEOUT_US;
> +	u32 rd_status = 0;
> +
> +	ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
> +
> +	while (timeout--) {
> +		rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
> +
> +		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED) {
> +			dev_err(ssbi->dev, "%s: transaction denied (0x%x)\n",
> +					__func__, rd_status);
> +			return -EPERM;
> +		}
> +
> +		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
> +			if (data)
> +				*data = rd_status & 0xff;
> +			return 0;
> +		}
> +		udelay(1);
> +	}
> +
> +	dev_err(ssbi->dev, "%s: timeout, status 0x%x\n", __func__, rd_status);
> +	return -ETIMEDOUT;
> +}
> +
> +static int
> +msm_ssbi_pa_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
> +{
> +	u32 cmd;
> +	int ret = 0;
> +
> +	cmd = SSBI_PA_CMD_RDWRN | (addr & 0x3fff) << 8;
> +
> +	while (len) {
> +		ret = msm_ssbi_pa_transfer(ssbi, cmd, buf);
> +		if (ret)
> +			goto err;
> +		buf++;
> +		len--;
> +	}
> +
> +err:
> +	return ret;
> +}
> +
> +static int
> +msm_ssbi_pa_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
> +{
> +	u32 cmd;
> +	int ret = 0;
> +
> +	while (len) {
> +		cmd = (addr & 0x3fff) << 8 | *buf;
> +		ret = msm_ssbi_pa_transfer(ssbi, cmd, NULL);
> +		if (ret)
> +			goto err;
> +		buf++;
> +		len--;
> +	}
> +
> +err:
> +	return ret;
> +}
> +
> +int msm_ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
> +{
> +	struct msm_ssbi *ssbi = to_msm_ssbi(dev);
> +	unsigned long flags;
> +	int ret;
> +
> +	BUG_ON(ssbi->dev != dev);

Are you sure you don't just want to bail out here, cause this hangs the
system when it triggers?

> +	spin_lock_irqsave(&ssbi->lock, flags);
> +	ret = ssbi->read(ssbi, addr, buf, len);
> +	spin_unlock_irqrestore(&ssbi->lock, flags);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(msm_ssbi_read);
> +
> +int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
> +{
> +	struct msm_ssbi *ssbi = to_msm_ssbi(dev);
> +	unsigned long flags;
> +	int ret;
> +
> +	BUG_ON(ssbi->dev != dev);
> +
> +	spin_lock_irqsave(&ssbi->lock, flags);
> +	ret = ssbi->write(ssbi, addr, buf, len);
> +	spin_unlock_irqrestore(&ssbi->lock, flags);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(msm_ssbi_write);
> +
> +static int __devinit msm_ssbi_add_slave(struct msm_ssbi *ssbi,
> +				     const struct msm_ssbi_slave_info *slave)
> +{
> +	struct platform_device *slave_pdev;
> +	int ret;
> +
> +	if (ssbi->slave) {
> +		pr_err("%s: slave already attached??\n", __func__);
> +		return -EBUSY;

You can use a pr_fmt line to add the __func__ part, look in mach-msm for
examples.

> +	}
> +
> +	slave_pdev = platform_device_alloc(slave->name, -1);
> +	if (!slave_pdev) {
> +		pr_err("%s: cannot allocate pdev for slave '%s'", __func__,
> +		       slave->name);
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	slave_pdev->dev.parent = ssbi->dev;
> +	slave_pdev->dev.platform_data = slave->platform_data;
> +
> +	ret = platform_device_add(slave_pdev);
> +	if (ret) {
> +		pr_err("%s: cannot add slave platform device for '%s'\n",
> +		       __func__, slave->name);
> +		goto err;
> +	}
> +
> +	ssbi->slave = &slave_pdev->dev;
> +	return 0;
> +
> +err:
> +	if (slave_pdev)
> +		platform_device_put(slave_pdev);
> +	return ret;
> +}
> +
> +static int __devinit msm_ssbi_probe(struct platform_device *pdev)
> +{
> +	const struct msm_ssbi_platform_data *pdata = pdev->dev.platform_data;
> +	struct resource *mem_res;
> +	struct msm_ssbi *ssbi;
> +	int ret = 0;
> +
> +	printk(KERN_INFO "%s: %s\n", __func__, pdata->slave.name);

pr_info() ?

Daniel

^ permalink raw reply

* [PATCH] arm: Footbridge: Fix I/O mappings for NOMMU mode
From: Stepan Moskovchenko @ 2011-02-25  2:05 UTC (permalink / raw)
  To: linux-arm-kernel

Use the correct I/O address definitions for Footbridge
peripherals when the kernel is compiled without MMU
support.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-footbridge/include/mach/hardware.h |   21 ++++++++++++++-------
 arch/arm/mach-footbridge/include/mach/io.h       |   10 ++++++++--
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
index 51dd902..b6fdf23 100644
--- a/arch/arm/mach-footbridge/include/mach/hardware.h
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -23,26 +23,33 @@
  * 0xf9000000	0x50000000	1MB	Cache flush
  * 0xf0000000	0x80000000	16MB	ISA memory
  */
+
+#ifdef CONFIG_MMU
+#define MMU_IO(a, b)	(a)
+#else
+#define MMU_IO(a, b)	(b)
+#endif
+
 #define XBUS_SIZE		0x00100000
-#define XBUS_BASE		0xff800000
+#define XBUS_BASE		MMU_IO(0xff800000, 0x40000000)

 #define ARMCSR_SIZE		0x00100000
-#define ARMCSR_BASE		0xfe000000
+#define ARMCSR_BASE		MMU_IO(0xfe000000, 0x42000000)

 #define WFLUSH_SIZE		0x00100000
-#define WFLUSH_BASE		0xfd000000
+#define WFLUSH_BASE		MMU_IO(0xfd000000, 0x78000000)

 #define PCIIACK_SIZE		0x00100000
-#define PCIIACK_BASE		0xfc000000
+#define PCIIACK_BASE		MMU_IO(0xfc000000, 0x79000000)

 #define PCICFG1_SIZE		0x01000000
-#define PCICFG1_BASE		0xfb000000
+#define PCICFG1_BASE		MMU_IO(0xfb000000, 0x7a000000)

 #define PCICFG0_SIZE		0x01000000
-#define PCICFG0_BASE		0xfa000000
+#define PCICFG0_BASE		MMU_IO(0xfa000000, 0x7b000000)

 #define PCIMEM_SIZE		0x01000000
-#define PCIMEM_BASE		0xf0000000
+#define PCIMEM_BASE		MMU_IO(0xf0000000, 0x80000000)

 #define XBUS_LEDS		((volatile unsigned char *)(XBUS_BASE + 0x12000))
 #define XBUS_LED_AMBER		(1 << 0)
diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h
index 101a4fe..32e4cc3 100644
--- a/arch/arm/mach-footbridge/include/mach/io.h
+++ b/arch/arm/mach-footbridge/include/mach/io.h
@@ -14,8 +14,14 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H

-#define PCIO_SIZE		0x00100000
-#define PCIO_BASE		0xff000000
+#ifdef CONFIG_MMU
+#define MMU_IO(a, b)	(a)
+#else
+#define MMU_IO(a, b)	(b)
+#endif
+
+#define PCIO_SIZE       0x00100000
+#define PCIO_BASE       MMU_IO(0xff000000, 0x7c000000)

 #define IO_SPACE_LIMIT 0xffff

--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 4/4] msm: iommu: Remove dependency on IDR
From: Stepan Moskovchenko @ 2011-02-25  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298599242-21971-1-git-send-email-stepanm@codeaurora.org>

Remove the depencency on the IOMMU IDR register, as it may
not be accessible depending on the security configuraton.
This involves moving the NCB field of IDR into the platform
data.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-msm/devices-iommu.c      |   26 +++++++++++++++++++-------
 arch/arm/mach-msm/include/mach/iommu.h |    4 ++++
 arch/arm/mach-msm/iommu.c              |    5 ++---
 arch/arm/mach-msm/iommu_dev.c          |   29 +++++++++++++++++------------
 4 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index af97afe..24030d0 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -280,50 +280,62 @@ static struct platform_device msm_root_iommu_dev = {

 static struct msm_iommu_dev jpegd_iommu = {
 	.name = "jpegd",
+	.ncb = 2,
 };

 static struct msm_iommu_dev vpe_iommu = {
-	.name = "vpe"
+	.name = "vpe",
+	.ncb = 2,
 };

 static struct msm_iommu_dev mdp0_iommu = {
-	.name = "mdp0"
+	.name = "mdp0",
+	.ncb = 2,
 };

 static struct msm_iommu_dev mdp1_iommu = {
-	.name = "mdp1"
+	.name = "mdp1",
+	.ncb = 2,
 };

 static struct msm_iommu_dev rot_iommu = {
-	.name = "rot"
+	.name = "rot",
+	.ncb = 2,
 };

 static struct msm_iommu_dev ijpeg_iommu = {
-	.name = "ijpeg"
+	.name = "ijpeg",
+	.ncb = 2,
 };

 static struct msm_iommu_dev vfe_iommu = {
 	.name = "vfe",
+	.ncb = 2,
 };

 static struct msm_iommu_dev vcodec_a_iommu = {
-	.name = "vcodec_a"
+	.name = "vcodec_a",
+	.ncb = 2,
 };

 static struct msm_iommu_dev vcodec_b_iommu = {
-	.name = "vcodec_b"
+	.name = "vcodec_b",
+	.ncb = 2,
 };

 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
+	.ncb = 3,
 };

 static struct msm_iommu_dev gfx2d0_iommu = {
 	.name = "gfx2d0",
+	.ncb = 2,
 };

 static struct msm_iommu_dev gfx2d1_iommu = {
 	.name = "gfx2d1",
+	.ncb = 2,
 };

 static struct platform_device msm_device_iommu_jpegd = {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 4dfe7ef..5c7c955 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -45,9 +45,11 @@
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
  * name		Human-readable name given to this IOMMU HW instance
+ * ncb		Number of context banks present on this IOMMU HW instance
  */
 struct msm_iommu_dev {
 	const char *name;
+	int ncb;
 };

 /**
@@ -69,6 +71,7 @@ struct msm_iommu_ctx_dev {
 /**
  * struct msm_iommu_drvdata - A single IOMMU hardware instance
  * @base:	IOMMU config port base address (VA)
+ * @ncb		The number of contexts on this IOMMU
  * @irq:	Interrupt number
  * @clk:	The bus clock for this IOMMU hardware instance
  * @pclk:	The clock for the IOMMU bus interconnect
@@ -79,6 +82,7 @@ struct msm_iommu_ctx_dev {
 struct msm_iommu_drvdata {
 	void __iomem *base;
 	int irq;
+	int ncb;
 	struct clk *clk;
 	struct clk *pclk;
 };
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 9c08740..0146f519 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -636,7 +636,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	struct msm_iommu_drvdata *drvdata = dev_id;
 	void __iomem *base;
 	unsigned int fsr;
-	int ncb, i, ret;
+	int i, ret;

 	spin_lock(&msm_iommu_lock);

@@ -654,8 +654,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	if (ret)
 		goto fail;

-	ncb = GET_NCB(base)+1;
-	for (i = 0; i < ncb; i++) {
+	for (i = 0; i < drvdata->ncb; i++) {
 		fsr = GET_FSR(base, i);
 		if (fsr) {
 			pr_err("Fault occurred in context %d.\n", i);
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index c1722eb..826a21d 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -85,9 +85,9 @@ fail:
 }
 EXPORT_SYMBOL(msm_iommu_get_ctx);

-static void msm_iommu_reset(void __iomem *base)
+static void msm_iommu_reset(void __iomem *base, int ncb)
 {
-	int ctx, ncb;
+	int ctx;

 	SET_RPUE(base, 0);
 	SET_RPUEIE(base, 0);
@@ -100,7 +100,6 @@ static void msm_iommu_reset(void __iomem *base)
 	SET_GLOBAL_TLBIALL(base, 0);
 	SET_RPU_ACR(base, 0);
 	SET_TLBLKCRWE(base, 1);
-	ncb = GET_NCB(base)+1;

 	for (ctx = 0; ctx < ncb; ctx++) {
 		SET_BPRCOSH(base, ctx, 0);
@@ -136,7 +135,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
 	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
 	void __iomem *regs_base;
 	resource_size_t	len;
-	int ret, ncb, nm2v, irq;
+	int ret, irq, par;

 	if (pdev->id == -1) {
 		msm_iommu_root_dev = pdev;
@@ -211,10 +210,18 @@ static int msm_iommu_probe(struct platform_device *pdev)
 		goto fail_io;
 	}

-	mb();
+	msm_iommu_reset(regs_base, iommu_dev->ncb);

-	if (GET_IDR(regs_base) == 0) {
-		pr_err("Invalid IDR value detected\n");
+	SET_M(regs_base, 0, 1);
+	SET_PAR(regs_base, 0, 0);
+	SET_V2PCFG(regs_base, 0, 1);
+	SET_V2PPR(regs_base, 0, 0);
+	par = GET_PAR(regs_base, 0);
+	SET_V2PCFG(regs_base, 0, 0);
+	SET_M(regs_base, 0, 0);
+
+	if (!par) {
+		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
 		ret = -ENODEV;
 		goto fail_io;
 	}
@@ -226,17 +233,15 @@ static int msm_iommu_probe(struct platform_device *pdev)
 		goto fail_io;
 	}

-	msm_iommu_reset(regs_base);
+
 	drvdata->pclk = iommu_pclk;
 	drvdata->clk = iommu_clk;
 	drvdata->base = regs_base;
 	drvdata->irq = irq;
-
-	nm2v = GET_NM2VCBMT((unsigned long) regs_base);
-	ncb = GET_NCB((unsigned long) regs_base);
+	drvdata->ncb = iommu_dev->ncb;

 	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
-			iommu_dev->name, regs_base, irq, ncb+1);
+		iommu_dev->name, regs_base, irq, iommu_dev->ncb);

 	platform_set_drvdata(pdev, drvdata);

--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 3/4] msm: iommu: Use ASID tagging instead of VMID tagging
From: Stepan Moskovchenko @ 2011-02-25  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298599242-21971-1-git-send-email-stepanm@codeaurora.org>

Use ASID tags in the TLB instead of VMID tags in
preparation for changes to the secure environment.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h |    4 +++-
 arch/arm/mach-msm/iommu.c                      |    9 ++++-----
 arch/arm/mach-msm/iommu_dev.c                  |   11 +++++++----
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index c2c3da9..bbd397c 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -68,6 +68,7 @@ do { \
 #define FL_CACHEABLE		(1 << 3)
 #define FL_TEX0			(1 << 12)
 #define FL_OFFSET(va)		(((va) & 0xFFF00000) >> 20)
+#define FL_NG			(1 << 17)

 /* Second-level page table bits */
 #define SL_BASE_MASK_LARGE	0xFFFF0000
@@ -81,6 +82,7 @@ do { \
 #define SL_CACHEABLE		(1 << 3)
 #define SL_TEX0			(1 << 6)
 #define SL_OFFSET(va)		(((va) & 0xFF000) >> 12)
+#define SL_NG			(1 << 11)

 /* Memory type and cache policy attributes */
 #define MT_SO			0
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index cde3cd0..9c08740 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -137,7 +137,6 @@ static void __reset_context(void __iomem *base, int ctx)
 	SET_TLBLKCR(base, ctx, 0);
 	SET_PRRR(base, ctx, 0);
 	SET_NMRR(base, ctx, 0);
-	SET_CONTEXTIDR(base, ctx, 0);
 }

 static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
@@ -418,11 +417,11 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 		for (i = 0; i < 16; i++)
 			*(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
 				  FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
-				  FL_SHARED | pgprot;
+				  FL_SHARED | FL_NG | pgprot;
 	}

 	if (len == SZ_1M)
-		*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE |
+		*fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | FL_NG |
 					    FL_TYPE_SECT | FL_SHARED | pgprot;

 	/* Need a 2nd level table */
@@ -447,7 +446,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,


 	if (len == SZ_4K)
-		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 |
+		*sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | SL_NG |
 					  SL_SHARED | SL_TYPE_SMALL | pgprot;

 	if (len == SZ_64K) {
@@ -455,7 +454,7 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,

 		for (i = 0; i < 16; i++)
 			*(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
-				SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
+			    SL_NG | SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
 	}

 	ret = __flush_iotlb(domain);
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index 69acd1e..c1722eb 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -330,14 +330,17 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 		SET_M2VCBR_N(drvdata->base, mid, 0);
 		SET_CBACR_N(drvdata->base, c->num, 0);

-		/* Set VMID = MID */
-		SET_VMID(drvdata->base, mid, mid);
+		/* Set VMID = 0 */
+		SET_VMID(drvdata->base, mid, 0);

 		/* Set the context number for that MID to this context */
 		SET_CBNDX(drvdata->base, mid, c->num);

-		/* Set MID associated with this context bank */
-		SET_CBVMID(drvdata->base, c->num, mid);
+		/* Set MID associated with this context bank to 0*/
+		SET_CBVMID(drvdata->base, c->num, 0);
+
+		/* Set the ASID for TLB tagging for this context */
+		SET_CONTEXTIDR_ASID(drvdata->base, c->num, c->num);

 		/* Set security bit override to be Non-secure */
 		SET_NSCFG(drvdata->base, mid, 3);
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control
From: Stepan Moskovchenko @ 2011-02-25  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298599242-21971-1-git-send-email-stepanm@codeaurora.org>

Clean up the clock control code in the probe calls, and add
support for controlling the clock for the IOMMU bus
interconnect. With the (proper) clock driver in place, the
clock control logic in the probe function can be made much
cleaner since it does not have to deal with the placeholder
driver anymore.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-msm/devices-iommu.c      |    5 -
 arch/arm/mach-msm/include/mach/iommu.h |    5 -
 arch/arm/mach-msm/iommu_dev.c          |  206 +++++++++++++++++++-------------
 3 files changed, 121 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index c0206b7..af97afe 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -280,7 +280,6 @@ static struct platform_device msm_root_iommu_dev = {

 static struct msm_iommu_dev jpegd_iommu = {
 	.name = "jpegd",
-	.clk_rate = -1
 };

 static struct msm_iommu_dev vpe_iommu = {
@@ -305,7 +304,6 @@ static struct msm_iommu_dev ijpeg_iommu = {

 static struct msm_iommu_dev vfe_iommu = {
 	.name = "vfe",
-	.clk_rate = -1
 };

 static struct msm_iommu_dev vcodec_a_iommu = {
@@ -318,17 +316,14 @@ static struct msm_iommu_dev vcodec_b_iommu = {

 static struct msm_iommu_dev gfx3d_iommu = {
 	.name = "gfx3d",
-	.clk_rate = 27000000
 };

 static struct msm_iommu_dev gfx2d0_iommu = {
 	.name = "gfx2d0",
-	.clk_rate = 27000000
 };

 static struct msm_iommu_dev gfx2d1_iommu = {
 	.name = "gfx2d1",
-	.clk_rate = 27000000
 };

 static struct platform_device msm_device_iommu_jpegd = {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 8738a44..4dfe7ef 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -45,14 +45,9 @@
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
  * name		Human-readable name given to this IOMMU HW instance
- * clk_rate	Rate to set for this IOMMU's clock, if applicable to this
- *		particular IOMMU. 0 means don't set a rate.
- *		-1 means it is an AXI clock with no valid rate
- *
  */
 struct msm_iommu_dev {
 	const char *name;
-	int clk_rate;
 };

 /**
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
index b83c73b..69acd1e 100644
--- a/arch/arm/mach-msm/iommu_dev.c
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@

 #include <mach/iommu_hw-8xxx.h>
 #include <mach/iommu.h>
+#include <mach/clk.h>

 struct iommu_ctx_iter_data {
 	/* input */
@@ -130,117 +131,134 @@ static int msm_iommu_probe(struct platform_device *pdev)
 {
 	struct resource *r, *r2;
 	struct clk *iommu_clk;
+	struct clk *iommu_pclk;
 	struct msm_iommu_drvdata *drvdata;
 	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
 	void __iomem *regs_base;
 	resource_size_t	len;
-	int ret = 0, ncb, nm2v, irq;
+	int ret, ncb, nm2v, irq;

-	if (pdev->id != -1) {
-		drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (pdev->id == -1) {
+		msm_iommu_root_dev = pdev;
+		return 0;
+	}

-		if (!drvdata) {
-			ret = -ENOMEM;
-			goto fail;
-		}
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);

-		if (!iommu_dev) {
-			ret = -ENODEV;
-			goto fail;
-		}
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	if (!iommu_dev) {
+		ret = -ENODEV;
+		goto fail;
+	}

-		if (iommu_dev->clk_rate != 0) {
-			iommu_clk = clk_get(&pdev->dev, "iommu_clk");
-
-			if (IS_ERR(iommu_clk)) {
-				ret = -ENODEV;
-				goto fail;
-			}
-
-			if (iommu_dev->clk_rate > 0) {
-				ret = clk_set_rate(iommu_clk,
-							iommu_dev->clk_rate);
-				if (ret) {
-					clk_put(iommu_clk);
-					goto fail;
-				}
-			}
-
-			ret = clk_enable(iommu_clk);
-			if (ret) {
-				clk_put(iommu_clk);
-				goto fail;
-			}
+	iommu_pclk = clk_get(NULL, "smmu_pclk");
+	if (IS_ERR(iommu_pclk)) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	ret = clk_enable(iommu_pclk);
+	if (ret)
+		goto fail_enable;
+
+	iommu_clk = clk_get(&pdev->dev, "iommu_clk");
+
+	if (!IS_ERR(iommu_clk))	{
+		if (clk_get_rate(iommu_clk) == 0)
+			clk_set_min_rate(iommu_clk, 1);
+
+		ret = clk_enable(iommu_clk);
+		if (ret) {
 			clk_put(iommu_clk);
+			goto fail_pclk;
 		}
+	} else
+		iommu_clk = NULL;

-		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						 "physbase");
-		if (!r) {
-			ret = -ENODEV;
-			goto fail;
-		}
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase");

-		len = r->end - r->start + 1;
+	if (!r) {
+		ret = -ENODEV;
+		goto fail_clk;
+	}

-		r2 = request_mem_region(r->start, len, r->name);
-		if (!r2) {
-			pr_err("Could not request memory region: "
-			"start=%p, len=%d\n", (void *) r->start, len);
-			ret = -EBUSY;
-			goto fail;
-		}
+	len = r->end - r->start + 1;

-		regs_base = ioremap(r2->start, len);
+	r2 = request_mem_region(r->start, len, r->name);
+	if (!r2) {
+		pr_err("Could not request memory region: start=%p, len=%d\n",
+							(void *) r->start, len);
+		ret = -EBUSY;
+		goto fail_clk;
+	}

-		if (!regs_base) {
-			pr_err("Could not ioremap: start=%p, len=%d\n",
-				 (void *) r2->start, len);
-			ret = -EBUSY;
-			goto fail_mem;
-		}
+	regs_base = ioremap(r2->start, len);

-		irq = platform_get_irq_byname(pdev, "secure_irq");
-		if (irq < 0) {
-			ret = -ENODEV;
-			goto fail_io;
-		}
+	if (!regs_base) {
+		pr_err("Could not ioremap: start=%p, len=%d\n",
+			 (void *) r2->start, len);
+		ret = -EBUSY;
+		goto fail_mem;
+	}
+
+	irq = platform_get_irq_byname(pdev, "secure_irq");
+	if (irq < 0) {
+		ret = -ENODEV;
+		goto fail_io;
+	}

-		mb();
+	mb();

-		if (GET_IDR(regs_base) == 0) {
-			pr_err("Invalid IDR value detected\n");
-			ret = -ENODEV;
-			goto fail_io;
-		}
+	if (GET_IDR(regs_base) == 0) {
+		pr_err("Invalid IDR value detected\n");
+		ret = -ENODEV;
+		goto fail_io;
+	}

-		ret = request_irq(irq, msm_iommu_fault_handler, 0,
-				"msm_iommu_secure_irpt_handler", drvdata);
-		if (ret) {
-			pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-			goto fail_io;
-		}
+	ret = request_irq(irq, msm_iommu_fault_handler, 0,
+			"msm_iommu_secure_irpt_handler", drvdata);
+	if (ret) {
+		pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
+		goto fail_io;
+	}

-		msm_iommu_reset(regs_base);
-		drvdata->base = regs_base;
-		drvdata->irq = irq;
+	msm_iommu_reset(regs_base);
+	drvdata->pclk = iommu_pclk;
+	drvdata->clk = iommu_clk;
+	drvdata->base = regs_base;
+	drvdata->irq = irq;

-		nm2v = GET_NM2VCBMT((unsigned long) regs_base);
-		ncb = GET_NCB((unsigned long) regs_base);
+	nm2v = GET_NM2VCBMT((unsigned long) regs_base);
+	ncb = GET_NCB((unsigned long) regs_base);

-		pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
+	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
 			iommu_dev->name, regs_base, irq, ncb+1);

-		platform_set_drvdata(pdev, drvdata);
-	} else
-		msm_iommu_root_dev = pdev;
+	platform_set_drvdata(pdev, drvdata);

-	return 0;
+	if (iommu_clk)
+		clk_disable(iommu_clk);
+
+	clk_disable(iommu_pclk);

+	return 0;
 fail_io:
 	iounmap(regs_base);
 fail_mem:
 	release_mem_region(r->start, len);
+fail_clk:
+	if (iommu_clk) {
+		clk_disable(iommu_clk);
+		clk_put(iommu_clk);
+	}
+fail_pclk:
+	clk_disable(iommu_pclk);
+fail_enable:
+	clk_put(iommu_pclk);
 fail:
 	kfree(drvdata);
 	return ret;
@@ -252,7 +270,10 @@ static int msm_iommu_remove(struct platform_device *pdev)

 	drv = platform_get_drvdata(pdev);
 	if (drv) {
-		memset(drv, 0, sizeof(struct msm_iommu_drvdata));
+		if (drv->clk)
+			clk_put(drv->clk);
+		clk_put(drv->pclk);
+		memset(drv, 0, sizeof(*drv));
 		kfree(drv);
 		platform_set_drvdata(pdev, NULL);
 	}
@@ -264,7 +285,7 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 	struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
 	struct msm_iommu_drvdata *drvdata;
 	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
-	int i, ret = 0;
+	int i, ret;
 	if (!c || !pdev->dev.parent) {
 		ret = -EINVAL;
 		goto fail;
@@ -288,6 +309,18 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
 	platform_set_drvdata(pdev, ctx_drvdata);

+	ret = clk_enable(drvdata->pclk);
+	if (ret)
+		goto fail;
+
+	if (drvdata->clk) {
+		ret = clk_enable(drvdata->clk);
+		if (ret) {
+			clk_disable(drvdata->pclk);
+			goto fail;
+		}
+	}
+
 	/* Program the M2V tables for this context */
 	for (i = 0; i < MAX_NUM_MIDS; i++) {
 		int mid = c->mids[i];
@@ -310,8 +343,11 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)
 		SET_NSCFG(drvdata->base, mid, 3);
 	}

-	pr_info("context device %s with bank index %d\n", c->name, c->num);
+	if (drvdata->clk)
+		clk_disable(drvdata->clk);
+	clk_disable(drvdata->pclk);

+	dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num);
 	return 0;
 fail:
 	kfree(ctx_drvdata);
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 1/4] msm: iommu: Clock control for the IOMMU driver
From: Stepan Moskovchenko @ 2011-02-25  2:00 UTC (permalink / raw)
  To: linux-arm-kernel

Add clock control to the IOMMU driver. The IOMMU bus clock
(and potentially an AXI clock) need to be on to gain access
to IOMMU registers. Actively control these clocks when
needed instead of leaving them on.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
---
 arch/arm/mach-msm/include/mach/iommu.h |    9 ++++-
 arch/arm/mach-msm/iommu.c              |   58 ++++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 296c0f1..8738a44 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 #define MSM_IOMMU_H

 #include <linux/interrupt.h>
+#include <linux/clk.h>

 /* Sharability attributes of MSM IOMMU mappings */
 #define MSM_IOMMU_ATTR_NON_SH		0x0
@@ -74,13 +75,17 @@ struct msm_iommu_ctx_dev {
  * struct msm_iommu_drvdata - A single IOMMU hardware instance
  * @base:	IOMMU config port base address (VA)
  * @irq:	Interrupt number
-  *
+ * @clk:	The bus clock for this IOMMU hardware instance
+ * @pclk:	The clock for the IOMMU bus interconnect
+ *
  * A msm_iommu_drvdata holds the global driver data about a single piece
  * of an IOMMU hardware instance.
  */
 struct msm_iommu_drvdata {
 	void __iomem *base;
 	int irq;
+	struct clk *clk;
+	struct clk *pclk;
 };

 /**
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index e2d58e4..cde3cd0 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/iommu.h>
+#include <linux/clk.h>

 #include <asm/cacheflush.h>
 #include <asm/sizes.h>
@@ -50,6 +51,30 @@ struct msm_priv {
 	struct list_head list_attached;
 };

+static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	int ret;
+
+	ret = clk_enable(drvdata->pclk);
+	if (ret)
+		goto fail;
+
+	if (drvdata->clk) {
+		ret = clk_enable(drvdata->clk);
+		if (ret)
+			clk_disable(drvdata->pclk);
+	}
+fail:
+	return ret;
+}
+
+static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+	if (drvdata->clk)
+		clk_disable(drvdata->clk);
+	clk_disable(drvdata->pclk);
+}
+
 static int __flush_iotlb(struct iommu_domain *domain)
 {
 	struct msm_priv *priv = domain->priv;
@@ -77,9 +102,16 @@ static int __flush_iotlb(struct iommu_domain *domain)
 			BUG();

 		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+		BUG_ON(!iommu_drvdata);
+
+		ret = __enable_clocks(iommu_drvdata);
+		if (ret)
+			goto fail;
+
 		SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
+		__disable_clocks(iommu_drvdata);
 	}
-
+fail:
 	return ret;
 }

@@ -265,9 +297,14 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			goto fail;
 		}

+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto fail;
+
 	__program_context(iommu_drvdata->base, ctx_dev->num,
 			  __pa(priv->pgtable));

+	__disable_clocks(iommu_drvdata);
 	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
 	ret = __flush_iotlb(domain);

@@ -303,7 +340,12 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
 	if (ret)
 		goto fail;

+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto fail;
+
 	__reset_context(iommu_drvdata->base, ctx_dev->num);
+	__disable_clocks(iommu_drvdata);
 	list_del_init(&ctx_drvdata->attached_elm);

 fail:
@@ -532,6 +574,10 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
 	base = iommu_drvdata->base;
 	ctx = ctx_drvdata->num;

+	ret = __enable_clocks(iommu_drvdata);
+	if (ret)
+		goto fail;
+
 	/* Invalidate context TLB */
 	SET_CTX_TLBIALL(base, ctx, 0);
 	SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT);
@@ -547,6 +593,7 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
 	if (GET_FAULT(base, ctx))
 		ret = 0;

+	__disable_clocks(iommu_drvdata);
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
 	return ret;
@@ -590,7 +637,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	struct msm_iommu_drvdata *drvdata = dev_id;
 	void __iomem *base;
 	unsigned int fsr;
-	int ncb, i;
+	int ncb, i, ret;

 	spin_lock(&msm_iommu_lock);

@@ -604,6 +651,10 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 	pr_err("Unexpected IOMMU page fault!\n");
 	pr_err("base = %08x\n", (unsigned int) base);

+	ret = __enable_clocks(drvdata);
+	if (ret)
+		goto fail;
+
 	ncb = GET_NCB(base)+1;
 	for (i = 0; i < ncb; i++) {
 		fsr = GET_FSR(base, i);
@@ -614,6 +665,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 			SET_FSR(base, i, 0x4000000F);
 		}
 	}
+	__disable_clocks(drvdata);
 fail:
 	spin_unlock(&msm_iommu_lock);
 	return 0;
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 1/3] msm: iommu: Create a Kconfig item for the IOMMU driver
From: David Brown @ 2011-02-25  0:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297799373.7088.5.camel@c-dwalke-linux.qualcomm.com>

On Tue, Feb 15 2011, Daniel Walker wrote:

> Typically we include everything the SoC has regardless of if drivers use
> the hardware or not . For instance there could be modules that use the
> hardware ..
>
> Regardless of this point, I've nacked the whole series. It looks like
> there was very little thought put into this.

I want to try to resolve this particular series.  I had originally
pulled the series in because I thought everything had been addressed,
you followed this with a generic NAK.

You raised a couple of issues:

  - Should this be configurable?  I responded that our iommu is
    optional.  Drivers will work whether the iommu is enabled or not.
    Other architectures have configurable iommu drivers (and some are
    selected).  For example: arm/plat-s5p, powerpc/pasemi, as well x86.

    One reason to disable may be for building a slimmed kernel for
    kexec.

  - Should the iommu driver be under arch/arm/mach-msm.  As discussed in
    <https://lkml.org/lkml/2011/2/22/722>, iommu drivers fall into kind
    of a grey area.  Currently, most platform iommu drivers are in arch
    specific directories.

  - The renaming of the device file.  At this point, the two MSM chips
    that have an IOMMU have an identical IOMMU configuration.  The
    patches reflect this by removing the soc name from the file.  Future
    chips will probably have iommu hardware that differs, but it isn't
    possible to predict what the differences will be, so that will have
    to be addressed then.

I can certainly back out the changes if necessary.  Please let me know
if you have any specific concerns.

David

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* [PATCH] drivers: ld9040 amoled driver support
From: Andrew Morton @ 2011-02-24 23:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294893628-16998-1-git-send-email-dh09.lee@samsung.com>

On Thu, 13 Jan 2011 13:40:28 +0900
Donghwa Lee <dh09.lee@samsung.com> wrote:

> This patch is ld9040 amoled panel driver.
> I resend because there was no comment.
> 
> It is similar to s6e63m0 panel driver and use spi gpio to send panel
> information.
> 
>
> ...
>
> +#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)

This could and should be implemented as a regular lower-case C function.

> +struct ld9040 {
> +	struct device			*dev;
> +	struct spi_device		*spi;
> +	unsigned int			power;
> +	unsigned int			gamma_mode;
> +	unsigned int			current_brightness;
> +	unsigned int			gamma_table_count;
> +
> +	struct lcd_device		*ld;
> +	struct backlight_device		*bd;
> +	struct lcd_platform_data	*lcd_pd;
> +};
> +
> +static const unsigned short SEQ_SWRESET[] = {
> +	0x01, COMMAND_ONLY,
> +	ENDDEF, 0x00
> +};

It's strange that all these tables have upper-case names.  Unless
there's some special reason for doing it this way, please make them
regular lower-case identifiers.

>
> ...
>
> +static int ld9040_ldi_init(struct ld9040 *lcd)
> +{
> +	int ret, i;
> +	const unsigned short *init_seq[] = {
> +		SEQ_USER_SETTING,
> +		SEQ_PANEL_CONDITION,
> +		SEQ_DISPCTL,
> +		SEQ_MANPWR,
> +		SEQ_PWR_CTRL,
> +		SEQ_ELVSS_ON,
> +		SEQ_GTCON,
> +		SEQ_GAMMA_SET1,
> +		SEQ_GAMMA_CTRL,
> +		SEQ_SLPOUT,
> +	};

Make this table static so the compiler doesn't rebuild it on the stack
each time the function is called.  The compiler probably already
performs that optimisation, but it doesn't hurt to be explicit.


> +	for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
> +		ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
> +		/* workaround: minimum delay time for transferring CMD */
> +		udelay(300);
> +		if (ret)
> +			break;
> +	}
> +
> +	return ret;
> +}
> +
>
> ...
>
> +static ssize_t ld9040_sysfs_show_gamma_mode(struct device *dev,
> +				      struct device_attribute *attr, char *buf)
> +{
> +	struct ld9040 *lcd = dev_get_drvdata(dev);
> +	char temp[10];
> +
> +	switch (lcd->gamma_mode) {
> +	case 0:
> +		sprintf(temp, "2.2 mode\n");
> +		strcat(buf, temp);

Could do sprintf(buf + strlen(buf)) and eliminate temp[].

> +		break;
> +	default:
> +		dev_info(dev, "gamma mode could be 0:2.2\n");
> +		break;
> +	}
> +
> +	return strlen(buf);
> +}
> +
> +static ssize_t ld9040_sysfs_store_gamma_mode(struct device *dev,
> +				       struct device_attribute *attr,
> +				       const char *buf, size_t len)
> +{
> +	struct ld9040 *lcd = dev_get_drvdata(dev);
> +	struct backlight_device *bd = NULL;
> +	int brightness, rc;
> +
> +	rc = strict_strtoul(buf, 0, (unsigned long *)&lcd->gamma_mode);

That's a bug.  gamma_mode has type int, which is 4 bytes, but you're
telling strict_strtoul() to write eight bytes - it will corrupt *lcd on
a 64-bit machine.  Use a temporary.


> +	if (rc < 0)
> +		return rc;
> +
> +	bd = lcd->bd;
> +
> +	brightness = bd->props.brightness;
> +
> +	switch (lcd->gamma_mode) {
> +	case 0:
> +		_ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]);
> +		break;
> +	default:
> +		dev_info(dev, "gamma mode could be 0:2.2\n");
> +		_ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]);
> +		break;
> +	}
> +	return len;
> +}
> +
> +static DEVICE_ATTR(gamma_mode, 0644,
> +		ld9040_sysfs_show_gamma_mode, ld9040_sysfs_store_gamma_mode);
> +
> +static ssize_t ld9040_sysfs_show_gamma_table(struct device *dev,
> +				      struct device_attribute *attr, char *buf)
> +{
> +	struct ld9040 *lcd = dev_get_drvdata(dev);
> +	char temp[3];
> +
> +	sprintf(temp, "%d\n", lcd->gamma_table_count);
> +	strcpy(buf, temp);

sprintf(buf + strlen(buf), remove temp[].

> +	return strlen(buf);
> +}
> +
> +static DEVICE_ATTR(gamma_table, 0644,
> +		ld9040_sysfs_show_gamma_table, NULL);
> +
> +static int ld9040_probe(struct spi_device *spi)
> +{
> +	int ret = 0;
> +	struct ld9040 *lcd = NULL;
> +	struct lcd_device *ld = NULL;
> +	struct backlight_device *bd = NULL;
> +
> +	lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
> +	if (!lcd)
> +		return -ENOMEM;
> +
> +	/* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
> +	spi->bits_per_word = 9;
> +
> +	ret = spi_setup(spi);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "spi setup failed.\n");
> +		goto out_free_lcd;
> +	}
> +
> +	lcd->spi = spi;
> +	lcd->dev = &spi->dev;
> +
> +	lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data;

Unneeded and undesirable typecast.

> +	if (!lcd->lcd_pd) {
> +		dev_err(&spi->dev, "platform data is NULL.\n");
> +		goto out_free_lcd;
> +	}
> +
> +	ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
> +	if (IS_ERR(ld)) {
> +		ret = PTR_ERR(ld);
> +		goto out_free_lcd;
> +	}
> +
> +	lcd->ld = ld;
> +
> +	bd = backlight_device_register("ld9040-bl", &spi->dev,
> +		lcd, &ld9040_backlight_ops, NULL);
> +	if (IS_ERR(ld)) {
> +		ret = PTR_ERR(ld);
> +		goto out_free_lcd;
> +	}
> +
> +	bd->props.max_brightness = MAX_BRIGHTNESS;
> +	bd->props.brightness = MAX_BRIGHTNESS;
> +	lcd->bd = bd;
> +
> +	/*
> +	 * it gets gamma table count available so it gets user
> +	 * know that.
> +	 */
> +	lcd->gamma_table_count =
> +	    sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int));
> +
> +	ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode);
> +	if (ret < 0)
> +		dev_err(&(spi->dev), "failed to add sysfs entries\n");
> +
> +	ret = device_create_file(&(spi->dev), &dev_attr_gamma_table);
> +	if (ret < 0)
> +		dev_err(&(spi->dev), "failed to add sysfs entries\n");

These errors are just ignored.  It would be better to perform cleanup
and to then return the correct errno.

> +	/*
> +	 * if lcd panel was on from bootloader like u-boot then
> +	 * do not lcd on.
> +	 */
> +	if (!lcd->lcd_pd->lcd_enabled) {
> +		/*
> +		 * if lcd panel was off from bootloader then
> +		 * current lcd status is powerdown and then
> +		 * it enables lcd panel.
> +		 */
> +		lcd->power = FB_BLANK_POWERDOWN;
> +
> +		ld9040_power(lcd, FB_BLANK_UNBLANK);
> +	} else
> +		lcd->power = FB_BLANK_UNBLANK;
> +
> +	dev_set_drvdata(&spi->dev, lcd);
> +
> +	dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
> +	return 0;
> +
> +out_free_lcd:
> +	kfree(lcd);
> +	return ret;
> +}
> +
> +static int __devexit ld9040_remove(struct spi_device *spi)
> +{
> +	struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
> +
> +	ld9040_power(lcd, FB_BLANK_POWERDOWN);
> +	lcd_device_unregister(lcd->ld);
> +	kfree(lcd);
> +
> +	return 0;
> +}
> +
> +#if defined(CONFIG_PM)
> +unsigned int beforepower;

This should be static.

Also, it shouldn't exist.  Its presence assumes that there will only be
one device controlled by this driver.  It should be moved into the
per-device data area.

>
> ...
>
> +struct ld9040_gamma {
> +	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
> +};
> +
> +static struct ld9040_gamma gamma_table = {

Could do

static struct ld9040_gamma {
	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL];
} gamma_table = {

here.

> +	.gamma_22_table[0] = (unsigned int *)&ld9040_22_50,
> +	.gamma_22_table[1] = (unsigned int *)&ld9040_22_70,
> +	.gamma_22_table[2] = (unsigned int *)&ld9040_22_80,
> +	.gamma_22_table[3] = (unsigned int *)&ld9040_22_90,
> +	.gamma_22_table[4] = (unsigned int *)&ld9040_22_100,
> +	.gamma_22_table[5] = (unsigned int *)&ld9040_22_110,
> +	.gamma_22_table[6] = (unsigned int *)&ld9040_22_120,
> +	.gamma_22_table[7] = (unsigned int *)&ld9040_22_130,
> +	.gamma_22_table[8] = (unsigned int *)&ld9040_22_140,
> +	.gamma_22_table[9] = (unsigned int *)&ld9040_22_150,
> +	.gamma_22_table[10] = (unsigned int *)&ld9040_22_160,
> +	.gamma_22_table[11] = (unsigned int *)&ld9040_22_170,
> +	.gamma_22_table[12] = (unsigned int *)&ld9040_22_180,
> +	.gamma_22_table[13] = (unsigned int *)&ld9040_22_190,
> +	.gamma_22_table[14] = (unsigned int *)&ld9040_22_200,
> +	.gamma_22_table[15] = (unsigned int *)&ld9040_22_210,
> +	.gamma_22_table[16] = (unsigned int *)&ld9040_22_220,
> +	.gamma_22_table[17] = (unsigned int *)&ld9040_22_230,
> +	.gamma_22_table[18] = (unsigned int *)&ld9040_22_240,
> +	.gamma_22_table[19] = (unsigned int *)&ld9040_22_250,
> +	.gamma_22_table[20] = (unsigned int *)&ld9040_22_260,
> +	.gamma_22_table[21] = (unsigned int *)&ld9040_22_270,
> +	.gamma_22_table[22] = (unsigned int *)&ld9040_22_280,
> +	.gamma_22_table[23] = (unsigned int *)&ld9040_22_290,
> +	.gamma_22_table[24] = (unsigned int *)&ld9040_22_300,
> +};
> +
> +#endif

Defining static tables in a header file is strange.  It would be very
wrong if that header was ever included by more than a single .c file,
so why not just eliminate this file and move its contents into that .c
file?

^ permalink raw reply

* [PATCH] omap2+: Minimize board specific init_early calls
From: Tony Lindgren @ 2011-02-24 23:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224223137.GV20560@atomide.com>

We should only call init_common_infrastructure and
init_common_devices from init_early.

Signed-off-by: Tony Lindgren <tony@atomide.com>

---
This is done against the linux-omap devel-board branch 
---
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index cc42d47..59de1dc 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -142,8 +142,6 @@ static struct omap_board_config_kernel sdp2430_config[] __initdata = {
 
 static void __init omap_2430sdp_init_early(void)
 {
-	omap_board_config = sdp2430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -246,6 +244,9 @@ static void __init omap_2430sdp_init(void)
 
 	omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
 
+	omap_board_config = sdp2430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
+
 	omap2430_i2c_init();
 
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 8950ecc..b12b620 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -315,9 +315,6 @@ static struct omap_board_config_kernel sdp3430_config[] __initdata = {
 
 static void __init omap_3430sdp_init_early(void)
 {
-	omap_board_config = sdp3430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
-	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL);
 }
@@ -788,6 +785,9 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init omap_3430sdp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = sdp3430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
 	omap3430_i2c_init();
 	omap_display_init(&sdp3430_dss_data);
 	if (omap_rev() > OMAP3430_REV_ES1_0)
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 8d1c435..c4e22b3 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -72,8 +72,6 @@ static struct omap_board_config_kernel sdp_config[] __initdata = {
 
 static void __init omap_sdp_init_early(void)
 {
-	omap_board_config = sdp_config;
-	omap_board_config_size = ARRAY_SIZE(sdp_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
 				  h8mbx00u0mer0em_sdrc_params);
@@ -206,6 +204,8 @@ static struct flash_partitions sdp_flash_partitions[] = {
 static void __init omap_sdp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+	omap_board_config = sdp_config;
+	omap_board_config_size = ARRAY_SIZE(sdp_config);
 	zoom_peripherals_init();
 	zoom_display_init();
 	board_smc91x_init();
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 1a943be..81ef979 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -325,8 +325,6 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = {
 
 static void __init omap_4430sdp_init_early(void)
 {
-	omap_board_config = sdp4430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp4430_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 #ifdef CONFIG_OMAP_32K_TIMER
@@ -640,6 +638,9 @@ static void __init omap_4430sdp_init(void)
 		package = OMAP_PACKAGE_CBL;
 	omap4_mux_init(board_mux, package);
 
+	omap_board_config = sdp4430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp4430_config);
+
 	omap4_i2c_init();
 	omap_sfh7741prox_init();
 	platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index ae3a83d..f53bbb2 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -51,9 +51,6 @@ static struct omap_board_mux board_mux[] __initdata = {
 
 static void __init am3517_crane_init_early(void)
 {
-	omap_board_config = am3517_crane_config;
-	omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
-
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -76,6 +73,9 @@ static void __init am3517_crane_init(void)
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_serial_init();
 
+	omap_board_config = am3517_crane_config;
+	omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
+
 	/* Configure GPIO for EHCI port */
 	if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
 		pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 634fe65..30ec451 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -381,13 +381,8 @@ static struct omap_dss_board_info am3517_evm_dss_data = {
 /*
  * Board initialization
  */
-static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
-};
-
 static void __init am3517_evm_init_early(void)
 {
-	omap_board_config = am3517_evm_config;
-	omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -481,8 +476,13 @@ static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
 	platform_device_register(&am3517_hecc_device);
 }
 
+static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
+};
+
 static void __init am3517_evm_init(void)
 {
+	omap_board_config = am3517_evm_config;
+	omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 
 	am3517_evm_i2c_init();
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 4ef4aad..f4f8374 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -276,8 +276,6 @@ static struct omap_board_config_kernel apollon_config[] __initdata = {
 
 static void __init omap_apollon_init_early(void)
 {
-	omap_board_config = apollon_config;
-	omap_board_config_size = ARRAY_SIZE(apollon_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -319,6 +317,8 @@ static void __init omap_apollon_init(void)
 	u32 v;
 
 	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+	omap_board_config = apollon_config;
+	omap_board_config_size = ARRAY_SIZE(apollon_config);
 
 	apollon_init_smc91x();
 	apollon_led_init();
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 7311824..27bea54 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -668,14 +668,8 @@ static void __init cm_t35_init_i2c(void)
 			      ARRAY_SIZE(cm_t35_i2c_boardinfo));
 }
 
-static struct omap_board_config_kernel cm_t35_config[] __initdata = {
-};
-
 static void __init cm_t35_init_early(void)
 {
-	omap_board_config = cm_t35_config;
-	omap_board_config_size = ARRAY_SIZE(cm_t35_config);
-
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
@@ -785,8 +779,13 @@ static struct omap_musb_board_data musb_board_data = {
 	.power			= 100,
 };
 
+static struct omap_board_config_kernel cm_t35_config[] __initdata = {
+};
+
 static void __init cm_t35_init(void)
 {
+	omap_board_config = cm_t35_config;
+	omap_board_config_size = ARRAY_SIZE(cm_t35_config);
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
 	omap_serial_init();
 	cm_t35_init_i2c();
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 38bef6d..9da6e82 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -256,9 +256,6 @@ static struct omap_board_config_kernel cm_t3517_config[] __initdata = {
 
 static void __init cm_t3517_init_early(void)
 {
-	omap_board_config = cm_t3517_config;
-	omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
-
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -293,6 +290,8 @@ static void __init cm_t3517_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_serial_init();
+	omap_board_config = cm_t3517_config;
+	omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
 	cm_t3517_init_leds();
 	cm_t3517_init_nand();
 	cm_t3517_init_rtc();
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 682da92..73e3c31 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -35,8 +35,6 @@ static struct omap_board_config_kernel generic_config[] = {
 
 static void __init omap_generic_init_early(void)
 {
-	omap_board_config = generic_config;
-	omap_board_config_size = ARRAY_SIZE(generic_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -44,6 +42,8 @@ static void __init omap_generic_init_early(void)
 static void __init omap_generic_init(void)
 {
 	omap_serial_init();
+	omap_board_config = generic_config;
+	omap_board_config_size = ARRAY_SIZE(generic_config);
 }
 
 static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index f6a3872..7e6bf4f 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -292,8 +292,6 @@ static struct omap_board_config_kernel h4_config[] __initdata = {
 
 static void __init omap_h4_init_early(void)
 {
-	omap_board_config = h4_config;
-	omap_board_config_size = ARRAY_SIZE(h4_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -334,6 +332,9 @@ static void __init omap_h4_init(void)
 {
 	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
 
+	omap_board_config = h4_config;
+	omap_board_config_size = ARRAY_SIZE(h4_config);
+
 	/*
 	 * Make sure the serial ports are muxed on at this point.
 	 * You have to mux them off in device drivers later on
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index a3fae56..a69e594 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -290,8 +290,6 @@ static struct omap_board_config_kernel ldp_config[] __initdata = {
 
 static void __init omap_ldp_init_early(void)
 {
-	omap_board_config = ldp_config;
-	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -422,6 +420,8 @@ static struct mtd_partition ldp_nand_partitions[] = {
 static void __init omap_ldp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = ldp_config;
+	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	ldp_init_smsc911x();
 	omap_i2c_init();
 	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 5364147..3d9b58a 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -732,8 +732,6 @@ static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
 
 static void __init omap3_evm_init_early(void)
 {
-	omap_board_config = omap3_evm_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
 }
@@ -824,6 +822,9 @@ static void __init omap3_evm_init(void)
 	else
 		omap3_mux_init(omap35x_board_mux, OMAP_PACKAGE_CBB);
 
+	omap_board_config = omap3_evm_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
+
 	omap3_evm_i2c_init();
 
 	omap_display_init(&omap3_evm_dss_data);
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 07006c3..fd8b764 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -581,8 +581,6 @@ static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
 
 static void __init omap3_stalker_init_early(void)
 {
-	omap_board_config = omap3_stalker_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
 }
@@ -629,6 +627,8 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init omap3_stalker_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+	omap_board_config = omap3_stalker_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
 	omap3_stalker_i2c_init();
 
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index a35afe2..8e2a7ba 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -417,8 +417,6 @@ static struct omap_board_mux board_mux[] __initdata = {
 
 static void __init omap3_touchbook_init_early(void)
 {
-	omap_board_config = omap3_touchbook_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
 				  mt46h32m32lf6_sdrc_params);
@@ -514,6 +512,9 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init omap3_touchbook_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = omap3_touchbook_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
+
 	pm_power_off = omap3_touchbook_poweroff;
 
 	omap3_touchbook_i2c_init();
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index a33ec0e..d480ddb 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -411,8 +411,6 @@ static struct omap_board_config_kernel overo_config[] __initdata = {
 
 static void __init overo_init_early(void)
 {
-	omap_board_config = overo_config;
-	omap_board_config_size = ARRAY_SIZE(overo_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
 				  mt46h32m32lf6_sdrc_params);
@@ -448,6 +446,8 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init overo_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = overo_config;
+	omap_board_config_size = ARRAY_SIZE(overo_config);
 	overo_i2c_init();
 	platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
 	omap_serial_init();
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 3cf72fe..e964895 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -102,9 +102,6 @@ static void __init rx51_init_early(void)
 {
 	struct omap_sdrc_params *sdrc_params;
 
-	omap_board_config = rx51_config;
-	omap_board_config_size = ARRAY_SIZE(rx51_config);
-	omap3_pm_init_cpuidle(rx51_cpuidle_params);
 	omap2_init_common_infrastructure();
 	sdrc_params = nokia_get_sdram_timings();
 	omap2_init_common_devices(sdrc_params, sdrc_params);
@@ -127,6 +124,9 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init rx51_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = rx51_config;
+	omap_board_config_size = ARRAY_SIZE(rx51_config);
+	omap3_pm_init_cpuidle(rx51_cpuidle_params);
 	omap_serial_init();
 	usb_musb_init(&musb_board_data);
 	rx51_peripherals_init();
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index f2b0971..09fa7bf 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -29,8 +29,6 @@ static struct omap_board_config_kernel ti8168_evm_config[] __initdata = {
 
 static void __init ti8168_init_early(void)
 {
-	omap_board_config = ti8168_evm_config;
-	omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(NULL, NULL);
 }
@@ -43,6 +41,8 @@ static void __init ti8168_evm_init_irq(void)
 static void __init ti8168_evm_init(void)
 {
 	omap_serial_init();
+	omap_board_config = ti8168_evm_config;
+	omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
 }
 
 static void __init ti8168_evm_map_io(void)

^ permalink raw reply related

* [PATCH v2 1/2] MAINTAINERS: Add drivers/msm to MSM subsystem
From: Nicolas Pitre @ 2011-02-24 23:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298585954-22422-2-git-send-email-kheitke@codeaurora.org>

On Thu, 24 Feb 2011, Kenneth Heitke wrote:

> Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>

Acked-by: Nicolas Pitre <nico@fluxnic.net>


> ---
>  MAINTAINERS |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6f99e12..e2ca70b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -889,6 +889,7 @@ M:	Daniel Walker <dwalker@fifo99.com>
>  M:	Bryan Huntsman <bryanh@codeaurora.org>
>  L:	linux-arm-msm at vger.kernel.org
>  F:	arch/arm/mach-msm/
> +F:	drivers/msm/
>  F:	drivers/video/msm/
>  F:	drivers/mmc/host/msm_sdcc.c
>  F:	drivers/mmc/host/msm_sdcc.h
> -- 
> 1.7.3.3
> 
> Sent by an employee of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

^ permalink raw reply

* [PATCH 1/2] lib: vsprintf: optimised put_dec() function
From: Michal Nazarewicz @ 2011-02-24 22:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224141818.7fd0207f.akpm@linux-foundation.org>

>> On Thu, 24 Feb 2011 22:52:42 +0100, Andrew Morton wrote:
>> > Also, the funky indenting to align on the "=" is atypical for kernel
>> > code and is inconsistent with the rest of vsprintf.c.  Just a single
>> > space, please.

> On Thu, 24 Feb 2011 23:10:09 +0100 "Michal Nazarewicz" wrote:
>> Want me to resubmit with spaces fixed?

On Thu, 24 Feb 2011 23:18:18 +0100, Andrew Morton wrote:
> nah, we'll live.
>
> I'd prefer that you find a workload where it actually matters :)

I'll try. :) Still have Contiguous Memory Allocator to work on. ;)
Thanks!

-- 
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=./ `o
..o | Computer Science,  Michal "mina86" Nazarewicz    (o o)
ooo +-----<email/xmpp: mnazarewicz@google.com>-----ooO--(_)--Ooo--

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Tony Lindgren @ 2011-02-24 22:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224203137.GH20560@atomide.com>

* Tony Lindgren <tony@atomide.com> [110224 12:29]:
> * Guzman Lugo, Fernando <fernando.lugo@ti.com> [110224 09:56]:
> > On Thu, Feb 24, 2011 at 5:29 AM, Felipe Balbi <balbi@ti.com> wrote:
> > > On Thu, Feb 24, 2011 at 01:26:05PM +0200, David Cohen wrote:
> > >> On Thu, Feb 24, 2011 at 10:35 AM, Felipe Balbi <balbi@ti.com> wrote:
> > >>
> > >> This patch is already acked. What about leave it as it is and discuss
> > >> multiple callbacks before release a new patch to support it?
> > >
> > > fine by me ;-)
> > 
> > Ok, maybe it was too late to change it, due to it is already acked, I
> > just wanted to avoid change isr here and then change it on other
> > patch. it is ok then.
> 
> Hiroshi any comments?
> 
> Would like to see a proper Acked-by before I apply, now there's
> just the earlier comment "Ok, I see. Let's go with this. Thanks." :)

Ah I see an ack in another mail. So applying these.

Tony

^ permalink raw reply

* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Kenneth Heitke @ 2011-02-24 22:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298585954-22422-1-git-send-email-kheitke@codeaurora.org>

SSBI is the Qualcomm single-wire serial bus interface used to connect
the MSM devices to the PMIC and other devices.

Since SSBI only supports a single slave, the driver gets the name of the
slave device passed in from the board file through the master device's
platform data.

SSBI registers pretty early (postcore), so that the PMIC can come up
before the board init. This is useful if the board init requires the
use of gpios that are connected through the PMIC.

Based on a patch by Dima Zavin <dima@android.com> that can be found at:
http://android.git.kernel.org/?p=kernel/msm.git;a=commitdiff;h=eb060bac4

This patch adds PMIC Arbiter support for the MSM8660. The PMIC Arbiter
is a hardware wrapper around the SSBI 2.0 controller that is designed to
overcome concurrency issues and security limitations.  A controller_type
field is added to the platform data to specify the type of the SSBI
controller (1.0, 2.0, or PMIC Arbiter).

Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
---
 drivers/Kconfig          |    2 +
 drivers/Makefile         |    1 +
 drivers/msm/Kconfig      |   13 ++
 drivers/msm/Makefile     |    4 +
 drivers/msm/ssbi.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/msm_ssbi.h |   49 ++++++
 6 files changed, 445 insertions(+), 0 deletions(-)
 create mode 100644 drivers/msm/Kconfig
 create mode 100644 drivers/msm/Makefile
 create mode 100644 drivers/msm/ssbi.c
 create mode 100644 include/linux/msm_ssbi.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9bfb71f..fceeb20 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -117,4 +117,6 @@ source "drivers/staging/Kconfig"
 source "drivers/platform/Kconfig"
 
 source "drivers/clk/Kconfig"
+
+source "drivers/msm/Kconfig"
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index b423bb1..14cb94b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -117,3 +117,4 @@ obj-y				+= platform/
 obj-y				+= ieee802154/
 #common clk code
 obj-y				+= clk/
+obj-y				+= msm/
diff --git a/drivers/msm/Kconfig b/drivers/msm/Kconfig
new file mode 100644
index 0000000..413bb65
--- /dev/null
+++ b/drivers/msm/Kconfig
@@ -0,0 +1,13 @@
+menu "Qualcomm MSM specific device drivers"
+	depends on ARCH_MSM
+
+config MSM_SSBI
+	bool "Qualcomm Single-wire Serial Bus Interface (SSBI)"
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in SSBI interface on Qualcomm MSM family processors.
+
+	  This is required for communicating with Qualcomm PMICs and
+	  other devices that have the SSBI interface.
+
+endmenu
diff --git a/drivers/msm/Makefile b/drivers/msm/Makefile
new file mode 100644
index 0000000..ea8c1e4
--- /dev/null
+++ b/drivers/msm/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for the MSM specific device drivers.
+#
+obj-$(CONFIG_MSM_SSBI) += ssbi.o
diff --git a/drivers/msm/ssbi.c b/drivers/msm/ssbi.c
new file mode 100644
index 0000000..1fae443
--- /dev/null
+++ b/drivers/msm/ssbi.c
@@ -0,0 +1,376 @@
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, Google Inc.
+ *
+ * Original authors: Code Aurura Forum
+ *
+ * Author: Dima Zavin <dima@android.com>
+ *  - Largely rewritten from original to not be an i2c driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/msm_ssbi.h>
+
+/* SSBI 2.0 controller registers */
+#define SSBI2_CMD			0x0008
+#define SSBI2_RD			0x0010
+#define SSBI2_STATUS			0x0014
+#define SSBI2_MODE2			0x001C
+
+/* SSBI_CMD fields */
+#define SSBI_CMD_RDWRN			(1 << 24)
+
+/* SSBI_STATUS fields */
+#define SSBI_STATUS_RD_READY		(1 << 2)
+#define SSBI_STATUS_READY		(1 << 1)
+#define SSBI_STATUS_MCHN_BUSY		(1 << 0)
+
+/* SSBI_MODE2 fields */
+#define SSBI_MODE2_REG_ADDR_15_8_SHFT	0x04
+#define SSBI_MODE2_REG_ADDR_15_8_MASK	(0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
+
+#define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
+	(((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
+	SSBI_MODE2_REG_ADDR_15_8_MASK))
+
+/* SSBI PMIC Arbiter command registers */
+#define SSBI_PA_CMD			0x0000
+#define SSBI_PA_RD_STATUS		0x0004
+
+/* SSBI_PA_CMD fields */
+#define SSBI_PA_CMD_RDWRN		(1 << 24)
+
+/* SSBI_PA_RD_STATUS fields */
+#define SSBI_PA_RD_STATUS_TRANS_DONE	(1 << 27)
+#define SSBI_PA_RD_STATUS_TRANS_DENIED	(1 << 26)
+
+#define SSBI_TIMEOUT_US			100
+
+struct msm_ssbi {
+	struct device		*dev;
+	struct device		*slave;
+	void __iomem		*base;
+	spinlock_t		lock;
+	enum msm_ssbi_controller_type controller_type;
+	int (*read)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
+	int (*write)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
+};
+
+#define to_msm_ssbi(dev)	platform_get_drvdata(to_platform_device(dev))
+
+static inline u32 ssbi_readl(struct msm_ssbi *ssbi, u32 reg)
+{
+	return readl(ssbi->base + reg);
+}
+
+static inline void ssbi_writel(struct msm_ssbi *ssbi, u32 val, u32 reg)
+{
+	writel(val, ssbi->base + reg);
+}
+
+static int ssbi_wait_mask(struct msm_ssbi *ssbi, u32 set_mask, u32 clr_mask)
+{
+	u32 timeout = SSBI_TIMEOUT_US;
+	u32 val;
+
+	while (timeout--) {
+		val = ssbi_readl(ssbi, SSBI2_STATUS);
+		if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
+			return 0;
+		udelay(1);
+	}
+
+	dev_err(ssbi->dev, "%s: timeout (status %x set_mask %x clr_mask %x)\n",
+		__func__, ssbi_readl(ssbi, SSBI2_STATUS), set_mask, clr_mask);
+	return -ETIMEDOUT;
+}
+
+static int
+msm_ssbi_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
+	int ret = 0;
+
+	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
+		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
+		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
+		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
+	}
+
+	while (len) {
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
+		if (ret)
+			goto err;
+
+		ssbi_writel(ssbi, cmd, SSBI2_CMD);
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
+		if (ret)
+			goto err;
+		*buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+static int
+msm_ssbi_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	int ret = 0;
+
+	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
+		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
+		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
+		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
+	}
+
+	while (len) {
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
+		if (ret)
+			goto err;
+
+		ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
+		ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+static inline int
+msm_ssbi_pa_transfer(struct msm_ssbi *ssbi, u32 cmd, u8 *data)
+{
+	u32 timeout = SSBI_TIMEOUT_US;
+	u32 rd_status = 0;
+
+	ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
+
+	while (timeout--) {
+		rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
+
+		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED) {
+			dev_err(ssbi->dev, "%s: transaction denied (0x%x)\n",
+					__func__, rd_status);
+			return -EPERM;
+		}
+
+		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
+			if (data)
+				*data = rd_status & 0xff;
+			return 0;
+		}
+		udelay(1);
+	}
+
+	dev_err(ssbi->dev, "%s: timeout, status 0x%x\n", __func__, rd_status);
+	return -ETIMEDOUT;
+}
+
+static int
+msm_ssbi_pa_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd;
+	int ret = 0;
+
+	cmd = SSBI_PA_CMD_RDWRN | (addr & 0x3fff) << 8;
+
+	while (len) {
+		ret = msm_ssbi_pa_transfer(ssbi, cmd, buf);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+static int
+msm_ssbi_pa_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd;
+	int ret = 0;
+
+	while (len) {
+		cmd = (addr & 0x3fff) << 8 | *buf;
+		ret = msm_ssbi_pa_transfer(ssbi, cmd, NULL);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+int msm_ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	struct msm_ssbi *ssbi = to_msm_ssbi(dev);
+	unsigned long flags;
+	int ret;
+
+	BUG_ON(ssbi->dev != dev);
+
+	spin_lock_irqsave(&ssbi->lock, flags);
+	ret = ssbi->read(ssbi, addr, buf, len);
+	spin_unlock_irqrestore(&ssbi->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_ssbi_read);
+
+int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	struct msm_ssbi *ssbi = to_msm_ssbi(dev);
+	unsigned long flags;
+	int ret;
+
+	BUG_ON(ssbi->dev != dev);
+
+	spin_lock_irqsave(&ssbi->lock, flags);
+	ret = ssbi->write(ssbi, addr, buf, len);
+	spin_unlock_irqrestore(&ssbi->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_ssbi_write);
+
+static int __devinit msm_ssbi_add_slave(struct msm_ssbi *ssbi,
+				     const struct msm_ssbi_slave_info *slave)
+{
+	struct platform_device *slave_pdev;
+	int ret;
+
+	if (ssbi->slave) {
+		pr_err("%s: slave already attached??\n", __func__);
+		return -EBUSY;
+	}
+
+	slave_pdev = platform_device_alloc(slave->name, -1);
+	if (!slave_pdev) {
+		pr_err("%s: cannot allocate pdev for slave '%s'", __func__,
+		       slave->name);
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	slave_pdev->dev.parent = ssbi->dev;
+	slave_pdev->dev.platform_data = slave->platform_data;
+
+	ret = platform_device_add(slave_pdev);
+	if (ret) {
+		pr_err("%s: cannot add slave platform device for '%s'\n",
+		       __func__, slave->name);
+		goto err;
+	}
+
+	ssbi->slave = &slave_pdev->dev;
+	return 0;
+
+err:
+	if (slave_pdev)
+		platform_device_put(slave_pdev);
+	return ret;
+}
+
+static int __devinit msm_ssbi_probe(struct platform_device *pdev)
+{
+	const struct msm_ssbi_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *mem_res;
+	struct msm_ssbi *ssbi;
+	int ret = 0;
+
+	printk(KERN_INFO "%s: %s\n", __func__, pdata->slave.name);
+
+	if (!pdata) {
+		pr_err("%s: missing platform data\n", __func__);
+		return -EINVAL;
+	}
+
+	ssbi = kzalloc(sizeof(struct msm_ssbi), GFP_KERNEL);
+	if (!ssbi) {
+		pr_err("%s: cannot allocate ssbi_data\n", __func__);
+		return -ENOMEM;
+	}
+
+	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem_res) {
+		pr_err("%s: missing mem resource\n", __func__);
+		ret = -EINVAL;
+		goto err_get_mem_res;
+	}
+
+	ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
+	if (!ssbi->base) {
+		pr_err("%s: ioremap of 0x%p failed\n", __func__,
+		       (void *)mem_res->start);
+		ret = -EINVAL;
+		goto err_ioremap;
+	}
+	ssbi->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ssbi);
+
+	ssbi->controller_type = pdata->controller_type;
+	if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
+		ssbi->read = msm_ssbi_pa_read_bytes;
+		ssbi->write = msm_ssbi_pa_write_bytes;
+	} else {
+		ssbi->read = msm_ssbi_read_bytes;
+		ssbi->write = msm_ssbi_write_bytes;
+	}
+
+	spin_lock_init(&ssbi->lock);
+
+	ret = msm_ssbi_add_slave(ssbi, &pdata->slave);
+	if (ret)
+		goto err_ssbi_add_slave;
+
+	return 0;
+
+err_ssbi_add_slave:
+	platform_set_drvdata(pdev, NULL);
+	iounmap(ssbi->base);
+err_ioremap:
+err_get_mem_res:
+	kfree(ssbi);
+	return ret;
+}
+
+static struct platform_driver msm_ssbi_driver = {
+	.probe		= msm_ssbi_probe,
+	.driver		= {
+		.name	= "msm_ssbi",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init msm_ssbi_init(void)
+{
+	return platform_driver_register(&msm_ssbi_driver);
+}
+postcore_initcall(msm_ssbi_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:msm_ssbi");
+MODULE_AUTHOR("Dima Zavin <dima@android.com>");
diff --git a/include/linux/msm_ssbi.h b/include/linux/msm_ssbi.h
new file mode 100644
index 0000000..cfa47df
--- /dev/null
+++ b/include/linux/msm_ssbi.h
@@ -0,0 +1,49 @@
+/* Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Author: Dima Zavin <dima@android.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_MSM_SSBI_H
+#define _LINUX_MSM_SSBI_H
+
+#include <linux/types.h>
+
+struct msm_ssbi_slave_info {
+	const char	*name;
+	void		*platform_data;
+};
+
+enum msm_ssbi_controller_type {
+	MSM_SBI_CTRL_SSBI = 0,
+	MSM_SBI_CTRL_SSBI2,
+	MSM_SBI_CTRL_PMIC_ARBITER,
+};
+
+struct msm_ssbi_platform_data {
+	struct msm_ssbi_slave_info	slave;
+	enum msm_ssbi_controller_type controller_type;
+};
+
+#ifdef CONFIG_MSM_SSBI
+int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len);
+int msm_ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
+#else
+static inline int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	return -ENXIO;
+}
+static inline int msm_ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	return -ENXIO;
+}
+#endif
+#endif
-- 
1.7.3.3

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

^ permalink raw reply related

* [PATCH v2 1/2] MAINTAINERS: Add drivers/msm to MSM subsystem
From: Kenneth Heitke @ 2011-02-24 22:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298585954-22422-1-git-send-email-kheitke@codeaurora.org>

Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
---
 MAINTAINERS |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6f99e12..e2ca70b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -889,6 +889,7 @@ M:	Daniel Walker <dwalker@fifo99.com>
 M:	Bryan Huntsman <bryanh@codeaurora.org>
 L:	linux-arm-msm at vger.kernel.org
 F:	arch/arm/mach-msm/
+F:	drivers/msm/
 F:	drivers/video/msm/
 F:	drivers/mmc/host/msm_sdcc.c
 F:	drivers/mmc/host/msm_sdcc.h
-- 
1.7.3.3

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

^ permalink raw reply related

* [PATCH v2 0/2] msm: add single-wire serial bus interface (SSBI) driver
From: Kenneth Heitke @ 2011-02-24 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

These patches replace the previous patch by moving the SSBI driver from
the arch/arm/mach-msm directory to drivers/msm.

The MAINTAINERS file is being updated to add the appropriate maintainer
for drivers/msm.

Kenneth Heitke (2):
  MAINTAINERS: Add drivers/msm to MSM subsystem
  msm: add single-wire serial bus interface (SSBI) driver

 MAINTAINERS              |    1 +
 drivers/Kconfig          |    2 +
 drivers/Makefile         |    1 +
 drivers/msm/Kconfig      |   13 ++
 drivers/msm/Makefile     |    4 +
 drivers/msm/ssbi.c       |  376 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/msm_ssbi.h |   49 ++++++
 7 files changed, 446 insertions(+), 0 deletions(-)
 create mode 100644 drivers/msm/Kconfig
 create mode 100644 drivers/msm/Makefile
 create mode 100644 drivers/msm/ssbi.c
 create mode 100644 include/linux/msm_ssbi.h

-- 
1.7.3.3

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

^ permalink raw reply

* [PATCH 1/2] lib: vsprintf: optimised put_dec() function
From: Andrew Morton @ 2011-02-24 22:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <op.vrfg66mgvgw7ix@mnazarewicz-glaptop>

On Thu, 24 Feb 2011 23:10:09 +0100
"Michal Nazarewicz" <mnazarewicz@google.com> wrote:

> On Thu, 24 Feb 2011 22:52:42 +0100, Andrew Morton wrote:
> > Also, the funky indenting to align on the "=" is atypical for kernel
> > code and is inconsistent with the rest of vsprintf.c.  Just a single
> > space, please.
> 
> Want me to resubmit with spaces fixed?

nah, we'll live.

I'd prefer that you find a workload where it actually matters :)

^ permalink raw reply

* [PATCH] MAINTAINERS: Update MSM maintainers
From: Linus Torvalds @ 2011-02-24 22:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D66CDD4.7080103@codeaurora.org>

On Thu, Feb 24, 2011 at 1:29 PM, Bryan Huntsman <bryanh@codeaurora.org> wrote:
>
>        ?Please let the MSM developers take full
> responsibility for the MSM architecture. ?That is, after all, what the
> community typically asks from SOC vendors.

Actually, "the community" (not that there really is any such cohesive
thing) generally asks that vendors be "involved". Not that vendors be
"exclusively in control". There's a big difference.

So what I personally find distasteful is how there's apparently some
entity that argues that _others_ should be removed from the
maintainership. Why would that be the case? This kind of exclusivity
argument is bad. Maintainers can step down, but having others remove
maintainership seems dubious at best.

So get your politics sorted out, guys.

                               Linus

^ permalink raw reply

* [PATCH 1/2] lib: vsprintf: optimised put_dec() function
From: Michal Nazarewicz @ 2011-02-24 22:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224135101.9205d91e.akpm@linux-foundation.org>

On Thu, 24 Feb 2011 22:51:01 +0100, Andrew Morton wrote:

>> Cc: linux-arm at lists.arm.linux.org.uk, Michal Nazarewicz  
>> <mina86@mina86.com>, "Douglas W. Jones" <jones@cs.uiowa.edu>, Denis  
>> Vlasenko <vda.linux@googlemail.com
>
> linux-arm-kernel is for arm patches.  linux-kernel at vger.kernel.org
> would be an appropriate cc for patches against lib/vsprintf.c.

Yes, I realised I forgot about LKML just after I submitted the patch.
I included ARM because of the benchmark I did on ARM I mentioned.

> On Tue, 22 Feb 2011 15:26:26 +0100 Michal Nazarewicz wrote:
>> The put_dec() and family of functions were based on a code
>> optimised for processors with 8-bit ALU but since we don't
>> need to limit ourselves to such small ALUs, the code was
>> optimised and used capacities of an 16-bit ALU anyway.
[...]

> I don't think this was worth optimising!  If any kernel workload is
> calling sprintf("%d") with any frequency then something surely is
> busted.

>>  lib/vsprintf.c |  269  
>> ++++++++++++++++++++++++++++++++++++++------------------
>>  1 files changed, 185 insertions(+), 84 deletions(-)

> Despite the code bloat, the patch somehow reduces the vsprintf.o
> footprint by 150 bytes (1%).
>
> I'm not really sure that we should apply this.  But given that the
> existing code is an incomprehensible over-optimised mess I guess this
> patch doesn't make things much worse.
>
> However I think that a better approach would be to rip out the existing
> stuff and go for some small, simple and slow thing.  Reduce the kernel
> footprint and increase understandability and hence maintainability.
>
> Unless I'm all wrong and you're aware of a workload which calls these
> things with any frequency?

Oh, no, I just felt like hacking this piece of code one evening. ;)
I don't have any strong feelings about this patch so feel free to
ignore it.  I just wanted decision to include it or not to include
it be made by someone with experience rather than be a consequence
of me forgetting about this patch.


>> +	r      = (q * (uint64_t)0xcccd) >> 19;
>> +	*buf++ = (q - 10 * r) + '0';

On Thu, 24 Feb 2011 22:52:42 +0100, Andrew Morton wrote:
> Also, the funky indenting to align on the "=" is atypical for kernel
> code and is inconsistent with the rest of vsprintf.c.  Just a single
> space, please.

Want me to resubmit with spaces fixed?

-- 
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=./ `o
..o | Computer Science,  Michal "mina86" Nazarewicz    (o o)
ooo +-----<email/xmpp: mnazarewicz@google.com>-----ooO--(_)--Ooo--

^ permalink raw reply

* [PATCH] i.MX51 & i.MX53: move registration of gpios to plat-mxc/gpio.c
From: Eric Bénard @ 2011-02-24 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Eric B?nard <eric@eukrea.com>
---
 arch/arm/mach-mx5/devices.c |   63 -------------------------------------------
 arch/arm/mach-mx5/mm.c      |   39 +++++++++++++++-----------
 arch/arm/plat-mxc/gpio.c    |   27 ++++++++++++++++++
 3 files changed, 49 insertions(+), 80 deletions(-)

diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 153ada5..8951312 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -119,66 +119,3 @@ struct platform_device mxc_usbh2_device = {
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 };
-
-static struct mxc_gpio_port mxc_gpio_ports[] = {
-	{
-		.chip.label = "gpio-0",
-		.base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO1_LOW,
-		.irq_high = MX51_MXC_INT_GPIO1_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START
-	},
-	{
-		.chip.label = "gpio-1",
-		.base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO2_LOW,
-		.irq_high = MX51_MXC_INT_GPIO2_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
-	},
-	{
-		.chip.label = "gpio-2",
-		.base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO3_LOW,
-		.irq_high = MX51_MXC_INT_GPIO3_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
-	},
-	{
-		.chip.label = "gpio-3",
-		.base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
-		.irq = MX51_MXC_INT_GPIO4_LOW,
-		.irq_high = MX51_MXC_INT_GPIO4_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
-	},
-	{
-		.chip.label = "gpio-4",
-		.base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
-		.irq = MX53_INT_GPIO5_LOW,
-		.irq_high = MX53_INT_GPIO5_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
-	},
-	{
-		.chip.label = "gpio-5",
-		.base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
-		.irq = MX53_INT_GPIO6_LOW,
-		.irq_high = MX53_INT_GPIO6_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
-	},
-	{
-		.chip.label = "gpio-6",
-		.base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
-		.irq = MX53_INT_GPIO7_LOW,
-		.irq_high = MX53_INT_GPIO7_HIGH,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
-	},
-};
-
-int __init imx51_register_gpios(void)
-{
-	return mxc_gpio_init(mxc_gpio_ports, 4);
-}
-
-int __init imx53_register_gpios(void)
-{
-	return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
-}
-
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index 457f9f9..c6d6787 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -20,6 +20,7 @@
 #include <mach/common.h>
 #include <mach/iomux-v3.h>
 
+#if defined(CONFIG_SOC_IMX51)
 /*
  * Define the MX51 memory map.
  */
@@ -32,15 +33,6 @@ static struct map_desc mx51_io_desc[] __initdata = {
 };
 
 /*
- * Define the MX53 memory map.
- */
-static struct map_desc mx53_io_desc[] __initdata = {
-	imx_map_entry(MX53, AIPS1, MT_DEVICE),
-	imx_map_entry(MX53, SPBA0, MT_DEVICE),
-	imx_map_entry(MX53, AIPS2, MT_DEVICE),
-};
-
-/*
  * This function initializes the memory map. It is called during the
  * system startup to create static physical to virtual memory mappings
  * for the IO modules.
@@ -53,14 +45,6 @@ void __init mx51_map_io(void)
 	iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc));
 }
 
-void __init mx53_map_io(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MX53);
-	mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG_BASE_ADDR));
-	iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc));
-}
-
 int imx51_register_gpios(void);
 
 void __init mx51_init_irq(void)
@@ -80,6 +64,26 @@ void __init mx51_init_irq(void)
 	tzic_init_irq(tzic_virt);
 	imx51_register_gpios();
 }
+#endif /* if defined(CONFIG_SOC_IMX51) */
+
+#if defined(CONFIG_SOC_IMX53)
+
+/*
+ * Define the MX53 memory map.
+ */
+static struct map_desc mx53_io_desc[] __initdata = {
+	imx_map_entry(MX53, AIPS1, MT_DEVICE),
+	imx_map_entry(MX53, SPBA0, MT_DEVICE),
+	imx_map_entry(MX53, AIPS2, MT_DEVICE),
+};
+
+void __init mx53_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX53);
+	mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG_BASE_ADDR));
+	iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc));
+}
 
 int imx53_register_gpios(void);
 
@@ -97,3 +101,4 @@ void __init mx53_init_irq(void)
 	tzic_init_irq(tzic_virt);
 	imx53_register_gpios();
 }
+#endif /* if defined(CONFIG_SOC_IMX53) */
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index d17b3c9..b204b45 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -459,3 +459,30 @@ static struct mxc_gpio_port imx50_gpio_ports[] = {
 DEFINE_REGISTER_FUNCTION(imx50)
 
 #endif /* if defined(CONFIG_SOC_IMX50) */
+
+#if defined(CONFIG_SOC_IMX51)
+static struct mxc_gpio_port imx51_gpio_ports[] = {
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 0, 1, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 1, 2, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 2, 3, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 3, 4, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH),
+};
+
+DEFINE_REGISTER_FUNCTION(imx51)
+
+#endif /* if defined(CONFIG_SOC_IMX51) */
+
+#if defined(CONFIG_SOC_IMX53)
+static struct mxc_gpio_port imx53_gpio_ports[] = {
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 0, 1, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 1, 2, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 2, 3, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 3, 4, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 4, 5, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 5, 6, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH),
+	DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX51, 6, 7, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH),
+};
+
+DEFINE_REGISTER_FUNCTION(imx53)
+
+#endif /* if defined(CONFIG_SOC_IMX53) */
-- 
1.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox