Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: zynq: Allow UART1 to be used as DEBUG_LL console.
From: Nick Bowler @ 2012-10-29 18:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121029165621.GF5190@beefymiracle.amer.corp.natinst.com>

On 2012-10-29 10:56 -0600, Josh Cartwright wrote:
> On Thu, Oct 25, 2012 at 06:47:34PM -0400, Nick Bowler wrote:
> > The main UART on the Xilinx ZC702 board is UART1, located at address
> > e0001000.  Add a Kconfig option to select this device as the low-level
> > debugging port.  This allows the really early boot printouts to reach
> > the USB serial adaptor on this board.
> > 
> > For consistency's sake, add a choice entry for UART0 even though it is
> > the the default if UART1 is not selected.
> > 
> > As there are currently known issues related to the UART virtual
> > mappings, this is KNOWN BROKEN, not to be merged yet!
> > 
> > Not-Yet-Signed-off-by: Nick Bowler <nbowler@elliptictech.com>
> 
> Tested-by: Josh Cartwright <josh.cartwright@ni.com>
> 
> Now that v5 of the initial zynq cleanup patchset is queued up for
> merging (with a workaround for the uart mapping problem), what would it
> take for you to sign off on this patch?

Great, I've tested this on top of the other 4 and the boot console is
working now.  I will resend the patch with my signoff.

(I wonder if UART0 has similar address problems on the ZC702 if it is
selected as the boot console... but this is harder to test as AFAIK it's
not connected to anything on this board by default, but it could in
principle be connected to something in the PL.  We can cross that bridge
if and when we get to it, I guess).

> There is some trivial merging that has to be done to get it to apply
> cleanly on v5.  See a rebased version below.

Yup, looks good.

Cheers,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

^ permalink raw reply

* [PATCH 0/3] Minor fixes for generic clock framework
From: Stephen Boyd @ 2012-10-29 18:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349332735-20096-1-git-send-email-sboyd@codeaurora.org>

On 10/03/12 23:38, Stephen Boyd wrote:
> This is a small set of patches that fixes some documentation
> and fixes return values of functions that aren't used that
> much yet. Noticed while going through this code.
>

Mike, any comments on these patches?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [PATCH] clk: fix return value check in of_fixed_clk_setup()
From: Mike Turquette @ 2012-10-29 17:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPgLHd-BtGhVBHYGW1UFT9wqmnPqmuf9AWkQk6mXG7xSzWqOOA@mail.gmail.com>

Quoting Wei Yongjun (2012-09-20 23:35:18)
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> 
> In case of error, the function clk_register_fixed_rate() returns
> ERR_PTR() not NULL pointer. The NULL test in the return value
> check should be replaced with IS_ERR().
> 
> dpatch engine is used to auto generated this patch.
> (https://github.com/weiyj/dpatch)
> 
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Taken into clk-next.

Thanks,
Mike

> ---
>  drivers/clk/clk-fixed-rate.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
> index f5ec0ee..af78ed6 100644
> --- a/drivers/clk/clk-fixed-rate.c
> +++ b/drivers/clk/clk-fixed-rate.c
> @@ -97,7 +97,7 @@ void __init of_fixed_clk_setup(struct device_node *node)
>         of_property_read_string(node, "clock-output-names", &clk_name);
>  
>         clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
> -       if (clk)
> +       if (!IS_ERR(clk))
>                 of_clk_add_provider(node, of_clk_src_simple_get, clk);
>  }
>  EXPORT_SYMBOL_GPL(of_fixed_clk_setup);

^ permalink raw reply

* [PATCH 2/2] ARM: tegra: T30 speedo-based identification
From: Stephen Warren @ 2012-10-29 17:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351495315-3282-3-git-send-email-dahuang@nvidia.com>

On 10/29/2012 01:21 AM, Danny Huang wrote:
> This patch adds speedo-based identification support for T30.

> diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c

> -#define FUSE_SPARE_BIT		0x200
> +
> +#define TEGRA20_FUSE_SPARE_BIT		0x200
> +#define TEGRA30_FUSE_SPARE_BIT		0x244
> +
> +static int tegra_fuse_spare_bit;

Can all the spare bit rework, and also prototype changes for
tegra_fuse_readl() and tegra_spare_fuse() be pulled out into a separate
patch at the start of the series?

> +int tegra_cpu_speedo_id;

Does Tegra20 not have a separate cpu_speedo_id? Should this variable be
added in patch 1 and appropriately initialized for Tegra20? If it's
Tegra30-specific, or Tegra30-and-later, a comment to that effect would
be useful. Is there a way to ensure that Tegra20-specific code doesn't
use that variable if it's not applicable?

> @@ -107,9 +112,18 @@ void tegra_init_fuse(void)
>  	id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
>  	tegra_chip_id = (id >> 8) & 0xff;
>  
> -	tegra_revision = tegra_get_revision(id);
> -
> -	tegra20_init_speedo_data();
> +	switch (tegra_chip_id) {
> +	case TEGRA20:
> +		tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
> +		tegra_revision = tegra_get_revision(id);
> +		tegra20_init_speedo_data();
> +		break;
> +	case TEGRA30:
> +		tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
> +		tegra_revision = tegra_get_revision(id);
> +		tegra30_init_speedo_data();
> +		break;
> +	}

I think there, I'd prefer to see:


switch (tegra_chip_id) {
case TEGRA20:
	tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
	break;
case TEGRA30:
	tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
	break;
}

tegra_revision = tegra_get_revision(id);

switch (tegra_chip_id) {
case TEGRA20:
	tegra20_init_speedo_data();
	break;
case TEGRA30:
	tegra30_init_speedo_data();
	break;
}

... to avoid duplicating the tegra_get_revision() call.

If this ends up needing a lot of separate switch statements in sequence,
you can always put the SoC-specific data into a struct, and do:

struct tegra_fuse_soc_data *sd = ...;
sd->set_spare_fuse_bit();
tegra_revision = tegra_get_revision(id);
sd->init_speedo_data();

although I don't think the complexity requires that yet.

> diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c

(similar comments apply here as for the table/array size checking in
patch 1)

> +static int threshold_index;
> +static int package_id;

Do those need to be globals? Can they simply be passed between the
appropriate functions?

> +static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)

> +	WARN_ON(!speedo_g || !speedo_lp);

That hardly seems worth checking since this function is called from one
specific place later in this file...

> +static void rev_sku_to_speedo_ids(int rev, int sku)
> +{
> +	switch (rev) {
> +	case TEGRA_REVISION_A01:
> +		tegra_cpu_speedo_id = 0;
> +		tegra_soc_speedo_id = 0;
> +		threshold_index = 0;
> +		break;
> +	case TEGRA_REVISION_A02:
> +	case TEGRA_REVISION_A03:
> +		switch (sku) {
> +		case 0x87:
...
> +			default:
> +				pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
> +				       package_id);
> +				BUG();
> +				break;
> +			}
> +			break;

Why BUG() there, but not:

> +		default:
> +			pr_err("Tegra3: Unknown SKU %d\n", sku);
> +			tegra_cpu_speedo_id = 0;
> +			tegra_soc_speedo_id = 0;
> +			threshold_index = 0;
> +			break;
> +		}
> +		break;
> +	default:

... but do here:

> +		BUG();
> +		break;
> +	}
> +}

> +void tegra30_init_speedo_data(void)

> +	for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
> +		if (cpu_speedo_val <
> +		    cpu_process_speedos[threshold_index][i]) {
> +			break;
> +		}
> +	}
> +	tegra_cpu_process_id = i - 1;
> +
> +	if (tegra_cpu_process_id == -1) {
> +		pr_err("****************************************************");
> +		pr_err("****************************************************");
> +		pr_err("* tegra3_speedo: CPU speedo value %3d out of range *",
> +		       cpu_speedo_val);
> +		pr_err("****************************************************");
> +		pr_err("****************************************************");

Just drop the lines of ***, and the * around the text in the middle
pr_err() too.

> +
> +		tegra_cpu_speedo_id = 1;

Shouldn't that fix the out-of-range tegra_cpu_process_id value?

This and the previous comment apply to the following calculation of
tegra_core_process_id too.

^ permalink raw reply

* [PATCH 1/2] ARM: OMAP2+: move mailbox.h out of plat-omap headers
From: Tony Lindgren @ 2012-10-29 17:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351530381-11459-2-git-send-email-omar.luna@linaro.org>

Hi,

> --- /dev/null
> +++ b/include/linux/platform_data/omap_mailbox.h
> @@ -0,0 +1,105 @@

This file should only contain pure platform data needed
by the core omap code to pass to the mailbox driver.

The mailbox API header should be somewhere else,
like include/linux/mailbox/mailbox-omap.h or similar.

But shouldn't this all now be handled by using the
remoteproc framework?

Regards,

Tony

^ permalink raw reply

* [PATCH v2 05/13] clk: Versatile Express clock generators ("osc") driver
From: Mike Turquette @ 2012-10-29 17:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1347977875-16855-6-git-send-email-pawel.moll@arm.com>

Quoting Pawel Moll (2012-09-18 07:17:47)
> This driver provides a common clock framework hardware driver
> for Versatile Express clock generators (a.k.a "osc") controlled
> via the config bus.
> 
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> ---
>  drivers/clk/versatile/Makefile           |    1 +
>  drivers/clk/versatile/clk-vexpress-osc.c |  146 ++++++++++++++++++++++++++++++
>  2 files changed, 147 insertions(+)
>  create mode 100644 drivers/clk/versatile/clk-vexpress-osc.c
> 
> Hi Mike,
> 
> As agreed - this patch and the next one ("clk: Common clocks
> implementation for Versatile Express") are all yours.
> 

Taken into clk-next.

Thanks,
Mike

> Regards
> 
> Pawel
> 
> diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
> index c0a0f64..1e49a7a 100644
> --- a/drivers/clk/versatile/Makefile
> +++ b/drivers/clk/versatile/Makefile
> @@ -2,3 +2,4 @@
>  obj-$(CONFIG_ICST)             += clk-icst.o
>  obj-$(CONFIG_ARCH_INTEGRATOR)  += clk-integrator.o
>  obj-$(CONFIG_ARCH_REALVIEW)    += clk-realview.o
> +obj-$(CONFIG_VEXPRESS_CONFIG)  += clk-vexpress-osc.o
> diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
> new file mode 100644
> index 0000000..dcb6ae0
> --- /dev/null
> +++ b/drivers/clk/versatile/clk-vexpress-osc.c
> @@ -0,0 +1,146 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License 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.
> + *
> + * Copyright (C) 2012 ARM Limited
> + */
> +
> +#define pr_fmt(fmt) "vexpress-osc: " fmt
> +
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/vexpress.h>
> +
> +struct vexpress_osc {
> +       struct vexpress_config_func *func;
> +       struct clk_hw hw;
> +       unsigned long rate_min;
> +       unsigned long rate_max;
> +};
> +
> +#define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw)
> +
> +static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw,
> +               unsigned long parent_rate)
> +{
> +       struct vexpress_osc *osc = to_vexpress_osc(hw);
> +       u32 rate;
> +
> +       vexpress_config_read(osc->func, 0, &rate);
> +
> +       return rate;
> +}
> +
> +static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate,
> +               unsigned long *parent_rate)
> +{
> +       struct vexpress_osc *osc = to_vexpress_osc(hw);
> +
> +       if (WARN_ON(osc->rate_min && rate < osc->rate_min))
> +               rate = osc->rate_min;
> +
> +       if (WARN_ON(osc->rate_max && rate > osc->rate_max))
> +               rate = osc->rate_max;
> +
> +       return rate;
> +}
> +
> +static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate,
> +               unsigned long parent_rate)
> +{
> +       struct vexpress_osc *osc = to_vexpress_osc(hw);
> +
> +       return vexpress_config_write(osc->func, 0, rate);
> +}
> +
> +static struct clk_ops vexpress_osc_ops = {
> +       .recalc_rate = vexpress_osc_recalc_rate,
> +       .round_rate = vexpress_osc_round_rate,
> +       .set_rate = vexpress_osc_set_rate,
> +};
> +
> +
> +struct clk * __init vexpress_osc_setup(struct device *dev)
> +{
> +       struct clk_init_data init;
> +       struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL);
> +
> +       if (!osc)
> +               return NULL;
> +
> +       osc->func = vexpress_config_func_get_by_dev(dev);
> +       if (!osc->func) {
> +               kfree(osc);
> +               return NULL;
> +       }
> +
> +       init.name = dev_name(dev);
> +       init.ops = &vexpress_osc_ops;
> +       init.flags = CLK_IS_ROOT;
> +       init.num_parents = 0;
> +       osc->hw.init = &init;
> +
> +       return clk_register(NULL, &osc->hw);
> +}
> +
> +void __init vexpress_osc_of_setup(struct device_node *node)
> +{
> +       struct clk_init_data init;
> +       struct vexpress_osc *osc;
> +       struct clk *clk;
> +       u32 range[2];
> +
> +       osc = kzalloc(sizeof(*osc), GFP_KERNEL);
> +       if (!osc)
> +               goto error;
> +
> +       osc->func = vexpress_config_func_get_by_node(node);
> +       if (!osc->func) {
> +               pr_err("Failed to obtain config func for node '%s'!\n",
> +                               node->name);
> +               goto error;
> +       }
> +
> +       if (of_property_read_u32_array(node, "freq-range", range,
> +                       ARRAY_SIZE(range)) == 0) {
> +               osc->rate_min = range[0];
> +               osc->rate_max = range[1];
> +       }
> +
> +       of_property_read_string(node, "clock-output-names", &init.name);
> +       if (!init.name)
> +               init.name = node->name;
> +
> +       init.ops = &vexpress_osc_ops;
> +       init.flags = CLK_IS_ROOT;
> +       init.num_parents = 0;
> +
> +       osc->hw.init = &init;
> +
> +       clk = clk_register(NULL, &osc->hw);
> +       if (IS_ERR(clk)) {
> +               pr_err("Failed to register clock '%s'!\n", init.name);
> +               goto error;
> +       }
> +
> +       of_clk_add_provider(node, of_clk_src_simple_get, clk);
> +
> +       pr_debug("Registered clock '%s'\n", init.name);
> +
> +       return;
> +
> +error:
> +       if (osc->func)
> +               vexpress_config_func_put(osc->func);
> +       kfree(osc);
> +}
> -- 
> 1.7.9.5

^ permalink raw reply

* [PATCH 1/2] ARM: tegra: Add speedo-based process identification
From: Stephen Warren @ 2012-10-29 17:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351495315-3282-2-git-send-email-dahuang@nvidia.com>

On 10/29/2012 01:21 AM, Danny Huang wrote:
> Detect CPU and core process ID by checking speedo corner tables.
> This can provide a more accurate process ID.

> diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c

> @@ -114,6 +109,8 @@ void tegra_init_fuse(void)
>  
>  	tegra_revision = tegra_get_revision(id);
>  
> +	tegra20_init_speedo_data();

This code executes on both Tegra20 and Tegra30. Calling a
Tegra20-specific function unconditionally isn't correct. This is
important because if someone does "git bisect" across this patch, patch
1 might be applied, but patch 2 not.

I think you need to add the switch statement from patch 2 here rather
than later in patch 2. Also, I think you need to keep the following
chunk of code in the Tegra30 case, and only remove it completely in patch 2

-	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
-	tegra_cpu_process_id = (reg >> 6) & 3;
-
-	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
-	tegra_core_process_id = (reg >> 12) & 3;

> diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c

> +static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
> +	{315, 366, 420, UINT_MAX},
> +	{303, 368, 419, UINT_MAX},
> +	{316, 331, 383, UINT_MAX},
> +};
> +
> +static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
> +	{165, 195, 224, UINT_MAX},
> +	{165, 195, 224, UINT_MAX},
> +	{165, 195, 224, UINT_MAX},
> +};
> +
> +void tegra20_init_speedo_data(void)
> +{
> +	u32 reg;
> +	u32 val;
> +	int i;
> +
> +	if (SPEEDO_ID_SELECT_0(tegra_revision))
> +		tegra_soc_speedo_id = 0;
> +	else if (SPEEDO_ID_SELECT_1(tegra_sku_id))
> +		tegra_soc_speedo_id = 1;
> +	else
> +		tegra_soc_speedo_id = 2;
> +
> +	WARN_ON(tegra_soc_speedo_id >= ARRAY_SIZE(cpu_process_speedos));
> +	WARN_ON(tegra_soc_speedo_id >= ARRAY_SIZE(core_process_speedos));

Can this be a BUILD_BUG_ON() instead;

#define SPEEDO_ID_0 0
#define SPEEDO_ID_1 1
#define SPEEDO_ID_2 2
#define SPEEDO_ID_COUNT (SPEEDO_ID_2 + 1)
BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) == SPEEDO_ID_COUNT)
BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) == SPEEDO_ID_COUNT)

and use those #defines in the assignments to tegra_soc_speedod_id above,
rather than literals?

Or even just the following without the BUILD_BUG_ONs:

> static const u32 core_process_speedos[SPEEDO_ID_COUNT][PROCESS_CORNERS_NUM] = {

> +	val = 0;
> +	for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
> +		reg = tegra_spare_fuse(i) |
> +			tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS);
> +		val = (val << 1) | (reg & 0x1);

Out of curiosity, why did the prototype of tegra_spare_fuse() change
from returning a bool to an int, if only bit 0 is going to be used?

^ permalink raw reply

* [PATCH] CLK: clk-twl6040: Initial clock driver for OMAP4+ McPDM fclk clock
From: Mike Turquette @ 2012-10-29 17:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1347633027-20731-1-git-send-email-peter.ujfalusi@ti.com>

Quoting Peter Ujfalusi (2012-09-14 07:30:27)
> On OMAP4+ platforms the functional clock for the McPDM IP is suplied by
> the twl6040 codec (bit clock on the PDM bus).
> This common clock driver for twl6040 will register the mcpdm_fclk clock to
> be used by the McPDM driver to make sure that the needed clocks are
> available when needed.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> 
> Hello Mike,
> 
> This driver is going to be used by the OMAP McPDM driver when we moved to common
> clock framework.
> To avoid merge conflicts I'm going to send the patch needed for the twl6040 MFD
> core driver to register the platform device for the clk driver.
> 

Peter,

The patch looks good to me.  To be clear, you wan this to go through
clk-next or the mfd tree for avoiding conflicts?

Thanks,
Mike

> Some background: OMAP McPDM's functional clock is coming from external source,
> which is the bitclock of the McPDM interface generated by external codec
> (twl6040). This clock is needed to access McPDM registers as well and when I'm
> going to implement the power states of twl6040 we need to make sure that the
> clock is running from twl6040 to McPDM in order to avoid surprises.
> 
> Regards,
> Peter
> 
>  drivers/clk/Kconfig       |   8 +++
>  drivers/clk/Makefile      |   1 +
>  drivers/clk/clk-twl6040.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 135 insertions(+)
>  create mode 100644 drivers/clk/clk-twl6040.c
> 
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index bace9e9..3d0b784 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -53,4 +53,12 @@ config COMMON_CLK_MAX77686
>         ---help---
>           This driver supports Maxim 77686 crystal oscillator clock. 
>  
> +config CLK_TWL6040
> +       tristate "External McPDM functional clock from twl6040"
> +       depends on TWL6040_CORE
> +       ---help---
> +         Enable the external functional clock support on OMAP4+ platforms for
> +         McPDM. McPDM module is using the external bit clock on the McPDM bus
> +         as functional clock.
> +
>  endmenu
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 6327536..c55d840 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -20,3 +20,4 @@ obj-$(CONFIG_ARCH_U8500)      += ux500/
>  # Chip specific
>  obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
>  obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
> +obj-$(CONFIG_CLK_TWL6040)      += clk-twl6040.o
> diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
> new file mode 100644
> index 0000000..f4a3389
> --- /dev/null
> +++ b/drivers/clk/clk-twl6040.c
> @@ -0,0 +1,126 @@
> +/*
> +* TWL6040 clock module driver for OMAP4 McPDM functional clock
> +*
> +* Copyright (C) 2012 Texas Instruments Inc.
> +* Peter Ujfalusi <peter.ujfalusi@ti.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 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.
> +*
> +* You should have received a copy of the GNU General Public License
> +* along with this program; if not, write to the Free Software
> +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> +* 02110-1301 USA
> +*
> +*/
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/twl6040.h>
> +#include <linux/clk-provider.h>
> +
> +struct twl6040_clk {
> +       struct twl6040 *twl6040;
> +       struct device *dev;
> +       struct clk_hw mcpdm_fclk;
> +       struct clk *clk;
> +       int enabled;
> +};
> +
> +static int twl6040_bitclk_is_enabled(struct clk_hw *hw)
> +{
> +       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
> +                                                      mcpdm_fclk);
> +       return twl6040_clk->enabled;
> +}
> +
> +static int twl6040_bitclk_prepare(struct clk_hw *hw)
> +{
> +       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
> +                                                      mcpdm_fclk);
> +       int ret;
> +
> +       ret = twl6040_power(twl6040_clk->twl6040, 1);
> +       if (!ret)
> +               twl6040_clk->enabled = 1;
> +
> +       return ret;
> +}
> +
> +static void twl6040_bitclk_unprepare(struct clk_hw *hw)
> +{
> +       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
> +                                                      mcpdm_fclk);
> +       int ret;
> +
> +       ret = twl6040_power(twl6040_clk->twl6040, 0);
> +       if (!ret)
> +               twl6040_clk->enabled = 0;
> +}
> +
> +static const struct clk_ops twl6040_mcpdm_ops = {
> +       .is_enabled = twl6040_bitclk_is_enabled,
> +       .prepare = twl6040_bitclk_prepare,
> +       .unprepare = twl6040_bitclk_unprepare,
> +};
> +
> +static struct clk_init_data wm831x_clkout_init = {
> +       .name = "mcpdm_fclk",
> +       .ops = &twl6040_mcpdm_ops,
> +       .flags = CLK_IS_ROOT,
> +};
> +
> +static int __devinit twl6040_clk_probe(struct platform_device *pdev)
> +{
> +       struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent);
> +       struct twl6040_clk *clkdata;
> +
> +       clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
> +       if (!clkdata)
> +               return -ENOMEM;
> +
> +       clkdata->dev = &pdev->dev;
> +       clkdata->twl6040 = twl6040;
> +
> +       clkdata->mcpdm_fclk.init = &wm831x_clkout_init;
> +       clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk);
> +       if (!clkdata->clk)
> +               return -EINVAL;
> +
> +       dev_set_drvdata(&pdev->dev, clkdata);
> +
> +       return 0;
> +}
> +
> +static int __devexit twl6040_clk_remove(struct platform_device *pdev)
> +{
> +       struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev);
> +
> +       clk_unregister(clkdata->clk);
> +
> +       return 0;
> +}
> +
> +static struct platform_driver twl6040_clk_driver = {
> +       .driver = {
> +               .name = "twl6040-clk",
> +               .owner = THIS_MODULE,
> +       },
> +       .probe = twl6040_clk_probe,
> +       .remove = __devexit_p(twl6040_clk_remove),
> +};
> +
> +module_platform_driver(twl6040_clk_driver);
> +
> +MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock");
> +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
> +MODULE_ALIAS("platform:twl6040-clk");
> +MODULE_LICENSE("GPL");
> -- 
> 1.7.12

^ permalink raw reply

* [PATCH 2/4] ARM: EXYNOS: PL330 MDMA1 fix for revision 0 of Exynos4210 SOC
From: Kukjin Kim @ 2012-10-29 17:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351504796-24788-3-git-send-email-b.zolnierkie@samsung.com>

On 10/29/12 10:59, Bartlomiej Zolnierkiewicz wrote:
> Commit 8214513 ("ARM: EXYNOS: fix address for EXYNOS4 MDMA1")
> changed EXYNOS specific setup of PL330 DMA engine to use 'non-secure'
> mdma1 address instead of 'secure' one (from 0x12840000 to 0x12850000)
> to fix issue with some Exynos4212 SOCs.  Unfortunately it brakes
> PL330 setup for revision 0 of Exynos4210 SOC (mdma1 device cannot
> be found at 'non-secure' address):
>
> [    0.566245] dma-pl330 dma-pl330.2: PERIPH_ID 0x0, PCELL_ID 0x0 !
> [    0.566278] dma-pl330: probe of dma-pl330.2 failed with error -22
>
> Fix it by using 'secure' mdma1 address on Exynos4210 revision 0 SOC.
>
> Cc: Tomasz Figa<t.figa@samsung.com>
> Cc: Kukjin Kim<kgene.kim@samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz<b.zolnierkie@samsung.com>
> Signed-off-by: Kyungmin Park<kyungmin.park@samsung.com>
> ---
>   arch/arm/mach-exynos/dma.c              | 5 ++++-
>   arch/arm/mach-exynos/include/mach/map.h | 3 ++-
>   2 files changed, 6 insertions(+), 2 deletions(-)

[...]

> +		if (samsung_rev() == EXYNOS4210_REV_0)
> +			exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;

Hi Bart,

Hmm...above change and adding definition of EXYNOS_PA_S_MDMA1 address 
can fix the problem you commented on EXYNOS4210 Rev0 without others?...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH V2 1/2] ARM: tegra: dt: add L2 cache controller
From: Stephen Warren @ 2012-10-29 17:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351506345-32524-1-git-send-email-josephl@nvidia.com>

On 10/29/2012 04:25 AM, Joseph Lo wrote:
> Add L2 cache controller binding into DT for Tegra.

The series applied to Tegra's tree for 3.8. Thanks.

^ permalink raw reply

* tidspbridge: ARM common zImage?
From: Omar Ramirez Luna @ 2012-10-29 17:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 26 October 2012 13:00, Tony Lindgren <tony@atomide.com> wrote:
...
>> > I would also like to move the tidspbridge to the DMA API, but I think we'll
>> > need to move step by step there, and using the OMAP IOMMU and IOVMM APIs as an
>> > intermediate step would allow splitting patches in reviewable chunks. I know
>> > it's a step backwards in term of OMAP IOMMU usage, but that's in my opinion a
>> > temporary nuisance to make the leap easier.
>>
>> Since tidspbridge is in staging I guess it's not a problem, though it
>> sounds to me like using the correct API in the first place is going to
>> make less churn.
>
> Not related to these patches, but also sounds like we may need to drop
> some staging/tidspbridge code to be able to move forward with the
> ARM common zImage plans. See the "[GIT PULL] omap plat header removal
> for v3.8 merge window, part1" thread for more info.

I was trying to find some more info on this, but only found one patch
for tidspbridge to delete an include... it seems that I must try with
these patches and see what explodes since we heavily abuse prcm code
too.

Thanks,

Omar

^ permalink raw reply

* [PATCH] ARM: highbank: retry wfi on reset request
From: Rob Herring @ 2012-10-29 17:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351221637-21747-1-git-send-email-robherring2@gmail.com>

On 10/25/2012 10:20 PM, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> In some cases, an interrupt can occur and prevent cause failure to enter
> wfi. This causes reset to hang. Retrying the wfi should be enough to
> prevent reset from hanging.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---

Arnd, Olof,

Can you please apply this for 3.7?

Rob

>  arch/arm/mach-highbank/system.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
> index 82c2723..86e37cd 100644
> --- a/arch/arm/mach-highbank/system.c
> +++ b/arch/arm/mach-highbank/system.c
> @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd)
>  		hignbank_set_pwr_soft_reset();
>  
>  	scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
> -	cpu_do_idle();
> +	while (1)
> +		cpu_do_idle();
>  }
>  
> 

^ permalink raw reply

* Representation of external memory-mapped devices in DT (gpmc)
From: Daniel Mack @ 2012-10-29 17:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508E9C42.10907@gmail.com>

On 29.10.2012 16:09, Rob Herring wrote:
> On 10/29/2012 09:39 AM, Daniel Mack wrote:
>> Hi,
>>
>> we're currently working on a DT binding for the GPMC bus that is found
>> on SoCs by TI. The implementation is based on CS lines and an 8, 16 or
>> 32 bit parallel interface. That IP is quite flexible, and it can for
>> example be used for physmap flash, external peripherals or even NAND.
>>
>> Depending on which CS is used to control the device, different memory
>> regions are reserved, and there's code to calculate the location and
>> size of them, given a CS number (see arch/arm/mach-omap2/gpmc.c).
> 
> I don't know the details of the h/w, but I would think the DT core code
> should be able work out the addresses. This can be done using ranges
> property which defines the mapping of a child bus into the parent bus
> addresses.

In this case, the controller is @0x50000000 while the external device is
mapped to address 0x0.

>> The binding will use one top-level node to describe the GPMC controller
>> itself and register the actual devices as sub-nodes to it. The NAND type
>> is the only one that is currently supported. This is how it currently looks:
>>
>> 	gpmc: gpmc at 50000000 {
>> 		compatible = "ti,gpmc";
>> 		ti,hwmods = "gpmc";
>> 		reg = <0x50000000 0x2000>;
>> 		interrupt-parent = <&intc>;
>> 		interrupts = <100>;
>> 		#address-cells = <1>;
>> 		#size-cells = <0>;
>>
>> 		nand at 0 {
> 
> You may want a CS0 node with nand as a child node of that.

Hmm, I don't see what that would buy us. The question is which way is
feasible for storing both the memory region and the cs number in the
device tree. The CS number should certainly go to the child node, no?

IOW, would it be a good idea to have something like the following layout?

	gpmc: gpmc at 50000000 {
		compatible = "ti,gpmc";
		ti,hwmods = "gpmc";
		reg = <0x50000000 0x2000>;

		/* cs-reg stores the setup of the controller's
		   memory map */

			/* offset	size */
		cs-reg = <0x0		0x1000000
			  ....		.....
			  ....		.....>;

		nand: child at 0 {
			/* timings */
			/* peripheral specifics */
		};
	};

I would actually much prefer that approach.

Afzal, because because that way, we can leave the code as-is for now and
add the "cs-reg" property once the code is switched to dynamic handling.
What do you think?


Thanks,
Daniel

^ permalink raw reply

* [PATCH V2 4/4] ARM: tegra: config: enable spi driver for Tegra SLINK controller
From: Laxman Dewangan @ 2012-10-29 17:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351531180-1652-1-git-send-email-ldewangan@nvidia.com>

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
No change from V1.

 arch/arm/configs/tegra_defconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index fb29680..60e1b2e 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -117,7 +117,7 @@ CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
-CONFIG_SPI_TEGRA=y
+CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
-- 
1.7.1.1

^ permalink raw reply related

* [PATCH V2 3/4] ARM: tegra: dts: cardhu: enable SLINK4
From: Laxman Dewangan @ 2012-10-29 17:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351531180-1652-1-git-send-email-ldewangan@nvidia.com>

Enable SLINK4 in Tegra30 based platform Cardhu.
Setting maximum spi frequency to 25MHz.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
Changes from V1:
rename the max freq prop to spi-max-frequency
 arch/arm/boot/dts/tegra30-cardhu.dtsi |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index b245e6c..1bd73ea 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -275,6 +275,11 @@
 		};
 	};
 
+	slink at 7000da00 {
+		status = "okay";
+		spi-max-frequency = <25000000>;
+	};
+
 	ahub {
 		i2s at 70080400 {
 			status = "okay";
-- 
1.7.1.1

^ permalink raw reply related

* [PATCH V2 2/4] ARM: tegra: Add OF_DEV_AUXDATA for SLINK driver in board dt
From: Laxman Dewangan @ 2012-10-29 17:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351531180-1652-1-git-send-email-ldewangan@nvidia.com>

Add OF_DEV_AUXDATA for slink driver for Tegra20 and Tegra30
board dt files.
Set the parent clock of slink controller to PLLP and configure
clock to 100MHz.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
Changes from V1:
- Revert the changes in clock table to get the driver name.

 arch/arm/mach-tegra/board-dt-tegra20.c   |    8 ++++++++
 arch/arm/mach-tegra/board-dt-tegra30.c   |   12 ++++++++++++
 arch/arm/mach-tegra/include/mach/iomap.h |   22 ++++++++++++++--------
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 2053f74..3fdcb45 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -90,6 +90,10 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 		       &tegra_ehci3_pdata),
 	OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", TEGRA_SLINK1_BASE, "spi_tegra.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", TEGRA_SLINK2_BASE, "spi_tegra.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", TEGRA_SLINK3_BASE, "spi_tegra.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", TEGRA_SLINK4_BASE, "spi_tegra.3", NULL),
 	{}
 };
 
@@ -109,6 +113,10 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
 	{ "sdmmc1",	"pll_p",	48000000,	false},
 	{ "sdmmc3",	"pll_p",	48000000,	false},
 	{ "sdmmc4",	"pll_p",	48000000,	false},
+	{ "sbc1",	"pll_p",	100000000,	false },
+	{ "sbc2",	"pll_p",	100000000,	false },
+	{ "sbc3",	"pll_p",	100000000,	false },
+	{ "sbc4",	"pll_p",	100000000,	false },
 	{ NULL,		NULL,		0,		0},
 };
 
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 9e6f79a..ec7c35d 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -52,6 +52,12 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK1_BASE, "spi_tegra.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK2_BASE, "spi_tegra.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK3_BASE, "spi_tegra.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK4_BASE, "spi_tegra.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK5_BASE, "spi_tegra.4", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", TEGRA_SLINK6_BASE, "spi_tegra.5", NULL),
 	{}
 };
 
@@ -71,6 +77,12 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
 	{ "sdmmc1",	"pll_p",	48000000,	false},
 	{ "sdmmc3",	"pll_p",	48000000,	false},
 	{ "sdmmc4",	"pll_p",	48000000,	false},
+	{ "sbc1",	"pll_p",	100000000,	false},
+	{ "sbc2",	"pll_p",	100000000,	false},
+	{ "sbc3",	"pll_p",	100000000,	false},
+	{ "sbc4",	"pll_p",	100000000,	false},
+	{ "sbc5",	"pll_p",	100000000,	false},
+	{ "sbc6",	"pll_p",	100000000,	false},
 	{ NULL,		NULL,		0,		0},
 };
 
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index fee3a94..0f46765 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -206,17 +206,23 @@
 #define TEGRA_DVC_BASE			0x7000D000
 #define TEGRA_DVC_SIZE			SZ_512
 
-#define TEGRA_SPI1_BASE			0x7000D400
-#define TEGRA_SPI1_SIZE			SZ_512
+#define TEGRA_SLINK1_BASE		0x7000D400
+#define TEGRA_SLINK1_SIZE		SZ_512
 
-#define TEGRA_SPI2_BASE			0x7000D600
-#define TEGRA_SPI2_SIZE			SZ_512
+#define TEGRA_SLINK2_BASE		0x7000D600
+#define TEGRA_SLINK2_SIZE		SZ_512
 
-#define TEGRA_SPI3_BASE			0x7000D800
-#define TEGRA_SPI3_SIZE			SZ_512
+#define TEGRA_SLINK3_BASE		0x7000D800
+#define TEGRA_SLINK3_SIZE		SZ_512
 
-#define TEGRA_SPI4_BASE			0x7000DA00
-#define TEGRA_SPI4_SIZE			SZ_512
+#define TEGRA_SLINK4_BASE		0x7000DA00
+#define TEGRA_SLINK4_SIZE		SZ_512
+
+#define TEGRA_SLINK5_BASE		0x7000DC00
+#define TEGRA_SLINK5_SIZE		SZ_512
+
+#define TEGRA_SLINK6_BASE		0x7000DE00
+#define TEGRA_SLINK6_SIZE		SZ_512
 
 #define TEGRA_RTC_BASE			0x7000E000
 #define TEGRA_RTC_SIZE			SZ_256
-- 
1.7.1.1

^ permalink raw reply related

* [PATCH V2 1/4] ARM: tegra: dts: add slink controller dt entry
From: Laxman Dewangan @ 2012-10-29 17:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351531180-1652-1-git-send-email-ldewangan@nvidia.com>

Add slink controller details in the dts file of
Tegra20 and Tegra30.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
Changes from V1:
rename the dma request prop to nvidia,dma-request-selector.

 arch/arm/boot/dts/tegra20.dtsi |   40 ++++++++++++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi |   60 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 6934bca..44cb979 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -186,6 +186,46 @@
 		status = "disabled";
 	};
 
+	slink at 7000d400 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d400 0x200>;
+		interrupts = <0 59 0x04>;
+		nvidia,dma-request-selector = <&apbdma 15>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000d600 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d600 0x200>;
+		interrupts = <0 82 0x04>;
+		nvidia,dma-request-selector = <&apbdma 16>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000d800 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d480 0x200>;
+		interrupts = <0 83 0x04>;
+		nvidia,dma-request-selector = <&apbdma 17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000da00 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000da00 0x200>;
+		interrupts = <0 93 0x04>;
+		nvidia,dma-request-selector = <&apbdma 18>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc";
 		reg = <0x7000e400 0x400>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 81f5df4..2703e3c 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -191,6 +191,66 @@
 		status = "disabled";
 	};
 
+	slink at 7000d400 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d400 0x200>;
+		interrupts = <0 59 0x04>;
+		nvidia,dma-request-selector = <&apbdma 15>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000d600 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d600 0x200>;
+		interrupts = <0 82 0x04>;
+		nvidia,dma-request-selector = <&apbdma 16>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000d800 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d480 0x200>;
+		interrupts = <0 83 0x04>;
+		nvidia,dma-request-selector = <&apbdma 17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000da00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000da00 0x200>;
+		interrupts = <0 93 0x04>;
+		nvidia,dma-request-selector = <&apbdma 18>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000dc00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000dc00 0x200>;
+		interrupts = <0 94 0x04>;
+		nvidia,dma-request-selector = <&apbdma 27>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	slink at 7000de00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000de00 0x200>;
+		interrupts = <0 79 0x04>;
+		nvidia,dma-request-selector = <&apbdma 28>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
 		reg = <0x7000e400 0x400>;
-- 
1.7.1.1

^ permalink raw reply related

* [PATCH V2 0/4] ARM: tegra: Enable SLINK controller driver
From: Laxman Dewangan @ 2012-10-29 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

This series modify the dts file to add the slink addresses,
make AUXDATA in board dt files, enable slink4 for tegra30-cardhu and
enable slink controller defconfig.

Changes from V1:
- Remove changes from clock tables.
- Make the dma req dt property name to nvidia,dma-request-selector.
- change the spi max frequency prop to spi-max-frequency.

Laxman Dewangan (4):
  ARM: tegra: dts: add slink controller dt entry
  ARM: tegra: Add OF_DEV_AUXDATA for SLINK driver in board dt
  ARM: tegra: dts: cardhu: enable SLINK4
  ARM: tegra: config: enable spi driver for Tegra SLINK controller

 arch/arm/boot/dts/tegra20.dtsi           |   40 ++++++++++++++++++++
 arch/arm/boot/dts/tegra30-cardhu.dtsi    |    5 ++
 arch/arm/boot/dts/tegra30.dtsi           |   60 ++++++++++++++++++++++++++++++
 arch/arm/configs/tegra_defconfig         |    2 +-
 arch/arm/mach-tegra/board-dt-tegra20.c   |    8 ++++
 arch/arm/mach-tegra/board-dt-tegra30.c   |   12 ++++++
 arch/arm/mach-tegra/include/mach/iomap.h |   22 +++++++----
 7 files changed, 140 insertions(+), 9 deletions(-)

^ permalink raw reply

* [PATCH V2] ARM: tegra30: clocks: add AHB and APB clocks
From: Stephen Warren @ 2012-10-29 17:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351506329-32427-1-git-send-email-josephl@nvidia.com>

On 10/29/2012 04:25 AM, Joseph Lo wrote:
> Adding the AHB and APB bus clock for Tegra30.

I have applied this to Tegra's tree for 3.8. Thanks.

^ permalink raw reply

* [PATCH] mfd/syscon: Fix compilation issue when built for imx
From: Vikram Narayanan @ 2012-10-29 17:12 UTC (permalink / raw)
  To: linux-arm-kernel

Compiling for a IMX6Q SoC with imx_v6_v7_defconfig results in the following error

<<<
drivers/mfd/syscon.c:94:15: error: variable 'syscon_regmap_config' has initializer but incomplete type
drivers/mfd/syscon.c:95:2: error: unknown field 'reg_bits' specified in initializer
drivers/mfd/syscon.c:95:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/syscon.c:95:2: warning: (near initialization for 'syscon_regmap_config') [enabled by default]
drivers/mfd/syscon.c:96:2: error: unknown field 'val_bits' specified in initializer
drivers/mfd/syscon.c:96:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/syscon.c:96:2: warning: (near initialization for 'syscon_regmap_config') [enabled by default]
drivers/mfd/syscon.c:97:2: error: unknown field 'reg_stride' specified in initializer
drivers/mfd/syscon.c:97:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/syscon.c:97:2: warning: (near initialization for 'syscon_regmap_config') [enabled by default]
drivers/mfd/syscon.c: In function 'syscon_probe':
drivers/mfd/syscon.c:124:2: error: invalid use of undefined type 'struct regmap_config'
drivers/mfd/syscon.c:125:2: error: implicit declaration of function 'devm_regmap_init_mmio' [-Werror=implicit-function-declaration]
drivers/mfd/syscon.c:125:17: warning: assignment makes pointer from integer without a cast [enabled by default]
cc1: some warnings being treated as errors
>>>

The datastructures are guarded with CONFIG_REGMAP in linux/regmap.h
Selecting REGMAP solves the compilation error.

Signed-off-by: Vikram Narayanan <vikram186@gmail.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
---
I'm not sure whether this is the right way to fix, or this is already fixed.
Please keep me in Cc while replying. I'm not subscribed to the list.

 drivers/mfd/Kconfig |   1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index acab3ef..641d191 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1029,6 +1029,7 @@ config MFD_STA2X11
 config MFD_SYSCON
 	bool "System Controller Register R/W Based on Regmap"
 	depends on OF
+	select REGMAP
 	select REGMAP_MMIO
 	help
 	  Select this option to enable accessing system control registers
--

^ permalink raw reply related

* [PATCH 1/3] ARM: timer: fix checkpatch warnings
From: Stephen Warren @ 2012-10-29 17:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351016892-21211-1-git-send-email-swarren@wwwdotorg.org>

On 10/23/2012 12:28 PM, Stephen Warren wrote:
> This prevents checkpatch complaining when this file is moved in a later
> patch.

I have applied patches 1 and 2 to Tegra's tree for 3.8. I'll hold off on
patch 3 for a bit. I need to see if it could benefit from similar rework
that drivers/irqchip recently received from Thomas Petazzoni.

^ permalink raw reply

* [PATCH 2/2] mailbox: OMAP: introduce mailbox framework
From: Omar Ramirez Luna @ 2012-10-29 17:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351530381-11459-1-git-send-email-omar.luna@linaro.org>

Actually moving it from plat-omap code as this is supposed to be
under drivers/ folder. This framework should work with the current
OMAP processors that have mailbox and can be used as a method of
interprocessor communication.

Signed-off-by: Omar Ramirez Luna <omar.luna@linaro.org>
---
 arch/arm/plat-omap/Kconfig   |   16 --
 arch/arm/plat-omap/Makefile  |    3 -
 arch/arm/plat-omap/mailbox.c |  435 ------------------------------------------
 drivers/Kconfig              |    2 +
 drivers/Makefile             |    1 +
 drivers/mailbox/Kconfig      |   28 +++
 drivers/mailbox/Makefile     |    1 +
 drivers/mailbox/mailbox.c    |  435 ++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 467 insertions(+), 454 deletions(-)
 delete mode 100644 arch/arm/plat-omap/mailbox.c
 create mode 100644 drivers/mailbox/Kconfig
 create mode 100644 drivers/mailbox/Makefile
 create mode 100644 drivers/mailbox/mailbox.c

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 82fcb20..419648f 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -116,22 +116,6 @@ config OMAP_MUX_WARNINGS
 	  to change the pin multiplexing setup.	 When there are no warnings
 	  printed, it's safe to deselect OMAP_MUX for your product.
 
-config OMAP_MBOX_FWK
-	tristate "Mailbox framework support"
-	depends on ARCH_OMAP
-	help
-	  Say Y here if you want to use OMAP Mailbox framework support for
-	  DSP, IVA1.0 and IVA2 in OMAP1/2/3.
-
-config OMAP_MBOX_KFIFO_SIZE
-	int "Mailbox kfifo default buffer size (bytes)"
-	depends on OMAP_MBOX_FWK
-	default 256
-	help
-	  Specify the default size of mailbox's kfifo buffers (bytes).
-	  This can also be changed at runtime (via the mbox_kfifo_size
-	  module parameter).
-
 config OMAP_IOMMU_IVA2
 	bool
 
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 4bd0ace..4702d1f 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -16,7 +16,4 @@ obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
 obj-y += $(i2c-omap-m) $(i2c-omap-y)
 
-# OMAP mailbox framework
-obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
-
 obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
deleted file mode 100644
index cae8692..0000000
--- a/arch/arm/plat-omap/mailbox.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * OMAP mailbox driver
- *
- * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
- *
- * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.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 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/kfifo.h>
-#include <linux/err.h>
-#include <linux/notifier.h>
-#include <linux/module.h>
-
-#include <linux/platform_data/omap_mailbox.h>
-
-static struct omap_mbox **mboxes;
-
-static int mbox_configured;
-static DEFINE_MUTEX(mbox_configured_lock);
-
-static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
-module_param(mbox_kfifo_size, uint, S_IRUGO);
-MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
-
-/* Mailbox FIFO handle functions */
-static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_read(mbox);
-}
-static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	mbox->ops->fifo_write(mbox, msg);
-}
-static inline int mbox_fifo_empty(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_empty(mbox);
-}
-static inline int mbox_fifo_full(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_full(mbox);
-}
-
-/* Mailbox IRQ handle functions */
-static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	if (mbox->ops->ack_irq)
-		mbox->ops->ack_irq(mbox, irq);
-}
-static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	return mbox->ops->is_irq(mbox, irq);
-}
-
-/*
- * message sender
- */
-static int __mbox_poll_for_space(struct omap_mbox *mbox)
-{
-	int ret = 0, i = 1000;
-
-	while (mbox_fifo_full(mbox)) {
-		if (mbox->ops->type == OMAP_MBOX_TYPE2)
-			return -1;
-		if (--i == 0)
-			return -1;
-		udelay(1);
-	}
-	return ret;
-}
-
-int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	struct omap_mbox_queue *mq = mbox->txq;
-	int ret = 0, len;
-
-	spin_lock_bh(&mq->lock);
-
-	if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
-		mbox_fifo_write(mbox, msg);
-		goto out;
-	}
-
-	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-	WARN_ON(len != sizeof(msg));
-
-	tasklet_schedule(&mbox->txq->tasklet);
-
-out:
-	spin_unlock_bh(&mq->lock);
-	return ret;
-}
-EXPORT_SYMBOL(omap_mbox_msg_send);
-
-static void mbox_tx_tasklet(unsigned long tx_data)
-{
-	struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
-	struct omap_mbox_queue *mq = mbox->txq;
-	mbox_msg_t msg;
-	int ret;
-
-	while (kfifo_len(&mq->fifo)) {
-		if (__mbox_poll_for_space(mbox)) {
-			omap_mbox_enable_irq(mbox, IRQ_TX);
-			break;
-		}
-
-		ret = kfifo_out(&mq->fifo, (unsigned char *)&msg,
-								sizeof(msg));
-		WARN_ON(ret != sizeof(msg));
-
-		mbox_fifo_write(mbox, msg);
-	}
-}
-
-/*
- * Message receiver(workqueue)
- */
-static void mbox_rx_work(struct work_struct *work)
-{
-	struct omap_mbox_queue *mq =
-			container_of(work, struct omap_mbox_queue, work);
-	mbox_msg_t msg;
-	int len;
-
-	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
-		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-		WARN_ON(len != sizeof(msg));
-
-		blocking_notifier_call_chain(&mq->mbox->notifier, len,
-								(void *)msg);
-		spin_lock_irq(&mq->lock);
-		if (mq->full) {
-			mq->full = false;
-			omap_mbox_enable_irq(mq->mbox, IRQ_RX);
-		}
-		spin_unlock_irq(&mq->lock);
-	}
-}
-
-/*
- * Mailbox interrupt handler
- */
-static void __mbox_tx_interrupt(struct omap_mbox *mbox)
-{
-	omap_mbox_disable_irq(mbox, IRQ_TX);
-	ack_mbox_irq(mbox, IRQ_TX);
-	tasklet_schedule(&mbox->txq->tasklet);
-}
-
-static void __mbox_rx_interrupt(struct omap_mbox *mbox)
-{
-	struct omap_mbox_queue *mq = mbox->rxq;
-	mbox_msg_t msg;
-	int len;
-
-	while (!mbox_fifo_empty(mbox)) {
-		if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
-			omap_mbox_disable_irq(mbox, IRQ_RX);
-			mq->full = true;
-			goto nomem;
-		}
-
-		msg = mbox_fifo_read(mbox);
-
-		len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-		WARN_ON(len != sizeof(msg));
-
-		if (mbox->ops->type == OMAP_MBOX_TYPE1)
-			break;
-	}
-
-	/* no more messages in the fifo. clear IRQ source. */
-	ack_mbox_irq(mbox, IRQ_RX);
-nomem:
-	schedule_work(&mbox->rxq->work);
-}
-
-static irqreturn_t mbox_interrupt(int irq, void *p)
-{
-	struct omap_mbox *mbox = p;
-
-	if (is_mbox_irq(mbox, IRQ_TX))
-		__mbox_tx_interrupt(mbox);
-
-	if (is_mbox_irq(mbox, IRQ_RX))
-		__mbox_rx_interrupt(mbox);
-
-	return IRQ_HANDLED;
-}
-
-static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
-					void (*work) (struct work_struct *),
-					void (*tasklet)(unsigned long))
-{
-	struct omap_mbox_queue *mq;
-
-	mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
-	if (!mq)
-		return NULL;
-
-	spin_lock_init(&mq->lock);
-
-	if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
-		goto error;
-
-	if (work)
-		INIT_WORK(&mq->work, work);
-
-	if (tasklet)
-		tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
-	return mq;
-error:
-	kfree(mq);
-	return NULL;
-}
-
-static void mbox_queue_free(struct omap_mbox_queue *q)
-{
-	kfifo_free(&q->fifo);
-	kfree(q);
-}
-
-static int omap_mbox_startup(struct omap_mbox *mbox)
-{
-	int ret = 0;
-	struct omap_mbox_queue *mq;
-
-	mutex_lock(&mbox_configured_lock);
-	if (!mbox_configured++) {
-		if (likely(mbox->ops->startup)) {
-			ret = mbox->ops->startup(mbox);
-			if (unlikely(ret))
-				goto fail_startup;
-		} else
-			goto fail_startup;
-	}
-
-	if (!mbox->use_count++) {
-		ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
-							mbox->name, mbox);
-		if (unlikely(ret)) {
-			pr_err("failed to register mailbox interrupt:%d\n",
-									ret);
-			goto fail_request_irq;
-		}
-		mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
-		if (!mq) {
-			ret = -ENOMEM;
-			goto fail_alloc_txq;
-		}
-		mbox->txq = mq;
-
-		mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
-		if (!mq) {
-			ret = -ENOMEM;
-			goto fail_alloc_rxq;
-		}
-		mbox->rxq = mq;
-		mq->mbox = mbox;
-
-		omap_mbox_enable_irq(mbox, IRQ_RX);
-	}
-	mutex_unlock(&mbox_configured_lock);
-	return 0;
-
-fail_alloc_rxq:
-	mbox_queue_free(mbox->txq);
-fail_alloc_txq:
-	free_irq(mbox->irq, mbox);
-fail_request_irq:
-	if (mbox->ops->shutdown)
-		mbox->ops->shutdown(mbox);
-	mbox->use_count--;
-fail_startup:
-	mbox_configured--;
-	mutex_unlock(&mbox_configured_lock);
-	return ret;
-}
-
-static void omap_mbox_fini(struct omap_mbox *mbox)
-{
-	mutex_lock(&mbox_configured_lock);
-
-	if (!--mbox->use_count) {
-		omap_mbox_disable_irq(mbox, IRQ_RX);
-		free_irq(mbox->irq, mbox);
-		tasklet_kill(&mbox->txq->tasklet);
-		flush_work(&mbox->rxq->work);
-		mbox_queue_free(mbox->txq);
-		mbox_queue_free(mbox->rxq);
-	}
-
-	if (likely(mbox->ops->shutdown)) {
-		if (!--mbox_configured)
-			mbox->ops->shutdown(mbox);
-	}
-
-	mutex_unlock(&mbox_configured_lock);
-}
-
-struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
-{
-	struct omap_mbox *_mbox, *mbox = NULL;
-	int i, ret;
-
-	if (!mboxes)
-		return ERR_PTR(-EINVAL);
-
-	for (i = 0; (_mbox = mboxes[i]); i++) {
-		if (!strcmp(_mbox->name, name)) {
-			mbox = _mbox;
-			break;
-		}
-	}
-
-	if (!mbox)
-		return ERR_PTR(-ENOENT);
-
-	if (nb)
-		blocking_notifier_chain_register(&mbox->notifier, nb);
-
-	ret = omap_mbox_startup(mbox);
-	if (ret) {
-		blocking_notifier_chain_unregister(&mbox->notifier, nb);
-		return ERR_PTR(-ENODEV);
-	}
-
-	return mbox;
-}
-EXPORT_SYMBOL(omap_mbox_get);
-
-void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
-{
-	blocking_notifier_chain_unregister(&mbox->notifier, nb);
-	omap_mbox_fini(mbox);
-}
-EXPORT_SYMBOL(omap_mbox_put);
-
-static struct class omap_mbox_class = { .name = "mbox", };
-
-int omap_mbox_register(struct device *parent, struct omap_mbox **list)
-{
-	int ret;
-	int i;
-
-	mboxes = list;
-	if (!mboxes)
-		return -EINVAL;
-
-	for (i = 0; mboxes[i]; i++) {
-		struct omap_mbox *mbox = mboxes[i];
-		mbox->dev = device_create(&omap_mbox_class,
-				parent, 0, mbox, "%s", mbox->name);
-		if (IS_ERR(mbox->dev)) {
-			ret = PTR_ERR(mbox->dev);
-			goto err_out;
-		}
-
-		BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
-	}
-	return 0;
-
-err_out:
-	while (i--)
-		device_unregister(mboxes[i]->dev);
-	return ret;
-}
-EXPORT_SYMBOL(omap_mbox_register);
-
-int omap_mbox_unregister(void)
-{
-	int i;
-
-	if (!mboxes)
-		return -EINVAL;
-
-	for (i = 0; mboxes[i]; i++)
-		device_unregister(mboxes[i]->dev);
-	mboxes = NULL;
-	return 0;
-}
-EXPORT_SYMBOL(omap_mbox_unregister);
-
-static int __init omap_mbox_init(void)
-{
-	int err;
-
-	err = class_register(&omap_mbox_class);
-	if (err)
-		return err;
-
-	/* kfifo size sanity check: alignment and minimal size */
-	mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
-	mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
-							sizeof(mbox_msg_t));
-
-	return 0;
-}
-subsys_initcall(omap_mbox_init);
-
-static void __exit omap_mbox_exit(void)
-{
-	class_unregister(&omap_mbox_class);
-}
-module_exit(omap_mbox_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
-MODULE_AUTHOR("Toshihiro Kobayashi");
-MODULE_AUTHOR("Hiroshi DOYU");
diff --git a/drivers/Kconfig b/drivers/Kconfig
index dbdefa3..7a4fb98 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -134,6 +134,8 @@ source "drivers/hwspinlock/Kconfig"
 
 source "drivers/clocksource/Kconfig"
 
+source "drivers/mailbox/Kconfig"
+
 source "drivers/iommu/Kconfig"
 
 source "drivers/remoteproc/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a16a8d0..78f2bf0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -132,6 +132,7 @@ obj-y				+= clk/
 
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
 obj-$(CONFIG_NFC)		+= nfc/
+obj-$(CONFIG_MAILBOX)		+= mailbox/
 obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
 obj-$(CONFIG_REMOTEPROC)	+= remoteproc/
 obj-$(CONFIG_RPMSG)		+= rpmsg/
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
new file mode 100644
index 0000000..937b887
--- /dev/null
+++ b/drivers/mailbox/Kconfig
@@ -0,0 +1,28 @@
+menuconfig MAILBOX
+	bool "Mailbox Hardware Support"
+	help
+	  Mailbox is a framework to control hardware communication between
+	  on-chip processors through queued messages and interrupt driven
+	  signals. Say Y if your platform supports hardware mailboxes.
+
+if MAILBOX
+
+config OMAP_MBOX_FWK
+	tristate "OMAP Mailbox framework support"
+	depends on ARCH_OMAP
+	help
+	  Mailbox implementation for OMAP family chips with hardware for
+	  interprocessor communication involving DSP, IVA1.0 and IVA2 in
+	  OMAP1/2/3; or IPU, IVA HD and DSP in OMAP4. Say Y here if you
+	  want to use OMAP Mailbox framework support.
+
+config OMAP_MBOX_KFIFO_SIZE
+	int "Mailbox kfifo default buffer size (bytes)"
+	depends on OMAP_MBOX_FWK
+	default 256
+	help
+	  Specify the default size of mailbox's kfifo buffers (bytes).
+	  This can also be changed at runtime (via the mbox_kfifo_size
+	  module parameter).
+
+endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
new file mode 100644
index 0000000..1040ac5
--- /dev/null
+++ b/drivers/mailbox/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
new file mode 100644
index 0000000..cae8692
--- /dev/null
+++ b/drivers/mailbox/mailbox.c
@@ -0,0 +1,435 @@
+/*
+ * OMAP mailbox driver
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.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 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/kfifo.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/module.h>
+
+#include <linux/platform_data/omap_mailbox.h>
+
+static struct omap_mbox **mboxes;
+
+static int mbox_configured;
+static DEFINE_MUTEX(mbox_configured_lock);
+
+static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
+module_param(mbox_kfifo_size, uint, S_IRUGO);
+MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_read(mbox);
+}
+static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	mbox->ops->fifo_write(mbox, msg);
+}
+static inline int mbox_fifo_empty(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_empty(mbox);
+}
+static inline int mbox_fifo_full(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_full(mbox);
+}
+
+/* Mailbox IRQ handle functions */
+static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	if (mbox->ops->ack_irq)
+		mbox->ops->ack_irq(mbox, irq);
+}
+static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	return mbox->ops->is_irq(mbox, irq);
+}
+
+/*
+ * message sender
+ */
+static int __mbox_poll_for_space(struct omap_mbox *mbox)
+{
+	int ret = 0, i = 1000;
+
+	while (mbox_fifo_full(mbox)) {
+		if (mbox->ops->type == OMAP_MBOX_TYPE2)
+			return -1;
+		if (--i == 0)
+			return -1;
+		udelay(1);
+	}
+	return ret;
+}
+
+int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	struct omap_mbox_queue *mq = mbox->txq;
+	int ret = 0, len;
+
+	spin_lock_bh(&mq->lock);
+
+	if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
+		mbox_fifo_write(mbox, msg);
+		goto out;
+	}
+
+	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+	WARN_ON(len != sizeof(msg));
+
+	tasklet_schedule(&mbox->txq->tasklet);
+
+out:
+	spin_unlock_bh(&mq->lock);
+	return ret;
+}
+EXPORT_SYMBOL(omap_mbox_msg_send);
+
+static void mbox_tx_tasklet(unsigned long tx_data)
+{
+	struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
+	struct omap_mbox_queue *mq = mbox->txq;
+	mbox_msg_t msg;
+	int ret;
+
+	while (kfifo_len(&mq->fifo)) {
+		if (__mbox_poll_for_space(mbox)) {
+			omap_mbox_enable_irq(mbox, IRQ_TX);
+			break;
+		}
+
+		ret = kfifo_out(&mq->fifo, (unsigned char *)&msg,
+								sizeof(msg));
+		WARN_ON(ret != sizeof(msg));
+
+		mbox_fifo_write(mbox, msg);
+	}
+}
+
+/*
+ * Message receiver(workqueue)
+ */
+static void mbox_rx_work(struct work_struct *work)
+{
+	struct omap_mbox_queue *mq =
+			container_of(work, struct omap_mbox_queue, work);
+	mbox_msg_t msg;
+	int len;
+
+	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		blocking_notifier_call_chain(&mq->mbox->notifier, len,
+								(void *)msg);
+		spin_lock_irq(&mq->lock);
+		if (mq->full) {
+			mq->full = false;
+			omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+		}
+		spin_unlock_irq(&mq->lock);
+	}
+}
+
+/*
+ * Mailbox interrupt handler
+ */
+static void __mbox_tx_interrupt(struct omap_mbox *mbox)
+{
+	omap_mbox_disable_irq(mbox, IRQ_TX);
+	ack_mbox_irq(mbox, IRQ_TX);
+	tasklet_schedule(&mbox->txq->tasklet);
+}
+
+static void __mbox_rx_interrupt(struct omap_mbox *mbox)
+{
+	struct omap_mbox_queue *mq = mbox->rxq;
+	mbox_msg_t msg;
+	int len;
+
+	while (!mbox_fifo_empty(mbox)) {
+		if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+			omap_mbox_disable_irq(mbox, IRQ_RX);
+			mq->full = true;
+			goto nomem;
+		}
+
+		msg = mbox_fifo_read(mbox);
+
+		len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		if (mbox->ops->type == OMAP_MBOX_TYPE1)
+			break;
+	}
+
+	/* no more messages in the fifo. clear IRQ source. */
+	ack_mbox_irq(mbox, IRQ_RX);
+nomem:
+	schedule_work(&mbox->rxq->work);
+}
+
+static irqreturn_t mbox_interrupt(int irq, void *p)
+{
+	struct omap_mbox *mbox = p;
+
+	if (is_mbox_irq(mbox, IRQ_TX))
+		__mbox_tx_interrupt(mbox);
+
+	if (is_mbox_irq(mbox, IRQ_RX))
+		__mbox_rx_interrupt(mbox);
+
+	return IRQ_HANDLED;
+}
+
+static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
+					void (*work) (struct work_struct *),
+					void (*tasklet)(unsigned long))
+{
+	struct omap_mbox_queue *mq;
+
+	mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	spin_lock_init(&mq->lock);
+
+	if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
+		goto error;
+
+	if (work)
+		INIT_WORK(&mq->work, work);
+
+	if (tasklet)
+		tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
+	return mq;
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void mbox_queue_free(struct omap_mbox_queue *q)
+{
+	kfifo_free(&q->fifo);
+	kfree(q);
+}
+
+static int omap_mbox_startup(struct omap_mbox *mbox)
+{
+	int ret = 0;
+	struct omap_mbox_queue *mq;
+
+	mutex_lock(&mbox_configured_lock);
+	if (!mbox_configured++) {
+		if (likely(mbox->ops->startup)) {
+			ret = mbox->ops->startup(mbox);
+			if (unlikely(ret))
+				goto fail_startup;
+		} else
+			goto fail_startup;
+	}
+
+	if (!mbox->use_count++) {
+		ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+							mbox->name, mbox);
+		if (unlikely(ret)) {
+			pr_err("failed to register mailbox interrupt:%d\n",
+									ret);
+			goto fail_request_irq;
+		}
+		mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+		if (!mq) {
+			ret = -ENOMEM;
+			goto fail_alloc_txq;
+		}
+		mbox->txq = mq;
+
+		mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+		if (!mq) {
+			ret = -ENOMEM;
+			goto fail_alloc_rxq;
+		}
+		mbox->rxq = mq;
+		mq->mbox = mbox;
+
+		omap_mbox_enable_irq(mbox, IRQ_RX);
+	}
+	mutex_unlock(&mbox_configured_lock);
+	return 0;
+
+fail_alloc_rxq:
+	mbox_queue_free(mbox->txq);
+fail_alloc_txq:
+	free_irq(mbox->irq, mbox);
+fail_request_irq:
+	if (mbox->ops->shutdown)
+		mbox->ops->shutdown(mbox);
+	mbox->use_count--;
+fail_startup:
+	mbox_configured--;
+	mutex_unlock(&mbox_configured_lock);
+	return ret;
+}
+
+static void omap_mbox_fini(struct omap_mbox *mbox)
+{
+	mutex_lock(&mbox_configured_lock);
+
+	if (!--mbox->use_count) {
+		omap_mbox_disable_irq(mbox, IRQ_RX);
+		free_irq(mbox->irq, mbox);
+		tasklet_kill(&mbox->txq->tasklet);
+		flush_work(&mbox->rxq->work);
+		mbox_queue_free(mbox->txq);
+		mbox_queue_free(mbox->rxq);
+	}
+
+	if (likely(mbox->ops->shutdown)) {
+		if (!--mbox_configured)
+			mbox->ops->shutdown(mbox);
+	}
+
+	mutex_unlock(&mbox_configured_lock);
+}
+
+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
+{
+	struct omap_mbox *_mbox, *mbox = NULL;
+	int i, ret;
+
+	if (!mboxes)
+		return ERR_PTR(-EINVAL);
+
+	for (i = 0; (_mbox = mboxes[i]); i++) {
+		if (!strcmp(_mbox->name, name)) {
+			mbox = _mbox;
+			break;
+		}
+	}
+
+	if (!mbox)
+		return ERR_PTR(-ENOENT);
+
+	if (nb)
+		blocking_notifier_chain_register(&mbox->notifier, nb);
+
+	ret = omap_mbox_startup(mbox);
+	if (ret) {
+		blocking_notifier_chain_unregister(&mbox->notifier, nb);
+		return ERR_PTR(-ENODEV);
+	}
+
+	return mbox;
+}
+EXPORT_SYMBOL(omap_mbox_get);
+
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&mbox->notifier, nb);
+	omap_mbox_fini(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_put);
+
+static struct class omap_mbox_class = { .name = "mbox", };
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **list)
+{
+	int ret;
+	int i;
+
+	mboxes = list;
+	if (!mboxes)
+		return -EINVAL;
+
+	for (i = 0; mboxes[i]; i++) {
+		struct omap_mbox *mbox = mboxes[i];
+		mbox->dev = device_create(&omap_mbox_class,
+				parent, 0, mbox, "%s", mbox->name);
+		if (IS_ERR(mbox->dev)) {
+			ret = PTR_ERR(mbox->dev);
+			goto err_out;
+		}
+
+		BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
+	}
+	return 0;
+
+err_out:
+	while (i--)
+		device_unregister(mboxes[i]->dev);
+	return ret;
+}
+EXPORT_SYMBOL(omap_mbox_register);
+
+int omap_mbox_unregister(void)
+{
+	int i;
+
+	if (!mboxes)
+		return -EINVAL;
+
+	for (i = 0; mboxes[i]; i++)
+		device_unregister(mboxes[i]->dev);
+	mboxes = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(omap_mbox_unregister);
+
+static int __init omap_mbox_init(void)
+{
+	int err;
+
+	err = class_register(&omap_mbox_class);
+	if (err)
+		return err;
+
+	/* kfifo size sanity check: alignment and minimal size */
+	mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
+	mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
+							sizeof(mbox_msg_t));
+
+	return 0;
+}
+subsys_initcall(omap_mbox_init);
+
+static void __exit omap_mbox_exit(void)
+{
+	class_unregister(&omap_mbox_class);
+}
+module_exit(omap_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
+MODULE_AUTHOR("Toshihiro Kobayashi");
+MODULE_AUTHOR("Hiroshi DOYU");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/2] ARM: OMAP2+: move mailbox.h out of plat-omap headers
From: Omar Ramirez Luna @ 2012-10-29 17:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351530381-11459-1-git-send-email-omar.luna@linaro.org>

CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: devel at driverdev.osuosl.org
Signed-off-by: Omar Ramirez Luna <omar.luna@linaro.org>
---
 arch/arm/mach-omap2/mailbox.c                      |    2 +-
 arch/arm/plat-omap/include/plat/mailbox.h          |  105 --------------------
 arch/arm/plat-omap/mailbox.c                       |    2 +-
 .../tidspbridge/include/dspbridge/host_os.h        |    2 +-
 include/linux/platform_data/omap_mailbox.h         |  105 ++++++++++++++++++++
 5 files changed, 108 insertions(+), 108 deletions(-)
 delete mode 100644 arch/arm/plat-omap/include/plat/mailbox.h
 create mode 100644 include/linux/platform_data/omap_mailbox.h

diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 0d97456..f69e659 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
 
-#include <plat/mailbox.h>
+#include <linux/platform_data/omap_mailbox.h>
 
 #include "soc.h"
 
diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h
deleted file mode 100644
index cc3921e..0000000
--- a/arch/arm/plat-omap/include/plat/mailbox.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* mailbox.h */
-
-#ifndef MAILBOX_H
-#define MAILBOX_H
-
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kfifo.h>
-
-typedef u32 mbox_msg_t;
-struct omap_mbox;
-
-typedef int __bitwise omap_mbox_irq_t;
-#define IRQ_TX ((__force omap_mbox_irq_t) 1)
-#define IRQ_RX ((__force omap_mbox_irq_t) 2)
-
-typedef int __bitwise omap_mbox_type_t;
-#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
-#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
-
-struct omap_mbox_ops {
-	omap_mbox_type_t	type;
-	int		(*startup)(struct omap_mbox *mbox);
-	void		(*shutdown)(struct omap_mbox *mbox);
-	/* fifo */
-	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
-	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
-	int		(*fifo_empty)(struct omap_mbox *mbox);
-	int		(*fifo_full)(struct omap_mbox *mbox);
-	/* irq */
-	void		(*enable_irq)(struct omap_mbox *mbox,
-						omap_mbox_irq_t irq);
-	void		(*disable_irq)(struct omap_mbox *mbox,
-						omap_mbox_irq_t irq);
-	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-	/* ctx */
-	void		(*save_ctx)(struct omap_mbox *mbox);
-	void		(*restore_ctx)(struct omap_mbox *mbox);
-};
-
-struct omap_mbox_queue {
-	spinlock_t		lock;
-	struct kfifo		fifo;
-	struct work_struct	work;
-	struct tasklet_struct	tasklet;
-	struct omap_mbox	*mbox;
-	bool full;
-};
-
-struct omap_mbox {
-	char			*name;
-	unsigned int		irq;
-	struct omap_mbox_queue	*txq, *rxq;
-	struct omap_mbox_ops	*ops;
-	struct device		*dev;
-	void			*priv;
-	int			use_count;
-	struct blocking_notifier_head   notifier;
-};
-
-int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
-void omap_mbox_init_seq(struct omap_mbox *);
-
-struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
-void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
-
-int omap_mbox_register(struct device *parent, struct omap_mbox **);
-int omap_mbox_unregister(void);
-
-static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
-{
-	if (!mbox->ops->save_ctx) {
-		dev_err(mbox->dev, "%s:\tno save\n", __func__);
-		return;
-	}
-
-	mbox->ops->save_ctx(mbox);
-}
-
-static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
-{
-	if (!mbox->ops->restore_ctx) {
-		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
-		return;
-	}
-
-	mbox->ops->restore_ctx(mbox);
-}
-
-static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
-					omap_mbox_irq_t irq)
-{
-	mbox->ops->enable_irq(mbox, irq);
-}
-
-static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
-					 omap_mbox_irq_t irq)
-{
-	mbox->ops->disable_irq(mbox, irq);
-}
-
-#endif /* MAILBOX_H */
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 42377ef..cae8692 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -31,7 +31,7 @@
 #include <linux/notifier.h>
 #include <linux/module.h>
 
-#include <plat/mailbox.h>
+#include <linux/platform_data/omap_mailbox.h>
 
 static struct omap_mbox **mboxes;
 
diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
index 896f157..bff9e3a 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
@@ -41,11 +41,11 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-#include <plat/mailbox.h>
 #include <linux/pagemap.h>
 #include <asm/cacheflush.h>
 #include <linux/dma-mapping.h>
 
+#include <linux/platform_data/omap_mailbox.h>
 /* TODO -- Remove, once BP defines them */
 #define INT_DSP_MMU_IRQ        28
 
diff --git a/include/linux/platform_data/omap_mailbox.h b/include/linux/platform_data/omap_mailbox.h
new file mode 100644
index 0000000..cc3921e
--- /dev/null
+++ b/include/linux/platform_data/omap_mailbox.h
@@ -0,0 +1,105 @@
+/* mailbox.h */
+
+#ifndef MAILBOX_H
+#define MAILBOX_H
+
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kfifo.h>
+
+typedef u32 mbox_msg_t;
+struct omap_mbox;
+
+typedef int __bitwise omap_mbox_irq_t;
+#define IRQ_TX ((__force omap_mbox_irq_t) 1)
+#define IRQ_RX ((__force omap_mbox_irq_t) 2)
+
+typedef int __bitwise omap_mbox_type_t;
+#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
+#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
+
+struct omap_mbox_ops {
+	omap_mbox_type_t	type;
+	int		(*startup)(struct omap_mbox *mbox);
+	void		(*shutdown)(struct omap_mbox *mbox);
+	/* fifo */
+	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
+	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
+	int		(*fifo_empty)(struct omap_mbox *mbox);
+	int		(*fifo_full)(struct omap_mbox *mbox);
+	/* irq */
+	void		(*enable_irq)(struct omap_mbox *mbox,
+						omap_mbox_irq_t irq);
+	void		(*disable_irq)(struct omap_mbox *mbox,
+						omap_mbox_irq_t irq);
+	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+	/* ctx */
+	void		(*save_ctx)(struct omap_mbox *mbox);
+	void		(*restore_ctx)(struct omap_mbox *mbox);
+};
+
+struct omap_mbox_queue {
+	spinlock_t		lock;
+	struct kfifo		fifo;
+	struct work_struct	work;
+	struct tasklet_struct	tasklet;
+	struct omap_mbox	*mbox;
+	bool full;
+};
+
+struct omap_mbox {
+	char			*name;
+	unsigned int		irq;
+	struct omap_mbox_queue	*txq, *rxq;
+	struct omap_mbox_ops	*ops;
+	struct device		*dev;
+	void			*priv;
+	int			use_count;
+	struct blocking_notifier_head   notifier;
+};
+
+int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
+void omap_mbox_init_seq(struct omap_mbox *);
+
+struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **);
+int omap_mbox_unregister(void);
+
+static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
+{
+	if (!mbox->ops->save_ctx) {
+		dev_err(mbox->dev, "%s:\tno save\n", __func__);
+		return;
+	}
+
+	mbox->ops->save_ctx(mbox);
+}
+
+static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+	if (!mbox->ops->restore_ctx) {
+		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
+		return;
+	}
+
+	mbox->ops->restore_ctx(mbox);
+}
+
+static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
+					omap_mbox_irq_t irq)
+{
+	mbox->ops->enable_irq(mbox, irq);
+}
+
+static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
+					 omap_mbox_irq_t irq)
+{
+	mbox->ops->disable_irq(mbox, irq);
+}
+
+#endif /* MAILBOX_H */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 0/2] ARM: OMAP: mailbox out of plat code
From: Omar Ramirez Luna @ 2012-10-29 17:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Omar Ramirez Luna <omar.ramirez@copitl.com>

Move Mailbox's headers and driver out of platform code as
per current plat-omap cleanup activities.

While at it move mailbox code out of platform and to drivers/
folder, given that this is an OMAP specific framework, some people
might frown upon this, however it seemed worth to try to move it now.
I was expecting this could also pull out the mailbox code from
ux-500 platform, but the platform with a similar mailbox mechanism
has been deleted during 3.5 rc cycle.

So, are there any other mailbox-like drivers out there?

Omar Ramirez Luna (2):
  ARM: OMAP2+: move mailbox.h out of plat-omap headers
  mailbox: OMAP: introduce mailbox framework

 arch/arm/mach-omap2/mailbox.c                      |    2 +-
 arch/arm/plat-omap/Kconfig                         |   16 -
 arch/arm/plat-omap/Makefile                        |    3 -
 arch/arm/plat-omap/include/plat/mailbox.h          |  105 -----
 arch/arm/plat-omap/mailbox.c                       |  435 --------------------
 drivers/Kconfig                                    |    2 +
 drivers/Makefile                                   |    1 +
 drivers/mailbox/Kconfig                            |   28 ++
 drivers/mailbox/Makefile                           |    1 +
 drivers/mailbox/mailbox.c                          |  435 ++++++++++++++++++++
 .../tidspbridge/include/dspbridge/host_os.h        |    2 +-
 include/linux/platform_data/omap_mailbox.h         |  105 +++++
 12 files changed, 574 insertions(+), 561 deletions(-)
 delete mode 100644 arch/arm/plat-omap/include/plat/mailbox.h
 delete mode 100644 arch/arm/plat-omap/mailbox.c
 create mode 100644 drivers/mailbox/Kconfig
 create mode 100644 drivers/mailbox/Makefile
 create mode 100644 drivers/mailbox/mailbox.c
 create mode 100644 include/linux/platform_data/omap_mailbox.h

-- 
1.7.9.5

^ permalink raw reply

* [PATCH 2/2] ARM: tegra: move irammap.h to mach-tegra
From: Stephen Warren @ 2012-10-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350326249-18405-2-git-send-email-swarren@wwwdotorg.org>

On 10/15/2012 12:37 PM, Stephen Warren wrote:
> Nothing outside mach-tegra uses this file, so there's no need for it to
> be in <mach/>.
> 
> Since uncompress.h and debug-macro.S remain in include/mach, they need
> to include "../../irammap.h" becaue of this change. Both these usages
> will be removed shortly, when Tegra's DEBUG_LL implementation is updated
> not to pass information through IRAM.

I have applied this to Tegra's tree for 3.8.

^ permalink raw reply


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