* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-17 19:22 [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to support Rev B boards Sean MacLennan
@ 2008-04-27 19:25 ` Sean MacLennan
2008-04-28 0:58 ` Stephen Rothwell
2008-04-28 18:53 ` Sean MacLennan
2008-04-29 1:47 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
2 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-27 19:25 UTC (permalink / raw)
To: linuxppc-dev
Update. HW decided that the panic was bad. Added a flashing led to the
critical temperature.
Cheers,
Sean
PIKA Warp: Update platform code to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Full DTM support including critical temperature.
* Added POST information.
* Removed LED function, moved to new LED driver.
* Moved ad7414 to new style I2C initialization.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index eb108a8..2178021 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -10,6 +10,7 @@
#include "ops.h"
#include "4xx.h"
#include "cuboot.h"
+#include "stdio.h"
#define TARGET_4xx
#define TARGET_44x
@@ -17,0 +18,0 @@
static bd_t bd;
-static void warp_fixups(void)
+static void warp_fixup_one_nor(u32 from, u32 to)
{
- unsigned long sysclk = 66000000;
+ void *devp;
+ char name[50];
+ u32 v[2];
+
+ sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from);
+
+ devp = finddevice(name);
+ if (!devp)
+ return;
+
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[0] = to;
+ setprop(devp, "reg", v, sizeof(v));
+
+ printf("NOR 64M fixup %x -> %x\r\n", from, to);
+ }
+}
+
- ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+static void warp_fixups(void)
+{
+ ibm440ep_fixup_clocks(66000000, 11059200, 50000000);
ibm4xx_sdram_fixup_memsize();
ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+
+ /* Fixup for 64M flash on Rev A boards. */
+ if (bd.bi_flashsize == 0x4000000) {
+ void *devp;
+ u32 v[3];
+
+ devp = finddevice("/plb/opb/ebc/nor_flash@0,0");
+ if (!devp)
+ return;
+
+ /* Fixup the size */
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[2] = bd.bi_flashsize;
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* Fixup parition offsets */
+ warp_fixup_one_nor(0x300000, 0x3f00000);
+ warp_fixup_one_nor(0x340000, 0x3f40000);
+ warp_fixup_one_nor(0x380000, 0x3f80000);
+ }
}
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index b04a52e..fa070b0 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -132,40 +132,33 @@
fpga@2,0 {
compatible = "pika,fpga";
- reg = <2 0 2200>;
+ reg = <2 0 1000>;
interrupts = <18 8>;
interrupt-parent = <&UIC0>;
};
+ fpga@2,4000 {
+ compatible = "pika,fpga-sd";
+ reg = <2 4000 A00>;
+ };
+
nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
+ compatible = "amd,s29gl032a", "cfi-flash";
bank-width = <2>;
- reg = <0 0 4000000>;
+ reg = <0 0 400000>;
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0 180000>;
- };
- partition@180000 {
- label = "root";
- reg = <180000 3480000>;
- };
- partition@3600000 {
- label = "user";
- reg = <3600000 900000>;
- };
- partition@3f00000 {
+ partition@300000 {
label = "fpga";
- reg = <3f00000 40000>;
+ reg = <300000 40000>;
};
- partition@3f40000 {
+ partition@340000 {
label = "env";
- reg = <3f40000 40000>;
+ reg = <340000 40000>;
};
- partition@3f80000 {
+ partition@380000 {
label = "u-boot";
- reg = <3f80000 80000>;
+ reg = <380000 80000>;
};
};
};
@@ -186,6 +179,16 @@
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
interrupts = <2 4>;
+ index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ad7414@4a {
+ compatible = "adi,ad7414";
+ reg = <4a>;
+ interrupts = <19 8>;
+ interrupt-parent = <&UIC0>;
+ };
};
GPIO0: gpio@ef600b00 {
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318..4c6a2a5 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/of_platform.h>
#include <asm/machdep.h>
+
#ifdef CONFIG_MTD_NAND_NDFC
#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
{
.name = "root",
.offset = 0x0200000,
- .size = 0x3400000
+ .size = 0x3E00000
+ },
+ {
+ .name = "persistent",
+ .offset = 0x4000000,
+ .size = 0x4000000
},
{
- .name = "user",
- .offset = 0x3600000,
- .size = 0x0A00000
+ .name = "persistent1",
+ .offset = 0x8000000,
+ .size = 0x4000000
},
+ {
+ .name = "persistent2",
+ .offset = 0xC000000,
+ .size = 0x4000000
+ }
};
struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
.resource = &warp_ndfc,
};
-static struct nand_ecclayout nand_oob_16 = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2, 3, 6, 7 },
- .oobfree = { {.offset = 8, .length = 16} }
-};
-
+/* Do NOT set the ecclayout: let it default so it is correct for both
+ * 64M and 256M flash chips.
+ */
static struct platform_nand_chip warp_nand_chip0 = {
.nr_chips = 1,
.chip_offset = CS_NAND_0,
.nr_partitions = ARRAY_SIZE(nand_parts),
.partitions = nand_parts,
- .chip_delay = 50,
- .ecclayout = &nand_oob_16,
+ .chip_delay = 20,
.priv = &warp_chip0_settings,
};
@@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
static int warp_setup_nand_flash(void)
{
+ struct device_node *np;
+
+ /* Try to detect a rev A based on NOR size. */
+ np = of_find_compatible_node(NULL, NULL, "cfi-flash");
+ if (np) {
+ struct property *pp;
+
+ pp = of_find_property(np, "reg", NULL);
+ if (pp && (pp->length == 12)) {
+ u32 *v = pp->value;
+ if (v[2] == 0x4000000)
+ /* Rev A = 64M NAND */
+ warp_nand_chip0.nr_partitions = 2;
+ }
+ of_node_put(np);
+ }
+
platform_device_register(&warp_ndfc_device);
platform_device_register(&warp_nand_device);
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf615..1b2d09e 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,10 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pika.h>
+#include <linux/delay.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
{},
};
+static __initdata struct i2c_board_info warp_i2c_info[] = {
+ { I2C_BOARD_INFO("ad7414", 0x4a) }
+};
+
+static int __init warp_arch_init(void)
+{
+ /* This should go away once support is moved to the dts. */
+ i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
+ return 0;
+}
+machine_arch_initcall(warp, warp_arch_init);
+
static int __init warp_device_probe(void)
{
of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +68,200 @@ define_machine(warp) {
};
-#define LED_GREEN (0x80000000 >> 0)
-#define LED_RED (0x80000000 >> 1)
+/* I am not sure this is the best place for this... */
+static int __init warp_post_info(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ u32 post1, post2;
+
+ /* Sighhhh... POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL)
+ return -ENOENT;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL)
+ return -ENOENT;
+
+ post1 = in_be32(fpga + 0x40);
+ post2 = in_be32(fpga + 0x44);
+
+ iounmap(fpga);
+
+ if (post1 || post2)
+ printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
+ else
+ printk(KERN_INFO "Warp POST OK\n");
+
+ return 0;
+}
+machine_late_initcall(warp, warp_post_info);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+static LIST_HEAD(dtm_shutdown_list);
+static void __iomem *dtm_fpga;
+static void __iomem *gpio_base;
-/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
-void warp_set_power_leds(int green, int red)
+
+struct dtm_shutdown {
+ struct list_head list;
+ void (*func)(void *arg);
+ void *arg;
+};
+
+
+int dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ struct dtm_shutdown *shutdown;
+
+ shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
+ if (shutdown == NULL)
+ return -ENOMEM;
+
+ shutdown->func = func;
+ shutdown->arg = arg;
+
+ list_add(&shutdown->list, &dtm_shutdown_list);
+
+ return 0;
+}
+
+int dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
{
- static void __iomem *gpio_base = NULL;
- unsigned leds;
-
- if (gpio_base == NULL) {
- struct device_node *np;
-
- /* Power LEDS are on the second GPIO controller */
- np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
- if (np)
- np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return;
+ struct dtm_shutdown *shutdown;
+
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ if (shutdown->func == func && shutdown->arg == arg) {
+ list_del(&shutdown->list);
+ kfree(shutdown);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static irqreturn_t temp_isr(int irq, void *context)
+{
+ struct dtm_shutdown *shutdown;
+
+ local_irq_disable();
+
+ /* Run through the shutdown list. */
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ shutdown->func(shutdown->arg);
+
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+
+ while (1) {
+ if (dtm_fpga) {
+ unsigned reset = in_be32(dtm_fpga + 0x14);
+ out_be32(dtm_fpga + 0x14, reset);
+ }
+
+ if (gpio_base) {
+ unsigned leds = in_be32(gpio_base);
+
+ /* green off, red toggle */
+ leds &= ~0x80000000;
+ leds ^= 0x40000000;
+
+ out_be32(gpio_base, leds);
}
+ mdelay(500);
+ }
+}
+
+static void pika_setup_critical_temp(struct i2c_client *client)
+{
+ struct device_node *np;
+ int irq, rc;
+
+ /* Setup power LEDS for possible critical temp */
+ np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
+ if (np)
+ np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
+ if (np) {
gpio_base = of_iomap(np, 0);
of_node_put(np);
- if (gpio_base == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return;
- }
}
- leds = in_be32(gpio_base);
+ /* These registers are in 1 degree increments. */
+ i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
+ i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
- switch (green) {
- case 0: leds &= ~LED_GREEN; break;
- case 1: leds |= LED_GREEN; break;
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
+ return;
}
- switch (red) {
- case 0: leds &= ~LED_RED; break;
- case 1: leds |= LED_RED; break;
+
+ irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
+ return;
}
- out_be32(gpio_base, leds);
+ rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
+ if (rc) {
+ printk(KERN_ERR __FILE__
+ ": Unable to request ad7414 irq %d = %d\n", irq, rc);
+ return;
+ }
}
-EXPORT_SYMBOL(warp_set_power_leds);
+static inline void pika_dtm_check_fan(void __iomem *fpga)
+{
+ static int fan_state;
+ u32 fan = in_be32(fpga + 0x34) & (1 << 14);
+
+ if (fan_state != fan) {
+ fan_state = fan;
+ if (fan)
+ printk(KERN_WARNING "Fan rotation error detected."
+ " Please check hardware.\n");
+ }
+}
-#ifdef CONFIG_SENSORS_AD7414
static int pika_dtm_thread(void __iomem *fpga)
{
- extern int ad7414_get_temp(int index);
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ /* We loop in case either driver was compiled as a module and
+ * has not been insmoded yet.
+ */
+ while (!(adap = i2c_get_adapter(0))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ while (1) {
+ list_for_each_entry(client, &adap->clients, list)
+ if (client->addr == 0x4a)
+ goto found_it;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+found_it:
+ i2c_put_adapter(adap);
+
+ pika_setup_critical_temp(client);
+
+ printk(KERN_INFO "PIKA DTM thread running.\n");
while (!kthread_should_stop()) {
- int temp = ad7414_get_temp(0);
+ u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
+ out_be32(fpga + 0x20, temp);
- out_be32(fpga, temp);
+ pika_dtm_check_fan(fpga);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
@@ -115,37 +270,44 @@ static int pika_dtm_thread(void __iomem *fpga)
return 0;
}
+
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
struct device_node *np;
- struct resource res;
- void __iomem *fpga;
np = of_find_compatible_node(NULL, NULL, "pika,fpga");
if (np == NULL)
return -ENOENT;
- /* We do not call of_iomap here since it would map in the entire
- * fpga space, which is over 8k.
- */
- if (of_address_to_resource(np, 0, &res)) {
- of_node_put(np);
- return -ENOENT;
- }
+ dtm_fpga = of_iomap(np, 0);
of_node_put(np);
-
- fpga = ioremap(res.start, 0x24);
- if (fpga == NULL)
+ if (dtm_fpga == NULL)
return -ENOENT;
- dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
- iounmap(fpga);
+ iounmap(dtm_fpga);
return PTR_ERR(dtm_thread);
}
return 0;
}
-device_initcall(pika_dtm_start);
+machine_late_initcall(warp, pika_dtm_start);
+
+#else /* !CONFIG_SENSORS_AD7414 */
+
+int dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
+int dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
#endif
+
+EXPORT_SYMBOL(dtm_register_shutdown);
+EXPORT_SYMBOL(dtm_unregister_shutdown);
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-27 19:25 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev " Sean MacLennan
@ 2008-04-28 0:58 ` Stephen Rothwell
2008-04-28 1:51 ` Grant Likely
2008-04-28 2:31 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev " Sean MacLennan
0 siblings, 2 replies; 28+ messages in thread
From: Stephen Rothwell @ 2008-04-28 0:58 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 895 bytes --]
Hi Sean,
On Sun, 27 Apr 2008 15:25:46 -0400 Sean MacLennan <smaclennan@pikatech.com> wrote:
>
> +++ b/arch/powerpc/platforms/44x/warp-nand.c
> @@ -11,8 +11,10 @@
> #include <linux/mtd/partitions.h>
> #include <linux/mtd/nand.h>
> #include <linux/mtd/ndfc.h>
> +#include <linux/of_platform.h>
You really want linux.of.h (unless there was some preexisting reason to
require of_platform.h).
> +static void pika_setup_critical_temp(struct i2c_client *client)
> +{
> + struct device_node *np;
> + int irq, rc;
> +
> + /* Setup power LEDS for possible critical temp */
> + np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
> + if (np)
> + np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
Did you really mean to test if (!np) above instead?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 0:58 ` Stephen Rothwell
@ 2008-04-28 1:51 ` Grant Likely
2008-04-28 2:25 ` Sean MacLennan
2008-04-28 2:31 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev " Sean MacLennan
1 sibling, 1 reply; 28+ messages in thread
From: Grant Likely @ 2008-04-28 1:51 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, Sean MacLennan
On Sun, Apr 27, 2008 at 6:58 PM, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi Sean,
>
>
> On Sun, 27 Apr 2008 15:25:46 -0400 Sean MacLennan <smaclennan@pikatech.com> wrote:
> >
> > +++ b/arch/powerpc/platforms/44x/warp-nand.c
> > @@ -11,8 +11,10 @@
> > #include <linux/mtd/partitions.h>
> > #include <linux/mtd/nand.h>
> > #include <linux/mtd/ndfc.h>
> > +#include <linux/of_platform.h>
>
> You really want linux.of.h (unless there was some preexisting reason to
> require of_platform.h).
>
>
> > +static void pika_setup_critical_temp(struct i2c_client *client)
> > +{
> > + struct device_node *np;
> > + int irq, rc;
> > +
> > + /* Setup power LEDS for possible critical temp */
> > + np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
> > + if (np)
> > + np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
>
> Did you really mean to test if (!np) above instead?
Actually, it looks like he's trying to find the second gpio node in the tree.
Sean, if that is true, then this is a very fragile way to do it.
Really, you should have a phandle somewhere that points to the GPIO
node that your LEDs are attached to. Others have been addressing the
same problem and the consensus seems to be to add a 'leds' node for
each of your leds with a phandle and gpio descriptor to the gpio node.
See the documentation added by this patch (section 't'):
http://patchwork.ozlabs.org/linuxppc/patch?id=18156
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 1:51 ` Grant Likely
@ 2008-04-28 2:25 ` Sean MacLennan
2008-04-28 4:47 ` Grant Likely
0 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 2:25 UTC (permalink / raw)
To: Grant Likely; +Cc: Stephen Rothwell, linuxppc-dev
On Sun, 27 Apr 2008 19:51:57 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:
> Actually, it looks like he's trying to find the second gpio node in
> the tree.
Correct.
> Sean, if that is true, then this is a very fragile way to do it.
> Really, you should have a phandle somewhere that points to the GPIO
> node that your LEDs are attached to. Others have been addressing the
> same problem and the consensus seems to be to add a 'leds' node for
> each of your leds with a phandle and gpio descriptor to the gpio node.
>
> See the documentation added by this patch (section 't'):
> http://patchwork.ozlabs.org/linuxppc/patch?id=18156
I saw that earlier. I thought that that method relied on the gpio_led
driver? I want to use the gpio_led driver, but I believe the underlying
gpio code for the 440EP is not done yet.
If *either* assumption is wrong, let me know! It would be one less
driver (the warp_led driver) that I would have to support outside the
mainline kernel.
I believe, if the platform update gets accepted, that in 2.6.26 the
Warp will be usable with the the mainline kernel. You will just lose
some functionally, such as the SD driver which has already been
rejected.
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 2:25 ` Sean MacLennan
@ 2008-04-28 4:47 ` Grant Likely
2008-04-28 17:10 ` Sean MacLennan
0 siblings, 1 reply; 28+ messages in thread
From: Grant Likely @ 2008-04-28 4:47 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Stephen Rothwell, linuxppc-dev
On Sun, Apr 27, 2008 at 8:25 PM, Sean MacLennan <smaclennan@pikatech.com> wrote:
> On Sun, 27 Apr 2008 19:51:57 -0600
> "Grant Likely" <grant.likely@secretlab.ca> wrote:
>
> > Actually, it looks like he's trying to find the second gpio node in
> > the tree.
>
> Correct.
>
>
> > Sean, if that is true, then this is a very fragile way to do it.
> > Really, you should have a phandle somewhere that points to the GPIO
> > node that your LEDs are attached to. Others have been addressing the
> > same problem and the consensus seems to be to add a 'leds' node for
> > each of your leds with a phandle and gpio descriptor to the gpio node.
> >
> > See the documentation added by this patch (section 't'):
> > http://patchwork.ozlabs.org/linuxppc/patch?id=18156
>
> I saw that earlier. I thought that that method relied on the gpio_led
> driver? I want to use the gpio_led driver, but I believe the underlying
> gpio code for the 440EP is not done yet.
Something very important to remember: The device tree is simply a
description of the hardware. Its layout *must* *not* be driven by
device driver design. Driver design can and will change over time;
hardware description conventions should be relatively stable.
If your LEDs are attached to gpio pins, then you should use the
current draft led->gpio bindings as shown in the above patch. Then,
let your platform code extract whatever data it needs from the device
tree to set up the LEDs.
It is irrelevant that the 44EP GPIO driver doesn't support that
binding. Just make sure that the warp platform code doesn't register
warp's linux,gpio-led device tree nodes onto the of_platform bus.
That way your platform code can do whatever it wants to handle the
LEDs itself.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 4:47 ` Grant Likely
@ 2008-04-28 17:10 ` Sean MacLennan
2008-04-28 17:44 ` Grant Likely
0 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 17:10 UTC (permalink / raw)
To: Grant Likely; +Cc: Stephen Rothwell, linuxppc-dev
On Sun, 27 Apr 2008 22:47:43 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:
> If your LEDs are attached to gpio pins, then you should use the
> current draft led->gpio bindings as shown in the above patch. Then,
> let your platform code extract whatever data it needs from the device
> tree to set up the LEDs.
I added the following to the dts:
led@31 {
compatible = "linux,gpio-led";
linux,name = "green";
gpios = <&GPIO1 31>;
};
led@30 {
compatible = "linux,gpio-led";
linux,name = "red";
gpios = <&GPIO1 30>;
};
I then map the gpio base as follows (I removed the if checks just to
make things short and sweet):
np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
gpios = of_get_property(np, "gpios", &lenp);
of_node_put(np);
np = of_find_node_by_phandle(gpios[0]);
gpio_base = of_iomap(np, 0);
of_node_put(np);
Comments?
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 17:10 ` Sean MacLennan
@ 2008-04-28 17:44 ` Grant Likely
2008-04-28 17:59 ` Sean MacLennan
0 siblings, 1 reply; 28+ messages in thread
From: Grant Likely @ 2008-04-28 17:44 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Stephen Rothwell, rpurdie, linuxppc-dev
On Mon, Apr 28, 2008 at 11:10 AM, Sean MacLennan
<smaclennan@pikatech.com> wrote:
> On Sun, 27 Apr 2008 22:47:43 -0600
>
> "Grant Likely" <grant.likely@secretlab.ca> wrote:
>
>
> > If your LEDs are attached to gpio pins, then you should use the
> > current draft led->gpio bindings as shown in the above patch. Then,
> > let your platform code extract whatever data it needs from the device
> > tree to set up the LEDs.
>
> I added the following to the dts:
>
> led@31 {
> compatible = "linux,gpio-led";
> linux,name = "green";
> gpios = <&GPIO1 31>;
> };
>
> led@30 {
> compatible = "linux,gpio-led";
> linux,name = "red";
> gpios = <&GPIO1 30>;
> };
This looks appropriate. You'll need to make sure that the values in
the linux,name property meet the Linux LED naming guidelines. I think
this is covered in Documentation/leds-class.c. You can also as
Richard Purdie; the LED subsystem maintainer.
> I then map the gpio base as follows (I removed the if checks just to
> make things short and sweet):
>
> np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
>
> gpios = of_get_property(np, "gpios", &lenp);
> of_node_put(np);
>
> np = of_find_node_by_phandle(gpios[0]);
>
>
> gpio_base = of_iomap(np, 0);
> of_node_put(np);
This isn't ideal, but it will do to start. However, if other devices
want to use the same GPIO block, then you'll probably have problems
with race conditions. Eventually, you'll want to use the common GPIO
infrastructure and remove the custom code.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 17:44 ` Grant Likely
@ 2008-04-28 17:59 ` Sean MacLennan
2008-04-28 20:44 ` Richard Purdie
0 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 17:59 UTC (permalink / raw)
To: Grant Likely; +Cc: Stephen Rothwell, rpurdie, Sean MacLennan, linuxppc-dev
On Mon, 28 Apr 2008 11:44:19 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:
> This looks appropriate. You'll need to make sure that the values in
> the linux,name property meet the Linux LED naming guidelines. I think
> this is covered in Documentation/leds-class.c. You can also as
> Richard Purdie; the LED subsystem maintainer.
The leds name is "devicename:colour:function" where you are allowed to
leave sections blank. So I only filled in the colour ;)
I also notice that it is colour, not color.
I am hoping that this code is only for 2.6.26 and that we will switch
to the gpio-leds driver for 2.6.27. I don't want to keep supporting yet
another driver outside of the mainline kernel. Let's face it, I'm
lazy :D
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 17:59 ` Sean MacLennan
@ 2008-04-28 20:44 ` Richard Purdie
2008-04-28 21:24 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code tosupportRev " Sean MacLennan
0 siblings, 1 reply; 28+ messages in thread
From: Richard Purdie @ 2008-04-28 20:44 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Stephen Rothwell, Sean MacLennan, linuxppc-dev
On Mon, 2008-04-28 at 13:59 -0400, Sean MacLennan wrote:
> On Mon, 28 Apr 2008 11:44:19 -0600
> "Grant Likely" <grant.likely@secretlab.ca> wrote:
>
> > This looks appropriate. You'll need to make sure that the values in
> > the linux,name property meet the Linux LED naming guidelines. I think
> > this is covered in Documentation/leds-class.c. You can also as
> > Richard Purdie; the LED subsystem maintainer.
>
> The leds name is "devicename:colour:function" where you are allowed to
> leave sections blank. So I only filled in the colour ;)
You can leave sections blank but it pays to leave the separator in so
use ":red:" or ":red", not "red".
> I also notice that it is colour, not color.
;-)
Cheers,
Richard
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code tosupportRev B boards
2008-04-28 20:44 ` Richard Purdie
@ 2008-04-28 21:24 ` Sean MacLennan
2008-04-28 21:36 ` Richard Purdie
0 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 21:24 UTC (permalink / raw)
To: Richard Purdie; +Cc: Stephen Rothwell, linuxppc-dev
On Mon, 28 Apr 2008 21:44:05 +0100
"Richard Purdie" <rpurdie@rpsys.net> wrote:
> You can leave sections blank but it pays to leave the separator in so
> use ":red:" or ":red", not "red".
Ok, :red: and :green: it is.
What would be the advantage of pika:red: or warp:red:?
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code tosupportRev B boards
2008-04-28 21:24 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code tosupportRev " Sean MacLennan
@ 2008-04-28 21:36 ` Richard Purdie
0 siblings, 0 replies; 28+ messages in thread
From: Richard Purdie @ 2008-04-28 21:36 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Stephen Rothwell, linuxppc-dev
On Mon, 2008-04-28 at 17:24 -0400, Sean MacLennan wrote:
> On Mon, 28 Apr 2008 21:44:05 +0100
> "Richard Purdie" <rpurdie@rpsys.net> wrote:
>
> > You can leave sections blank but it pays to leave the separator in so
> > use ":red:" or ":red", not "red".
>
> Ok, :red: and :green: it is.
>
> What would be the advantage of pika:red: or warp:red:?
It makes it more obvious which driver is involved which can be useful
when reading bug reports and helps identify things in cases where LEDs
may be plugged in, e.g. USB.
Cheers,
Richard
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 0:58 ` Stephen Rothwell
2008-04-28 1:51 ` Grant Likely
@ 2008-04-28 2:31 ` Sean MacLennan
1 sibling, 0 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 2:31 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev
On Mon, 28 Apr 2008 10:58:59 +1000
"Stephen Rothwell" <sfr@canb.auug.org.au> wrote:
> You really want linux.of.h (unless there was some preexisting reason
> to require of_platform.h).
You are correct. That was a cut and paste from warp.c which
specifically needs of_platform.h.
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-17 19:22 [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to support Rev B boards Sean MacLennan
2008-04-27 19:25 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev " Sean MacLennan
@ 2008-04-28 18:53 ` Sean MacLennan
2008-04-28 19:56 ` Grant Likely
2008-04-29 1:47 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
2 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 18:53 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
Ok, here is another version of the patch with Stephen Rothwell's and
Grant Likely's suggestions.
Cheers,
Sean
PIKA Warp: Update platform code to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Full DTM support including critical temperature.
* Added POST information.
* Removed LED function, moved to new LED driver.
* Moved ad7414 to new style I2C initialization.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index eb108a8..2178021 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -10,6 +10,7 @@
#include "ops.h"
#include "4xx.h"
#include "cuboot.h"
+#include "stdio.h"
#define TARGET_4xx
#define TARGET_44x
@@ -17,14 +18,54 @@
static bd_t bd;
-static void warp_fixups(void)
+static void warp_fixup_one_nor(u32 from, u32 to)
{
- unsigned long sysclk = 66000000;
+ void *devp;
+ char name[50];
+ u32 v[2];
+
+ sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from);
+
+ devp = finddevice(name);
+ if (!devp)
+ return;
+
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[0] = to;
+ setprop(devp, "reg", v, sizeof(v));
+
+ printf("NOR 64M fixup %x -> %x\r\n", from, to);
+ }
+}
+
- ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+static void warp_fixups(void)
+{
+ ibm440ep_fixup_clocks(66000000, 11059200, 50000000);
ibm4xx_sdram_fixup_memsize();
ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+
+ /* Fixup for 64M flash on Rev A boards. */
+ if (bd.bi_flashsize == 0x4000000) {
+ void *devp;
+ u32 v[3];
+
+ devp = finddevice("/plb/opb/ebc/nor_flash@0,0");
+ if (!devp)
+ return;
+
+ /* Fixup the size */
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[2] = bd.bi_flashsize;
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* Fixup parition offsets */
+ warp_fixup_one_nor(0x300000, 0x3f00000);
+ warp_fixup_one_nor(0x340000, 0x3f40000);
+ warp_fixup_one_nor(0x380000, 0x3f80000);
+ }
}
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index b04a52e..d124497 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -132,40 +132,33 @@
fpga@2,0 {
compatible = "pika,fpga";
- reg = <2 0 2200>;
+ reg = <2 0 1000>;
interrupts = <18 8>;
interrupt-parent = <&UIC0>;
};
+ fpga@2,4000 {
+ compatible = "pika,fpga-sd";
+ reg = <2 4000 A00>;
+ };
+
nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
+ compatible = "amd,s29gl032a", "cfi-flash";
bank-width = <2>;
- reg = <0 0 4000000>;
+ reg = <0 0 400000>;
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0 180000>;
- };
- partition@180000 {
- label = "root";
- reg = <180000 3480000>;
- };
- partition@3600000 {
- label = "user";
- reg = <3600000 900000>;
- };
- partition@3f00000 {
+ partition@300000 {
label = "fpga";
- reg = <3f00000 40000>;
+ reg = <300000 40000>;
};
- partition@3f40000 {
+ partition@340000 {
label = "env";
- reg = <3f40000 40000>;
+ reg = <340000 40000>;
};
- partition@3f80000 {
+ partition@380000 {
label = "u-boot";
- reg = <3f80000 80000>;
+ reg = <380000 80000>;
};
};
};
@@ -186,6 +179,16 @@
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
interrupts = <2 4>;
+ index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ad7414@4a {
+ compatible = "adi,ad7414";
+ reg = <4a>;
+ interrupts = <19 8>;
+ interrupt-parent = <&UIC0>;
+ };
};
GPIO0: gpio@ef600b00 {
@@ -196,8 +199,22 @@
GPIO1: gpio@ef600c00 {
compatible = "ibm,gpio-440ep";
reg = <ef600c00 48>;
+
+ };
+
+ led@31 {
+ compatible = "linux,gpio-led";
+ linux,name = "green";
+ gpios = <&GPIO1 31>;
+ };
+
+ led@30 {
+ compatible = "linux,gpio-led";
+ linux,name = "red";
+ gpios = <&GPIO1 30>;
};
+
ZMII0: emac-zmii@ef600d00 {
compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
reg = <ef600d00 c>;
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318..d293c70 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/of.h>
#include <asm/machdep.h>
+
#ifdef CONFIG_MTD_NAND_NDFC
#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
{
.name = "root",
.offset = 0x0200000,
- .size = 0x3400000
+ .size = 0x3E00000
+ },
+ {
+ .name = "persistent",
+ .offset = 0x4000000,
+ .size = 0x4000000
},
{
- .name = "user",
- .offset = 0x3600000,
- .size = 0x0A00000
+ .name = "persistent1",
+ .offset = 0x8000000,
+ .size = 0x4000000
},
+ {
+ .name = "persistent2",
+ .offset = 0xC000000,
+ .size = 0x4000000
+ }
};
struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
.resource = &warp_ndfc,
};
-static struct nand_ecclayout nand_oob_16 = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2, 3, 6, 7 },
- .oobfree = { {.offset = 8, .length = 16} }
-};
-
+/* Do NOT set the ecclayout: let it default so it is correct for both
+ * 64M and 256M flash chips.
+ */
static struct platform_nand_chip warp_nand_chip0 = {
.nr_chips = 1,
.chip_offset = CS_NAND_0,
.nr_partitions = ARRAY_SIZE(nand_parts),
.partitions = nand_parts,
- .chip_delay = 50,
- .ecclayout = &nand_oob_16,
+ .chip_delay = 20,
.priv = &warp_chip0_settings,
};
@@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
static int warp_setup_nand_flash(void)
{
+ struct device_node *np;
+
+ /* Try to detect a rev A based on NOR size. */
+ np = of_find_compatible_node(NULL, NULL, "cfi-flash");
+ if (np) {
+ struct property *pp;
+
+ pp = of_find_property(np, "reg", NULL);
+ if (pp && (pp->length == 12)) {
+ u32 *v = pp->value;
+ if (v[2] == 0x4000000)
+ /* Rev A = 64M NAND */
+ warp_nand_chip0.nr_partitions = 2;
+ }
+ of_node_put(np);
+ }
+
platform_device_register(&warp_ndfc_device);
platform_device_register(&warp_nand_device);
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf615..8f7d016 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,10 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pika.h>
+#include <linux/delay.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
{},
};
+static __initdata struct i2c_board_info warp_i2c_info[] = {
+ { I2C_BOARD_INFO("ad7414", 0x4a) }
+};
+
+static int __init warp_arch_init(void)
+{
+ /* This should go away once support is moved to the dts. */
+ i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
+ return 0;
+}
+machine_arch_initcall(warp, warp_arch_init);
+
static int __init warp_device_probe(void)
{
of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +68,232 @@ define_machine(warp) {
};
-#define LED_GREEN (0x80000000 >> 0)
-#define LED_RED (0x80000000 >> 1)
+/* I am not sure this is the best place for this... */
+static int __init warp_post_info(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ u32 post1, post2;
+
+ /* Sighhhh... POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL)
+ return -ENOENT;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL)
+ return -ENOENT;
+
+ post1 = in_be32(fpga + 0x40);
+ post2 = in_be32(fpga + 0x44);
+
+ iounmap(fpga);
+
+ if (post1 || post2)
+ printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
+ else
+ printk(KERN_INFO "Warp POST OK\n");
+
+ return 0;
+}
+machine_late_initcall(warp, warp_post_info);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+
+static LIST_HEAD(dtm_shutdown_list);
+static void __iomem *dtm_fpga;
+static void __iomem *gpio_base;
+
+
+struct dtm_shutdown {
+ struct list_head list;
+ void (*func)(void *arg);
+ void *arg;
+};
-/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
-void warp_set_power_leds(int green, int red)
+int dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
- static void __iomem *gpio_base = NULL;
- unsigned leds;
-
- if (gpio_base == NULL) {
- struct device_node *np;
-
- /* Power LEDS are on the second GPIO controller */
- np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
- if (np)
- np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return;
+ struct dtm_shutdown *shutdown;
+
+ shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
+ if (shutdown == NULL)
+ return -ENOMEM;
+
+ shutdown->func = func;
+ shutdown->arg = arg;
+
+ list_add(&shutdown->list, &dtm_shutdown_list);
+
+ return 0;
+}
+
+int dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ struct dtm_shutdown *shutdown;
+
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ if (shutdown->func == func && shutdown->arg == arg) {
+ list_del(&shutdown->list);
+ kfree(shutdown);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static irqreturn_t temp_isr(int irq, void *context)
+{
+ struct dtm_shutdown *shutdown;
+
+ local_irq_disable();
+
+ /* Run through the shutdown list. */
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ shutdown->func(shutdown->arg);
+
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+
+ while (1) {
+ if (dtm_fpga) {
+ unsigned reset = in_be32(dtm_fpga + 0x14);
+ out_be32(dtm_fpga + 0x14, reset);
}
- gpio_base = of_iomap(np, 0);
- of_node_put(np);
- if (gpio_base == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return;
+ if (gpio_base) {
+ unsigned leds = in_be32(gpio_base);
+
+ /* green off, red toggle */
+ leds &= ~0x80000000;
+ leds ^= 0x40000000;
+
+ out_be32(gpio_base, leds);
}
+
+ mdelay(500);
+ }
+}
+
+static int pika_setup_leds(void)
+{
+ struct device_node *np;
+ const u32 *gpios;
+ int lenp;
+
+ np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
+ return -ENOENT;
}
- leds = in_be32(gpio_base);
+ gpios = of_get_property(np, "gpios", &lenp);
+ of_node_put(np);
+ if (!gpios || lenp != 8) {
+ printk(KERN_ERR __FILE__
+ ": Unable to get gpios property (%d)\n", lenp);
+ return -ENOENT;
+ }
- switch (green) {
- case 0: leds &= ~LED_GREEN; break;
- case 1: leds |= LED_GREEN; break;
+ np = of_find_node_by_phandle(gpios[0]);
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
+ return -ENOENT;
}
- switch (red) {
- case 0: leds &= ~LED_RED; break;
- case 1: leds |= LED_RED; break;
+
+ gpio_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!gpio_base) {
+ printk(KERN_ERR __FILE__ ": Unable to map gpio");
+ return -ENOMEM;
}
- out_be32(gpio_base, leds);
+ return 0;
}
-EXPORT_SYMBOL(warp_set_power_leds);
+static void pika_setup_critical_temp(struct i2c_client *client)
+{
+ struct device_node *np;
+ int irq, rc;
+
+ /* Do this before enabling critical temp interrupt since we
+ * may immediately interrupt.
+ */
+ pika_setup_leds();
+
+ /* These registers are in 1 degree increments. */
+ i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
+ i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
+
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
+ return;
+ }
+
+ rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
+ if (rc) {
+ printk(KERN_ERR __FILE__
+ ": Unable to request ad7414 irq %d = %d\n", irq, rc);
+ return;
+ }
+}
+
+static inline void pika_dtm_check_fan(void __iomem *fpga)
+{
+ static int fan_state;
+ u32 fan = in_be32(fpga + 0x34) & (1 << 14);
+
+ if (fan_state != fan) {
+ fan_state = fan;
+ if (fan)
+ printk(KERN_WARNING "Fan rotation error detected."
+ " Please check hardware.\n");
+ }
+}
-#ifdef CONFIG_SENSORS_AD7414
static int pika_dtm_thread(void __iomem *fpga)
{
- extern int ad7414_get_temp(int index);
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ /* We loop in case either driver was compiled as a module and
+ * has not been insmoded yet.
+ */
+ while (!(adap = i2c_get_adapter(0))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ while (1) {
+ list_for_each_entry(client, &adap->clients, list)
+ if (client->addr == 0x4a)
+ goto found_it;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+found_it:
+ i2c_put_adapter(adap);
+
+ pika_setup_critical_temp(client);
+
+ printk(KERN_INFO "PIKA DTM thread running.\n");
while (!kthread_should_stop()) {
- int temp = ad7414_get_temp(0);
+ u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
+ out_be32(fpga + 0x20, temp);
- out_be32(fpga, temp);
+ pika_dtm_check_fan(fpga);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
@@ -115,37 +302,44 @@ static int pika_dtm_thread(void __iomem *fpga)
return 0;
}
+
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
struct device_node *np;
- struct resource res;
- void __iomem *fpga;
np = of_find_compatible_node(NULL, NULL, "pika,fpga");
if (np == NULL)
return -ENOENT;
- /* We do not call of_iomap here since it would map in the entire
- * fpga space, which is over 8k.
- */
- if (of_address_to_resource(np, 0, &res)) {
- of_node_put(np);
- return -ENOENT;
- }
+ dtm_fpga = of_iomap(np, 0);
of_node_put(np);
-
- fpga = ioremap(res.start, 0x24);
- if (fpga == NULL)
+ if (dtm_fpga == NULL)
return -ENOENT;
- dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
- iounmap(fpga);
+ iounmap(dtm_fpga);
return PTR_ERR(dtm_thread);
}
return 0;
}
-device_initcall(pika_dtm_start);
+machine_late_initcall(warp, pika_dtm_start);
+
+#else /* !CONFIG_SENSORS_AD7414 */
+
+int dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
+int dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
#endif
+
+EXPORT_SYMBOL(dtm_register_shutdown);
+EXPORT_SYMBOL(dtm_unregister_shutdown);
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 18:53 ` Sean MacLennan
@ 2008-04-28 19:56 ` Grant Likely
2008-04-28 21:37 ` Sean MacLennan
0 siblings, 1 reply; 28+ messages in thread
From: Grant Likely @ 2008-04-28 19:56 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Sean MacLennan, linuxppc-dev
On Mon, Apr 28, 2008 at 12:53 PM, Sean MacLennan
<smaclennan@pikatech.com> wrote:
> Ok, here is another version of the patch with Stephen Rothwell's and
> Grant Likely's suggestions.
>
> Cheers,
> Sean
A few more comments below.
Also, it might help to split up the .dts and code changes into 2
separate patches. That way the .dts can be picked up even if the
actual platform code still needs some revisions.
Finally, since this is a 4xx board port, you need to cc: Josh Boyer on
these patches.
> diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
> index b04a52e..d124497 100644
> --- a/arch/powerpc/boot/dts/warp.dts
> +++ b/arch/powerpc/boot/dts/warp.dts
> @@ -186,6 +179,16 @@
> reg = <ef600700 14>;
> interrupt-parent = <&UIC0>;
> interrupts = <2 4>;
> + index = <0>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + ad7414@4a {
> + compatible = "adi,ad7414";
> + reg = <4a>;
> + interrupts = <19 8>;
> + interrupt-parent = <&UIC0>;
> + };
> };
>
> GPIO0: gpio@ef600b00 {
> @@ -196,8 +199,22 @@
> GPIO1: gpio@ef600c00 {
> compatible = "ibm,gpio-440ep";
> reg = <ef600c00 48>;
> +
> + };
You need to add the gpio-controller and #gpio-cells properties to the
GPIO nodes for the LED's gpios property to work correctly. Search for
"2) gpio-controller nodes" in
Documentation/powerpc/booting-without-of.txt for details. #gpio-cells
should probably be '2' for this gpio controller; 1 cell for the gpio
pin and 1 cell for flags.
> +
> + led@31 {
>
> + compatible = "linux,gpio-led";
> + linux,name = "green";
> + gpios = <&GPIO1 31>;
> + };
> +
> + led@30 {
> + compatible = "linux,gpio-led";
> + linux,name = "red";
> + gpios = <&GPIO1 30>;
> };
These should not be children of the soc node (they are not part of the
SoC internal bus). However, I think it would be perfectly valid to
make them children of the gpio node since they don't have any
connections to other device on the platform.
>
> +
> ZMII0: emac-zmii@ef600d00 {
> compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
> reg = <ef600d00 c>;
>
> diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
> index 9150318..d293c70 100644
>
> --- a/arch/powerpc/platforms/44x/warp-nand.c
> +++ b/arch/powerpc/platforms/44x/warp-nand.c
> @@ -11,8 +11,10 @@
> #include <linux/mtd/partitions.h>
> #include <linux/mtd/nand.h>
> #include <linux/mtd/ndfc.h>
> +#include <linux/of.h>
>
>
> #include <asm/machdep.h>
>
> +
> #ifdef CONFIG_MTD_NAND_NDFC
>
> #define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
> @@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
> {
> .name = "root",
> .offset = 0x0200000,
> - .size = 0x3400000
> + .size = 0x3E00000
> + },
> + {
> + .name = "persistent",
> + .offset = 0x4000000,
> + .size = 0x4000000
> },
> {
> - .name = "user",
> - .offset = 0x3600000,
> - .size = 0x0A00000
> + .name = "persistent1",
> + .offset = 0x8000000,
> + .size = 0x4000000
> },
> + {
> + .name = "persistent2",
> + .offset = 0xC000000,
> + .size = 0x4000000
> + }
> };
Why is this information in the dts *and* the platform file? I haven't
been following the flash partition map binding conventions, but having
it in both places looks wrong....
oh, wait... the one in the dts is for NOR and this one is for NAND,
right? And we don't have a binding yet for NAND partitions yet,
correct?
>
> struct ndfc_controller_settings warp_ndfc_settings = {
> @@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
> .resource = &warp_ndfc,
> };
>
> -static struct nand_ecclayout nand_oob_16 = {
> - .eccbytes = 3,
> - .eccpos = { 0, 1, 2, 3, 6, 7 },
> - .oobfree = { {.offset = 8, .length = 16} }
> -};
> -
> +/* Do NOT set the ecclayout: let it default so it is correct for both
> + * 64M and 256M flash chips.
> + */
> static struct platform_nand_chip warp_nand_chip0 = {
> .nr_chips = 1,
> .chip_offset = CS_NAND_0,
> .nr_partitions = ARRAY_SIZE(nand_parts),
> .partitions = nand_parts,
> - .chip_delay = 50,
> - .ecclayout = &nand_oob_16,
> + .chip_delay = 20,
> .priv = &warp_chip0_settings,
> };
>
> @@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
>
> static int warp_setup_nand_flash(void)
> {
> + struct device_node *np;
> +
> + /* Try to detect a rev A based on NOR size. */
> + np = of_find_compatible_node(NULL, NULL, "cfi-flash");
> + if (np) {
> + struct property *pp;
> +
> + pp = of_find_property(np, "reg", NULL);
> + if (pp && (pp->length == 12)) {
> + u32 *v = pp->value;
> + if (v[2] == 0x4000000)
> + /* Rev A = 64M NAND */
> + warp_nand_chip0.nr_partitions = 2;
> + }
> + of_node_put(np);
> + }
> +
> platform_device_register(&warp_ndfc_device);
> platform_device_register(&warp_nand_device);
>
> diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
> index 39cf615..8f7d016 100644
>
> --- a/arch/powerpc/platforms/44x/warp.c
> +++ b/arch/powerpc/platforms/44x/warp.c
> @@ -12,6 +12,10 @@
>
> #include <linux/init.h>
> #include <linux/of_platform.h>
> #include <linux/kthread.h>
> +#include <linux/i2c.h>
> +#include <linux/interrupt.h>
> +#include <linux/pika.h>
> +#include <linux/delay.h>
>
>
> #include <asm/machdep.h>
> #include <asm/prom.h>
> @@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
>
> {},
> };
>
> +static __initdata struct i2c_board_info warp_i2c_info[] = {
> + { I2C_BOARD_INFO("ad7414", 0x4a) }
> +};
> +
> +static int __init warp_arch_init(void)
> +{
> + /* This should go away once support is moved to the dts. */
> + i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
> + return 0;
> +}
> +machine_arch_initcall(warp, warp_arch_init);
> +
> static int __init warp_device_probe(void)
> {
> of_platform_bus_probe(NULL, warp_of_bus, NULL);
> @@ -52,61 +68,232 @@ define_machine(warp) {
>
>
> };
>
>
> -#define LED_GREEN (0x80000000 >> 0)
> -#define LED_RED (0x80000000 >> 1)
> +/* I am not sure this is the best place for this... */
> +static int __init warp_post_info(void)
> +{
> + struct device_node *np;
> + void __iomem *fpga;
> + u32 post1, post2;
> +
> + /* Sighhhh... POST information is in the sd area. */
> + np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
> + if (np == NULL)
> + return -ENOENT;
> +
> + fpga = of_iomap(np, 0);
> + of_node_put(np);
> + if (fpga == NULL)
> + return -ENOENT;
> +
> + post1 = in_be32(fpga + 0x40);
> + post2 = in_be32(fpga + 0x44);
> +
> + iounmap(fpga);
> +
> + if (post1 || post2)
> + printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
> + else
> + printk(KERN_INFO "Warp POST OK\n");
> +
> + return 0;
> +}
> +machine_late_initcall(warp, warp_post_info);
> +
> +
> +#ifdef CONFIG_SENSORS_AD7414
<snip>
> +#else /* !CONFIG_SENSORS_AD7414 */
>
> +
> +int dtm_register_shutdown(void (*func)(void *arg), void *arg)
> +{
> + return 0;
> +}
>
> +
> +int dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
> +{
> + return 0;
> +}
> +
> #endif
> +
>
> +EXPORT_SYMBOL(dtm_register_shutdown);
>
> +EXPORT_SYMBOL(dtm_unregister_shutdown);
When exporting symbols for platform code you should avoid polluting
the global Linux namespace and prefix the functions with your platform
name.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 19:56 ` Grant Likely
@ 2008-04-28 21:37 ` Sean MacLennan
2008-04-28 21:54 ` Scott Wood
2008-04-28 22:07 ` Grant Likely
0 siblings, 2 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 21:37 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
On Mon, 28 Apr 2008 13:56:11 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:
>
> You need to add the gpio-controller and #gpio-cells properties to the
> GPIO nodes for the LED's gpios property to work correctly. Search for
> "2) gpio-controller nodes" in
> Documentation/powerpc/booting-without-of.txt for details. #gpio-cells
> should probably be '2' for this gpio controller; 1 cell for the gpio
> pin and 1 cell for flags.
I believe these gpio nodes predate that text, but I added the fields
anyway.
>
> These should not be children of the soc node (they are not part of the
> SoC internal bus). However, I think it would be perfectly valid to
> make them children of the gpio node since they don't have any
> connections to other device on the platform.
I put them in gpio. That was where I put them initialy.
> Why is this information in the dts *and* the platform file? I haven't
> been following the flash partition map binding conventions, but having
> it in both places looks wrong....
>
> oh, wait... the one in the dts is for NOR and this one is for NAND,
> right? And we don't have a binding yet for NAND partitions yet,
> correct?
Correct. Josh originally asked me to split out the warp-nand.c file so
that once the NAND is in the dts, we can just delete the file. NAND is
much more complicated that NOR to configure.
> When exporting symbols for platform code you should avoid polluting
> the global Linux namespace and prefix the functions with your platform
> name.
I was hoping dtm was good enough. I prefixed them with the company name.
We are expecting to have a "family" of Asterisk appliances and I am
trying to make educated guesses as to what will be family wide
(prefixed with pika) and what will be warp specific.
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 21:37 ` Sean MacLennan
@ 2008-04-28 21:54 ` Scott Wood
2008-04-28 22:07 ` Sean MacLennan
2008-04-28 22:07 ` Grant Likely
1 sibling, 1 reply; 28+ messages in thread
From: Scott Wood @ 2008-04-28 21:54 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
On Mon, Apr 28, 2008 at 05:37:38PM -0400, Sean MacLennan wrote:
> > Why is this information in the dts *and* the platform file? I haven't
> > been following the flash partition map binding conventions, but having
> > it in both places looks wrong....
> >
> > oh, wait... the one in the dts is for NOR and this one is for NAND,
> > right? And we don't have a binding yet for NAND partitions yet,
> > correct?
>
> Correct.
Why can't the existing partition binding be used with NAND? It's what we
do with Freescale FCM NAND.
-Scott
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 21:54 ` Scott Wood
@ 2008-04-28 22:07 ` Sean MacLennan
2008-04-30 0:48 ` Josh Boyer
0 siblings, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-28 22:07 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
On Mon, 28 Apr 2008 16:54:24 -0500
Scott Wood <scottwood@freescale.com> wrote:
> Why can't the existing partition binding be used with NAND? It's
> what we do with Freescale FCM NAND.
I guess I could put the partitions in the dts. But I would have to
read them and dynamically create an array to pass to the ndfc driver.
It seems simpler to just statically initialize the array. Once the ndfc
is modified to use the dts, I will switch to that method.
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 22:07 ` Sean MacLennan
@ 2008-04-30 0:48 ` Josh Boyer
0 siblings, 0 replies; 28+ messages in thread
From: Josh Boyer @ 2008-04-30 0:48 UTC (permalink / raw)
To: Sean MacLennan; +Cc: Scott Wood, linuxppc-dev
On Mon, 28 Apr 2008 18:07:17 -0400
Sean MacLennan <seanm@seanm.ca> wrote:
> On Mon, 28 Apr 2008 16:54:24 -0500
> Scott Wood <scottwood@freescale.com> wrote:
>
> > Why can't the existing partition binding be used with NAND? It's
> > what we do with Freescale FCM NAND.
>
> I guess I could put the partitions in the dts. But I would have to
> read them and dynamically create an array to pass to the ndfc driver.
>
> It seems simpler to just statically initialize the array. Once the ndfc
> is modified to use the dts, I will switch to that method.
Right. It's a limitation of NDFC, which isn't WARP specific and needs
fixing in general.
josh
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-28 21:37 ` Sean MacLennan
2008-04-28 21:54 ` Scott Wood
@ 2008-04-28 22:07 ` Grant Likely
1 sibling, 0 replies; 28+ messages in thread
From: Grant Likely @ 2008-04-28 22:07 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
On Mon, Apr 28, 2008 at 3:37 PM, Sean MacLennan <seanm@seanm.ca> wrote:
> On Mon, 28 Apr 2008 13:56:11 -0600
>
> "Grant Likely" <grant.likely@secretlab.ca> wrote:
>
> >
>
> > You need to add the gpio-controller and #gpio-cells properties to the
> > GPIO nodes for the LED's gpios property to work correctly. Search for
> > "2) gpio-controller nodes" in
> > Documentation/powerpc/booting-without-of.txt for details. #gpio-cells
> > should probably be '2' for this gpio controller; 1 cell for the gpio
> > pin and 1 cell for flags.
>
> I believe these gpio nodes predate that text, but I added the fields
> anyway.
>
>
> >
> > These should not be children of the soc node (they are not part of the
> > SoC internal bus). However, I think it would be perfectly valid to
> > make them children of the gpio node since they don't have any
> > connections to other device on the platform.
>
> I put them in gpio. That was where I put them initialy.
>
>
> > Why is this information in the dts *and* the platform file? I haven't
> > been following the flash partition map binding conventions, but having
> > it in both places looks wrong....
> >
> > oh, wait... the one in the dts is for NOR and this one is for NAND,
> > right? And we don't have a binding yet for NAND partitions yet,
> > correct?
>
> Correct. Josh originally asked me to split out the warp-nand.c file so
> that once the NAND is in the dts, we can just delete the file. NAND is
> much more complicated that NOR to configure.
>
>
> > When exporting symbols for platform code you should avoid polluting
> > the global Linux namespace and prefix the functions with your platform
> > name.
>
> I was hoping dtm was good enough. I prefixed them with the company name.
> We are expecting to have a "family" of Asterisk appliances and I am
> trying to make educated guesses as to what will be family wide
> (prefixed with pika) and what will be warp specific.
Its just kernel code; it can be changed easily at later date. When
the company has *2* boards supported mainline in the kernel, then make
it generic. :-P
My experience is that educated guesses in this context are almost
always wrong (ie. the API won't be what you think it should be now).
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-17 19:22 [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to support Rev B boards Sean MacLennan
2008-04-27 19:25 ` [RESEND][PATCH][POWERPC] PIKA Warp: Update platform code to supportRev " Sean MacLennan
2008-04-28 18:53 ` Sean MacLennan
@ 2008-04-29 1:47 ` Sean MacLennan
2008-04-29 1:50 ` [RESEND][PATCH 2/2][POWERPC] " Sean MacLennan
2008-04-29 3:28 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
2 siblings, 2 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-29 1:47 UTC (permalink / raw)
To: Josh Boyer, linuxppc-dev; +Cc: Stephen Rothwell
Ok, I think I have everybodys changes in. I will split out the DTS into
a separate patch. The changelog is in this one.
Cheers,
Sean
PIKA Warp: Update platform code to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Full DTM support including critical temperature.
* Added POST information.
* Removed LED function, moved to new LED driver.
* Moved ad7414 to new style I2C initialization.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index eb108a8..2178021 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -10,6 +10,7 @@
#include "ops.h"
#include "4xx.h"
#include "cuboot.h"
+#include "stdio.h"
#define TARGET_4xx
#define TARGET_44x
@@ -17,14 +18,54 @@
static bd_t bd;
-static void warp_fixups(void)
+static void warp_fixup_one_nor(u32 from, u32 to)
{
- unsigned long sysclk = 66000000;
+ void *devp;
+ char name[50];
+ u32 v[2];
+
+ sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from);
+
+ devp = finddevice(name);
+ if (!devp)
+ return;
+
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[0] = to;
+ setprop(devp, "reg", v, sizeof(v));
+
+ printf("NOR 64M fixup %x -> %x\r\n", from, to);
+ }
+}
+
- ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+static void warp_fixups(void)
+{
+ ibm440ep_fixup_clocks(66000000, 11059200, 50000000);
ibm4xx_sdram_fixup_memsize();
ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+
+ /* Fixup for 64M flash on Rev A boards. */
+ if (bd.bi_flashsize == 0x4000000) {
+ void *devp;
+ u32 v[3];
+
+ devp = finddevice("/plb/opb/ebc/nor_flash@0,0");
+ if (!devp)
+ return;
+
+ /* Fixup the size */
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[2] = bd.bi_flashsize;
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* Fixup parition offsets */
+ warp_fixup_one_nor(0x300000, 0x3f00000);
+ warp_fixup_one_nor(0x340000, 0x3f40000);
+ warp_fixup_one_nor(0x380000, 0x3f80000);
+ }
}
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318..d293c70 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/of.h>
#include <asm/machdep.h>
+
#ifdef CONFIG_MTD_NAND_NDFC
#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
{
.name = "root",
.offset = 0x0200000,
- .size = 0x3400000
+ .size = 0x3E00000
+ },
+ {
+ .name = "persistent",
+ .offset = 0x4000000,
+ .size = 0x4000000
},
{
- .name = "user",
- .offset = 0x3600000,
- .size = 0x0A00000
+ .name = "persistent1",
+ .offset = 0x8000000,
+ .size = 0x4000000
},
+ {
+ .name = "persistent2",
+ .offset = 0xC000000,
+ .size = 0x4000000
+ }
};
struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
.resource = &warp_ndfc,
};
-static struct nand_ecclayout nand_oob_16 = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2, 3, 6, 7 },
- .oobfree = { {.offset = 8, .length = 16} }
-};
-
+/* Do NOT set the ecclayout: let it default so it is correct for both
+ * 64M and 256M flash chips.
+ */
static struct platform_nand_chip warp_nand_chip0 = {
.nr_chips = 1,
.chip_offset = CS_NAND_0,
.nr_partitions = ARRAY_SIZE(nand_parts),
.partitions = nand_parts,
- .chip_delay = 50,
- .ecclayout = &nand_oob_16,
+ .chip_delay = 20,
.priv = &warp_chip0_settings,
};
@@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
static int warp_setup_nand_flash(void)
{
+ struct device_node *np;
+
+ /* Try to detect a rev A based on NOR size. */
+ np = of_find_compatible_node(NULL, NULL, "cfi-flash");
+ if (np) {
+ struct property *pp;
+
+ pp = of_find_property(np, "reg", NULL);
+ if (pp && (pp->length == 12)) {
+ u32 *v = pp->value;
+ if (v[2] == 0x4000000)
+ /* Rev A = 64M NAND */
+ warp_nand_chip0.nr_partitions = 2;
+ }
+ of_node_put(np);
+ }
+
platform_device_register(&warp_ndfc_device);
platform_device_register(&warp_nand_device);
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf615..aa0f737 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,10 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pika.h>
+#include <linux/delay.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
{},
};
+static __initdata struct i2c_board_info warp_i2c_info[] = {
+ { I2C_BOARD_INFO("ad7414", 0x4a) }
+};
+
+static int __init warp_arch_init(void)
+{
+ /* This should go away once support is moved to the dts. */
+ i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
+ return 0;
+}
+machine_arch_initcall(warp, warp_arch_init);
+
static int __init warp_device_probe(void)
{
of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +68,232 @@ define_machine(warp) {
};
-#define LED_GREEN (0x80000000 >> 0)
-#define LED_RED (0x80000000 >> 1)
+/* I am not sure this is the best place for this... */
+static int __init warp_post_info(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ u32 post1, post2;
+
+ /* Sighhhh... POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL)
+ return -ENOENT;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL)
+ return -ENOENT;
+
+ post1 = in_be32(fpga + 0x40);
+ post2 = in_be32(fpga + 0x44);
+
+ iounmap(fpga);
+
+ if (post1 || post2)
+ printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
+ else
+ printk(KERN_INFO "Warp POST OK\n");
+
+ return 0;
+}
+machine_late_initcall(warp, warp_post_info);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+
+static LIST_HEAD(dtm_shutdown_list);
+static void __iomem *dtm_fpga;
+static void __iomem *gpio_base;
+
+
+struct dtm_shutdown {
+ struct list_head list;
+ void (*func)(void *arg);
+ void *arg;
+};
-/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
-void warp_set_power_leds(int green, int red)
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
- static void __iomem *gpio_base = NULL;
- unsigned leds;
-
- if (gpio_base == NULL) {
- struct device_node *np;
-
- /* Power LEDS are on the second GPIO controller */
- np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
- if (np)
- np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return;
+ struct dtm_shutdown *shutdown;
+
+ shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
+ if (shutdown == NULL)
+ return -ENOMEM;
+
+ shutdown->func = func;
+ shutdown->arg = arg;
+
+ list_add(&shutdown->list, &dtm_shutdown_list);
+
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ struct dtm_shutdown *shutdown;
+
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ if (shutdown->func == func && shutdown->arg == arg) {
+ list_del(&shutdown->list);
+ kfree(shutdown);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static irqreturn_t temp_isr(int irq, void *context)
+{
+ struct dtm_shutdown *shutdown;
+
+ local_irq_disable();
+
+ /* Run through the shutdown list. */
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ shutdown->func(shutdown->arg);
+
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+
+ while (1) {
+ if (dtm_fpga) {
+ unsigned reset = in_be32(dtm_fpga + 0x14);
+ out_be32(dtm_fpga + 0x14, reset);
}
- gpio_base = of_iomap(np, 0);
- of_node_put(np);
- if (gpio_base == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return;
+ if (gpio_base) {
+ unsigned leds = in_be32(gpio_base);
+
+ /* green off, red toggle */
+ leds &= ~0x80000000;
+ leds ^= 0x40000000;
+
+ out_be32(gpio_base, leds);
}
+
+ mdelay(500);
+ }
+}
+
+static int pika_setup_leds(void)
+{
+ struct device_node *np;
+ const u32 *gpios;
+ int lenp;
+
+ np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
+ return -ENOENT;
}
- leds = in_be32(gpio_base);
+ gpios = of_get_property(np, "gpios", &lenp);
+ of_node_put(np);
+ if (!gpios || lenp != 8) {
+ printk(KERN_ERR __FILE__
+ ": Unable to get gpios property (%d)\n", lenp);
+ return -ENOENT;
+ }
- switch (green) {
- case 0: leds &= ~LED_GREEN; break;
- case 1: leds |= LED_GREEN; break;
+ np = of_find_node_by_phandle(gpios[0]);
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
+ return -ENOENT;
}
- switch (red) {
- case 0: leds &= ~LED_RED; break;
- case 1: leds |= LED_RED; break;
+
+ gpio_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!gpio_base) {
+ printk(KERN_ERR __FILE__ ": Unable to map gpio");
+ return -ENOMEM;
}
- out_be32(gpio_base, leds);
+ return 0;
}
-EXPORT_SYMBOL(warp_set_power_leds);
+static void pika_setup_critical_temp(struct i2c_client *client)
+{
+ struct device_node *np;
+ int irq, rc;
+
+ /* Do this before enabling critical temp interrupt since we
+ * may immediately interrupt.
+ */
+ pika_setup_leds();
+
+ /* These registers are in 1 degree increments. */
+ i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
+ i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
+
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
+ return;
+ }
+
+ rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
+ if (rc) {
+ printk(KERN_ERR __FILE__
+ ": Unable to request ad7414 irq %d = %d\n", irq, rc);
+ return;
+ }
+}
+
+static inline void pika_dtm_check_fan(void __iomem *fpga)
+{
+ static int fan_state;
+ u32 fan = in_be32(fpga + 0x34) & (1 << 14);
+
+ if (fan_state != fan) {
+ fan_state = fan;
+ if (fan)
+ printk(KERN_WARNING "Fan rotation error detected."
+ " Please check hardware.\n");
+ }
+}
-#ifdef CONFIG_SENSORS_AD7414
static int pika_dtm_thread(void __iomem *fpga)
{
- extern int ad7414_get_temp(int index);
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ /* We loop in case either driver was compiled as a module and
+ * has not been insmoded yet.
+ */
+ while (!(adap = i2c_get_adapter(0))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ while (1) {
+ list_for_each_entry(client, &adap->clients, list)
+ if (client->addr == 0x4a)
+ goto found_it;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+found_it:
+ i2c_put_adapter(adap);
+
+ pika_setup_critical_temp(client);
+
+ printk(KERN_INFO "PIKA DTM thread running.\n");
while (!kthread_should_stop()) {
- int temp = ad7414_get_temp(0);
+ u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
+ out_be32(fpga + 0x20, temp);
- out_be32(fpga, temp);
+ pika_dtm_check_fan(fpga);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
@@ -115,37 +302,44 @@ static int pika_dtm_thread(void __iomem *fpga)
return 0;
}
+
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
struct device_node *np;
- struct resource res;
- void __iomem *fpga;
np = of_find_compatible_node(NULL, NULL, "pika,fpga");
if (np == NULL)
return -ENOENT;
- /* We do not call of_iomap here since it would map in the entire
- * fpga space, which is over 8k.
- */
- if (of_address_to_resource(np, 0, &res)) {
- of_node_put(np);
- return -ENOENT;
- }
+ dtm_fpga = of_iomap(np, 0);
of_node_put(np);
-
- fpga = ioremap(res.start, 0x24);
- if (fpga == NULL)
+ if (dtm_fpga == NULL)
return -ENOENT;
- dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
- iounmap(fpga);
+ iounmap(dtm_fpga);
return PTR_ERR(dtm_thread);
}
return 0;
}
-device_initcall(pika_dtm_start);
+machine_late_initcall(warp, pika_dtm_start);
+
+#else /* !CONFIG_SENSORS_AD7414 */
+
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
#endif
+
+EXPORT_SYMBOL(pika_dtm_register_shutdown);
+EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 2/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-29 1:47 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
@ 2008-04-29 1:50 ` Sean MacLennan
2008-04-29 1:58 ` Grant Likely
2008-04-29 3:28 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
1 sibling, 1 reply; 28+ messages in thread
From: Sean MacLennan @ 2008-04-29 1:50 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, Stephen Rothwell
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index b04a52e..3e95e99 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -132,40 +132,33 @@
fpga@2,0 {
compatible = "pika,fpga";
- reg = <2 0 2200>;
+ reg = <2 0 1000>;
interrupts = <18 8>;
interrupt-parent = <&UIC0>;
};
+ fpga@2,4000 {
+ compatible = "pika,fpga-sd";
+ reg = <2 4000 A00>;
+ };
+
nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
+ compatible = "amd,s29gl032a", "cfi-flash";
bank-width = <2>;
- reg = <0 0 4000000>;
+ reg = <0 0 400000>;
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0 180000>;
- };
- partition@180000 {
- label = "root";
- reg = <180000 3480000>;
- };
- partition@3600000 {
- label = "user";
- reg = <3600000 900000>;
- };
- partition@3f00000 {
+ partition@300000 {
label = "fpga";
- reg = <3f00000 40000>;
+ reg = <300000 40000>;
};
- partition@3f40000 {
+ partition@340000 {
label = "env";
- reg = <3f40000 40000>;
+ reg = <340000 40000>;
};
- partition@3f80000 {
+ partition@380000 {
label = "u-boot";
- reg = <3f80000 80000>;
+ reg = <380000 80000>;
};
};
};
@@ -186,18 +179,45 @@
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
interrupts = <2 4>;
+ index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ad7414@4a {
+ compatible = "adi,ad7414";
+ reg = <4a>;
+ interrupts = <19 8>;
+ interrupt-parent = <&UIC0>;
+ };
};
GPIO0: gpio@ef600b00 {
compatible = "ibm,gpio-440ep";
reg = <ef600b00 48>;
+ #gpio-cells = <2>;
+ gpio-controller;
};
GPIO1: gpio@ef600c00 {
compatible = "ibm,gpio-440ep";
reg = <ef600c00 48>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ led@31 {
+ compatible = "linux,gpio-led";
+ linux,name = ":green:";
+ gpios = <&GPIO1 31>;
+ };
+
+ led@30 {
+ compatible = "linux,gpio-led";
+ linux,name = ":red:";
+ gpios = <&GPIO1 30>;
+ };
};
+
ZMII0: emac-zmii@ef600d00 {
compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
reg = <ef600d00 c>;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 2/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-29 1:50 ` [RESEND][PATCH 2/2][POWERPC] " Sean MacLennan
@ 2008-04-29 1:58 ` Grant Likely
2008-04-29 3:27 ` Sean MacLennan
0 siblings, 1 reply; 28+ messages in thread
From: Grant Likely @ 2008-04-29 1:58 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev, Stephen Rothwell
On Mon, Apr 28, 2008 at 7:50 PM, Sean MacLennan <smaclennan@pikatech.com> wrote:
> diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
> index b04a52e..3e95e99 100644
You still need to have *some* kind of change log and a signed-off-by
line in this patch. :-)
There is one minor change that needs to be added below; otherwise:
Acked-by: Grant Likely <grant.likely@secretlab.ca>
(You can add my acked-by line to the next version of this patch if
you're only changing the thing I comment on).
Josh, when he respins it I think the dts changes are ready to be picked up.
> @@ -186,18 +179,45 @@
> GPIO1: gpio@ef600c00 {
> compatible = "ibm,gpio-440ep";
> reg = <ef600c00 48>;
> + #gpio-cells = <2>;
> + gpio-controller;
> +
> + led@31 {
>
> + compatible = "linux,gpio-led";
> + linux,name = ":green:";
> + gpios = <&GPIO1 31>;
Since #gpio-cells is '2'; the gpios property needs to reflect that.
It should be:
gpios = <&GPIO1 31 0>;
The second cell the GPIO controller would use for flags (inverted,
open-drain, etc).
> + };
> +
> + led@30 {
> + compatible = "linux,gpio-led";
> + linux,name = ":red:";
> + gpios = <&GPIO1 30>;
ditto
> + };
>
>
> };
>
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 2/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-29 1:58 ` Grant Likely
@ 2008-04-29 3:27 ` Sean MacLennan
0 siblings, 0 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-29 3:27 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Sean MacLennan, Stephen Rothwell
PIKA Warp: Update DTS to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Added led entries.
* Added fpga-sd entry.
* Added ad7414 entry.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index b04a52e..c086501 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -132,40 +132,33 @@
fpga@2,0 {
compatible = "pika,fpga";
- reg = <2 0 2200>;
+ reg = <2 0 1000>;
interrupts = <18 8>;
interrupt-parent = <&UIC0>;
};
+ fpga@2,4000 {
+ compatible = "pika,fpga-sd";
+ reg = <2 4000 A00>;
+ };
+
nor_flash@0,0 {
- compatible = "amd,s29gl512n", "cfi-flash";
+ compatible = "amd,s29gl032a", "cfi-flash";
bank-width = <2>;
- reg = <0 0 4000000>;
+ reg = <0 0 400000>;
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0 180000>;
- };
- partition@180000 {
- label = "root";
- reg = <180000 3480000>;
- };
- partition@3600000 {
- label = "user";
- reg = <3600000 900000>;
- };
- partition@3f00000 {
+ partition@300000 {
label = "fpga";
- reg = <3f00000 40000>;
+ reg = <300000 40000>;
};
- partition@3f40000 {
+ partition@340000 {
label = "env";
- reg = <3f40000 40000>;
+ reg = <340000 40000>;
};
- partition@3f80000 {
+ partition@380000 {
label = "u-boot";
- reg = <3f80000 80000>;
+ reg = <380000 80000>;
};
};
};
@@ -186,18 +179,45 @@
reg = <ef600700 14>;
interrupt-parent = <&UIC0>;
interrupts = <2 4>;
+ index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ad7414@4a {
+ compatible = "adi,ad7414";
+ reg = <4a>;
+ interrupts = <19 8>;
+ interrupt-parent = <&UIC0>;
+ };
};
GPIO0: gpio@ef600b00 {
compatible = "ibm,gpio-440ep";
reg = <ef600b00 48>;
+ #gpio-cells = <2>;
+ gpio-controller;
};
GPIO1: gpio@ef600c00 {
compatible = "ibm,gpio-440ep";
reg = <ef600c00 48>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ led@31 {
+ compatible = "linux,gpio-led";
+ linux,name = ":green:";
+ gpios = <&GPIO1 31 0>;
+ };
+
+ led@30 {
+ compatible = "linux,gpio-led";
+ linux,name = ":red:";
+ gpios = <&GPIO1 30 0>;
+ };
};
+
ZMII0: emac-zmii@ef600d00 {
compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
reg = <ef600d00 c>;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-29 1:47 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
2008-04-29 1:50 ` [RESEND][PATCH 2/2][POWERPC] " Sean MacLennan
@ 2008-04-29 3:28 ` Sean MacLennan
2008-04-29 5:08 ` Paul Mackerras
2008-05-06 15:27 ` Sean MacLennan
1 sibling, 2 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-29 3:28 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev, Stephen Rothwell
A change to the dts to get gpios correct broke the led code.
PIKA Warp: Update platform code to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Full DTM support including critical temperature.
* Added POST information.
* Removed LED function, moved to new LED driver.
* Moved ad7414 to new style I2C initialization.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index eb108a8..2178021 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -10,6 +10,7 @@
#include "ops.h"
#include "4xx.h"
#include "cuboot.h"
+#include "stdio.h"
#define TARGET_4xx
#define TARGET_44x
@@ -17,14 +18,54 @@
static bd_t bd;
-static void warp_fixups(void)
+static void warp_fixup_one_nor(u32 from, u32 to)
{
- unsigned long sysclk = 66000000;
+ void *devp;
+ char name[50];
+ u32 v[2];
+
+ sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from);
+
+ devp = finddevice(name);
+ if (!devp)
+ return;
+
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[0] = to;
+ setprop(devp, "reg", v, sizeof(v));
+
+ printf("NOR 64M fixup %x -> %x\r\n", from, to);
+ }
+}
+
- ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+static void warp_fixups(void)
+{
+ ibm440ep_fixup_clocks(66000000, 11059200, 50000000);
ibm4xx_sdram_fixup_memsize();
ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+
+ /* Fixup for 64M flash on Rev A boards. */
+ if (bd.bi_flashsize == 0x4000000) {
+ void *devp;
+ u32 v[3];
+
+ devp = finddevice("/plb/opb/ebc/nor_flash@0,0");
+ if (!devp)
+ return;
+
+ /* Fixup the size */
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[2] = bd.bi_flashsize;
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* Fixup parition offsets */
+ warp_fixup_one_nor(0x300000, 0x3f00000);
+ warp_fixup_one_nor(0x340000, 0x3f40000);
+ warp_fixup_one_nor(0x380000, 0x3f80000);
+ }
}
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318..d293c70 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/of.h>
#include <asm/machdep.h>
+
#ifdef CONFIG_MTD_NAND_NDFC
#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
{
.name = "root",
.offset = 0x0200000,
- .size = 0x3400000
+ .size = 0x3E00000
+ },
+ {
+ .name = "persistent",
+ .offset = 0x4000000,
+ .size = 0x4000000
},
{
- .name = "user",
- .offset = 0x3600000,
- .size = 0x0A00000
+ .name = "persistent1",
+ .offset = 0x8000000,
+ .size = 0x4000000
},
+ {
+ .name = "persistent2",
+ .offset = 0xC000000,
+ .size = 0x4000000
+ }
};
struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
.resource = &warp_ndfc,
};
-static struct nand_ecclayout nand_oob_16 = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2, 3, 6, 7 },
- .oobfree = { {.offset = 8, .length = 16} }
-};
-
+/* Do NOT set the ecclayout: let it default so it is correct for both
+ * 64M and 256M flash chips.
+ */
static struct platform_nand_chip warp_nand_chip0 = {
.nr_chips = 1,
.chip_offset = CS_NAND_0,
.nr_partitions = ARRAY_SIZE(nand_parts),
.partitions = nand_parts,
- .chip_delay = 50,
- .ecclayout = &nand_oob_16,
+ .chip_delay = 20,
.priv = &warp_chip0_settings,
};
@@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
static int warp_setup_nand_flash(void)
{
+ struct device_node *np;
+
+ /* Try to detect a rev A based on NOR size. */
+ np = of_find_compatible_node(NULL, NULL, "cfi-flash");
+ if (np) {
+ struct property *pp;
+
+ pp = of_find_property(np, "reg", NULL);
+ if (pp && (pp->length == 12)) {
+ u32 *v = pp->value;
+ if (v[2] == 0x4000000)
+ /* Rev A = 64M NAND */
+ warp_nand_chip0.nr_partitions = 2;
+ }
+ of_node_put(np);
+ }
+
platform_device_register(&warp_ndfc_device);
platform_device_register(&warp_nand_device);
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf615..318f859 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,10 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pika.h>
+#include <linux/delay.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
{},
};
+static __initdata struct i2c_board_info warp_i2c_info[] = {
+ { I2C_BOARD_INFO("ad7414", 0x4a) }
+};
+
+static int __init warp_arch_init(void)
+{
+ /* This should go away once support is moved to the dts. */
+ i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
+ return 0;
+}
+machine_arch_initcall(warp, warp_arch_init);
+
static int __init warp_device_probe(void)
{
of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +68,232 @@ define_machine(warp) {
};
-#define LED_GREEN (0x80000000 >> 0)
-#define LED_RED (0x80000000 >> 1)
+/* I am not sure this is the best place for this... */
+static int __init warp_post_info(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ u32 post1, post2;
+
+ /* Sighhhh... POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL)
+ return -ENOENT;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL)
+ return -ENOENT;
+
+ post1 = in_be32(fpga + 0x40);
+ post2 = in_be32(fpga + 0x44);
+
+ iounmap(fpga);
+
+ if (post1 || post2)
+ printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
+ else
+ printk(KERN_INFO "Warp POST OK\n");
+
+ return 0;
+}
+machine_late_initcall(warp, warp_post_info);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+
+static LIST_HEAD(dtm_shutdown_list);
+static void __iomem *dtm_fpga;
+static void __iomem *gpio_base;
+
+
+struct dtm_shutdown {
+ struct list_head list;
+ void (*func)(void *arg);
+ void *arg;
+};
-/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
-void warp_set_power_leds(int green, int red)
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
- static void __iomem *gpio_base = NULL;
- unsigned leds;
-
- if (gpio_base == NULL) {
- struct device_node *np;
-
- /* Power LEDS are on the second GPIO controller */
- np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
- if (np)
- np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return;
+ struct dtm_shutdown *shutdown;
+
+ shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
+ if (shutdown == NULL)
+ return -ENOMEM;
+
+ shutdown->func = func;
+ shutdown->arg = arg;
+
+ list_add(&shutdown->list, &dtm_shutdown_list);
+
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ struct dtm_shutdown *shutdown;
+
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ if (shutdown->func == func && shutdown->arg == arg) {
+ list_del(&shutdown->list);
+ kfree(shutdown);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static irqreturn_t temp_isr(int irq, void *context)
+{
+ struct dtm_shutdown *shutdown;
+
+ local_irq_disable();
+
+ /* Run through the shutdown list. */
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ shutdown->func(shutdown->arg);
+
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+
+ while (1) {
+ if (dtm_fpga) {
+ unsigned reset = in_be32(dtm_fpga + 0x14);
+ out_be32(dtm_fpga + 0x14, reset);
}
- gpio_base = of_iomap(np, 0);
- of_node_put(np);
- if (gpio_base == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return;
+ if (gpio_base) {
+ unsigned leds = in_be32(gpio_base);
+
+ /* green off, red toggle */
+ leds &= ~0x80000000;
+ leds ^= 0x40000000;
+
+ out_be32(gpio_base, leds);
}
+
+ mdelay(500);
+ }
+}
+
+static int pika_setup_leds(void)
+{
+ struct device_node *np;
+ const u32 *gpios;
+ int len;
+
+ np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
+ return -ENOENT;
}
- leds = in_be32(gpio_base);
+ gpios = of_get_property(np, "gpios", &len);
+ of_node_put(np);
+ if (!gpios || len < 4) {
+ printk(KERN_ERR __FILE__
+ ": Unable to get gpios property (%d)\n", len);
+ return -ENOENT;
+ }
- switch (green) {
- case 0: leds &= ~LED_GREEN; break;
- case 1: leds |= LED_GREEN; break;
+ np = of_find_node_by_phandle(gpios[0]);
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
+ return -ENOENT;
}
- switch (red) {
- case 0: leds &= ~LED_RED; break;
- case 1: leds |= LED_RED; break;
+
+ gpio_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!gpio_base) {
+ printk(KERN_ERR __FILE__ ": Unable to map gpio");
+ return -ENOMEM;
}
- out_be32(gpio_base, leds);
+ return 0;
}
-EXPORT_SYMBOL(warp_set_power_leds);
+static void pika_setup_critical_temp(struct i2c_client *client)
+{
+ struct device_node *np;
+ int irq, rc;
+
+ /* Do this before enabling critical temp interrupt since we
+ * may immediately interrupt.
+ */
+ pika_setup_leds();
+
+ /* These registers are in 1 degree increments. */
+ i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
+ i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
+
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
+ return;
+ }
+
+ rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
+ if (rc) {
+ printk(KERN_ERR __FILE__
+ ": Unable to request ad7414 irq %d = %d\n", irq, rc);
+ return;
+ }
+}
+
+static inline void pika_dtm_check_fan(void __iomem *fpga)
+{
+ static int fan_state;
+ u32 fan = in_be32(fpga + 0x34) & (1 << 14);
+
+ if (fan_state != fan) {
+ fan_state = fan;
+ if (fan)
+ printk(KERN_WARNING "Fan rotation error detected."
+ " Please check hardware.\n");
+ }
+}
-#ifdef CONFIG_SENSORS_AD7414
static int pika_dtm_thread(void __iomem *fpga)
{
- extern int ad7414_get_temp(int index);
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ /* We loop in case either driver was compiled as a module and
+ * has not been insmoded yet.
+ */
+ while (!(adap = i2c_get_adapter(0))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ while (1) {
+ list_for_each_entry(client, &adap->clients, list)
+ if (client->addr == 0x4a)
+ goto found_it;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+found_it:
+ i2c_put_adapter(adap);
+
+ pika_setup_critical_temp(client);
+
+ printk(KERN_INFO "PIKA DTM thread running.\n");
while (!kthread_should_stop()) {
- int temp = ad7414_get_temp(0);
+ u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
+ out_be32(fpga + 0x20, temp);
- out_be32(fpga, temp);
+ pika_dtm_check_fan(fpga);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
@@ -115,37 +302,44 @@ static int pika_dtm_thread(void __iomem *fpga)
return 0;
}
+
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
struct device_node *np;
- struct resource res;
- void __iomem *fpga;
np = of_find_compatible_node(NULL, NULL, "pika,fpga");
if (np == NULL)
return -ENOENT;
- /* We do not call of_iomap here since it would map in the entire
- * fpga space, which is over 8k.
- */
- if (of_address_to_resource(np, 0, &res)) {
- of_node_put(np);
- return -ENOENT;
- }
+ dtm_fpga = of_iomap(np, 0);
of_node_put(np);
-
- fpga = ioremap(res.start, 0x24);
- if (fpga == NULL)
+ if (dtm_fpga == NULL)
return -ENOENT;
- dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
- iounmap(fpga);
+ iounmap(dtm_fpga);
return PTR_ERR(dtm_thread);
}
return 0;
}
-device_initcall(pika_dtm_start);
+machine_late_initcall(warp, pika_dtm_start);
+
+#else /* !CONFIG_SENSORS_AD7414 */
+
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
#endif
+
+EXPORT_SYMBOL(pika_dtm_register_shutdown);
+EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
2008-04-29 3:28 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
@ 2008-04-29 5:08 ` Paul Mackerras
2008-04-29 5:42 ` [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code tosupportRev " Sean MacLennan
2008-05-06 15:27 ` Sean MacLennan
1 sibling, 1 reply; 28+ messages in thread
From: Paul Mackerras @ 2008-04-29 5:08 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev, Sean MacLennan, Stephen Rothwell
It doesn't help that both of these patches have the same subject line,
nor that it starts with "Re:". :(
Also, I find the statement "A change to the dts to get gpios correct
broke the led code" a bit opaque. It doesn't tell me in what way it
was broken or what this patch does to correct, or even what the change
was in enough detail that I could find the change in the git
repository.
Paul.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code tosupportRev B boards
2008-04-29 5:08 ` Paul Mackerras
@ 2008-04-29 5:42 ` Sean MacLennan
0 siblings, 0 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-04-29 5:42 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Stephen Rothwell
On Tue, 29 Apr 2008 15:08:29 +1000
"Paul Mackerras" <paulus@samba.org> wrote:
> It doesn't help that both of these patches have the same subject line,
> nor that it starts with "Re:". :(
Sorry about that. I just split up the two patches, but the same subject
does apply to both. The code currently in the mainline kernel is for a
Rev A. Since there are no Rev As outside of PIKA, that is not very
useful. These patches bring the platform code up to Rev B standards
(while still maintaining Rev A support).
So the subject is correct for both.
> Also, I find the statement "A change to the dts to get gpios correct
> broke the led code" a bit opaque. It doesn't tell me in what way it
> was broken or what this patch does to correct, or even what the change
> was in enough detail that I could find the change in the git
> repository.
You won't find it. One of the problems is that I am basically adding
patches to patches to patches, but since none of them are in a
mainline git, they all just keep showing up as one big patch.
That comment was meant as a quick note to explain why the platform patch
changed from the previous platform patch. Short of diffing the
patches, you can't easily see how they changed.
After the Warp is released (sometime in May), the hardware churn should
end and I can submit patches one at a time rather than one massive
patch.
Cheers,
Sean
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code tosupportRev B boards
2008-04-29 3:28 ` [RESEND][PATCH 1/2][POWERPC] " Sean MacLennan
2008-04-29 5:08 ` Paul Mackerras
@ 2008-05-06 15:27 ` Sean MacLennan
1 sibling, 0 replies; 28+ messages in thread
From: Sean MacLennan @ 2008-05-06 15:27 UTC (permalink / raw)
Cc: linuxppc-dev, Stephen Rothwell
Opps, there is a bug in this patch. The file pika.h is not included. I
have attached it below, but a simpler solution might be to just delete
it from this file. It is not required to build the kernel.
The file currently contains the exported dtm functions. These functions
are only used by the telephony driver, which is not in the mainline
kernel.
Cheers,
Sean
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/include/linux/pika.h b/include/linux/pika.h
new file mode 100644
index 0000000..83d51df
--- /dev/null
+++ b/include/linux/pika.h
@@ -0,0 +1,18 @@
+/*
+ * PIKA exported functions
+ *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.com>
+ */
+
+#ifndef _LINUX_PIKA_H
+#define _LINUX_PIKA_H
+
+#ifdef __KERNEL__
+
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg);
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg);
+
+#endif
+
+#endif
^ permalink raw reply related [flat|nested] 28+ messages in thread