* [PATCH 1/3] ARM: OMAP: Remove unnecessary mach and plat includes
From: Tony Lindgren @ 2012-11-01 22:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121101224703.2103.95474.stgit@muffinssi.local>
Now mach/hardware.h is empty for omap2+ and can be
removed except for plat-omap/dmtimer.c for omap1.
Also the include of mach/irqs.h can now be removed
for shared plat-omap/i2c.c as it's no longer needed.
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-2430sdp.c | 1 -
arch/arm/mach-omap2/board-cm-t35.c | 2 --
arch/arm/mach-omap2/hsmmc.c | 1 -
arch/arm/plat-omap/debug-devices.c | 1 -
arch/arm/plat-omap/dmtimer.c | 4 +---
arch/arm/plat-omap/fb.c | 1 -
arch/arm/plat-omap/i2c.c | 2 --
7 files changed, 1 insertion(+), 11 deletions(-)
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 3fc6d83..d1c0162 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -28,7 +28,6 @@
#include <linux/io.h>
#include <linux/gpio.h>
-#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index cf9449b..a8cad22 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -44,8 +44,6 @@
#include <video/omap-panel-tfp410.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <mach/hardware.h>
-
#include "common.h"
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index e3406dc..4a96433 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -14,7 +14,6 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/gpio.h>
-#include <mach/hardware.h>
#include <linux/platform_data/gpio-omap.h>
#include "soc.h"
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
index b49be51..a609e21 100644
--- a/arch/arm/plat-omap/debug-devices.c
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -15,7 +15,6 @@
#include <linux/io.h>
#include <linux/smc91x.h>
-#include <mach/hardware.h>
#include <plat/debug-devices.h>
/* Many OMAP development platforms reuse the same "debug board"; these
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 9a0bbc4..82231a7 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -43,8 +43,6 @@
#include <plat/dmtimer.h>
-#include <mach/hardware.h>
-
static u32 omap_reserved_systimers;
static LIST_HEAD(omap_timer_list);
static DEFINE_SPINLOCK(dm_timer_lock);
@@ -270,7 +268,7 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
#if defined(CONFIG_ARCH_OMAP1)
-
+#include <mach/hardware.h>
/**
* omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
* @inputmask: current value of idlect mask
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index f868cae..3a77b30 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -30,7 +30,6 @@
#include <linux/io.h>
#include <linux/omapfb.h>
-#include <mach/hardware.h>
#include <asm/mach/map.h>
#include <plat/cpu.h>
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 4645dd4..f9df624 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -33,8 +33,6 @@
#include <plat/i2c.h>
-#include <mach/irqs.h>
-
#define OMAP_I2C_MAX_CONTROLLERS 4
static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
^ permalink raw reply related
* [PATCH 0/3] more omap clean-up for ARCH_MULTIPLATFORM
From: Tony Lindgren @ 2012-11-01 22:48 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
Here are patches to remove some now unnecessary code
in preparation for enabling ARCH_MULTIPLATFORM for
omap2+.
These are based on omap-for-v3.8/cleanup-headers-relative
branch.
Regards,
Tony
---
Tony Lindgren (3):
ARM: OMAP: Remove unnecessary mach and plat includes
ARM: OMAP: Remove NEED_MACH_GPIO_H
ARM: OMAP: Remove plat-omap/common.c
arch/arm/Kconfig | 1 -
arch/arm/mach-omap1/gpio15xx.c | 2 ++
arch/arm/mach-omap1/gpio16xx.c | 2 ++
arch/arm/mach-omap1/gpio7xx.c | 2 ++
arch/arm/mach-omap1/include/mach/gpio.h | 3 ---
arch/arm/mach-omap2/board-2430sdp.c | 1 -
arch/arm/mach-omap2/board-cm-t35.c | 2 --
arch/arm/mach-omap2/hsmmc.c | 1 -
arch/arm/mach-omap2/include/mach/gpio.h | 3 ---
arch/arm/plat-omap/Makefile | 2 +-
arch/arm/plat-omap/common.c | 26 --------------------------
arch/arm/plat-omap/debug-devices.c | 1 -
arch/arm/plat-omap/dma.c | 8 ++++++++
arch/arm/plat-omap/dmtimer.c | 4 +---
arch/arm/plat-omap/fb.c | 1 -
arch/arm/plat-omap/i2c.c | 2 --
include/linux/platform_data/gpio-omap.h | 1 -
sound/soc/omap/am3517evm.c | 2 --
sound/soc/omap/n810.c | 1 -
sound/soc/omap/osk5912.c | 1 -
sound/soc/omap/sdp3430.c | 2 --
sound/soc/omap/zoom2.c | 3 ---
22 files changed, 16 insertions(+), 55 deletions(-)
delete mode 100644 arch/arm/mach-omap1/include/mach/gpio.h
delete mode 100644 arch/arm/mach-omap2/include/mach/gpio.h
delete mode 100644 arch/arm/plat-omap/common.c
--
Signature
^ permalink raw reply
* [PATCH] i2c: at91: add a sanity check on i2c message length
From: Wolfram Sang @ 2012-11-01 22:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349879158-27268-1-git-send-email-ludovic.desroches@atmel.com>
On Wed, Oct 10, 2012 at 04:25:58PM +0200, ludovic.desroches at atmel.com wrote:
> From: Ludovic Desroches <ludovic.desroches@atmel.com>
>
> If the i2c message length is zero, i2c-at91 will directly return an error
> instead of trying to send a zero-length message.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
What happens if you send a 0 byte message? Some hardware is able to do
this and it will be used in SMBUS QUICK which the driver states to
support according to at91_twi_func().
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121101/f5d6d91d/attachment.sig>
^ permalink raw reply
* [PATCH] i2c: omap: ensure writes to dev->buf_len are ordered
From: Wolfram Sang @ 2012-11-01 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351155648-20429-1-git-send-email-balbi@ti.com>
On Thu, Oct 25, 2012 at 12:00:48PM +0300, Felipe Balbi wrote:
> if we allow compiler reorder our writes, we could
> fall into a situation where dev->buf_len is reset
> for no apparent reason.
>
> This bug was found with a simple script which would
> transfer data to an i2c client from 1 to 1024 bytes
> (a simple for loop), when we got to transfer sizes
> bigger than the fifo size, dev->buf_len was reset
> to zero before we had an oportunity to handle XDR
> Interrupt. Because dev->buf_len was zero, we entered
> omap_i2c_transmit_data() to transfer zero bytes,
> which would mean we would just silently exit
> omap_i2c_transmit_data() without actually writing
> anything to DATA register. That would cause XDR
> IRQ to trigger forever and we would never transfer
> the remaining bytes.
>
> After adding the memory barrier, we also drop resetting
> dev->buf_len to zero in omap_i2c_xfer_msg() because
> both omap_i2c_transmit_data() and omap_i2c_receive_data()
> will act until dev->buf_len reaches zero, rendering the
> other write in omap_i2c_xfer_msg() redundant.
>
> This patch has been tested with pandaboard for a few
> iterations of the script mentioned above.
>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
>
> This bug has been there forever, but it's quite annoying.
> I think it deserves being pushed upstream during this -rc
> cycle, but if Wolfram decides to wait until v3.8, I don't
> mind.
I would add this into 3.7, but what about the comments suggesting to use
barrier()?
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121101/928fba26/attachment.sig>
^ permalink raw reply
* [PATCH v2] ARM: plat-versatile: move FPGA irq driver to drivers/irqchip
From: Thomas Petazzoni @ 2012-11-01 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351805329-19576-1-git-send-email-linus.walleij@linaro.org>
Linus,
On Thu, 1 Nov 2012 22:28:49 +0100, Linus Walleij wrote:
> +void fpga_handle_irq(struct pt_regs *regs);
This function does not need to be exposed in a public header: as
proposed for the bcm2835 and armada-370-xp IRQ controller drivers, the
driver should directly do handle_arch_irq = fpga_handle_irq, and
therefore there is no need for the machine desc structure to reference
fpga_handle_irq anymore.
> +void fpga_irq_init(void __iomem *, const char *, int, int, u32,
> + struct device_node *node);
> +int fpga_irq_of_init(struct device_node *node,
> + struct device_node *parent);
I don't think this function needs to be exported. Just move the
compatible string to drivers/irqchip/irqchip.c and instead of calling
of_irq_init(), call irqchip_init().
This will leave only the fpga_irq_init() function, which we could get
rid of once the non-DT support is removed.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] ARM: kirkwood: Increase NAND chip-delay for DNS-320
From: Jamie Lentin @ 2012-11-01 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121030060226.GA14093@lunn.ch>
On Tue, 30 Oct 2012, Andrew Lunn wrote:
>>> I'm currently downloading the GPL sources from dlink. If the kernel
>>> sources are included, we can see how dlink sets this. If its also 35,
>>> then there is no argument.
>>
>> Rummaging myself, my best guess is:
>>
>> linux-2.6.22.18/arch/arm/mach-feroceon-kw/nand.c
>> 173: this->chip_delay = 30;
>>
>> u-boot-1.1.4/board/mv_feroceon/USP/mv_nand.c
>> 68: nand->chip_delay = 30;
>>
>> However, this is too fast for my NAS when using a mainline kernel.
>> 31usecs seems to work though. It's probably worth noting that the
>> original firmware wasn't without it's problems on this particular
>> board---I couldn't get it to reflash the NAND with a new firmware
>> image. It could certainly read the NAND though.
>>
>> This chip_delay value seems to be there in both the DNS320 and
>> DNS325 GPL source. Maybe increasing chip_delay for both would be
>> safest.
>
> Yep. Please could you submit a new patch for dnskw.dtsi.
>
> I guess you are not the only person with problems with 30, so 35 seems
> sensible.
>
> Do you have any idea how much this affects performance? It might not
> be worth the effort to probe the chip and set the timing, if its only
> a couple of % difference.
Highly unscientific tests show that it's not making a vast difference.
Even if it did, collecting chip to speed mappings is going to be a
headache.
Given a range of chip_delay values, would it make sense for the NAND
driver to find the lowest chip_delay that results in a stable NAND.
Possibly during the bad block scan?
>
> Andrew
>
--
Jamie Lentin
^ permalink raw reply
* [PATCH V2] ARM: kirkwood: Increase NAND chip-delay for DNS-32[05]
From: Jamie Lentin @ 2012-11-01 21:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121030060226.GA14093@lunn.ch>
The default chip-delay of 25us is a bit too tight for some DNS-320's,
and D-Link seem to specify 30us in their kernels for both devices.
Increase to 35us to make sure the NAND is stable.
Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
---
arch/arm/boot/dts/kirkwood-dnskw.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
index e0e4397..0360361 100644
--- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -48,6 +48,7 @@
nand at 3000000 {
status = "okay";
+ chip-delay = <35>;
partition at 0 {
label = "u-boot";
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2] ARM: plat-versatile: move FPGA irq driver to drivers/irqchip
From: Linus Walleij @ 2012-11-01 21:28 UTC (permalink / raw)
To: linux-arm-kernel
This moves the Versatile FPGA interrupt controller driver, used in
the Integrator/AP, Integrator/CP and some Versatile boards, out
of arch/arm/plat-versatile and down to drivers/irqchip where we
have consensus that such drivers belong. The header file is
consequently moved to <linux/platform_data/irq-versatile-fpga.h>.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Moved include to <linux/irqchip/versatile-fpga.h>
- Deleted merge/moval artifact
---
arch/arm/Kconfig | 4 +-
arch/arm/mach-integrator/integrator_ap.c | 3 +-
arch/arm/mach-integrator/integrator_cp.c | 2 +-
arch/arm/mach-versatile/core.c | 2 +-
arch/arm/plat-versatile/Kconfig | 9 --
arch/arm/plat-versatile/Makefile | 1 -
arch/arm/plat-versatile/fpga-irq.c | 204 ------------------------
arch/arm/plat-versatile/include/plat/fpga-irq.h | 13 --
drivers/irqchip/Kconfig | 9 +-
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-versatile-fpga.c | 204 ++++++++++++++++++++++++
include/linux/irqchip/versatile-fpga.h | 13 ++
12 files changed, 231 insertions(+), 234 deletions(-)
delete mode 100644 arch/arm/plat-versatile/fpga-irq.c
delete mode 100644 arch/arm/plat-versatile/include/plat/fpga-irq.h
create mode 100644 drivers/irqchip/irq-versatile-fpga.c
create mode 100644 include/linux/irqchip/versatile-fpga.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 73067ef..2205e3e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -284,8 +284,8 @@ config ARCH_INTEGRATOR
select MULTI_IRQ_HANDLER
select NEED_MACH_MEMORY_H
select PLAT_VERSATILE
- select PLAT_VERSATILE_FPGA_IRQ
select SPARSE_IRQ
+ select VERSATILE_FPGA_IRQ
help
Support for ARM's Integrator platform.
@@ -318,7 +318,7 @@ config ARCH_VERSATILE
select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
select PLAT_VERSATILE_CLOCK
- select PLAT_VERSATILE_FPGA_IRQ
+ select VERSATILE_FPGA_IRQ
help
This enables support for ARM Ltd Versatile board.
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 4f13bc5..e67a9fe 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -31,6 +31,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irqchip/versatile-fpga.h>
#include <linux/mtd/physmap.h>
#include <linux/clk.h>
#include <linux/platform_data/clk-integrator.h>
@@ -56,8 +57,6 @@
#include <asm/mach/pci.h>
#include <asm/mach/time.h>
-#include <plat/fpga-irq.h>
-
#include "common.h"
/*
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 4423bc8..acecf04 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -20,6 +20,7 @@
#include <linux/amba/clcd.h>
#include <linux/amba/mmci.h>
#include <linux/io.h>
+#include <linux/irqchip/versatile-fpga.h>
#include <linux/gfp.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_data/clk-integrator.h>
@@ -46,7 +47,6 @@
#include <asm/hardware/timer-sp.h>
#include <plat/clcd.h>
-#include <plat/fpga-irq.h>
#include <plat/sched_clock.h>
#include "common.h"
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 5b5c1ee..5d59294 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -32,6 +32,7 @@
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/irqchip/versatile-fpga.h>
#include <linux/gfp.h>
#include <linux/clkdev.h>
#include <linux/mtd/physmap.h>
@@ -51,7 +52,6 @@
#include <asm/hardware/timer-sp.h>
#include <plat/clcd.h>
-#include <plat/fpga-irq.h>
#include <plat/sched_clock.h>
#include "core.h"
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
index 2a4ae8a..619f0fa 100644
--- a/arch/arm/plat-versatile/Kconfig
+++ b/arch/arm/plat-versatile/Kconfig
@@ -6,15 +6,6 @@ config PLAT_VERSATILE_CLOCK
config PLAT_VERSATILE_CLCD
bool
-config PLAT_VERSATILE_FPGA_IRQ
- bool
- select IRQ_DOMAIN
-
-config PLAT_VERSATILE_FPGA_IRQ_NR
- int
- default 4
- depends on PLAT_VERSATILE_FPGA_IRQ
-
config PLAT_VERSATILE_LEDS
def_bool y if NEW_LEDS
depends on ARCH_REALVIEW || ARCH_VERSATILE
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 74cfd94..f88d448 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -2,7 +2,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
-obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c
deleted file mode 100644
index dfe317c..0000000
--- a/arch/arm/plat-versatile/fpga-irq.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Support for Versatile FPGA-based IRQ controllers
- */
-#include <linux/bitops.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/irqdomain.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#include <asm/exception.h>
-#include <asm/mach/irq.h>
-#include <plat/fpga-irq.h>
-
-#define IRQ_STATUS 0x00
-#define IRQ_RAW_STATUS 0x04
-#define IRQ_ENABLE_SET 0x08
-#define IRQ_ENABLE_CLEAR 0x0c
-#define INT_SOFT_SET 0x10
-#define INT_SOFT_CLEAR 0x14
-#define FIQ_STATUS 0x20
-#define FIQ_RAW_STATUS 0x24
-#define FIQ_ENABLE 0x28
-#define FIQ_ENABLE_SET 0x28
-#define FIQ_ENABLE_CLEAR 0x2C
-
-/**
- * struct fpga_irq_data - irq data container for the FPGA IRQ controller
- * @base: memory offset in virtual memory
- * @chip: chip container for this instance
- * @domain: IRQ domain for this instance
- * @valid: mask for valid IRQs on this controller
- * @used_irqs: number of active IRQs on this controller
- */
-struct fpga_irq_data {
- void __iomem *base;
- struct irq_chip chip;
- u32 valid;
- struct irq_domain *domain;
- u8 used_irqs;
-};
-
-/* we cannot allocate memory when the controllers are initially registered */
-static struct fpga_irq_data fpga_irq_devices[CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR];
-static int fpga_irq_id;
-
-static void fpga_irq_mask(struct irq_data *d)
-{
- struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << d->hwirq;
-
- writel(mask, f->base + IRQ_ENABLE_CLEAR);
-}
-
-static void fpga_irq_unmask(struct irq_data *d)
-{
- struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << d->hwirq;
-
- writel(mask, f->base + IRQ_ENABLE_SET);
-}
-
-static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
-{
- struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
- u32 status = readl(f->base + IRQ_STATUS);
-
- if (status == 0) {
- do_bad_IRQ(irq, desc);
- return;
- }
-
- do {
- irq = ffs(status) - 1;
- status &= ~(1 << irq);
- generic_handle_irq(irq_find_mapping(f->domain, irq));
- } while (status);
-}
-
-/*
- * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero
- * if we've handled at least one interrupt. This does a single read of the
- * status register and handles all interrupts in order from LSB first.
- */
-static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
-{
- int handled = 0;
- int irq;
- u32 status;
-
- while ((status = readl(f->base + IRQ_STATUS))) {
- irq = ffs(status) - 1;
- handle_IRQ(irq_find_mapping(f->domain, irq), regs);
- handled = 1;
- }
-
- return handled;
-}
-
-/*
- * Keep iterating over all registered FPGA IRQ controllers until there are
- * no pending interrupts.
- */
-asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
-{
- int i, handled;
-
- do {
- for (i = 0, handled = 0; i < fpga_irq_id; ++i)
- handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
- } while (handled);
-}
-
-static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq)
-{
- struct fpga_irq_data *f = d->host_data;
-
- /* Skip invalid IRQs, only register handlers for the real ones */
- if (!(f->valid & BIT(hwirq)))
- return -ENOTSUPP;
- irq_set_chip_data(irq, f);
- irq_set_chip_and_handler(irq, &f->chip,
- handle_level_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- return 0;
-}
-
-static struct irq_domain_ops fpga_irqdomain_ops = {
- .map = fpga_irqdomain_map,
- .xlate = irq_domain_xlate_onetwocell,
-};
-
-void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
- int parent_irq, u32 valid, struct device_node *node)
-{
- struct fpga_irq_data *f;
- int i;
-
- if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
- pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
- return;
- }
- f = &fpga_irq_devices[fpga_irq_id];
- f->base = base;
- f->chip.name = name;
- f->chip.irq_ack = fpga_irq_mask;
- f->chip.irq_mask = fpga_irq_mask;
- f->chip.irq_unmask = fpga_irq_unmask;
- f->valid = valid;
-
- if (parent_irq != -1) {
- irq_set_handler_data(parent_irq, f);
- irq_set_chained_handler(parent_irq, fpga_irq_handle);
- }
-
- /* This will also allocate irq descriptors */
- f->domain = irq_domain_add_simple(node, fls(valid), irq_start,
- &fpga_irqdomain_ops, f);
-
- /* This will allocate all valid descriptors in the linear case */
- for (i = 0; i < fls(valid); i++)
- if (valid & BIT(i)) {
- if (!irq_start)
- irq_create_mapping(f->domain, i);
- f->used_irqs++;
- }
-
- pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
- fpga_irq_id, name, base, f->used_irqs);
-
- fpga_irq_id++;
-}
-
-#ifdef CONFIG_OF
-int __init fpga_irq_of_init(struct device_node *node,
- struct device_node *parent)
-{
- struct fpga_irq_data *f;
- void __iomem *base;
- u32 clear_mask;
- u32 valid_mask;
-
- if (WARN_ON(!node))
- return -ENODEV;
-
- base = of_iomap(node, 0);
- WARN(!base, "unable to map fpga irq registers\n");
-
- if (of_property_read_u32(node, "clear-mask", &clear_mask))
- clear_mask = 0;
-
- if (of_property_read_u32(node, "valid-mask", &valid_mask))
- valid_mask = 0;
-
- fpga_irq_init(base, node->name, 0, -1, valid_mask, node);
-
- writel(clear_mask, base + IRQ_ENABLE_CLEAR);
- writel(clear_mask, base + FIQ_ENABLE_CLEAR);
-
- return 0;
-}
-#endif
diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h
deleted file mode 100644
index 1fac965..0000000
--- a/arch/arm/plat-versatile/include/plat/fpga-irq.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef PLAT_FPGA_IRQ_H
-#define PLAT_FPGA_IRQ_H
-
-struct device_node;
-struct pt_regs;
-
-void fpga_handle_irq(struct pt_regs *regs);
-void fpga_irq_init(void __iomem *, const char *, int, int, u32,
- struct device_node *node);
-int fpga_irq_of_init(struct device_node *node,
- struct device_node *parent);
-
-#endif
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 1bb8bf6..62ca575 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -1 +1,8 @@
-# empty
+config VERSATILE_FPGA_IRQ
+ bool
+ select IRQ_DOMAIN
+
+config VERSATILE_FPGA_IRQ_NR
+ int
+ default 4
+ depends on VERSATILE_FPGA_IRQ
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 054321d..e2e6eb5 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
+obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
new file mode 100644
index 0000000..789b3e5
--- /dev/null
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -0,0 +1,204 @@
+/*
+ * Support for Versatile FPGA-based IRQ controllers
+ */
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/irqchip/versatile-fpga.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#define IRQ_STATUS 0x00
+#define IRQ_RAW_STATUS 0x04
+#define IRQ_ENABLE_SET 0x08
+#define IRQ_ENABLE_CLEAR 0x0c
+#define INT_SOFT_SET 0x10
+#define INT_SOFT_CLEAR 0x14
+#define FIQ_STATUS 0x20
+#define FIQ_RAW_STATUS 0x24
+#define FIQ_ENABLE 0x28
+#define FIQ_ENABLE_SET 0x28
+#define FIQ_ENABLE_CLEAR 0x2C
+
+/**
+ * struct fpga_irq_data - irq data container for the FPGA IRQ controller
+ * @base: memory offset in virtual memory
+ * @chip: chip container for this instance
+ * @domain: IRQ domain for this instance
+ * @valid: mask for valid IRQs on this controller
+ * @used_irqs: number of active IRQs on this controller
+ */
+struct fpga_irq_data {
+ void __iomem *base;
+ struct irq_chip chip;
+ u32 valid;
+ struct irq_domain *domain;
+ u8 used_irqs;
+};
+
+/* we cannot allocate memory when the controllers are initially registered */
+static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR];
+static int fpga_irq_id;
+
+static void fpga_irq_mask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << d->hwirq;
+
+ writel(mask, f->base + IRQ_ENABLE_CLEAR);
+}
+
+static void fpga_irq_unmask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << d->hwirq;
+
+ writel(mask, f->base + IRQ_ENABLE_SET);
+}
+
+static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+ struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
+ u32 status = readl(f->base + IRQ_STATUS);
+
+ if (status == 0) {
+ do_bad_IRQ(irq, desc);
+ return;
+ }
+
+ do {
+ irq = ffs(status) - 1;
+ status &= ~(1 << irq);
+ generic_handle_irq(irq_find_mapping(f->domain, irq));
+ } while (status);
+}
+
+/*
+ * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero
+ * if we've handled at least one interrupt. This does a single read of the
+ * status register and handles all interrupts in order from LSB first.
+ */
+static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
+{
+ int handled = 0;
+ int irq;
+ u32 status;
+
+ while ((status = readl(f->base + IRQ_STATUS))) {
+ irq = ffs(status) - 1;
+ handle_IRQ(irq_find_mapping(f->domain, irq), regs);
+ handled = 1;
+ }
+
+ return handled;
+}
+
+/*
+ * Keep iterating over all registered FPGA IRQ controllers until there are
+ * no pending interrupts.
+ */
+asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
+{
+ int i, handled;
+
+ do {
+ for (i = 0, handled = 0; i < fpga_irq_id; ++i)
+ handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
+ } while (handled);
+}
+
+static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct fpga_irq_data *f = d->host_data;
+
+ /* Skip invalid IRQs, only register handlers for the real ones */
+ if (!(f->valid & BIT(hwirq)))
+ return -ENOTSUPP;
+ irq_set_chip_data(irq, f);
+ irq_set_chip_and_handler(irq, &f->chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+static struct irq_domain_ops fpga_irqdomain_ops = {
+ .map = fpga_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
+ int parent_irq, u32 valid, struct device_node *node)
+{
+ struct fpga_irq_data *f;
+ int i;
+
+ if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
+ pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
+ return;
+ }
+ f = &fpga_irq_devices[fpga_irq_id];
+ f->base = base;
+ f->chip.name = name;
+ f->chip.irq_ack = fpga_irq_mask;
+ f->chip.irq_mask = fpga_irq_mask;
+ f->chip.irq_unmask = fpga_irq_unmask;
+ f->valid = valid;
+
+ if (parent_irq != -1) {
+ irq_set_handler_data(parent_irq, f);
+ irq_set_chained_handler(parent_irq, fpga_irq_handle);
+ }
+
+ /* This will also allocate irq descriptors */
+ f->domain = irq_domain_add_simple(node, fls(valid), irq_start,
+ &fpga_irqdomain_ops, f);
+
+ /* This will allocate all valid descriptors in the linear case */
+ for (i = 0; i < fls(valid); i++)
+ if (valid & BIT(i)) {
+ if (!irq_start)
+ irq_create_mapping(f->domain, i);
+ f->used_irqs++;
+ }
+
+ pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
+ fpga_irq_id, name, base, f->used_irqs);
+
+ fpga_irq_id++;
+}
+
+#ifdef CONFIG_OF
+int __init fpga_irq_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct fpga_irq_data *f;
+ void __iomem *base;
+ u32 clear_mask;
+ u32 valid_mask;
+
+ if (WARN_ON(!node))
+ return -ENODEV;
+
+ base = of_iomap(node, 0);
+ WARN(!base, "unable to map fpga irq registers\n");
+
+ if (of_property_read_u32(node, "clear-mask", &clear_mask))
+ clear_mask = 0;
+
+ if (of_property_read_u32(node, "valid-mask", &valid_mask))
+ valid_mask = 0;
+
+ fpga_irq_init(base, node->name, 0, -1, valid_mask, node);
+
+ writel(clear_mask, base + IRQ_ENABLE_CLEAR);
+ writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+
+ return 0;
+}
+#endif
diff --git a/include/linux/irqchip/versatile-fpga.h b/include/linux/irqchip/versatile-fpga.h
new file mode 100644
index 0000000..1fac965
--- /dev/null
+++ b/include/linux/irqchip/versatile-fpga.h
@@ -0,0 +1,13 @@
+#ifndef PLAT_FPGA_IRQ_H
+#define PLAT_FPGA_IRQ_H
+
+struct device_node;
+struct pt_regs;
+
+void fpga_handle_irq(struct pt_regs *regs);
+void fpga_irq_init(void __iomem *, const char *, int, int, u32,
+ struct device_node *node);
+int fpga_irq_of_init(struct device_node *node,
+ struct device_node *parent);
+
+#endif
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2] ARM: zynq: Allow UART1 to be used as DEBUG_LL console.
From: Nick Bowler @ 2012-11-01 18:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <508FB9B1.5060404@monstr.eu>
On 2012-10-30 12:27 +0100, Michal Simek wrote:
> On 10/29/2012 07:19 PM, Nick Bowler wrote:
> > +#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
> > +# define LL_UART_PADDR UART1_PHYS
> > +# define LL_UART_VADDR UART_VIRT
> > +#else
> > +# define LL_UART_PADDR UART0_PHYS
> > +# define LL_UART_VADDR UART_VIRT
> > +#endif
>
> Probably no reason to setup LL_UART_VADDR on two lines.
> It is enough to set it up once.
>
> MINOR: It is just my personal preference to use different coding style.
>
> #if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
> # define LL_UART_PADDR UART1_PHYS
> #else
> # define LL_UART_PADDR UART0_PHYS
> #endif
>
> #define LL_UART_VADDR UART_VIRT
I have no strong feeling either way, so I will send v3 with these
changes.
Thanks,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
^ permalink raw reply
* [PATCH v2 4/4] ARM: OMAP: gpmc: add DT bindings for GPMC timings and NAND
From: Daniel Mack @ 2012-11-01 18:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351794970-14675-1-git-send-email-zonque@gmail.com>
This patch adds basic DT bindings for OMAP GPMC.
The actual peripherals are instanciated from child nodes within the GPMC
node, and the only type of device that is currently supported is NAND.
Code was added to parse the generic GPMC timing parameters and some
documentation with examples on how to use them.
Successfully tested on an AM33xx board.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
Documentation/devicetree/bindings/bus/ti-gpmc.txt | 73 +++++++++++
.../devicetree/bindings/mtd/gpmc-nand.txt | 61 +++++++++
arch/arm/mach-omap2/gpmc.c | 139 +++++++++++++++++++++
3 files changed, 273 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
new file mode 100644
index 0000000..6f44487
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
@@ -0,0 +1,73 @@
+Device tree bindings for OMAP general purpose memory controllers (GPMC)
+
+The actual devices are instantiated from the child nodes of a GPMC node.
+
+Required properties:
+
+ - compatible: Should be set to "ti,gpmc"
+ - reg: A resource specifier for the register space
+ (see the example below)
+ - ti,hwmods: Should be set to "ti,gpmc" until the DT transition is
+ completed.
+ - #address-cells: Must be set to 2 to allow memory address translation
+ - #size-cells: Must be set to 1 to allow CS address passing
+ - ranges: Must be set up to reflect the memory layout
+ Note that this property is not currently parsed.
+ Calculated values derived from the contents of
+ GPMC_CS_CONFIG7 as set up by the bootloader. That will
+ change in the future, so be sure to fill the correct
+ values here.
+
+Timing properties for child nodes. All are optional and default to 0.
+
+ - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds
+
+ Chip-select signal timings corresponding to GPMC_CS_CONFIG2:
+ - gpmc,cs-on: Assertion time
+ - gpmc,cs-rd-off: Read deassertion time
+ - gpmc,cs-wr-off: Write deassertion time
+
+ ADV signal timings corresponding to GPMC_CONFIG3:
+ - gpmc,adv-on: Assertion time
+ - gpmc,adv-rd-off: Read deassertion time
+ - gpmc,adv-wr-off: Write deassertion time
+
+ WE signals timings corresponding to GPMC_CONFIG4:
+ - gpmc,we-on: Assertion time
+ - gpmc,we-off: Deassertion time
+
+ OE signals timings corresponding to GPMC_CONFIG4
+ - gpmc,oe-on: Assertion time
+ - gpmc,oe-off: Deassertion time
+
+ Access time and cycle time timings corresponding to GPMC_CONFIG5
+ - gpmc,page-burst-access: Multiple access word delay
+ - gpmc,access: Start-cycle to first data valid delay
+ - gpmc,rd-cycle: Total read cycle time
+ - gpmc,wr-cycle: Total write cycle time
+
+The following are only on OMAP3430
+ - gpmc,wr-access
+ - gpmc,wr-data-mux-bus
+
+
+Example for an AM33xx board:
+
+ gpmc: gpmc at 50000000 {
+ compatible = "ti,gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x50000000 0x2000>;
+ interrupt-parent = <&intc>;
+ interrupts = <100>;
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x08000000 0x10000000>; /* CS0 */
+
+ /* child nodes go here */
+ };
+
+
+
+
+
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
new file mode 100644
index 0000000..e0c1e67
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -0,0 +1,61 @@
+Device tree bindings for GPMC connected NANDs
+
+GPMC connected NAND (found on OMAP boards) are represented as child nodes of
+the GPMC controller with a name of "nand".
+
+All timing relevant properties as well as generic gpmc child properties are
+explained in a separate documents - please refer to
+Documentation/devicetree/bindings/bus/ti-gpmc.txt
+
+For NAND specific properties such as ECC modes or bus width, please refer to
+Documentation/devicetree/bindings/mtd/nand.txt
+
+
+Required properties:
+
+ - reg: The CS line the peripheral is connected to
+
+For inline partiton table parsing (optional):
+
+ - #address-cells: should be set to 1
+ - #size-cells: should be set to 1
+
+Example for an AM33xx board:
+
+ gpmc: gpmc at 50000000 {
+ compatible = "ti,gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x50000000 0x1000000>;
+ interrupt-parent = <&intc>;
+ interrupts = <100>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */
+
+ nand at 0,0 {
+ reg = <0 0 0>; /* CS0, offset 0 */
+ nand-bus-width = <16>;
+ nand-ecc-mode = "none";
+
+ gpmc,sync-clk = <0>;
+ gpmc,cs-on = <0>;
+ gpmc,cs-rd-off = <36>;
+ gpmc,cs-wr-off = <36>;
+ gpmc,adv-on = <6>;
+ gpmc,adv-rd-off = <24>;
+ gpmc,adv-wr-off = <36>;
+ gpmc,we-off = <30>;
+ gpmc,oe-off = <48>;
+ gpmc,access = <54>;
+ gpmc,rd-cycle = <72>;
+ gpmc,wr-cycle = <72>;
+ gpmc,wr-access = <30>;
+ gpmc,wr-data-mux-bus = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* partitions go here */
+ };
+ };
+
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1dcb30c..b028225 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -25,6 +25,10 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/of_device.h>
+#include <linux/mtd/nand.h>
#include <linux/platform_data/mtd-nand-omap2.h>
@@ -37,6 +41,7 @@
#include "soc.h"
#include "common.h"
#include "gpmc.h"
+#include "gpmc-nand.h"
#define DEVICE_NAME "omap-gpmc"
@@ -751,6 +756,131 @@ static int __devinit gpmc_mem_init(void)
return 0;
}
+#ifdef CONFIG_OF
+static struct of_device_id gpmc_dt_ids[] = {
+ { .compatible = "ti,gpmc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
+
+static void gpmc_read_timings_dt(struct device_node *np,
+ struct gpmc_timings *gpmc_t)
+{
+ u32 val;
+
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+ /* minimum clock period for syncronous mode */
+ if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
+ gpmc_t->sync_clk = val;
+
+ /* chip select timtings */
+ if (!of_property_read_u32(np, "gpmc,cs-on", &val))
+ gpmc_t->cs_on = val;
+
+ if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
+ gpmc_t->cs_rd_off = val;
+
+ if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
+ gpmc_t->cs_wr_off = val;
+
+ /* ADV signal timings */
+ if (!of_property_read_u32(np, "gpmc,adv-on", &val))
+ gpmc_t->adv_on = val;
+
+ if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
+ gpmc_t->adv_rd_off = val;
+
+ if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
+ gpmc_t->adv_wr_off = val;
+
+ /* WE signal timings */
+ if (!of_property_read_u32(np, "gpmc,we-on", &val))
+ gpmc_t->we_on = val;
+
+ if (!of_property_read_u32(np, "gpmc,we-off", &val))
+ gpmc_t->we_off = val;
+
+ /* OE signal timings */
+ if (!of_property_read_u32(np, "gpmc,oe-on", &val))
+ gpmc_t->oe_on = val;
+
+ if (!of_property_read_u32(np, "gpmc,oe-off", &val))
+ gpmc_t->oe_off = val;
+
+ /* access and cycle timings */
+ if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
+ gpmc_t->page_burst_access = val;
+
+ if (!of_property_read_u32(np, "gpmc,access", &val))
+ gpmc_t->access = val;
+
+ if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
+ gpmc_t->rd_cycle = val;
+
+ if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
+ gpmc_t->wr_cycle = val;
+
+ /* only for OMAP3430 */
+ if (!of_property_read_u32(np, "gpmc,wr-access", &val))
+ gpmc_t->wr_access = val;
+
+ if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
+ gpmc_t->wr_data_mux_bus = val;
+}
+
+static int gpmc_probe_dt(struct platform_device *pdev)
+{
+ u32 val;
+ struct device_node *child;
+ struct gpmc_timings gpmc_t;
+ const struct of_device_id *of_id =
+ of_match_device(gpmc_dt_ids, &pdev->dev);
+
+ if (!of_id)
+ return 0;
+
+ for_each_node_by_name(child, "nand") {
+ struct omap_nand_platform_data *gpmc_nand_data;
+
+ if (of_property_read_u32(child, "reg", &val) < 0) {
+ dev_err(&pdev->dev, "%s has no 'reg' property\n",
+ child->full_name);
+ continue;
+ }
+
+ gpmc_nand_data = devm_kzalloc(&pdev->dev,
+ sizeof(*gpmc_nand_data),
+ GFP_KERNEL);
+ if (!gpmc_nand_data) {
+ dev_err(&pdev->dev, "unable to allocate memory?");
+ return -ENOMEM;
+ }
+
+ gpmc_nand_data->cs = val;
+ gpmc_nand_data->of_node = child;
+
+ val = of_get_nand_ecc_mode(child);
+ if (val >= 0)
+ gpmc_nand_data->ecc_opt = val;
+
+ val = of_get_nand_bus_width(child);
+ if (val == 16)
+ gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
+
+ gpmc_read_timings_dt(child, &gpmc_t);
+ gpmc_nand_init(gpmc_nand_data, &gpmc_t);
+ }
+
+ return 0;
+}
+#else
+static int gpmc_probe_dt(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
static __devinit int gpmc_probe(struct platform_device *pdev)
{
int rc;
@@ -804,6 +934,14 @@ static __devinit int gpmc_probe(struct platform_device *pdev)
if (IS_ERR_VALUE(gpmc_setup_irq()))
dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+ rc = gpmc_probe_dt(pdev);
+ if (rc < 0) {
+ clk_disable_unprepare(gpmc_l3_clk);
+ clk_put(gpmc_l3_clk);
+ dev_err(gpmc_dev, "failed to probe DT parameters\n");
+ return rc;
+ }
+
return 0;
}
@@ -821,6 +959,7 @@ static struct platform_driver gpmc_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpmc_dt_ids),
},
};
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 3/4] ARM: OMAP: gpmc: don't create devices from initcall on DT
From: Daniel Mack @ 2012-11-01 18:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351794970-14675-1-git-send-email-zonque@gmail.com>
On DT driven boards, the gpmc node will match the driver. Hence, there's
no need to do that unconditionally from the initcall.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
arch/arm/mach-omap2/gpmc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 60f1cce..1dcb30c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -844,6 +844,13 @@ static int __init omap_gpmc_init(void)
struct platform_device *pdev;
char *oh_name = "gpmc";
+ /*
+ * if the board boots up with a populated DT, do not
+ * manually add the device from this initcall
+ */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up %s\n", oh_name);
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 2/4] ARM: OMAP: gpmc: enable hwecc for AM33xx SoCs
From: Daniel Mack @ 2012-11-01 18:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351794970-14675-1-git-send-email-zonque@gmail.com>
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 8607735..c3616c6 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -92,7 +92,7 @@ static int omap2_nand_gpmc_retime(
static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
{
/* support only OMAP3 class */
- if (!cpu_is_omap34xx()) {
+ if (!cpu_is_omap34xx() && !soc_is_am33xx()) {
pr_err("BCH ecc is not supported on this CPU\n");
return 0;
}
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 1/4] mtd: omap-nand: pass device_node in platform data
From: Daniel Mack @ 2012-11-01 18:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351794970-14675-1-git-send-email-zonque@gmail.com>
Pass an optional device_node pointer in the platform data, which in turn
will be put into a mtd_part_parser_data. This way, code that sets up the
platform devices can pass along the node from DT so that the partitions
can be parsed.
For non-DT boards, this change has no effect.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/mtd/nand/omap2.c | 4 +++-
include/linux/platform_data/mtd-nand-omap2.h | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 3282b15..a733f15 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1331,6 +1331,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
dma_cap_mask_t mask;
unsigned sig;
struct resource *res;
+ struct mtd_part_parser_data ppdata = {};
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
@@ -1556,7 +1557,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
goto out_release_mem_region;
}
- mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts,
+ ppdata.of_node = pdata->of_node;
+ mtd_device_parse_register(&info->mtd, NULL, &ppdata, pdata->parts,
pdata->nr_parts);
platform_set_drvdata(pdev, &info->mtd);
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 24d32ca..5217d6e 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -60,6 +60,8 @@ struct omap_nand_platform_data {
int devsize;
enum omap_ecc ecc_opt;
struct gpmc_nand_regs reg;
+ /* for passing the partitions */
+ struct device_node *of_node;
};
#endif
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 0/4] RFC: OMAP GPMC DT bindings
From: Daniel Mack @ 2012-11-01 18:36 UTC (permalink / raw)
To: linux-arm-kernel
This is a series of patches to support GPMC peripherals on OMAP boards.
Depends on Linus' master +
omap-next (branch omap-for-v3.8/cleanup-headers-gpmc)
The only supported peripheral for now is NAND, but other types would be
easy to add.
Version 2 addresses details pointed out by Jon Hunter, Afzal Mohammed
and Rob Herring:
- add "reg" and "ti,hwmod" properties to Documentation
- use generic of_mtd functions and the property names defined by them,
namely "nand-bus-width" and "nand-ecc-mode"
- reduce the default register space size in the Documentation to 8K,
as found in the hwmod code
- switch to a DT layout based on ranges and address translation.
Although this property is not currently looked at as long as the
handling code still uses the runtime calculation methods, we now
have these values in the bindings, eventually allowing us to
switch the implementation with less pain.
Thanks,
Daniel
Daniel Mack (4):
mtd: omap-nand: pass device_node in platform data
ARM: OMAP: gpmc: enable hwecc for AM33xx SoCs
ARM: OMAP: gpmc: don't create devices from initcall on DT
ARM: OMAP: gpmc: add DT bindings for GPMC timings and NAND
Documentation/devicetree/bindings/bus/ti-gpmc.txt | 73 +++++++++++
.../devicetree/bindings/mtd/gpmc-nand.txt | 61 +++++++++
arch/arm/mach-omap2/gpmc-nand.c | 2 +-
arch/arm/mach-omap2/gpmc.c | 146 +++++++++++++++++++++
drivers/mtd/nand/omap2.c | 4 +-
include/linux/platform_data/mtd-nand-omap2.h | 2 +
6 files changed, 286 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
--
1.7.11.7
^ permalink raw reply
* [PATCH v3 03/11] clk: davinci - common clk utilities to init clk driver
From: Murali Karicheri @ 2012-11-01 18:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50926E03.8050102@ti.com>
On 11/01/2012 08:41 AM, Sekhar Nori wrote:
> On 10/25/2012 9:41 PM, Murali Karicheri wrote:
>> This is the common clk driver initialization functions for DaVinci
>> SoCs and other SoCs that uses similar hardware architecture.
>> clock.h also defines struct types for clock definitions in a SoC
>> and clock data type for configuring clk-mux. The initialization
>> functions are used by clock initialization code in a specific
>> platform/SoC.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>> +struct clk *davinci_plldiv_clk(const char *name, const char *parent,
>> + struct clk_plldiv_data *data)
>> +{
>> + /*
>> + * This is a PLL divider clock with divider specified by
>> + * div_reg in pll_div_data.
>> + */
>> + data->reg = ioremap(data->phys_div_reg, 4);
>> + if (WARN_ON(!data->reg))
>> + return NULL;
>> +
>> + return clk_register_davinci_plldiv(NULL, name, parent, data, &_lock);
> This function does not exist at this point. Looks like you need to swap
> 3/11 with 4/11. Also, you should also add build infrastructure
> (makefile, Kconfig) changes in the same patch that creates the file.
> There is no point in adding those separately.
>
> Thanks,
> Sekhar
>
Sekhar,
So the Makefile, Kconfig and new files should be in the same patch.
Also will re-order the 3/11 and 4/11 in the next revision.
Murali
^ permalink raw reply
* [PATCH] ARM: plat-versatile: move FPGA irq driver to drivers/irqchip
From: Linus Walleij @ 2012-11-01 18:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121101101233.17ffcf5a@skate>
On Thu, Nov 1, 2012 at 10:12 AM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> On Thu, 1 Nov 2012 10:00:19 +0100, Linus Walleij wrote:
>
>> Sounds like a separate patch but surely we can do this. Is Thomas'
>> stuff on a branch somewhere that I can then rebase upon to get
>> it upstream? I was planning to get this series as such to the
>> ARM SoC maintainers soon-ish.
>
> Not at the moment. But do you want me to put that in a branch, and
> agglomerate all the related patches (posted by Rob for GIC/VIC and by
> you for the FPGA IRQ controller), and then later send a pull request to
> Arnd with those changes?
Whatever I can base on ... I would just push the stuff you consider
stable to ARM SoC as quickly as possible so we can grab it
from there and base development on it. Then each of us can
just request the ARM SoC people to pull it and state that it
is based on that branch so they need to pull it into the same
place.
> Also, again, the whole point of the initial infrastructure in
> drivers/irqchip/ was to avoid adding per-driver header files in
> include/linux/irqchip/, so there should at least be a long term plan on
> how to remove those headers file, either by moving more platforms to
> DT, or my extending the irqchip infrastructure to cover more features.
So the header in this case looks like this:
#ifndef PLAT_FPGA_IRQ_H
#define PLAT_FPGA_IRQ_H
struct device_node;
struct pt_regs;
void fpga_handle_irq(struct pt_regs *regs);
void fpga_irq_init(void __iomem *, const char *, int, int, u32,
struct device_node *node);
int fpga_irq_of_init(struct device_node *node,
struct device_node *parent);
#endif
So this is the stuff that needs to be called from the machine
descriptor, nothing else.
Example:
MACHINE_START(INTEGRATOR, "ARM-Integrator")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100,
.reserve = integrator_reserve,
.map_io = ap_map_io,
.init_early = ap_init_early,
.init_irq = ap_init_irq,
.handle_irq = fpga_handle_irq,
.timer = &ap_timer,
.init_machine = ap_init,
.restart = integrator_restart,
MACHINE_END
The .init_irq hooks above contain some other stuff apart from just
calling these directly, but the problem remains: how to cross-call
these functions from the machine start since the IRQs are needed
by say the timer and everything else.
include/linux/irqchip/bcm2835.h look exactly the same (just one
function instead of separete DT/non-DT versions) so
there isn't exactly a precedent on how to solve this in an
elegant way.
But maybe your patch set contains the silver bullet that will decouple
this and fix everything?
Then I can do a patch to convert this and the BCM2835 too
probably...
Yours,
Linus Walleij
^ permalink raw reply
* [RFC PATCH] ARM: OMAP4: ID: Improve features detection and check
From: Santosh Shilimkar @ 2012-11-01 18:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121101170609.GA23552@kahuna>
On Thursday 01 November 2012 10:36 PM, Nishanth Menon wrote:
> On 22:05-20121101, Santosh Shilimkar wrote:
>> On Thursday 01 November 2012 09:50 PM, ivan.khoronzhuk wrote:
>>> On 11/01/2012 01:35 PM, Santosh Shilimkar wrote:
>>>> On Thursday 01 November 2012 03:53 PM, Ivan Khoronzhuk wrote:
>>>>> Replaces several flags bearing the same meaning. There is no need
>>>>> to set flags due to different omap types here, it can be checked
>>>>> in appropriate places as well.
>>>>>
>>>>> Cc: Tony Lindgren <tony@atomide.com>
>>>>> Cc: Russell King <linux@arm.linux.org.uk>
>>>>> Cc: linux-omap at vger.kernel.org
>>>>> Cc: linux-arm-kernel at lists.infradead.org
>>>>> Cc: linux-kernel at vger.kernel.org
>>>>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
>>>>> ---
[..]
>>>>> + if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
>>>>> + omap_features = OMAP4_HAS_PERF_SILICON;
>>>>
>>>> Well the detection isn't for performance/standard but there are some
>>>> features depend on it. For example 1 GHz doesn't DPLL DCC enable feature
>>>> where as 1.2 GHz, 1.5 GHz doesn't need. This is the main reason this
>>>> information is also effused. Have you considered this aspect while
>>>> creating this patch ?
>>>>
>>>> Regards
>>>> Santosh
>>>>
>>>
>>> I had considered it. There is no dependency on the features.
>>> DCC usage depends on asked frequency on the fly, not from the features.
>>> Depending on "performance/standard" feature the available frequencies
>>> should be chosen in places where they are needed, for example while
>>> initializing OPPs.
>>>
>> You are correct about the way DCC is handled in the clock code. Infact
>> all these features like L2CACHE, SGX, IVA etc is more for to display
>> boot messages.
>>
>>> Currently we have several features while it is only one indeed.
>>>
>> 1GHz, 1.2GHz, 1.5 GHz are not same since the silicon capability itself
>> is different.
>>
>> git blame tells me that Nishant has sent this update so looping him
>> if above differentiation in boot log helps.
>>
>> Nishant,
>> What's your take on removing above freq prints and marking
>> those silicon as performance silicons as the $subject patch does ?
>>
>> Regards
>> Santosh
> Yes $subject patch is a better approach compared to having freq based
> handling which just increases the number of macros we need to enable
> depending on SoC variants that we spin off the main SoC. This also
> allows us to conserve the features bitfield ahead as well.
>
> I hate to admit, but after a couple of generations of SoC spinoffs,
> my original logic is proving to be was pretty short sighted,
> unfortunately :(
>
> So, approach
> Acked-by: Nishanth Menon <nm@ti.com>
>
Thanks Nishant for clarification and ack.
With the clarification I also like the subject patch.
Feel free add.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
^ permalink raw reply
* [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single
From: Stephen Warren @ 2012-11-01 18:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351724661-29050-6-git-send-email-haojian.zhuang@gmail.com>
On 10/31/2012 05:04 PM, Haojian Zhuang wrote:
> Add comments with pinconf & gpio range in the document of
> pinctrl-single.
I'd tend to suggest separating the series to add GPIO range support and
pinconf support, especially since didn't Tony suggest a separate driver
for pinconf? Perhaps that was just for non-generic properties.
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
> +- pinctrl-single,gpio-ranges : gpio range list of phandles.
> + Must be present if gpio range phandle is specified.
> + This property should be existing in .dtsi files for those silicons.
> +
> +- pinctrl-single,gpio : array with gpio range start, size & register
> + offset. Must be present if gpio range phandle is specified.
> + This property should be existing in .dts files for those boards.
> +
> +- pinctrl-single,gpio-func : gpio function value in the pinmux register.
> + Must be present if gpio range phandle is specified.
> + This property should be existing in .dts files for those boards.
I don't see any reason why pinctrl-single,gpio or
pinctrl-single,gpio-func are board-specific rather than SoC-specific.
Surely it's the Soc HW construction that defines how the pinctrl and
GPIO modules relate to each-other? I would simply remove the last
sentence from each of the three descriptions above.
Also, isn't this list a list of properties for the main pinctrl-single
node itself? I think you should split the list up as follows:
1) A description of the main node
2) A list of required and optional properties for the main node
3) A description of what a GPIO range node is
4) A list of required and optional properties for a GPIO range node.
I think that would explain the whole structure a lot more clearly.
Oh, and why not just get rid of the pinctrl-single,gpio-ranges property
entirely, and simply make the GPIO range definitions be child nodes of
the pinctrl-single node? That would require them to either be named
according to some scheme or have some compatible property to
differentiate them from any other nodes, but I think that's workable.
> @@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
> device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
> be used when applying this change to the register.
>
> +In case pinctrl device supports gpio function, it needs to define gpio range.
> +All the phandles of gpio range list should be set in below:
> +
> + pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
> +
> + [phandle of gpio range]: {
That's a label, not a phandle. The reference to the label gets compiled
to a phandle in the DTB. The node name is missing. you should probably
just use an example label and re-write the last 3 lines as:
pinctrl-single,gpio-ranges = <&range0>;
range0: range0 {
^ permalink raw reply
* [PATCH 2/2] mfd: vexpress-sysreg: Use MMIO driver for platform LEDs
From: Pawel Moll @ 2012-11-01 17:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351792722-15250-1-git-send-email-pawel.moll@arm.com>
This patch removes custom code for controlling LEDs on
Versatile Express platform and register MFD cell for
the SYS_LED register for the leds-mmio-simple driver.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/mfd/Kconfig | 1 +
drivers/mfd/vexpress-sysreg.c | 125 +++++++++++++++--------------------------
2 files changed, 46 insertions(+), 80 deletions(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 637bcdf..611d989 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1073,6 +1073,7 @@ endmenu
config VEXPRESS_CONFIG
bool
+ select MFD_CORE
help
Platform configuration infrastructure for the ARM Ltd.
Versatile Express.
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index 059d6b1..2241b98 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -15,6 +15,7 @@
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/leds.h>
+#include <linux/mfd/core.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
@@ -406,6 +407,35 @@ static struct gpio_chip vexpress_sysreg_gpio_chip = {
};
+static struct mfd_cell vexpress_sysreg_leds = {
+ .name = "leds-mmio-simple",
+ .platform_data = &(struct mmio_simple_leds_platform_data) {
+ .reg_size = 32,
+ .shift = 0,
+ .width = 8,
+ .names = (const char *[]) {
+ "v2m:green:user1", "v2m:green:user2",
+ "v2m:green:user3", "v2m:green:user4",
+ "v2m:green:user5", "v2m:green:user6",
+ "v2m:green:user7", "v2m:green:user8",
+ },
+ .default_triggers = (const char *[]) {
+ "heartbeat", "mmc0",
+ "cpu0", "cpu1",
+ "cpu2", "cpu3",
+ "cpu4", "cpu5",
+ },
+ .init_off = true,
+ },
+ .pdata_size = sizeof(struct mmio_simple_leds_platform_data),
+ .num_resources = 1,
+ .resources = (struct resource []) {
+ DEFINE_RES_MEM(SYS_LED, 4),
+ },
+ .ignore_resource_conflicts = true,
+};
+
+
static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -438,14 +468,19 @@ static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
setup_timer(&vexpress_sysreg_config_timer,
vexpress_sysreg_config_complete, 0);
+ err = mfd_add_devices(&pdev->dev, 0, &vexpress_sysreg_leds, 1,
+ res, 0, NULL);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to add LED device! (%d)\n", err);
+ goto error_mfd_add_devices;
+ }
+
vexpress_sysreg_gpio_chip.dev = &pdev->dev;
err = gpiochip_add(&vexpress_sysreg_gpio_chip);
if (err) {
- vexpress_config_bridge_unregister(
- vexpress_sysreg_config_bridge);
dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
err);
- return err;
+ goto error_gpiochip_add;
}
vexpress_sysreg_dev = &pdev->dev;
@@ -453,6 +488,13 @@ static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
return 0;
+
+error_gpiochip_add:
+ mfd_remove_devices(&pdev->dev);
+error_mfd_add_devices:
+ vexpress_config_bridge_unregister(vexpress_sysreg_config_bridge);
+ return err;
+
}
static const struct of_device_id vexpress_sysreg_match[] = {
@@ -473,80 +515,3 @@ static int __init vexpress_sysreg_init(void)
return platform_driver_register(&vexpress_sysreg_driver);
}
core_initcall(vexpress_sysreg_init);
-
-
-#if defined(CONFIG_LEDS_CLASS)
-
-struct vexpress_sysreg_led {
- u32 mask;
- struct led_classdev cdev;
-} vexpress_sysreg_leds[] = {
- { .mask = 1 << 0, .cdev.name = "v2m:green:user1",
- .cdev.default_trigger = "heartbeat", },
- { .mask = 1 << 1, .cdev.name = "v2m:green:user2",
- .cdev.default_trigger = "mmc0", },
- { .mask = 1 << 2, .cdev.name = "v2m:green:user3",
- .cdev.default_trigger = "cpu0", },
- { .mask = 1 << 3, .cdev.name = "v2m:green:user4",
- .cdev.default_trigger = "cpu1", },
- { .mask = 1 << 4, .cdev.name = "v2m:green:user5",
- .cdev.default_trigger = "cpu2", },
- { .mask = 1 << 5, .cdev.name = "v2m:green:user6",
- .cdev.default_trigger = "cpu3", },
- { .mask = 1 << 6, .cdev.name = "v2m:green:user7",
- .cdev.default_trigger = "cpu4", },
- { .mask = 1 << 7, .cdev.name = "v2m:green:user8",
- .cdev.default_trigger = "cpu5", },
-};
-
-static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock);
-
-static void vexpress_sysreg_led_brightness_set(struct led_classdev *cdev,
- enum led_brightness brightness)
-{
- struct vexpress_sysreg_led *led = container_of(cdev,
- struct vexpress_sysreg_led, cdev);
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&vexpress_sysreg_leds_lock, flags);
-
- val = readl(vexpress_sysreg_base + SYS_LED);
- if (brightness == LED_OFF)
- val &= ~led->mask;
- else
- val |= led->mask;
- writel(val, vexpress_sysreg_base + SYS_LED);
-
- spin_unlock_irqrestore(&vexpress_sysreg_leds_lock, flags);
-}
-
-static int __init vexpress_sysreg_init_leds(void)
-{
- struct vexpress_sysreg_led *led;
- int i;
-
- /* Clear all user LEDs */
- writel(0, vexpress_sysreg_base + SYS_LED);
-
- for (i = 0, led = vexpress_sysreg_leds;
- i < ARRAY_SIZE(vexpress_sysreg_leds); i++, led++) {
- int err;
-
- led->cdev.brightness_set = vexpress_sysreg_led_brightness_set;
- err = led_classdev_register(vexpress_sysreg_dev, &led->cdev);
- if (err) {
- dev_err(vexpress_sysreg_dev,
- "Failed to register LED %d! (%d)\n",
- i, err);
- while (led--, i--)
- led_classdev_unregister(&led->cdev);
- return err;
- }
- }
-
- return 0;
-}
-device_initcall(vexpress_sysreg_init_leds);
-
-#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/2] leds: Add generic support for memory mapped LEDs
From: Pawel Moll @ 2012-11-01 17:58 UTC (permalink / raw)
To: linux-arm-kernel
LEDs are often controlled by writing to memory mapped
register. This patch adds:
1. Generic functions for platform code and drivers to create
class device for LEDs controlled by arbitrary bit masks.
The control register value is read, modified by logic AND
and OR operations with respective mask and written back.
2. A platform driver for simple use case when one or more LED
are controlled by consecutive bits in a register pointed
at by the platform device's memory resource. It can be
particularly useful for MFD cells being part of an other
device.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/leds/Kconfig | 8 ++
drivers/leds/Makefile | 1 +
drivers/leds/leds-mmio.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/leds.h | 38 +++++++
4 files changed, 297 insertions(+)
create mode 100644 drivers/leds/leds-mmio.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f508def..93707e6 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -457,6 +457,14 @@ config LEDS_BLINKM
This option enables support for the BlinkM RGB LED connected
through I2C. Say Y to enable support for the BlinkM LED.
+config LEDS_MMIO
+ tristate "Generic LED support for memory mapped peripherals"
+ depends on LEDS_CLASS
+ depends on HAS_IOMEM
+ help
+ This option enables generic support for LEDs controlled via
+ memory mapped registers.
+
config LEDS_TRIGGERS
bool "LED Trigger support"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3fb9641..8e5d0c8 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
+obj-$(CONFIG_LEDS_MMIO) += leds-mmio.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
diff --git a/drivers/leds/leds-mmio.c b/drivers/leds/leds-mmio.c
new file mode 100644
index 0000000..1ef0cda
--- /dev/null
+++ b/drivers/leds/leds-mmio.c
@@ -0,0 +1,250 @@
+/*
+ * 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
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+
+static u32 mmio_led_read(void __iomem *reg, unsigned reg_size)
+{
+ switch (reg_size) {
+ case 32:
+ return readl(reg);
+ case 16:
+ return readw(reg);
+ case 8:
+ return readb(reg);
+ }
+ return 0;
+}
+
+static void mmio_led_write(void __iomem *reg, unsigned reg_size, u32 val)
+{
+ switch (reg_size) {
+ case 32:
+ writel(val, reg);
+ return;
+ case 16:
+ writew(val, reg);
+ return;
+ case 8:
+ writeb(val, reg);
+ return;
+ }
+}
+
+
+struct mmio_led {
+ struct led_classdev cdev;
+ spinlock_t *lock;
+ void __iomem *reg;
+ unsigned reg_size;
+ u32 off_and_mask, off_or_mask;
+ u32 on_and_mask, on_or_mask;
+};
+
+static void mmio_led_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct mmio_led *led = container_of(cdev, struct mmio_led, cdev);
+ unsigned long uninitialized_var(flags);
+ u32 val;
+
+ if (led->lock)
+ spin_lock_irqsave(led->lock, flags);
+
+ val = mmio_led_read(led->reg, led->reg_size);
+ if (brightness == LED_OFF) {
+ val &= led->off_and_mask;
+ val |= led->off_or_mask;
+ } else {
+ val &= led->on_and_mask;
+ val |= led->on_or_mask;
+ }
+ mmio_led_write(led->reg, led->reg_size, val);
+
+ if (led->lock)
+ spin_unlock_irqrestore(led->lock, flags);
+};
+
+static enum led_brightness mmio_led_brightness_get(struct led_classdev *cdev)
+{
+ struct mmio_led *led = container_of(cdev, struct mmio_led, cdev);
+ unsigned long uninitialized_var(flags);
+ u32 val;
+
+ if (led->lock)
+ spin_lock_irqsave(led->lock, flags);
+ val = mmio_led_read(led->reg, led->reg_size);
+ if (led->lock)
+ spin_unlock_irqrestore(led->lock, flags);
+
+ if (((val & led->on_and_mask) | led->on_or_mask) == val)
+ return LED_FULL;
+ else
+ return LED_OFF;
+}
+
+struct mmio_led *mmio_led_register(struct device *parent, spinlock_t *lock,
+ const char *name, const char *default_trigger,
+ void __iomem *reg, unsigned reg_size, u32 off_and_mask,
+ u32 off_or_mask, u32 on_and_mask, u32 on_or_mask)
+{
+ struct mmio_led *led;
+ int err;
+
+ if (WARN_ON(reg_size != 8 && reg_size != 16 && reg_size != 32))
+ return ERR_PTR(-EINVAL);
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ return ERR_PTR(-ENOMEM);
+
+ led->cdev.brightness_set = mmio_led_brightness_set;
+ led->cdev.brightness_get = mmio_led_brightness_get;
+ led->cdev.name = name;
+ led->cdev.default_trigger = default_trigger;
+
+ led->lock = lock;
+ led->reg = reg;
+ led->reg_size = reg_size;
+ led->off_and_mask = off_and_mask;
+ led->off_or_mask = off_or_mask;
+ led->on_and_mask = on_and_mask;
+ led->on_or_mask = on_or_mask;
+
+ err = led_classdev_register(parent, &led->cdev);
+ if (err) {
+ kfree(led);
+ return ERR_PTR(err);
+ }
+
+ return led;
+}
+EXPORT_SYMBOL_GPL(mmio_led_register);
+
+void mmio_led_unregister(struct mmio_led *led)
+{
+ led_classdev_unregister(&led->cdev);
+ kfree(led);
+}
+EXPORT_SYMBOL_GPL(mmio_led_unregister);
+
+
+struct mmio_simple_leds {
+ spinlock_t lock;
+ int num_leds;
+ struct mmio_led *leds[0];
+};
+
+static int __devinit mmio_simple_leds_probe(struct platform_device *pdev)
+{
+ struct mmio_simple_leds_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct mmio_simple_leds *leds;
+ void __iomem *reg;
+ u32 val, mask;
+ int i;
+
+ if (!pdata)
+ return -EINVAL;
+
+ if (pdata->reg_size != 8 && pdata->reg_size != 16 &&
+ pdata->reg_size != 32)
+ return -EFAULT;
+
+ leds = devm_kzalloc(&pdev->dev, sizeof(*leds) +
+ sizeof(leds->leds) * pdata->width, GFP_KERNEL);
+ if (!leds)
+ return -ENOMEM;
+ spin_lock_init(&leds->lock);
+
+ if ((!pdev->mfd_cell || !pdev->mfd_cell->ignore_resource_conflicts) &&
+ !devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!reg)
+ return -ENOMEM;
+
+ val = mmio_led_read(reg, pdata->reg_size);
+ mask = ((1 << pdata->width) - 1) << pdata->shift;
+ if ((pdata->init_full && pdata->active_low) ||
+ (pdata->init_off && !pdata->active_low))
+ val &= ~mask;
+ else if ((pdata->init_off && pdata->active_low) ||
+ (pdata->init_full && !pdata->active_low))
+ val |= mask;
+ mmio_led_write(reg, pdata->reg_size, val);
+
+ leds->num_leds = pdata->width;
+ for (i = 0; i < leds->num_leds; i++) {
+ unsigned shift = pdata->shift + i;
+ u32 and_mask = ~BIT(shift);
+ u32 off_or_mask = pdata->active_low ? BIT(shift) : 0;
+ u32 on_or_mask = pdata->active_low ? 0 : BIT(shift);
+ struct mmio_led *led = mmio_led_register(&pdev->dev,
+ &leds->lock, pdata->names[i],
+ pdata->default_triggers ?
+ pdata->default_triggers[i] : NULL,
+ reg, pdata->reg_size, and_mask, off_or_mask,
+ and_mask, on_or_mask);
+
+ if (IS_ERR(led)) {
+ while (--i >= 0)
+ mmio_led_unregister(leds->leds[i]);
+ return PTR_ERR(led);
+ }
+ leds->leds[i] = led;
+ }
+
+ platform_set_drvdata(pdev, leds);
+
+ return 0;
+}
+
+static int __devexit mmio_simple_leds_remove(struct platform_device *pdev)
+{
+ struct mmio_simple_leds *leds = platform_get_drvdata(pdev);
+ int i;
+
+ platform_set_drvdata(pdev, NULL);
+
+ for (i = 0; i < leds->num_leds; i++)
+ mmio_led_unregister(leds->leds[i]);
+
+ return 0;
+}
+
+static struct platform_driver mmio_simple_leds_driver = {
+ .probe = mmio_simple_leds_probe,
+ .remove = __devexit_p(mmio_simple_leds_remove),
+ .driver = {
+ .name = "leds-mmio-simple",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(mmio_simple_leds_driver);
+
+MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
+MODULE_DESCRIPTION("MMIO LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-mmio-simple");
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 6e53bb3..a6338b0 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -241,6 +241,44 @@ struct gpio_led_platform_data {
struct platform_device *gpio_led_register_device(
int id, const struct gpio_led_platform_data *pdata);
+/* For the leds-mmio driver */
+
+struct mmio_led;
+
+#if defined(CONFIG_LEDS_MMIO)
+/* Returns ERR_PTR in case of error */
+struct mmio_led *mmio_led_register(struct device *parent, spinlock_t *lock,
+ const char *name, const char *default_trigger,
+ void __iomem *reg, unsigned reg_size, u32 off_and_mask,
+ u32 off_or_mask, u32 on_and_mask, u32 on_or_mask);
+void mmio_led_unregister(struct mmio_led *led);
+#else
+struct mmio_led *mmio_led_register(struct device *parent, spinlock_t *lock,
+ const char *name, const char *default_trigger,
+ void __iomem *reg, unsigned reg_size, u32 off_and_mask,
+ u32 off_or_mask, u32 on_and_mask, u32 on_or_mask)
+{
+ return NULL;
+}
+
+void mmio_led_unregister(struct mmio_led *led)
+{
+}
+#endif
+
+struct mmio_simple_leds_platform_data {
+ unsigned reg_size; /* Register size (8/16/32) */
+ unsigned shift; /* First bit controlling LEDs */
+ unsigned width; /* Number of consecutive bits */
+ const char **names; /* Must define 'width' names */
+ const char **default_triggers; /* NULL or 'width' strings */
+ bool active_low;
+ bool init_full;
+ bool init_off;
+};
+
+/* CPU led trigger */
+
enum cpu_led_event {
CPU_LED_IDLE_START, /* CPU enters idle */
CPU_LED_IDLE_END, /* CPU idle ends */
--
1.7.10.4
^ permalink raw reply related
* gic_set_affinity
From: Robert Beckett @ 2012-11-01 17:54 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
I was looking through the arm gic code while debugging a problem I am
having, and noticed something in gic_set_affinity.
When something comes along and setts an irq affinity mask (e.g.
through /proc/irq/<irq>/smp_affinity_mask), the calls goes like so :
...
1. irq_set_affinity : grabs the desc->lock
2. __irq_set_affinity_locked : calls chip->irq_set_affinity
3. gic_set_affinity : writes a new mask to the gic distributor
my question is, what happens if an interrupt is raised between 1 and 3?
To me, it looks like the interrupt could end up being handled on 2
cpus. When it is raised, the handler will be called and sit spinning
for desc->lock (e.g. in handle_fasteoi_irq). The mask will be set to
set the affinity to the new cpu, the new cpu will receive the
interrupt as it has not been ackd or disabled yet, and the handler
will be called on the second cpu and will wait for the same lock in
the handler. Once the affinity setting calls have finished, the lock
is released, and whichever cpu gets the lock will handle the interrupt
while still locking out the other cpu. Once it finishes, the other cpu
will try to handle it leading to an interrupt handler call for an
interrupt that no longer exists, which could lead to spurious
interrupt if it returns IRQ_NONE because it cant see that the
interrupt is raised.
Is this what will happen? If so, the interrupt should be masked across
the affinity setting so that it cant be raised on both cpus.
if I have just missed something obvious, then please let me know...
Cheers.
Bob
^ permalink raw reply
* [GIT PULL] ARM: OMAP: DTS for 3.8
From: Benoit Cousson @ 2012-11-01 17:14 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tony,
Please pull some more OMAP5 and AM33xx data for 3.8.
The branch contains as well some cleanup and the omap3-beagle support since the previous one was in fact a beagle-xm.
Thanks,
Benoit
The following changes since commit 8f0d8163b50e01f398b14bcd4dc039ac5ab18d64:
Linus Torvalds (1):
Linux 3.7-rc3
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git for_3.8/dts
Afzal Mohammed (1):
ARM: dts: AM33XX: Add rtc node
AnilKumar Ch (8):
ARM: dts: AM33XX: Add device tree OPP table
ARM: dts: AM33XX: Add basic pinctrl device tree data
ARM: dts: AM33XX: Add D_CAN device tree data
ARM: dts: AM33XX: Add lis331dlh device tree data to am335x-evm
ARM: dts: AM33XX: Add temperature sensor device tree data to am335x-evm
ARM: dts: AM33XX: Add tsl2550 ambient light sensor DT data
ARM: dts: Add am335x-evmsk.dts
Documentation: dt: i2c: Update trivial-devices list
Benoit Cousson (2):
ARM: dts: OMAP: Move interrupt-parent to the root node to avoid duplication
ARM: dts: OMAP: Rename pandaES and var_som for consistency
Jon Hunter (6):
ARM: dts: Add omap3-beagle.dts
ARM: dts: OMAP: Add timer nodes
ARM: dts: OMAP: Add counter-32k nodes
ARM: dts: OMAP4: Update timer addresses
ARM: dts: OMAP5: Add timer nodes
ARM: dts: OMAP5: Add counter node
Kishon Vijay Abraham I (3):
ARM: dts: Add twl6030-usb data
ARM: dts: Add twl4030-usb data
ARM: dts: OMAP4: add *reg* property for ocp2scp
Philip, Avinash (1):
ARM: dts: AM33XX: Add SPI node
Sebastien Guiriec (4):
ARM: dts: omap5: Update GPIO with address space and interrupts
ARM: dts: omap5: Update I2C with address space and interrupts
ARM: dts: omap5: Update UART with address space and interrupts
ARM: dts: omap5: Update MMC with address space and interrupts
.../devicetree/bindings/arm/omap/counter.txt | 15 ++
.../devicetree/bindings/arm/omap/timer.txt | 31 ++++
.../devicetree/bindings/bus/omap-ocp2scp.txt | 18 ++
.../devicetree/bindings/i2c/trivial-devices.txt | 2 +
arch/arm/boot/dts/Makefile | 5 +-
arch/arm/boot/dts/am335x-bone.dts | 6 +
arch/arm/boot/dts/am335x-evm.dts | 55 +++++++
arch/arm/boot/dts/am335x-evmsk.dts | 166 ++++++++++++++++++++
arch/arm/boot/dts/am33xx.dtsi | 139 +++++++++++++++--
arch/arm/boot/dts/omap2.dtsi | 86 ++++++++++
arch/arm/boot/dts/omap2420.dtsi | 16 ++-
arch/arm/boot/dts/omap2430.dtsi | 19 ++-
arch/arm/boot/dts/omap3-beagle-xm.dts | 6 -
arch/arm/boot/dts/omap3-beagle.dts | 67 ++++++++
arch/arm/boot/dts/omap3.dtsi | 107 ++++++++++++-
.../dts/{omap4-pandaES.dts => omap4-panda-es.dts} | 0
arch/arm/boot/dts/omap4-panda.dts | 4 +
arch/arm/boot/dts/omap4-sdp.dts | 4 +
.../dts/{omap4-var_som.dts => omap4-var-som.dts} | 0
arch/arm/boot/dts/omap4.dtsi | 105 ++++++++++++-
arch/arm/boot/dts/omap5.dtsi | 156 +++++++++++++++++-
arch/arm/boot/dts/twl4030.dtsi | 27 +++
arch/arm/boot/dts/twl6030.dtsi | 5 +
23 files changed, 989 insertions(+), 50 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/omap/counter.txt
create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt
create mode 100644 arch/arm/boot/dts/am335x-evmsk.dts
create mode 100644 arch/arm/boot/dts/omap3-beagle.dts
rename arch/arm/boot/dts/{omap4-pandaES.dts => omap4-panda-es.dts} (100%)
rename arch/arm/boot/dts/{omap4-var_som.dts => omap4-var-som.dts} (100%)
^ permalink raw reply
* [RFC PATCH] ARM: OMAP4: ID: Improve features detection and check
From: Nishanth Menon @ 2012-11-01 17:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5092A4DF.4080405@ti.com>
On 22:05-20121101, Santosh Shilimkar wrote:
> On Thursday 01 November 2012 09:50 PM, ivan.khoronzhuk wrote:
> >On 11/01/2012 01:35 PM, Santosh Shilimkar wrote:
> >>On Thursday 01 November 2012 03:53 PM, Ivan Khoronzhuk wrote:
> >>>Replaces several flags bearing the same meaning. There is no need
> >>>to set flags due to different omap types here, it can be checked
> >>>in appropriate places as well.
> >>>
> >>>Cc: Tony Lindgren <tony@atomide.com>
> >>>Cc: Russell King <linux@arm.linux.org.uk>
> >>>Cc: linux-omap at vger.kernel.org
> >>>Cc: linux-arm-kernel at lists.infradead.org
> >>>Cc: linux-kernel at vger.kernel.org
> >>>Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
> >>>---
> >>> arch/arm/mach-omap2/id.c | 25 +++++++------------------
> >>> arch/arm/mach-omap2/soc.h | 8 ++------
> >>> 2 files changed, 9 insertions(+), 24 deletions(-)
> >>>
> >>>diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
> >>>index cf2362c..3c47a19 100644
> >>>--- a/arch/arm/mach-omap2/id.c
> >>>+++ b/arch/arm/mach-omap2/id.c
> >>>@@ -28,6 +28,9 @@
> >>> #include "soc.h"
> >>> #include "control.h"
> >>>
> >>>+#define OMAP4_SILICON_TYPE_STANDARD 0x01
> >>>+#define OMAP4_SILICON_TYPE_PERFORMANCE 0x02
> >>>+
> >>> static unsigned int omap_revision;
> >>> static const char *cpu_rev;
> >>> u32 omap_features;
> >>>@@ -273,25 +276,11 @@ void __init omap4xxx_check_features(void)
> >>> {
> >>> u32 si_type;
> >>>
> >>>- if (cpu_is_omap443x())
> >>>- omap_features |= OMAP4_HAS_MPU_1GHZ;
> >>>-
> >>>+ si_type =
> >>>+ (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16)
> >>>& 0x03;
> >>>
> >>>- if (cpu_is_omap446x()) {
> >>>- si_type =
> >>>- read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1);
> >>>- switch ((si_type & (3 << 16)) >> 16) {
> >>>- case 2:
> >>>- /* High performance device */
> >>>- omap_features |= OMAP4_HAS_MPU_1_5GHZ;
> >>>- break;
> >>>- case 1:
> >>>- default:
> >>>- /* Standard device */
> >>>- omap_features |= OMAP4_HAS_MPU_1_2GHZ;
> >>>- break;
> >>>- }
> >>>- }
> >>>+ if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
> >>>+ omap_features = OMAP4_HAS_PERF_SILICON;
> >>
> >>Well the detection isn't for performance/standard but there are some
> >>features depend on it. For example 1 GHz doesn't DPLL DCC enable feature
> >>where as 1.2 GHz, 1.5 GHz doesn't need. This is the main reason this
> >>information is also effused. Have you considered this aspect while
> >>creating this patch ?
> >>
> >>Regards
> >>Santosh
> >>
> >
> >I had considered it. There is no dependency on the features.
> >DCC usage depends on asked frequency on the fly, not from the features.
> >Depending on "performance/standard" feature the available frequencies
> >should be chosen in places where they are needed, for example while
> >initializing OPPs.
> >
> You are correct about the way DCC is handled in the clock code. Infact
> all these features like L2CACHE, SGX, IVA etc is more for to display
> boot messages.
>
> >Currently we have several features while it is only one indeed.
> >
> 1GHz, 1.2GHz, 1.5 GHz are not same since the silicon capability itself
> is different.
>
> git blame tells me that Nishant has sent this update so looping him
> if above differentiation in boot log helps.
>
> Nishant,
> What's your take on removing above freq prints and marking
> those silicon as performance silicons as the $subject patch does ?
>
> Regards
> Santosh
Yes $subject patch is a better approach compared to having freq based
handling which just increases the number of macros we need to enable
depending on SoC variants that we spin off the main SoC. This also
allows us to conserve the features bitfield ahead as well.
I hate to admit, but after a couple of generations of SoC spinoffs,
my original logic is proving to be was pretty short sighted,
unfortunately :(
So, approach
Acked-by: Nishanth Menon <nm@ti.com>
--
Regards,
Nishanth Menon
^ permalink raw reply
* [PATCH] ARM: dts: mxs: Add 16 bits LCD screen muxing options for I.MX28
From: Gwenhael Goavec-Merou @ 2012-11-01 16:50 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Julien Boibessot <julien.boibessot@armadeus.com>
Signed-off-by: Gwenhael Goavec-Merou <gwenhael.goavec-merou@armadeus.com>
---
arch/arm/boot/dts/imx28.dtsi | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 2b607aa..8e2c8b2 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -544,6 +544,31 @@
fsl,pull-up = <0>;
};
+ lcdif_16bit_pins_a: lcdif-16bit at 0 {
+ reg = <0>;
+ fsl,pinmux-ids = <
+ 0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
+ 0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
+ 0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
+ 0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
+ 0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
+ 0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
+ 0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
+ 0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
+ 0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
+ 0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
+ 0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
+ 0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
+ 0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
+ 0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
+ 0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
+ 0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+ >;
+ fsl,drive-strength = <0>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <0>;
+ };
+
can0_pins_a: can0 at 0 {
reg = <0>;
fsl,pinmux-ids = <
--
1.7.8.6
^ permalink raw reply related
* [RFC PATCH] ARM: OMAP4: ID: Improve features detection and check
From: Santosh Shilimkar @ 2012-11-01 16:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5092A156.4000601@ti.com>
On Thursday 01 November 2012 09:50 PM, ivan.khoronzhuk wrote:
> On 11/01/2012 01:35 PM, Santosh Shilimkar wrote:
>> On Thursday 01 November 2012 03:53 PM, Ivan Khoronzhuk wrote:
>>> Replaces several flags bearing the same meaning. There is no need
>>> to set flags due to different omap types here, it can be checked
>>> in appropriate places as well.
>>>
>>> Cc: Tony Lindgren <tony@atomide.com>
>>> Cc: Russell King <linux@arm.linux.org.uk>
>>> Cc: linux-omap at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
>>> ---
>>> arch/arm/mach-omap2/id.c | 25 +++++++------------------
>>> arch/arm/mach-omap2/soc.h | 8 ++------
>>> 2 files changed, 9 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
>>> index cf2362c..3c47a19 100644
>>> --- a/arch/arm/mach-omap2/id.c
>>> +++ b/arch/arm/mach-omap2/id.c
>>> @@ -28,6 +28,9 @@
>>> #include "soc.h"
>>> #include "control.h"
>>>
>>> +#define OMAP4_SILICON_TYPE_STANDARD 0x01
>>> +#define OMAP4_SILICON_TYPE_PERFORMANCE 0x02
>>> +
>>> static unsigned int omap_revision;
>>> static const char *cpu_rev;
>>> u32 omap_features;
>>> @@ -273,25 +276,11 @@ void __init omap4xxx_check_features(void)
>>> {
>>> u32 si_type;
>>>
>>> - if (cpu_is_omap443x())
>>> - omap_features |= OMAP4_HAS_MPU_1GHZ;
>>> -
>>> + si_type =
>>> + (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16)
>>> & 0x03;
>>>
>>> - if (cpu_is_omap446x()) {
>>> - si_type =
>>> - read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1);
>>> - switch ((si_type & (3 << 16)) >> 16) {
>>> - case 2:
>>> - /* High performance device */
>>> - omap_features |= OMAP4_HAS_MPU_1_5GHZ;
>>> - break;
>>> - case 1:
>>> - default:
>>> - /* Standard device */
>>> - omap_features |= OMAP4_HAS_MPU_1_2GHZ;
>>> - break;
>>> - }
>>> - }
>>> + if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
>>> + omap_features = OMAP4_HAS_PERF_SILICON;
>>
>> Well the detection isn't for performance/standard but there are some
>> features depend on it. For example 1 GHz doesn't DPLL DCC enable feature
>> where as 1.2 GHz, 1.5 GHz doesn't need. This is the main reason this
>> information is also effused. Have you considered this aspect while
>> creating this patch ?
>>
>> Regards
>> Santosh
>>
>
> I had considered it. There is no dependency on the features.
> DCC usage depends on asked frequency on the fly, not from the features.
> Depending on "performance/standard" feature the available frequencies
> should be chosen in places where they are needed, for example while
> initializing OPPs.
>
You are correct about the way DCC is handled in the clock code. Infact
all these features like L2CACHE, SGX, IVA etc is more for to display
boot messages.
> Currently we have several features while it is only one indeed.
>
1GHz, 1.2GHz, 1.5 GHz are not same since the silicon capability itself
is different.
git blame tells me that Nishant has sent this update so looping him
if above differentiation in boot log helps.
Nishant,
What's your take on removing above freq prints and marking
those silicon as performance silicons as the $subject patch does ?
Regards
Santosh
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox