[PATCH 4/8] powernv/eeh: Update the EEH code to use the opal irq domain

2015-04-01 Thread Alistair Popple
The eeh code currently uses the old notifier method to get eeh events
from OPAL. It also contains some logic to filter opal events which has
been moved into the virtual irqchip. This patch converts the eeh code
to the new event interface which simplifies event handling.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/eeh-ioda.c | 39 ++-
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c 
b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 2809c98..6eee1d1 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -36,34 +37,20 @@
 
 static int ioda_eeh_nb_init = 0;
 
-static int ioda_eeh_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t ioda_eeh_event(int irq, void *data)
 {
-   uint64_t changed_evts = (uint64_t)change;
-
/*
 * We simply send special EEH event if EEH has
 * been enabled, or clear pending events in
 * case that we enable EEH soon
 */
-   if (!(changed_evts & OPAL_EVENT_PCI_ERROR) ||
-   !(events & OPAL_EVENT_PCI_ERROR))
-   return 0;
 
if (eeh_enabled())
eeh_send_failure_event(NULL);
-   else
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
-   return 0;
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block ioda_eeh_nb = {
-   .notifier_call  = ioda_eeh_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 #ifdef CONFIG_DEBUG_FS
 static ssize_t ioda_eeh_ei_write(struct file *filp,
 const char __user *user_buf,
@@ -181,14 +168,23 @@ DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, 
ioda_eeh_inbB_dbgfs_get,
 static int ioda_eeh_post_init(struct pci_controller *hose)
 {
struct pnv_phb *phb = hose->private_data;
-   int ret;
+   int irq, ret;
 
/* Register OPAL event notifier */
if (!ioda_eeh_nb_init) {
-   ret = opal_notifier_register(&ioda_eeh_nb);
-   if (ret) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
-  __func__, ret);
+   irq = opal_event_request(ilog2(OPAL_EVENT_PCI_ERROR));
+   if (irq < 0) {
+   pr_err("%s: Can't register OPAL event interrupt (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   ret = request_irq(irq, ioda_eeh_event, IRQ_TYPE_EDGE_RISING,
+   "opal-eeh", NULL);
+   if (ret < 0) {
+   irq_dispose_mapping(irq);
+   pr_err("%s: Can't request OPAL event interrupt (%d)\n",
+  __func__, irq);
return ret;
}
 
@@ -969,7 +965,6 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
 * between the kernel and firmware.
 */
eeh_remove_event(NULL, false);
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
list_for_each_entry(hose, &hose_list, list_node) {
/*
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 2/8] ipmi/powernv: Convert to irq event interface

2015-04-01 Thread Alistair Popple
Convert the opal ipmi driver to use the new irq interface for events.

Signed-off-by: Alistair Popple 
---
 drivers/char/ipmi/ipmi_powernv.c | 39 ++-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c
index 79524ed..b3a2224 100644
--- a/drivers/char/ipmi/ipmi_powernv.c
+++ b/drivers/char/ipmi/ipmi_powernv.c
@@ -15,6 +15,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -23,8 +25,7 @@ struct ipmi_smi_powernv {
u64 interface_id;
struct ipmi_device_id   ipmi_id;
ipmi_smi_t  intf;
-   u64 event;
-   struct notifier_block   event_nb;
+   unsigned intirq;
 
/**
 * We assume that there can only be one outstanding request, so
@@ -196,15 +197,12 @@ static struct ipmi_smi_handlers ipmi_powernv_smi_handlers 
= {
.poll   = ipmi_powernv_poll,
 };
 
-static int ipmi_opal_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t ipmi_opal_event(int irq, void *data)
 {
-   struct ipmi_smi_powernv *smi = container_of(nb,
-   struct ipmi_smi_powernv, event_nb);
+   struct ipmi_smi_powernv *smi = data;
 
-   if (events & smi->event)
-   ipmi_powernv_recv(smi);
-   return 0;
+   ipmi_powernv_recv(smi);
+   return IRQ_HANDLED;
 }
 
 static int ipmi_powernv_probe(struct platform_device *pdev)
@@ -239,13 +237,16 @@ static int ipmi_powernv_probe(struct platform_device 
*pdev)
goto err_free;
}
 
-   ipmi->event = 1ull << prop;
-   ipmi->event_nb.notifier_call = ipmi_opal_event;
+   ipmi->irq = irq_of_parse_and_map(dev->of_node, 0);
+   if (!ipmi->irq) {
+   dev_info(dev, "Unable to map irq from device tree\n");
+   ipmi->irq = opal_event_request(prop);
+   }
 
-   rc = opal_notifier_register(&ipmi->event_nb);
-   if (rc) {
-   dev_warn(dev, "OPAL notifier registration failed (%d)\n", rc);
-   goto err_free;
+   if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH,
+   "opal-ipmi", ipmi)) {
+   dev_warn(dev, "Unable to request irq\n");
+   goto err_dispose;
}
 
ipmi->opal_msg = devm_kmalloc(dev,
@@ -270,7 +271,9 @@ static int ipmi_powernv_probe(struct platform_device *pdev)
 err_free_msg:
devm_kfree(dev, ipmi->opal_msg);
 err_unregister:
-   opal_notifier_unregister(&ipmi->event_nb);
+   free_irq(ipmi->irq, ipmi);
+err_dispose:
+   irq_dispose_mapping(ipmi->irq);
 err_free:
devm_kfree(dev, ipmi);
return rc;
@@ -281,7 +284,9 @@ static int ipmi_powernv_remove(struct platform_device *pdev)
struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev);
 
ipmi_unregister_smi(smi->intf);
-   opal_notifier_unregister(&smi->event_nb);
+   free_irq(smi->irq, smi);
+   irq_dispose_mapping(smi->irq);
+
return 0;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/8] powerpc/powernv: Add a virtual irqchip for opal events

2015-04-01 Thread Alistair Popple
Whenever an interrupt is received for opal the linux kernel gets a
bitfield indicating certain events that have occurred and need handling
by the various device drivers. Currently this is handled using a
notifier interface where we call every device driver that has
registered to receive opal events.

This approach has several drawbacks. For example each driver has to do
its own checking to see if the event is relevant as well as event
masking. There is also no easy method of recording the number of times
we receive particular events.

This patch solves these issues by exposing opal events via the
standard interrupt APIs by adding a new interrupt chip and
domain. Drivers can then register for the appropriate events using
standard kernel calls such as irq_of_parse_and_map().

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/opal.h   |   2 +
 arch/powerpc/platforms/powernv/Makefile   |   2 +-
 arch/powerpc/platforms/powernv/opal-irqchip.c | 259 ++
 arch/powerpc/platforms/powernv/opal.c |  70 +--
 arch/powerpc/platforms/powernv/powernv.h  |   4 +
 5 files changed, 271 insertions(+), 66 deletions(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-irqchip.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9ee0a30..4d969f7 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -979,6 +979,8 @@ extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
+extern int opal_event_request(unsigned int opal_event_nr);
+
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 unsigned long vmalloc_size);
 void opal_free_sg_list(struct opal_sg_list *sg);
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 6f3c5d3..911154f 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
 obj-y  += setup.o opal-wrappers.o opal.o opal-async.o
 obj-y  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
-obj-y  += opal-msglog.o opal-hmi.o opal-power.o
+obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
new file mode 100644
index 000..acc12e3
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -0,0 +1,259 @@
+/*
+ * This file implements an irqchip for OPAL events. Whenever there is
+ * an interrupt that is handled by OPAL we get passed a list of events
+ * that Linux needs to do something about. These basically look like
+ * interrupts to Linux so we implement an irqchip to handle them.
+ *
+ * Copyright Alistair Popple, IBM Corporation 2014.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "powernv.h"
+
+struct opal_event_irqchip {
+   struct irq_chip irqchip;
+   struct irq_domain *domain;
+   unsigned long mask;
+   unsigned long ack;
+   unsigned long edge;
+};
+static struct opal_event_irqchip opal_event_irqchip;
+
+static unsigned int opal_irq_count;
+static unsigned int *opal_irqs;
+
+static void opal_event_ack(struct irq_data *d)
+{
+   /* Set the ack bit so that we don't get any more interrupts
+* until the event is cleared. */
+   if (opal_event_irqchip.edge & BIT_ULL(d->hwirq))
+   set_bit(d->hwirq, &opal_event_irqchip.ack);
+}
+
+static void opal_event_mask(struct irq_data *d)
+{
+   clear_bit(d->hwirq, &opal_event_irqchip.mask);
+}
+
+static void opal_event_unmask(struct irq_data *d)
+{
+   set_bit(d->hwirq, &opal_event_irqchip.mask);
+}
+
+static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)
+{
+   /* We support two flow types - level and edge. These
+* correspond to the two possible ways events are used. When
+* flow_type is set to LEVEL_HIGH the irq handler will be
+* called continuously until the event has been cleared.
+*
+* When flow_type is set to EDGE_RISING we call the irq
+* handler once each time the event is set. The handler will
+* not be called again until Linux has seen the event cleared
+* in OPAL. */
+
+   switch (flo

[PATCH 3/8] hvc: Convert to using interrupts instead of opal events

2015-04-01 Thread Alistair Popple
Convert the opal hvc driver to use the new irqchip to register for
opal events. As older firmware version may not have device tree
bindings for the interrupt parent we just use a hardcoded hwirq based
on the event number.

Signed-off-by: Alistair Popple 
---
 drivers/tty/hvc/hvc_opal.c | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 071551b..240283e 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -162,27 +163,21 @@ static const struct hv_ops hvc_opal_hvsi_ops = {
.tiocmset = hvc_opal_hvsi_tiocmset,
 };
 
-static int hvc_opal_console_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t hvc_opal_console_event(int irq, void *data)
 {
-   if (events & OPAL_EVENT_CONSOLE_INPUT)
-   hvc_kick();
+   hvc_kick();
return 0;
 }
 
-static struct notifier_block hvc_opal_console_nb = {
-   .notifier_call  = hvc_opal_console_event,
-};
-
 static int hvc_opal_probe(struct platform_device *dev)
 {
const struct hv_ops *ops;
struct hvc_struct *hp;
struct hvc_opal_priv *pv;
hv_protocol_t proto;
-   unsigned int termno, boot = 0;
+   unsigned int termno, irq, boot = 0;
const __be32 *reg;
-
+   int rc;
 
if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
proto = HV_PROTOCOL_RAW;
@@ -235,7 +230,19 @@ static int hvc_opal_probe(struct platform_device *dev)
 
/* ...  but we use OPAL event to kick the console */
if (!hvc_opal_event_registered) {
-   opal_notifier_register(&hvc_opal_console_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_CONSOLE_INPUT));
+   if (!irq) {
+   pr_err("hvc_opal: Unable to map interrupt for device 
%s\n",
+   dev->dev.of_node->full_name);
+   return irq;
+   }
+   rc = request_irq(irq, hvc_opal_console_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-hvc", NULL);
+   if (rc) {
+   pr_err("hvc_opal: Unable to request interrput for 
device %s\n",
+   dev->dev.of_node->full_name);
+   return rc;
+   }
hvc_opal_event_registered = true;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 5/8] powernv/opal: Convert opal message events to opal irq domain

2015-04-01 Thread Alistair Popple
This patch converts the opal message event to use the new opal irq
domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 1d73b85..b37f0fc 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -356,33 +356,34 @@ static void opal_handle_message(void)
opal_message_do_notify(type, (void *)&msg);
 }
 
-static int opal_message_notify(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t opal_message_notify(int irq, void *data)
 {
-   if (events & OPAL_EVENT_MSG_PENDING)
-   opal_handle_message();
-   return 0;
+   opal_handle_message();
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block opal_message_nb = {
-   .notifier_call  = opal_message_notify,
-   .next   = NULL,
-   .priority   = 0,
-};
-
 static int __init opal_message_init(void)
 {
-   int ret, i;
+   int ret, i, irq;
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
 
-   ret = opal_notifier_register(&opal_message_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_MSG_PENDING));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   ret = request_irq(irq, opal_message_notify,
+   IRQ_TYPE_LEVEL_HIGH, "opal-msg", NULL);
if (ret) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
   __func__, ret);
return ret;
}
+
return 0;
 }
 machine_early_initcall(powernv, opal_message_init);
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 7/8] powernv/opal-dump: Convert to irq domain

2015-04-01 Thread Alistair Popple
Convert the opal dump driver to the new opal irq domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 33 +++---
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 23260f7..812f168 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -60,7 +61,7 @@ static ssize_t dump_type_show(struct dump_obj *dump_obj,
  struct dump_attribute *attr,
  char *buf)
 {
-   
+
return sprintf(buf, "0x%x %s\n", dump_obj->type,
   dump_type_to_string(dump_obj->type));
 }
@@ -408,24 +409,16 @@ static void schedule_process_dump(void)
  * Once we get notification, we add sysfs entries for it.
  * We only fetch the dump on demand, and create sysfs asynchronously.
  */
-static int dump_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t dump_event(int irq, void *data)
 {
-   if (events & OPAL_EVENT_DUMP_AVAIL)
-   schedule_process_dump();
+   schedule_process_dump();
 
-   return 0;
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block dump_nb = {
-   .notifier_call  = dump_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 void __init opal_platform_dump_init(void)
 {
-   int rc;
+   int rc, irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_DUMP_READ))
@@ -445,10 +438,18 @@ void __init opal_platform_dump_init(void)
return;
}
 
-   rc = opal_notifier_register(&dump_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_DUMP_AVAIL));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return;
+   }
+
+   rc = request_irq(irq, dump_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-dump", NULL);
if (rc) {
-   pr_warn("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 8/8] opal: Remove events notifier

2015-04-01 Thread Alistair Popple
All users of the old opal events notifier have been converted over to
the irq domain so remove the event notifier functions.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-irqchip.c |  4 --
 arch/powerpc/platforms/powernv/opal.c | 84 +--
 arch/powerpc/platforms/powernv/powernv.h  |  1 -
 arch/powerpc/platforms/powernv/setup.c|  2 +-
 4 files changed, 2 insertions(+), 89 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
index acc12e3..a6f7dfd 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -132,10 +132,6 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
opal_handle_interrupt(virq_to_hw(irq), &events);
 
-   /* Continue to call the notifiers until we have converted
-* existing users over. */
-   opal_do_notifier(be64_to_cpu(events));
-
/* Clear the ack bit once an event is set to zero */
opal_event_irqchip.ack &= events;
 
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index b37f0fc..11794d7 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -51,11 +51,7 @@ static int mc_recoverable_range_len;
 
 struct device_node *opal_node;
 static DEFINE_SPINLOCK(opal_write_lock);
-static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
-static DEFINE_SPINLOCK(opal_notifier_lock);
-static uint64_t last_notified_mask = 0x0ul;
-static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 
 static void opal_reinit_cores(void)
 {
@@ -220,82 +216,6 @@ static int __init opal_register_exception_handlers(void)
 }
 machine_early_initcall(powernv, opal_register_exception_handlers);
 
-int opal_notifier_register(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_register(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_register);
-
-int opal_notifier_unregister(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_unregister(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_unregister);
-
-void opal_do_notifier(uint64_t events)
-{
-   unsigned long flags;
-   uint64_t changed_mask;
-
-   if (atomic_read(&opal_notifier_hold))
-   return;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   changed_mask = last_notified_mask ^ events;
-   last_notified_mask = events;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-
-   /*
-* We feed with the event bits and changed bits for
-* enough information to the callback.
-*/
-   atomic_notifier_call_chain(&opal_notifier_head,
-  events, (void *)changed_mask);
-}
-
-void opal_notifier_update_evt(uint64_t evt_mask,
- uint64_t evt_val)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   last_notified_mask &= ~evt_mask;
-   last_notified_mask |= evt_val;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-}
-
-void opal_notifier_enable(void)
-{
-   int64_t rc;
-   __be64 evt = 0;
-
-   atomic_set(&opal_notifier_hold, 0);
-
-   /* Process pending events */
-   rc = opal_poll_events(&evt);
-   if (rc == OPAL_SUCCESS && evt)
-   opal_do_notifier(be64_to_cpu(evt));
-}
-
-void opal_notifier_disable(void)
-{
-   atomic_set(&opal_notifier_hold, 1);
-}
-
 /*
  * Opal message notifier based on message type. Allow subscribers to get
  * notified for specific messgae type.
@@ -565,10 +485,8 @@ int opal_handle_hmi_exception(struct pt_regs *regs)
 
local_paca->hmi_event_available = 0;
rc = opal_poll_events(&evt);
-   if (rc == OPAL_SUCCESS && evt) {
-   opal_do_notifier(be64_to_cpu(evt));
+   if (rc == OPAL_SUCCESS && evt)
opal_handle_events(be64_to_cpu(evt));
-   }
 
return 1;
 }
diff --git a/arch/powerpc/platforms/powernv/powernv.h 
b/arch/powerpc/platforms/powernv/powernv.h
index 41edf6c..addd15c 100644
--- a/arch/powerpc/platforms/powernv/powernv.h
+++ b/arch/powerpc/platforms/powernv/powernv.h
@@ -33,7 +33,6 @@ extern u32 pnv_get_supported_cpuidle_states(void);
 
 extern void pnv_lpc_init(void);
 
-extern void opal_do_notifier(uint64_t events);
 extern void opal_handle_events(uint64_t events);
 e

[PATCH 6/8] powernv/elog: Convert elog to opal irq domain

2015-04-01 Thread Alistair Popple
This patch converts the elog code to use the opal irq domain instead
of notifier events.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-elog.c | 32 +++---
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 518fe95..99b50cd 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -10,6 +10,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -276,24 +277,15 @@ static void elog_work_fn(struct work_struct *work)
 
 static DECLARE_WORK(elog_work, elog_work_fn);
 
-static int elog_event(struct notifier_block *nb,
-   unsigned long events, void *change)
+static irqreturn_t elog_event(int irq, void *data)
 {
-   /* check for error log event */
-   if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
-   schedule_work(&elog_work);
-   return 0;
+   schedule_work(&elog_work);
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block elog_nb = {
-   .notifier_call  = elog_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 int __init opal_elog_init(void)
 {
-   int rc = 0;
+   int rc = 0, irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_ELOG_READ))
@@ -305,10 +297,18 @@ int __init opal_elog_init(void)
return -1;
}
 
-   rc = opal_notifier_register(&elog_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_ERROR_LOG_AVAIL));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   rc = request_irq(irq, elog_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL);
if (rc) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return rc;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 4/8] powernv/eeh: Update the EEH code to use the opal irq domain

2015-05-06 Thread Alistair Popple
The eeh code currently uses the old notifier method to get eeh events
from OPAL. It also contains some logic to filter opal events which has
been moved into the virtual irqchip. This patch converts the eeh code
to the new event interface which simplifies event handling.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 58 +++-
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index ce738ab..ca825ec 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,7 @@
 #include "pci.h"
 
 static bool pnv_eeh_nb_init = false;
+static int eeh_event_irq = -EINVAL;
 
 /**
  * pnv_eeh_init - EEH platform dependent initialization
@@ -88,34 +90,22 @@ static int pnv_eeh_init(void)
return 0;
 }
 
-static int pnv_eeh_event(struct notifier_block *nb,
-unsigned long events, void *change)
+static irqreturn_t pnv_eeh_event(int irq, void *data)
 {
-   uint64_t changed_evts = (uint64_t)change;
-
/*
-* We simply send special EEH event if EEH has
-* been enabled, or clear pending events in
-* case that we enable EEH soon
+* We simply send a special EEH event if EEH has been
+* enabled. We don't care about EEH events until we've
+* finished processing the outstanding ones. Event processing
+* gets unmasked in next_error() if EEH is enabled.
 */
-   if (!(changed_evts & OPAL_EVENT_PCI_ERROR) ||
-   !(events & OPAL_EVENT_PCI_ERROR))
-   return 0;
+   disable_irq_nosync(irq);
 
if (eeh_enabled())
eeh_send_failure_event(NULL);
-   else
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
-   return 0;
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block pnv_eeh_nb = {
-   .notifier_call  = pnv_eeh_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 #ifdef CONFIG_DEBUG_FS
 static ssize_t pnv_eeh_ei_write(struct file *filp,
const char __user *user_buf,
@@ -237,16 +227,28 @@ static int pnv_eeh_post_init(void)
 
/* Register OPAL event notifier */
if (!pnv_eeh_nb_init) {
-   ret = opal_notifier_register(&pnv_eeh_nb);
-   if (ret) {
-   pr_warn("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, ret);
+   eeh_event_irq = opal_event_request(ilog2(OPAL_EVENT_PCI_ERROR));
+   if (eeh_event_irq < 0) {
+   pr_err("%s: Can't register OPAL event interrupt (%d)\n",
+  __func__, eeh_event_irq);
+   return eeh_event_irq;
+   }
+
+   ret = request_irq(eeh_event_irq, pnv_eeh_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-eeh", NULL);
+   if (ret < 0) {
+   irq_dispose_mapping(eeh_event_irq);
+   pr_err("%s: Can't request OPAL event interrupt (%d)\n",
+  __func__, eeh_event_irq);
return ret;
}
 
pnv_eeh_nb_init = true;
}
 
+   if (!eeh_enabled())
+   disable_irq(eeh_event_irq);
+
list_for_each_entry(hose, &hose_list, list_node) {
phb = hose->private_data;
 
@@ -1303,12 +1305,10 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
int state, ret = EEH_NEXT_ERR_NONE;
 
/*
-* While running here, it's safe to purge the event queue.
-* And we should keep the cached OPAL notifier event sychronized
-* between the kernel and firmware.
+* While running here, it's safe to purge the event queue. The
+* event should still be masked.
 */
eeh_remove_event(NULL, false);
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
list_for_each_entry(hose, &hose_list, list_node) {
/*
@@ -1477,6 +1477,10 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
break;
}
 
+   /* Unmask the event */
+   if (eeh_enabled())
+   enable_irq(eeh_event_irq);
+
return ret;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 2/8] ipmi/powernv: Convert to irq event interface

2015-05-06 Thread Alistair Popple
Convert the opal ipmi driver to use the new irq interface for events.

Signed-off-by: Alistair Popple 
Cc: Corey Minyard 
Cc: openipmi-develo...@lists.sourceforge.net
---

Corey,

If this looks ok can you please ack it? Michael Ellerman will then take
the whole series via the powerpc tree. Thanks.

 drivers/char/ipmi/ipmi_powernv.c | 39 ++-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c
index 8753b0f..9b409c0 100644
--- a/drivers/char/ipmi/ipmi_powernv.c
+++ b/drivers/char/ipmi/ipmi_powernv.c
@@ -15,6 +15,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include 

@@ -23,8 +25,7 @@ struct ipmi_smi_powernv {
u64 interface_id;
struct ipmi_device_id   ipmi_id;
ipmi_smi_t  intf;
-   u64 event;
-   struct notifier_block   event_nb;
+   unsigned intirq;

/**
 * We assume that there can only be one outstanding request, so
@@ -197,15 +198,12 @@ static struct ipmi_smi_handlers ipmi_powernv_smi_handlers 
= {
.poll   = ipmi_powernv_poll,
 };

-static int ipmi_opal_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t ipmi_opal_event(int irq, void *data)
 {
-   struct ipmi_smi_powernv *smi = container_of(nb,
-   struct ipmi_smi_powernv, event_nb);
+   struct ipmi_smi_powernv *smi = data;

-   if (events & smi->event)
-   ipmi_powernv_recv(smi);
-   return 0;
+   ipmi_powernv_recv(smi);
+   return IRQ_HANDLED;
 }

 static int ipmi_powernv_probe(struct platform_device *pdev)
@@ -240,13 +238,16 @@ static int ipmi_powernv_probe(struct platform_device 
*pdev)
goto err_free;
}

-   ipmi->event = 1ull << prop;
-   ipmi->event_nb.notifier_call = ipmi_opal_event;
+   ipmi->irq = irq_of_parse_and_map(dev->of_node, 0);
+   if (!ipmi->irq) {
+   dev_info(dev, "Unable to map irq from device tree\n");
+   ipmi->irq = opal_event_request(prop);
+   }

-   rc = opal_notifier_register(&ipmi->event_nb);
-   if (rc) {
-   dev_warn(dev, "OPAL notifier registration failed (%d)\n", rc);
-   goto err_free;
+   if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH,
+   "opal-ipmi", ipmi)) {
+   dev_warn(dev, "Unable to request irq\n");
+   goto err_dispose;
}

ipmi->opal_msg = devm_kmalloc(dev,
@@ -271,7 +272,9 @@ static int ipmi_powernv_probe(struct platform_device *pdev)
 err_free_msg:
devm_kfree(dev, ipmi->opal_msg);
 err_unregister:
-   opal_notifier_unregister(&ipmi->event_nb);
+   free_irq(ipmi->irq, ipmi);
+err_dispose:
+   irq_dispose_mapping(ipmi->irq);
 err_free:
devm_kfree(dev, ipmi);
return rc;
@@ -282,7 +285,9 @@ static int ipmi_powernv_remove(struct platform_device *pdev)
struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev);

ipmi_unregister_smi(smi->intf);
-   opal_notifier_unregister(&smi->event_nb);
+   free_irq(smi->irq, smi);
+   irq_dispose_mapping(smi->irq);
+
return 0;
 }

--
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 3/8] hvc: Convert to using interrupts instead of opal events

2015-05-06 Thread Alistair Popple
Convert the opal hvc driver to use the new irqchip to register for
opal events. As older firmware versions may not have device tree
bindings for the interrupt parent we just use a hardcoded hwirq based
on the event number.

Signed-off-by: Alistair Popple 
---
 drivers/tty/hvc/hvc_opal.c | 33 ++---
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 543b234..47b54c6 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -61,7 +62,6 @@ static struct hvc_opal_priv 
*hvc_opal_privs[MAX_NR_HVC_CONSOLES];
 /* For early boot console */
 static struct hvc_opal_priv hvc_opal_boot_priv;
 static u32 hvc_opal_boot_termno;
-static bool hvc_opal_event_registered;
 
 static const struct hv_ops hvc_opal_raw_ops = {
.get_chars = opal_get_chars,
@@ -162,28 +162,15 @@ static const struct hv_ops hvc_opal_hvsi_ops = {
.tiocmset = hvc_opal_hvsi_tiocmset,
 };
 
-static int hvc_opal_console_event(struct notifier_block *nb,
- unsigned long events, void *change)
-{
-   if (events & OPAL_EVENT_CONSOLE_INPUT)
-   hvc_kick();
-   return 0;
-}
-
-static struct notifier_block hvc_opal_console_nb = {
-   .notifier_call  = hvc_opal_console_event,
-};
-
 static int hvc_opal_probe(struct platform_device *dev)
 {
const struct hv_ops *ops;
struct hvc_struct *hp;
struct hvc_opal_priv *pv;
hv_protocol_t proto;
-   unsigned int termno, boot = 0;
+   unsigned int termno, irq, boot = 0;
const __be32 *reg;
 
-
if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
proto = HV_PROTOCOL_RAW;
ops = &hvc_opal_raw_ops;
@@ -227,18 +214,18 @@ static int hvc_opal_probe(struct platform_device *dev)
dev->dev.of_node->full_name,
boot ? " (boot console)" : "");
 
-   /* We don't do IRQ ... */
-   hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS);
+   irq = opal_event_request(ilog2(OPAL_EVENT_CONSOLE_INPUT));
+   if (!irq) {
+   pr_err("hvc_opal: Unable to map interrupt for device %s\n",
+   dev->dev.of_node->full_name);
+   return irq;
+   }
+
+   hp = hvc_alloc(termno, irq, ops, MAX_VIO_PUT_CHARS);
if (IS_ERR(hp))
return PTR_ERR(hp);
dev_set_drvdata(&dev->dev, hp);
 
-   /* ...  but we use OPAL event to kick the console */
-   if (!hvc_opal_event_registered) {
-   opal_notifier_register(&hvc_opal_console_nb);
-   hvc_opal_event_registered = true;
-   }
-
return 0;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 1/8] powerpc/powernv: Add a virtual irqchip for opal events

2015-05-06 Thread Alistair Popple
Whenever an interrupt is received for opal the linux kernel gets a
bitfield indicating certain events that have occurred and need handling
by the various device drivers. Currently this is handled using a
notifier interface where we call every device driver that has
registered to receive opal events.

This approach has several drawbacks. For example each driver has to do
its own checking to see if the event is relevant as well as event
masking. There is also no easy method of recording the number of times
we receive particular events.

This patch solves these issues by exposing opal events via the
standard interrupt APIs by adding a new interrupt chip and
domain. Drivers can then register for the appropriate events using
standard kernel calls such as irq_of_parse_and_map().

Signed-off-by: Alistair Popple 
---

Changes from v2:
 - Addressed comments by Neelesh Gupta
 - Fixed soft-lockup bug reported by Neelesh in the opal-dump driver
 - Rebased on v4.1-rc1

 arch/powerpc/include/asm/opal.h   |   2 +
 arch/powerpc/platforms/powernv/Makefile   |   2 +-
 arch/powerpc/platforms/powernv/opal-irqchip.c | 248 ++
 arch/powerpc/platforms/powernv/opal.c |  70 +---
 arch/powerpc/platforms/powernv/powernv.h  |   4 +
 5 files changed, 260 insertions(+), 66 deletions(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-irqchip.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 042af1a..9ffd113 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -250,6 +250,8 @@ extern int opal_resync_timebase(void);

 extern void opal_lpc_init(void);

+extern int opal_event_request(unsigned int opal_event_nr);
+
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 unsigned long vmalloc_size);
 void opal_free_sg_list(struct opal_sg_list *sg);
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 33e44f3..f1d7de2 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
 obj-y  += setup.o opal-wrappers.o opal.o opal-async.o
 obj-y  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
-obj-y  += opal-msglog.o opal-hmi.o opal-power.o
+obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o

 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
new file mode 100644
index 000..4b6f951
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -0,0 +1,248 @@
+/*
+ * This file implements an irqchip for OPAL events. Whenever there is
+ * an interrupt that is handled by OPAL we get passed a list of events
+ * that Linux needs to do something about. These basically look like
+ * interrupts to Linux so we implement an irqchip to handle them.
+ *
+ * Copyright Alistair Popple, IBM Corporation 2014.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "powernv.h"
+
+/* Maximum number of events supported by OPAL firmware */
+#define MAX_NUM_EVENTS 64
+
+struct opal_event_irqchip {
+   struct irq_chip irqchip;
+   struct irq_domain *domain;
+   unsigned long mask;
+};
+static struct opal_event_irqchip opal_event_irqchip;
+
+static unsigned int opal_irq_count;
+static unsigned int *opal_irqs;
+
+static void opal_handle_irq_work(struct irq_work *work);
+static __be64 last_outstanding_events;
+static struct irq_work opal_event_irq_work = {
+   .func = opal_handle_irq_work,
+};
+
+static void opal_event_mask(struct irq_data *d)
+{
+   clear_bit(d->hwirq, &opal_event_irqchip.mask);
+}
+
+static void opal_event_unmask(struct irq_data *d)
+{
+   set_bit(d->hwirq, &opal_event_irqchip.mask);
+
+   opal_poll_events(&last_outstanding_events);
+   if (last_outstanding_events & opal_event_irqchip.mask)
+   /* Need to retrigger the interrupt */
+   irq_work_queue(&opal_event_irq_work);
+}
+
+static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)
+{
+   /*
+* For now we only support level triggered events. The irq
+* handler will be called continuously until the event has
+* been cleared in OPAL.
+*/
+   

[PATCH v3 5/8] powernv/opal: Convert opal message events to opal irq domain

2015-05-06 Thread Alistair Popple
This patch converts the opal message event to use the new opal irq
domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 4399ff2..0196220 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -362,33 +362,34 @@ static void opal_handle_message(void)
opal_message_do_notify(type, (void *)&msg);
 }
 
-static int opal_message_notify(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t opal_message_notify(int irq, void *data)
 {
-   if (events & OPAL_EVENT_MSG_PENDING)
-   opal_handle_message();
-   return 0;
+   opal_handle_message();
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block opal_message_nb = {
-   .notifier_call  = opal_message_notify,
-   .next   = NULL,
-   .priority   = 0,
-};
-
 static int __init opal_message_init(void)
 {
-   int ret, i;
+   int ret, i, irq;
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
 
-   ret = opal_notifier_register(&opal_message_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_MSG_PENDING));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   ret = request_irq(irq, opal_message_notify,
+   IRQ_TYPE_LEVEL_HIGH, "opal-msg", NULL);
if (ret) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
   __func__, ret);
return ret;
}
+
return 0;
 }
 machine_early_initcall(powernv, opal_message_init);
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 7/8] powernv/opal-dump: Convert to irq domain

2015-05-06 Thread Alistair Popple
Convert the opal dump driver to the new opal irq domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 56 +-
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 5aa9c1c..2ee9643 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -60,7 +61,7 @@ static ssize_t dump_type_show(struct dump_obj *dump_obj,
  struct dump_attribute *attr,
  char *buf)
 {
-   
+
return sprintf(buf, "0x%x %s\n", dump_obj->type,
   dump_type_to_string(dump_obj->type));
 }
@@ -363,7 +364,7 @@ static struct dump_obj *create_dump_obj(uint32_t id, size_t 
size,
return dump;
 }
 
-static int process_dump(void)
+static irqreturn_t process_dump(int irq, void *data)
 {
int rc;
uint32_t dump_id, dump_size, dump_type;
@@ -387,45 +388,13 @@ static int process_dump(void)
if (!dump)
return -1;
 
-   return 0;
-}
-
-static void dump_work_fn(struct work_struct *work)
-{
-   process_dump();
+   return IRQ_HANDLED;
 }
 
-static DECLARE_WORK(dump_work, dump_work_fn);
-
-static void schedule_process_dump(void)
-{
-   schedule_work(&dump_work);
-}
-
-/*
- * New dump available notification
- *
- * Once we get notification, we add sysfs entries for it.
- * We only fetch the dump on demand, and create sysfs asynchronously.
- */
-static int dump_event(struct notifier_block *nb,
- unsigned long events, void *change)
-{
-   if (events & OPAL_EVENT_DUMP_AVAIL)
-   schedule_process_dump();
-
-   return 0;
-}
-
-static struct notifier_block dump_nb = {
-   .notifier_call  = dump_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 void __init opal_platform_dump_init(void)
 {
int rc;
+   int dump_irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_DUMP_READ))
@@ -445,10 +414,19 @@ void __init opal_platform_dump_init(void)
return;
}
 
-   rc = opal_notifier_register(&dump_nb);
+   dump_irq = opal_event_request(ilog2(OPAL_EVENT_DUMP_AVAIL));
+   if (!dump_irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, dump_irq);
+   return;
+   }
+
+   rc = request_threaded_irq(dump_irq, NULL, process_dump,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+   "opal-dump", NULL);
if (rc) {
-   pr_warn("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 6/8] powernv/elog: Convert elog to opal irq domain

2015-05-06 Thread Alistair Popple
This patch converts the elog code to use the opal irq domain instead
of notifier events.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-elog.c | 32 +++---
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 38ce757..4949ef0 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -10,6 +10,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -276,24 +277,15 @@ static void elog_work_fn(struct work_struct *work)
 
 static DECLARE_WORK(elog_work, elog_work_fn);
 
-static int elog_event(struct notifier_block *nb,
-   unsigned long events, void *change)
+static irqreturn_t elog_event(int irq, void *data)
 {
-   /* check for error log event */
-   if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
-   schedule_work(&elog_work);
-   return 0;
+   schedule_work(&elog_work);
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block elog_nb = {
-   .notifier_call  = elog_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 int __init opal_elog_init(void)
 {
-   int rc = 0;
+   int rc = 0, irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_ELOG_READ))
@@ -305,10 +297,18 @@ int __init opal_elog_init(void)
return -1;
}
 
-   rc = opal_notifier_register(&elog_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_ERROR_LOG_AVAIL));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   rc = request_irq(irq, elog_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL);
if (rc) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return rc;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 8/8] opal: Remove events notifier

2015-05-06 Thread Alistair Popple
All users of the old opal events notifier have been converted over to
the irq domain so remove the event notifier functions.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-irqchip.c | 16 ++---
 arch/powerpc/platforms/powernv/opal.c | 84 +--
 arch/powerpc/platforms/powernv/powernv.h  |  1 -
 arch/powerpc/platforms/powernv/setup.c|  2 +-
 4 files changed, 8 insertions(+), 95 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
index 4b6f951..8c17d81 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -100,21 +100,17 @@ void opal_handle_events(uint64_t events)
 {
int virq, hwirq = 0;
u64 mask = opal_event_irqchip.mask;
-   u64 notifier_mask = 0;
 
-   while (events) {
+   while (events & mask) {
hwirq = fls64(events) - 1;
-   virq = irq_find_mapping(opal_event_irqchip.domain,
-   hwirq);
-   if (virq) {
-   if (BIT_ULL(hwirq) & mask)
+   if (BIT_ULL(hwirq) & mask) {
+   virq = irq_find_mapping(opal_event_irqchip.domain,
+   hwirq);
+   if (virq)
generic_handle_irq(virq);
-   } else
-   notifier_mask |= BIT_ULL(hwirq);
+   }
events &= ~BIT_ULL(hwirq);
}
-
-   opal_do_notifier(notifier_mask);
 }
 
 static irqreturn_t opal_interrupt(int irq, void *data)
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 0196220..a5e48cd 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -53,11 +53,7 @@ static int mc_recoverable_range_len;
 
 struct device_node *opal_node;
 static DEFINE_SPINLOCK(opal_write_lock);
-static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
-static DEFINE_SPINLOCK(opal_notifier_lock);
-static uint64_t last_notified_mask = 0x0ul;
-static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 static uint32_t opal_heartbeat;
 
 static void opal_reinit_cores(void)
@@ -223,82 +219,6 @@ static int __init opal_register_exception_handlers(void)
 }
 machine_early_initcall(powernv, opal_register_exception_handlers);
 
-int opal_notifier_register(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_register(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_register);
-
-int opal_notifier_unregister(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_unregister(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_unregister);
-
-void opal_do_notifier(uint64_t events)
-{
-   unsigned long flags;
-   uint64_t changed_mask;
-
-   if (atomic_read(&opal_notifier_hold))
-   return;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   changed_mask = last_notified_mask ^ events;
-   last_notified_mask = events;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-
-   /*
-* We feed with the event bits and changed bits for
-* enough information to the callback.
-*/
-   atomic_notifier_call_chain(&opal_notifier_head,
-  events, (void *)changed_mask);
-}
-
-void opal_notifier_update_evt(uint64_t evt_mask,
- uint64_t evt_val)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   last_notified_mask &= ~evt_mask;
-   last_notified_mask |= evt_val;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-}
-
-void opal_notifier_enable(void)
-{
-   int64_t rc;
-   __be64 evt = 0;
-
-   atomic_set(&opal_notifier_hold, 0);
-
-   /* Process pending events */
-   rc = opal_poll_events(&evt);
-   if (rc == OPAL_SUCCESS && evt)
-   opal_do_notifier(be64_to_cpu(evt));
-}
-
-void opal_notifier_disable(void)
-{
-   atomic_set(&opal_notifier_hold, 1);
-}
-
 /*
  * Opal message notifier based on message type. Allow subscribers to get
  * notified for specific messgae type.
@@ -571,10 +491,8 @@ int opal_handle_hmi_exception(struct pt_regs *regs)
 
local_paca->hmi_event_available = 0;
rc = opal_poll_events(&evt);
-   if (rc == OPAL_S

Re: [PATCH v3 2/8] ipmi/powernv: Convert to irq event interface

2015-05-10 Thread Alistair Popple
Hi,

On Thu, 7 May 2015 12:43:11 Corey Minyard wrote:
> 
> The only thing I would suggest is passing the irq level
> (IRQ_TYPE_LEVEL_HIGH) as
> part of the openfirmware data instead of hard-coding it.

I intend to do that in future once our firmware is updated to pass this 
information (via 
the device-tree). However systems with older firmware won't pass this 
information, 
hence we hard code it for the existing events.

- Alistair

> 
> Acked-by: Corey Minyard 
> 
> >  drivers/char/ipmi/ipmi_powernv.c | 39
> >  ++- 1 file changed, 22
> >  insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/char/ipmi/ipmi_powernv.c
> > b/drivers/char/ipmi/ipmi_powernv.c index 8753b0f..9b409c0 100644
> > --- a/drivers/char/ipmi/ipmi_powernv.c
> > +++ b/drivers/char/ipmi/ipmi_powernv.c
> > @@ -15,6 +15,8 @@
> > 
> >  #include 
> >  #include 
> >  #include 
> > 
> > +#include 
> > +#include 
> > 
> >  #include 
> > 
> > @@ -23,8 +25,7 @@ struct ipmi_smi_powernv {
> > 
> > u64 interface_id;
> > struct ipmi_device_id   ipmi_id;
> > ipmi_smi_t  intf;
> > 
> > -   u64 event;
> > -   struct notifier_block   event_nb;
> > +   unsigned intirq;
> > 
> > /**
> > 
> >  * We assume that there can only be one outstanding request, so
> > 
> > @@ -197,15 +198,12 @@ static struct ipmi_smi_handlers
> > ipmi_powernv_smi_handlers = {> 
> > .poll   = ipmi_powernv_poll,
> >  
> >  };
> > 
> > -static int ipmi_opal_event(struct notifier_block *nb,
> > - unsigned long events, void *change)
> > +static irqreturn_t ipmi_opal_event(int irq, void *data)
> > 
> >  {
> > 
> > -   struct ipmi_smi_powernv *smi = container_of(nb,
> > -   struct 
ipmi_smi_powernv, event_nb);
> > +   struct ipmi_smi_powernv *smi = data;
> > 
> > -   if (events & smi->event)
> > -   ipmi_powernv_recv(smi);
> > -   return 0;
> > +   ipmi_powernv_recv(smi);
> > +   return IRQ_HANDLED;
> > 
> >  }
> >  
> >  static int ipmi_powernv_probe(struct platform_device *pdev)
> > 
> > @@ -240,13 +238,16 @@ static int ipmi_powernv_probe(struct platform_device
> > *pdev)> 
> > goto err_free;
> > 
> > }
> > 
> > -   ipmi->event = 1ull << prop;
> > -   ipmi->event_nb.notifier_call = ipmi_opal_event;
> > +   ipmi->irq = irq_of_parse_and_map(dev->of_node, 0);
> > +   if (!ipmi->irq) {
> > +   dev_info(dev, "Unable to map irq from device tree\n");
> > +   ipmi->irq = opal_event_request(prop);
> > +   }
> > 
> > -   rc = opal_notifier_register(&ipmi->event_nb);
> > -   if (rc) {
> > -   dev_warn(dev, "OPAL notifier registration failed 
(%d)\n", rc);
> > -   goto err_free;
> > +   if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH,
> > +   "opal-ipmi", ipmi)) {
> > +   dev_warn(dev, "Unable to request irq\n");
> > +   goto err_dispose;
> > 
> > }
> > 
> > ipmi->opal_msg = devm_kmalloc(dev,
> > 
> > @@ -271,7 +272,9 @@ static int ipmi_powernv_probe(struct platform_device
> > *pdev)> 
> >  err_free_msg:
> > devm_kfree(dev, ipmi->opal_msg);
> >  
> >  err_unregister:
> > -   opal_notifier_unregister(&ipmi->event_nb);
> > +   free_irq(ipmi->irq, ipmi);
> > +err_dispose:
> > +   irq_dispose_mapping(ipmi->irq);
> > 
> >  err_free:
> > devm_kfree(dev, ipmi);
> > return rc;
> > 
> > @@ -282,7 +285,9 @@ static int ipmi_powernv_remove(struct platform_device
> > *pdev)> 
> > struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev);
> > 
> > ipmi_unregister_smi(smi->intf);
> > 
> > -   opal_notifier_unregister(&smi->event_nb);
> > +   free_irq(smi->irq, smi);
> > +   irq_dispose_mapping(smi->irq);
> > +
> > 
> > return 0;
> >  
> >  }___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 2/9] powerpc/powernv: Add a virtual irqchip for opal events

2015-05-14 Thread Alistair Popple
Whenever an interrupt is received for opal the linux kernel gets a
bitfield indicating certain events that have occurred and need handling
by the various device drivers. Currently this is handled using a
notifier interface where we call every device driver that has
registered to receive opal events.

This approach has several drawbacks. For example each driver has to do
its own checking to see if the event is relevant as well as event
masking. There is also no easy method of recording the number of times
we receive particular events.

This patch solves these issues by exposing opal events via the
standard interrupt APIs by adding a new interrupt chip and
domain. Drivers can then register for the appropriate events using
standard kernel calls such as irq_of_parse_and_map().

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/opal.h   |   3 +
 arch/powerpc/platforms/powernv/Makefile   |   2 +-
 arch/powerpc/platforms/powernv/opal-irqchip.c | 253 ++
 arch/powerpc/platforms/powernv/opal.c |  78 ++--
 arch/powerpc/platforms/powernv/powernv.h  |   4 +
 5 files changed, 273 insertions(+), 67 deletions(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-irqchip.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 518a22e..520dfb2 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -242,6 +242,7 @@ extern void opal_msglog_init(void);
 extern int opal_async_comp_init(void);
 extern int opal_sensor_init(void);
 extern int opal_hmi_handler_init(void);
+extern int opal_event_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
 extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
@@ -253,6 +254,8 @@ extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
+extern int opal_event_request(unsigned int opal_event_nr);
+
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 unsigned long vmalloc_size);
 void opal_free_sg_list(struct opal_sg_list *sg);
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 33e44f3..f1d7de2 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
 obj-y  += setup.o opal-wrappers.o opal.o opal-async.o
 obj-y  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
-obj-y  += opal-msglog.o opal-hmi.o opal-power.o
+obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
new file mode 100644
index 000..bd5125d
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -0,0 +1,253 @@
+/*
+ * This file implements an irqchip for OPAL events. Whenever there is
+ * an interrupt that is handled by OPAL we get passed a list of events
+ * that Linux needs to do something about. These basically look like
+ * interrupts to Linux so we implement an irqchip to handle them.
+ *
+ * Copyright Alistair Popple, IBM Corporation 2014.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "powernv.h"
+
+/* Maximum number of events supported by OPAL firmware */
+#define MAX_NUM_EVENTS 64
+
+struct opal_event_irqchip {
+   struct irq_chip irqchip;
+   struct irq_domain *domain;
+   unsigned long mask;
+};
+static struct opal_event_irqchip opal_event_irqchip;
+
+static unsigned int opal_irq_count;
+static unsigned int *opal_irqs;
+
+static void opal_handle_irq_work(struct irq_work *work);
+static __be64 last_outstanding_events;
+static struct irq_work opal_event_irq_work = {
+   .func = opal_handle_irq_work,
+};
+
+static void opal_event_mask(struct irq_data *d)
+{
+   clear_bit(d->hwirq, &opal_event_irqchip.mask);
+}
+
+static void opal_event_unmask(struct irq_data *d)
+{
+   set_bit(d->hwirq, &opal_event_irqchip.mask);
+
+   opal_poll_events(&last_outstanding_events);
+   if (last_outstanding_events & opal_event_irqchip.mask)
+   /* Need to retrigger the interrupt */
+   irq_work_queue(&opal_event_irq_work);
+}
+
+static int opal_event_set_type(struct irq_data *d, unsigned int flow_type)
+{
+   /*
+* For

[PATCH v4 4/9] hvc: Convert to using interrupts instead of opal events

2015-05-14 Thread Alistair Popple
Convert the opal hvc driver to use the new irqchip to register for
opal events. As older firmware versions may not have device tree
bindings for the interrupt parent we just use a hardcoded hwirq based
on the event number.

Signed-off-by: Alistair Popple 
---
 drivers/tty/hvc/hvc_opal.c | 33 ++---
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 543b234..47b54c6 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -61,7 +62,6 @@ static struct hvc_opal_priv 
*hvc_opal_privs[MAX_NR_HVC_CONSOLES];
 /* For early boot console */
 static struct hvc_opal_priv hvc_opal_boot_priv;
 static u32 hvc_opal_boot_termno;
-static bool hvc_opal_event_registered;
 
 static const struct hv_ops hvc_opal_raw_ops = {
.get_chars = opal_get_chars,
@@ -162,28 +162,15 @@ static const struct hv_ops hvc_opal_hvsi_ops = {
.tiocmset = hvc_opal_hvsi_tiocmset,
 };
 
-static int hvc_opal_console_event(struct notifier_block *nb,
- unsigned long events, void *change)
-{
-   if (events & OPAL_EVENT_CONSOLE_INPUT)
-   hvc_kick();
-   return 0;
-}
-
-static struct notifier_block hvc_opal_console_nb = {
-   .notifier_call  = hvc_opal_console_event,
-};
-
 static int hvc_opal_probe(struct platform_device *dev)
 {
const struct hv_ops *ops;
struct hvc_struct *hp;
struct hvc_opal_priv *pv;
hv_protocol_t proto;
-   unsigned int termno, boot = 0;
+   unsigned int termno, irq, boot = 0;
const __be32 *reg;
 
-
if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
proto = HV_PROTOCOL_RAW;
ops = &hvc_opal_raw_ops;
@@ -227,18 +214,18 @@ static int hvc_opal_probe(struct platform_device *dev)
dev->dev.of_node->full_name,
boot ? " (boot console)" : "");
 
-   /* We don't do IRQ ... */
-   hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS);
+   irq = opal_event_request(ilog2(OPAL_EVENT_CONSOLE_INPUT));
+   if (!irq) {
+   pr_err("hvc_opal: Unable to map interrupt for device %s\n",
+   dev->dev.of_node->full_name);
+   return irq;
+   }
+
+   hp = hvc_alloc(termno, irq, ops, MAX_VIO_PUT_CHARS);
if (IS_ERR(hp))
return PTR_ERR(hp);
dev_set_drvdata(&dev->dev, hp);
 
-   /* ...  but we use OPAL event to kick the console */
-   if (!hvc_opal_event_registered) {
-   opal_notifier_register(&hvc_opal_console_nb);
-   hvc_opal_event_registered = true;
-   }
-
return 0;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 3/9] ipmi/powernv: Convert to irq event interface

2015-05-14 Thread Alistair Popple
Convert the opal ipmi driver to use the new irq interface for events.

Signed-off-by: Alistair Popple 
Acked-by: Corey Minyard 
Cc: Corey Minyard 
Cc: openipmi-develo...@lists.sourceforge.net
---
 drivers/char/ipmi/ipmi_powernv.c | 39 ++-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c
index 8753b0f..9b409c0 100644
--- a/drivers/char/ipmi/ipmi_powernv.c
+++ b/drivers/char/ipmi/ipmi_powernv.c
@@ -15,6 +15,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -23,8 +25,7 @@ struct ipmi_smi_powernv {
u64 interface_id;
struct ipmi_device_id   ipmi_id;
ipmi_smi_t  intf;
-   u64 event;
-   struct notifier_block   event_nb;
+   unsigned intirq;
 
/**
 * We assume that there can only be one outstanding request, so
@@ -197,15 +198,12 @@ static struct ipmi_smi_handlers ipmi_powernv_smi_handlers 
= {
.poll   = ipmi_powernv_poll,
 };
 
-static int ipmi_opal_event(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t ipmi_opal_event(int irq, void *data)
 {
-   struct ipmi_smi_powernv *smi = container_of(nb,
-   struct ipmi_smi_powernv, event_nb);
+   struct ipmi_smi_powernv *smi = data;
 
-   if (events & smi->event)
-   ipmi_powernv_recv(smi);
-   return 0;
+   ipmi_powernv_recv(smi);
+   return IRQ_HANDLED;
 }
 
 static int ipmi_powernv_probe(struct platform_device *pdev)
@@ -240,13 +238,16 @@ static int ipmi_powernv_probe(struct platform_device 
*pdev)
goto err_free;
}
 
-   ipmi->event = 1ull << prop;
-   ipmi->event_nb.notifier_call = ipmi_opal_event;
+   ipmi->irq = irq_of_parse_and_map(dev->of_node, 0);
+   if (!ipmi->irq) {
+   dev_info(dev, "Unable to map irq from device tree\n");
+   ipmi->irq = opal_event_request(prop);
+   }
 
-   rc = opal_notifier_register(&ipmi->event_nb);
-   if (rc) {
-   dev_warn(dev, "OPAL notifier registration failed (%d)\n", rc);
-   goto err_free;
+   if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH,
+   "opal-ipmi", ipmi)) {
+   dev_warn(dev, "Unable to request irq\n");
+   goto err_dispose;
}
 
ipmi->opal_msg = devm_kmalloc(dev,
@@ -271,7 +272,9 @@ static int ipmi_powernv_probe(struct platform_device *pdev)
 err_free_msg:
devm_kfree(dev, ipmi->opal_msg);
 err_unregister:
-   opal_notifier_unregister(&ipmi->event_nb);
+   free_irq(ipmi->irq, ipmi);
+err_dispose:
+   irq_dispose_mapping(ipmi->irq);
 err_free:
devm_kfree(dev, ipmi);
return rc;
@@ -282,7 +285,9 @@ static int ipmi_powernv_remove(struct platform_device *pdev)
struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev);
 
ipmi_unregister_smi(smi->intf);
-   opal_notifier_unregister(&smi->event_nb);
+   free_irq(smi->irq, smi);
+   irq_dispose_mapping(smi->irq);
+
return 0;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 0/9] Convert OPAL notifier events to an irqchip

2015-05-14 Thread Alistair Popple
Whenever an interrupt is received for opal the linux kernel gets a
bitfield indicating certain events that have occurred and need handling
by the various device drivers. Currently this is handled using a
notifier interface where we call every device driver that has
registered to receive opal events.

This approach has several drawbacks. For example each driver has to do
its own checking to see if the event is relevant as well as event
masking. There is also no easy method of recording the number of times
we receive particular events.

This series solves these issues by exposing opal events via the
standard interrupt APIs by adding a new interrupt chip and
domain. Drivers can then register for the appropriate events using
standard kernel calls such as irq_of_parse_and_map().

Patches 2-8 of this series are the same as for v3.

Changes from v3:
 - Changed initialisation sequence to solve the following errors on
   some machines:

   irq: XICS didn't like hwirq-0xb to VIRQ17 mapping (rc=-22)
   opal: opal_message_init: Can't register OPAL event irq (0)

 - Added a poller to the OPAL heartbeat to support machines where OPAL
   can't generate an interrupt for the host (eg. mambo)

Changes from v2:
 - Addressed comments by Neelesh Gupta
 - Fixed soft-lockup bug reported by Neelesh in the opal-dump driver
 - Rebased on v4.1-rc1

Alistair Popple (9):
  powerpc/powernv: Reorder OPAL subsystem initialisation
  powerpc/powernv: Add a virtual irqchip for opal events
  ipmi/powernv: Convert to irq event interface
  hvc: Convert to using interrupts instead of opal events
  powernv/eeh: Update the EEH code to use the opal irq domain
  powernv/opal: Convert opal message events to opal irq domain
  powernv/elog: Convert elog to opal irq domain
  powernv/opal-dump: Convert to irq domain
  opal: Remove events notifier

 arch/powerpc/include/asm/opal.h|   6 +
 arch/powerpc/platforms/powernv/Makefile|   2 +-
 arch/powerpc/platforms/powernv/eeh-powernv.c   |  58 ++---
 arch/powerpc/platforms/powernv/opal-async.c|   3 +-
 arch/powerpc/platforms/powernv/opal-dump.c |  56 ++---
 arch/powerpc/platforms/powernv/opal-elog.c |  32 +--
 arch/powerpc/platforms/powernv/opal-hmi.c  |   3 +-
 arch/powerpc/platforms/powernv/opal-irqchip.c  | 249 +
 .../powerpc/platforms/powernv/opal-memory-errors.c |   2 +-
 arch/powerpc/platforms/powernv/opal-sensor.c   |   3 +-
 arch/powerpc/platforms/powernv/opal.c  | 196 +++-
 arch/powerpc/platforms/powernv/powernv.h   |   3 +
 arch/powerpc/platforms/powernv/setup.c |   2 +-
 drivers/char/ipmi/ipmi_powernv.c   |  39 ++--
 drivers/tty/hvc/hvc_opal.c |  33 +--
 15 files changed, 396 insertions(+), 291 deletions(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-irqchip.c

--
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 1/9] powerpc/powernv: Reorder OPAL subsystem initialisation

2015-05-14 Thread Alistair Popple
Most of the OPAL subsystems are always compiled in for PowerNV and
many of them need to be initialised before or after other OPAL
subsystems. Rather than trying to control this ordering through
machine initcalls it is clearer and easier to control initialisation
order with explicit calls in opal_init.

Signed-off-by: Alistair Popple 
Cc: Mahesh Jagannath Salgaonkar 
---
 arch/powerpc/include/asm/opal.h |  3 +++
 arch/powerpc/platforms/powernv/opal-async.c |  3 +--
 arch/powerpc/platforms/powernv/opal-hmi.c   |  3 +--
 arch/powerpc/platforms/powernv/opal-memory-errors.c |  2 +-
 arch/powerpc/platforms/powernv/opal-sensor.c|  3 +--
 arch/powerpc/platforms/powernv/opal.c   | 13 -
 6 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 042af1a..518a22e 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -239,6 +239,9 @@ extern int opal_elog_init(void);
 extern void opal_platform_dump_init(void);
 extern void opal_sys_param_init(void);
 extern void opal_msglog_init(void);
+extern int opal_async_comp_init(void);
+extern int opal_sensor_init(void);
+extern int opal_hmi_handler_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
 extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
diff --git a/arch/powerpc/platforms/powernv/opal-async.c 
b/arch/powerpc/platforms/powernv/opal-async.c
index 693b6cd..bdc8c0c 100644
--- a/arch/powerpc/platforms/powernv/opal-async.c
+++ b/arch/powerpc/platforms/powernv/opal-async.c
@@ -151,7 +151,7 @@ static struct notifier_block opal_async_comp_nb = {
.priority   = 0,
 };
 
-static int __init opal_async_comp_init(void)
+int __init opal_async_comp_init(void)
 {
struct device_node *opal_node;
const __be32 *async;
@@ -205,4 +205,3 @@ out_opal_node:
 out:
return err;
 }
-machine_subsys_initcall(powernv, opal_async_comp_init);
diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c 
b/arch/powerpc/platforms/powernv/opal-hmi.c
index b322bfb..a8f49d3 100644
--- a/arch/powerpc/platforms/powernv/opal-hmi.c
+++ b/arch/powerpc/platforms/powernv/opal-hmi.c
@@ -170,7 +170,7 @@ static struct notifier_block opal_hmi_handler_nb = {
.priority   = 0,
 };
 
-static int __init opal_hmi_handler_init(void)
+int __init opal_hmi_handler_init(void)
 {
int ret;
 
@@ -186,4 +186,3 @@ static int __init opal_hmi_handler_init(void)
}
return 0;
 }
-machine_subsys_initcall(powernv, opal_hmi_handler_init);
diff --git a/arch/powerpc/platforms/powernv/opal-memory-errors.c 
b/arch/powerpc/platforms/powernv/opal-memory-errors.c
index 43db213..00a2943 100644
--- a/arch/powerpc/platforms/powernv/opal-memory-errors.c
+++ b/arch/powerpc/platforms/powernv/opal-memory-errors.c
@@ -144,4 +144,4 @@ static int __init opal_mem_err_init(void)
}
return 0;
 }
-machine_subsys_initcall(powernv, opal_mem_err_init);
+machine_device_initcall(powernv, opal_mem_err_init);
diff --git a/arch/powerpc/platforms/powernv/opal-sensor.c 
b/arch/powerpc/platforms/powernv/opal-sensor.c
index 6552504..a06059d 100644
--- a/arch/powerpc/platforms/powernv/opal-sensor.c
+++ b/arch/powerpc/platforms/powernv/opal-sensor.c
@@ -77,7 +77,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(opal_get_sensor_data);
 
-static __init int opal_sensor_init(void)
+int __init opal_sensor_init(void)
 {
struct platform_device *pdev;
struct device_node *sensor;
@@ -93,4 +93,3 @@ static __init int opal_sensor_init(void)
 
return PTR_ERR_OR_ZERO(pdev);
 }
-machine_subsys_initcall(powernv, opal_sensor_init);
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 2241565..eb3decc 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -393,7 +393,6 @@ static int __init opal_message_init(void)
}
return 0;
 }
-machine_early_initcall(powernv, opal_message_init);
 
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
@@ -807,6 +806,18 @@ static int __init opal_init(void)
of_node_put(consoles);
}
 
+   /* Initialise OPAL messaging system */
+   opal_message_init();
+
+   /* Initialise OPAL asynchronous completion interface */
+   opal_async_comp_init();
+
+   /* Initialise OPAL sensor interface */
+   opal_sensor_init();
+
+   /* Initialise OPAL hypervisor maintainence interrupt handling */
+   opal_hmi_handler_init();
+
/* Create i2c platform devices */
opal_i2c_create_devs();
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 5/9] powernv/eeh: Update the EEH code to use the opal irq domain

2015-05-14 Thread Alistair Popple
The eeh code currently uses the old notifier method to get eeh events
from OPAL. It also contains some logic to filter opal events which has
been moved into the virtual irqchip. This patch converts the eeh code
to the new event interface which simplifies event handling.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 58 +++-
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index ce738ab..ca825ec 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,7 @@
 #include "pci.h"
 
 static bool pnv_eeh_nb_init = false;
+static int eeh_event_irq = -EINVAL;
 
 /**
  * pnv_eeh_init - EEH platform dependent initialization
@@ -88,34 +90,22 @@ static int pnv_eeh_init(void)
return 0;
 }
 
-static int pnv_eeh_event(struct notifier_block *nb,
-unsigned long events, void *change)
+static irqreturn_t pnv_eeh_event(int irq, void *data)
 {
-   uint64_t changed_evts = (uint64_t)change;
-
/*
-* We simply send special EEH event if EEH has
-* been enabled, or clear pending events in
-* case that we enable EEH soon
+* We simply send a special EEH event if EEH has been
+* enabled. We don't care about EEH events until we've
+* finished processing the outstanding ones. Event processing
+* gets unmasked in next_error() if EEH is enabled.
 */
-   if (!(changed_evts & OPAL_EVENT_PCI_ERROR) ||
-   !(events & OPAL_EVENT_PCI_ERROR))
-   return 0;
+   disable_irq_nosync(irq);
 
if (eeh_enabled())
eeh_send_failure_event(NULL);
-   else
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
-   return 0;
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block pnv_eeh_nb = {
-   .notifier_call  = pnv_eeh_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 #ifdef CONFIG_DEBUG_FS
 static ssize_t pnv_eeh_ei_write(struct file *filp,
const char __user *user_buf,
@@ -237,16 +227,28 @@ static int pnv_eeh_post_init(void)
 
/* Register OPAL event notifier */
if (!pnv_eeh_nb_init) {
-   ret = opal_notifier_register(&pnv_eeh_nb);
-   if (ret) {
-   pr_warn("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, ret);
+   eeh_event_irq = opal_event_request(ilog2(OPAL_EVENT_PCI_ERROR));
+   if (eeh_event_irq < 0) {
+   pr_err("%s: Can't register OPAL event interrupt (%d)\n",
+  __func__, eeh_event_irq);
+   return eeh_event_irq;
+   }
+
+   ret = request_irq(eeh_event_irq, pnv_eeh_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-eeh", NULL);
+   if (ret < 0) {
+   irq_dispose_mapping(eeh_event_irq);
+   pr_err("%s: Can't request OPAL event interrupt (%d)\n",
+  __func__, eeh_event_irq);
return ret;
}
 
pnv_eeh_nb_init = true;
}
 
+   if (!eeh_enabled())
+   disable_irq(eeh_event_irq);
+
list_for_each_entry(hose, &hose_list, list_node) {
phb = hose->private_data;
 
@@ -1303,12 +1305,10 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
int state, ret = EEH_NEXT_ERR_NONE;
 
/*
-* While running here, it's safe to purge the event queue.
-* And we should keep the cached OPAL notifier event sychronized
-* between the kernel and firmware.
+* While running here, it's safe to purge the event queue. The
+* event should still be masked.
 */
eeh_remove_event(NULL, false);
-   opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
list_for_each_entry(hose, &hose_list, list_node) {
/*
@@ -1477,6 +1477,10 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
break;
}
 
+   /* Unmask the event */
+   if (eeh_enabled())
+   enable_irq(eeh_event_irq);
+
return ret;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 9/9] opal: Remove events notifier

2015-05-14 Thread Alistair Popple
All users of the old opal events notifier have been converted over to
the irq domain so remove the event notifier functions.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-irqchip.c | 16 ++---
 arch/powerpc/platforms/powernv/opal.c | 84 +--
 arch/powerpc/platforms/powernv/powernv.h  |  1 -
 arch/powerpc/platforms/powernv/setup.c|  2 +-
 4 files changed, 8 insertions(+), 95 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
index bd5125d..841135f 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -100,7 +100,6 @@ void opal_handle_events(uint64_t events)
 {
int virq, hwirq = 0;
u64 mask = opal_event_irqchip.mask;
-   u64 notifier_mask = 0;
 
if (!in_irq() && (events & mask)) {
last_outstanding_events = events;
@@ -108,19 +107,16 @@ void opal_handle_events(uint64_t events)
return;
}
 
-   while (events) {
+   while (events & mask) {
hwirq = fls64(events) - 1;
-   virq = irq_find_mapping(opal_event_irqchip.domain,
-   hwirq);
-   if (virq) {
-   if (BIT_ULL(hwirq) & mask)
+   if (BIT_ULL(hwirq) & mask) {
+   virq = irq_find_mapping(opal_event_irqchip.domain,
+   hwirq);
+   if (virq)
generic_handle_irq(virq);
-   } else
-   notifier_mask |= BIT_ULL(hwirq);
+   }
events &= ~BIT_ULL(hwirq);
}
-
-   opal_do_notifier(notifier_mask);
 }
 
 static irqreturn_t opal_interrupt(int irq, void *data)
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index cd5718b..8403307 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -53,11 +53,7 @@ static int mc_recoverable_range_len;
 
 struct device_node *opal_node;
 static DEFINE_SPINLOCK(opal_write_lock);
-static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
-static DEFINE_SPINLOCK(opal_notifier_lock);
-static uint64_t last_notified_mask = 0x0ul;
-static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 static uint32_t opal_heartbeat;
 
 static void opal_reinit_cores(void)
@@ -223,82 +219,6 @@ static int __init opal_register_exception_handlers(void)
 }
 machine_early_initcall(powernv, opal_register_exception_handlers);
 
-int opal_notifier_register(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_register(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_register);
-
-int opal_notifier_unregister(struct notifier_block *nb)
-{
-   if (!nb) {
-   pr_warning("%s: Invalid argument (%p)\n",
-  __func__, nb);
-   return -EINVAL;
-   }
-
-   atomic_notifier_chain_unregister(&opal_notifier_head, nb);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(opal_notifier_unregister);
-
-void opal_do_notifier(uint64_t events)
-{
-   unsigned long flags;
-   uint64_t changed_mask;
-
-   if (atomic_read(&opal_notifier_hold))
-   return;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   changed_mask = last_notified_mask ^ events;
-   last_notified_mask = events;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-
-   /*
-* We feed with the event bits and changed bits for
-* enough information to the callback.
-*/
-   atomic_notifier_call_chain(&opal_notifier_head,
-  events, (void *)changed_mask);
-}
-
-void opal_notifier_update_evt(uint64_t evt_mask,
- uint64_t evt_val)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(&opal_notifier_lock, flags);
-   last_notified_mask &= ~evt_mask;
-   last_notified_mask |= evt_val;
-   spin_unlock_irqrestore(&opal_notifier_lock, flags);
-}
-
-void opal_notifier_enable(void)
-{
-   int64_t rc;
-   __be64 evt = 0;
-
-   atomic_set(&opal_notifier_hold, 0);
-
-   /* Process pending events */
-   rc = opal_poll_events(&evt);
-   if (rc == OPAL_SUCCESS && evt)
-   opal_do_notifier(be64_to_cpu(evt));
-}
-
-void opal_notifier_disable(void)
-{
-   atomic_set(&opal_notifier_hold, 1);
-}
-
 /*
  * Opal message notifier based on message type. Allow subscribers to get
  * not

[PATCH v4 6/9] powernv/opal: Convert opal message events to opal irq domain

2015-05-14 Thread Alistair Popple
This patch converts the opal message event to use the new opal irq
domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 3baca71..cd5718b 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -362,33 +362,34 @@ static void opal_handle_message(void)
opal_message_do_notify(type, (void *)&msg);
 }
 
-static int opal_message_notify(struct notifier_block *nb,
- unsigned long events, void *change)
+static irqreturn_t opal_message_notify(int irq, void *data)
 {
-   if (events & OPAL_EVENT_MSG_PENDING)
-   opal_handle_message();
-   return 0;
+   opal_handle_message();
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block opal_message_nb = {
-   .notifier_call  = opal_message_notify,
-   .next   = NULL,
-   .priority   = 0,
-};
-
 static int __init opal_message_init(void)
 {
-   int ret, i;
+   int ret, i, irq;
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
 
-   ret = opal_notifier_register(&opal_message_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_MSG_PENDING));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   ret = request_irq(irq, opal_message_notify,
+   IRQ_TYPE_LEVEL_HIGH, "opal-msg", NULL);
if (ret) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
   __func__, ret);
return ret;
}
+
return 0;
 }
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 7/9] powernv/elog: Convert elog to opal irq domain

2015-05-14 Thread Alistair Popple
This patch converts the elog code to use the opal irq domain instead
of notifier events.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-elog.c | 32 +++---
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 38ce757..4949ef0 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -10,6 +10,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -276,24 +277,15 @@ static void elog_work_fn(struct work_struct *work)
 
 static DECLARE_WORK(elog_work, elog_work_fn);
 
-static int elog_event(struct notifier_block *nb,
-   unsigned long events, void *change)
+static irqreturn_t elog_event(int irq, void *data)
 {
-   /* check for error log event */
-   if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
-   schedule_work(&elog_work);
-   return 0;
+   schedule_work(&elog_work);
+   return IRQ_HANDLED;
 }
 
-static struct notifier_block elog_nb = {
-   .notifier_call  = elog_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 int __init opal_elog_init(void)
 {
-   int rc = 0;
+   int rc = 0, irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_ELOG_READ))
@@ -305,10 +297,18 @@ int __init opal_elog_init(void)
return -1;
}
 
-   rc = opal_notifier_register(&elog_nb);
+   irq = opal_event_request(ilog2(OPAL_EVENT_ERROR_LOG_AVAIL));
+   if (!irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, irq);
+   return irq;
+   }
+
+   rc = request_irq(irq, elog_event,
+   IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL);
if (rc) {
-   pr_err("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return rc;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v4 8/9] powernv/opal-dump: Convert to irq domain

2015-05-14 Thread Alistair Popple
Convert the opal dump driver to the new opal irq domain.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 56 +-
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 5aa9c1c..2ee9643 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -60,7 +61,7 @@ static ssize_t dump_type_show(struct dump_obj *dump_obj,
  struct dump_attribute *attr,
  char *buf)
 {
-   
+
return sprintf(buf, "0x%x %s\n", dump_obj->type,
   dump_type_to_string(dump_obj->type));
 }
@@ -363,7 +364,7 @@ static struct dump_obj *create_dump_obj(uint32_t id, size_t 
size,
return dump;
 }
 
-static int process_dump(void)
+static irqreturn_t process_dump(int irq, void *data)
 {
int rc;
uint32_t dump_id, dump_size, dump_type;
@@ -387,45 +388,13 @@ static int process_dump(void)
if (!dump)
return -1;
 
-   return 0;
-}
-
-static void dump_work_fn(struct work_struct *work)
-{
-   process_dump();
+   return IRQ_HANDLED;
 }
 
-static DECLARE_WORK(dump_work, dump_work_fn);
-
-static void schedule_process_dump(void)
-{
-   schedule_work(&dump_work);
-}
-
-/*
- * New dump available notification
- *
- * Once we get notification, we add sysfs entries for it.
- * We only fetch the dump on demand, and create sysfs asynchronously.
- */
-static int dump_event(struct notifier_block *nb,
- unsigned long events, void *change)
-{
-   if (events & OPAL_EVENT_DUMP_AVAIL)
-   schedule_process_dump();
-
-   return 0;
-}
-
-static struct notifier_block dump_nb = {
-   .notifier_call  = dump_event,
-   .next   = NULL,
-   .priority   = 0
-};
-
 void __init opal_platform_dump_init(void)
 {
int rc;
+   int dump_irq;
 
/* ELOG not supported by firmware */
if (!opal_check_token(OPAL_DUMP_READ))
@@ -445,10 +414,19 @@ void __init opal_platform_dump_init(void)
return;
}
 
-   rc = opal_notifier_register(&dump_nb);
+   dump_irq = opal_event_request(ilog2(OPAL_EVENT_DUMP_AVAIL));
+   if (!dump_irq) {
+   pr_err("%s: Can't register OPAL event irq (%d)\n",
+  __func__, dump_irq);
+   return;
+   }
+
+   rc = request_threaded_irq(dump_irq, NULL, process_dump,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+   "opal-dump", NULL);
if (rc) {
-   pr_warn("%s: Can't register OPAL event notifier (%d)\n",
-   __func__, rc);
+   pr_err("%s: Can't request OPAL event irq (%d)\n",
+  __func__, rc);
return;
}
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v4 4/9] hvc: Convert to using interrupts instead of opal events

2015-05-18 Thread Alistair Popple
On Tue, 19 May 2015 14:33:39 Michael Ellerman wrote:
> On Fri, 2015-05-15 at 14:06 +1000, Alistair Popple wrote:
> > Convert the opal hvc driver to use the new irqchip to register for
> > opal events. As older firmware versions may not have device tree
> > bindings for the interrupt parent we just use a hardcoded hwirq based
> > on the event number.
> 
> This is still breaking the mambo skiboot test for me.

As in you still can't get to userspace?

You probably need http://patchwork.ozlabs.org/patch/472202/ which fixes a bug 
in skiboot.

> Nothing obvious on the console
> 
> cheers

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] IBM Akebono: Remove obsolete config select

2014-09-04 Thread Alistair Popple
On Fri, 5 Sep 2014 00:20:42 Paul Bolle wrote:



> > On Fri, 13 Jun 2014 13:56:32 Paul Bolle wrote:
> > > On Fri, 2014-05-02 at 18:06 +1000, Alistair Popple wrote:
> > > > The original implementation of MMC support for Akebono introduced a
> > > > new configuration symbol (MMC_SDHCI_OF_476GTR). This symbol has been
> > > > dropped in favour of using the generic platform driver however the
> > > > select for this symbol was mistakenly left in the platform
> > > > configuration.
> > > > 
> > > > This patch removes the obsolete symbol selection.
> > > > 
> > > > Signed-off-by: Alistair Popple 
> > > 
> > > This patch hasn't yet entered linux-next nor Linus' tree. Is it queued
> > > somewhere? If not, would a
> > > 
> > > Acked-by: Paul Bolle 
> > > 
> > > help to get this trivial patch queued for either of those trees?
> > > 
> > > 
> > > Paul Bolle
> > > 
> > > > ---
> > > > 
> > > >  arch/powerpc/platforms/44x/Kconfig | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > > 
> > > > diff --git a/arch/powerpc/platforms/44x/Kconfig
> > > > b/arch/powerpc/platforms/44x/Kconfig index 8beec7d..908bf11 100644
> > > > --- a/arch/powerpc/platforms/44x/Kconfig
> > > > +++ b/arch/powerpc/platforms/44x/Kconfig
> > > > @@ -220,7 +220,6 @@ config AKEBONO
> > > > 
> > > > select USB_EHCI_HCD_PLATFORM
> > > > select MMC_SDHCI
> > > > select MMC_SDHCI_PLTFM
> > > > 
> > > > -   select MMC_SDHCI_OF_476GTR
> > > > 
> > > > select ATA
> > > > select SATA_AHCI_PLATFORM
> > > > help
> 
> This trivial cleanup is still not in linux-next nor in Linus' tree.
> Could someone else please have a look at it?
> 
> Thanks,
> 
> 
> Paul Bolle

Ben,

Any chance you could merge this? It's in patchwork (see 
http://patchwork.ozlabs.org/patch/344894/).

Regards,

Alistair

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Fix build failure

2014-09-15 Thread Alistair Popple
Thanks for fixing these!

Acked-by: Alistair Popple 

On Thu, 21 Aug 2014 09:04:31 Pranith Kumar wrote:
> Fix the following build failure
> 
> drivers/built-in.o: In function `nhi_init':
> nhi.c:(.init.text+0x63390): undefined reference to `ehci_init_driver'
> 
> by adding a dependency on USB_EHCI_HCD which supplies the
> ehci_init_driver().
> 
> Also we need to depend on USB_OHCI_HCD similarly
> 
> Signed-off-by: Pranith Kumar 
> ---
>  arch/powerpc/platforms/44x/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/44x/Kconfig
> b/arch/powerpc/platforms/44x/Kconfig index 4d88f6a..3e7deb2 100644
> --- a/arch/powerpc/platforms/44x/Kconfig
> +++ b/arch/powerpc/platforms/44x/Kconfig
> @@ -216,8 +216,8 @@ config AKEBONO
>   select IBM_EMAC_EMAC4
>   select IBM_EMAC_RGMII_WOL
>   select USB
> - select USB_OHCI_HCD_PLATFORM
> - select USB_EHCI_HCD_PLATFORM
> + select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
> + select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
>   select MMC_SDHCI
>   select MMC_SDHCI_PLTFM
>   select MMC_SDHCI_OF_476GTR

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Fix build failure when CONFIG_USB=y

2014-09-15 Thread Alistair Popple
Thanks for fixing these!

Acked-by: Alistair Popple 

On Thu, 21 Aug 2014 09:16:04 Pranith Kumar wrote:
> We are enabling USB unconditionally which results in following build failure
> 
> drivers/built-in.o: In function `tb_drom_read':
> (.text+0x1b62b70): undefined reference to `usb_speed_string'
> make: *** [vmlinux] Error
> 
> Enable USB only if USB_SUPPORT is set to avoid such failures
> 
> Signed-off-by: Pranith Kumar 
> ---
>  arch/powerpc/platforms/44x/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/platforms/44x/Kconfig
> b/arch/powerpc/platforms/44x/Kconfig index 3e7deb2..82f2da2 100644
> --- a/arch/powerpc/platforms/44x/Kconfig
> +++ b/arch/powerpc/platforms/44x/Kconfig
> @@ -215,7 +215,7 @@ config AKEBONO
>   select NET_VENDOR_IBM
>   select IBM_EMAC_EMAC4
>   select IBM_EMAC_RGMII_WOL
> - select USB
> + select USB if USB_SUPPORT
>   select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
>   select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
>   select MMC_SDHCI

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 0/2] Add IPMI support for powernv powerpc machines

2014-11-09 Thread Alistair Popple
Ben,

> 
> Our OPAL interface can only do one at a time ? Because our underlying FW
> driver already has a queue ..

The OPAL interface supports sending more than one message at a time using the 
underlying FW queue as you suggest. However in theory the interface doesn't 
make any response order guarantees, but in practice they should be ordered as 
our BMC doesn't send out-of-order responses.

Regards,

Alistair

> > > I'll look at doing that.  If that is the case, then your NULL check
> > > for current message should probably be a BUG_ON().
> > 
> > OK, I'll update this when the msghandler bit is implemented.
> > 
> > > Do you need to handle any BMC flags?  Particularly incoming events?
> > 
> > Not at this stage - we may in future though.
> > 
> > Cheers,
> > 
> > 
> > Jeremy
> > ___
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> ___
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc/powernv: Support OPAL requested heartbeat

2014-11-13 Thread Alistair Popple
Hi Ben,

On Wed, 12 Nov 2014 17:03:14 Benjamin Herrenschmidt wrote:



> +
> +static int kopald(void *unused)
> +{
> + set_freezable();
> + do {
> + try_to_freeze();
> + opal_poll_events(NULL);

Do we need to check for outstanding events (and call opal_do_notifier)? The 
Linux OPAL-IPMI interface signals an event which the interrupt handler 
(opal_interrupt) checks for, but if interrupts aren't functional no event will 
be signalled and hence the Linux IPMI layer won't get a response.

It's probably only an issue for lab bring up though as I would expect 
interrupts to generally be working...

> + msleep_interruptible(opal_heartbeat);
> + } while (!kthread_should_stop());
> +
> + return 0;
> +}
> +

Regards,

Alistair
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] [TRIVIAL] IBM Akebono: Remove select of IBM_EMAC_RGMII_WOL

2014-12-22 Thread Alistair Popple
Hi Paul,

These days I've been made maintainer of the PPC4XX tree so maybe adding Acked-
by: Alistair Popple  might help?

Jiri, if you would rather this go via the main PPC tree please let us know and 
we'll see if Michael Ellerman (added to CC) would be willing to take it (he 
has taken over most of the day to day maintenance of the PPC tree). Thanks!

Regards,

Alistair

On Mon, 22 Dec 2014 11:14:33 Paul Bolle wrote:
> Hi Jiri,
> 
> On Mon, 2014-11-03 at 10:52 +0100, Paul Bolle wrote:
> > Commit 2a2c74b2efcb ("IBM Akebono: Add the Akebono platform") added a
> > select of IBM_EMAC_RGMII_WOL. But that Kconfig symbol isn't (yet) part
> > of the tree. So this select has been a nop since that commit was
> > included in v3.16-rc1.
> > 
> > The code to add this symbol is not included in next-20141103. So let's
> > remove this select. It can be readded when that symbol is actually added
> > to the tree.
> > 
> > Signed-off-by: Paul Bolle 
> > Cc: Alistair Popple 
> > ---
> > Untested. Done on top of next-20141103.
> > 
> > Third time's a charm? First raised in
> > https://lkml.org/lkml/2014/5/1/106 . Reminder sent in
> > https://lkml.org/lkml/2014/9/4/645 . I'm not aware of any news on this
> > front, so this trivial patch seems reasonable now.
> > 
> > A patch to readd this select could be added - if people still care about
> > it, that is - in the series that adds this symbol. A web search suggests
> > Alistair takes care of that series, so Alistair gets a Cc: here.
> 
> This select of IBM_EMAC_RGMII_WOL still shows up in next-20141221 and
> v3.19-rc1. Did you have a chance to look at this patch?
> 
> >  arch/powerpc/platforms/44x/Kconfig | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/arch/powerpc/platforms/44x/Kconfig
> > b/arch/powerpc/platforms/44x/Kconfig index d2ac1c116454..5538e57c36c1
> > 100644
> > --- a/arch/powerpc/platforms/44x/Kconfig
> > +++ b/arch/powerpc/platforms/44x/Kconfig
> > @@ -214,7 +214,6 @@ config AKEBONO
> > 
> > select ETHERNET
> > select NET_VENDOR_IBM
> > select IBM_EMAC_EMAC4
> > 
> > -   select IBM_EMAC_RGMII_WOL
> > 
> > select USB if USB_SUPPORT
> > select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
> > select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
> 
> Thanks,
> 
> 
> Paul Bolle

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 0/2] powerpc: Early debug console configuration clean up

2013-04-28 Thread Alistair Popple
This patch series (based on v3.9) adds a configuration option to
enable the use of BootX or OpenFirmware console for early debug
console support.

Previously the use of BootX/OpenFirmware as an early debug console was
selected by CONFIG_BOOTX. However this left the ability to select a
different early debug console under the "Early debugging" menu which
was not supported by udbg.c. Instead the actual console selected when
both CONFIG_BOOTX and another early debug console is conifigured was
based on the arbitrary order of a series of #if/#elif's in udbg.c.

This patch replaces the previously sent "[PATCH] Make CONFIG_BOOTX an
exclusive early debug option".

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] powerpc: Add a configuration option for early BootX/OpenFirmware debug

2013-04-28 Thread Alistair Popple

Signed-off-by: Alistair Popple 
---
 arch/powerpc/Kconfig.debug |7 +++
 arch/powerpc/kernel/udbg.c |2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5416e28..e826853 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -147,6 +147,13 @@ choice
  enable debugging for the wrong type of machine your kernel
  _will not boot_.
 
+config PPC_EARLY_DEBUG_BOOTX
+   bool "BootX or OpenFirmware"
+   depends on BOOTX_TEXT
+   help
+ Select this to enable early debugging for a machine using BootX
+ or OpenFirmware.
+
 config PPC_EARLY_DEBUG_LPAR
bool "LPAR HV Console"
depends on PPC_PSERIES
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index f974849..9bbf07b 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -50,7 +50,7 @@ void __init udbg_early_init(void)
udbg_init_debug_beat();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE)
udbg_init_pas_realmode();
-#elif defined(CONFIG_BOOTX_TEXT)
+#elif defined(CONFIG_PPC_EARLY_DEBUG_BOOTX)
udbg_init_btext();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
/* PPC44x debug */
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2] powerpc: Update default configurations

2013-04-28 Thread Alistair Popple
Update default configurations for systems with CONFIG_BOOTX_TEXT
selected so that they continue to print early debug messages as is
currently the case.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/configs/c2k_defconfig|2 ++
 arch/powerpc/configs/g5_defconfig |2 ++
 arch/powerpc/configs/maple_defconfig  |2 ++
 arch/powerpc/configs/pmac32_defconfig |2 ++
 arch/powerpc/configs/ppc64_defconfig  |2 ++
 arch/powerpc/configs/ppc6xx_defconfig |2 ++
 6 files changed, 12 insertions(+)

diff --git a/arch/powerpc/configs/c2k_defconfig 
b/arch/powerpc/configs/c2k_defconfig
index 2a84fd7..671a8f9 100644
--- a/arch/powerpc/configs/c2k_defconfig
+++ b/arch/powerpc/configs/c2k_defconfig
@@ -423,6 +423,8 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
diff --git a/arch/powerpc/configs/g5_defconfig 
b/arch/powerpc/configs/g5_defconfig
index 07b7f2a..1ea22fc 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -284,6 +284,8 @@ CONFIG_DEBUG_MUTEXES=y
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_ECB=m
diff --git a/arch/powerpc/configs/maple_defconfig 
b/arch/powerpc/configs/maple_defconfig
index 02ac96b..2a5afac 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -138,6 +138,8 @@ CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/pmac32_defconfig 
b/arch/powerpc/configs/pmac32_defconfig
index 29767a8..a73626b 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -350,6 +350,8 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MD4=m
diff --git a/arch/powerpc/configs/ppc64_defconfig 
b/arch/powerpc/configs/ppc64_defconfig
index aef3f71..c86fcb9 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -398,6 +398,8 @@ CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
diff --git a/arch/powerpc/configs/ppc6xx_defconfig 
b/arch/powerpc/configs/ppc6xx_defconfig
index be1cb6e..20ebfaf 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -1264,6 +1264,8 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_XMON=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: Add an in memory udbg console

2013-04-28 Thread Alistair Popple
This patch adds a new udbg early debug console which utilises
statically defined input and output buffers stored within the kernel
BSS. It is primarily designed to assist with bring up of new hardware
which may not have a working console but which has a method of
reading/writing kernel memory.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/Kconfig.debug |   23 ++
 arch/powerpc/include/asm/udbg.h|1 +
 arch/powerpc/kernel/udbg.c |3 ++
 arch/powerpc/sysdev/Makefile   |2 +
 arch/powerpc/sysdev/udbg_memcons.c |   85 
 5 files changed, 114 insertions(+)
 create mode 100644 arch/powerpc/sysdev/udbg_memcons.c

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5416e28..863d877 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI
  Select this to enable early debugging for the PowerNV platform
  using an "hvsi" console
 
+config PPC_EARLY_DEBUG_MEMCONS
+   bool "In memory console"
+   help
+ Select this to enable early debugging using an in memory console.
+ This console provides input and output buffers stored within the
+ kernel BSS and should be safe to select on any system. A debugger
+ can then be used to read kernel output or send input to the console.
 endchoice
 
+config PPC_MEMCONS_OUTPUT_SIZE
+   int "In memory console output buffer size"
+   depends on PPC_EARLY_DEBUG_MEMCONS
+   default 4096
+   help
+ Selects the size of the output buffer (in bytes) of the in memory
+ console.
+
+config PPC_MEMCONS_INPUT_SIZE
+   int "In memory console input buffer size"
+   depends on PPC_EARLY_DEBUG_MEMCONS
+   default 128
+   help
+ Selects the size of the input buffer (in bytes) of the in memory
+ console.
+
 config PPC_EARLY_DEBUG_OPAL
def_bool y
depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 5a7510e..dc59091 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_memcons(void);
 extern void __init udbg_init_ehv_bc(void);
 extern void __init udbg_init_ps3gelic(void);
 extern void __init udbg_init_debug_opal_raw(void);
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index f974849..efa5c93 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -64,6 +64,9 @@ void __init udbg_early_init(void)
udbg_init_usbgecko();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
+   /* In memory console */
+   udbg_init_memcons();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
udbg_init_ehv_bc();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index b0a518e..99464a7 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -64,6 +64,8 @@ endif
 
 obj-$(CONFIG_PPC_SCOM) += scom.o
 
+obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS)  += udbg_memcons.o
+
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 obj-$(CONFIG_PPC_XICS) += xics/
diff --git a/arch/powerpc/sysdev/udbg_memcons.c 
b/arch/powerpc/sysdev/udbg_memcons.c
new file mode 100644
index 000..36f5c44
--- /dev/null
+++ b/arch/powerpc/sysdev/udbg_memcons.c
@@ -0,0 +1,85 @@
+/*
+ * A udbg backend which logs messages and reads input from in memory
+ * buffers.
+ *
+ * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
+ * Copyright (C) 2013 Alistair Popple, IBM Corp
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct memcons {
+   char *output_start;
+   char *output_pos;
+   char *output_end;
+   char *input_start;
+   char *input_pos;
+   char *input_end;
+};
+
+static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
+static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
+
+struct memcons memcons = {
+   .output_start = memcons_output,
+   .output_pos = memcons_output,
+   .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
+   .input_start = memcons_input,
+   .input_pos = memcons_input,
+   .input_end = &memcons_input[CONFIG_PPC_MEMC

[PATCH v2] powerpc: Add an in memory udbg console

2013-04-29 Thread Alistair Popple

This patch adds a new udbg early debug console which utilises
statically defined input and output buffers stored within the kernel
BSS. It is primarily designed to assist with bring up of new hardware
which may not have a working console but which has a method of
reading/writing kernel memory.

This version incorporates comments made by Ben H (thanks!).

Changes from v1:
- Add memory barriers.
- Ensure updating of read/write positions is atomic.

Signed-off-by: Alistair Popple 
---
arch/powerpc/Kconfig.debug |   23 
arch/powerpc/include/asm/udbg.h|1 +
arch/powerpc/kernel/udbg.c |3 ++
arch/powerpc/sysdev/Makefile   |2 +
arch/powerpc/sysdev/udbg_memcons.c |  105 
5 files changed, 134 insertions(+)
create mode 100644 arch/powerpc/sysdev/udbg_memcons.c

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5416e28..863d877 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI
  Select this to enable early debugging for the PowerNV platform
  using an "hvsi" console

+config PPC_EARLY_DEBUG_MEMCONS
+   bool "In memory console"
+   help
+ Select this to enable early debugging using an in memory console.
+ This console provides input and output buffers stored within the
+ kernel BSS and should be safe to select on any system. A debugger
+ can then be used to read kernel output or send input to the console.
endchoice

+config PPC_MEMCONS_OUTPUT_SIZE
+   int "In memory console output buffer size"
+   depends on PPC_EARLY_DEBUG_MEMCONS
+   default 4096
+   help
+ Selects the size of the output buffer (in bytes) of the in memory
+ console.
+
+config PPC_MEMCONS_INPUT_SIZE
+   int "In memory console input buffer size"
+   depends on PPC_EARLY_DEBUG_MEMCONS
+   default 128
+   help
+ Selects the size of the input buffer (in bytes) of the in memory
+ console.
+
config PPC_EARLY_DEBUG_OPAL
def_bool y
depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 5a7510e..dc59091 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void);
extern void __init udbg_init_cpm(void);
extern void __init udbg_init_usbgecko(void);
extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_memcons(void);
extern void __init udbg_init_ehv_bc(void);
extern void __init udbg_init_ps3gelic(void);
extern void __init udbg_init_debug_opal_raw(void);
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index f974849..efa5c93 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -64,6 +64,9 @@ void __init udbg_early_init(void)
udbg_init_usbgecko();
#elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
+   /* In memory console */
+   udbg_init_memcons();
#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
udbg_init_ehv_bc();
#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index b0a518e..99464a7 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -64,6 +64,8 @@ endif

obj-$(CONFIG_PPC_SCOM)  += scom.o

+obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS)  += udbg_memcons.o
+
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror

obj-$(CONFIG_PPC_XICS)  += xics/
diff --git a/arch/powerpc/sysdev/udbg_memcons.c 
b/arch/powerpc/sysdev/udbg_memcons.c
new file mode 100644
index 000..ce5a7b4
--- /dev/null
+++ b/arch/powerpc/sysdev/udbg_memcons.c
@@ -0,0 +1,105 @@
+/*
+ * A udbg backend which logs messages and reads input from in memory
+ * buffers.
+ *
+ * The console output can be read from memcons_output which is a
+ * circular buffer whose next write position is stored in memcons.output_pos.
+ *
+ * Input may be passed by writing into the memcons_input buffer when it is
+ * empty. The input buffer is empty when both input_pos == input_start and
+ * *input_start == '\0'.
+ *
+ * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
+ * Copyright (C) 2013 Alistair Popple, IBM Corp
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct memcons {
+   char *output_start;
+   char *output_pos;
+   char *output_end;
+   char *input_start;
+   char *inpu

[PATCH] powerpc: Update currituck pci/usb fixup for new board revision

2013-05-08 Thread Alistair Popple
The currituck board uses a different IRQ for the pci usb host
controller depending on the board revision. This patch adds support
for newer board revisions by retrieving the board revision from the
FPGA and mapping the appropriate IRQ.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/boot/dts/currituck.dts|5 
 arch/powerpc/platforms/44x/currituck.c |   39 ++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/currituck.dts 
b/arch/powerpc/boot/dts/currituck.dts
index b801dd0..cd3247e 100644
--- a/arch/powerpc/boot/dts/currituck.dts
+++ b/arch/powerpc/boot/dts/currituck.dts
@@ -103,6 +103,11 @@
interrupts = <34 2>;
};
 
+   FPGA0: fpga@5000 {
+   compatible = "ibm,currituck-fpga";
+   reg = <0x5000 0x1>;
+   };
+
IIC0: i2c@ {
compatible = "ibm,iic-currituck", "ibm,iic";
reg = <0x0 0x0014>;
diff --git a/arch/powerpc/platforms/44x/currituck.c 
b/arch/powerpc/platforms/44x/currituck.c
index ecd3890..c52e1b3 100644
--- a/arch/powerpc/platforms/44x/currituck.c
+++ b/arch/powerpc/platforms/44x/currituck.c
@@ -176,13 +176,48 @@ static int __init ppc47x_probe(void)
return 1;
 }
 
+static int board_rev = -1;
+static int __init ppc47x_get_board_rev(void)
+{
+   u8 fpga_reg0;
+   void *fpga;
+   struct device_node *np;
+
+   np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
+   if (!np)
+   goto fail;
+
+   fpga = of_iomap(np, 0);
+   of_node_put(np);
+   if (!fpga)
+   goto fail;
+
+   fpga_reg0 = ioread8(fpga);
+   board_rev = fpga_reg0 & 0x03;
+   pr_info("%s: Found board revision %d\n", __func__, board_rev);
+   iounmap(fpga);
+   return 0;
+
+fail:
+   pr_info("%s: Unable to find board revision\n", __func__);
+   return 0;
+}
+machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
+
 /* Use USB controller should have been hardware swizzled but it wasn't :( */
 static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
 {
if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
  dev->device == 0x00e0)) {
-   dev->irq = irq_create_mapping(NULL, 47);
-   pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq);
+   if (board_rev == 0) {
+   dev->irq = irq_create_mapping(NULL, 47);
+   pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+   } else if (board_rev == 2) {
+   dev->irq = irq_create_mapping(NULL, 49);
+   pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+   } else {
+   pr_alert("%s: Unknown board revision\n", __func__);
+   }
}
 }
 
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Update currituck pci/usb fixup for new board revision

2013-05-08 Thread Alistair Popple

The currituck board uses a different IRQ for the pci usb host
controller depending on the board revision. This patch adds support
for newer board revisions by retrieving the board revision from the
FPGA and mapping the appropriate IRQ.

Signed-off-by: Alistair Popple 
---

Sorry - I had forgotten to commit a minor fix to the device tree
changes in the last patch. Corrected patch below.

arch/powerpc/boot/dts/currituck.dts|5 
arch/powerpc/platforms/44x/currituck.c |   39 ++--
2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/currituck.dts 
b/arch/powerpc/boot/dts/currituck.dts
index b801dd0..d2c8a87 100644
--- a/arch/powerpc/boot/dts/currituck.dts
+++ b/arch/powerpc/boot/dts/currituck.dts
@@ -103,6 +103,11 @@
interrupts = <34 2>;
};

+   FPGA0: fpga@5000 {
+   compatible = "ibm,currituck-fpga";
+   reg = <0x5000 0x4>;
+   };
+
IIC0: i2c@ {
compatible = "ibm,iic-currituck", "ibm,iic";
reg = <0x0 0x0014>;
diff --git a/arch/powerpc/platforms/44x/currituck.c 
b/arch/powerpc/platforms/44x/currituck.c
index ecd3890..c52e1b3 100644
--- a/arch/powerpc/platforms/44x/currituck.c
+++ b/arch/powerpc/platforms/44x/currituck.c
@@ -176,13 +176,48 @@ static int __init ppc47x_probe(void)
return 1;
}

+static int board_rev = -1;
+static int __init ppc47x_get_board_rev(void)
+{
+   u8 fpga_reg0;
+   void *fpga;
+   struct device_node *np;
+
+   np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
+   if (!np)
+   goto fail;
+
+   fpga = of_iomap(np, 0);
+   of_node_put(np);
+   if (!fpga)
+   goto fail;
+
+   fpga_reg0 = ioread8(fpga);
+   board_rev = fpga_reg0 & 0x03;
+   pr_info("%s: Found board revision %d\n", __func__, board_rev);
+   iounmap(fpga);
+   return 0;
+
+fail:
+   pr_info("%s: Unable to find board revision\n", __func__);
+   return 0;
+}
+machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
+
/* Use USB controller should have been hardware swizzled but it wasn't :( */
static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
{
if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
  dev->device == 0x00e0)) {
-   dev->irq = irq_create_mapping(NULL, 47);
-   pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq);
+   if (board_rev == 0) {
+   dev->irq = irq_create_mapping(NULL, 47);
+   pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+   } else if (board_rev == 2) {
+   dev->irq = irq_create_mapping(NULL, 49);
+   pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+   } else {
+   pr_alert("%s: Unknown board revision\n", __func__);
+   }
}
}

--
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc/powernv: Bump opal_init initcall priority

2015-06-11 Thread Alistair Popple
opal_init() is called via a machine_subsys_initcall(). Due to a hack
in the eeh code the eeh driver is initialised with at the same
initcall level. This means depending on link ordering the following
error can occur because the opal irchip has not been initialised:

irq: XICS didn't like hwirq-0x9 to VIRQ17 mapping (rc=-22)
pnv_eeh_post_init: Can't request OPAL event interrupt (0)

This patch solves the issue by making sure opal_init is called prior
to the subsystems that may need it.

Signed-off-by: Alistair Popple 
Reported-by: Daniel Axtens 
---

Michael,

This fixes a problem in your next tree introduced by my opal irqchip
series. I encountered similar problems when moving some of the other
subsystems across to the new interface which was the motivation behind
the first patch in that series (powerpc/powernv: Reorder OPAL
subsystem initialisation). I missed this one due to a quirk in the
generic eeh code.

It seems that initcall dependencies are not well defined (or at least
my understanding of the dependencies isn't), so I'm not overly
comfortable with this fix. To be honest I don't have a clear
understanding of what side effects bumping this up a level might have
- it boots, everything seems to "work", and a quick grep reveals
nothing obvious. However I'm open to suggestions for a better fix...

In the meantime this should fix the problem in your branch until I get
a chance to dig further.

- Alistair

 arch/powerpc/platforms/powernv/opal.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 9e9c483..cc3ba5f 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -718,7 +718,7 @@ static int __init opal_init(void)

return 0;
 }
-machine_subsys_initcall(powernv, opal_init);
+machine_arch_initcall(powernv, opal_init);

 void opal_shutdown(void)
 {
--
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: powerpc/powernv: Bump opal_init initcall priority

2015-06-14 Thread Alistair Popple
On Fri, 12 Jun 2015 19:47:35 Michael Ellerman wrote:
> On Thu, 2015-11-06 at 09:25:29 UTC, Alistair Popple wrote:
> > opal_init() is called via a machine_subsys_initcall(). Due to a hack
> > in the eeh code the eeh driver is initialised with at the same
> > initcall level. This means depending on link ordering the following
> > error can occur because the opal irchip has not been initialised:
> > 
> > irq: XICS didn't like hwirq-0x9 to VIRQ17 mapping (rc=-22)
> > pnv_eeh_post_init: Can't request OPAL event interrupt (0)
> > 
> > This patch solves the issue by making sure opal_init is called prior
> > to the subsystems that may need it.
> 
> What is the hack in the eeh code?
> 
> I'm seeing eeh_ops->post_init() called from eeh_init() which is
> core_initcall_sync(), is that what you're talking about?

Yes, but there is this at the start of eeh_init():

/*
 * We have to delay the initialization on PowerNV after
 * the PCI hierarchy tree has been built because the PEs
 * are figured out based on PCI devices instead of device
 * tree nodes
 */
if (machine_is(powernv) && cnt++ <= 0)
return ret;

Which basically stops eeh_init() running from the core initcall level on 
PowerNV. Instead on PowerNV eeh_init() gets called from pnv_pci_ioda_fixup() 
which itself is called via the PCI layer from a subsys_initcall (ie. the same 
level as opal_init() is called at without this patch). This is why I missed 
this during my testing - apparently I got lucky during my compilations and 
opal_init() must have been called prior to the pci subsystem initialisation.

Ideally I'd like to change the way eeh_init() is called and make it an 
explicit call for each machine type, however that is a more invasive change 
which will take some time as there seem to be a bunch of subtle dependencies 
between initcalls for different platforms that aren't well documented and I'm 
not convinced I understand them all yet. Hence this "quick" fix.

> Then pnv_eeh_post_init() is the powernv version of eeh_ops->post_init, and 
it
> calls opal_event_request().
> 
> So you'd need the irq_chip setup by then I think?

Yeah, it needs to be setup prior to eeh_post_init() being called. 

> So I guess I'm missing the hack you're talking about.
> 
> Regardless of which level it needs to be at, the only thing that needs to 
run
> early is opal_event_init() am I right? Not all of opal_init().

Yes, that is correct. But I was trying to avoid doing the thing which seemed 
to have got us in this mess in the first place (ie. just making everything 
that needs to run "early" run from a core_initcall). However I guess just 
running opal_event_init() earlier is less likely to have unintended side 
effects than running all of opal_init() earlier. Let me know what you'd 
prefer.

Thanks.

- Alistair

> cheers
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc/powernv: Increase opal-irqchip initcall priority

2015-06-16 Thread Alistair Popple
The eeh subsystem for powernv requires the opal event irqchip to be
initialised prior to initialisation or the following errors are
produced (and eeh doesn't work as expected):

irq: XICS didn't like hwirq-0x9 to VIRQ17 mapping (rc=-22)
pnv_eeh_post_init: Can't request OPAL event interrupt (0)

On powernv eeh is initialised from a subsys_initcall due to a check
for machine_is(powernv) in eeh_init(). This patch increases the
initcall priority of opal_event_init() to an arch_initcall to ensure
the opal event interface is initialised prior to any users of it.

Signed-off-by: Alistair Popple 
Reported-by: Daniel Axtens 
---

Michael,

This supercedes my previous patch (powerpc/powernv: Bump opal_init
initcall priority).

Thanks.

 arch/powerpc/platforms/powernv/opal-irqchip.c | 4 
 arch/powerpc/platforms/powernv/opal.c | 3 ---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c 
b/arch/powerpc/platforms/powernv/opal-irqchip.c
index 841135f..e2e7d75 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -231,6 +231,7 @@ out:
of_node_put(opal_node);
return rc;
 }
+machine_arch_initcall(powernv, opal_event_init);

 /**
  * opal_event_request(unsigned int opal_event_nr) - Request an event
@@ -244,6 +245,9 @@ out:
  */
 int opal_event_request(unsigned int opal_event_nr)
 {
+   if (WARN_ON_ONCE(!opal_event_irqchip.domain))
+   return NO_IRQ;
+
return irq_create_mapping(opal_event_irqchip.domain, opal_event_nr);
 }
 EXPORT_SYMBOL(opal_event_request);
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 9e9c483..f084afa 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -657,9 +657,6 @@ static int __init opal_init(void)
return -ENODEV;
}

-   /* Initialise OPAL events */
-   opal_event_init();
-
/* Register OPAL consoles if any ports */
if (firmware_has_feature(FW_FEATURE_OPALv2))
consoles = of_find_node_by_path("/ibm,opal/consoles");
--
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] opal-elog: Fix opal-elog interrupt handler

2015-07-03 Thread Alistair Popple
The conversion of opal events to a proper irqchip means that handlers
are called until the relevant opal event has been cleared by
processing it. Events that queue work should therefore use a threaded
handler to mask the event until processing is complete.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/powernv/opal-elog.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 4949ef0..37f959b 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -237,7 +237,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t 
size, uint64_t type)
return elog;
 }
 
-static void elog_work_fn(struct work_struct *work)
+static irqreturn_t elog_event(int irq, void *data)
 {
__be64 size;
__be64 id;
@@ -251,7 +251,7 @@ static void elog_work_fn(struct work_struct *work)
rc = opal_get_elog_size(&id, &size, &type);
if (rc != OPAL_SUCCESS) {
pr_err("ELOG: OPAL log info read failed\n");
-   return;
+   return IRQ_HANDLED;
}
 
elog_size = be64_to_cpu(size);
@@ -270,16 +270,10 @@ static void elog_work_fn(struct work_struct *work)
 * entries.
 */
if (kset_find_obj(elog_kset, name))
-   return;
+   return IRQ_HANDLED;
 
create_elog_obj(log_id, elog_size, elog_type);
-}
-
-static DECLARE_WORK(elog_work, elog_work_fn);
 
-static irqreturn_t elog_event(int irq, void *data)
-{
-   schedule_work(&elog_work);
return IRQ_HANDLED;
 }
 
@@ -304,8 +298,8 @@ int __init opal_elog_init(void)
return irq;
}
 
-   rc = request_irq(irq, elog_event,
-   IRQ_TYPE_LEVEL_HIGH, "opal-elog", NULL);
+   rc = request_threaded_irq(irq, NULL, elog_event,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "opal-elog", NULL);
if (rc) {
pr_err("%s: Can't request OPAL event irq (%d)\n",
   __func__, rc);
-- 
2.1.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: eeh-powernv.c: Unbalanced IRQ warning

2015-07-27 Thread Alistair Popple
Hi Daniel,

I see the problem - pnv_eeh_next_error() re-enables the interrupt but it gets 
called from a loop if there are more outstanding events to process. The most 
obvious solution would be to do this check before enabling interrupts:

if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())

instead of:

if (eeh_enabled())
 
This should work fine so long as pnv_eeh_next_error() is called continuously 
until is returns either EEH_NEXT_ERR_NONE or another value which signals that 
pnv_eeh_next_error() should never be called again. As far as I can tell this 
looks to be true (perhaps Gavin can confirm?)

Would you mind trying the below patch and seeing if it fixes the problem? 
Thanks!

-- >8 --
From 6eeed1d6dd25e8cf6bfe3423dc50ff855d1cbc42 Mon Sep 17 00:00:00 2001
From: Alistair Popple 

---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index ca825ec..ff41c03 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1478,7 +1478,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
}
 
/* Unmask the event */
-   if (eeh_enabled())
+   if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())
enable_irq(eeh_event_irq);
 
return ret;
-- 
1.8.3.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: eeh-powernv.c: Unbalanced IRQ warning

2015-07-27 Thread Alistair Popple
On Tue, 28 Jul 2015 11:56:31 Daniel Axtens wrote:
> Hi Alistair and Gavin,
> 
> The patch from Alistair fixes my issue. Thanks heaps!
> 
> Alistair, are you right to post that formally?

Yep. I'll post it tomorrow morning.

> Regards,
> Daniel
> 
> On Tue, 2015-07-28 at 11:28 +1000, Gavin Shan wrote:
> > On Tue, Jul 28, 2015 at 11:14:51AM +1000, Alistair Popple wrote:
> > >Hi Daniel,
> > >
> > >I see the problem - pnv_eeh_next_error() re-enables the interrupt but it 
> > >gets 
> > >called from a loop if there are more outstanding events to process. The 
> > >most 
> > >obvious solution would be to do this check before enabling interrupts:
> > >
> > >if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())
> > >
> > >instead of:
> > >
> > >if (eeh_enabled())
> > >
> > >This should work fine so long as pnv_eeh_next_error() is called 
> > >continuously 
> > >until is returns either EEH_NEXT_ERR_NONE or another value which signals 
> > >that 
> > >pnv_eeh_next_error() should never be called again. As far as I can tell 
> > >this 
> > >looks to be true (perhaps Gavin can confirm?)
> > >
> > 
> > Yeah, I confirmed. The way that Alistair fixes the issue is simple and more
> > precise. Please try his fix and ignore the one I sent couple of minutes
> > before.
> > 
> > Thanks,
> > Gavin
> > 
> > >Would you mind trying the below patch and seeing if it fixes the problem? 
> > >Thanks!
> > >
> > >-- >8 --
> > >>From 6eeed1d6dd25e8cf6bfe3423dc50ff855d1cbc42 Mon Sep 17 00:00:00 2001
> > >From: Alistair Popple 
> > >
> > >---
> > > arch/powerpc/platforms/powernv/eeh-powernv.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > >diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
> > >b/arch/powerpc/platforms/powernv/eeh-powernv.c
> > >index ca825ec..ff41c03 100644
> > >--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
> > >+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
> > >@@ -1478,7 +1478,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
> > >   }
> > >
> > >   /* Unmask the event */
> > >-  if (eeh_enabled())
> > >+  if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())
> > >   enable_irq(eeh_event_irq);
> > >
> > >   return ret;
> > 
> 
> 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] ipmi/powernv: Fix potential invalid pointer dereference

2015-07-28 Thread Alistair Popple
Hi Neelesh,

This fix looks reasonable to me, although Jeremy would be the best person to 
comment if he has time. I wonder why we bother polling at all given that our 
event interface should call opal_ipmi_recv() whenever a message is ready?

Also the firmware fix you refer to and this fix are independent of each other 
so there's no ordering issues there.

Reviewed-By: Alistair Popple 

On Tue, 28 Jul 2015 13:20:07 Neelesh Gupta wrote:
> 
> On 07/17/2015 02:12 PM, Neelesh Gupta wrote:
> > Hi Corey,
> >
> > On 07/16/2015 08:31 PM, Corey Minyard wrote:
> >> Ok, this looks fine.  A couple of question...
> >>
> >> Do I need to send this upstream right now?  How well has this been 
tested?
> >
> > I would want either Jeremy or Alistair to review this patch before you 
> > send this
> > upstream. There is also firmware piece 
> > http://patchwork.ozlabs.org/patch/496645/
> > awaiting review.
> >
> > In the testing front, I manually made the opal_ipmi_recv() function to 
> > fail for testing
> > the error path and see if the driver recovers from it and subsequent 
> > ipmi commands
> > work all good.
> 
> Hi Jeremy/Alistair,
> 
> Could you please review it and the corresponding skiboot patch...
> 
> Thanks,
> Neelesh.
> 
> >
> >> Do you want this backported to 4.0 stable?
> >
> > Yes, I want this to be be backported to 4.0 stable.
> >
> > Thanks,
> > Neelesh.
> >
> >> -corey
> >>
> >> On 07/16/2015 06:16 AM, Neelesh Gupta wrote:
> >>> If the OPAL call to receive the ipmi message fails, then we free up the
> >>> smi message and return. But, the driver still holds the reference to
> >>> old smi message in the 'cur_msg' which can potentially be accessed later
> >>> and freed again leading to kernel oops. To fix it up,
> >>>
> >>> The kernel driver should reset the 'cur_msg' and send reply to the user
> >>> in addition to freeing the message.
> >>>
> >>> Signed-off-by: Neelesh Gupta
> >>> ---
> >>>   drivers/char/ipmi/ipmi_powernv.c |   13 ++---
> >>>   1 file changed, 10 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/drivers/char/ipmi/ipmi_powernv.c 
b/drivers/char/ipmi/ipmi_powernv.c
> >>> index 9b409c0..637486d 100644
> >>> --- a/drivers/char/ipmi/ipmi_powernv.c
> >>> +++ b/drivers/char/ipmi/ipmi_powernv.c
> >>> @@ -143,9 +143,16 @@ static int ipmi_powernv_recv(struct 
ipmi_smi_powernv *smi)
> >>>   pr_devel("%s:   -> %d (size %lld)\n", __func__,
> >>>   rc, rc == 0 ? size : 0);
> >>>   if (rc) {
> >>> - spin_unlock_irqrestore(&smi->msg_lock, flags);
> >>> - ipmi_free_smi_msg(msg);
> >>> - return 0;
> >>> + /* If came via the poll, and response was not yet ready */
> >>> + if (rc == OPAL_EMPTY) {
> >>> + spin_unlock_irqrestore(&smi->msg_lock, flags);
> >>> + return 0;
> >>> + } else {
> >>> + smi->cur_msg = NULL;
> >>> + spin_unlock_irqrestore(&smi->msg_lock, flags);
> >>> + send_error_reply(smi, msg, IPMI_ERR_UNSPECIFIED);
> >>> + return 0;
> >>> + }
> >>>   }
> >>>
> >>>   if (size < sizeof(*opal_msg)) {
> >>>
> >
> >
> >
> > ___
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc/eeh-powernv: Fix unbalanced IRQ warning

2015-07-29 Thread Alistair Popple
pnv_eeh_next_error() re-enables the eeh opal event interrupt but it
gets called from a loop if there are more outstanding events to
process, resulting in a warning due to enabling an already enabled
interrupt. Instead the interrupt should only be re-enabled once the
last outstanding event has been processed.

Tested-by: Daniel Axtens 
Reported-by: Daniel Axtens 
Signed-off-by: Alistair Popple 
Acked-by: Gavin Shan 
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index ca825ec..ff41c03 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1478,7 +1478,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
}
 
/* Unmask the event */
-   if (eeh_enabled())
+   if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())
enable_irq(eeh_event_irq);
 
return ret;
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 0/2] iommu: Support pages size other than 4K

2013-09-30 Thread Alistair Popple
This series of patches adds support for iommu page sizes other than
4K. Currently iommu page sizes are hardcoded to 4K. This series does
not actually change the page size but adds support for doing so.

It has been tested on a pSeries machine.

Alistair Popple (2):
  iommu: Add support for iommu page sizes other than 4K
  iommu: Update platform initialisation of iommu to use it_page_shift

 arch/powerpc/include/asm/iommu.h   |   28 --
 arch/powerpc/kernel/dma-iommu.c|4 +-
 arch/powerpc/kernel/iommu.c|   64 
 arch/powerpc/kernel/vio.c  |   20 +-
 arch/powerpc/platforms/cell/iommu.c|   14 ---
 arch/powerpc/platforms/powernv/pci.c   |3 +-
 arch/powerpc/platforms/pseries/iommu.c |   10 +++--
 arch/powerpc/platforms/pseries/setup.c |4 +-
 drivers/net/ethernet/ibm/ibmveth.c |9 +++--
 9 files changed, 85 insertions(+), 71 deletions(-)

-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] iommu: Add support for iommu page sizes other than 4K

2013-09-30 Thread Alistair Popple
Currently the iommu uses hardcoded pages sizes of 4K even though some
hardware supports other page sizes. This patch adds a field (it_page_shift)
to struct iommu_table to support different page sizes and updates the generic
iommu code to use that field.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h |   28 ++---
 arch/powerpc/kernel/dma-iommu.c  |4 +--
 arch/powerpc/kernel/iommu.c  |   64 +++---
 3 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index c34656a..e412a15 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -30,22 +30,19 @@
 #include 
 #include 
 
-#define IOMMU_PAGE_SHIFT  12
-#define IOMMU_PAGE_SIZE   (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
-#define IOMMU_PAGE_MASK   (~((1 << IOMMU_PAGE_SHIFT) - 1))
-#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
+#define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
+#define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
+#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
+
+#define IOMMU_PAGE_SHIFT_4K(12)
+#define IOMMU_PAGE_SIZE_4K (ASM_CONST(1) << 12)
+#define IOMMU_PAGE_MASK_4k (~((1 << 12) - 1))
+#define IOMMU_PAGE_ALIGN_4K(addr)  _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
 /* Boot time flags */
 extern int iommu_is_off;
 extern int iommu_force_on;
 
-/* Pure 2^n version of get_order */
-static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
-{
-   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
-}
-
-
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
@@ -76,11 +73,20 @@ struct iommu_table {
struct iommu_pool large_pool;
struct iommu_pool pools[IOMMU_NR_POOLS];
unsigned long *it_map;   /* A simple allocation bitmap for now */
+   unsigned long  it_page_shift;/* table iommu page size */
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
 };
 
+/* Pure 2^n version of get_order */
+static inline __attribute_const__
+int get_iommu_order(unsigned long size, struct iommu_table *tbl)
+{
+   return __ilog2((size - 1) >> tbl->it_page_shift) + 1;
+}
+
+
 struct scatterlist;
 
 static inline void set_iommu_table_base(struct device *dev, void *base)
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index e489752..54d0116 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,10 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 
mask)
return 0;
}
 
-   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) {
+   if (tbl->it_offset > (mask >> tbl->it_page_shift)) {
dev_info(dev, "Warning: IOMMU offset too big for device 
mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
-   mask, tbl->it_offset << IOMMU_PAGE_SHIFT);
+   mask, tbl->it_offset << tbl->it_page_shift);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index b20ff17..38f6e0c 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -251,14 +251,13 @@ again:
 
if (dev)
boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
- 1 << IOMMU_PAGE_SHIFT);
+ 1 << tbl->it_page_shift);
else
-   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT);
+   boundary_size = ALIGN(1UL << 32, 1 << tbl->it_page_shift);
/* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
 
-   n = iommu_area_alloc(tbl->it_map, limit, start, npages,
-tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT,
-align_mask);
+   n = iommu_area_alloc(tbl->it_map, limit, start, npages, tbl->it_offset,
+boundary_size >> tbl->it_page_shift, align_mask);
if (n == -1) {
if (likely(pass == 0)) {
/* First try the pool from the start */
@@ -320,12 +319,12 @@ static dma_addr_t iommu_alloc(struct device *dev, struct 
iommu_table *tbl,
return DMA_ERROR_CODE;
 
entry += tbl->it_offset;/* Offset into real TCE table */
-   ret = entry << IOMMU_PAGE_SHIFT;/* Set the return dma address */
+   ret = entry << tbl->it_page_shift;  /* Set the return dma address */
 
/* Put the T

[PATCH 2/2] iommu: Update platform initialisation of iommu to use it_page_shift

2013-09-30 Thread Alistair Popple
This patch initialises the iommu page size used for vio, cell, powernv
and pseries platforms to 4K.  It has been boot tested on a pseries
machine with vio.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/kernel/vio.c  |   20 +++-
 arch/powerpc/platforms/cell/iommu.c|   14 --
 arch/powerpc/platforms/powernv/pci.c   |3 ++-
 arch/powerpc/platforms/pseries/iommu.c |   10 ++
 arch/powerpc/platforms/pseries/setup.c |4 ++--
 drivers/net/ethernet/ibm/ibmveth.c |9 +
 6 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 536016d..1dbab4e 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -520,14 +520,14 @@ static dma_addr_t vio_dma_iommu_map_page(struct device 
*dev, struct page *page,
struct vio_dev *viodev = to_vio_dev(dev);
dma_addr_t ret = DMA_ERROR_CODE;
 
-   if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE))) {
+   if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K))) {
atomic_inc(&viodev->cmo.allocs_failed);
return ret;
}
 
ret = dma_iommu_ops.map_page(dev, page, offset, size, direction, attrs);
if (unlikely(dma_mapping_error(dev, ret))) {
-   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
+   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K));
atomic_inc(&viodev->cmo.allocs_failed);
}
 
@@ -543,7 +543,7 @@ static void vio_dma_iommu_unmap_page(struct device *dev, 
dma_addr_t dma_handle,
 
dma_iommu_ops.unmap_page(dev, dma_handle, size, direction, attrs);
 
-   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE));
+   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K));
 }
 
 static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
@@ -556,7 +556,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct 
scatterlist *sglist,
size_t alloc_size = 0;
 
for (sgl = sglist; count < nelems; count++, sgl++)
-   alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE);
+   alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE_4K);
 
if (vio_cmo_alloc(viodev, alloc_size)) {
atomic_inc(&viodev->cmo.allocs_failed);
@@ -572,7 +572,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct 
scatterlist *sglist,
}
 
for (sgl = sglist, count = 0; count < ret; count++, sgl++)
-   alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE);
+   alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE_4K);
if (alloc_size)
vio_cmo_dealloc(viodev, alloc_size);
 
@@ -590,7 +590,7 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
int count = 0;
 
for (sgl = sglist; count < nelems; count++, sgl++)
-   alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE);
+   alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE_4K);
 
dma_iommu_ops.unmap_sg(dev, sglist, nelems, direction, attrs);
 
@@ -736,7 +736,8 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev)
return -EINVAL;
}
 
-   viodev->cmo.desired = 
IOMMU_PAGE_ALIGN(viodrv->get_desired_dma(viodev));
+   viodev->cmo.desired =
+   IOMMU_PAGE_ALIGN_4K(viodrv->get_desired_dma(viodev));
if (viodev->cmo.desired < VIO_CMO_MIN_ENT)
viodev->cmo.desired = VIO_CMO_MIN_ENT;
size = VIO_CMO_MIN_ENT;
@@ -1170,9 +1171,10 @@ static struct iommu_table *vio_build_iommu_table(struct 
vio_dev *dev)
&tbl->it_index, &offset, &size);
 
/* TCE table size - measured in tce entries */
-   tbl->it_size = size >> IOMMU_PAGE_SHIFT;
+   tbl->it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   tbl->it_size = size >> tbl->it_page_shift;
/* offset for VIO should always be 0 */
-   tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
+   tbl->it_offset = offset >> tbl->it_page_shift;
tbl->it_busno = 0;
tbl->it_type = TCE_VB;
tbl->it_blocksize = 16;
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index 946306b..c0bb88a 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -197,7 +197,7 @@ static int tce_build_cell(struct iommu_table *tbl, long 
index, long npages,
 
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
-   for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
+   for (i = 0; i < npages; i++, uaddr += tbl->it_page_shift)
io_pte[i] = base_pte | (__pa(uaddr) &a

Re: [PATCH 2/2] iommu: Update platform initialisation of iommu to use it_page_shift

2013-10-01 Thread Alistair Popple
On Tue, 1 Oct 2013 14:12:29 Michael Ellerman wrote:
> On Tue, Oct 01, 2013 at 01:54:10PM +1000, Alistair Popple wrote:
> > This patch initialises the iommu page size used for vio, cell, powernv
> > and pseries platforms to 4K.  It has been boot tested on a pseries
> > machine with vio.
> 
> This patch fixes the build errors introduced by the previous patch
> right?
> 
> In which case you need to rework it so that you introduce the new
> constants, use them everywhere, before removing the old constants. ie.
> the build should never break.

Thanks, I'll rework and resubmit.

Alistair

> cheers
> ___
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: Fix 64K page size support for PPC44x

2013-10-16 Thread Alistair Popple
PPC44x supports page sizes other than 4K however when 64K page sizes
are selected compilation fails. This is due to a change in the
definition of pgtable_t introduced by the following patch:

commit 5c1f6ee9a31cbdac90bbb8ae1ba4475031ac74b4
Author: Aneesh Kumar K.V 
powerpc: Reduce PTE table memory wastage

The above patch only implements the new layout for PPC64 so it doesn't
compile for PPC32 with a 64K page size. Ideally we should implement
the same layout for PPC32 however for the meantime this patch reverts
the definition of pgtable_t for PPC32.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/page.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index b9f4262..b142d58 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -403,7 +403,7 @@ void arch_free_page(struct page *page, int order);
 
 struct vm_area_struct;
 
-#ifdef CONFIG_PPC_64K_PAGES
+#if defined(CONFIG_PPC_64K_PAGES) && defined(PPC64)
 typedef pte_t *pgtable_t;
 #else
 typedef struct page *pgtable_t;
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Fix 64K page size support for PPC44x

2013-10-16 Thread Alistair Popple
On Thu, 17 Oct 2013 10:55:25 Aneesh Kumar K.V wrote:
> Alistair Popple  writes:

> > diff --git a/arch/powerpc/include/asm/page.h
> > b/arch/powerpc/include/asm/page.h index b9f4262..b142d58 100644
> > --- a/arch/powerpc/include/asm/page.h
> > +++ b/arch/powerpc/include/asm/page.h
> > @@ -403,7 +403,7 @@ void arch_free_page(struct page *page, int order);
> > 
> >  struct vm_area_struct;
> > 
> > -#ifdef CONFIG_PPC_64K_PAGES
> > +#if defined(CONFIG_PPC_64K_PAGES) && defined(PPC64)
> 
>^^^ CONFIG_PPC64 ?

Yes, of course it should be. Thanks for picking that up - I'll send an updated 
patch.

> >  typedef pte_t *pgtable_t;
> >  #else
> >  typedef struct page *pgtable_t;
> 
> ___
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V2] powerpc: Fix 64K page size support for PPC44x

2013-10-16 Thread Alistair Popple
PPC44x supports page sizes other than 4K however when 64K page sizes
are selected compilation fails. This is due to a change in the
definition of pgtable_t introduced by the following patch:

commit 5c1f6ee9a31cbdac90bbb8ae1ba4475031ac74b4
Author: Aneesh Kumar K.V 
powerpc: Reduce PTE table memory wastage

The above patch only implements the new layout for PPC64 so it doesn't
compile for PPC32 with a 64K page size. Ideally we should implement
the same layout for PPC32 however for the meantime this patch reverts
the definition of pgtable_t for PPC32.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/page.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index b9f4262..7dde512 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -403,7 +403,7 @@ void arch_free_page(struct page *page, int order);
 
 struct vm_area_struct;
 
-#ifdef CONFIG_PPC_64K_PAGES
+#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64)
 typedef pte_t *pgtable_t;
 #else
 typedef struct page *pgtable_t;
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/7] IBM Akebono: Add support to AHCI platform driver

2013-11-04 Thread Alistair Popple
The new IBM Akebono board has an AHCI compliant SATA controller. This
patch adds a compatible property for the new board to the AHCI
platform driver.

Signed-off-by: Alistair Popple 
Cc: linux-...@vger.kernel.org
---
 drivers/ata/ahci_platform.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 7d3b853..b20b130 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -328,6 +328,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, 
ahci_resume);
 static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,spear-ahci", },
{ .compatible = "snps,exynos5440-ahci", },
+   { .compatible = "ibm,akebono-ahci", },
{},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/7] IBM Akebono: Add a SDHCI platform driver

2013-11-04 Thread Alistair Popple
This patch adds a SDHCI platform driver for the new IBM Akebono board.

Signed-off-by: Alistair Popple 
Cc: Chris Ball 
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/host/Kconfig|   12 +++
 drivers/mmc/host/Makefile   |1 +
 drivers/mmc/host/sdhci-of-akebono.c |   60 +++
 3 files changed, 73 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-of-akebono.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7fc5099..d7a1414 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,18 @@ config MMC_SDHCI_OF_HLWD
 
  If unsure, say N.
 
+config MMC_SDHCI_OF_AKEBONO
+   tristate "SDHCI OF support for the IBM Akebono board"
+   depends on MMC_SDHCI_PLTFM
+   depends on PPC_OF
+   help
+ This selects the Secure Digital Host Controller Interface (SDHCI)
+ found on the Akebono 476FP SoC.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
 config MMC_SDHCI_CNS3XXX
tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
depends on ARCH_CNS3XXX
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c41d0c3..ea7e757 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)  += sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)  += sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)   += sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_OF_AKEBONO) += sdhci-of-akebono.o
 obj-$(CONFIG_MMC_SDHCI_BCM_KONA)   += sdhci-bcm-kona.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)+= sdhci-bcm2835.o
 
diff --git a/drivers/mmc/host/sdhci-of-akebono.c 
b/drivers/mmc/host/sdhci-of-akebono.c
new file mode 100644
index 000..20041c1
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-akebono.c
@@ -0,0 +1,60 @@
+/*
+ * drivers/mmc/host/sdhci-of-akebono.c
+ *
+ * Copyright © 2013 Alistair Popple  IBM Corporation
+ *
+ * Based on sdhci-of-hlwd.c
+ *
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include "sdhci-pltfm.h"
+
+static const struct sdhci_ops sdhci_akebono_ops = {
+};
+
+static const struct sdhci_pltfm_data sdhci_akebono_pdata = {
+   .ops = &sdhci_akebono_ops,
+};
+
+static int sdhci_akebono_probe(struct platform_device *pdev)
+{
+   return sdhci_pltfm_register(pdev, &sdhci_akebono_pdata, 0);
+}
+
+static int sdhci_akebono_remove(struct platform_device *pdev)
+{
+   return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_akebono_of_match[] = {
+   { .compatible = "ibm,akebono-sdhci" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_akebono_of_match);
+
+static struct platform_driver sdhci_akebono_driver = {
+   .driver = {
+   .name = "sdhci-akebono",
+   .owner = THIS_MODULE,
+   .of_match_table = sdhci_akebono_of_match,
+   .pm = SDHCI_PLTFM_PMOPS,
+   },
+   .probe = sdhci_akebono_probe,
+   .remove = sdhci_akebono_remove,
+};
+
+module_platform_driver(sdhci_akebono_driver);
+
+MODULE_DESCRIPTION("Akebono SDHCI OF driver");
+MODULE_AUTHOR("Alistair Popple");
+MODULE_LICENSE("GPL v2");
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/7] IBM Akebono: Add support for a new PHY to the IBM emac driver

2013-11-04 Thread Alistair Popple
The IBM Akebono board uses a different ethernet PHY that has wake on
lan (WOL) support with the IBM emac. This patch adds suppot to the IBM
emac driver for this new PHY.

At this stage the wake on lan functionality has not been implemented.

Signed-off-by: Alistair Popple 
Cc: "David S. Miller" 
Cc: net...@vger.kernel.org
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   |9 +
 drivers/net/ethernet/ibm/emac/Kconfig  |4 +
 drivers/net/ethernet/ibm/emac/Makefile |1 +
 drivers/net/ethernet/ibm/emac/core.c   |   50 +++-
 drivers/net/ethernet/ibm/emac/core.h   |   12 +
 drivers/net/ethernet/ibm/emac/rgmii_wol.c  |  262 
 drivers/net/ethernet/ibm/emac/rgmii_wol.h  |   62 +
 7 files changed, 394 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6..9928d9d 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -61,6 +61,8 @@
  Fox Axon: present, whatever value is appropriate for 
each
  EMAC, that is the content of the current (bogus) 
"phy-port"
  property.
+- rgmii-wol-device  : 1 cell, required iff conntect to a RGMII in the WKUP
+  power domain. phandle of the RGMII-WOL device node.
 
 Optional properties:
 - phy-address   : 1 cell, optional, MDIO address of the PHY. If absent,
@@ -146,3 +148,10 @@
   available.
   For Axon: 0x012a
 
+  iv) RGMII-WOL node
+
+Required properties:
+- compatible : compatible list, containing 2 entries, first is
+  "ibm,rgmii-wol-CHIP" where CHIP is the host ASIC 
(like
+  EMAC) and the second is "ibm,rgmii-wol".
+- reg: 
diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30..7425c27 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -55,6 +55,10 @@ config IBM_EMAC_RGMII
bool
default n
 
+config IBM_EMAC_RGMII_WOL
+   bool
+   default n
+
 config IBM_EMAC_TAH
bool
default n
diff --git a/drivers/net/ethernet/ibm/emac/Makefile 
b/drivers/net/ethernet/ibm/emac/Makefile
index eba2183..8843803 100644
--- a/drivers/net/ethernet/ibm/emac/Makefile
+++ b/drivers/net/ethernet/ibm/emac/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
 ibm_emac-y := mal.o core.o phy.o
 ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
 ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII_WOL) += rgmii_wol.o
 ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
 ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 6b5c722..fc1a775 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -630,6 +630,8 @@ static int emac_configure(struct emac_instance *dev)
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_set_speed(dev->rgmii_dev, dev->rgmii_port,
dev->phy.speed);
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_set_speed(dev->rgmii_wol_dev, dev->phy.speed);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
zmii_set_speed(dev->zmii_dev, dev->zmii_port, dev->phy.speed);
 
@@ -797,6 +799,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 
id, u8 reg)
zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_get_mdio(dev->rgmii_wol_dev);
 
/* Wait for management interface to become idle */
n = 20;
@@ -844,6 +848,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 
id, u8 reg)
DBG2(dev, "mdio_read -> %04x" NL, r);
err = 0;
  bail:
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_put_mdio(dev->rgmii_wol_dev);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -869,6 +875,8 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 
id, u8 reg,
zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
if (emac_has_fe

[PATCH 4/7] IBM Akebono: Add support to the OHCI platform driver for Akebono

2013-11-04 Thread Alistair Popple
The IBM Akebono board has a OHCI compliant USB host interface. This
patch adds support for it to the OHCI platform driver.

As we use device tree to pass platform specific data instead of
platform data we remove the check for platform data and instead
provide reasonable defaults if no platform data is present. This is
similar to what is currently done in ehci-platform.c.

Signed-off-by: Alistair Popple 
Cc: Alan Stern 
Cc: linux-...@vger.kernel.org
---
 drivers/usb/host/ohci-platform.c |   20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index a4c6410..4331454 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "ohci.h"
 
@@ -55,6 +57,8 @@ static const struct ohci_driver_overrides platform_overrides 
__initconst = {
.reset =ohci_platform_reset,
 };
 
+static struct usb_ohci_pdata ohci_platform_defaults;
+
 static int ohci_platform_probe(struct platform_device *dev)
 {
struct usb_hcd *hcd;
@@ -63,14 +67,14 @@ static int ohci_platform_probe(struct platform_device *dev)
int irq;
int err = -ENOMEM;
 
-   if (!pdata) {
-   WARN_ON(1);
-   return -ENODEV;
-   }
-
if (usb_disabled())
return -ENODEV;
 
+   /* Platforms using DT don't always provide platform data.
+* This should provide reasonable defaults. */
+   if (!pdata)
+   dev->dev.platform_data = pdata = &ohci_platform_defaults;
+
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
@@ -171,6 +175,11 @@ static int ohci_platform_resume(struct device *dev)
 #define ohci_platform_resume   NULL
 #endif /* CONFIG_PM */
 
+static const struct of_device_id ohci_of_match[] = {
+   { .compatible = "ibm,akebono-ohci", },
+   {},
+};
+
 static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -191,6 +200,7 @@ static struct platform_driver ohci_platform_driver = {
.owner  = THIS_MODULE,
.name   = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+   .of_match_table = ohci_of_match,
}
 };
 
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 5/7] IBM Akebono: Add support to the EHCI platform driver for Akebono

2013-11-04 Thread Alistair Popple
The IBM Akebono board has an EHCI compliant USB host interface. This
patch adds support for it to the EHCI platform driver.

Signed-off-by: Alistair Popple 
Cc: Alan Stern 
Cc: linux-...@vger.kernel.org
---
 drivers/usb/host/ehci-platform.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index f6b790c..0a67616 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -203,9 +203,10 @@ static int ehci_platform_resume(struct device *dev)
 #define ehci_platform_resume   NULL
 #endif /* CONFIG_PM */
 
-static const struct of_device_id vt8500_ehci_ids[] = {
+static const struct of_device_id ehci_platform_ids[] = {
{ .compatible = "via,vt8500-ehci", },
{ .compatible = "wm,prizm-ehci", },
+   { .compatible = "ibm,akebono-ehci", },
{}
 };
 
@@ -229,7 +230,7 @@ static struct platform_driver ehci_platform_driver = {
.owner  = THIS_MODULE,
.name   = "ehci-platform",
.pm = &ehci_platform_pm_ops,
-   .of_match_table = vt8500_ehci_ids,
+   .of_match_table = ehci_platform_ids,
}
 };
 
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 7/7] IBM Akebono: Add the Akebono platform

2013-11-04 Thread Alistair Popple
This patch adds support for the IBM Akebono board.

Signed-off-by: Alistair Popple 
---
 .../devicetree/bindings/powerpc/4xx/akebono.txt|   76 
 arch/powerpc/boot/Makefile |3 +
 arch/powerpc/boot/dcr.h|2 +
 arch/powerpc/boot/dts/akebono.dts  |  385 
 arch/powerpc/boot/treeboot-akebono.c   |  179 +
 arch/powerpc/boot/wrapper  |3 +
 arch/powerpc/configs/44x/akebono_defconfig |  148 
 arch/powerpc/platforms/44x/Kconfig |   28 ++
 arch/powerpc/platforms/44x/Makefile|1 +
 arch/powerpc/platforms/44x/ppc476fpe.c |  112 --
 10 files changed, 914 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
 create mode 100644 arch/powerpc/boot/dts/akebono.dts
 create mode 100644 arch/powerpc/boot/treeboot-akebono.c
 create mode 100644 arch/powerpc/configs/44x/akebono_defconfig

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
new file mode 100644
index 000..cb5272d
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
@@ -0,0 +1,76 @@
+
+IBM Akebono board device tree
+=
+
+The IBM Akebono board is a development board for a 476FPE bases SoC.
+
+0) The root node
+
+   Required properties:
+
+   - model : "ibm,akebono".
+   - compatible : "ibm,akebono" , "ibm,476fpe".
+
+1.a) The Open Host Controller Interface (OHCI) nodes
+
+  Represent the USB 1.x Open Host Controller Interfaces.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-ohci".
+   - reg : should contain the OHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the OHCI interrupt.
+
+1.b) The Open Host Controller Interface (EHCI) nodes
+
+  Represent the USB 2.0 Enhanced Host Controller Interface.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-ehci".
+   - reg : should contain the EHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the EHCI interrupt.
+
+1.c) The Secure Digital Host Controller Interface (SDHCI) node
+
+  Represent the Secure Digital Host Controller Interfaces.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-sdhci","sdhci".
+   - reg : should contain the SDHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the SDHCI interrupt.
+
+1.d) The Advanced Host Controller Interface (AHCI) SATA node
+
+  Represents the advanced host controller SATA interface.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-ahci".
+   - reg : should contain the AHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the AHCI interrupt.
+
+1.e) The FPGA node
+
+  The Akebono board stores some board information such as the revision
+  number in an FPGA which is represented by this node.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-fpga".
+   - reg : should contain the FPGA registers location and length.
+
+1.f) The AVR node
+
+  The Akebono board has an Atmel AVR microprocessor attached to the I2C
+  bus as a power controller for the board.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-avr".
+   - reg : should contain the I2C bus address for the AVR.
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 15ca225..645ff21 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -46,6 +46,7 @@ $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405
+$(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405
 $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
 
 
@@ -85,6 +86,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c 
treeboot-bamboo.c \
cuboot-taishan.c cuboot-katmai.c \
cuboot-warp.c cuboot-yosemite.c \
treeboot-iss4xx.c treeboot-currituck.c \
+   treeboot-akebono.c \
simpleboot.c fixed-head.S virtex.c
 src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
 src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c
@@ -235,6 +237,7 @@ image-$(CONFIG_YOSEMITE)+= cuImage.yosemite
 image-$(CONFIG_ISS4xx) += treeImage

[PATCH 6/7] IBM Currituck: Clean up board specific code before adding Akebono code

2013-11-04 Thread Alistair Popple
The IBM Akebono code uses the same initialisation functions as the
earlier Currituck board. Rather than create a copy of this code for
Akebono we will instead integrate support for it into the same file as
the Currituck code.

This patch simply renames the file.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/44x/Makefile|2 +-
 arch/powerpc/platforms/44x/currituck.c |  233 
 arch/powerpc/platforms/44x/ppc476fpe.c |  233 
 3 files changed, 234 insertions(+), 234 deletions(-)
 delete mode 100644 arch/powerpc/platforms/44x/currituck.c
 create mode 100644 arch/powerpc/platforms/44x/ppc476fpe.c

diff --git a/arch/powerpc/platforms/44x/Makefile 
b/arch/powerpc/platforms/44x/Makefile
index d03833a..c4fe9cd 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
 obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
 obj-$(CONFIG_ISS4xx)   += iss4xx.o
 obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
-obj-$(CONFIG_CURRITUCK)+= currituck.o
+obj-$(CONFIG_CURRITUCK)+= ppc476fpe.o
diff --git a/arch/powerpc/platforms/44x/currituck.c 
b/arch/powerpc/platforms/44x/currituck.c
deleted file mode 100644
index 7f1b71a..000
--- a/arch/powerpc/platforms/44x/currituck.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Currituck board specific routines
- *
- * Copyright © 2011 Tony Breeds IBM Corporation
- *
- * Based on earlier code:
- *Matt Porter 
- *Copyright 2002-2005 MontaVista Software Inc.
- *
- *Eugene Surovegin  or 
- *Copyright (c) 2003-2005 Zultys Technologies
- *
- *Rewritten and ported to the merged powerpc tree:
- *Copyright 2007 David Gibson , IBM Corporation.
- *Copyright © 2011 David Kliekamp IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-static __initdata struct of_device_id ppc47x_of_bus[] = {
-   { .compatible = "ibm,plb4", },
-   { .compatible = "ibm,plb6", },
-   { .compatible = "ibm,opb", },
-   { .compatible = "ibm,ebc", },
-   {},
-};
-
-/* The EEPROM is missing and the default values are bogus.  This forces USB in
- * to EHCI mode */
-static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
-{
-   if (of_machine_is_compatible("ibm,currituck")) {
-   pci_write_config_dword(dev, 0xe0, 0x0114231f);
-   pci_write_config_dword(dev, 0xe4, 0x6c40);
-   }
-}
-DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
-
-static int __init ppc47x_device_probe(void)
-{
-   of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
-
-   return 0;
-}
-machine_device_initcall(ppc47x, ppc47x_device_probe);
-
-/* We can have either UICs or MPICs */
-static void __init ppc47x_init_irq(void)
-{
-   struct device_node *np;
-
-   /* Find top level interrupt controller */
-   for_each_node_with_property(np, "interrupt-controller") {
-   if (of_get_property(np, "interrupts", NULL) == NULL)
-   break;
-   }
-   if (np == NULL)
-   panic("Can't find top level interrupt controller");
-
-   /* Check type and do appropriate initialization */
-   if (of_device_is_compatible(np, "chrp,open-pic")) {
-   /* The MPIC driver will get everything it needs from the
-* device-tree, just pass 0 to all arguments
-*/
-   struct mpic *mpic =
-   mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC ");
-   BUG_ON(mpic == NULL);
-   mpic_init(mpic);
-   ppc_md.get_irq = mpic_get_irq;
-   } else
-   panic("Unrecognized top level interrupt controller");
-}
-
-#ifdef CONFIG_SMP
-static void smp_ppc47x_setup_cpu(int cpu)
-{
-   mpic_setup_this_cpu();
-}
-
-static int smp_ppc47x_kick_cpu(int cpu)
-{
-   struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
-   const u64 *spin_table_addr_prop;
-   u32 *spin_table;
-   extern void start_secondary_47x(void);
-
-   BUG_ON(cpunode == NULL);
-
-   /* Assume spin table. We could test for the enable-method in
-* the device-tree but currently there's little point as it's
-* our only supported method
-*/
-   spin_table_addr_prop =
-   of_get_property(cpunode, "cpu-release-addr", NULL);
-
-   if (spin_table_addr_prop == N

Re: [PATCH 3/7] IBM Akebono: Add support for a new PHY to the IBM emac driver

2013-11-05 Thread Alistair Popple
On Tue, 5 Nov 2013 10:47:22 Florian Fainelli wrote:
> [snip]
> 
> > +/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
> > +static inline int rgmii_valid_mode(int phy_mode)
> > +{
> > +   return  phy_mode == PHY_MODE_GMII ||
> > +   phy_mode == PHY_MODE_MII ||
> > +   phy_mode == PHY_MODE_RGMII ||
> > +   phy_mode == PHY_MODE_TBI ||
> > +   phy_mode == PHY_MODE_RTBI;
> > +}
> > +
> > +static inline const char *rgmii_mode_name(int mode)
> > +{
> > +   switch (mode) {
> > +   case PHY_MODE_RGMII:
> > +   return "RGMII";
> > +   case PHY_MODE_TBI:
> > +   return "TBI";
> > +   case PHY_MODE_GMII:
> > +   return "GMII";
> > +   case PHY_MODE_MII:
> > +   return "MII";
> > +   case PHY_MODE_RTBI:
> > +   return "RTBI";
> > +   default:
> > +   BUG();
> > +   }
> 
> Any reasons why you are duplicating what is available in
> drivers/of/of_net.c ::of_get_phy_mode()?

Unless I'm missing something of_get_phy_mode() is going the other way. 
rgmii_mode_name() is converting PHY_MODE_* into a human-readable string. I 
couldn't find any obvious kernel method to do this but maybe I missed it?

Regards,

Alistair

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/7] IBM Akebono: Add support for a new PHY to the IBM emac driver

2013-11-05 Thread Alistair Popple
On Tue, 5 Nov 2013 23:11:50 Ben Hutchings wrote:
> On Wed, 2013-11-06 at 06:54 +1100, Benjamin Herrenschmidt wrote:

[snip]

> > It's an SoC bit so there's little point making it generally
> > selectable by the user.
> 
> I think a better way to do this is:
> 
> config IBM_EMAC_RGMII_WOL
>   bool "IBM EMAC RGMII wake-on-LAN support"
>   depends on MY_WONDERFUL_NEW_SOC || COMPILE_TEST
>   default y if MY_WONDERFUL_NEW_SOC
> 
> Then anyone making an API change that affects this driver can check that
> it still complies.

The method used in this patch is the same as what is currently used by the 
other IBM EMAC PHY interfaces (eg. config IBM_EMAC_ZMII etc). I'm happy to 
send a patch to update all of those as well for consistency but that would 
mean adding what each platform requires into EMACS Kconfig as well.

Personally I think it is nicer to keep the definitions of what each platform 
requires in one place (ie. arch/powerpc/platforms/44x/Kconfig) as it is 
consistent with what we do for other 44x drivers, however I am happy to use 
the above method if people think it's better.

Alternatively we could do something like this:

config IBM_EMAC_RGMII_WOL
bool
default y if COMPILE_TEST
default n

This would leave the platform dependencies as they are currently but still 
allow compile testing.

Regards,

Alistair

> Ben.
> 
> > Alistair: The commit name should be different, it's not a PHY you are
> > adding, it's a PHY interface (the PHY itself is off chip).
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/7] IBM Akebono: Add support for a new PHY to the IBM emac driver

2013-11-05 Thread Alistair Popple
On Tue, 5 Nov 2013 16:16:08 Florian Fainelli wrote:

[snip]

> 2013/11/5 Alistair Popple :
> >> Any reasons why you are duplicating what is available in
> >> drivers/of/of_net.c ::of_get_phy_mode()?
> > 
> > Unless I'm missing something of_get_phy_mode() is going the other way.
> > rgmii_mode_name() is converting PHY_MODE_* into a human-readable string. I
> > couldn't find any obvious kernel method to do this but maybe I missed it?
> 
> Right, rgmii_mode_name() just has informative purposes and should be
> removed, I would suggest using standard device tree bindings property
> (phy-mode) anyway such that you could use of_get_phy_mode() and use
> phy_interface_t types.

Ok, that's what is currently done in the core IBM EMAC driver. As this is used 
just for informative purposes I will remove it. Thanks.

Regards,

Alistair

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 5/7] IBM Akebono: Add support to the EHCI platform driver for Akebono

2013-11-05 Thread Alistair Popple
On Wed, 6 Nov 2013 06:52:13 Benjamin Herrenschmidt wrote:

[snip]

> 
> Why ? Do we need to add an entry for every platform in there ? Besides,
> it probably should be the SoC name not the platform here
> 
> Why not simply a generic compatible "usb-ehci" ? It's a standard
> programming interface, there are no specific quirks, we shouldn't
> need to have to add new entries to the driver like that for every
> new SoC/platform.
> 

Actually a grep of "usb-ehci" turns up the ehci-ppc-of driver which I somehow 
missed. This driver works and uses .compatible = "usb-ehci" so I can use that 
instead if that is preferable?

However it is basically the same as the ehci-platform driver so I guess at 
some point the two should be merged...

> > > @@ -229,7 +230,7 @@ static struct platform_driver ehci_platform_driver =
> > > {
> > > 
> > >   .owner  = THIS_MODULE,
> > >   .name   = "ehci-platform",
> > >   .pm = &ehci_platform_pm_ops,
> > > 
> > > - .of_match_table = vt8500_ehci_ids,
> > > + .of_match_table = ehci_platform_ids,
> > > 
> > >   }
> > >  
> > >  };
> > 
> > Acked-by: Alan Stern 
> > 
> > ___
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC PATCH] ehci-platform: Merge ppc-of EHCI driver into the ehci-platform driver

2013-11-05 Thread Alistair Popple
Currently the ppc-of driver uses the compatibility string
"usb-ehci". This means platforms that use device-tree and implement an
EHCI compatible interface have to either use the ppc-of driver or add
a compatible line to the ehci-platform driver. It would be more
appropriate for the platform driver to be compatible with "usb-ehci"
as non-powerpc platforms are also beginning to utilise device-tree.

This patch merges the device tree property parsing from ehci-ppc-of
into the platform driver and adds a "usb-ehci" compatibility
string. The existing ehci-ppc-of driver is renamed to ehci-440epx as
it contains platform specific work arounds for the 440EPX SoC.

Signed-off-by: Alistair Popple 
---

So I could submit something like this that essentially merges the ppc-of 
driver into the platform driver instead of adding the "ibm,akebono-ehci" 
compatible line to the platform driver.

However I'm still fairly new to device-tree so I'm not sure what (if any) the 
broader impact would be. A quick grep for "usb-ehci" turned up a couple of ARM 
device tree's using it however they all provided their own drivers and don't 
select CONFIG_USB_EHCI_HCD_PLATFORM so I'm guess they shouldn't be impacted.

I have attempted to fix up any PowerPC device trees/configs, although I wasn't 
sure if "usb-ehci" should remain in sequoia.dts or not given that it needs to 
use the 440EPX specific driver.

Also this hasn't been tested (beyond compilation) yet.

 arch/powerpc/boot/dts/sequoia.dts  |2 +-
 arch/powerpc/configs/44x/canyonlands_defconfig |1 +
 drivers/usb/host/Kconfig   |8 +-
 drivers/usb/host/ehci-440epx.c |  236 

 drivers/usb/host/ehci-hcd.c|6 +-
 drivers/usb/host/ehci-platform.c   |   18 +-
 drivers/usb/host/ehci-ppc-of.c |  236 

 7 files changed, 261 insertions(+), 246 deletions(-)
 create mode 100644 drivers/usb/host/ehci-440epx.c
 delete mode 100644 drivers/usb/host/ehci-ppc-of.c

diff --git a/arch/powerpc/boot/dts/sequoia.dts 
b/arch/powerpc/boot/dts/sequoia.dts
index b1d3292..e28371e 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -153,7 +153,7 @@
};
 
USB0: ehci@e300 {
-   compatible = "ibm,usb-ehci-440epx", "usb-ehci";
+   compatible = "ibm,usb-ehci-440epx";
interrupt-parent = <&UIC0>;
interrupts = <0x1a 0x4>;
reg = <0x 0xe300 0x0090 0x 
0xe390 0x0070>;
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig 
b/arch/powerpc/configs/44x/canyonlands_defconfig
index d5be93e..16dc37f 100644
--- a/arch/powerpc/configs/44x/canyonlands_defconfig
+++ b/arch/powerpc/configs/44x/canyonlands_defconfig
@@ -75,6 +75,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b3f20d7..b8d7c24 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -188,13 +188,13 @@ config USB_EHCI_TEGRA
  This driver enables support for the internal USB Host Controllers
  found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
 
-config USB_EHCI_HCD_PPC_OF
-   bool "EHCI support for PPC USB controller on OF platform bus"
-   depends on PPC_OF
+config USB_EHCI_HCD_440EPX
+   bool "EHCI support for PPC USB controller on 440EPX"
+   depends on PPC_OF && 440EPX
default y
---help---
  Enables support for the USB controller present on the PowerPC
- OpenFirmware platform bus.
+ 440EPX SoC.
 
 config USB_EHCI_SH
bool "EHCI support for SuperH USB controller"
diff --git a/drivers/usb/host/ehci-440epx.c b/drivers/usb/host/ehci-440epx.c
new file mode 100644
index 000..4223700
--- /dev/null
+++ b/drivers/usb/host/ehci-440epx.c
@@ -0,0 +1,236 @@
+/*
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus
+ * Tested on AMCC PPC 440EPx
+ *
+ * Valentine Barshak 
+ *
+ * Based on "ehci-ppc-soc.c" by Stefan Roese 
+ * and "ohci-ppc-of.c" by Sylvain Munaut 
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+
+static const struct hc_driver ehci_440epx_hc_driver = {
+   .description= hcd_name,
+   .product_desc   = "OF EHCI",
+   .hcd_priv_size  = sizeof(struct ehc

Re: [RFC PATCH] ehci-platform: Merge ppc-of EHCI driver into the ehci-platform driver

2013-11-06 Thread Alistair Popple
On Wed, 6 Nov 2013 11:14:44 Alan Stern wrote:
> On Wed, 6 Nov 2013, Alistair Popple wrote:

[snip]

> > +   /* Initialise platform data from device tree if available. */
> > +   if (!dn) {
> 
> Shouldn't this be "if (dn)"?

Yep. Thanks.

> > +   if (of_get_property(dn, "big-endian", NULL)) {
> > +   pdata->big_endian_mmio = 1;
> > +   pdata->big_endian_desc = 1;
> > +   }
> > +   if (of_get_property(dn, "big-endian-regs", NULL))
> > +   pdata->big_endian_mmio = 1;
> > +   if (of_get_property(dn, "big-endian-desc", NULL))
> > +   pdata->big_endian_desc = 1;
> > +   }
> > +
> 
> This isn't good if there is more than one EHCI controller using
> ehci-platform.  To accomodate such cases, it would be necessary to
> allocate a separate copy of ehci_platform_defaults for each controller.

OK, that's a problem. Rather than allocating platform data for each controller 
I will move the device tree parsing into ehci_platform_reset().

> Alan Stern
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC PATCH] ehci-platform: Merge ppc-of EHCI driver into the ehci-platform driver

2013-11-06 Thread Alistair Popple
On Thu, 7 Nov 2013 06:57:00 Benjamin Herrenschmidt wrote:
> On Wed, 2013-11-06 at 18:39 +1100, Alistair Popple wrote:

[snip]

> 
> I would go even further and add the 44x workarounds to the normal
> platform device, with a compatible check in there. That isn't the
> first time we add quirks to an existing driver.

Ok, easily done. I guess I was just cautious of adding a bunch of platform 
specific code into an otherwise generic driver as there seems to be a number 
of other platforms with their own quirks and it would be easy to end up with a 
driver full of platform specific quirks.

That said it is probably better than the current situation in which each 
platform has its own copy/variation of the generic code in ehci-platform.

Unless anyone is against this I will merge the 440EPX specific quirks into the 
ehci-platform driver and submit it as part of the next version of the Akebono 
patch series.

> > +   /* Initialise platform data from device tree if available. */
> > +   if (!dn) {
> 
> That was supposed to be if (dn) no ?

It sure was, thanks.

> 
> > +   if (of_get_property(dn, "big-endian", NULL)) {
> > +   pdata->big_endian_mmio = 1;
> > +   pdata->big_endian_desc = 1;
> > +   }
> > +   if (of_get_property(dn, "big-endian-regs", NULL))
> > +   pdata->big_endian_mmio = 1;
> > +   if (of_get_property(dn, "big-endian-desc", NULL))
> > +   pdata->big_endian_desc = 1;
> > +   }
> > +
> > 
> > irq = platform_get_irq(dev, 0);
> > if (irq < 0) {
> > 
> > dev_err(&dev->dev, "no irq provided");
> > 
> > @@ -203,9 +216,10 @@ static int ehci_platform_resume(struct device *dev)
> > 
> >  #define ehci_platform_resume   NULL
> >  #endif /* CONFIG_PM */
> > 
> > -static const struct of_device_id vt8500_ehci_ids[] = {
> > +static const struct of_device_id ehci_platform_ids[] = {
> > 
> > { .compatible = "via,vt8500-ehci", },
> > { .compatible = "wm,prizm-ehci", },
> > 
> > +   { .compatible = "usb-ehci", },
> > 
> > {}
> >  
> >  };
> 
> Cheers,
> Ben.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/7] IBM Akebono: Add support for a new PHY to the IBM emac driver

2013-11-06 Thread Alistair Popple
On Wed, 6 Nov 2013 16:40:10 Ben Hutchings wrote:
> On Wed, 2013-11-06 at 12:34 +1100, Alistair Popple wrote:
> > On Tue, 5 Nov 2013 23:11:50 Ben Hutchings wrote:
> > > On Wed, 2013-11-06 at 06:54 +1100, Benjamin Herrenschmidt wrote:
> > [snip]
> > 
> > > > It's an SoC bit so there's little point making it generally
> > > > selectable by the user.
> > > 
> > > I think a better way to do this is:
> > > 
> > > config IBM_EMAC_RGMII_WOL
> > > 
> > >   bool "IBM EMAC RGMII wake-on-LAN support"
> > >   depends on MY_WONDERFUL_NEW_SOC || COMPILE_TEST
> > >   default y if MY_WONDERFUL_NEW_SOC
> > > 
> > > Then anyone making an API change that affects this driver can check that
> > > it still complies.
> > 
> > The method used in this patch is the same as what is currently used by the
> > other IBM EMAC PHY interfaces (eg. config IBM_EMAC_ZMII etc). I'm happy to
> > send a patch to update all of those as well for consistency but that would
> > mean adding what each platform requires into EMACS Kconfig as well.
> > 
> > Personally I think it is nicer to keep the definitions of what each
> > platform requires in one place (ie. arch/powerpc/platforms/44x/Kconfig)
> > as it is consistent with what we do for other 44x drivers, however I am
> > happy to use the above method if people think it's better.
> 
> Yes, I see your point.
> 
> > Alternatively we could do something like this:
> > 
> > config IBM_EMAC_RGMII_WOL
> > 
> > bool
> > default y if COMPILE_TEST
> > default n
> > 
> > This would leave the platform dependencies as they are currently but still
> > allow compile testing.
> 
> It still shouldn't default to y in that case.  Instead you can make the
> symbol conditionally configurable:
> 
> config IBM_EMAC_RGMII_WOL
>   bool "IBM EMAC RGMII wake-on-LAN support" if COMPILE_TEST
> 
> and then select this from your platform Kconfig as you intended.

That looks reasonable - I will include it in the next version of the patch 
series. Thanks.

> (There is no need to put 'default n' as that's implicit for a
> configurable symbol.  But it doesn't hurt either.)
> 
> Ben.

Alistair
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 4/7] IBM Akebono: Add support to the OHCI platform driver for Akebono

2013-11-06 Thread Alistair Popple
On Tue, 5 Nov 2013 10:04:02 Alan Stern wrote:

[snip]

> > 
> > +   /* Platforms using DT don't always provide platform data.
> > +* This should provide reasonable defaults. */
> 
>   /*
>* The accepted format for multi-line
>* comments is like this.
>*/
> 

Ok, I'll fix that for the next revision.

> > +   if (!pdata)
> > +   dev->dev.platform_data = pdata = &ohci_platform_defaults;
> > +
> > 
> > irq = platform_get_irq(dev, 0);
> > if (irq < 0) {
> > 
> > dev_err(&dev->dev, "no irq provided");
> > 
> > @@ -171,6 +175,11 @@ static int ohci_platform_resume(struct device *dev)
> > 
> >  #define ohci_platform_resume   NULL
> >  #endif /* CONFIG_PM */
> > 
> > +static const struct of_device_id ohci_of_match[] = {
> > +   { .compatible = "ibm,akebono-ohci", },
> > +   {},
> > +};
> > +
> > 
> >  static const struct platform_device_id ohci_platform_table[] = {
> >  
> > { "ohci-platform", 0 },
> > { }
> > 
> > @@ -191,6 +200,7 @@ static struct platform_driver ohci_platform_driver = {
> > 
> > .owner  = THIS_MODULE,
> > .name   = "ohci-platform",
> > .pm = &ohci_platform_pm_ops,
> > 
> > +   .of_match_table = ohci_of_match,
> > 
> > }
> >  
> >  };
> 
> Update the comment formatting, and then you can resubmit with
> 
> Acked-by: Alan Stern 

Thanks. Based on the discussion for the EHCI driver I would like to change the 
compatibility string to "usb-ochi" (instead of "ibm,akebono-ohci"). Are you 
still happy for me to add the Acked-by with the alternate compatibility (and 
of course the formatting fix)? No other drivers currently use "usb-ochi" so it 
shouldn't require any merging of drivers.

Regards,

Alistair

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/3] powerpc iommu: Remove hardcoded page sizes

2013-11-10 Thread Alistair Popple
This patch series replaces the hardcoded iommu page sizes used by the iommu
backend with a dynamic page size initialised by each platform. This will make
it easier to use iommu page sizes other than 4K.

The series doesn't actually change the iommu page size as each platform 
continues to
initialise the iommu page size to a hardcoded value of 4K.

At this stage testing has only been carried out on a pSeries machine, other 
platforms
including cell have yet to be tested.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/3] powerpc iommu: Update constant names to reflect their hardcoded page size

2013-11-10 Thread Alistair Popple
The powerpc iommu uses a hardcoded page size of 4K. This patch changes
the name of the IOMMU_PAGE_* macros to reflect the hardcoded values. A
future patch will use the existing names to support dynamic page
sizes.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h   |   10 ++--
 arch/powerpc/kernel/dma-iommu.c|4 +-
 arch/powerpc/kernel/iommu.c|   80 
 arch/powerpc/kernel/vio.c  |   19 
 arch/powerpc/platforms/powernv/pci.c   |2 +-
 arch/powerpc/platforms/pseries/iommu.c |8 ++--
 arch/powerpc/platforms/pseries/setup.c |4 +-
 drivers/net/ethernet/ibm/ibmveth.c |9 ++--
 8 files changed, 69 insertions(+), 67 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index c34656a..e53de39 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -30,10 +30,10 @@
 #include 
 #include 
 
-#define IOMMU_PAGE_SHIFT  12
-#define IOMMU_PAGE_SIZE   (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
-#define IOMMU_PAGE_MASK   (~((1 << IOMMU_PAGE_SHIFT) - 1))
-#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
+#define IOMMU_PAGE_SHIFT_4K  12
+#define IOMMU_PAGE_SIZE_4K   (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K)
+#define IOMMU_PAGE_MASK_4K   (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
+#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
 /* Boot time flags */
 extern int iommu_is_off;
@@ -42,7 +42,7 @@ extern int iommu_force_on;
 /* Pure 2^n version of get_order */
 static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
 {
-   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
+   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT_4K) + 1;
 }
 
 
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index e489752..5cfe3db 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,10 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 
mask)
return 0;
}
 
-   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) {
+   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT_4K)) {
dev_info(dev, "Warning: IOMMU offset too big for device 
mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
-   mask, tbl->it_offset << IOMMU_PAGE_SHIFT);
+   mask, tbl->it_offset << IOMMU_PAGE_SHIFT_4K);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 572bb5b..6bc5d14 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -251,14 +251,14 @@ again:
 
if (dev)
boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
- 1 << IOMMU_PAGE_SHIFT);
+ 1 << IOMMU_PAGE_SHIFT_4K);
else
-   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT);
+   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT_4K);
/* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
 
n = iommu_area_alloc(tbl->it_map, limit, start, npages,
-tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT,
-align_mask);
+   tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT_4K,
+   align_mask);
if (n == -1) {
if (likely(pass == 0)) {
/* First try the pool from the start */
@@ -320,12 +320,12 @@ static dma_addr_t iommu_alloc(struct device *dev, struct 
iommu_table *tbl,
return DMA_ERROR_CODE;
 
entry += tbl->it_offset;/* Offset into real TCE table */
-   ret = entry << IOMMU_PAGE_SHIFT;/* Set the return dma address */
+   ret = entry << IOMMU_PAGE_SHIFT_4K; /* Set the return dma address */
 
/* Put the TCEs in the HW table */
build_fail = ppc_md.tce_build(tbl, entry, npages,
- (unsigned long)page & IOMMU_PAGE_MASK,
- direction, attrs);
+   (unsigned long)page & IOMMU_PAGE_MASK_4K,
+   direction, attrs);
 
/* ppc_md.tce_build() only returns non-zero for transient errors.
 * Clean up the table bitmap in this case and return
@@ -352,7 +352,7 @@ static bool iommu_free_check(struct iommu_table *tbl, 
dma_addr_t dma_addr,
 {
unsigned long entry, free_entry;
 
-   entry = dma_addr >> IOMMU_PAGE_SHIFT;
+   entry = dma_addr >> IOMMU_PAGE_SHIFT_4K;
 

[PATCH 2/3] powerpc iommu: Add it_page_shift field to determine iommu page size

2013-11-10 Thread Alistair Popple
This patch adds a it_page_shift field to struct iommu_table and
initiliases it to 4K for all platforms.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h   |1 +
 arch/powerpc/kernel/vio.c  |5 +++--
 arch/powerpc/platforms/cell/iommu.c|   14 --
 arch/powerpc/platforms/powernv/pci.c   |3 ++-
 arch/powerpc/platforms/pseries/iommu.c |   10 ++
 5 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index e53de39..706073a 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -76,6 +76,7 @@ struct iommu_table {
struct iommu_pool large_pool;
struct iommu_pool pools[IOMMU_NR_POOLS];
unsigned long *it_map;   /* A simple allocation bitmap for now */
+   unsigned long  it_page_shift;/* table iommu page size */
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index a93e501..30c1cf5 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1171,9 +1171,10 @@ static struct iommu_table *vio_build_iommu_table(struct 
vio_dev *dev)
&tbl->it_index, &offset, &size);
 
/* TCE table size - measured in tce entries */
-   tbl->it_size = size >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   tbl->it_size = size >> tbl->it_page_shift;
/* offset for VIO should always be 0 */
-   tbl->it_offset = offset >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_offset = offset >> tbl->it_page_shift;
tbl->it_busno = 0;
tbl->it_type = TCE_VB;
tbl->it_blocksize = 16;
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index b535606..2b90ff8 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -197,7 +197,7 @@ static int tce_build_cell(struct iommu_table *tbl, long 
index, long npages,
 
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
-   for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
+   for (i = 0; i < npages; i++, uaddr += tbl->it_page_shift)
io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask);
 
mb();
@@ -430,7 +430,7 @@ static void cell_iommu_setup_hardware(struct cbe_iommu 
*iommu,
 {
cell_iommu_setup_stab(iommu, base, size, 0, 0);
iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
-   IOMMU_PAGE_SHIFT);
+   IOMMU_PAGE_SHIFT_4K);
cell_iommu_enable_hardware(iommu);
 }
 
@@ -487,8 +487,10 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct 
device_node *np,
window->table.it_blocksize = 16;
window->table.it_base = (unsigned long)iommu->ptab;
window->table.it_index = iommu->nid;
-   window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
-   window->table.it_size = size >> IOMMU_PAGE_SHIFT;
+   window->table.it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   window->table.it_offset =
+   (offset >> window->table.it_page_shift) + pte_offset;
+   window->table.it_size = size >> window->table.it_page_shift;
 
iommu_init_table(&window->table, iommu->nid);
 
@@ -773,7 +775,7 @@ static void __init cell_iommu_init_one(struct device_node 
*np,
 
/* Setup the iommu_table */
cell_iommu_setup_window(iommu, np, base, size,
-   offset >> IOMMU_PAGE_SHIFT);
+   offset >> IOMMU_PAGE_SHIFT_4K);
 }
 
 static void __init cell_disable_iommus(void)
@@ -1122,7 +1124,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
 
cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
-   IOMMU_PAGE_SHIFT);
+   IOMMU_PAGE_SHIFT_4K);
cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
 fbase, fsize);
cell_iommu_enable_hardware(iommu);
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 78b231c..cfab147 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -452,7 +452,8 @@ void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
 {
tbl->it_blocksize = 16;
tbl->it_base = (unsigned long)tce_mem;
-   tbl->it_offset = dma_offset >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_page_shift = IOMMU_PAGE_SH

[PATCH 3/3] powerpc iommu: Update the generic code to use dynamic iommu page sizes

2013-11-10 Thread Alistair Popple
This patch updates the generic iommu backend code to use the
it_page_shift field to determine the iommu page size instead of
using hardcoded values.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h   |   19 +---
 arch/powerpc/kernel/dma-iommu.c|4 +-
 arch/powerpc/kernel/iommu.c|   90 +++-
 arch/powerpc/kernel/vio.c  |   25 +++---
 drivers/net/ethernet/ibm/ibmveth.c |   15 +++---
 5 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 706073a..8032c71 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -35,17 +35,14 @@
 #define IOMMU_PAGE_MASK_4K   (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
 #define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
+#define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
+#define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
+#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
+
 /* Boot time flags */
 extern int iommu_is_off;
 extern int iommu_force_on;
 
-/* Pure 2^n version of get_order */
-static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
-{
-   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT_4K) + 1;
-}
-
-
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
@@ -82,6 +79,14 @@ struct iommu_table {
 #endif
 };
 
+/* Pure 2^n version of get_order */
+static inline __attribute_const__
+int get_iommu_order(unsigned long size, struct iommu_table *tbl)
+{
+   return __ilog2((size - 1) >> tbl->it_page_shift) + 1;
+}
+
+
 struct scatterlist;
 
 static inline void set_iommu_table_base(struct device *dev, void *base)
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 5cfe3db..54d0116 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,10 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 
mask)
return 0;
}
 
-   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT_4K)) {
+   if (tbl->it_offset > (mask >> tbl->it_page_shift)) {
dev_info(dev, "Warning: IOMMU offset too big for device 
mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
-   mask, tbl->it_offset << IOMMU_PAGE_SHIFT_4K);
+   mask, tbl->it_offset << tbl->it_page_shift);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 6bc5d14..10dc7c5 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -251,14 +251,13 @@ again:
 
if (dev)
boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
- 1 << IOMMU_PAGE_SHIFT_4K);
+ 1 << tbl->it_page_shift);
else
-   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT_4K);
+   boundary_size = ALIGN(1UL << 32, 1 << tbl->it_page_shift);
/* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
 
-   n = iommu_area_alloc(tbl->it_map, limit, start, npages,
-   tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT_4K,
-   align_mask);
+   n = iommu_area_alloc(tbl->it_map, limit, start, npages, tbl->it_offset,
+boundary_size >> tbl->it_page_shift, align_mask);
if (n == -1) {
if (likely(pass == 0)) {
/* First try the pool from the start */
@@ -320,12 +319,12 @@ static dma_addr_t iommu_alloc(struct device *dev, struct 
iommu_table *tbl,
return DMA_ERROR_CODE;
 
entry += tbl->it_offset;/* Offset into real TCE table */
-   ret = entry << IOMMU_PAGE_SHIFT_4K; /* Set the return dma address */
+   ret = entry << tbl->it_page_shift;  /* Set the return dma address */
 
/* Put the TCEs in the HW table */
build_fail = ppc_md.tce_build(tbl, entry, npages,
-   (unsigned long)page & IOMMU_PAGE_MASK_4K,
-   direction, attrs);
+ (unsigned long)page &
+ IOMMU_PAGE_MASK(tbl), direction, attrs);
 
/* ppc_md.tce_build() only returns non-zero for transient errors.
 * Clean up the table bitmap in this case and return
@@ -352,7 +351,7 @@ static bool iommu_free_check(struct iommu_table *tbl, 
dma_addr_t dma_addr,
 {
unsigned long entry, free_entry;
 
-

[PATCH] powerpc: Fix audit crash due to save/restore PPR changes

2013-04-14 Thread Alistair Popple
The current mainline crashes when hitting userspace with the following:

kernel BUG at /home/alistair/Source/linux-stable/kernel/auditsc.c:1769!
cpu 0x1: Vector: 700 (Program Check) at [c00023883a60]
pc: c01047a8: .__audit_syscall_entry+0x38/0x130
lr: c000ed64: .do_syscall_trace_enter+0xc4/0x270
sp: c00023883ce0
   msr: 80029032
  current = 0xc0002380
  paca= 0xcf080380   softe: 0irq_happened: 0x01
pid   = 1629, comm = start_udev
kernel BUG at /home/alistair/Source/linux-stable/kernel/auditsc.c:1769!
enter ? for help
[c00023883d80] c000ed64 .do_syscall_trace_enter+0xc4/0x270
[c00023883e30] c0009b08 syscall_dotrace+0xc/0x38
--- Exception: c00 (System Call) at 008010ec50dc

Bisecting found the following patch caused it:

commit 44e9309f1f357794b7ae93d5f3e3e6f11d2b8a7f
Author: Haren Myneni 
powerpc: Implement PPR save/restore

It was found this patch corrupted r9 when calling
SET_DEFAULT_THREAD_PPR()

Using r10 as a scratch register instead of r9 solved the problem.

Signed-off-by: Alistair Popple 
Acked-by: Michael Neuling 
---

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 256c5bf..3acb1a0 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -304,7 +304,7 @@ syscall_exit_work:
subir12,r12,TI_FLAGS

 4: /* Anything else left to do? */
-   SET_DEFAULT_THREAD_PPR(r3, r9)  /* Set thread.ppr = 3 */
+   SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */
andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
beq .ret_from_except_lite


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] Make CONFIG_BOOTX an exclusive early debug option

2013-04-23 Thread Alistair Popple

This patch makes the kernel configuration option "Support for early boot text
console (BootX or OpenFirmware only)" an exclusive choice under the "Early
debugging" menu. This prevents selection of two early debug consoles
simultaneously which does not appear to be supported by the code in
arch/powerpc/kernel/udbg.c.

Currently if two consoles are enabled the code in udbg.c selects one based on
the order in which initialisation functions are called which seems fairly
arbitrary.

For example if both CONFIG_BOOTX_TEXT and CONFIG_PPC_EARLY_DEBUG_LPAR are
enabled then the BootX console will be used. However if both CONFIG_BOOTX_TEXT
and CONFIG_PPC_EARLY_DEBUG_PS3GELIC are selected then the latter will be used.

Signed-off-by: Alistair Popple 
---

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5416e28..659120c 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -122,13 +122,6 @@ config BDI_SWITCH
  Unless you are intending to debug the kernel with one of these
  machines, say N here.

-config BOOTX_TEXT
-   bool "Support for early boot text console (BootX or OpenFirmware only)"
-   depends on PPC_OF && PPC_BOOK3S
-   help
- Say Y here to see progress messages from the boot firmware in text
- mode. Requires either BootX or Open Firmware.
-
config PPC_EARLY_DEBUG
bool "Early debugging (dangerous)"
help
@@ -147,6 +140,13 @@ choice
  enable debugging for the wrong type of machine your kernel
  _will not boot_.

+config BOOTX_TEXT
+   bool "Support for early boot text console (BootX or OpenFirmware only)"
+   depends on PPC_OF && PPC_BOOK3S
+   help
+ Say Y here to see progress messages from the boot firmware in text
+ mode. Requires either BootX or Open Firmware.
+
config PPC_EARLY_DEBUG_LPAR
bool "LPAR HV Console"
depends on PPC_PSERIES

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [4/5] IBM Akebono: Add the Akebono platform

2014-05-01 Thread Alistair Popple
Paul,

On Thu, 1 May 2014 11:27:27 Paul Bolle wrote:
> On Thu, 2014-03-06 at 14:52 +1100, Alistair Popple wrote:

[...]

> > This patch adds support for the IBM Akebono board.
> > +   select IBM_EMAC_RGMII_WOL
> 
> The patch that added this symbol (and the related driver) was submitted
> in https://lkml.org/lkml/2014/2/21/25 . It's not (yet) included in
> linux-next. Is it queued somewhere else?

To be honest I'm not sure. I will follow this up on the netdev list.

> > +   select USB
> > +   select USB_OHCI_HCD_PLATFORM
> > +   select USB_EHCI_HCD_PLATFORM
> > +   select MMC_SDHCI
> > +   select MMC_SDHCI_PLTFM
> > +   select MMC_SDHCI_OF_476GTR
> 
> The plan to add MMC_SDHCI_OF_476GTR seems to have been abandoned (see
> the discussion of https://lkml.org/lkml/2014/2/21/24 ). So this select
> is not needed. Should I submit a trivial patch to drop this select?

Thanks for pointing this out, I should have removed the select for 
MMC_SDHCI_OF_476GTR as suggested. I can submit a patch to drop the select or 
send an updated version of the original patch. Which is easiest for you Ben?

> > +   select ATA
> > +   select SATA_AHCI_PLATFORM
> > +   help
> > + This option enables support for the IBM Akebono (476gtr) evaluation
> > board +
> > +
> > 
> >  config ICON
> >  
> > bool "Icon"
> > depends on 44x
> 
> Paul Bolle

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 2/5 V2] IBM Akebono: Add support for a new PHY interface to the IBM emac driver

2014-05-01 Thread Alistair Popple
Hi David,

Given that the Akebono board support has landed in linux-next (next-20140501) 
and there are no outstanding issues with this patch that I'm aware of (please 
let me know if I've missed anything) would it be possible to get this included 
via your tree? Or should I get Ben H to take this through his tree (with your 
Ack)?

Regards,

Alistair

On Tue, 11 Mar 2014 11:44:33 Alistair Popple wrote:
> The IBM PPC476GTR SoC that is used on the Akebono board uses a
> different ethernet PHY interface that has wake on lan (WOL) support
> with the IBM emac. This patch adds support to the IBM emac driver for
> this new PHY interface.
> 
> At this stage the wake on lan functionality has not been implemented.
> 
> Signed-off-by: Alistair Popple 
> Acked-by: Benjamin Herrenschmidt 
> ---
> 
> This version just fixes the coding style as suggested by David M.
> 
>  .../devicetree/bindings/powerpc/4xx/emac.txt   |   9 +
>  drivers/net/ethernet/ibm/emac/Kconfig  |   4 +
>  drivers/net/ethernet/ibm/emac/Makefile |   1 +
>  drivers/net/ethernet/ibm/emac/core.c   |  50 -
>  drivers/net/ethernet/ibm/emac/core.h   |  12 +
>  drivers/net/ethernet/ibm/emac/rgmii_wol.c  | 244
> + drivers/net/ethernet/ibm/emac/rgmii_wol.h  | 
> 62 ++
>  7 files changed, 376 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
>  create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h
> 
> diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt index
> 712baf6..0c20529 100644
> --- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> +++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> @@ -61,6 +61,8 @@
> Fox Axon: present, whatever value is appropriate for 
each
> EMAC, that is the content of the current (bogus) 
"phy-port"
> property.
> +- rgmii-wol-device  : 1 cell, required iff connected to a RGMII in the
> WKUP +  power domain. phandle of the RGMII-WOL
> device node.
> 
>  Optional properties:
>  - phy-address   : 1 cell, optional, MDIO address of the PHY. If
> absent, @@ -146,3 +148,10 @@
>  available.
>  For Axon: 0x012a
> 
> +  iv) RGMII-WOL node
> +
> +Required properties:
> +- compatible : compatible list, containing 2 entries, first is
> +"ibm,rgmii-wol-CHIP" where CHIP is the host ASIC 
(like
> +EMAC) and the second is "ibm,rgmii-wol".
> +- reg: 
> diff --git a/drivers/net/ethernet/ibm/emac/Kconfig
> b/drivers/net/ethernet/ibm/emac/Kconfig index 3f44a30..56ea346 100644
> --- a/drivers/net/ethernet/ibm/emac/Kconfig
> +++ b/drivers/net/ethernet/ibm/emac/Kconfig
> @@ -55,6 +55,10 @@ config IBM_EMAC_RGMII
>   bool
>   default n
> 
> +config IBM_EMAC_RGMII_WOL
> + bool "IBM EMAC RGMII wake-on-LAN support" if COMPILE_TEST
> + default n
> +
>  config IBM_EMAC_TAH
>   bool
>   default n
> diff --git a/drivers/net/ethernet/ibm/emac/Makefile
> b/drivers/net/ethernet/ibm/emac/Makefile index eba2183..8843803 100644
> --- a/drivers/net/ethernet/ibm/emac/Makefile
> +++ b/drivers/net/ethernet/ibm/emac/Makefile
> @@ -7,5 +7,6 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
>  ibm_emac-y := mal.o core.o phy.o
>  ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
>  ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
> +ibm_emac-$(CONFIG_IBM_EMAC_RGMII_WOL) += rgmii_wol.o
>  ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
>  ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
> diff --git a/drivers/net/ethernet/ibm/emac/core.c
> b/drivers/net/ethernet/ibm/emac/core.c index ae342fd..ff58474 100644
> --- a/drivers/net/ethernet/ibm/emac/core.c
> +++ b/drivers/net/ethernet/ibm/emac/core.c
> @@ -632,6 +632,8 @@ static int emac_configure(struct emac_instance *dev)
>   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
>   rgmii_set_speed(dev->rgmii_dev, dev->rgmii_port,
>   dev->phy.speed);
> + if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
> + rgmii_wol_set_speed(dev->rgmii_wol_dev, dev->phy.speed);
>   if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
>   zmii_set_speed(dev->zmii_dev, dev->zmii_port, dev->phy.speed);
> 
> @@ -799,6 +801,8 @@ static int __emac_mdio_read(struct emac_instance *dev,
> u8 id, u8 reg) zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
>   if

[PATCH] IBM Akebono: Remove obsolete config select

2014-05-02 Thread Alistair Popple
The original implementation of MMC support for Akebono introduced a
new configuration symbol (MMC_SDHCI_OF_476GTR). This symbol has been
dropped in favour of using the generic platform driver however the
select for this symbol was mistakenly left in the platform
configuration.

This patch removes the obsolete symbol selection.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/44x/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/platforms/44x/Kconfig 
b/arch/powerpc/platforms/44x/Kconfig
index 8beec7d..908bf11 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -220,7 +220,6 @@ config AKEBONO
select USB_EHCI_HCD_PLATFORM
select MMC_SDHCI
select MMC_SDHCI_PLTFM
-   select MMC_SDHCI_OF_476GTR
select ATA
select SATA_AHCI_PLATFORM
help
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] IBM Akebono: Remove obsolete config select

2014-06-19 Thread Alistair Popple
Hi Ben,

It looks like we may have missed this trivial fix? Can you please apply it to 
your tree?

Regards,

Alistair

On Fri, 13 Jun 2014 13:56:32 Paul Bolle wrote:
> On Fri, 2014-05-02 at 18:06 +1000, Alistair Popple wrote:
> > The original implementation of MMC support for Akebono introduced a
> > new configuration symbol (MMC_SDHCI_OF_476GTR). This symbol has been
> > dropped in favour of using the generic platform driver however the
> > select for this symbol was mistakenly left in the platform
> > configuration.
> > 
> > This patch removes the obsolete symbol selection.
> > 
> > Signed-off-by: Alistair Popple 
> 
> This patch hasn't yet entered linux-next nor Linus' tree. Is it queued
> somewhere? If not, would a
> Acked-by: Paul Bolle 
> 
> help to get this trivial patch queued for either of those trees?
> 
> 
> Paul Bolle
> 
> > ---
> > 
> >  arch/powerpc/platforms/44x/Kconfig | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/arch/powerpc/platforms/44x/Kconfig
> > b/arch/powerpc/platforms/44x/Kconfig index 8beec7d..908bf11 100644
> > --- a/arch/powerpc/platforms/44x/Kconfig
> > +++ b/arch/powerpc/platforms/44x/Kconfig
> > @@ -220,7 +220,6 @@ config AKEBONO
> > 
> > select USB_EHCI_HCD_PLATFORM
> > select MMC_SDHCI
> > select MMC_SDHCI_PLTFM
> > 
> > -   select MMC_SDHCI_OF_476GTR
> > 
> > select ATA
> > select SATA_AHCI_PLATFORM
> > help

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc/ppc476: Disable BTAC

2014-08-06 Thread Alistair Popple
This patch disables the branch target address CAM which under specific
circumstances may cause the processor to skip execution of 1-4
instructions. This fixes IBM Erratum #47.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/kernel/head_44x.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index c334f53..b5061ab 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -1210,10 +1210,12 @@ clear_utlb_entry:
 
/* We configure icbi to invalidate 128 bytes at a time since the
 * current 32-bit kernel code isn't too happy with icache != dcache
-* block size
+* block size. We also disable the BTAC as this can cause errors
+* in some circumstances (see IBM Erratum 47).
 */
mfspr   r3,SPRN_CCR0
orisr3,r3,0x0020
+   ori r3,r3,0x0040
mtspr   SPRN_CCR0,r3
isync
 
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc: Don't use ELFv2 ABI to build the kernel

2013-11-17 Thread Alistair Popple
The kernel doesn't build correctly using the ELFv2 ABI.  This patch
ensures that the ELFv1 ABI is used when building a kernel with an
ELFv2 enabled compiler.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 607acf5..8a24636 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -111,6 +111,7 @@ endif
 endif
 
 CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc
+CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
 CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD)
-- 
1.8.2.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Don't use ELFv2 ABI to build the kernel

2013-11-18 Thread Alistair Popple
On Mon, 18 Nov 2013 13:29:25 Scott Wood wrote:
> On Mon, 2013-11-18 at 17:21 +1100, Alistair Popple wrote:

[snip]

> 
> How hard would it be to get the kernel to work with the new ABI?

We are preparing patches at the moment to allow the kernel to support a 
userspace compiled with the new ABI, however the kernel itself still needs to 
be built using the old ABI.

I'm not sure how hard it would be to compile a kernel with the new ABI. It 
mostly compiles now however I'm guessing there's probably some code that would 
need porting to make it functional.

> Do you know where I can find a document for it?

The ABI is still under development so there isn't any documentation available 
for it yet.

> -Scott

Regards,

Alistair
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Don't use ELFv2 ABI to build the kernel

2013-11-18 Thread Alistair Popple
On Tue, 19 Nov 2013 14:25:53 Michael Ellerman wrote:
> On Mon, Nov 18, 2013 at 05:21:34PM +1100, Alistair Popple wrote:
> > The kernel doesn't build correctly using the ELFv2 ABI.  This patch
> > ensures that the ELFv1 ABI is used when building a kernel with an
> > ELFv2 enabled compiler.
> 
> Let me check I've got this straight.
> 
> The ELFv2 ABI is still being developed, so there are no released
> toolchains that support it right?

I believe ELFv2 patches started going upstream to gcc last week.

> So this patch is precautionary, in that it means kernels from this
> commit onward will build correctly with newer toolchains. Anyone wanting
> to build an older kernel with a new toolchain will need to backport this
> patch?

No, only people wanting to build PPC64 little endian kernels with newer 
toolchains should need this (as ELFv2 is the default for PPC64LE). In all 
cases execpt PPC64LE the newer toolchains should default to ELFv1.

> cheers

Regards,

Alistair
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/8] IBM Akebono: Add support to AHCI platform driver

2013-11-21 Thread Alistair Popple
The new IBM Akebono board has a PPC476GTR SoC with an AHCI compliant
SATA controller. This patch adds a compatible property for the new SoC
to the AHCI platform driver.

Signed-off-by: Alistair Popple 
Cc: linux-...@vger.kernel.org
---
 drivers/ata/ahci_platform.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 7d3b853..e247594 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -328,6 +328,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, 
ahci_resume);
 static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,spear-ahci", },
{ .compatible = "snps,exynos5440-ahci", },
+   { .compatible = "ibm,476gtr-ahci", },
{},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/8] IBM Akebono/PPC476GTR Support

2013-11-21 Thread Alistair Popple
The IBM Akebono board is a development board for the new PPC476GTR
system on chip (SoC).

Changes from V1:
 * Update device-tree compatible strings to reflect the name of the
   SoC rather than the board when those components are integrated into
   the SoC.
 * Updates to allow the new EMAC PHY interface to be compile tested.
 * Rather than adding a new compatible string for EHCI support
   usb-ehci is used and the corresponding driver (ehci-ppc-of)
   is merged into the generic EHCI platform driver.
 * A generic (usb-ohci) compatible string is used for OHCI.
 * PCI MSI support has been added via the HSTA module.

Alistair Popple (8):
  IBM Akebono: Add support to AHCI platform driver
  IBM Akebono: Add a SDHCI platform driver
  IBM Akebono: Add support for a new PHY interface to the IBM emac
driver
  IBM Akebono: Add support to the OHCI platform driver for PPC476GTR
  ECHI Platform: Merge ppc-of EHCI driver into the ehci-platform driver
  IBM Currituck: Clean up board specific code before adding Akebono
code
  IBM Akebono: Add the Akebono platform
  powerpc: Added PCI MSI support using the HSTA module

 .../devicetree/bindings/powerpc/4xx/akebono.txt|   54 +++
 .../devicetree/bindings/powerpc/4xx/emac.txt   |9 +
 arch/powerpc/boot/Makefile |3 +
 arch/powerpc/boot/dcr.h|4 +
 arch/powerpc/boot/dts/akebono.dts  |  415 
 arch/powerpc/boot/treeboot-akebono.c   |  179 +
 arch/powerpc/boot/wrapper  |3 +
 arch/powerpc/configs/44x/akebono_defconfig |  148 +++
 arch/powerpc/platforms/44x/Kconfig |   32 +-
 arch/powerpc/platforms/44x/Makefile|3 +-
 arch/powerpc/platforms/44x/currituck.c |  233 ---
 arch/powerpc/platforms/44x/ppc476.c|  299 ++
 arch/powerpc/sysdev/Kconfig|6 +
 arch/powerpc/sysdev/Makefile   |1 +
 arch/powerpc/sysdev/ppc4xx_hsta_msi.c  |  266 +
 arch/powerpc/sysdev/ppc4xx_pci.c   |   41 +-
 arch/powerpc/sysdev/ppc4xx_pci.h   |4 +-
 drivers/ata/ahci_platform.c|1 +
 drivers/mmc/host/Kconfig   |   12 +
 drivers/mmc/host/Makefile  |1 +
 drivers/mmc/host/sdhci-of-476gtr.c |   60 +++
 drivers/net/ethernet/ibm/emac/Kconfig  |4 +
 drivers/net/ethernet/ibm/emac/Makefile |1 +
 drivers/net/ethernet/ibm/emac/core.c   |   50 ++-
 drivers/net/ethernet/ibm/emac/core.h   |   12 +
 drivers/net/ethernet/ibm/emac/rgmii_wol.c  |  243 
 drivers/net/ethernet/ibm/emac/rgmii_wol.h  |   62 +++
 drivers/usb/host/Kconfig   |7 +-
 drivers/usb/host/ehci-hcd.c|5 -
 drivers/usb/host/ehci-platform.c   |   86 +++-
 drivers/usb/host/ehci-ppc-of.c |  236 ---
 drivers/usb/host/ohci-platform.c   |   22 +-
 32 files changed, 1992 insertions(+), 510 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
 create mode 100644 arch/powerpc/boot/dts/akebono.dts
 create mode 100644 arch/powerpc/boot/treeboot-akebono.c
 create mode 100644 arch/powerpc/configs/44x/akebono_defconfig
 delete mode 100644 arch/powerpc/platforms/44x/currituck.c
 create mode 100644 arch/powerpc/platforms/44x/ppc476.c
 create mode 100644 arch/powerpc/sysdev/ppc4xx_hsta_msi.c
 create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h
 delete mode 100644 drivers/usb/host/ehci-ppc-of.c

-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/8] IBM Akebono: Add a SDHCI platform driver

2013-11-21 Thread Alistair Popple
This patch adds a SDHCI platform driver for the new IBM PPC476GTR SoC
which is on the Akebono board.

Signed-off-by: Alistair Popple 
Cc: Chris Ball 
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/host/Kconfig   |   12 
 drivers/mmc/host/Makefile  |1 +
 drivers/mmc/host/sdhci-of-476gtr.c |   60 
 3 files changed, 73 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7fc5099..14210df 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,18 @@ config MMC_SDHCI_OF_HLWD
 
  If unsure, say N.
 
+config MMC_SDHCI_OF_476GTR
+   tristate "SDHCI OF support for the IBM PPC476GTR SoC"
+   depends on MMC_SDHCI_PLTFM
+   depends on PPC_OF
+   help
+ This selects the Secure Digital Host Controller Interface (SDHCI)
+ found on the PPC476GTR SoC.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
 config MMC_SDHCI_CNS3XXX
tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
depends on ARCH_CNS3XXX
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c41d0c3..92beff3 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)  += sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)  += sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)   += sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_OF_476GTR)  += sdhci-of-476gtr.o
 obj-$(CONFIG_MMC_SDHCI_BCM_KONA)   += sdhci-bcm-kona.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)+= sdhci-bcm2835.o
 
diff --git a/drivers/mmc/host/sdhci-of-476gtr.c 
b/drivers/mmc/host/sdhci-of-476gtr.c
new file mode 100644
index 000..1310f8c
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-476gtr.c
@@ -0,0 +1,60 @@
+/*
+ * drivers/mmc/host/sdhci-of-476gtr.c
+ *
+ * Copyright © 2013 Alistair Popple  IBM Corporation
+ *
+ * Based on sdhci-of-hlwd.c
+ *
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include "sdhci-pltfm.h"
+
+static const struct sdhci_ops sdhci_476gtr_ops = {
+};
+
+static const struct sdhci_pltfm_data sdhci_476gtr_pdata = {
+   .ops = &sdhci_476gtr_ops,
+};
+
+static int sdhci_476gtr_probe(struct platform_device *pdev)
+{
+   return sdhci_pltfm_register(pdev, &sdhci_476gtr_pdata, 0);
+}
+
+static int sdhci_476gtr_remove(struct platform_device *pdev)
+{
+   return sdhci_pltfm_unregister(pdev);
+}
+
+static const struct of_device_id sdhci_476gtr_of_match[] = {
+   { .compatible = "ibm,476gtr-sdhci" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, sdhci_476gtr_of_match);
+
+static struct platform_driver sdhci_476gtr_driver = {
+   .driver = {
+   .name = "sdhci-476gtr",
+   .owner = THIS_MODULE,
+   .of_match_table = sdhci_476gtr_of_match,
+   .pm = SDHCI_PLTFM_PMOPS,
+   },
+   .probe = sdhci_476gtr_probe,
+   .remove = sdhci_476gtr_remove,
+};
+
+module_platform_driver(sdhci_476gtr_driver);
+
+MODULE_DESCRIPTION("PPC476GTR SDHCI OF driver");
+MODULE_AUTHOR("Alistair Popple");
+MODULE_LICENSE("GPL v2");
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/8] IBM Akebono: Add support for a new PHY interface to the IBM emac driver

2013-11-21 Thread Alistair Popple
The IBM PPC476GTR SoC that is used on the Akebono board uses a
different ethernet PHY interface that has wake on lan (WOL) support
with the IBM emac. This patch adds support to the IBM emac driver for
this new PHY interface.

At this stage the wake on lan functionality has not been implemented.

Signed-off-by: Alistair Popple 
Cc: "David S. Miller" 
Cc: net...@vger.kernel.org
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   |9 +
 drivers/net/ethernet/ibm/emac/Kconfig  |4 +
 drivers/net/ethernet/ibm/emac/Makefile |1 +
 drivers/net/ethernet/ibm/emac/core.c   |   50 +++-
 drivers/net/ethernet/ibm/emac/core.h   |   12 +
 drivers/net/ethernet/ibm/emac/rgmii_wol.c  |  243 
 drivers/net/ethernet/ibm/emac/rgmii_wol.h  |   62 +
 7 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.c
 create mode 100644 drivers/net/ethernet/ibm/emac/rgmii_wol.h

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6..9928d9d 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -61,6 +61,8 @@
  Fox Axon: present, whatever value is appropriate for 
each
  EMAC, that is the content of the current (bogus) 
"phy-port"
  property.
+- rgmii-wol-device  : 1 cell, required iff conntect to a RGMII in the WKUP
+  power domain. phandle of the RGMII-WOL device node.
 
 Optional properties:
 - phy-address   : 1 cell, optional, MDIO address of the PHY. If absent,
@@ -146,3 +148,10 @@
   available.
   For Axon: 0x012a
 
+  iv) RGMII-WOL node
+
+Required properties:
+- compatible : compatible list, containing 2 entries, first is
+  "ibm,rgmii-wol-CHIP" where CHIP is the host ASIC 
(like
+  EMAC) and the second is "ibm,rgmii-wol".
+- reg: 
diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30..56ea346 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -55,6 +55,10 @@ config IBM_EMAC_RGMII
bool
default n
 
+config IBM_EMAC_RGMII_WOL
+   bool "IBM EMAC RGMII wake-on-LAN support" if COMPILE_TEST
+   default n
+
 config IBM_EMAC_TAH
bool
default n
diff --git a/drivers/net/ethernet/ibm/emac/Makefile 
b/drivers/net/ethernet/ibm/emac/Makefile
index eba2183..8843803 100644
--- a/drivers/net/ethernet/ibm/emac/Makefile
+++ b/drivers/net/ethernet/ibm/emac/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
 ibm_emac-y := mal.o core.o phy.o
 ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
 ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII_WOL) += rgmii_wol.o
 ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
 ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 6b5c722..fc1a775 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -630,6 +630,8 @@ static int emac_configure(struct emac_instance *dev)
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_set_speed(dev->rgmii_dev, dev->rgmii_port,
dev->phy.speed);
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_set_speed(dev->rgmii_wol_dev, dev->phy.speed);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
zmii_set_speed(dev->zmii_dev, dev->zmii_port, dev->phy.speed);
 
@@ -797,6 +799,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 
id, u8 reg)
zmii_get_mdio(dev->zmii_dev, dev->zmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_get_mdio(dev->rgmii_wol_dev);
 
/* Wait for management interface to become idle */
n = 20;
@@ -844,6 +848,8 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 
id, u8 reg)
DBG2(dev, "mdio_read -> %04x" NL, r);
err = 0;
  bail:
+   if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII_WOL))
+   rgmii_wol_put_mdio(dev->rgmii_wol_dev);
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII))
rgmii_put_mdio(dev->rgmii_dev, dev->rgmii_port);
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
@@ -869,6 +875,8 @@ static void __emac_mdio_write(stru

[PATCH 4/8] IBM Akebono: Add support to the OHCI platform driver for PPC476GTR

2013-11-21 Thread Alistair Popple
The IBM Akebono board uses the PPC476GTR SoC which has a OHCI
compliant USB host interface. This patch adds support for it to the
OHCI platform driver.

As we use device tree to pass platform specific data instead of
platform data we remove the check for platform data and instead
provide reasonable defaults if no platform data is present. This is
similar to what is currently done in ehci-platform.c.

Signed-off-by: Alistair Popple 
Acked-by: Alan Stern 
Cc: linux-...@vger.kernel.org
---
 drivers/usb/host/ohci-platform.c |   22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index a4c6410..e1ae5d3 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "ohci.h"
 
@@ -55,6 +57,8 @@ static const struct ohci_driver_overrides platform_overrides 
__initconst = {
.reset =ohci_platform_reset,
 };
 
+static struct usb_ohci_pdata ohci_platform_defaults;
+
 static int ohci_platform_probe(struct platform_device *dev)
 {
struct usb_hcd *hcd;
@@ -63,14 +67,16 @@ static int ohci_platform_probe(struct platform_device *dev)
int irq;
int err = -ENOMEM;
 
-   if (!pdata) {
-   WARN_ON(1);
-   return -ENODEV;
-   }
-
if (usb_disabled())
return -ENODEV;
 
+   /*
+* Platforms using DT don't always provide platform data.
+* This should provide reasonable defaults.
+*/
+   if (!pdata)
+   dev->dev.platform_data = pdata = &ohci_platform_defaults;
+
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
@@ -171,6 +177,11 @@ static int ohci_platform_resume(struct device *dev)
 #define ohci_platform_resume   NULL
 #endif /* CONFIG_PM */
 
+static const struct of_device_id ohci_of_match[] = {
+   { .compatible = "usb-ohci", },
+   {},
+};
+
 static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -191,6 +202,7 @@ static struct platform_driver ohci_platform_driver = {
.owner  = THIS_MODULE,
.name   = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+   .of_match_table = ohci_of_match,
}
 };
 
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 5/8] ECHI Platform: Merge ppc-of EHCI driver into the ehci-platform driver

2013-11-21 Thread Alistair Popple
Currently the ppc-of driver uses the compatibility string
"usb-ehci". This means platforms that use device-tree and implement an
EHCI compatible interface have to either use the ppc-of driver or add
a compatible line to the ehci-platform driver. It would be more
appropriate for the platform driver to be compatible with "usb-ehci"
as non-powerpc platforms are also beginning to utilise device-tree.

This patch merges the device tree property parsing from ehci-ppc-of
into the platform driver and adds a "usb-ehci" compatibility
string. The existing ehci-ppc-of driver is removed and the 440EPX
specific quirks are added to the ehci-platform driver.

Signed-off-by: Alistair Popple 
---
 drivers/usb/host/Kconfig |7 +-
 drivers/usb/host/ehci-hcd.c  |5 -
 drivers/usb/host/ehci-platform.c |   86 +-
 drivers/usb/host/ehci-ppc-of.c   |  236 --
 4 files changed, 88 insertions(+), 246 deletions(-)
 delete mode 100644 drivers/usb/host/ehci-ppc-of.c

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b3f20d7..288fec1 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -189,12 +189,13 @@ config USB_EHCI_TEGRA
  found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
 
 config USB_EHCI_HCD_PPC_OF
-   bool "EHCI support for PPC USB controller on OF platform bus"
+   bool "EHCI support for PPC USB controller on OF platform bus 
(DEPRECATED)"
depends on PPC_OF
default y
+   select USB_EHCI_HCD_PLATFORM
---help---
- Enables support for the USB controller present on the PowerPC
- OpenFirmware platform bus.
+ This option is deprecated now and the driver was removed, use
+ USB_EHCI_HCD_PLATFORM instead.
 
 config USB_EHCI_SH
bool "EHCI support for SuperH USB controller"
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 86ab9fd..d0f384a 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1228,11 +1228,6 @@ MODULE_LICENSE ("GPL");
 #definePS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
-#include "ehci-ppc-of.c"
-#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver
-#endif
-
 #ifdef CONFIG_XPS_USB_HCD_XILINX
 #include "ehci-xilinx-of.c"
 #define XILINX_OF_PLATFORM_DRIVER  ehci_hcd_xilinx_of_driver
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index f6b790c..d9747fb 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -36,11 +36,33 @@
 
 static const char hcd_name[] = "ehci-platform";
 
+/*
+ * 440EPx Errata USBH_3
+ * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
+ */
+#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0)
+static int
+ppc44x_enable_bmt(struct device_node *dn)
+{
+   __iomem u32 *insreg_virt;
+
+   insreg_virt = of_iomap(dn, 1);
+   if (!insreg_virt)
+   return  -EINVAL;
+
+   out_be32(insreg_virt + 3, PPC440EPX_EHCI0_INSREG_BMT);
+
+   iounmap(insreg_virt);
+   return 0;
+}
+
 static int ehci_platform_reset(struct usb_hcd *hcd)
 {
struct platform_device *pdev = to_platform_device(hcd->self.controller);
struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+   struct device_node *dn, *np;
+   struct resource res;
int retval;
 
hcd->has_tt = pdata->has_tt;
@@ -48,6 +70,43 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
ehci->big_endian_desc = pdata->big_endian_desc;
ehci->big_endian_mmio = pdata->big_endian_mmio;
 
+   /* Device tree properties if available will override platform data. */
+   dn = hcd_to_bus(hcd)->controller->of_node;
+   if (dn) {
+   if (of_get_property(dn, "big-endian", NULL)) {
+   ehci->big_endian_mmio = 1;
+   ehci->big_endian_desc = 1;
+   }
+   if (of_get_property(dn, "big-endian-regs", NULL))
+   ehci->big_endian_mmio = 1;
+   if (of_get_property(dn, "big-endian-desc", NULL))
+   ehci->big_endian_desc = 1;
+   }
+
+   np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
+   if (np != NULL) {
+   /* claim we really affected by usb23 erratum */
+   if (!of_address_to_resource(np, 0, &res))
+   ehci->ohci_hcctrl_reg =
+   devm_ioremap(&pdev->dev,
+res.start + OHCI_HCCTRL_OFFSET,
+OHCI_HCCTRL_LEN);
+   el

[PATCH 6/8] IBM Currituck: Clean up board specific code before adding Akebono code

2013-11-21 Thread Alistair Popple
The IBM Akebono code uses the same initialisation functions as the
earlier Currituck board. Rather than create a copy of this code for
Akebono we will instead integrate support for it into the same file as
the Currituck code.

This patch renames the board support file and updates the 476FPE PCI
code to use a more generic name.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/platforms/44x/Kconfig |4 +-
 arch/powerpc/platforms/44x/Makefile|2 +-
 arch/powerpc/platforms/44x/currituck.c |  233 
 arch/powerpc/platforms/44x/ppc476.c|  233 
 arch/powerpc/sysdev/ppc4xx_pci.c   |   20 +--
 arch/powerpc/sysdev/ppc4xx_pci.h   |4 +-
 6 files changed, 248 insertions(+), 248 deletions(-)
 delete mode 100644 arch/powerpc/platforms/44x/currituck.c
 create mode 100644 arch/powerpc/platforms/44x/ppc476.c

diff --git a/arch/powerpc/platforms/44x/Kconfig 
b/arch/powerpc/platforms/44x/Kconfig
index d6c7506..156d474 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -194,7 +194,7 @@ config CURRITUCK
depends on PPC_47x
default n
select SWIOTLB
-   select 476FPE
+   select 476
select PPC4xx_PCI_EXPRESS
help
  This option enables support for the IBM Currituck (476fpe) evaluation 
board
@@ -314,7 +314,7 @@ config 460SX
select IBM_EMAC_ZMII
select IBM_EMAC_TAH
 
-config 476FPE
+config 476
bool
select PPC_FPU
 
diff --git a/arch/powerpc/platforms/44x/Makefile 
b/arch/powerpc/platforms/44x/Makefile
index d03833a..f896b89 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
 obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
 obj-$(CONFIG_ISS4xx)   += iss4xx.o
 obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
-obj-$(CONFIG_CURRITUCK)+= currituck.o
+obj-$(CONFIG_CURRITUCK)+= ppc476.o
diff --git a/arch/powerpc/platforms/44x/currituck.c 
b/arch/powerpc/platforms/44x/currituck.c
deleted file mode 100644
index 7f1b71a..000
--- a/arch/powerpc/platforms/44x/currituck.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Currituck board specific routines
- *
- * Copyright © 2011 Tony Breeds IBM Corporation
- *
- * Based on earlier code:
- *Matt Porter 
- *Copyright 2002-2005 MontaVista Software Inc.
- *
- *Eugene Surovegin  or 
- *Copyright (c) 2003-2005 Zultys Technologies
- *
- *Rewritten and ported to the merged powerpc tree:
- *Copyright 2007 David Gibson , IBM Corporation.
- *Copyright © 2011 David Kliekamp IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-static __initdata struct of_device_id ppc47x_of_bus[] = {
-   { .compatible = "ibm,plb4", },
-   { .compatible = "ibm,plb6", },
-   { .compatible = "ibm,opb", },
-   { .compatible = "ibm,ebc", },
-   {},
-};
-
-/* The EEPROM is missing and the default values are bogus.  This forces USB in
- * to EHCI mode */
-static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
-{
-   if (of_machine_is_compatible("ibm,currituck")) {
-   pci_write_config_dword(dev, 0xe0, 0x0114231f);
-   pci_write_config_dword(dev, 0xe4, 0x6c40);
-   }
-}
-DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
-
-static int __init ppc47x_device_probe(void)
-{
-   of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
-
-   return 0;
-}
-machine_device_initcall(ppc47x, ppc47x_device_probe);
-
-/* We can have either UICs or MPICs */
-static void __init ppc47x_init_irq(void)
-{
-   struct device_node *np;
-
-   /* Find top level interrupt controller */
-   for_each_node_with_property(np, "interrupt-controller") {
-   if (of_get_property(np, "interrupts", NULL) == NULL)
-   break;
-   }
-   if (np == NULL)
-   panic("Can't find top level interrupt controller");
-
-   /* Check type and do appropriate initialization */
-   if (of_device_is_compatible(np, "chrp,open-pic")) {
-   /* The MPIC driver will get everything it needs from the
-* device-tree, just pass 0 to all arguments
-*/
-   struct mpic *mpic =
-   mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC ");
-   BUG_ON(mpic == NULL);
-   mpic_init(mpic);
-   ppc_md.

[PATCH 8/8] powerpc: Added PCI MSI support using the HSTA module

2013-11-21 Thread Alistair Popple
The PPC476GTR SoC supports message signalled interrupts (MSI) by writing
to special addresses within the High Speed Transfer Assist (HSTA) module.

This patch adds support for PCI MSI with a new system device. The DMA
window is also updated to allow access to the entire 42-bit address range
to allow PCI devices write access to the HSTA module.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/boot/dts/akebono.dts |   46 +-
 arch/powerpc/platforms/44x/Kconfig|2 +
 arch/powerpc/sysdev/Kconfig   |6 +
 arch/powerpc/sysdev/Makefile  |1 +
 arch/powerpc/sysdev/ppc4xx_hsta_msi.c |  266 +
 arch/powerpc/sysdev/ppc4xx_pci.c  |8 +-
 6 files changed, 319 insertions(+), 10 deletions(-)
 create mode 100644 arch/powerpc/sysdev/ppc4xx_hsta_msi.c

diff --git a/arch/powerpc/boot/dts/akebono.dts 
b/arch/powerpc/boot/dts/akebono.dts
index 6dd47e9..4cb917f 100644
--- a/arch/powerpc/boot/dts/akebono.dts
+++ b/arch/powerpc/boot/dts/akebono.dts
@@ -82,6 +82,28 @@
ranges;
clock-frequency = <2>; // 200Mhz
 
+   HSTA0: hsta@31e {
+   compatible = "ibm,476gtr-hsta-msi", "ibm,hsta-msi";
+   reg = <0x310 0x000e 0x0 0xf0>;
+   interrupt-parent = <&MPIC>;
+   interrupts = <108 0
+ 109 0
+ 110 0
+ 111 0
+ 112 0
+ 113 0
+ 114 0
+ 115 0
+ 116 0
+ 117 0
+ 118 0
+ 119 0
+ 120 0
+ 121 0
+ 122 0
+ 123 0>;
+   };
+
MAL0: mcmal {
compatible = "ibm,mcmal-476gtr", "ibm,mcmal2";
dcr-reg = <0xc000 0x062>;
@@ -242,8 +264,10 @@
ranges = <0x0200 0x 0x8000 0x0110 
0x8000 0x0 0x8000
  0x0100 0x00x00x0140 
0x00x0 0x0001>;
 
-   /* Inbound starting at 0 to memsize filled in by zImage 
*/
-   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x0 0x0>;
+   /* Inbound starting at 0x0 to 0x400. In order 
to use MSI
+* PCI devices must be able to write to the HSTA module.
+*/
+   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x400 0x0>;
 
/* This drives busses 0 to 0xf */
bus-range = <0x0 0xf>;
@@ -280,8 +304,10 @@
ranges = <0x0200 0x 0x8000 0x0210 
0x8000 0x0 0x8000
  0x0100 0x00x00x0240 
0x00x0 0x0001>;
 
-   /* Inbound starting at 0 to memsize filled in by zImage 
*/
-   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x0 0x0>;
+   /* Inbound starting at 0x0 to 0x400. In order 
to use MSI
+* PCI devices must be able to write to the HSTA module.
+*/
+   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x400 0x0>;
 
/* This drives busses 0 to 0xf */
bus-range = <0x0 0xf>;
@@ -318,8 +344,10 @@
ranges = <0x0200 0x 0x8000 0x0190 
0x8000 0x0 0x8000
  0x0100 0x00x00x01c0 
0x00x0 0x0001>;
 
-   /* Inbound starting at 0 to memsize filled in by zImage 
*/
-   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x0 0x0>;
+   /* Inbound starting at 0x0 to 0x400. In order 
to use MSI
+* PCI devices must be able to write to the HSTA module.
+*/
+   dma-ranges = <0x4200 0x0 0x0 0x0 0x0 0x400 0x0>;
 
/* This drives busses 0 to 0xf */
bus-range = <0x0 0xf>;
@@ -356,8 +384,10 @@
ranges = <0x0200 0x 0x8000 0x0290 
0x8000 0x0 0x8000
  0x0100 0x00x00x02c0 
0x00x0 0x0001>;
 
-   /* Inbound starting at 0 t

[PATCH 7/8] IBM Akebono: Add the Akebono platform

2013-11-21 Thread Alistair Popple
This patch adds support for the IBM Akebono board.

Signed-off-by: Alistair Popple 
---
 .../devicetree/bindings/powerpc/4xx/akebono.txt|   54 +++
 arch/powerpc/boot/Makefile |3 +
 arch/powerpc/boot/dcr.h|4 +
 arch/powerpc/boot/dts/akebono.dts  |  385 
 arch/powerpc/boot/treeboot-akebono.c   |  179 +
 arch/powerpc/boot/wrapper  |3 +
 arch/powerpc/configs/44x/akebono_defconfig |  148 
 arch/powerpc/platforms/44x/Kconfig |   26 ++
 arch/powerpc/platforms/44x/Makefile|1 +
 arch/powerpc/platforms/44x/ppc476.c|  112 --
 arch/powerpc/sysdev/ppc4xx_pci.c   |   13 +-
 11 files changed, 902 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
 create mode 100644 arch/powerpc/boot/dts/akebono.dts
 create mode 100644 arch/powerpc/boot/treeboot-akebono.c
 create mode 100644 arch/powerpc/configs/44x/akebono_defconfig

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
new file mode 100644
index 000..75adb84
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
@@ -0,0 +1,54 @@
+
+IBM Akebono board device tree
+=
+
+The IBM Akebono board is a development board for the PPC476GTR SoC.
+
+0) The root node
+
+   Required properties:
+
+   - model : "ibm,akebono".
+   - compatible : "ibm,akebono" , "ibm,476gtr".
+
+1.a) The Secure Digital Host Controller Interface (SDHCI) node
+
+  Represent the Secure Digital Host Controller Interfaces.
+
+  Required properties:
+
+   - compatible : should be "ibm,476gtr-sdhci","sdhci".
+   - reg : should contain the SDHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the SDHCI interrupt.
+
+1.b) The Advanced Host Controller Interface (AHCI) SATA node
+
+  Represents the advanced host controller SATA interface.
+
+  Required properties:
+
+   - compatible : should be "ibm,476gtr-ahci".
+   - reg : should contain the AHCI registers location and length.
+   - interrupt-parent : a phandle for the interrupt controller.
+   - interrupts : should contain the AHCI interrupt.
+
+1.c) The FPGA node
+
+  The Akebono board stores some board information such as the revision
+  number in an FPGA which is represented by this node.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-fpga".
+   - reg : should contain the FPGA registers location and length.
+
+1.d) The AVR node
+
+  The Akebono board has an Atmel AVR microprocessor attached to the I2C
+  bus as a power controller for the board.
+
+  Required properties:
+
+   - compatible : should be "ibm,akebono-avr".
+   - reg : should contain the I2C bus address for the AVR.
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 15ca225..645ff21 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -46,6 +46,7 @@ $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405
+$(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405
 $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
 
 
@@ -85,6 +86,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c 
treeboot-bamboo.c \
cuboot-taishan.c cuboot-katmai.c \
cuboot-warp.c cuboot-yosemite.c \
treeboot-iss4xx.c treeboot-currituck.c \
+   treeboot-akebono.c \
simpleboot.c fixed-head.S virtex.c
 src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
 src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c
@@ -235,6 +237,7 @@ image-$(CONFIG_YOSEMITE)+= cuImage.yosemite
 image-$(CONFIG_ISS4xx) += treeImage.iss4xx \
   treeImage.iss4xx-mpic
 image-$(CONFIG_CURRITUCK)  += treeImage.currituck
+image-$(CONFIG_AKEBONO)+= treeImage.akebono
 
 # Board ports in arch/powerpc/platform/8xx/Kconfig
 image-$(CONFIG_MPC86XADS)  += cuImage.mpc866ads
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index cc73f7a..bf8f4ed 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -15,6 +15,10 @@
asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \
rval; \
})
+#define mtdcrx(rn, val) \
+   ({  \
+   asm volatile("mtdcrx %

[PATCH V2 0/3] powerpc iommu: Remove hardcoded page sizes

2013-12-08 Thread Alistair Popple
The series doesn't actually change the iommu page size as each platform 
continues to
initialise the iommu page size to a hardcoded value of 4K.

At this stage testing has only been carried out on a pSeries machine, other 
platforms
including cell have yet to be tested.

Changes from V1:
* Rebased on Ben's next tree
* Updated constants in 1/3 that were not present in V1 (thanks Alexy!)
* Added initialisation for pasemi platform that was missed in V1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V2 1/3] powerpc iommu: Update constant names to reflect their hardcoded page size

2013-12-08 Thread Alistair Popple
The powerpc iommu uses a hardcoded page size of 4K. This patch changes
the name of the IOMMU_PAGE_* macros to reflect the hardcoded values. A
future patch will use the existing names to support dynamic page
sizes.

Signed-off-by: Alistair Popple 
Signed-off-by: Alexey Kardashevskiy 
---
 arch/powerpc/include/asm/iommu.h   |   10 ++--
 arch/powerpc/kernel/dma-iommu.c|4 +-
 arch/powerpc/kernel/iommu.c|   78 
 arch/powerpc/kernel/vio.c  |   19 
 arch/powerpc/platforms/cell/iommu.c|   12 ++---
 arch/powerpc/platforms/powernv/pci.c   |4 +-
 arch/powerpc/platforms/pseries/iommu.c |8 ++--
 arch/powerpc/platforms/pseries/setup.c |4 +-
 arch/powerpc/platforms/wsp/wsp_pci.c   |   10 ++--
 drivers/net/ethernet/ibm/ibmveth.c |9 ++--
 drivers/vfio/vfio_iommu_spapr_tce.c|   28 ++--
 11 files changed, 94 insertions(+), 92 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 774fa27..0869c7e 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -30,10 +30,10 @@
 #include 
 #include 
 
-#define IOMMU_PAGE_SHIFT  12
-#define IOMMU_PAGE_SIZE   (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
-#define IOMMU_PAGE_MASK   (~((1 << IOMMU_PAGE_SHIFT) - 1))
-#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
+#define IOMMU_PAGE_SHIFT_4K  12
+#define IOMMU_PAGE_SIZE_4K   (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K)
+#define IOMMU_PAGE_MASK_4K   (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
+#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
 /* Boot time flags */
 extern int iommu_is_off;
@@ -42,7 +42,7 @@ extern int iommu_force_on;
 /* Pure 2^n version of get_order */
 static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
 {
-   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
+   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT_4K) + 1;
 }
 
 
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index e489752..5cfe3db 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,10 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 
mask)
return 0;
}
 
-   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) {
+   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT_4K)) {
dev_info(dev, "Warning: IOMMU offset too big for device 
mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
-   mask, tbl->it_offset << IOMMU_PAGE_SHIFT);
+   mask, tbl->it_offset << IOMMU_PAGE_SHIFT_4K);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index d22abe0..df4a7f1 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -251,14 +251,14 @@ again:
 
if (dev)
boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
- 1 << IOMMU_PAGE_SHIFT);
+ 1 << IOMMU_PAGE_SHIFT_4K);
else
-   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT);
+   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT_4K);
/* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
 
n = iommu_area_alloc(tbl->it_map, limit, start, npages,
-tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT,
-align_mask);
+   tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT_4K,
+   align_mask);
if (n == -1) {
if (likely(pass == 0)) {
/* First try the pool from the start */
@@ -320,12 +320,12 @@ static dma_addr_t iommu_alloc(struct device *dev, struct 
iommu_table *tbl,
return DMA_ERROR_CODE;
 
entry += tbl->it_offset;/* Offset into real TCE table */
-   ret = entry << IOMMU_PAGE_SHIFT;/* Set the return dma address */
+   ret = entry << IOMMU_PAGE_SHIFT_4K; /* Set the return dma address */
 
/* Put the TCEs in the HW table */
build_fail = ppc_md.tce_build(tbl, entry, npages,
- (unsigned long)page & IOMMU_PAGE_MASK,
- direction, attrs);
+   (unsigned long)page & IOMMU_PAGE_MASK_4K,
+   direction, attrs);
 
/* ppc_md.tce_build() only returns non-zero for transient errors.
 * Clean up the table bitmap in this case and return
@@ -352,7 +352,7 @@ static bool iommu_free_check(struct i

[PATCH V2 2/3] powerpc iommu: Add it_page_shift field to determine iommu page size

2013-12-08 Thread Alistair Popple
This patch adds a it_page_shift field to struct iommu_table and
initiliases it to 4K for all platforms.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h   |1 +
 arch/powerpc/kernel/vio.c  |5 +++--
 arch/powerpc/platforms/cell/iommu.c|8 +---
 arch/powerpc/platforms/pasemi/iommu.c  |5 -
 arch/powerpc/platforms/powernv/pci.c   |3 ++-
 arch/powerpc/platforms/pseries/iommu.c |   10 ++
 arch/powerpc/platforms/wsp/wsp_pci.c   |5 +++--
 7 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 0869c7e..7c92834 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -76,6 +76,7 @@ struct iommu_table {
struct iommu_pool large_pool;
struct iommu_pool pools[IOMMU_NR_POOLS];
unsigned long *it_map;   /* A simple allocation bitmap for now */
+   unsigned long  it_page_shift;/* table iommu page size */
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 2e89fa3..170ac24 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1177,9 +1177,10 @@ static struct iommu_table *vio_build_iommu_table(struct 
vio_dev *dev)
&tbl->it_index, &offset, &size);
 
/* TCE table size - measured in tce entries */
-   tbl->it_size = size >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   tbl->it_size = size >> tbl->it_page_shift;
/* offset for VIO should always be 0 */
-   tbl->it_offset = offset >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_offset = offset >> tbl->it_page_shift;
tbl->it_busno = 0;
tbl->it_type = TCE_VB;
tbl->it_blocksize = 16;
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index fc61b90..2b90ff8 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -197,7 +197,7 @@ static int tce_build_cell(struct iommu_table *tbl, long 
index, long npages,
 
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
-   for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE_4K)
+   for (i = 0; i < npages; i++, uaddr += tbl->it_page_shift)
io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask);
 
mb();
@@ -487,8 +487,10 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct 
device_node *np,
window->table.it_blocksize = 16;
window->table.it_base = (unsigned long)iommu->ptab;
window->table.it_index = iommu->nid;
-   window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT_4K) + pte_offset;
-   window->table.it_size = size >> IOMMU_PAGE_SHIFT_4K;
+   window->table.it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   window->table.it_offset =
+   (offset >> window->table.it_page_shift) + pte_offset;
+   window->table.it_size = size >> window->table.it_page_shift;
 
iommu_init_table(&window->table, iommu->nid);
 
diff --git a/arch/powerpc/platforms/pasemi/iommu.c 
b/arch/powerpc/platforms/pasemi/iommu.c
index 7d2d036..2e576f2 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -138,8 +138,11 @@ static void iommu_table_iobmap_setup(void)
pr_debug(" -> %s\n", __func__);
iommu_table_iobmap.it_busno = 0;
iommu_table_iobmap.it_offset = 0;
+   iommu_table_iobmap.it_page_shift = IOBMAP_PAGE_SHIFT;
+
/* it_size is in number of entries */
-   iommu_table_iobmap.it_size = 0x8000 >> IOBMAP_PAGE_SHIFT;
+   iommu_table_iobmap.it_size =
+   0x8000 >> iommu_table_iobmap.it_page_shift;
 
/* Initialize the common IOMMU code */
iommu_table_iobmap.it_base = (unsigned long)iob_l2_base;
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 7f4d857..569b464 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -564,7 +564,8 @@ void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
 {
tbl->it_blocksize = 16;
tbl->it_base = (unsigned long)tce_mem;
-   tbl->it_offset = dma_offset >> IOMMU_PAGE_SHIFT_4K;
+   tbl->it_page_shift = IOMMU_PAGE_SHIFT_4K;
+   tbl->it_offset = dma_offset >> tbl->it_page_shift;
tbl->it_index = 0;
tbl->it_size = tce_size >> 3;
tbl->it_busno = 0;
diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 1b7531c..e029918 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platform

[PATCH V2 3/3] powerpc iommu: Update the generic code to use dynamic iommu page sizes

2013-12-08 Thread Alistair Popple
This patch updates the generic iommu backend code to use the
it_page_shift field to determine the iommu page size instead of
using hardcoded values.

Signed-off-by: Alistair Popple 
---
 arch/powerpc/include/asm/iommu.h |   19 +---
 arch/powerpc/kernel/dma-iommu.c  |4 +-
 arch/powerpc/kernel/iommu.c  |   88 ++
 arch/powerpc/kernel/vio.c|   25 +++---
 arch/powerpc/platforms/powernv/pci.c |2 -
 drivers/net/ethernet/ibm/ibmveth.c   |   15 +++---
 6 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 7c92834..f7a8036 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -35,17 +35,14 @@
 #define IOMMU_PAGE_MASK_4K   (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
 #define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
+#define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
+#define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
+#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
+
 /* Boot time flags */
 extern int iommu_is_off;
 extern int iommu_force_on;
 
-/* Pure 2^n version of get_order */
-static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
-{
-   return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT_4K) + 1;
-}
-
-
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
@@ -82,6 +79,14 @@ struct iommu_table {
 #endif
 };
 
+/* Pure 2^n version of get_order */
+static inline __attribute_const__
+int get_iommu_order(unsigned long size, struct iommu_table *tbl)
+{
+   return __ilog2((size - 1) >> tbl->it_page_shift) + 1;
+}
+
+
 struct scatterlist;
 
 static inline void set_iommu_table_base(struct device *dev, void *base)
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 5cfe3db..54d0116 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -83,10 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 
mask)
return 0;
}
 
-   if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT_4K)) {
+   if (tbl->it_offset > (mask >> tbl->it_page_shift)) {
dev_info(dev, "Warning: IOMMU offset too big for device 
mask\n");
dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
-   mask, tbl->it_offset << IOMMU_PAGE_SHIFT_4K);
+   mask, tbl->it_offset << tbl->it_page_shift);
return 0;
} else
return 1;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index df4a7f1..f58d813 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -251,14 +251,13 @@ again:
 
if (dev)
boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
- 1 << IOMMU_PAGE_SHIFT_4K);
+ 1 << tbl->it_page_shift);
else
-   boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT_4K);
+   boundary_size = ALIGN(1UL << 32, 1 << tbl->it_page_shift);
/* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
 
-   n = iommu_area_alloc(tbl->it_map, limit, start, npages,
-   tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT_4K,
-   align_mask);
+   n = iommu_area_alloc(tbl->it_map, limit, start, npages, tbl->it_offset,
+boundary_size >> tbl->it_page_shift, align_mask);
if (n == -1) {
if (likely(pass == 0)) {
/* First try the pool from the start */
@@ -320,12 +319,12 @@ static dma_addr_t iommu_alloc(struct device *dev, struct 
iommu_table *tbl,
return DMA_ERROR_CODE;
 
entry += tbl->it_offset;/* Offset into real TCE table */
-   ret = entry << IOMMU_PAGE_SHIFT_4K; /* Set the return dma address */
+   ret = entry << tbl->it_page_shift;  /* Set the return dma address */
 
/* Put the TCEs in the HW table */
build_fail = ppc_md.tce_build(tbl, entry, npages,
-   (unsigned long)page & IOMMU_PAGE_MASK_4K,
-   direction, attrs);
+ (unsigned long)page &
+ IOMMU_PAGE_MASK(tbl), direction, attrs);
 
/* ppc_md.tce_build() only returns non-zero for transient errors.
 * Clean up the table bitmap in this case and return
@@ -352,7 +351,7 @@ static bool iommu_free_check(struct iommu_table *tbl, 
dma_addr_t dma_addr

Re: [PATCH 2/8] IBM Akebono: Add a SDHCI platform driver

2013-12-16 Thread Alistair Popple
Hi,

I originally sent this to the linuxppc-dev list thinking Ben H might take it, 
however it should go through the appropriate subsystem. Can someone please 
merge it into the appropriate tree (unless the are problems with it)?

Thanks.

Regards,

Alistair

On Fri, 22 Nov 2013 13:08:30 Alistair Popple wrote:
> This patch adds a SDHCI platform driver for the new IBM PPC476GTR SoC
> which is on the Akebono board.
> 
> Signed-off-by: Alistair Popple 
> Cc: Chris Ball 
> Cc: linux-...@vger.kernel.org
> ---
>  drivers/mmc/host/Kconfig   |   12 
>  drivers/mmc/host/Makefile  |1 +
>  drivers/mmc/host/sdhci-of-476gtr.c |   60
>  3 files changed, 73 insertions(+)
>  create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 7fc5099..14210df 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -130,6 +130,18 @@ config MMC_SDHCI_OF_HLWD
> 
> If unsure, say N.
> 
> +config MMC_SDHCI_OF_476GTR
> + tristate "SDHCI OF support for the IBM PPC476GTR SoC"
> + depends on MMC_SDHCI_PLTFM
> + depends on PPC_OF
> + help
> +   This selects the Secure Digital Host Controller Interface (SDHCI)
> +   found on the PPC476GTR SoC.
> +
> +   If you have a controller with this interface, say Y or M here.
> +
> +   If unsure, say N.
> +
>  config MMC_SDHCI_CNS3XXX
>   tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
>   depends on ARCH_CNS3XXX
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index c41d0c3..92beff3 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)+= sdhci-dove.o
>  obj-$(CONFIG_MMC_SDHCI_TEGRA)+= sdhci-tegra.o
>  obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
>  obj-$(CONFIG_MMC_SDHCI_OF_HLWD)  += sdhci-of-hlwd.o
> +obj-$(CONFIG_MMC_SDHCI_OF_476GTR)+= sdhci-of-476gtr.o
>  obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o
>  obj-$(CONFIG_MMC_SDHCI_BCM2835)  += sdhci-bcm2835.o
> 
> diff --git a/drivers/mmc/host/sdhci-of-476gtr.c
> b/drivers/mmc/host/sdhci-of-476gtr.c new file mode 100644
> index 000..1310f8c
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-of-476gtr.c
> @@ -0,0 +1,60 @@
> +/*
> + * drivers/mmc/host/sdhci-of-476gtr.c
> + *
> + * Copyright © 2013 Alistair Popple  IBM Corporation
> + *
> + * Based on sdhci-of-hlwd.c
> + *
> + * Copyright (C) 2009 The GameCube Linux Team
> + * Copyright (C) 2009 Albert Herranz
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or (at
> + * your option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include "sdhci-pltfm.h"
> +
> +static const struct sdhci_ops sdhci_476gtr_ops = {
> +};
> +
> +static const struct sdhci_pltfm_data sdhci_476gtr_pdata = {
> + .ops = &sdhci_476gtr_ops,
> +};
> +
> +static int sdhci_476gtr_probe(struct platform_device *pdev)
> +{
> + return sdhci_pltfm_register(pdev, &sdhci_476gtr_pdata, 0);
> +}
> +
> +static int sdhci_476gtr_remove(struct platform_device *pdev)
> +{
> + return sdhci_pltfm_unregister(pdev);
> +}
> +
> +static const struct of_device_id sdhci_476gtr_of_match[] = {
> + { .compatible = "ibm,476gtr-sdhci" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, sdhci_476gtr_of_match);
> +
> +static struct platform_driver sdhci_476gtr_driver = {
> + .driver = {
> + .name = "sdhci-476gtr",
> +     .owner = THIS_MODULE,
> + .of_match_table = sdhci_476gtr_of_match,
> + .pm = SDHCI_PLTFM_PMOPS,
> + },
> + .probe = sdhci_476gtr_probe,
> + .remove = sdhci_476gtr_remove,
> +};
> +
> +module_platform_driver(sdhci_476gtr_driver);
> +
> +MODULE_DESCRIPTION("PPC476GTR SDHCI OF driver");
> +MODULE_AUTHOR("Alistair Popple");
> +MODULE_LICENSE("GPL v2");
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


  1   2   3   4   5   6   7   8   >