Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 3/3] arm/tegra: device tree support for ventana board
From: Olof Johansson @ 2011-09-28 18:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201109281516.42513.arnd@arndb.de>

On Wed, Sep 28, 2011 at 6:16 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 28 September 2011, Peter De Schrijver wrote:
>> --- a/arch/arm/mach-tegra/board-dt.c
>> +++ b/arch/arm/mach-tegra/board-dt.c
>> @@ -47,7 +47,7 @@
>>
>> ?void harmony_pinmux_init(void);
>> ?void seaboard_pinmux_init(void);
>> -
>> +void ventana_pinmux_init(void);
>>
>> ?struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
>> ? ? ? ? OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
>> @@ -95,6 +95,8 @@ static void __init tegra_dt_init(void)
>> ? ? ? ? ? ? ? ? harmony_pinmux_init();
>> ? ? ? ? else if (of_machine_is_compatible("nvidia,seaboard"))
>> ? ? ? ? ? ? ? ? seaboard_pinmux_init();
>> + ? ? ? else if (of_machine_is_compatible("nvidia,ventana"))
>> + ? ? ? ? ? ? ? ventana_pinmux_init();
>
> Are you (Peter, Colin, Olof) confident that this is not getting out
> of hand before it's getting better?
>
> If we are keeping the per-board pinmux configuration in the kernel
> for longer, I think it would be better to do this table-driven than
> having a list of top-level of_machine_is_compatible() statements
> and do something like:
>
> static struct {
> ? ? ? ?const char *machine;
> ? ? ? ?struct tegra_pingroup_config *config[];
> } pinmux_configs[] __initdata = {
> ? ? ? ?{ "nvidia,ventana", &ventana_pinmux },
> ? ? ? ?{ "nvidia,seaboard, &seaboard_pinmux },
> };

That is definitely a nicer solution. I didn't see a strong need to
switch to that model now since it should hopefully be a temporary
thing, but given Stephen's mention of Cardhu, I think it does make
sense.

Peter, care to respin this patch with the above solution instead?
Also, please print a warning if no match is found.


Thanks,

-Olof

^ permalink raw reply

* [PATCH v2 0/4] Fixes to twl4030-madc and add BeagleBoard support
From: Tony Lindgren @ 2011-09-28 18:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110822135530.GR4607@sortiz-mobl>

* Samuel Ortiz <sameo@linux.intel.com> [110822 06:20]:
> Hi Kyle,
> 
> On Thu, Aug 11, 2011 at 10:33:11PM -0500, Kyle Manna wrote:
> > These patches add basic functionality to the twl4030-madc driver to make
> > it work on the BeagleBoard xM.
> > 
> > Version 2 adds fixes per Grazvydas Ignotas and the check for NULL pointer patch.
> > 
> > Kyle Manna (4):
> >   mfd: twl4030-madc: copy the device pointer
> >   mfd: twl4030-madc: turn on the MADC clock
> >   mfd: twl4030-madc: check for NULL pointer
> >   arm: BeagleBoard: add support for the twl4030-madc
> Tony, are you ok with the BeagleBoard changes ?
> The MFD ones look fine to me, I'd like to apply them.

Yes sorry for the delay in replying. I acked it, maybe
you can just copy the subject to have a proper description
for the patch.

Tony

^ permalink raw reply

* [PATCH v2 4/4] arm: BeagleBoard: add support for the twl4030-madc
From: Tony Lindgren @ 2011-09-28 18:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1313119995-15382-5-git-send-email-kyle@kylemanna.com>

* Kyle Manna <kyle@kylemanna.com> [110811 20:01]:
> Signed-off-by: Kyle Manna <kyle@kylemanna.com>

Missing description, but with that corrected:

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

> ---
>  arch/arm/mach-omap2/board-omap3beagle.c |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
> index 3ae16b4..9cc9fa9 100644
> --- a/arch/arm/mach-omap2/board-omap3beagle.c
> +++ b/arch/arm/mach-omap2/board-omap3beagle.c
> @@ -378,7 +378,8 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
>  static int __init omap3_beagle_i2c_init(void)
>  {
>  	omap3_pmic_get_config(&beagle_twldata,
> -			TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
> +			TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
> +			TWL_COMMON_PDATA_AUDIO,
>  			TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
>  
>  	beagle_twldata.vpll2->constraints.name = "VDVI";
> @@ -456,9 +457,15 @@ static void __init omap3_beagle_init_irq(void)
>  	omap3_init_irq();
>  }
>  
> +static struct platform_device madc_hwmon = {
> +	.name	= "twl4030_madc_hwmon",
> +	.id	= -1,
> +};
> +
>  static struct platform_device *omap3_beagle_devices[] __initdata = {
>  	&leds_gpio,
>  	&keys_gpio,
> +	&madc_hwmon,
>  };
>  
>  static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
> -- 
> 1.7.4.1
> 

^ permalink raw reply

* [PATCH] OMAP: Fix linking error in twl-common.c for OMAP2/3/4 only builds
From: Tony Lindgren @ 2011-09-28 18:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E43F029.6060208@matrix-vision.de>

Hi,

Sorry for the delay in replying..

* Michael Jones <michael.jones@matrix-vision.de> [110811 07:34]:
> 
> I still stumbled upon these linker errors when building for my OMAP3
> board, using the current linux-omap master branch. I inadvertently had
> CONFIG_ARCH_OMAP4=y (leftover from my starting point,
> omap2plus_defconfig), but didn't have any of the boards with
> omap_phy_internal.o selected (OMAP_4430SDP, OMAP4_PANDA, PCM049, PCM049,
> OMAP3517EVM). Maybe this isn't a concern anyway, since anybody building
> with CONFIG_ARCH_OMAP4 will presumably also be building one of those
> boards? I don't know if it is our goal to build successfully with every
> wacky CONFIG_ combination, but I thought I would report it here just in
> case.

Probably the best way is to get omap specific randconfigs going based
on something what Arnd posted few days ago. Even with the old defconfig
files we'll still be missing many corner cases.

Regards,

Tony

^ permalink raw reply

* [PATCH 02/13] gpio/omap: Adapt GPIO driver to DT
From: Scott Wood @ 2011-09-28 18:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E82D7B3.6080909@ti.com>

On 09/28/2011 03:15 AM, Cousson, Benoit wrote:
> On 9/27/2011 7:40 AM, Nayak, Rajendra wrote:
>> On Monday 26 September 2011 10:20 PM, Benoit Cousson wrote:
>>> +Required properties:
>>> +- compatible:
>>> +  - "ti,omap2-gpio" for OMAP2 and OMAP3 controllers
>>
>> Would it be more readable to have
>> "ti,omap2-gpio" for OMAP2 controllers and
>> "ti,omap3-gpio" for OMAP3 controllers?

Or have OMAP3 say this if it's fully backwards compatible:

	compatible = "ti,omap3-gpio", "ti,omap2-gpio";

>>> +  - "ti,omap4-gpio" for OMAP4 controller
>>> +- #gpio-cells : Should be two.
>>> +  - first cell is the pin number
>>> +  - second cell is used to specify optional parameters (unused)
>>> +- gpio-controller : Marks the device node as a GPIO controller.
>>> +
>>> +OMAP specific properties:
>>> +- ti,hwmods: Name of the hwmod associated to the GPIO
>>> +- id: 32 bits to identify the id (1 based index)

What does "the id" mean, in relation to the actual hardware?

Some existing bindings have such a thing (often called "cell-index"),
but it should be well-defined what it refers to.  Often aliases would be
a better approach, if it just refers to what the manual calls the device.

>>> +- bank-width: number of pin supported by the controller (16 or 32)
>>> +- debounce: set if the controller support the debouce funtionnality
>>> +- bank-count: number of controller support by the SoC. This is a
>>> temporary
>>> +  hack until the bank_count is removed from the driver.
>>
>> Is there a general rule to be followed as to when to use
>> "ti,<prop-name>" and when to use just"<prop-name>".
>> Since all these are OMAP specific properties, shouldn't all
>> of them be "ti,<prop-name>"?
> 
> To be honest, I was wondering as well about this rule.
> I think that a property that is not purely OMAP specific and that
> represents some standard HW information does not have to be prefixed by
> "ti,XXX".
> So hwmods must be "ti,hwmods", but bank-witdh and bank-count seems to me
> quite generic.

It's about where the property is documented.  Suppose you use an
un-prefixed bank-width but define it in the TI-specific binding to mean
width in bits.  Later, someone wants something similar for another
driver, doesn't look at the TI binding, but says, "This is generic, I'll
define something in the main gpio binding," but defines it as width in
bytes (ignore the (de)merits of defining it that way in this case).  If
you had a namespace prefix, it would be clear which binding a node is
referring to.

As for bank-count, the description "this is a temporary hack until the
bank_count is removed from the driver" suggests it shouldn't be there at
all, much less be part of the generic binding.

-Scott

^ permalink raw reply

* [PATCH] arm/tegra: select AUTO_ZRELADDR by default
From: Stephen Warren @ 2011-09-28 17:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1317172068-14872-1-git-send-email-pdeschrijver@nvidia.com>

Peter De Schrijver wrote at Tuesday, September 27, 2011 7:08 PM:
> This patch causes the kernel uncompressor to determine the physical address
> of the SDRAM at runtime. This allows the kernel to boot on both tegra20 and
> tegra30 even though SDRAM is at different physical addresses on both SoCs.
> 
> Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>

An alternative would be to simply add that config option to the relevant
defconfig/.config file. I see both cases in use in the kernel. Still, the
code change this enables looks fine to just turn on all the time, and will
be needed for Tegra30 support, so I'm fine just selecting it as you have.

Acked-by: Stephen Warren <swarren@nvidia.com>

> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 472a7f8..474737b 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -596,6 +596,7 @@ config ARCH_TEGRA
>  	select HAVE_CLK
>  	select HAVE_SCHED_CLOCK
>  	select ARCH_HAS_CPUFREQ
> +	select AUTO_ZRELADDR
>  	help
>  	  This enables support for NVIDIA Tegra based systems (Tegra APX,
>  	  Tegra 6xx and Tegra 2 series).

P.S. Since this patch relates to Tegra, you should CC the Tegra maintainers
and list; I've done so on this message. I also added Arnd; he might take
this through the arm-soc tree.

-- 
nvpublic

^ permalink raw reply

* [PATCH v3 2/2] OMAP: omap_device: Add a method to build an omap_device from a DT node
From: Kevin Hilman @ 2011-09-28 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E834748.50908@ti.com>

"Cousson, Benoit" <b-cousson@ti.com> writes:

> Hi Grant, Kevin,
>
> Should I go ahead with this version and repost the series with that
> third patch?

Fine with me.

Grant let me know if you prefer if I merge it (with your ack) with the
rest of the series or if you want to take it to avoid conflicts.

Kevin

^ permalink raw reply

* [PATCH v4 3/3] arm/tegra: device tree support for ventana board
From: Stephen Warren @ 2011-09-28 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110928171151.GN21166@tbergstrom-lnx.Nvidia.com>

Peter De Schrijver wrote at Wednesday, September 28, 2011 11:12 AM:
> On Wed, Sep 28, 2011 at 03:16:42PM +0200, Arnd Bergmann wrote:
> > On Wednesday 28 September 2011, Peter De Schrijver wrote:
> > > --- a/arch/arm/mach-tegra/board-dt.c
...
> > > @@ -95,6 +95,8 @@ static void __init tegra_dt_init(void)
> > >                 harmony_pinmux_init();
> > >         else if (of_machine_is_compatible("nvidia,seaboard"))
> > >                 seaboard_pinmux_init();
> > > +       else if (of_machine_is_compatible("nvidia,ventana"))
> > > +               ventana_pinmux_init();
> >
> > Are you (Peter, Colin, Olof) confident that this is not getting out
> > of hand before it's getting better?
> >
> 
> We don't planning to add more derived boards besides ventana until we have the
> devicetree bindings for the new pinmux API in at which point this code
> will become obsolete.

Well, I think there will be one more; we're hoping to start uptreaming Tegra30
support soon, and the reference board for that will be Cardhu. That'll likely
happen before we have the initialize-pinmux-from-device-tree patches complete,
since I'm holding those off until we all think about whether the new pinmux API
core should be driving the initialization rather than individual pinmux drivers.

But, I hope Ventana and Cardhu will be the last before that's in place.

If not, we can certainly switch these if's to a table.

-- 
nvpublic

^ permalink raw reply

* [PATCH 2/2 v7] pinmux: add a driver for the U300 pinmux
From: Stephen Warren @ 2011-09-28 17:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdYx-iKPJisP7PgNynu9z3tu7s6KieFAoAOU2YO_5X2iqA@mail.gmail.com>

Linus Walleij wrote at Wednesday, September 28, 2011 5:59 AM:
> On Wed, Sep 28, 2011 at 2:15 AM, Stephen Warren <swarren@nvidia.com> wrote:
> 
> > But can't debugfs just get its information from the device name field in
> > the mapping table? I'm not sure why the need to use that information for
> > debugfs prevents the having entries with both the hog flag set and a
> > device name set?
> 
> That feels unsafe - then you have some string claiming to represent the
> device for that pinmux, but the system has not matched that string
> against dev_name() for any real device, so it could be a lie, any string
> like "foo" would do.
> 
> What I do now for U300 is complete resolution by matching dev_name
> in the mapping to dev_name(device) on the struct device * actually
> instantiated, which means you're 100% sure it is really mapped
> to that very device.
> 
> I like this since it's much more stringent...

OK, I can see the advantage, and I suppose one could still move
u300_pinmux_fetch() into the pinmux core as a helper function in the
future if needed without too much issue. If it's hard for some other
machine to set up the .dev entries in the table the function uses, one
can always fall back on system/non-device hog entries in the main
mapping table.

So I'll drop my objection to this.

-- 
nvpublic

^ permalink raw reply

* [PATCH v4 3/3] arm/tegra: device tree support for ventana board
From: Peter De Schrijver @ 2011-09-28 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201109281516.42513.arnd@arndb.de>

On Wed, Sep 28, 2011 at 03:16:42PM +0200, Arnd Bergmann wrote:
> On Wednesday 28 September 2011, Peter De Schrijver wrote:
> > --- a/arch/arm/mach-tegra/board-dt.c
> > +++ b/arch/arm/mach-tegra/board-dt.c
> > @@ -47,7 +47,7 @@
> >  
> >  void harmony_pinmux_init(void);
> >  void seaboard_pinmux_init(void);
> > -
> > +void ventana_pinmux_init(void);
> >  
> >  struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
> >         OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
> > @@ -95,6 +95,8 @@ static void __init tegra_dt_init(void)
> >                 harmony_pinmux_init();
> >         else if (of_machine_is_compatible("nvidia,seaboard"))
> >                 seaboard_pinmux_init();
> > +       else if (of_machine_is_compatible("nvidia,ventana"))
> > +               ventana_pinmux_init();
> 
> Are you (Peter, Colin, Olof) confident that this is not getting out
> of hand before it's getting better?
> 

We don't planning to add more derived boards besides ventana until we have the
devicetree bindings for the new pinmux API in at which point this code
will become obsolete.

Cheers,

Peter.

^ permalink raw reply

* MAC firmware does not load due to (commit 288d5abe usermodehelper)
From: Richard Cochran @ 2011-09-28 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CA+55aFy4aZPdUNBR0O3SP1iRRJyeF9kPZxH9G_eYdxueYskF4g@mail.gmail.com>

On Wed, Sep 28, 2011 at 08:21:05AM -0700, Linus Torvalds wrote:
> 
> Something seems to be calling ioctl() befor rest_init() has even
> completed. Which sounds odd, but I wonder if the schedule() there
> before it might have let 'init' get going.

It does look like it. The init is busybox, and the startup script does
mount, syslogd, and then ifup, so that all can go by quickly.

> Does something like the attached (UNTESTED) fix it?

Yup, problem cured.

Thanks,
Richard

^ permalink raw reply

* [PATCH v3 2/2] OMAP: omap_device: Add a method to build an omap_device from a DT node
From: Cousson, Benoit @ 2011-09-28 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E81F42B.5070806@ti.com>

Hi Grant, Kevin,

Should I go ahead with this version and repost the series with that 
third patch?

Thanks,
Benoit


On 9/27/2011 6:04 PM, Cousson, Benoit wrote:

[...]

> From 4403f8a00090e5ea1814a5242947b81c348947a1 Mon Sep 17 00:00:00 2001
> From: Benoit Cousson<b-cousson@ti.com>
> Date: Tue, 27 Sep 2011 17:45:43 +0200
> Subject: [PATCH] of: Add helpers to get one string in multiple strings property
>
> Add of_property_read_string_index and of_property_count_strings
> to retrieve one string inside a property that will contains
> severals strings.
>
> Signed-off-by: Benoit Cousson<b-cousson@ti.com>
> ---
>   drivers/of/base.c  |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>   include/linux/of.h |   18 +++++++++++
>   2 files changed, 103 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 3ff22e3..d97d53e 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -662,6 +662,91 @@ int of_property_read_string(struct device_node *np, const char *propname,
>   EXPORT_SYMBOL_GPL(of_property_read_string);
>
>   /**
> + * of_property_read_string_index - Find and read a string from a multiple
> + * strings property.
> + * @np:		device node from which the property value is to be read.
> + * @propname:	name of the property to be searched.
> + * @index:	index of the string in the list of strings
> + * @out_string:	pointer to null terminated return string, modified only if
> + *		return value is 0.
> + *
> + * Search for a property in a device tree node and retrieve a null
> + * terminated string value (pointer to data, not a copy) in the list of strings
> + * contained in that property.
> + * Returns 0 on
> + * success, -EINVAL if the property does not exist, -ENODATA if property
> + * does not have a value, and -EILSEQ if the string is not null-terminated
> + * within the length of the property data.
> + *
> + * The out_string pointer is modified only if a valid string can be decoded.
> + */
> +int of_property_read_string_index(struct device_node *np, const char *propname,
> +				  int index, const char **output)
> +{
> +	struct property *prop = of_find_property(np, propname, NULL);
> +	int i = 0;
> +	size_t l = 0, total = 0;
> +	const char *p;
> +
> +	if (!prop)
> +		return -EINVAL;
> +	if (!prop->value)
> +		return -ENODATA;
> +	if (strnlen(prop->value, prop->length)>= prop->length)
> +		return -EILSEQ;
> +
> +	p = prop->value;
> +
> +	for (i = 0; total<  prop->length; total += l, p += l) {
> +		l = strlen(p) + 1;
> +		if ((*p != 0)&&  (i++ == index)) {
> +			*output = p;
> +			return 0;
> +		}
> +	}
> +	return -ENODATA;
> +}
> +EXPORT_SYMBOL_GPL(of_property_read_string_index);
> +
> +
> +/**
> + * of_property_count_strings - Find and return the number of strings from a
> + * multiple strings property.
> + * @np:		device node from which the property value is to be read.
> + * @propname:	name of the property to be searched.
> + *
> + * Search for a property in a device tree node and retrieve the number of null
> + * terminated string contain in it. Returns the number of strings on
> + * success, -EINVAL if the property does not exist, -ENODATA if property
> + * does not have a value, and -EILSEQ if the string is not null-terminated
> + * within the length of the property data.
> + */
> +int of_property_count_strings(struct device_node *np, const char *propname)
> +{
> +	struct property *prop = of_find_property(np, propname, NULL);
> +	int i = 0;
> +	size_t l = 0, total = 0;
> +	const char *p;
> +
> +	if (!prop)
> +		return -EINVAL;
> +	if (!prop->value)
> +		return -ENODATA;
> +	if (strnlen(prop->value, prop->length)>= prop->length)
> +		return -EILSEQ;
> +
> +	p = prop->value;
> +
> +	for (i = 0; total<  prop->length; total += l, p += l) {
> +		l = strlen(p) + 1;
> +		if (*p != 0)
> +			i++;
> +	}
> +	return i;
> +}
> +EXPORT_SYMBOL_GPL(of_property_count_strings);
> +
> +/**
>    * of_parse_phandle - Resolve a phandle property to a device_node pointer
>    * @np: Pointer to device node holding phandle property
>    * @phandle_name: Name of property holding a phandle value
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 9180dc5..9eadc4e 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -203,6 +203,11 @@ extern int of_property_read_u32_array(const struct device_node *np,
>   extern int of_property_read_string(struct device_node *np,
>   				   const char *propname,
>   				   const char **out_string);
> +extern int of_property_read_string_index(struct device_node *np,
> +					 const char *propname,
> +					 int index, const char **output);
> +extern int of_property_count_strings(struct device_node *np,
> +				     const char *propname);
>   extern int of_device_is_compatible(const struct device_node *device,
>   				   const char *);
>   extern int of_device_is_available(const struct device_node *device);
> @@ -256,6 +261,19 @@ static inline int of_property_read_string(struct device_node *np,
>   	return -ENOSYS;
>   }
>
> +static inline int of_property_read_string_index(struct device_node *np,
> +						const char *propname, index,
> +						const char **out_string)
> +{
> +	return -ENOSYS;
> +}
> +
> +static inline int of_property_count_strings(struct device_node *np,
> +					    const char *propname)
> +{
> +	return -ENOSYS;
> +}
> +
>   static inline const void *of_get_property(const struct device_node *node,
>   				const char *name,
>   				int *lenp)

^ permalink raw reply

* Perf support for OMAP4
From: Will Deacon @ 2011-09-28 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tom,

I can't see your OMAP4 Perf/PMU patches from here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2011-March/045283.html

in mainline or next.

Are you still pushing these or did you get blocked awaiting feedback?

Cheers,

Will

^ permalink raw reply

* [PATCH v3 3/6] OMAP3+: use DPLL's round_rate when setting rate
From: Jon Hunter @ 2011-09-28 15:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1109280059380.4399@utopia.booyaka.com>

Hi Paul,

On 9/28/2011 2:02, Paul Walmsley wrote:
> Hi,
>
> On Fri, 16 Sep 2011, Jon Hunter wrote:
>
>> From: Mike Turquette<mturquette@ti.com>
>>
>> omap3_noncore_dpll_set_rate uses omap2_dpll_round_rate explicitly.  Instead
>> use the struct clk pointer's round_rate function to allow for DPLL's with
>> special needs.
>>
>> Also the rounded rate can differ from target rate, so to better reflect
>> reality set clk->rate equal to the rounded rate when setting DPLL frequency.
>> This avoids issues where the DPLL frequency is slightly different than what
>> debugfs clock tree reports using the old target rate.
>>
>> An example of both of these needs is DPLL_ABE on OMAP4 which can have a 4x
>> multiplier on top of the usual MN dividers depending on register settings.
>> This requires a special round_rate function that might yield a rate
>> different from the initial target.
>>
>> Signed-off-by: Mike Turquette<mturquette@ti.com>
>> Signed-off-by: Jon Hunter<jon-hunter@ti.com>
>
> The two separate changes in this patch have been separated out into two
> patches - both included below.  Please let me know if you have any
> comments; otherwise, I'll queue for 3.2.

Yes, looks good to me. Thanks. Jon

^ permalink raw reply

* [PATCH v2 07/16] ARM: GIC: Add global gic_handle_irq_offset() function
From: Rob Herring @ 2011-09-28 15:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1317034955-1029-8-git-send-email-marc.zyngier@arm.com>

On 09/26/2011 06:02 AM, Marc Zyngier wrote:
> Similar to gic_handle_irq(), gic_handle_irq_offset() is provided
> for those platform who insist on having their GIC base interrupt
> at something different from zero. At the moment, Exynos4 is the
> only one...
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/common/gic.c               |   24 ++++++++++++++++++++++++
>  arch/arm/include/asm/hardware/gic.h |    1 +
>  2 files changed, 25 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 5a22896..ef803d2 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -232,6 +232,30 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>  	} while (1);
>  }
>  
> +asmlinkage void __exception_irq_entry gic_handle_irq_offset(struct pt_regs *regs)
> +{
> +	u32 irqstat, irqnr;
> +	u32 offset = gic_data[0].irq_offset;
> +
> +	do {
> +		irqstat = readl_relaxed(gic_cpu_base_addr + GIC_CPU_INTACK);
> +		irqnr = irqstat & ~0x1c00;
> +
> +		if (likely(irqnr > 15 && irqnr < 1021)) {
> +			handle_IRQ(irqnr + offset, regs);

Can't this be combined with gic_handle_irq. irq_offset will be 0 in that
case. Really, irq_domain should be used here.

Rob

> +			continue;
> +		}
> +		if (irqnr < 16) {
> +			writel_relaxed(irqstat, gic_cpu_base_addr + GIC_CPU_EOI);
> +#ifdef CONFIG_SMP
> +			handle_IPI(irqnr, regs);
> +#endif
> +			continue;
> +		}
> +		break;
> +	} while (1);
> +}
> +
>  static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
>  {
>  	struct gic_chip_data *chip_data = irq_get_handler_data(irq);
> diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
> index 45e4ab4..0f454c6 100644
> --- a/arch/arm/include/asm/hardware/gic.h
> +++ b/arch/arm/include/asm/hardware/gic.h
> @@ -39,6 +39,7 @@ extern struct irq_chip gic_arch_extn;
>  void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
>  void gic_secondary_init(unsigned int);
>  void gic_handle_irq(struct pt_regs *regs);
> +void gic_handle_irq_offset(struct pt_regs *regs);
>  void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
>  void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
>  

^ permalink raw reply

* [PATCH] arm: Add VIRTUALIZATION configuration menu and virtio options
From: Pawel Moll @ 2011-09-28 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds menuconfig VIRTUALIZATION to arm Kconfig
and includes virtio Kconfig in it.

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
 arch/arm/Kconfig |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3269576..426f330 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2101,4 +2101,20 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
+menuconfig VIRTUALIZATION
+	bool "Virtualization"
+	default n
+	---help---
+	  Say Y here to get to see options for using your Linux host to run other
+	  operating systems inside virtual machines (guests).
+	  This option alone does not add any kernel code.
+
+	  If you say N, all options in this submenu will be skipped and disabled.
+
+if VIRTUALIZATION
+
+source drivers/virtio/Kconfig
+
+endif # VIRTUALIZATION
+
 source "lib/Kconfig"
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH v2 2/6] OMAP4: Clock: round_rate and recalc functions for DPLL_ABE
From: Jon Hunter @ 2011-09-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1109280056570.4399@utopia.booyaka.com>

Hi Paul,

On 9/28/2011 1:59, Paul Walmsley wrote:
> Hi Jon and Mike,
>
> On Fri, 16 Sep 2011, Jon Hunter wrote:
>
>> From: Mike Turquette<mturquette@ti.com>
>>
>> OMAP4 DPLL_ABE can enable a 4X multipler on top of the normal MN multipler
>> and divider. This is achieved by setting CM_CLKMODE_DPLL_ABE.DPLL_REGM4XEN
>> bit in CKGEN module of CM1. From the OMAP4 TRM:
>>
>> Fdpll = Fref x 2 x (4 x M/(N+1)) in case REGM4XEN bit field is set (only
>> applicable to DPLL_ABE).
>>
>> Add new round_rate() and recalc() functions for OMAP4, that check the
>> setting of REGM4XEN bit and handle this appropriately. The new functions
>> are a simple wrapper on top of the existing omap2_dpll_round_rate() and
>> omap2_dpll_get_rate() functions to handle the REGM4XEN bit.
>>
>> The REGM4XEN bit is only implemented for the ABE DPLL on OMAP4 and so
>> only dpll_abe_ck uses omap4_dpll_regm4xen_round_rate() and
>> omap4_dpll_regm4xen_recalc() functions.
>>
>> Signed-off-by: Mike Turquette<mturquette@ti.com>
>> Tested-by: Jon Hunter<jon-hunter@ti.com>
>
> Some changes have been made to this patch here, to fix a few minor bugs in
> error paths and to add documentation and Jon's Signed-off-by: (since he's
> in the submittal chain).
>
> Care to review and send any comments?  Otherwise, I plan to queue this
> revised version for 3.2.

Looks good to me. Thanks for fixes and documentation.

Cheers
Jon

^ permalink raw reply

* nr_cpus cmdline parameter not working
From: Mark Salter @ 2011-09-28 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

I noticed that nr_cpus=1 doesn't appear to have any effect on a
pandaboard (and probably others from the looks of things). This
changes seems to be needed, but I'm not really sure if this is
the right thing or not.

diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ce65e93..a1198ac 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -117,6 +117,9 @@ void __init smp_init_cpus(void)
 		ncores = NR_CPUS;
 	}
 
+	if (ncores > nr_cpu_ids)
+		ncores = nr_cpu_ids;
+
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);

--Mark

^ permalink raw reply related

* MAC firmware does not load due to (commit 288d5abe usermodehelper)
From: Linus Torvalds @ 2011-09-28 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110928120630.GB9456@netboy.at.omicron.at>

On Wed, Sep 28, 2011 at 5:06 AM, Richard Cochran
<richardcochran@gmail.com> wrote:
>
> A warning appears on the console, shown below. ?I don't know what
> commit 288d5abe was trying to fix, but it sure made a regression for
> me. It probably would also spoil using NFS boot, too.
>
> Any ideas what to do about this?

Something seems to be calling ioctl() befor rest_init() has even
completed. Which sounds odd, but I wonder if the schedule() there
before it might have let 'init' get going.

Does something like the attached (UNTESTED) fix it?

                             Linus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.diff
Type: text/x-patch
Size: 678 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110928/ab9b1404/attachment.bin>

^ permalink raw reply

* [PATCH] virtio: Add platform bus driver for memory mapped virtio device
From: Pawel Moll @ 2011-09-28 13:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1317217663-32647-1-git-send-email-pawel.moll@arm.com>

> So here I am with the first non-RFC patch :-) It will be followed by the
> spec, as we discussed, in the form of an appendix to the main document.

Here it goes than... It's LaTeX so Rusty can easily get it into his
spec, hope it's readable enough - if not I can provide a PDF.

8<---------------------------------------------------------------------

\documentclass[12pt]{article}

\begin{document}

Virtual environments without PCI support (a common situation in embedded
devices models) might use simple memory mapped device (``virtio-mmio'')
instead of the PCI device.

The memory mapped virtio device behaviour is based on the PCI device
specification. Therefore most of operations like device initialization,
queues configuration and buffer transfers are nearly identical. Existing
differences are described in the following sections. 

\subsection{Device Initialization}

Instead of using the PCI IO space for virtio header, the ``virtio-mmio''
device provides a set of memory mapped control registers, all 32 bits
wide, followed by device-specific configuration space. The following
list presents their layout: 

\begin{itemize}
\item Offset from the device base address | Direction | Name \\
Description
\item 0x000 | R | MagicValue \\
``virt'' string.
\item 0x004 | R | Version \\
Device version number. Currently must be 1.
\item 0x008 | R | DeviceID \\
Virtio Subsystem Device ID (ie. 1 for network card).
\item 0x00c | R | VendorID \\
Virtio Subsystem Vendor ID.
\item 0x010 | R | HostFeatures \\
Flags representing features the device supports.\\
Reading from this register returns 32 consecutive flag bits, first bit
depending on the last value written to HostFeaturesSel register.  Access
to this register returns bits $HostFeaturesSel*32$ to
$(HostFeaturesSel*32)+31$, eg. feature bits 0 to 31 if HostFeaturesSel
is set to 0 and features bits 32 to 63 if HostFeaturesSel is set to 1.
Also see p. 2.2.2.2 ``Feature Bits''.
\item 0x014 | W | HostFeaturesSel \\
Device (Host) features word selection.\\
Writing to this register selects a set of 32 device feature bits
accessible by reading from HostFeatures register. Device driver must
write a value to the HostFeaturesSel register before reading from the
HostFeatures register.
\item 0x020 | W | GuestFeatures \\
Flags representing device features understood and activated by the
driver.\\
Writing to this register sets 32 consecutive flag bits, first bit
depending on the last value written to GuestFeaturesSel register. Access
to this register sets bits $GuestFeaturesSel*32$ to
$(GuestFeaturesSel*32)+31$, eg. feature bits 0 to 31 if GuestFeaturesSel
is set to 0 and features bits 32 to 63 if GuestFeaturesSel is set to 1.\
\
Also see p. 2.2.2.2 ``Feature Bits''.
\item 0x024 | W | GuestFeaturesSel \\
Activated (Guest) features word selection.\\
Writing to this register selects a set of 32 activated feature bits
accessible by writing to the GuestFeatures register. Device driver must
write a value to the GuestFeaturesSel register before writing to the
GuestFeatures register.
\item 0x028 | W | GuestPageSize \\
Guest page size.\\
Device driver must write the guest page size in bytes to the register
during initialization, before any queues are used.
\item 0x030 | W | QueueSel \\
Virtual queue index (first queue is 0).\\
Writing to this register selects the virtual queue that the following
operations on QueueNum, QueueAlign and QueuePFN apply to.
\item 0x034 | RW | QueueNum \\
Virtual queue size (number of elements in the queue, therefore size of
the descriptor table and both available and used rings).\\
Writing to this register notifies the Host what size of the queue the
Guest would like to use.\\
Reading from the register returns the queue size that the Host is ready
to process (might be different than the requested size) or zero (0x0) if
queue is not available.\\
Both read and write accesses apply to the queue selected by writing to
QueueSel.
\item 0x038 | W | QueueAlign \\
Used Ring alignment in the virtual queue.\\
Writing to this register notifies the Host about alignment boundary of
the Used Ring in bytes. This applies to the queue selected by writing to
QueueSel.
\item 0x03c | RW | QueuePFN \\
Guest physical page number of the virtual queue.\\
Writing to this register notifies the host about location of the virtual
queue in the Guest's physical address space. This value is the index
number of a page starting with the queue Descriptor Table.  Value zero
(0x0) means physical address zero (0x00000000) and is illegal. When the
Guest stops using the queue it must write zero (0x0) to this register.\\
Reading from this register returns the currently used page number of the
queue, therefore a value other than zero (0x0) means that the queue is
in use.\\
Both read and write accesses apply to the queue selected by writing to
QueueSel.
\item 0x050 | W | QueueNotify \\
Queue notifier.\\
Writing a queue index to this register notifies the Host that there are
new buffers to process in the queue.
\item 0x060 | W | InterruptACK \\
Interrupt acknowledge. \\
Writing to this register notifies the Host that the Guest finished
receiving used buffers from the device and therefore serviced an
asserted interrupt. Values written to this register are currently not
used, but for future extensions it must be set to one (0x1).
\item 0x070 | RW | Status \\
Device status. \\
Reading from this register returns the current device status flags. \\
Writing non-zero values to this register sets the status flags,
indicating the Guest progress. Writing zero (0x0) to this register
triggers a device reset. \\
Also see p. 2.2.2.1 ``Device Status''.
\item 0x100+ | RW | Config \\
Device-specific configuration space starts@an offset 0x100 and is
accessed with byte alignment. Its meaning and size depends on the device
and the driver.
\end{itemize}

The endianness of the registers follows the native endianness of the
Guest. Writing to registers described as ``R'' and reading from
registers described as ``W'' is not permitted and can cause undefined
behavior.

The device initialization is performed as described in p. 2.2.1 ``Device
Initialization Sequence'' with one exception: the Guest must notify the
Host about its page size, writing the size in bytes to GuestPageSize
register before the initialization is finished.

The memory mapped virtio devices generate single interrupt only,
therefore no special configuration is required.


\subsection{Virtqueue Configuration}

The virtual queue configuration is performed in a similar way to the one
described in p 2.3 ``Virtqueue Configuration'' with a few additional
operations:
\begin{enumerate}
\item Write the queue index (first queue is 0) to the QueueSel register.
\item Check if the queue is not already in use: read QueuePFN register,
returned value should be zero (0x0).
\item Optionally write requested queue size to QueueNum register. If
this is not done, the Host uses the default, device specific, queue
size.
\item Read configured queue size from the QueueNum register. Note that
it might be different from the size requested in previous step.
\item Allocate and zero the queue in contiguous virtual memory, aligning
the Used Ring to an optimal boundary (usually page size).
\item Notify the Host about the used alignment by writing its value in
bytes to QueueAlign register.
\item Write the physical number of the first page of the queue to the
QueuePFN register.
\end{enumerate}
The queue and the device are ready to begin normal operations now.


\subsection{Device Operation}

The memory mapped virtio device behaves in the same way as described in
p. 2.4 ``Device Operation'', with the following exceptions:
\begin{enumerate}
\item The device is notified about new buffers available in a queue by
writing the queue index to register QueueNum instead of the virtio
header in PCI I/O space (p. 2.4.1.4 ``Notifying The Device'').
\item As the memory mapped virtio device is using single, dedicated
interrupt signal, its handling is much simpler than in the PCI (MSI-X)
case (p.  2.4.2 ``Receiving Used Buffer From The Device''). Therefore
all the Guest interrupt handler should do after receiving used buffers
is acknowledging the interrupt by writing a value to the InterruptACK
register. Currently this value does not carry any meaning, but for
future extensions it must be set to one (0x1).
\item The dynamic configuration changes, as described in p. 2.4.3
``Dealing With Configuration Changes'' are not permitted.
\end{enumerate}

\end{document}


8<---------------------------------------------------------------------

Cheers!

Pawe?

^ permalink raw reply

* [PATCH] virtio: Add platform bus driver for memory mapped virtio device
From: Pawel Moll @ 2011-09-28 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

This patch, based on virtio PCI driver, adds support for memory
mapped (platform) virtio device. This should allow environments
like qemu to use virtio-based block & network devices even on
platforms without PCI support.

One can define and register a platform device which resources
will describe memory mapped control registers and "mailbox"
interrupt. Such device can be also instantiated using the Device
Tree node with compatible property equal "virtio,mmio".

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Cc: Michael S.Tsirkin <mst@redhat.com>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---

So here I am with the first non-RFC patch :-) It will be followed by the
spec, as we discussed, in the form of an appendix to the main document.

Comparing to RFCv3 I've added "version" register, to make the device's
evolution easier. I hope the code is good enough for next merge window,
if you think otherwise - please, do shout! ;-)

If there are no objections I'll ask Peter to start adding support for
this into qemu. I've tested the driver with a virtio block device in
our proprietary emulation environment and it works just fine :-)

Cheers!

Pawel

 Documentation/devicetree/bindings/virtio/mmio.txt |   17 +
 drivers/virtio/Kconfig                            |   11 +
 drivers/virtio/Makefile                           |    1 +
 drivers/virtio/virtio_mmio.c                      |  459 +++++++++++++++++++++
 include/linux/virtio_mmio.h                       |   92 ++++
 5 files changed, 580 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/virtio/mmio.txt
 create mode 100644 drivers/virtio/virtio_mmio.c
 create mode 100644 include/linux/virtio_mmio.h

diff --git a/Documentation/devicetree/bindings/virtio/mmio.txt b/Documentation/devicetree/bindings/virtio/mmio.txt
new file mode 100644
index 0000000..5069c1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/virtio/mmio.txt
@@ -0,0 +1,17 @@
+* virtio memory mapped device
+
+See http://ozlabs.org/~rusty/virtio-spec/ for more details.
+
+Required properties:
+
+- compatible:	"virtio,mmio" compatibility string
+- reg:		control registers base address and size including configuration space
+- interrupts:	interrupt generated by the device
+
+Example:
+
+	virtio_block at 3000 {
+		compatible = "virtio,mmio";
+		reg = <0x3000 0x100>;
+		interrupts = <41>;
+	}
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 57e493b..816ed08 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -35,4 +35,15 @@ config VIRTIO_BALLOON
 
 	 If unsure, say M.
 
+ config VIRTIO_MMIO
+ 	tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
+ 	select VIRTIO
+ 	select VIRTIO_RING
+ 	---help---
+ 	 This drivers provides support for memory mapped virtio
+	 platform device driver.
+
+ 	 If unsure, say N.
+
 endmenu
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 6738c44..5a4c63c 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_VIRTIO) += virtio.o
 obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o
+obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
 obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
new file mode 100644
index 0000000..3c8d52f
--- /dev/null
+++ b/drivers/virtio/virtio_mmio.c
@@ -0,0 +1,459 @@
+/*
+ * Virtio memory mapped device driver
+ *
+ * Copyright 2011, ARM Ltd.
+ *
+ * This module allows virtio devices to be used over a virtual, memory mapped
+ * platform device.
+ *
+ * Registers layout (all 32-bit wide):
+ *
+ * offset name             description
+ * ------ ---------------- -----------------
+ *
+ *  0x000 MagicValue       Magic value "virt"
+ *  0x004 Version          Device version (current max. 1)
+ *  0x008 DeviceID         Virtio device ID
+ *  0x00c VendorID         Virtio vendor ID
+ *
+ *  0x010 HostFeatures     Features supported by the host
+ *  0x014 HostFeaturesSel  Set of host features to access via HostFeatures
+ *
+ *  0x020 GuestFeatures    Features activated by the guest
+ *  0x024 GuestFeaturesSel Set of activated features to set via GuestFeatures
+ *  0x028 GuestPageSize    Size of guest's memory page in bytes
+ *
+ *  0x030 QueueSel         Queue selector
+ *  0x034 QueueNum         Queue size for the currently selected queue
+ *  0x038 QueueAlign       Used Ring alignment for the current queue
+ *  0x03c QueuePFN         PFN for the currently selected queue
+
+ *  0x050 QueueNotify      Queue notifier
+ *  0x060 InterruptACK     Interrupt acknowledge register
+ *  0x070 Status           Device status register
+ *
+ *  0x100+                 Device-specific configuration space
+ *
+ * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_mmio.h>
+#include <linux/virtio_ring.h>
+
+
+
+/* The alignment to use between consumer and producer parts of vring.
+ * Currently hardcoded to page size. */
+#define VIRTIO_MMIO_VRING_ALIGN		PAGE_SIZE
+
+
+
+#define to_virtio_mmio_device(_plat_dev) \
+	container_of(_plat_dev, struct virtio_mmio_device, vdev)
+
+struct virtio_mmio_device {
+	struct virtio_device vdev;
+	struct platform_device *pdev;
+
+	void __iomem *base;
+	unsigned long version;
+
+	/* a list of queues so we can dispatch IRQs */
+	spinlock_t lock;
+	struct list_head virtqueues;
+};
+
+struct virtio_mmio_vq_info {
+	/* the actual virtqueue */
+	struct virtqueue *vq;
+
+	/* the number of entries in the queue */
+	int num;
+
+	/* the index of the queue */
+	int queue_index;
+
+	/* the virtual address of the ring queue */
+	void *queue;
+
+	/* the list node for the virtqueues list */
+	struct list_head node;
+};
+
+
+
+/* Configuration interface */
+
+static u32 vm_get_features(struct virtio_device *vdev)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+	/* TODO: Features > 32 bits */
+	writel(0, vm_dev->base + VIRTIO_MMIO_HOST_FEATURES_SEL);
+
+	return readl(vm_dev->base + VIRTIO_MMIO_HOST_FEATURES);
+}
+
+static void vm_finalize_features(struct virtio_device *vdev)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	int i;
+
+	/* Give virtio_ring a chance to accept features. */
+	vring_transport_features(vdev);
+
+	for (i = 0; i < ARRAY_SIZE(vdev->features); i++) {
+		writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET);
+		writel(vdev->features[i],
+				vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES);
+	}
+}
+
+static void vm_get(struct virtio_device *vdev, unsigned offset,
+		   void *buf, unsigned len)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	u8 *ptr = buf;
+	int i;
+
+	for (i = 0; i < len; i++)
+		ptr[i] = readb(vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i);
+}
+
+static void vm_set(struct virtio_device *vdev, unsigned offset,
+		   const void *buf, unsigned len)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	const u8 *ptr = buf;
+	int i;
+
+	for (i = 0; i < len; i++)
+		writeb(ptr[i], vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i);
+}
+
+static u8 vm_get_status(struct virtio_device *vdev)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+	return readl(vm_dev->base + VIRTIO_MMIO_STATUS) & 0xff;
+}
+
+static void vm_set_status(struct virtio_device *vdev, u8 status)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+	/* We should never be setting status to 0. */
+	BUG_ON(status == 0);
+
+	writel(status, vm_dev->base + VIRTIO_MMIO_STATUS);
+}
+
+static void vm_reset(struct virtio_device *vdev)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+	/* 0 status means a reset. */
+	writel(0, vm_dev->base + VIRTIO_MMIO_STATUS);
+}
+
+
+
+/* Transport interface */
+
+/* the notify function used when creating a virt queue */
+static void vm_notify(struct virtqueue *vq)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
+	struct virtio_mmio_vq_info *info = vq->priv;
+
+	/* We write the queue's selector into the notification register to
+	 * signal the other end */
+	writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY);
+}
+
+/* Notify all virtqueues on an interrupt. */
+static irqreturn_t vm_interrupt(int irq, void *opaque)
+{
+	struct virtio_mmio_device *vm_dev = opaque;
+	struct virtio_mmio_vq_info *info;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned long flags;
+
+	writel(1, vm_dev->base + VIRTIO_MMIO_INTERRUPT_ACK);
+
+	spin_lock_irqsave(&vm_dev->lock, flags);
+	list_for_each_entry(info, &vm_dev->virtqueues, node) {
+		if (vring_interrupt(irq, info->vq) == IRQ_HANDLED)
+			ret = IRQ_HANDLED;
+	}
+	spin_unlock_irqrestore(&vm_dev->lock, flags);
+
+	return ret;
+}
+
+
+
+static void vm_del_vq(struct virtqueue *vq)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
+	struct virtio_mmio_vq_info *info = vq->priv;
+	unsigned long flags, size;
+
+	spin_lock_irqsave(&vm_dev->lock, flags);
+	list_del(&info->node);
+	spin_unlock_irqrestore(&vm_dev->lock, flags);
+
+	vring_del_virtqueue(vq);
+
+	/* Select and deactivate the queue */
+	writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
+	writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+
+	size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
+	free_pages_exact(info->queue, size);
+	kfree(info);
+}
+
+static void vm_del_vqs(struct virtio_device *vdev)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	struct virtqueue *vq, *n;
+
+	list_for_each_entry_safe(vq, n, &vdev->vqs, list)
+		vm_del_vq(vq);
+
+	free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
+}
+
+
+
+static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
+				  void (*callback)(struct virtqueue *vq),
+				  const char *name)
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	struct virtio_mmio_vq_info *info;
+	struct virtqueue *vq;
+	unsigned long flags, size;
+	u16 num;
+	int err;
+
+	/* Select the queue we're interested in */
+	writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
+
+	/* TODO: Write requested queue size to VIRTIO_MMIO_QUEUE_NUM */
+
+	/* Check if queue is either not available or already active. */
+	num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
+	if (!num || readl(vm_dev->base + VIRTIO_MMIO_QUEUE_PFN)) {
+		err = -ENOENT;
+		goto error_available;
+	}
+
+	/* Allocate and fill out our structure the represents an active
+	 * queue */
+	info = kmalloc(sizeof(struct virtio_mmio_vq_info), GFP_KERNEL);
+	if (!info) {
+		err = -ENOMEM;
+		goto error_kmalloc;
+	}
+
+	info->queue_index = index;
+	info->num = num;
+
+	size = PAGE_ALIGN(vring_size(num, VIRTIO_MMIO_VRING_ALIGN));
+	info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
+	if (info->queue == NULL) {
+		err = -ENOMEM;
+		goto error_alloc_pages;
+	}
+
+	/* Activate the queue */
+	writel(VIRTIO_MMIO_VRING_ALIGN,
+			vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
+	writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
+			vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+
+	/* Create the vring */
+	vq = vring_new_virtqueue(info->num, VIRTIO_MMIO_VRING_ALIGN,
+				 vdev, info->queue, vm_notify, callback, name);
+	if (!vq) {
+		err = -ENOMEM;
+		goto error_new_virtqueue;
+	}
+
+	vq->priv = info;
+	info->vq = vq;
+
+	spin_lock_irqsave(&vm_dev->lock, flags);
+	list_add(&info->node, &vm_dev->virtqueues);
+	spin_unlock_irqrestore(&vm_dev->lock, flags);
+
+	return vq;
+
+error_new_virtqueue:
+	writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+	free_pages_exact(info->queue, size);
+error_alloc_pages:
+	kfree(info);
+error_kmalloc:
+error_available:
+	return ERR_PTR(err);
+}
+
+static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+		       struct virtqueue *vqs[],
+		       vq_callback_t *callbacks[],
+		       const char *names[])
+{
+	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	unsigned int irq = platform_get_irq(vm_dev->pdev, 0);
+	int i, err;
+
+	err = request_irq(irq, vm_interrupt, IRQF_SHARED,
+			dev_name(&vdev->dev), vm_dev);
+	if (err)
+		return err;
+
+	for (i = 0; i < nvqs; ++i) {
+		vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i]);
+		if (IS_ERR(vqs[i])) {
+			vm_del_vqs(vdev);
+			free_irq(irq, vm_dev);
+			return PTR_ERR(vqs[i]);
+		}
+	}
+
+	return 0;
+}
+
+
+
+static struct virtio_config_ops virtio_mmio_config_ops = {
+	.get		= vm_get,
+	.set		= vm_set,
+	.get_status	= vm_get_status,
+	.set_status	= vm_set_status,
+	.reset		= vm_reset,
+	.find_vqs	= vm_find_vqs,
+	.del_vqs	= vm_del_vqs,
+	.get_features	= vm_get_features,
+	.finalize_features = vm_finalize_features,
+};
+
+
+
+/* Platform device */
+
+static int __devinit virtio_mmio_probe(struct platform_device *pdev)
+{
+	struct virtio_mmio_device *vm_dev;
+	struct resource *mem;
+	unsigned long magic;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -EINVAL;
+
+	if (!devm_request_mem_region(&pdev->dev, mem->start,
+			resource_size(mem), pdev->name))
+		return -EBUSY;
+
+	vm_dev = devm_kzalloc(&pdev->dev, sizeof(struct virtio_mmio_device),
+			GFP_KERNEL);
+	if (!vm_dev)
+		return  -ENOMEM;
+
+	vm_dev->vdev.dev.parent = &pdev->dev;
+	vm_dev->vdev.config = &virtio_mmio_config_ops;
+	vm_dev->pdev = pdev;
+	INIT_LIST_HEAD(&vm_dev->virtqueues);
+	spin_lock_init(&vm_dev->lock);
+
+	vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+	if (vm_dev->base == NULL)
+		return -EFAULT;
+
+	/* Check magic value */
+	magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
+	if (memcmp(&magic, "virt", 4) != 0) {
+		dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
+		return -ENODEV;
+	}
+
+	/* Check device version */
+	vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION);
+	if (vm_dev->version != 1) {
+		dev_err(&pdev->dev, "Version %ld not supported!\n",
+				vm_dev->version);
+		return -ENXIO;
+	}
+
+	vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
+	vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
+
+	writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
+
+	platform_set_drvdata(pdev, vm_dev);
+
+	return register_virtio_device(&vm_dev->vdev);
+}
+
+static int __devexit virtio_mmio_remove(struct platform_device *pdev)
+{
+	struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev);
+
+	unregister_virtio_device(&vm_dev->vdev);
+
+	return 0;
+}
+
+
+
+/* Platform driver */
+
+static struct of_device_id virtio_mmio_match[] = {
+	{ .compatible = "virtio,mmio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, virtio_mmio_match);
+
+static struct platform_driver virtio_mmio_driver = {
+	.probe		= virtio_mmio_probe,
+	.remove		= __devexit_p(virtio_mmio_remove),
+	.driver		= {
+		.name	= "virtio-mmio",
+		.owner	= THIS_MODULE,
+		.of_match_table	= virtio_mmio_match,
+	},
+};
+
+static int __init virtio_mmio_init(void)
+{
+	return platform_driver_register(&virtio_mmio_driver);
+}
+
+static void __exit virtio_mmio_exit(void)
+{
+	platform_driver_unregister(&virtio_mmio_driver);
+}
+
+module_init(virtio_mmio_init);
+module_exit(virtio_mmio_exit);
+
+MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
+MODULE_DESCRIPTION("Platform bus driver for memory mapped virtio devices");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/virtio_mmio.h b/include/linux/virtio_mmio.h
new file mode 100644
index 0000000..5d1ea5c
--- /dev/null
+++ b/include/linux/virtio_mmio.h
@@ -0,0 +1,92 @@
+/*
+ * Virtio platform device driver
+ *
+ * Copyright 2011, ARM Ltd.
+ *
+ * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_VIRTIO_MMIO_H
+#define _LINUX_VIRTIO_MMIO_H
+
+/* Magic value ("virt" string) */
+#define VIRTIO_MMIO_MAGIC_VALUE		0x000
+
+/* Virtio device version */
+#define VIRTIO_MMIO_VERSION		0x004
+
+/* Virtio device ID */
+#define VIRTIO_MMIO_DEVICE_ID		0x008
+
+/* Virtio vendor ID */
+#define VIRTIO_MMIO_VENDOR_ID		0x00c
+
+/* Bitmask of the features supported by the host (32 bits per set) */
+#define VIRTIO_MMIO_HOST_FEATURES	0x010
+
+/* Host features set selector */
+#define VIRTIO_MMIO_HOST_FEATURES_SEL	0x014
+
+/* Bitmask of features activated by the guest (32 bits per set) */
+#define VIRTIO_MMIO_GUEST_FEATURES	0x020
+
+/* Activated features set selector */
+#define VIRTIO_MMIO_GUEST_FEATURES_SET	0x024
+
+/* Guest's memory page size in bytes */
+#define VIRTIO_MMIO_GUEST_PAGE_SIZE	0x028
+
+/* Queue selector */
+#define VIRTIO_MMIO_QUEUE_SEL		0x030
+
+/* Queue size for the currently selected queue */
+#define VIRTIO_MMIO_QUEUE_NUM		0x034
+
+/* Used Ring alignment for the currently selected queue */
+#define VIRTIO_MMIO_QUEUE_ALIGN		0x038
+
+/* Guest's PFN for the currently selected queue */
+#define VIRTIO_MMIO_QUEUE_PFN		0x03c
+
+/* Queue notifier */
+#define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
+
+/* Interrupt acknowledge */
+#define VIRTIO_MMIO_INTERRUPT_ACK	0x060
+
+/* Device status register */
+#define VIRTIO_MMIO_STATUS		0x070
+
+/* The config space is defined by each driver as
+ * the per-driver configuration space */
+#define VIRTIO_MMIO_CONFIG		0x100
+
+
+
+#endif
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH] dma/imx-sdma+imx-dma: explicitly #include <linux/module.h>
From: Paul Gortmaker @ 2011-09-28 13:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110928064614.GN20550@pengutronix.de>

On 11-09-28 02:46 AM, Uwe Kleine-K?nig wrote:
> [Cc: += linux-kbuild at v.k.o + Michal Marek]
> 
> Hello,
> 
> On Tue, Sep 27, 2011 at 06:03:13PM -0400, Paul Gortmaker wrote:
>> On 11-09-26 02:26 AM, Uwe Kleine-K?nig wrote:
>>> This is needed after commit
>>>
>>> 	include: replace linux/module.h with "struct module" wherever possible
>>>
>>> (currently 25215aa in next).
>>>
>>> Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
>>> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>>> ---
>>> Hello,
>>>
>>> maybe it's sensible for Paul to take that before his commit?
>>
>> Thanks, I'll blend it into the commit adding module.h to the other
>> drivers/dma files.  It seems the imx boards don't have a defconfig
>> in the arch/arm/configs that enables this (CONFIG_IMX_[S]DMA).
>>
>> What is really interesting (at least to me anyway) is that I
>> didn't get one iMX build in some 6000+ ARM randconfig builds....
>>
>> I would have thought it would have showed up at least a couple
>> times, given that number of builds.  Maybe randconfig doesn't
>> deal so well with "choice" Kconfig items?
>>
>> ~/git/module.h/linux-2.6.git$ ls -1 ../build-10*arm |wc -l
>> 6399
>> ~/git/module.h/linux-2.6.git$ grep CONFIG_ARCH_[A-Z0-9]*=y ../build-10*arm*/.config | sed 's/.*CON/CON/'|sort |uniq
>> CONFIG_ARCH_EBSA110=y
>> CONFIG_ARCH_H7201=y
>> CONFIG_ARCH_H7202=y
>> CONFIG_ARCH_H720X=y
>> CONFIG_ARCH_VERSATILE=y
> 
> I don't understand why you did that sed, but AFAICT it doesn't hurt,
> too. Maybe adding -c to uniq in your command line is interesting for the
> kbuild people?!

The sed was to strip the build paths from the grep output.  I could
have used "grep -h" instead.

> 
>> ~/git/module.h/linux-2.6.git$ 
>>
>> No ARCH_MXC, no ARCH_MXS, PXA, or any of the other 20+ variants.
>> Definitely not a random spread there, with all 6000 builds falling
>> in just 5 buckets.
> How did you test? Generate a .config, test without your change and if
> that succeeds test with it? If so, maybe the problem isn't that
> randconfig doesn't generate more random configs but that you got many
> failures in the first run?!

Testing was with the following chunk out of my $0.02 script:

 i=10000 ; while [ 1 ] ; do D=../build-$i-$MYARCH ; mkdir $D ; echo xxxxxxx $D xxxxxx  ; make ARCH=$MYARCH O=$D randconfig > $D/cfg.log 2>&1 ; if [ $? != 0 ] ; then echo  cfg failed in $D ; break ; fi ; time make ARCH=$MYARCH O=$D -j16 > $D/build.log 2>&1 ; if [ $? != 0 ]; then echo  bld fail in $D ; fi ; i=$[$i+1] ; done

Then I'd comb all the build logs looking for errors that were caused
by changes that I made.  As you can see, it just calls randconfig, but
the coverage never really "randomly" covered all arm platforms.

Paul.



> 
> Best regards
> Uwe
> 

^ permalink raw reply

* [RFC PATCH v3] drivercore: Add driver probe deferral mechanism
From: Mark Brown @ 2011-09-28 13:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201109281504.34560.arnd@arndb.de>

On Wed, Sep 28, 2011 at 03:04:34PM +0200, Arnd Bergmann wrote:
> On Wednesday 28 September 2011, Mark Brown wrote:

> > Note that I'm not sure this answers the issue I was raising - the issue
> > isn't that the caller doesn't know what the error code means, the issue
> > is that in some cases the driver needs to take a decision about what
> > failure to get a resource means.  Does it mean that the driver can work
> > fine and be slightly less featureful or should it cause a deferral?

> Can you think of cases where this information cannot be put into the
> device tree or platform_data? If a board provides an optional feature,
> I think that should be a property of the device that the driver gets,
> so it can return an error when that feature is not around, or continue
> when it knows that the feature will never become available.

Not off the top of my head, most of the cases I'm aware of were cases
where the supply is mandatory but soft control is optional so don't need
to make this decision in the driver at all.  In the MMC case I didn't
push this as working with the people concerned was extremely painful.

^ permalink raw reply

* [PATCH v4 3/3] arm/tegra: device tree support for ventana board
From: Arnd Bergmann @ 2011-09-28 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1317171902-14736-4-git-send-email-pdeschrijver@nvidia.com>

On Wednesday 28 September 2011, Peter De Schrijver wrote:
> --- a/arch/arm/mach-tegra/board-dt.c
> +++ b/arch/arm/mach-tegra/board-dt.c
> @@ -47,7 +47,7 @@
>  
>  void harmony_pinmux_init(void);
>  void seaboard_pinmux_init(void);
> -
> +void ventana_pinmux_init(void);
>  
>  struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
>         OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
> @@ -95,6 +95,8 @@ static void __init tegra_dt_init(void)
>                 harmony_pinmux_init();
>         else if (of_machine_is_compatible("nvidia,seaboard"))
>                 seaboard_pinmux_init();
> +       else if (of_machine_is_compatible("nvidia,ventana"))
> +               ventana_pinmux_init();

Are you (Peter, Colin, Olof) confident that this is not getting out
of hand before it's getting better?

If we are keeping the per-board pinmux configuration in the kernel
for longer, I think it would be better to do this table-driven than
having a list of top-level of_machine_is_compatible() statements
and do something like:

static struct {
	const char *machine;
	struct tegra_pingroup_config *config[];
} pinmux_configs[] __initdata = {
	{ "nvidia,ventana", &ventana_pinmux },
	{ "nvidia,seaboard, &seaboard_pinmux },
};

	Arnd

^ permalink raw reply

* [PATCH 1/1] ixp4xx: support omicron ixp425 based boards
From: Richard Cochran @ 2011-09-28 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1317215339.git.richard.cochran@omicron.at>

This patch adds board support for the DEVIXP, the MICCPT, and the
MIC256, which are three IXP425 based boards produced by OMICRON
electronics, GmbH.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 arch/arm/mach-ixp4xx/Kconfig                   |   19 ++
 arch/arm/mach-ixp4xx/Makefile                  |    4 +
 arch/arm/mach-ixp4xx/include/mach/uncompress.h |    3 +-
 arch/arm/mach-ixp4xx/miccpt-pci.c              |   78 +++++++
 arch/arm/mach-ixp4xx/omixp-setup.c             |  273 ++++++++++++++++++++++++
 5 files changed, 376 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-ixp4xx/miccpt-pci.c
 create mode 100644 arch/arm/mach-ixp4xx/omixp-setup.c

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 6f991c5..fd5e7b6 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -179,6 +179,25 @@ config MACH_GTWX5715
 		"High Speed" UART is n/c (as far as I can tell)
 		20 Pin ARM/Xscale JTAG interface on J2
 
+config MACH_DEVIXP
+	bool "Omicron DEVIXP"
+	help
+	  Say 'Y' here if you want your kernel to support the DEVIXP
+	  board from OMICRON electronics GmbH.
+
+config MACH_MICCPT
+	bool "Omicron MICCPT"
+	select PCI
+	help
+	  Say 'Y' here if you want your kernel to support the MICCPT
+	  board from OMICRON electronics GmbH.
+
+config MACH_MIC256
+	bool "Omicron MIC256"
+	help
+	  Say 'Y' here if you want your kernel to support the MIC256
+	  board from OMICRON electronics GmbH.
+
 comment "IXP4xx Options"
 
 config IXP4XX_INDIRECT_PCI
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index d807fc3..eded94c 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -10,6 +10,7 @@ obj-pci-$(CONFIG_MACH_AVILA)		+= avila-pci.o
 obj-pci-$(CONFIG_MACH_IXDPG425)		+= ixdpg425-pci.o
 obj-pci-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o
 obj-pci-$(CONFIG_MACH_GTWX5715)		+= gtwx5715-pci.o
+obj-pci-$(CONFIG_MACH_MICCPT)		+= miccpt-pci.o
 obj-pci-$(CONFIG_MACH_NSLU2)		+= nslu2-pci.o
 obj-pci-$(CONFIG_MACH_NAS100D)		+= nas100d-pci.o
 obj-pci-$(CONFIG_MACH_DSMG600)		+= dsmg600-pci.o
@@ -25,6 +26,9 @@ obj-$(CONFIG_MACH_AVILA)	+= avila-setup.o
 obj-$(CONFIG_MACH_IXDPG425)	+= coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-setup.o
 obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-setup.o
+obj-$(CONFIG_MACH_DEVIXP)	+= omixp-setup.o
+obj-$(CONFIG_MACH_MICCPT)	+= omixp-setup.o
+obj-$(CONFIG_MACH_MIC256)	+= omixp-setup.o
 obj-$(CONFIG_MACH_NSLU2)	+= nslu2-setup.o
 obj-$(CONFIG_MACH_NAS100D)	+= nas100d-setup.o
 obj-$(CONFIG_MACH_DSMG600)      += dsmg600-setup.o
diff --git a/arch/arm/mach-ixp4xx/include/mach/uncompress.h b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
index 219d7c1..eb945a9 100644
--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -41,7 +41,8 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 	 * Some boards are using UART2 as console
 	 */
 	if (machine_is_adi_coyote() || machine_is_gtwx5715() ||
-			 machine_is_gateway7001() || machine_is_wg302v2())
+	    machine_is_gateway7001() || machine_is_wg302v2() ||
+	    machine_is_devixp() || machine_is_miccpt() || machine_is_mic256())
 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
 	else
 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
diff --git a/arch/arm/mach-ixp4xx/miccpt-pci.c b/arch/arm/mach-ixp4xx/miccpt-pci.c
new file mode 100644
index 0000000..ca0bae7
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/miccpt-pci.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-ixp4xx/miccpt-pci.c
+ *
+ * MICCPT board-level PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * Copyright (C) 2006 OMICRON electronics GmbH
+ *
+ * Author: Michael Jochum <michael.jochum@omicron.at>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV		4
+#define IRQ_LINES	4
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		1
+#define INTB		2
+#define INTC		3
+#define INTD		4
+
+
+void __init miccpt_pci_preinit(void)
+{
+	irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+	irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+	ixp4xx_pci_preinit();
+}
+
+static int __init miccpt_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static int pci_irq_table[IRQ_LINES] = {
+		IXP4XX_GPIO_IRQ(INTA),
+		IXP4XX_GPIO_IRQ(INTB),
+		IXP4XX_GPIO_IRQ(INTC),
+		IXP4XX_GPIO_IRQ(INTD)
+	};
+
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[(slot + pin - 2) % 4];
+
+	return -1;
+}
+
+struct hw_pci miccpt_pci __initdata = {
+	.nr_controllers = 1,
+	.preinit	= miccpt_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= ixp4xx_setup,
+	.scan		= ixp4xx_scan_bus,
+	.map_irq	= miccpt_map_irq,
+};
+
+int __init miccpt_pci_init(void)
+{
+	if (machine_is_miccpt())
+		pci_common_init(&miccpt_pci);
+	return 0;
+}
+
+subsys_initcall(miccpt_pci_init);
diff --git a/arch/arm/mach-ixp4xx/omixp-setup.c b/arch/arm/mach-ixp4xx/omixp-setup.c
new file mode 100644
index 0000000..4dfdc69
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/omixp-setup.c
@@ -0,0 +1,273 @@
+/*
+ * arch/arm/mach-ixp4xx/omixp-setup.c
+ *
+ * omicron ixp4xx board setup
+ *      Copyright (C) 2009 OMICRON electronics GmbH
+ *
+ * based nslu2-setup.c, ixdp425-setup.c:
+ *      Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#ifdef CONFIG_LEDS_CLASS
+#include <linux/leds.h>
+#endif
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct resource omixp_flash_resources[] = {
+	{
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct mtd_partition omixp_partitions[] = {
+	{
+		.name =		"Recovery Bootloader",
+		.size =		0x00020000,
+		.offset =	0,
+	}, {
+		.name =		"Calibration Data",
+		.size =		0x00020000,
+		.offset =	0x00020000,
+	}, {
+		.name =		"Recovery FPGA",
+		.size =		0x00020000,
+		.offset =	0x00040000,
+	}, {
+		.name =		"Release Bootloader",
+		.size =		0x00020000,
+		.offset =	0x00060000,
+	}, {
+		.name =		"Release FPGA",
+		.size =		0x00020000,
+		.offset =	0x00080000,
+	}, {
+		.name =		"Kernel",
+		.size =		0x00160000,
+		.offset =	0x000a0000,
+	}, {
+		.name =		"Filesystem",
+		.size =		0x00C00000,
+		.offset =	0x00200000,
+	}, {
+		.name =		"Persistent Storage",
+		.size =		0x00200000,
+		.offset =	0x00E00000,
+	},
+};
+
+static struct flash_platform_data omixp_flash_data[] = {
+	{
+		.map_name	= "cfi_probe",
+		.parts		= omixp_partitions,
+		.nr_parts	= ARRAY_SIZE(omixp_partitions),
+	}, {
+		.map_name	= "cfi_probe",
+		.parts		= NULL,
+		.nr_parts	= 0,
+	},
+};
+
+static struct platform_device omixp_flash_device[] = {
+	{
+		.name		= "IXP4XX-Flash",
+		.id		= 0,
+		.dev = {
+			.platform_data = &omixp_flash_data[0],
+		},
+		.resource = &omixp_flash_resources[0],
+		.num_resources = 1,
+	}, {
+		.name		= "IXP4XX-Flash",
+		.id		= 1,
+		.dev = {
+			.platform_data = &omixp_flash_data[1],
+		},
+		.resource = &omixp_flash_resources[1],
+		.num_resources = 1,
+	},
+};
+
+/* Swap UART's - These boards have the console on UART2. The following
+ * configuration is used:
+ *      ttyS0 .. UART2
+ *      ttyS1 .. UART1
+ * This way standard images can be used with the kernel that expect
+ * the console on ttyS0.
+ */
+static struct resource omixp_uart_resources[] = {
+	{
+		.start		= IXP4XX_UART2_BASE_PHYS,
+		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IXP4XX_UART1_BASE_PHYS,
+		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct plat_serial8250_port omixp_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	}, {
+		.mapbase	= IXP4XX_UART1_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	}, {
+		/* list termination */
+	}
+};
+
+static struct platform_device omixp_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev.platform_data	= omixp_uart_data,
+	.num_resources		= 2,
+	.resource		= omixp_uart_resources,
+};
+
+static struct gpio_led mic256_led_pins[] = {
+	{
+		.name		= "LED-A",
+		.gpio		= 7,
+	},
+};
+
+static struct gpio_led_platform_data mic256_led_data = {
+	.num_leds		= ARRAY_SIZE(mic256_led_pins),
+	.leds			= mic256_led_pins,
+};
+
+static struct platform_device mic256_leds = {
+	.name			= "leds-gpio",
+	.id			= -1,
+	.dev.platform_data	= &mic256_led_data,
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info ixdp425_plat_eth[] = {
+	{
+		.phy		= 0,
+		.rxq		= 3,
+		.txreadyq	= 20,
+	}, {
+		.phy		= 1,
+		.rxq		= 4,
+		.txreadyq	= 21,
+	},
+};
+
+static struct platform_device ixdp425_eth[] = {
+	{
+		.name			= "ixp4xx_eth",
+		.id			= IXP4XX_ETH_NPEB,
+		.dev.platform_data	= ixdp425_plat_eth,
+	}, {
+		.name			= "ixp4xx_eth",
+		.id			= IXP4XX_ETH_NPEC,
+		.dev.platform_data	= ixdp425_plat_eth + 1,
+	},
+};
+
+
+static struct platform_device *devixp_pldev[] __initdata = {
+	&omixp_uart,
+	&omixp_flash_device[0],
+	&ixdp425_eth[0],
+	&ixdp425_eth[1],
+};
+
+static struct platform_device *mic256_pldev[] __initdata = {
+	&omixp_uart,
+	&omixp_flash_device[0],
+	&mic256_leds,
+	&ixdp425_eth[0],
+	&ixdp425_eth[1],
+};
+
+static struct platform_device *miccpt_pldev[] __initdata = {
+	&omixp_uart,
+	&omixp_flash_device[0],
+	&omixp_flash_device[1],
+	&ixdp425_eth[0],
+	&ixdp425_eth[1],
+};
+
+static void __init omixp_init(void)
+{
+	ixp4xx_sys_init();
+
+	/* 16MiB Boot Flash */
+	omixp_flash_resources[0].start = IXP4XX_EXP_BUS_BASE(0);
+	omixp_flash_resources[0].end   = IXP4XX_EXP_BUS_END(0);
+
+	/* 32 MiB Data Flash */
+	omixp_flash_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
+	omixp_flash_resources[1].end   = IXP4XX_EXP_BUS_END(2);
+
+	if (machine_is_devixp())
+		platform_add_devices(devixp_pldev, ARRAY_SIZE(devixp_pldev));
+	else if (machine_is_miccpt())
+		platform_add_devices(miccpt_pldev, ARRAY_SIZE(miccpt_pldev));
+	else if (machine_is_mic256())
+		platform_add_devices(mic256_pldev, ARRAY_SIZE(mic256_pldev));
+}
+
+#ifdef CONFIG_MACH_DEVIXP
+MACHINE_START(DEVIXP, "Omicron DEVIXP")
+	.boot_params    = 0x100,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer          = &ixp4xx_timer,
+	.init_machine	= omixp_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICCPT
+MACHINE_START(MICCPT, "Omicron MICCPT")
+	.boot_params    = 0x100,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer          = &ixp4xx_timer,
+	.init_machine	= omixp_init,
+#if defined(CONFIG_PCI)
+	.dma_zone_size	= SZ_64M,
+#endif
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MIC256
+MACHINE_START(MIC256, "Omicron MIC256")
+	.boot_params    = 0x100,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer          = &ixp4xx_timer,
+	.init_machine	= omixp_init,
+MACHINE_END
+#endif
-- 
1.7.2.5

^ 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