* [PATCH] of/base: Fix PowerPC address parsing hack
From: Benjamin Herrenschmidt @ 2014-11-12 5:51 UTC (permalink / raw)
To: Rob Herring, Grant Likely
Cc: Olof Johansson, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Arnd Bergmann, linuxppc-dev
We have a historical hack that treats missing ranges properties as the
equivalent of an empty one. This is needed for ancient PowerMac "bad"
device-trees, and shouldn't be enabled for any other PowerPC platform,
otherwise we get some nasty layout of devices in sysfs or even
duplication when a set of otherwise identically named devices is
created multiple times under a different parent node with no ranges
property.
This fix is needed for the PowerNV i2c busses to be exposed properly
and will fix a number of other embedded cases.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org>
---
diff --git a/drivers/of/address.c b/drivers/of/address.c
index e371825..e37f017 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -7,6 +7,10 @@
#include <linux/pci_regs.h>
#include <linux/string.h>
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif
+
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
@@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
* This code is only enabled on powerpc. --gcl
*/
ranges = of_get_property(parent, rprop, &rlen);
-#if !defined(CONFIG_PPC)
+#if defined(CONFIG_PPC)
+ if (!machine_is(powermac))
+#endif /* defined(CONFIG_PPC) */
if (ranges == NULL) {
- pr_err("OF: no ranges; cannot translate\n");
+ pr_debug("OF: no ranges; cannot translate\n");
return 1;
}
-#endif /* !defined(CONFIG_PPC) */
if (ranges == NULL || rlen == 0) {
offset = of_read_number(addr, na);
memset(addr, 0, pna * 4);
^ permalink raw reply related
* [PATCH] powerpc/powernv: Support OPAL requested heartbeat
From: Benjamin Herrenschmidt @ 2014-11-12 6:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jeremy Kerr
If OPAL requests it, call it back via opal_poll_events() at a
regular interval. Some versions of OPAL on some machines require
this to operate some internal timeouts properly.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powernv/opal.c | 64 ++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index f1e0d8c..0153064 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -22,6 +22,8 @@
#include <linux/kobject.h>
#include <linux/delay.h>
#include <linux/memblock.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <asm/machdep.h>
#include <asm/opal.h>
@@ -58,6 +60,7 @@ 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)
{
@@ -633,17 +636,9 @@ static void opal_ipmi_init(struct device_node *opal_node)
of_platform_device_create(np, NULL, NULL);
}
-static int __init opal_init(void)
+static void opal_console_create_devs(void)
{
struct device_node *np, *consoles;
- const __be32 *irqs;
- int rc, i, irqlen;
-
- opal_node = of_find_node_by_path("/ibm,opal");
- if (!opal_node) {
- pr_warn("opal: Node not found\n");
- return -ENODEV;
- }
/* Register OPAL consoles if any ports */
if (firmware_has_feature(FW_FEATURE_OPALv2))
@@ -659,6 +654,13 @@ static int __init opal_init(void)
of_node_put(consoles);
}
+}
+
+static void opal_request_interrupts(void)
+{
+ const __be32 *irqs;
+ int rc, i, irqlen;
+
/* Find all OPAL interrupts and request them */
irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
pr_debug("opal: Found %d interrupts reserved for OPAL\n",
@@ -678,6 +680,49 @@ static int __init opal_init(void)
" (0x%x)\n", rc, irq, hwirq);
opal_irqs[i] = irq;
}
+}
+
+static int kopald(void *unused)
+{
+ set_freezable();
+ do {
+ try_to_freeze();
+ opal_poll_events(NULL);
+ msleep_interruptible(opal_heartbeat);
+ } while (!kthread_should_stop());
+
+ return 0;
+}
+
+static void opal_init_heartbeat(void)
+{
+ /* Old firwmware, we assume the HVC heartbeat is sufficient */
+ if (of_property_read_u32(opal_node, "ibm,heartbeat-freq",
+ &opal_heartbeat) != 0)
+ opal_heartbeat = 0;
+
+ if (opal_heartbeat)
+ kthread_run(kopald, NULL, "kopald");
+}
+
+static int __init opal_init(void)
+{
+ int rc;
+
+ opal_node = of_find_node_by_path("/ibm,opal");
+ if (!opal_node) {
+ pr_warn("opal: Node not found\n");
+ return -ENODEV;
+ }
+
+ /* Setup a heatbeat thread if requested by OPAL */
+ opal_init_heartbeat();
+
+ /* Create console platform devices */
+ opal_console_create_devs();
+
+ /* Register OPAL interrupts */
+ opal_request_interrupts();
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
@@ -696,6 +741,7 @@ static int __init opal_init(void)
opal_msglog_init();
}
+ /* Initialize OPAL IPMI backend */
opal_ipmi_init(opal_node);
return 0;
^ permalink raw reply related
* Re: [PATCH 0/2] Add IPMI support for powernv powerpc machines
From: Michael Ellerman @ 2014-11-12 6:10 UTC (permalink / raw)
To: minyard; +Cc: openipmi-developer, linuxppc-dev, Jeremy Kerr
In-Reply-To: <545B826F.7050501@acm.org>
On Thu, 2014-11-06 at 08:15 -0600, Corey Minyard wrote:
> On 11/05/2014 09:38 PM, Jeremy Kerr wrote:
> > Corey & Michael: if this is acceptable, it may be mergable as two
> > separate patches - one for the IPMI subsystem, one for the powernv
> > platform. However, we'd need to preserve their order: patch 2/2 depends
> > on 1/2, which provides the structure & function definitions. This'll
> > break the build if only 2/2 is in the tree, and CONFIG_IPMI_POWERNV is
> > set.
> >
> > Alternatively, they could be merged by one maintainer, pending an ack
> > from the other.
>
> I'm fine either way.
How about the third option? :)
I've put patch 1 in a topic branch:
https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=topic/opal-ipmi
And will merge that into my next, probably by tomorrow.
If you merge the topic branch and then apply patch 2/2, then it should all go
in without any hiccups.
cheers
^ permalink raw reply
* Re: [PATCH] i2c: Driver to expose PowerNV platform i2c busses
From: Benjamin Herrenschmidt @ 2014-11-12 6:07 UTC (permalink / raw)
To: Neelesh Gupta; +Cc: linuxppc-dev, linux-i2c, Jeremy Kerr
In-Reply-To: <20141110060424.9407.2498.stgit@localhost.localdomain>
On Mon, 2014-11-10 at 11:35 +0530, Neelesh Gupta wrote:
> The patch exposes the available i2c busses on the PowerNV platform
> to the kernel and implements the bus driver to support i2c and
> smbus commands.
> The driver uses the platform device infrastructure to probe the busses
> on the platform and registers them with the i2c driver framework.
>
> Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This version slightly modified removes the unrelated gunk in opal.c
(but needs to apply on top of some other patches in the powerpc tree)
The driver is the same, it's only the
arch/powerpc/platform/powernv/opal.c init bits that get cleaned up and
simplified.
From: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Date: Fri, 7 Nov 2014 16:20:07 +1100
Subject: [PATCH v2] i2c: Driver to expose PowerNV platform i2c busses
The patch exposes the available i2c busses on the PowerNV platform
to the kernel and implements the bus driver to support i2c and
smbus commands.
If the devices are found on the device tree for a given bus/adapter,
the platform init code registers them to the core and binds them
a static bus/adapter number, otherwise the driver registers the
adapter to get the adapter number dynamically.
Results:
--------
[root@tul176p1 ~]# ls -l /sys/class/i2c-adapter/
total 0
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-1 -> ../../devices/i2c-maxim:0/i2c-1
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-2 -> ../../devices/i2c-maxim:1/i2c-2
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-3 -> ../../devices/i2c-vpd:0/i2c-3
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-4 -> ../../devices/i2c-vpd:1/i2c-4
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-5 -> ../../devices/i2c-vpd:2/i2c-5
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-6 -> ../../devices/i2c-vpd:3/i2c-6
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-7 -> ../../devices/i2c-vpd:4/i2c-7
lrwxrwxrwx 1 root root 0 Oct 27 12:41 i2c-8 -> ../../devices/i2c-vpd:5/i2c-8
[root@tul176p1 ~]# ls -l /sys/class/i2c-adapter/i2c-1/
total 0
drwxr-xr-x 2 root root 0 Oct 27 12:41 1-0032
drwxr-xr-x 2 root root 0 Oct 27 12:41 1-0035
drwxr-xr-x 2 root root 0 Oct 27 12:41 1-0036
drwxr-xr-x 2 root root 0 Oct 27 12:41 1-0039
--w------- 1 root root 65536 Oct 27 12:44 delete_device
lrwxrwxrwx 1 root root 0 Oct 27 12:44 device -> ../../i2c-maxim:0
-r--r--r-- 1 root root 65536 Oct 27 12:41 name
--w------- 1 root root 65536 Oct 27 12:44 new_device
lrwxrwxrwx 1 root root 0 Oct 27 12:41 subsystem -> ../../../bus/i2c
-rw-r--r-- 1 root root 65536 Oct 27 12:41 uevent
[root@tul176p1 ~]# cat /sys/class/i2c-adapter/i2c-1/1-0032/name
slot-C10-C11
[root@tul176p1 ~]#
Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/opal.h | 22 +-
arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
arch/powerpc/platforms/powernv/opal.c | 23 ++-
drivers/i2c/busses/Kconfig | 11 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-opal.c | 276 +++++++++++++++++++++++++
6 files changed, 328 insertions(+), 6 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-opal.c
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index a1bf400..a873193 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -153,6 +153,7 @@ struct opal_sg_list {
#define OPAL_UNREGISTER_DUMP_REGION 102
#define OPAL_IPMI_SEND 107
#define OPAL_IPMI_RECV 108
+#define OPAL_I2C_REQUEST 109
#ifndef __ASSEMBLY__
@@ -779,6 +780,24 @@ typedef struct oppanel_line {
uint64_t line_len;
} oppanel_line_t;
+/* OPAL I2C request */
+struct opal_i2c_request {
+ uint8_t type;
+#define OPAL_I2C_RAW_READ 0
+#define OPAL_I2C_RAW_WRITE 1
+#define OPAL_I2C_SM_READ 2
+#define OPAL_I2C_SM_WRITE 3
+ uint8_t flags;
+#define OPAL_I2C_ADDR_10 0x01 /* Not supported yet */
+ uint8_t subaddr_sz; /* Max 4 */
+ uint8_t reserved;
+ __be16 addr; /* 7 or 10 bit address */
+ __be16 reserved2;
+ __be32 subaddr; /* Sub-address if any */
+ __be32 size; /* Data size */
+ __be64 buffer_ra; /* Buffer real address */
+};
+
/* /sys/firmware/opal */
extern struct kobject *opal_kobj;
@@ -941,7 +960,8 @@ int64_t opal_ipmi_send(uint64_t interface, struct opal_ipmi_msg *msg,
uint64_t msg_len);
int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg,
uint64_t *msg_len);
-
+int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
+ struct opal_i2c_request *oreq);
/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
int depth, void *data);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 4ed13f8..a45148c 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -247,5 +247,6 @@ OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
+OPAL_CALL(opal_i2c_request, OPAL_I2C_REQUEST);
OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND);
OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 0153064..a5b9b0e 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -656,6 +656,14 @@ static void opal_console_create_devs(void)
}
+static void opal_i2c_create_devs(void)
+{
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, "ibm,power8-i2c-port")
+ of_platform_device_create(np, NULL, NULL);
+}
+
static void opal_request_interrupts(void)
{
const __be32 *irqs;
@@ -721,6 +729,9 @@ static int __init opal_init(void)
/* Create console platform devices */
opal_console_create_devs();
+ /* Create i2c platform devices */
+ opal_i2c_create_devs();
+
/* Register OPAL interrupts */
opal_request_interrupts();
@@ -777,11 +788,6 @@ void opal_shutdown(void)
opal_unregister_dump_region(OPAL_DUMP_REGION_LOG_BUF);
}
-/* Export this so that test modules can use it */
-EXPORT_SYMBOL_GPL(opal_invalid_call);
-EXPORT_SYMBOL_GPL(opal_ipmi_send);
-EXPORT_SYMBOL_GPL(opal_ipmi_recv);
-
/* Convert a region of vmalloc memory to an opal sg list */
struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
unsigned long vmalloc_size)
@@ -844,3 +850,10 @@ void opal_free_sg_list(struct opal_sg_list *sg)
sg = NULL;
}
}
+
+/* Export this so that test modules can use it */
+EXPORT_SYMBOL_GPL(opal_invalid_call);
+EXPORT_SYMBOL_GPL(opal_ipmi_send);
+EXPORT_SYMBOL_GPL(opal_ipmi_recv);
+EXPORT_SYMBOL_GPL(opal_i2c_request);
+
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2ac87fa..3ad6e17 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1021,4 +1021,15 @@ config SCx200_ACB
This support is also available as a module. If so, the module
will be called scx200_acb.
+config I2C_OPAL
+ tristate "IBM OPAL I2C driver"
+ depends on PPC_POWERNV
+ default y
+ help
+ This exposes the PowerNV platform i2c busses to the linux i2c layer,
+ the driver is based on the OPAL interfaces.
+
+ This driver can also be built as a module. If so, the module will be
+ called as i2c-opal.
+
endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 49bf07e..8f36ef7c 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -100,5 +100,6 @@ obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
+obj-$(CONFIG_I2C_OPAL) += i2c-opal.o
ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c
new file mode 100644
index 0000000..85aa089
--- /dev/null
+++ b/drivers/i2c/busses/i2c-opal.c
@@ -0,0 +1,276 @@
+/*
+ * IBM OPAL I2C driver
+ * Copyright (C) 2014 IBM
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/mm.h>
+#include <asm/opal.h>
+#include <asm/firmware.h>
+
+static int i2c_opal_send_request(u32 bus_id, struct opal_i2c_request *req)
+{
+ struct opal_msg msg;
+ int token, rc;
+
+ token = opal_async_get_token_interruptible();
+ if (token < 0) {
+ if (token != -ERESTARTSYS)
+ pr_err("Failed to get the async token\n");
+
+ return token;
+ }
+
+ rc = opal_i2c_request(token, bus_id, req);
+ if (rc != OPAL_ASYNC_COMPLETION) {
+ rc = -EIO;
+ goto exit;
+ }
+
+ rc = opal_async_wait_response(token, &msg);
+ if (rc) {
+ rc = -EIO;
+ goto exit;
+ }
+
+ rc = be64_to_cpu(msg.params[1]);
+ if (rc != OPAL_SUCCESS) {
+ rc = -EIO;
+ goto exit;
+ }
+
+exit:
+ opal_async_release_token(token);
+ return rc;
+}
+
+static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ unsigned long opal_id = (unsigned long)adap->algo_data;
+ struct opal_i2c_request req;
+ int rc, i;
+
+ /* We only support fairly simple combinations here of one
+ * or two messages
+ */
+ memset(&req, 0, sizeof(req));
+ switch(num) {
+ case 0:
+ return 0;
+ case 1:
+ req.type = (msgs[0].flags & I2C_M_RD) ?
+ OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE;
+ req.addr = cpu_to_be16(msgs[0].addr);
+ req.size = cpu_to_be32(msgs[0].len);
+ req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf));
+ break;
+ case 2:
+ /* For two messages, we basically support only simple
+ * smbus transactions of a write plus a read. We might
+ * want to allow also two writes but we'd have to bounce
+ * the data into a single buffer.
+ */
+ if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD))
+ return -EIO;
+ if (msgs[0].len > 4)
+ return -EIO;
+ if (msgs[0].addr != msgs[1].addr)
+ return -EIO;
+ req.type = OPAL_I2C_SM_READ;
+ req.addr = cpu_to_be16(msgs[0].addr);
+ req.subaddr_sz = msgs[0].len;
+ for (i = 0; i < msgs[0].len; i++)
+ req.subaddr = (req.subaddr << 8) | msgs[0].buf[i];
+ req.subaddr = cpu_to_be32(req.subaddr);
+ req.size = cpu_to_be32(msgs[1].len);
+ req.buffer_ra = cpu_to_be64(__pa(msgs[1].buf));
+ break;
+ default:
+ return -EIO;
+ }
+
+ rc = i2c_opal_send_request(opal_id, &req);
+ if (rc)
+ return rc;
+
+ return num;
+}
+
+static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ unsigned long opal_id = (unsigned long)adap->algo_data;
+ struct opal_i2c_request req;
+ u8 local[2];
+ int rc;
+
+ memset(&req, 0, sizeof(req));
+
+ req.addr = cpu_to_be16(addr);
+ switch (size) {
+ case I2C_SMBUS_BYTE:
+ req.buffer_ra = cpu_to_be64(__pa(&data->byte));
+ req.size = cpu_to_be32(1);
+ /* Fall through */
+ case I2C_SMBUS_QUICK:
+ req.type = (read_write == I2C_SMBUS_READ) ?
+ OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ req.buffer_ra = cpu_to_be64(__pa(&data->byte));
+ req.size = cpu_to_be32(1);
+ req.subaddr = cpu_to_be32(command);
+ req.subaddr_sz = 1;
+ req.type = (read_write == I2C_SMBUS_READ) ?
+ OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ if (!read_write) {
+ local[0] = data->word & 0xff;
+ local[1] = (data->word >> 8) & 0xff;
+ }
+ req.buffer_ra = cpu_to_be64(__pa(local));
+ req.size = cpu_to_be32(2);
+ req.subaddr = cpu_to_be32(command);
+ req.subaddr_sz = 1;
+ req.type = (read_write == I2C_SMBUS_READ) ?
+ OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE;
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ req.buffer_ra = cpu_to_be64(__pa(&data->block[1]));
+ req.size = cpu_to_be32(data->block[0]);
+ req.subaddr = cpu_to_be32(command);
+ req.subaddr_sz = 1;
+ req.type = (read_write == I2C_SMBUS_READ) ?
+ OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rc = i2c_opal_send_request(opal_id, &req);
+ if (!rc && read_write && size == I2C_SMBUS_WORD_DATA) {
+ data->word = ((u16)local[1]) << 8;
+ data->word |= local[0];
+ }
+
+ return rc;
+}
+
+static u32 i2c_opal_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm i2c_opal_algo = {
+ .master_xfer = i2c_opal_master_xfer,
+ .smbus_xfer = i2c_opal_smbus_xfer,
+ .functionality = i2c_opal_func,
+};
+
+static int i2c_opal_probe(struct platform_device *pdev)
+{
+ struct i2c_adapter *adapter;
+ const char *pname;
+ u32 opal_id;
+ int rc;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+ rc = of_property_read_u32(pdev->dev.of_node, "ibm,opal-id", &opal_id);
+ if (rc) {
+ dev_err(&pdev->dev, "Missing ibm,opal-id property !\n");
+ return -EIO;
+ }
+ adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+ if (!adapter)
+ return -ENOMEM;
+ adapter->algo = &i2c_opal_algo;
+ adapter->algo_data = (void *)(unsigned long)opal_id;
+ adapter->dev.parent = &pdev->dev;
+ adapter->dev.of_node = of_node_get(pdev->dev.of_node);
+ pname = of_get_property(pdev->dev.of_node, "port-name", NULL);
+ if (pname)
+ strlcpy(adapter->name, pname, sizeof(adapter->name));
+ else
+ strlcpy(adapter->name, "opal", sizeof(adapter->name));
+
+ platform_set_drvdata(pdev, adapter);
+ rc = i2c_add_adapter(adapter);
+ if (rc)
+ dev_err(&pdev->dev, "Failed to register the i2c adapter\n");
+
+ return rc;
+}
+
+static int i2c_opal_remove(struct platform_device *pdev)
+{
+ struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(adapter);
+
+ kfree(adapter);
+
+ return 0;
+}
+
+static const struct of_device_id i2c_opal_of_match[] = {
+ {
+ .compatible = "ibm,power8-i2c-port",
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, i2c_opal_of_match);
+
+static struct platform_driver i2c_opal_driver = {
+ .probe = i2c_opal_probe,
+ .remove = i2c_opal_remove,
+ .driver = {
+ .name = "i2c-opal",
+ .owner = THIS_MODULE,
+ .of_match_table = i2c_opal_of_match,
+ },
+};
+
+static int __init i2c_opal_init(void)
+{
+ if (!firmware_has_feature(FW_FEATURE_OPAL))
+ return -ENODEV;
+
+ return platform_driver_register(&i2c_opal_driver);
+}
+
+static void __exit i2c_opal_exit(void)
+{
+ return platform_driver_unregister(&i2c_opal_driver);
+}
+
+MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("IBM OPAL I2C driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_opal_init);
+module_exit(i2c_opal_exit);
^ permalink raw reply related
* Re: [PATCH 3/4] powernv: cpuidle: Redesign idle states management
From: Preeti U Murthy @ 2014-11-12 6:51 UTC (permalink / raw)
To: Shreyas B. Prabhu, linux-kernel
Cc: Paul Mackerras, Rafael J. Wysocki, linuxppc-dev, linux-pm
In-Reply-To: <1415030910-5799-4-git-send-email-shreyas@linux.vnet.ibm.com>
Hi Shreyas,
On 11/03/2014 09:38 PM, Shreyas B. Prabhu wrote:
> diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
> index 283c603..df11acb 100644
> --- a/arch/powerpc/kernel/idle_power7.S
> +++ b/arch/powerpc/kernel/idle_power7.S
> _GLOBAL(power7_idle)
> /* Now check if user or arch enabled NAP mode */
> @@ -141,49 +192,16 @@ _GLOBAL(power7_idle)
>
> _GLOBAL(power7_nap)
> mr r4,r3
> - li r3,0
> + li r3,1
The comment at the top of this file states 0 for nap and 1 for sleep.
You will need to change that. As an alternative I would suggest using
the macros that you have already defined:PNV_THREAD_NAP and
PNV_THREAD_SLEEP to write to r3 above and remove the lines that say 0
for nap and 1 for sleep in the comments.
> b power7_powersave_common
> /* No return */
>
<snip>
> @@ -210,12 +226,91 @@ _GLOBAL(power7_wakeup_tb_loss)
> BEGIN_FTR_SECTION
> CHECK_HMI_INTERRUPT
> END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
> +
> + li r7,1
> + mfspr r8,SPRN_PIR
> + /*
> + * The last 3 bits of PIR represents the thread id of a cpu
> + * in power8. This will need adjusting for power7.
> + */
> + andi. r8,r8,0x07 /* Get thread id into r8 */
> + rotld r7,r7,r8
> + /* r7 now has 'thread_id'th bit set */
> +
> + ld r14,PACA_CORE_IDLE_STATE_PTR(r13)
> +lwarx_loop2:
> + lwarx r15,0,r14
> + andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
> + /*
> + * Lock bit is set in one of the 2 cases-
> + * a. In the sleep/winkle enter path, the last thread is executing
> + * fastsleep workaround code.
> + * b. In the wake up path, another thread is executing fastsleep
> + * workaround undo code or resyncing timebase or restoring context
> + * In either case loop until the lock bit is cleared.
> + */
> + bne lwarx_loop2
> +
> + cmpwi cr2,r15,0
> + or r15,r15,r7 /* Set thread bit */
> +
> + beq cr2,first_thread
> +
> + /* Not first thread in core to wake up */
> + stwcx. r15,0,r14
> + bne- lwarx_loop2
> + b common_exit
> +
> +first_thread:
> + /* First thread in core to wakeup */
> + ori r15,r15,PNV_CORE_IDLE_LOCK_BIT
> + stwcx. r15,0,r14
> + bne- lwarx_loop2
> +
> + LOAD_REG_ADDR(r3, pnv_need_fastsleep_workaround)
> + lbz r3,0(r3)
> + cmpwi r3,1
> + /* skip fastsleep workaround if its not needed */
> + bne timebase_resync
> +
> + /* Undo fast sleep workaround */
> + mfcr r16 /* Backup CR into a non-volatile register */
Don't you want to do this ^^ before calling opal_call_realmode for
timebase resync below also?
> + li r3,1
> + li r4,0
> + li r0,OPAL_CONFIG_CPU_IDLE_STATE
> + bl opal_call_realmode
> + mtcr r16 /* Restore CR */
> +
> + /* Do timebase resync if we are waking up from sleep. Use cr1 value
> + * set in exceptions-64s.S */
> + ble cr1,clear_lock
> +
> +timebase_resync:
> /* Time base re-sync */
> - li r3,OPAL_RESYNC_TIMEBASE
> + li r0,OPAL_RESYNC_TIMEBASE
> bl opal_call_realmode;
> -
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 34c6665..980c964 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -36,6 +36,8 @@
> #include <asm/opal.h>
> #include <asm/kexec.h>
> #include <asm/smp.h>
> +#include <asm/cputhreads.h>
> +#include <asm/cpuidle.h>
>
> #include "powernv.h"
>
> @@ -292,11 +294,55 @@ static void __init pnv_setup_machdep_rtas(void)
>
> static u32 supported_cpuidle_states;
>
> +static void pnv_alloc_idle_core_states(void)
> +{
> + int i, j;
> + int nr_cores = cpu_nr_cores();
> + u32 *core_idle_state;
> +
> + /*
> + * Deep idle states like sleep and winkle are per core idle states.
> + * A core enters these states only when all the threads enter either
> + * the particular idle state or a deeper one. There are tasks like
> + * fastsleep hardware bug workaround and hypervisor core state save
> + * which have to be done only by the last thread of the core entering
> + * deep idle state and similarly tasks like timebase resync, hypervisor
> + * core register restore that have to be done only by the first thread
> + * waking up from these states. Introducing core_idle_state, a per core
> + * structure which will keep track threads entering idle states deeper
> + * than sleep.
Since you already have explained ^^ in the changelog, you do not need to
elaborate it here.
> + * core_idle_state - First 8 bits track the idle state of each thread
> + * of the core. The 8th bit is the lock bit. Initially all thread bits
> + * are set. They are cleared when the thread enters deep idle state
> + * like sleep and winkle. Initially the lock bit is cleared.
you can simply have the comment about the bits of core_idle_state
without having to mention about when they are cleared etc..
> + * The lock bit has 2 purposes
> + * a. While the first thread is restoring core state, it prevents
> + * from other threads in the core from switching to prcoess context.
> + * b. While the last thread in the core is saving the core state, it
> + * prevent a different thread from waking up.
The above two points are useful. As far as I see besides explaining the
bits of core_idle_state structure and the purpose of lock bit the rest
of the comments is redundant. A git-blame will let people know why all
this is needed. The comment section should not be used up for this
purpose IMO.
Regards
Preeti U Murthy
^ permalink raw reply
* Re: [PATCH 0/2] Add IPMI support for powernv powerpc machines
From: Jeremy Kerr @ 2014-11-12 7:37 UTC (permalink / raw)
To: Michael Ellerman, minyard; +Cc: openipmi-developer, linuxppc-dev
In-Reply-To: <1415772636.10731.6.camel@concordia>
Hi Corey,
>>> Alternatively, they could be merged by one maintainer, pending an ack
>>> from the other.
>>
>> I'm fine either way.
>
> How about the third option? :)
>
> I've put patch 1 in a topic branch:
>
> https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=topic/opal-ipmi
>
> And will merge that into my next, probably by tomorrow.
>
> If you merge the topic branch and then apply patch 2/2, then it should all go
> in without any hiccups.
OK, and I have an updated IPMI driver patch (ie, 2/2) that will apply on
top of the new ipmi/for-next tree (best done after that merge). Patch
coming shortly...
Cheers,
Jeremy
^ permalink raw reply
* [PATCH v2] drivers/char/ipmi: Add powernv IPMI driver
From: Jeremy Kerr @ 2014-11-12 7:41 UTC (permalink / raw)
To: linuxppc-dev, Corey Minyard, openipmi-developer; +Cc: Michael Ellerman
In-Reply-To: <1415772636.10731.6.camel@concordia>
This change adds an initial IPMI driver for powerpc OPAL firmware. The
interface is exposed entirely through firmware: we have two functions to
send and receive IPMI messages, and an interrupt notification from the
firmware to signify that a message is available.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
v2: Update for ipmi/for-next tree, add copyright header
---
drivers/char/ipmi/Kconfig | 6
drivers/char/ipmi/Makefile | 1
drivers/char/ipmi/ipmi_powernv.c | 307 +++++++++++++++++++++++++++++++
3 files changed, 314 insertions(+)
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index c1fccf4..65fb008 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -72,6 +72,12 @@ config IPMI_SSIF
have a driver that must be accessed over an I2C bus instead of a
standard interface. This module requires I2C support.
+config IPMI_POWERNV
+ depends on PPC_POWERNV
+ tristate 'POWERNV (OPAL firmware) IPMI interface'
+ help
+ Provides a driver for OPAL firmware-based IPMI interfaces.
+
config IPMI_WATCHDOG
tristate 'IPMI Watchdog Timer'
help
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index 115c08d..f3ffde1 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
obj-$(CONFIG_IPMI_SI) += ipmi_si.o
obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
+obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c
new file mode 100644
index 0000000..50134ec
--- /dev/null
+++ b/drivers/char/ipmi/ipmi_powernv.c
@@ -0,0 +1,307 @@
+/*
+ * PowerNV OPAL IPMI driver
+ *
+ * Copyright 2014 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.
+ */
+
+#define pr_fmt(fmt) "ipmi-powernv: " fmt
+
+#include <linux/ipmi_smi.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <asm/opal.h>
+
+
+struct ipmi_smi_powernv {
+ u64 interface_id;
+ struct ipmi_device_id ipmi_id;
+ ipmi_smi_t intf;
+ u64 event;
+ struct notifier_block event_nb;
+
+ /**
+ * We assume that there can only be one outstanding request, so
+ * keep the pending message in cur_msg. We protect this from concurrent
+ * updates through send & recv calls, (and consequently opal_msg, which
+ * is in-use when cur_msg is set) with msg_lock
+ */
+ spinlock_t msg_lock;
+ struct ipmi_smi_msg *cur_msg;
+ struct opal_ipmi_msg *opal_msg;
+};
+
+static int ipmi_powernv_start_processing(void *send_info, ipmi_smi_t intf)
+{
+ struct ipmi_smi_powernv *smi = send_info;
+ smi->intf = intf;
+ return 0;
+}
+
+static void send_error_reply(struct ipmi_smi_powernv *smi,
+ struct ipmi_smi_msg *msg, u8 completion_code)
+{
+ msg->rsp[0] = msg->data[0] | 0x4;
+ msg->rsp[1] = msg->data[1];
+ msg->rsp[2] = completion_code;
+ msg->rsp_size = 3;
+ ipmi_smi_msg_received(smi->intf, msg);
+}
+
+static void ipmi_powernv_send(void *send_info, struct ipmi_smi_msg *msg)
+{
+ struct ipmi_smi_powernv *smi = send_info;
+ struct opal_ipmi_msg *opal_msg;
+ unsigned long flags;
+ int comp, rc;
+ size_t size;
+
+ /* ensure data_len will fit in the opal_ipmi_msg buffer... */
+ if (msg->data_size > IPMI_MAX_MSG_LENGTH) {
+ comp = IPMI_REQ_LEN_EXCEEDED_ERR;
+ goto err;
+ }
+
+ /* ... and that we at least have netfn and cmd bytes */
+ if (msg->data_size < 2) {
+ comp = IPMI_REQ_LEN_INVALID_ERR;
+ goto err;
+ }
+
+ spin_lock_irqsave(&smi->msg_lock, flags);
+
+ if (smi->cur_msg) {
+ comp = IPMI_NODE_BUSY_ERR;
+ goto err_unlock;
+ }
+
+ /* format our data for the OPAL API */
+ opal_msg = smi->opal_msg;
+ opal_msg->version = OPAL_IPMI_MSG_FORMAT_VERSION_1;
+ opal_msg->netfn = msg->data[0];
+ opal_msg->cmd = msg->data[1];
+ if (msg->data_size > 2)
+ memcpy(opal_msg->data, msg->data + 2, msg->data_size - 2);
+
+ /* data_size already includes the netfn and cmd bytes */
+ size = sizeof(*opal_msg) + msg->data_size - 2;
+
+ pr_devel("%s: opal_ipmi_send(0x%llx, %p, %ld)\n", __func__,
+ smi->interface_id, opal_msg, size);
+ rc = opal_ipmi_send(smi->interface_id, opal_msg, size);
+ pr_devel("%s: -> %d\n", __func__, rc);
+
+ if (!rc) {
+ smi->cur_msg = msg;
+ spin_unlock_irqrestore(&smi->msg_lock, flags);
+ return;
+ }
+
+ comp = IPMI_ERR_UNSPECIFIED;
+err_unlock:
+ spin_unlock_irqrestore(&smi->msg_lock, flags);
+err:
+ send_error_reply(smi, msg, comp);
+}
+
+static int ipmi_powernv_recv(struct ipmi_smi_powernv *smi)
+{
+ struct opal_ipmi_msg *opal_msg;
+ struct ipmi_smi_msg *msg;
+ unsigned long flags;
+ uint64_t size;
+ int rc;
+
+ pr_devel("%s: opal_ipmi_recv(%llx, msg, sz)\n", __func__,
+ smi->interface_id);
+
+ spin_lock_irqsave(&smi->msg_lock, flags);
+
+ if (!smi->cur_msg) {
+ pr_warn("no current message?\n");
+ return 0;
+ }
+
+ msg = smi->cur_msg;
+ opal_msg = smi->opal_msg;
+
+ size = cpu_to_be64(sizeof(*opal_msg) + IPMI_MAX_MSG_LENGTH);
+
+ rc = opal_ipmi_recv(smi->interface_id,
+ opal_msg,
+ &size);
+ size = be64_to_cpu(size);
+ 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 (size < sizeof(*opal_msg)) {
+ spin_unlock_irqrestore(&smi->msg_lock, flags);
+ pr_warn("unexpected IPMI message size %lld\n", size);
+ return 0;
+ }
+
+ if (opal_msg->version != OPAL_IPMI_MSG_FORMAT_VERSION_1) {
+ spin_unlock_irqrestore(&smi->msg_lock, flags);
+ pr_warn("unexpected IPMI message format (version %d)\n",
+ opal_msg->version);
+ return 0;
+ }
+
+ msg->rsp[0] = opal_msg->netfn;
+ msg->rsp[1] = opal_msg->cmd;
+ if (size > sizeof(*opal_msg))
+ memcpy(&msg->rsp[2], opal_msg->data, size - sizeof(*opal_msg));
+ msg->rsp_size = 2 + size - sizeof(*opal_msg);
+
+ smi->cur_msg = NULL;
+ spin_unlock_irqrestore(&smi->msg_lock, flags);
+ ipmi_smi_msg_received(smi->intf, msg);
+ return 0;
+}
+
+static void ipmi_powernv_request_events(void *send_info)
+{
+}
+
+static void ipmi_powernv_set_run_to_completion(void *send_info,
+ bool run_to_completion)
+{
+}
+
+static void ipmi_powernv_poll(void *send_info)
+{
+ struct ipmi_smi_powernv *smi = send_info;
+ ipmi_powernv_recv(smi);
+}
+
+static struct ipmi_smi_handlers ipmi_powernv_smi_handlers = {
+ .owner = THIS_MODULE,
+ .start_processing = ipmi_powernv_start_processing,
+ .sender = ipmi_powernv_send,
+ .request_events = ipmi_powernv_request_events,
+ .set_run_to_completion = ipmi_powernv_set_run_to_completion,
+ .poll = ipmi_powernv_poll,
+};
+
+static int ipmi_opal_event(struct notifier_block *nb,
+ unsigned long events, void *change)
+{
+ struct ipmi_smi_powernv *smi = container_of(nb,
+ struct ipmi_smi_powernv, event_nb);
+
+ if (events & smi->event)
+ ipmi_powernv_recv(smi);
+ return 0;
+}
+
+static int ipmi_powernv_probe(struct platform_device *pdev)
+{
+ struct ipmi_smi_powernv *ipmi;
+ struct device *dev;
+ u32 prop;
+ int rc;
+
+ if (!pdev || !pdev->dev.of_node)
+ return -ENODEV;
+
+ dev = &pdev->dev;
+
+ ipmi = devm_kzalloc(dev, sizeof(*ipmi), GFP_KERNEL);
+ if (!ipmi)
+ return -ENOMEM;
+
+ spin_lock_init(&ipmi->msg_lock);
+
+ rc = of_property_read_u32(dev->of_node, "ibm,ipmi-interface-id",
+ &prop);
+ if (rc) {
+ dev_warn(dev, "No interface ID property\n");
+ goto err_free;
+ }
+ ipmi->interface_id = prop;
+
+ rc = of_property_read_u32(dev->of_node, "interrupts", &prop);
+ if (rc) {
+ dev_warn(dev, "No interrupts property\n");
+ goto err_free;
+ }
+
+ ipmi->event = 1ull << prop;
+ ipmi->event_nb.notifier_call = ipmi_opal_event;
+
+ rc = opal_notifier_register(&ipmi->event_nb);
+ if (rc) {
+ dev_warn(dev, "OPAL notifier registration failed (%d)\n", rc);
+ goto err_free;
+ }
+
+ ipmi->opal_msg = devm_kmalloc(dev,
+ sizeof(*ipmi->opal_msg) + IPMI_MAX_MSG_LENGTH,
+ GFP_KERNEL);
+ if (!ipmi->opal_msg) {
+ rc = -ENOMEM;
+ goto err_unregister;
+ }
+
+ /* todo: query actual ipmi_device_id */
+ rc = ipmi_register_smi(&ipmi_powernv_smi_handlers, ipmi,
+ &ipmi->ipmi_id, dev, 0);
+ if (rc) {
+ dev_warn(dev, "IPMI SMI registration failed (%d)\n", rc);
+ goto err_free_msg;
+ }
+
+ dev_set_drvdata(dev, ipmi);
+ return 0;
+
+err_free_msg:
+ devm_kfree(dev, ipmi->opal_msg);
+err_unregister:
+ opal_notifier_unregister(&ipmi->event_nb);
+err_free:
+ devm_kfree(dev, ipmi);
+ return rc;
+}
+
+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);
+ return 0;
+}
+
+static const struct of_device_id ipmi_powernv_match[] = {
+ { .compatible = "ibm,opal-ipmi" },
+ { },
+};
+
+
+static struct platform_driver powernv_ipmi_driver = {
+ .driver = {
+ .name = "ipmi-powernv",
+ .owner = THIS_MODULE,
+ .of_match_table = ipmi_powernv_match,
+ },
+ .probe = ipmi_powernv_probe,
+ .remove = ipmi_powernv_remove,
+};
+
+
+module_platform_driver(powernv_ipmi_driver);
+
+MODULE_DEVICE_TABLE(of, ipmi_powernv_match);
+MODULE_DESCRIPTION("powernv IPMI driver");
+MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>");
+MODULE_LICENSE("GPL");
^ permalink raw reply related
* [PATCH 0/3] VPHN parsing fixes
From: Greg Kurz @ 2014-11-12 8:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
The following commit fixed an endianness issue in the VPHN code:
commit 5c9fb1899400096c6818181c525897a31d57e488
Author: Greg Kurz <gkurz@linux.vnet.ibm.com>
Date: Wed Oct 15 12:42:58 2014 +0200
powerpc/vphn: NUMA node code expects big-endian
It was discussed at the time that we should patch the parsing code instead
of boldly fixing all the values returned by the hypervisor. It is the goal
of this series.
I have an extra question: PAPR+ says that H_HOME_NODE_ASSOCIATIVITY is supposed
to populate registers R4 to R9 with 16-bit or 32-bit values. This means that we
could theorically get 24 associativity domain numbers. According to this commentthe code is limited to 12 though:
/*
* 6 64-bit registers unpacked into 12 32-bit associativity values. To form
* the complete property we have to add the length in the first cell.
*/
#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u32) + 1)
I could find no justification for the fact that we don't expect the registers
to hold 16-bit relevant numbers only. Have I missed something ?
---
Greg Kurz (3):
powerpc/vphn: clarify the H_HOME_NODE_ASSOCIATIVITY API
powerpc/vphn: simplify the parsing code
powerpc/vphn: move endianness fixing to vphn_unpack_associativity()
arch/powerpc/mm/numa.c | 61 ++++++++++++++++++++++++++++++------------------
1 file changed, 38 insertions(+), 23 deletions(-)
--
Greg
^ permalink raw reply
* [PATCH 1/3] powerpc/vphn: clarify the H_HOME_NODE_ASSOCIATIVITY API
From: Greg Kurz @ 2014-11-12 8:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141112083123.6492.22889.stgit@bahia.local>
The number of values returned by the H_HOME_NODE_ASSOCIATIVITY h_call deserves
to be explicitly defined, for a better understanding of the code.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b9d1dfd..1425517 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1401,11 +1401,15 @@ static int update_cpu_associativity_changes_mask(void)
return cpumask_weight(changes);
}
+/* The H_HOME_NODE_ASSOCIATIVITY h_call returns 6 64-bit registers.
+ */
+#define VPHN_REGISTER_COUNT 6
+
/*
* 6 64-bit registers unpacked into 12 32-bit associativity values. To form
* the complete property we have to add the length in the first cell.
*/
-#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32) + 1)
+#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u32) + 1)
/*
* Convert the associativity domain numbers returned from the hypervisor
@@ -1463,7 +1467,7 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity)
int i;
rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
- for (i = 0; i < 6; i++)
+ for (i = 0; i < VPHN_REGISTER_COUNT; i++)
retbuf[i] = cpu_to_be64(retbuf[i]);
vphn_unpack_associativity(retbuf, associativity);
^ permalink raw reply related
* [PATCH 2/3] powerpc/vphn: simplify the parsing code
From: Greg Kurz @ 2014-11-12 8:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141112083123.6492.22889.stgit@bahia.local>
According to PAPR+ 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY, the hypervisor is
supposed to pack significant fields first and fill the remaining unused
fields with "all ones". It means that the first unused field can be viewed
as an end-of-list marker.
The "ibm,associativity" property in the DT isn't padded with ones and no
code in arch/powerpc/mm/numa.c seems to expect the associativity array
to be padded either.
This patch simply ends the parsing when we reach the first unused field.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 1425517..e30c469 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1417,7 +1417,7 @@ static int update_cpu_associativity_changes_mask(void)
*/
static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
{
- int i, nr_assoc_doms = 0;
+ int i;
const __be16 *field = (const __be16 *) packed;
#define VPHN_FIELD_UNUSED (0xffff)
@@ -1425,33 +1425,29 @@ static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
- if (be16_to_cpup(field) == VPHN_FIELD_UNUSED) {
- /* All significant fields processed, and remaining
- * fields contain the reserved value of all 1's.
- * Just store them.
+ if (be16_to_cpup(field) == VPHN_FIELD_UNUSED)
+ /* All significant fields processed.
*/
- unpacked[i] = *((__be32 *)field);
- field += 2;
- } else if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
+ break;
+
+ if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
/* Data is in the lower 15 bits of this field */
unpacked[i] = cpu_to_be32(
be16_to_cpup(field) & VPHN_FIELD_MASK);
field++;
- nr_assoc_doms++;
} else {
/* Data is in the lower 15 bits of this field
* concatenated with the next 16 bit field
*/
unpacked[i] = *((__be32 *)field);
field += 2;
- nr_assoc_doms++;
}
}
/* The first cell contains the length of the property */
- unpacked[0] = cpu_to_be32(nr_assoc_doms);
+ unpacked[0] = cpu_to_be32(i - 1);
- return nr_assoc_doms;
+ return i - 1;
}
/*
^ permalink raw reply related
* [PATCH 3/3] powerpc/vphn: move endianness fixing to vphn_unpack_associativity()
From: Greg Kurz @ 2014-11-12 8:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20141112083123.6492.22889.stgit@bahia.local>
The first argument to vphn_unpack_associativity() is a const long *, but the
parsing code expects __be64 values actually. This is inconsistent. We should
either pass a const __be64 * or change vphn_unpack_associativity() so that
it fixes endianness by itself.
This patch does the latter, since the caller doesn't need to know about
endianness and this allows to fix significant 64-bit values only. Please
note that the previous code was able to cope with 32-bit fields being split
accross two consecutives 64-bit values. Since PAPR+ doesn't say this cannot
happen, the behaviour was kept. It requires extra checking to know when fixing
is needed though.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index e30c469..903ef27 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1417,30 +1417,49 @@ static int update_cpu_associativity_changes_mask(void)
*/
static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
{
- int i;
- const __be16 *field = (const __be16 *) packed;
+ int i, j, k;
+ union {
+ __be64 packed[VPHN_REGISTER_COUNT];
+ __be16 field[VPHN_REGISTER_COUNT * 4];
+ } fixed;
#define VPHN_FIELD_UNUSED (0xffff)
#define VPHN_FIELD_MSB (0x8000)
#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
- for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
- if (be16_to_cpup(field) == VPHN_FIELD_UNUSED)
+ for (i = 1, j = 0, k = 0; i < VPHN_ASSOC_BUFSIZE;) {
+ u16 field;
+
+ if (j % 4 == 0) {
+ fixed.packed[k] = cpu_to_be64(packed[k]);
+ k++;
+ }
+
+ field = be16_to_cpu(fixed.field[j]);
+
+ if (field == VPHN_FIELD_UNUSED)
/* All significant fields processed.
*/
break;
- if (be16_to_cpup(field) & VPHN_FIELD_MSB) {
+ if (field & VPHN_FIELD_MSB) {
/* Data is in the lower 15 bits of this field */
- unpacked[i] = cpu_to_be32(
- be16_to_cpup(field) & VPHN_FIELD_MASK);
- field++;
+ unpacked[i++] = cpu_to_be32(field & VPHN_FIELD_MASK);
+ j++;
} else {
/* Data is in the lower 15 bits of this field
* concatenated with the next 16 bit field
*/
- unpacked[i] = *((__be32 *)field);
- field += 2;
+ if (unlikely(j % 4 == 3)) {
+ /* The next field is to be copied from the next
+ * 64-bit input value. We must fix it now.
+ */
+ fixed.packed[k] = cpu_to_be64(packed[k]);
+ k++;
+ }
+
+ unpacked[i++] = *((__be32 *)&fixed.field[j]);
+ j += 2;
}
}
@@ -1460,11 +1479,8 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity)
long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
u64 flags = 1;
int hwcpu = get_hard_smp_processor_id(cpu);
- int i;
rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
- for (i = 0; i < VPHN_REGISTER_COUNT; i++)
- retbuf[i] = cpu_to_be64(retbuf[i]);
vphn_unpack_associativity(retbuf, associativity);
return rc;
^ permalink raw reply related
* Re: [RFC 01/11] sched: introduce sys_cpumask in tsk to adapt asymmetric system
From: Srikar Dronamraju @ 2014-11-12 9:22 UTC (permalink / raw)
To: kernelfans; +Cc: Paul Mackerras, linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <1413487800-7162-2-git-send-email-kernelfans@gmail.com>
* kernelfans@gmail.com <kernelfans@gmail.com> [2014-10-16 15:29:50]:
> Some system such as powerpc, some tsk (vcpu thread) can only run on
> the dedicated cpu. Since we adapt some asymmetric method to monitor the
> whole physical cpu. (powerKVM only allows the primary hwthread to
> set up runtime env for the secondary when entering guest).
>
> Nowadays, powerKVM run with all the secondary hwthread offline to ensure
> the vcpu threads only run on the primary thread. But we plan to keep all
> cpus online when running powerKVM to give more power when switching back
> to host, so introduce sys_allowed cpumask to reflect the cpuset which
> the vcpu thread can run on.
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> include/linux/init_task.h | 1 +
> include/linux/sched.h | 6 ++++++
> kernel/sched/core.c | 10 ++++++++--
> 3 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/init_task.h b/include/linux/init_task.h
> index 2bb4c4f3..c56f69e 100644
> --- a/include/linux/init_task.h
> +++ b/include/linux/init_task.h
> @@ -172,6 +172,7 @@ extern struct task_group root_task_group;
> .normal_prio = MAX_PRIO-20, \
> .policy = SCHED_NORMAL, \
> .cpus_allowed = CPU_MASK_ALL, \
> + .sys_allowed = CPU_MASK_ALL, \
Do we really need another mask, cant we just use cpus_allowed itself.
> .nr_cpus_allowed= NR_CPUS, \
> .mm = NULL, \
> .active_mm = &init_mm, \
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 5c2c885..ce429f3 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1260,7 +1260,10 @@ struct task_struct {
>
> unsigned int policy;
> int nr_cpus_allowed;
> + /* Anded user and sys_allowed */
> cpumask_t cpus_allowed;
> + /* due to the feature of asymmetric, some tsk can only run on such cpu */
> + cpumask_t sys_allowed;
>
> #ifdef CONFIG_PREEMPT_RCU
> int rcu_read_lock_nesting;
> @@ -2030,6 +2033,9 @@ static inline void tsk_restore_flags(struct task_struct *task,
> }
>
> #ifdef CONFIG_SMP
> +extern void set_cpus_sys_allowed(struct task_struct *p,
> + const struct cpumask *new_mask);
> +
> extern void do_set_cpus_allowed(struct task_struct *p,
> const struct cpumask *new_mask);
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index ec1a286..2cd1ae3 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -4596,13 +4596,19 @@ void init_idle(struct task_struct *idle, int cpu)
> }
>
> #ifdef CONFIG_SMP
> +void set_cpus_sys_allowed(struct task_struct *p,
> + const struct cpumask *new_mask)
> +{
> + cpumask_copy(&p->sys_allowed, new_mask);
> +}
> +
This function doesnt seem to be used anywhere... Not sure why it is
introduced
> void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
> {
> if (p->sched_class && p->sched_class->set_cpus_allowed)
> p->sched_class->set_cpus_allowed(p, new_mask);
>
> - cpumask_copy(&p->cpus_allowed, new_mask);
> - p->nr_cpus_allowed = cpumask_weight(new_mask);
> + cpumask_and(&p->cpus_allowed, &p->sys_allowed, new_mask);
> + p->nr_cpus_allowed = cpumask_weight(&p->cpus_allowed);
> }
>
> /*
> --
> 1.8.3.1
>
>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* re: powerpc: Remove bootmem allocator
From: Dan Carpenter @ 2014-11-12 10:02 UTC (permalink / raw)
To: anton; +Cc: linuxppc-dev
Hello Anton Blanchard,
The patch 10239733ee86: "powerpc: Remove bootmem allocator" from Sep
17, 2014, leads to the following static checker warning:
arch/powerpc/mm/pgtable_32.c:108 pte_alloc_one_kernel()
warn: 'pte' can't be NULL.
arch/powerpc/mm/pgtable_32.c
99 __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
100 {
101 pte_t *pte;
102 extern int mem_init_done;
103
104 if (mem_init_done) {
105 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
106 } else {
107 pte = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
108 if (pte)
It's complaining because we need to check the return from
memblock_alloc() instead of the return from __va().
109 clear_page(pte);
110 }
111 return pte;
112 }
regards,
dan carpenter
^ permalink raw reply
* Re: [RFC 02/11] powerpc: kvm: ensure vcpu-thread run only on primary hwthread
From: Srikar Dronamraju @ 2014-11-12 10:17 UTC (permalink / raw)
To: kernelfans; +Cc: Paul Mackerras, linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <1413487800-7162-3-git-send-email-kernelfans@gmail.com>
* kernelfans@gmail.com <kernelfans@gmail.com> [2014-10-16 15:29:51]:
> When vcpu thread runs at the first time, it will ensure to stick
> to the primary thread.
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/kvm_host.h | 3 +++
> arch/powerpc/kvm/book3s_hv.c | 17 +++++++++++++++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 98d9dd5..9a3355e 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -666,6 +666,9 @@ struct kvm_vcpu_arch {
> spinlock_t tbacct_lock;
> u64 busy_stolen;
> u64 busy_preempt;
> +#ifdef CONFIG_KVMPPC_ENABLE_SECONDARY
> + bool cpu_selected;
> +#endif
> #endif
> };
>
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 27cced9..ba258c8 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -1909,6 +1909,23 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
> {
> int r;
> int srcu_idx;
> +#ifdef CONFIG_KVMPPC_ENABLE_SECONDARY
> + int cpu = smp_processor_id();
> + int target_cpu;
> + unsigned int cpu;
2 variables with same name... cpu
> + struct task_struct *p = current;
> +
> + if (unlikely(!vcpu->arch.cpu_selected)) {
> + vcpu->arch.cpu_selected = true;
Nit: something like cpumask_set seems to be better than cpu_selected
> + for (cpu = 0; cpu < NR_CPUS; cpu+=threads_per_core) {
> + cpumask_set_cpu(cpu, &p->sys_allowed);
Dont we need to reset the cpumask first before we set
the cpumask here?
> + }
> + if (cpu%threads_per_core != 0) {
At this time, cpu should be NR_CPUS and most times it should be a
multiple of threads_per_core. Unfortunately there wont be a cpu with
cpu number NR_CPUS.
> + target_cpu = cpu/threads_per_core*threads_per_core;
Its probably better of to have parenthesis here.
> + migrate_task_to(current, target_cpu);
We are probably migrating to a non-existant cpu.
Also dont you need to check if the target_cpu is part of the cpumask?
> + }
> + }
> +#endif
>
> if (!vcpu->arch.sane) {
> run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
> --
> 1.8.3.1
>
>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* Re: [RFC 03/11] powerpc: kvm: add interface to control kvm function on a core
From: Srikar Dronamraju @ 2014-11-12 13:01 UTC (permalink / raw)
To: kernelfans; +Cc: Paul Mackerras, linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <1413487800-7162-4-git-send-email-kernelfans@gmail.com>
* kernelfans@gmail.com <kernelfans@gmail.com> [2014-10-16 15:29:52]:
> When kvm is enabled on a core, we migrate all external irq to primary
> thread. Since currently, the kvmirq logic is handled by the primary
> hwthread.
>
> Todo: this patch lacks re-enable of irqbalance when kvm is disable on
> the core
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> arch/powerpc/kernel/sysfs.c | 39 ++++++++++++++++++++++++++++++++++
> arch/powerpc/sysdev/xics/xics-common.c | 12 +++++++++++
> 2 files changed, 51 insertions(+)
>
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index 67fd2fd..a2595dd 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -552,6 +552,45 @@ static void sysfs_create_dscr_default(void)
> if (cpu_has_feature(CPU_FTR_DSCR))
> err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default);
> }
> +
> +#ifdef CONFIG_KVMPPC_ENABLE_SECONDARY
> +#define NR_CORES (CONFIG_NR_CPUS/threads_per_core)
> +static DECLARE_BITMAP(kvm_on_core, NR_CORES) __read_mostly
> +
> +static ssize_t show_kvm_enable(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> +}
> +
> +static ssize_t __used store_kvm_enable(struct device *dev,
> + struct device_attribute *attr, const char *buf,
> + size_t count)
> +{
> + struct cpumask stop_cpus;
> + unsigned long core, thr;
> +
> + sscanf(buf, "%lx", &core);
> + if (core > NR_CORES)
> + return -1;
> + if (!test_bit(core, &kvm_on_core))
> + for (thr = 1; thr< threads_per_core; thr++)
> + if (cpu_online(thr * threads_per_core + thr))
> + cpumask_set_cpu(thr * threads_per_core + thr, &stop_cpus);
Shouldnt this be
if (cpu_online(core * threads_per_core + thr))
cpumask_set_cpu(core * threads_per_core + thr, &stop_cpus);
?
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* RE: [PATCH] DT: add MDIO node for FMan node
From: Shaohui Xie @ 2014-11-12 13:40 UTC (permalink / raw)
To: Scott Wood
Cc: Igal.Liberman@freescale.com, linuxppc-dev@lists.ozlabs.org,
Emilian Medve, devicetree@vger.kernel.org
In-Reply-To: <1415727479.15957.29.camel@freescale.com>
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0K
PiBTZW50OiBXZWRuZXNkYXksIE5vdmVtYmVyIDEyLCAyMDE0IDE6MzggQU0NCj4gVG86IFhpZSBT
aGFvaHVpLUIyMTk4OQ0KPiBDYzogTGliZXJtYW4gSWdhbC1CMzE5NTA7IGxpbnV4cHBjLWRldkBs
aXN0cy5vemxhYnMub3JnOw0KPiBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsgTWVkdmUgRW1p
bGlhbi1FTU1FRFZFMQ0KPiBTdWJqZWN0OiBSZTogW1BBVENIXSBEVDogYWRkIE1ESU8gbm9kZSBm
b3IgRk1hbiBub2RlDQo+IA0KPiBPbiBUdWUsIDIwMTQtMTEtMTEgYXQgMDQ6MzIgLTA2MDAsIFhp
ZSBTaGFvaHVpLUIyMTk4OSB3cm90ZToNCj4gPiA+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0t
DQo+ID4gPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0KPiA+ID4gU2VudDogVHVlc2RheSwgTm92
ZW1iZXIgMTEsIDIwMTQgODoyMyBBTQ0KPiA+ID4gVG86IHNoaC54aWVAZ21haWwuY29tDQo+ID4g
PiBDYzogbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IGRldmljZXRyZWVAdmdlci5rZXJu
ZWwub3JnOyBNZWR2ZQ0KPiA+ID4gRW1pbGlhbi1FTU1FRFZFMTsgWGllIFNoYW9odWktQjIxOTg5
DQo+ID4gPiBTdWJqZWN0OiBSZTogW1BBVENIXSBEVDogYWRkIE1ESU8gbm9kZSBmb3IgRk1hbiBu
b2RlDQo+ID4gPg0KPiA+ID4gT24gVHVlLCAyMDE0LTExLTA0IGF0IDE5OjU2ICswODAwLCBzaGgu
eGllQGdtYWlsLmNvbSB3cm90ZToNCj4gPiA+ID4gRnJvbTogU2hhb2h1aSBYaWUgPFNoYW9odWku
WGllQGZyZWVzY2FsZS5jb20+DQo+ID4gPiA+DQo+ID4gPiA+IFRoaXMgYmluZGluZyBpcyBmb3Ig
Rk1hbiBNRElPLCBpdCBjb3ZlcnMgRk1hbiB2MiAmIEZNYW4gdjMuDQo+ID4gPiA+DQo+ID4gPiA+
IFNpZ25lZC1vZmYtYnk6IFNoYW9odWkgWGllIDxTaGFvaHVpLlhpZUBmcmVlc2NhbGUuY29tPg0K
PiA+ID4gPiAtLS0NCj4gPiA+ID4gYmFzZWQgb24gaHR0cDovL3BhdGNod29yay5vemxhYnMub3Jn
L3BhdGNoLzM5MDM1MS8NCj4gPiA+ID4gZm9yICduZXh0JyBvZg0KPiA+ID4gPiBnaXQ6Ly9naXQu
a2VybmVsLm9yZy9wdWIvc2NtL2xpbnV4L2tlcm5lbC9naXQvc2NvdHR3b29kL2xpbnV4LmdpdA0K
PiA+ID4NCj4gPiA+IEFyZSB0aGVyZSBhbnkgb3RoZXIgRk1hbiBwaWVjZXMgdGhhdCBhcmUgbWlz
c2luZyBmcm9tIHRoZSBhYm92ZSBwYXRjaD8NCj4gPiBbUy5IXSBJJ20gYWRkaW5nIElnYWwgZm9y
IHRoaXMgY29tbWVudC4NCj4gPg0KPiA+ID4NCj4gPiA+ID4gKy0gYnVzLWZyZXF1ZW5jeQ0KPiA+
ID4gPiArCQlVc2FnZTogb3B0aW9uYWwNCj4gPiA+ID4gKwkJVmFsdWUgdHlwZTogPHUzMj4NCj4g
PiA+ID4gKwkJRGVmaW5pdGlvbjogRGVmYXVsdCBNRElPIGJ1cyBjbG9jayBzcGVlZC4NCj4gPiA+
DQo+ID4gPiBVc2UgY2xvY2tzL2Nsb2NrLW5hbWVzDQo+ID4gW1MuSF0gVGhlIE1ESU8gdXNlcyBG
bWFuIGNsb2NrIGFuZCBkaXZpZGVzIGl0IHRvIGEgcHJvcGVyIHZhbHVlIHdoaWNoDQo+IGlzIHNw
ZWNpZmllZCBieSB0aGlzIHByb3BlcnR5Lg0KPiANCj4gVXNlIGNsb2Nrcy9jbG9jay1uYW1lcyB0
byBkZXNjcmliZSB0aGF0IHJlbGF0aW9uc2hpcC4NCj4gDQpbUy5IXSBUaGUgTURJTyBub2RlIGlz
IHN1Yi1ub2RlIGFuZCBlbWJlZGRlZCBpbiBGbWFuIG5vZGUsIHRoZSBjbG9ja3MvY2xvY2stbmFt
ZXMgaXMgcHJvdmlkZWQgYnkgRm1hbiBub2RlLCBzaG91bGQgcmVwZWF0IHRoZW0gaW4gTURJTyBu
b2RlPyBGb3IgdGhlIGRlZmF1bHQgTURJTyBidXMgY2xvY2sgc3BlZWQsIG1heWJlICJjbG9jay1y
YW5nZXMiIHNob3VsZCBiZSB1c2VkPw0KDQo+ID4gPg0KPiA+ID4gPiArLSBpbnRlcnJ1cHRzDQo+
ID4gPiA+ICsJCVVzYWdlOiBvcHRpb25hbA0KPiA+ID4gPiArCQlWYWx1ZSB0eXBlOiA8cHJvcC1l
bmNvZGVkLWFycmF5Pg0KPiA+ID4gPiArCQlEZWZpbml0aW9uOiBNRElPIGNvbnRyb2xsZXIgZXZl
bnQgaW50ZXJydXB0cy4NCj4gPiA+DQo+ID4gPiBPbmUgaW50ZXJydXB0IG9yIG11bHRpcGxlPw0K
PiA+IFtTLkhdIE9uZSBmb3IgMSBHYi9zLCBvbmUgZm9yIDEwIEdiL3MuDQo+IA0KPiBUaGVuIHRo
ZSBiaW5kaW5nIG5lZWRzIHRvIHNheSB0aGF0IHRoZXJlIGFyZSB0d28gKGV4Y2VwdCBmb3IgImZz
bCxmbWFuLQ0KPiBtZGlvIiwgcmlnaHQ/KSBhbmQgd2hpY2ggaXMgd2hpY2guDQo+IA0KW1MuSF0g
T0suDQoNCj4gPiA+DQo+ID4gPiA+ICsNCj4gPiA+ID4gKy0gdHlwZQ0KPiA+ID4gPiArCQlVc2Fn
ZTogcmVxdWlyZWQgZm9yIEZNYW4gdjMNCj4gPiA+ID4gKwkJVmFsdWUgdHlwZTogPHN0cmluZ2xp
c3Q+DQo+ID4gPiA+ICsJCURlZmluaXRpb246IEEgc3RhbmRhcmQgcHJvcGVydHkuDQo+ID4gPg0K
PiA+ID4gV2hhdCBzdGFuZGFyZCBpcyAidHlwZSIgZGVmaW5lZCBpbj8NCj4gPg0KPiA+IFtTLkhd
IEl0J3MgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIHRoZSBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwg
TURJTywNCj4gPiBJJ20gbm90IHF1aXRlIHN1cmUgYWJvdXQgbmFtaW5nIGl0LCBvciB3aGF0IGNv
dWxkIGJlIGJldHRlciB3YXkgdG8NCj4gPiBkaWZmZXJlbnRpYXRlIHRoZSBNRElPcz8NCj4gDQo+
IEknbSBub3QgcXVlc3Rpb25pbmcgdGhlIG5lZWQgdG8gY29udmV5IHRoaXMgaW5mb3JtYXRpb24u
ICBJJ20gc2F5aW5nIGl0J3MNCj4gbm90ICJBIHN0YW5kYXJkIHByb3BlcnR5Ii4gIEknZCBhbHNv
IGxpa2UgdG8gc2VlIGEgYmV0dGVyIG5hbWUuDQo+IA0KW1MuSF0gc2luY2UgRm1hbiBWMiAmIFYz
IGNhbiBiZSBkaWZmZXJlbnRpYXRlZCBieSBjb21wYXRpYmxlLCBhIGJvb2xlYW4gcHJvcGVydHkg
ImZzbCxmbWFuLWludGVybmFsLW1kaW8iIHNlZW1zIGJldHRlciwgaWYgZGVmaW5lZCwgaXQgaW5k
aWNhdGVzIGFuIGludGVybmFsIE1ESU8uIEl0IGxvb2tzIGxpa2UgYmVsb3c6DQoNCmZzbCxmbWFu
LWludGVybmFsLW1kaW8NCgkJVXNhZ2U6IHJlcXVpcmVkIGZvciBpbnRlcm5hbCBNRElPDQoJCVZh
bHVlIHR5cGU6IEJvb2xlYW4NCgkJRGVmaW5pdGlvbjogRm1hbiBoYXMgaW50ZXJuYWwgTURJTyBm
b3IgaW50ZXJuYWwgUENTKFBoeXNpY2FsDQoJCUNvZGluZyBTdWJsYXllcikgUEhZcyBhbmQgZXh0
ZXJuYWwgTURJTyBmb3IgZXh0ZXJuYWwgUEhZcy4NCgkJVGhlIHNldHRpbmdzIGFuZCBwcm9ncmFt
bWluZyByb3V0aW5lcyBmb3IgaW50ZXJuYWwvZXh0ZXJuYWwNCgkJTURJTyBhcmUgZGlmZmVyZW50
LiBNdXN0IGJlIGluY2x1ZGVkIGZvciBpbnRlcm5hbCBNRElPLg0KDQpIb3cgYWJvdXQgdGhpcz8N
Cg0KVGhhbmtzIQ0KU2hhb2h1aQ0KIA0K
^ permalink raw reply
* Re: [PATCH] of/base: Fix PowerPC address parsing hack
From: Rob Herring @ 2014-11-12 14:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: devicetree@vger.kernel.org, Arnd Bergmann, linuxppc-dev,
linux-kernel@vger.kernel.org, Olof Johansson, Grant Likely
In-Reply-To: <1415771461.5124.33.camel@kernel.crashing.org>
On Tue, Nov 11, 2014 at 11:51 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> We have a historical hack that treats missing ranges properties as the
> equivalent of an empty one. This is needed for ancient PowerMac "bad"
> device-trees, and shouldn't be enabled for any other PowerPC platform,
> otherwise we get some nasty layout of devices in sysfs or even
> duplication when a set of otherwise identically named devices is
> created multiple times under a different parent node with no ranges
> property.
>
> This fix is needed for the PowerNV i2c busses to be exposed properly
> and will fix a number of other embedded cases.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: <stable@vger.kernel.org>
> ---
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index e371825..e37f017 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -7,6 +7,10 @@
> #include <linux/pci_regs.h>
> #include <linux/string.h>
>
> +#ifdef CONFIG_PPC
> +#include <asm/machdep.h>
> +#endif
> +
> /* Max address size we deal with */
> #define OF_MAX_ADDR_CELLS 4
> #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
> @@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> * This code is only enabled on powerpc. --gcl
> */
> ranges = of_get_property(parent, rprop, &rlen);
> -#if !defined(CONFIG_PPC)
> +#if defined(CONFIG_PPC)
> + if (!machine_is(powermac))
Can we use a machine compatible here or something not PPC specific?
Then we can use IS_ENABLED(CONFIG_PPC) instead of ifdefs.
Rob
> +#endif /* defined(CONFIG_PPC) */
> if (ranges == NULL) {
> - pr_err("OF: no ranges; cannot translate\n");
> + pr_debug("OF: no ranges; cannot translate\n");
> return 1;
> }
> -#endif /* !defined(CONFIG_PPC) */
> if (ranges == NULL || rlen == 0) {
> offset = of_read_number(addr, na);
> memset(addr, 0, pna * 4);
>
^ permalink raw reply
* powerpc-405
From: Javier Ignacio Rennola Mata @ 2014-11-12 15:04 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 380 bytes --]
Hi guys
I was following a tutorial to compile my own tools for my powerpc 405
,(Virtex II Pro Processor), I tried it by using crosstool but when Im going
to compile busybox I get some errors so I decided to take this path ,
although I need the patch for powerpc for any of these kernel version
linux.2.6.32.63
linux.3.7.2
found both of them on
https://www.kernel.org/
Thanks
[-- Attachment #2: Type: text/html, Size: 545 bytes --]
^ permalink raw reply
* [PATCH V3] kexec: Add IND_FLAGS macro
From: Geoff Levand @ 2014-11-12 19:29 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: kexec, linuxppc-dev, Eric Biederman, Vivek Goyal, linux-kernel
In-Reply-To: <20141007175248.GG27464@redhat.com>
Add a new kexec preprocessor macro IND_FLAGS, which is the bitwise OR of
all the possible kexec IND_ kimage_entry indirection flags. Having this
macro allows for simplified code in the processing of the kexec
kimage_entry items. Also, remove the local powerpc definition and use
the generic one.
Signed-off-by: Geoff Levand <geoff@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
---
Hi Ben,
Could you give your ack on this, then I'll try to get it
merged with my other kexec patches.
Thanks.
-Geoff
arch/powerpc/kernel/machine_kexec_64.c | 2 --
include/linux/kexec.h | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 879b3aa..75652a32 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -96,8 +96,6 @@ int default_machine_kexec_prepare(struct kimage *image)
return 0;
}
-#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
-
static void copy_segments(unsigned long ind)
{
unsigned long entry;
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 25e039c..b23412c 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -10,6 +10,7 @@
#define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
#define IND_DONE (1 << IND_DONE_BIT)
#define IND_SOURCE (1 << IND_SOURCE_BIT)
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
#if !defined(__ASSEMBLY__)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] of/base: Fix PowerPC address parsing hack
From: Benjamin Herrenschmidt @ 2014-11-12 19:55 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree@vger.kernel.org, Arnd Bergmann, linuxppc-dev,
linux-kernel@vger.kernel.org, Olof Johansson, Grant Likely
In-Reply-To: <CAL_JsqKfBGdpFV_XuE4DEhFrkhN33kOMkiZE_TOnAZDm2qjwMw@mail.gmail.com>
On Wed, 2014-11-12 at 08:39 -0600, Rob Herring wrote:
> On Tue, Nov 11, 2014 at 11:51 PM, Benjamin Herrenschmidt
> <benh@kernel.crashing.org> wrote:
> > We have a historical hack that treats missing ranges properties as the
> > equivalent of an empty one. This is needed for ancient PowerMac "bad"
> > device-trees, and shouldn't be enabled for any other PowerPC platform,
> > otherwise we get some nasty layout of devices in sysfs or even
> > duplication when a set of otherwise identically named devices is
> > created multiple times under a different parent node with no ranges
> > property.
> >
> > This fix is needed for the PowerNV i2c busses to be exposed properly
> > and will fix a number of other embedded cases.
> >
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > CC: <stable@vger.kernel.org>
> > ---
> >
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > index e371825..e37f017 100644
> > --- a/drivers/of/address.c
> > +++ b/drivers/of/address.c
> > @@ -7,6 +7,10 @@
> > #include <linux/pci_regs.h>
> > #include <linux/string.h>
> >
> > +#ifdef CONFIG_PPC
> > +#include <asm/machdep.h>
> > +#endif
> > +
> > /* Max address size we deal with */
> > #define OF_MAX_ADDR_CELLS 4
> > #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
> > @@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> > * This code is only enabled on powerpc. --gcl
> > */
> > ranges = of_get_property(parent, rprop, &rlen);
> > -#if !defined(CONFIG_PPC)
> > +#if defined(CONFIG_PPC)
> > + if (!machine_is(powermac))
>
> Can we use a machine compatible here or something not PPC specific?
> Then we can use IS_ENABLED(CONFIG_PPC) instead of ifdefs.
We could, we'd have to use a pair of machine compatible, I'll spin a new
patch later today.
Ben.
> Rob
>
> > +#endif /* defined(CONFIG_PPC) */
> > if (ranges == NULL) {
> > - pr_err("OF: no ranges; cannot translate\n");
> > + pr_debug("OF: no ranges; cannot translate\n");
> > return 1;
> > }
> > -#endif /* !defined(CONFIG_PPC) */
> > if (ranges == NULL || rlen == 0) {
> > offset = of_read_number(addr, na);
> > memset(addr, 0, pna * 4);
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH] of/base: Fix PowerPC address parsing hack
From: Grant Likely @ 2014-11-12 17:02 UTC (permalink / raw)
To: Rob Herring, Benjamin Herrenschmidt
Cc: Olof Johansson, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Arnd Bergmann, linuxppc-dev
In-Reply-To: <CAL_JsqKfBGdpFV_XuE4DEhFrkhN33kOMkiZE_TOnAZDm2qjwMw@mail.gmail.com>
On Wed, 12 Nov 2014 08:39:32 -0600
, Rob Herring <robherring2@gmail.com>
wrote:
> On Tue, Nov 11, 2014 at 11:51 PM, Benjamin Herrenschmidt
> <benh@kernel.crashing.org> wrote:
> > We have a historical hack that treats missing ranges properties as the
> > equivalent of an empty one. This is needed for ancient PowerMac "bad"
> > device-trees, and shouldn't be enabled for any other PowerPC platform,
> > otherwise we get some nasty layout of devices in sysfs or even
> > duplication when a set of otherwise identically named devices is
> > created multiple times under a different parent node with no ranges
> > property.
> >
> > This fix is needed for the PowerNV i2c busses to be exposed properly
> > and will fix a number of other embedded cases.
> >
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > CC: <stable@vger.kernel.org>
> > ---
> >
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > index e371825..e37f017 100644
> > --- a/drivers/of/address.c
> > +++ b/drivers/of/address.c
> > @@ -7,6 +7,10 @@
> > #include <linux/pci_regs.h>
> > #include <linux/string.h>
> >
> > +#ifdef CONFIG_PPC
> > +#include <asm/machdep.h>
> > +#endif
> > +
> > /* Max address size we deal with */
> > #define OF_MAX_ADDR_CELLS 4
> > #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
> > @@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> > * This code is only enabled on powerpc. --gcl
> > */
> > ranges = of_get_property(parent, rprop, &rlen);
> > -#if !defined(CONFIG_PPC)
> > +#if defined(CONFIG_PPC)
> > + if (!machine_is(powermac))
>
> Can we use a machine compatible here or something not PPC specific?
> Then we can use IS_ENABLED(CONFIG_PPC) instead of ifdefs.
Yeah, that's kind of nasty!
g.
^ permalink raw reply
* Re: [PATCH] of/base: Fix PowerPC address parsing hack
From: Stephen Rothwell @ 2014-11-12 22:10 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: devicetree@vger.kernel.org, Arnd Bergmann, linuxppc-dev,
linux-kernel@vger.kernel.org, Olof Johansson, Rob Herring,
Grant Likely
In-Reply-To: <1415771461.5124.33.camel@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 1473 bytes --]
Hi Ben,
Urk! :-)
How about:
On Wed, 12 Nov 2014 16:51:01 +1100 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index e371825..e37f017 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -7,6 +7,10 @@
> #include <linux/pci_regs.h>
> #include <linux/string.h>
>
> +#ifdef CONFIG_PPC
> +#include <asm/machdep.h>
#define IS_PMAC machine_is(pmac)
#else
#define IS_PMAC (0)
> +#endif
> +
> /* Max address size we deal with */
> #define OF_MAX_ADDR_CELLS 4
> #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
> @@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> * This code is only enabled on powerpc. --gcl
> */
> ranges = of_get_property(parent, rprop, &rlen);
> -#if !defined(CONFIG_PPC)
> +#if defined(CONFIG_PPC)
> + if (!machine_is(powermac))
> +#endif /* defined(CONFIG_PPC) */
> if (ranges == NULL) {
if ((!IS_PMAC) && (ranges == NULL)) {
> - pr_err("OF: no ranges; cannot translate\n");
> + pr_debug("OF: no ranges; cannot translate\n");
> return 1;
> }
> -#endif /* !defined(CONFIG_PPC) */
> if (ranges == NULL || rlen == 0) {
> offset = of_read_number(addr, na);
> memset(addr, 0, pna * 4);
There might be a better identifier than IS_PMAC ...
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH V3] kexec: Add IND_FLAGS macro
From: Benjamin Herrenschmidt @ 2014-11-12 23:06 UTC (permalink / raw)
To: Geoff Levand
Cc: kexec, linuxppc-dev, Eric Biederman, Vivek Goyal, linux-kernel
In-Reply-To: <1415820588.15847.6.camel@smoke>
On Wed, 2014-11-12 at 11:29 -0800, Geoff Levand wrote:
> Add a new kexec preprocessor macro IND_FLAGS, which is the bitwise OR of
> all the possible kexec IND_ kimage_entry indirection flags. Having this
> macro allows for simplified code in the processing of the kexec
> kimage_entry items. Also, remove the local powerpc definition and use
> the generic one.
>
> Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Acked-by: Vivek Goyal <vgoyal@redhat.com>
> ---
> Hi Ben,
>
> Could you give your ack on this, then I'll try to get it
> merged with my other kexec patches.
>
> Thanks.
>
> -Geoff
>
> arch/powerpc/kernel/machine_kexec_64.c | 2 --
> include/linux/kexec.h | 1 +
> 2 files changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
> index 879b3aa..75652a32 100644
> --- a/arch/powerpc/kernel/machine_kexec_64.c
> +++ b/arch/powerpc/kernel/machine_kexec_64.c
> @@ -96,8 +96,6 @@ int default_machine_kexec_prepare(struct kimage *image)
> return 0;
> }
>
> -#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
> -
> static void copy_segments(unsigned long ind)
> {
> unsigned long entry;
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 25e039c..b23412c 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -10,6 +10,7 @@
> #define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
> #define IND_DONE (1 << IND_DONE_BIT)
> #define IND_SOURCE (1 << IND_SOURCE_BIT)
> +#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
>
> #if !defined(__ASSEMBLY__)
>
^ permalink raw reply
* Re: [PATCH] of/base: Fix PowerPC address parsing hack
From: Benjamin Herrenschmidt @ 2014-11-12 23:08 UTC (permalink / raw)
To: Stephen Rothwell
Cc: devicetree@vger.kernel.org, Arnd Bergmann, linuxppc-dev,
linux-kernel@vger.kernel.org, Olof Johansson, Rob Herring,
Grant Likely
In-Reply-To: <20141113091036.4e9ec43d@canb.auug.org.au>
On Thu, 2014-11-13 at 09:10 +1100, Stephen Rothwell wrote:
> Hi Ben,
>
> Urk! :-)
>
> How about:
>
> On Wed, 12 Nov 2014 16:51:01 +1100 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> >
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > index e371825..e37f017 100644
> > --- a/drivers/of/address.c
> > +++ b/drivers/of/address.c
> > @@ -7,6 +7,10 @@
> > #include <linux/pci_regs.h>
> > #include <linux/string.h>
> >
> > +#ifdef CONFIG_PPC
> > +#include <asm/machdep.h>
>
> #define IS_PMAC machine_is(pmac)
> #else
> #define IS_PMAC (0)
I'll just do an of machine compatible check instead, so there's no ifdef
at all, I'll send a new patch later today.
> > +#endif
> > +
> > /* Max address size we deal with */
> > #define OF_MAX_ADDR_CELLS 4
> > #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
> > @@ -428,12 +432,13 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> > * This code is only enabled on powerpc. --gcl
> > */
> > ranges = of_get_property(parent, rprop, &rlen);
> > -#if !defined(CONFIG_PPC)
> > +#if defined(CONFIG_PPC)
> > + if (!machine_is(powermac))
> > +#endif /* defined(CONFIG_PPC) */
> > if (ranges == NULL) {
>
> if ((!IS_PMAC) && (ranges == NULL)) {
>
> > - pr_err("OF: no ranges; cannot translate\n");
> > + pr_debug("OF: no ranges; cannot translate\n");
> > return 1;
> > }
> > -#endif /* !defined(CONFIG_PPC) */
> > if (ranges == NULL || rlen == 0) {
> > offset = of_read_number(addr, na);
> > memset(addr, 0, pna * 4);
>
> There might be a better identifier than IS_PMAC ...
>
^ permalink raw reply
* [PATCH V3 3/4] kexec: Add bit definitions for kimage entry flags
From: Geoff Levand @ 2014-11-13 0:19 UTC (permalink / raw)
To: Andrew Morton
Cc: linuxppc-dev, kexec, Eric Biederman, Vivek Goyal, linux-kernel
In-Reply-To: <cover.1415837218.git.geoff@infradead.org>
Define new kexec preprocessor macros IND_*_BIT that define the bit position of
the kimage entry flags. Change the existing IND_* flag macros to be defined as
bit shifts of the corresponding IND_*_BIT macros. Also wrap all C language code
in kexec.h with #if !defined(__ASSEMBLY__) so assembly files can include kexec.h
to get the IND_* and IND_*_BIT macros.
Some CPU instruction sets have tests for bit position which are convenient in
implementing routines that operate on the kimage entry list. The addition of
these bit position macros in a common location will avoid duplicate definitions
and the chance that changes to the IND_* flags will not be propagated to
assembly files.
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
---
include/linux/kexec.h | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 9d957b7..25e039c 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -1,6 +1,18 @@
#ifndef LINUX_KEXEC_H
#define LINUX_KEXEC_H
+#define IND_DESTINATION_BIT 0
+#define IND_INDIRECTION_BIT 1
+#define IND_DONE_BIT 2
+#define IND_SOURCE_BIT 3
+
+#define IND_DESTINATION (1 << IND_DESTINATION_BIT)
+#define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
+#define IND_DONE (1 << IND_DONE_BIT)
+#define IND_SOURCE (1 << IND_SOURCE_BIT)
+
+#if !defined(__ASSEMBLY__)
+
#include <uapi/linux/kexec.h>
#ifdef CONFIG_KEXEC
@@ -64,10 +76,6 @@
*/
typedef unsigned long kimage_entry_t;
-#define IND_DESTINATION 0x1
-#define IND_INDIRECTION 0x2
-#define IND_DONE 0x4
-#define IND_SOURCE 0x8
struct kexec_segment {
/*
@@ -313,4 +321,7 @@ struct task_struct;
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
#endif /* CONFIG_KEXEC */
+
+#endif /* !defined(__ASSEBMLY__) */
+
#endif /* LINUX_KEXEC_H */
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox