* powerpc/powernv: Framework to log critical errors on powernv.
From: Deepthi Dharwar @ 2013-12-12 11:25 UTC (permalink / raw)
To: PowerPC email list, Benjamin Herrenschmidt
powerpc/powernv: Framework to log critical errors on powernv.
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
This patch provides error logging interfaces to report critical
powernv error logs to FSP.
All the required information to dump the error is collected
at POWERNV level through error log interfaces
and then pushed on to FSP.
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/opal.h | 125 ++++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-elog.c | 59 +++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 1
3 files changed, 184 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index be404ea..b8d1dd4 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -134,6 +134,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
#define OPAL_ELOG_ACK 73
#define OPAL_ELOG_RESEND 74
#define OPAL_ELOG_SIZE 75
+#define OPAL_ELOG_SEND 87
#ifndef __ASSEMBLY__
@@ -216,6 +217,122 @@ enum OpalPendingState {
OPAL_EVENT_PCI_ERROR = 0x200
};
+/* Classification of Error/Events reporting type classification
+ * Platform Events/Errors: Report Machine Check Interrupt
+ * INPUT_OUTPUT: Report all I/O related events/errors
+ * RESOURCE_DEALLOC: Hotplug events and errors
+ * MISC: Miscellanous error
+ * Field: error_events_type
+ */
+enum Error_Events {
+ OPAL_PLATFORM,
+ OPAL_INPUT_OUTPUT,
+ OPAL_RESOURCE_DEALLOC,
+ OPAL_MISC,
+};
+
+/* OPAL Subsystem IDs listed for reporting events/errors
+ * Field: subsystem_id
+ */
+
+#define OPAL_PROCESSOR_SUBSYSTEM 0x10
+#define OPAL_MEMORY_SUBSYSTEM 0x20
+#define OPAL_IO_SUBSYSTEM 0x30
+#define OPAL_IO_DEVICES 0x40
+#define OPAL_CEC_HARDWARE 0x50
+#define OPAL_POWER_COOLING 0x60
+#define OPAL_MISC_SUBSYSTEM 0x70
+#define OPAL_SURVEILLANCE_ERR 0x7A
+#define OPAL_PLATFORM_FIRMWARE 0x80
+#define OPAL_SOFTWARE 0x90
+#define OPAL_EXTERNAL_ENV 0xA0
+
+/* During reporting an event/error the following represents
+ * how serious the logged event/error is. (Severity)
+ * Field: event_sev
+ */
+#define OPAL_INFO 0x00
+#define OPAL_RECOVERED_ERR_GENERAL 0x10
+
+/* 0x2X series is to denote set of Predictive Error
+ * 0x20 Generic predictive error
+ * 0x21 Predictive error, degraded performance
+ * 0x22 Predictive error, fault may be corrected after reboot
+ * 0x23 Predictive error, fault may be corrected after reboot,
+ * degraded performance
+ * 0x24 Predictive error, loss of redundancy
+ */
+#define OPAL_PREDICTIVE_ERR_GENERAL 0x20
+#define OPAL_PREDICTIVE_ERR_DEGRADED_PERF 0x21
+#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT 0x22
+#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_BOOT_DEGRADE_PERF 0x23
+#define OPAL_PREDICTIVE_ERR_LOSS_OF_REDUNDANCY 0x24
+
+/* 0x4X series for Unrecoverable Error
+ * 0x40 Generic Unrecoverable error
+ * 0x41 Unrecoverable error bypassed with degraded performance
+ * 0x44 Unrecoverable error bypassed with loss of redundancy
+ * 0x45 Unrecoverable error bypassed with loss of redundancy and performance
+ * 0x48 Unrecoverable error bypassed with loss of function
+ */
+#define OPAL_UNRECOVERABLE_ERR_GENERAL 0x40
+#define OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF 0x41
+#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY 0x44
+#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY_PERF 0x45
+#define OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION 0x48
+
+/* Event Sub-type
+ * This field provides additional information on the non-error
+ * event type
+ * Field: event_subtype
+ */
+#define OPAL_NA 0x00
+#define OPAL_MISCELLANEOUS_INFO_ONLY 0x01
+#define OPAL_PREV_REPORTED_ERR_RECTIFIED 0x10
+#define OPAL_SYS_RESOURCES_DECONFIG_BY_USER 0x20
+#define OPAL_SYS_RESOURCE_DECONFIG_PRIOR_ERR 0x21
+#define OPAL_RESOURCE_DEALLOC_EVENT_NOTIFY 0x22
+#define OPAL_CONCURRENT_MAINTENANCE_EVENT 0x40
+#define OPAL_CAPACITY_UPGRADE_EVENT 0x60
+#define OPAL_RESOURCE_SPARING_EVENT 0x70
+#define OPAL_DYNAMIC_RECONFIG_EVENT 0x80
+#define OPAL_NORMAL_SYS_PLATFORM_SHUTDOWN 0xD0
+#define OPAL_ABNORMAL_POWER_OFF 0xE0
+
+/* Max user dump size is 14K */
+#define OPAL_LOG_MAX_DUMP 14336
+
+/* Multiple user data sections */
+struct opal_usr_data_scn {
+ uint32_t tag;
+ uint16_t size;
+ uint16_t component_id;
+ char data_dump[4];
+};
+
+
+/* All the information regarding an error/event to be reported
+ * needs to populate this structure using pre-defined interfaces
+ * only
+ */
+struct opal_errorlog {
+
+ uint16_t component_id;
+ uint8_t error_events_type:3;
+ uint8_t subsystem_id;
+
+ uint8_t event_sev;
+ uint8_t event_subtype;
+ uint8_t usr_scn_count; /* User section count */
+ uint8_t elog_origin;
+
+ uint32_t usr_scn_size; /* User section size */
+ uint32_t reason_code;
+ uint32_t additional_info[4];
+
+ char usr_data_dump[OPAL_LOG_MAX_DUMP];
+};
+
/* Machine check related definitions */
enum OpalMCE_Version {
OpalMCE_V1 = 1,
@@ -667,6 +784,14 @@ int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
int64_t opal_send_ack_elog(uint64_t log_id);
void opal_resend_pending_logs(void);
+struct opal_errorlog *elog_create(uint8_t err_evt_type, uint16_t component_id,
+ uint8_t subsystem_id, uint8_t event_sev, uint8_t event_subtype,
+ uint32_t reason_code, uint32_t info0, uint32_t info1,
+ uint32_t info2, uint32_t info3);
+int update_user_dump(struct opal_errorlog *buf, unsigned char *data,
+ uint32_t tag, uint16_t size);
+void commit_errorlog_to_fsp(struct opal_errorlog *buf);
+int opal_commit_log_to_fsp(void *buf);
/* 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-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 58849d0..af8d385 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -16,13 +16,15 @@
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/fcntl.h>
+#include <linux/mm.h>
#include <asm/uaccess.h>
#include <asm/opal.h>
/* Maximum size of a single log on FSP is 16KB */
#define OPAL_MAX_ERRLOG_SIZE 16384
+#define USR_CHAR_ARRAY_FIXED_SIZE 4
-/* maximu number of records powernv can hold */
+/* maximum number of records powernv can hold */
#define MAX_NUM_RECORD 128
struct opal_err_log {
@@ -272,6 +274,61 @@ static int init_err_log_buffer(void)
return 0;
}
+/* Interface to be used by POWERNV to push the logs to FSP via Sapphire */
+struct opal_errorlog *elog_create(uint8_t err_evt_type, uint16_t component_id,
+ uint8_t subsystem_id, uint8_t event_sev, uint8_t event_subtype,
+ uint32_t reason_code, uint32_t info0, uint32_t info1,
+ uint32_t info2, uint32_t info3)
+{
+ struct opal_errorlog *buf;
+
+ buf = kzalloc(sizeof(struct opal_errorlog), GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "ELOG: failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+
+ buf->error_events_type = err_evt_type;
+ buf->component_id = component_id;
+ buf->subsystem_id = subsystem_id;
+ buf->event_sev = event_sev;
+ buf->event_subtype = event_subtype;
+ buf->reason_code = reason_code;
+ buf->additional_info[0] = info0;
+ buf->additional_info[1] = info1;
+ buf->additional_info[2] = info2;
+ buf->additional_info[3] = info3;
+ return buf;
+}
+
+int update_user_dump(struct opal_errorlog *buf, unsigned char *data,
+ uint32_t tag, uint16_t size)
+{
+ char *buffer = (char *)buf->usr_data_dump + buf->usr_scn_size;
+ struct opal_usr_data_scn *tmp;
+
+ if ((buf->usr_scn_size + size) > OPAL_LOG_MAX_DUMP) {
+ printk(KERN_ERR "ELOG: Size of dump data overruns buffer");
+ return -1;
+ }
+
+ tmp = (struct opal_usr_data_scn *)buffer;
+ tmp->tag = tag;
+ tmp->size = size + sizeof(struct opal_usr_data_scn)
+ - USR_CHAR_ARRAY_FIXED_SIZE;
+ memcpy(tmp->data_dump, data, size);
+
+ buf->usr_scn_size += tmp->size;
+ buf->usr_scn_count++;
+ return 0;
+}
+
+void commit_errorlog_to_fsp(struct opal_errorlog *buf)
+{
+ opal_commit_log_to_fsp((void *)(vmalloc_to_pfn(buf) << PAGE_SHIFT));
+ kfree(buf);
+}
+
/* Initialize error logging */
static int __init opal_elog_init(void)
{
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 66def92..f0c5178 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -121,3 +121,4 @@ OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK);
OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE);
OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND);
OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE);
+OPAL_CALL(opal_commit_log_to_fsp, OPAL_ELOG_SEND);
^ permalink raw reply related
* [RFC][PATCH v1] ASoC: fsl_ssi: Add DAI master mode support for SSI on i.MX series
From: Nicolin Chen @ 2013-12-12 10:44 UTC (permalink / raw)
To: broonie, timur; +Cc: tiwai, alsa-devel, linuxppc-dev, lgirdwood, perex
From: Nicolin Chen <b42378@freescale.com>
This patch adds three main functions for DAI master mode: set_dai_fmt(),
set_dai_sysclk() and set_dai_tdm_slot(), and one essential baud clock
accordingly. After appending this patch, the fsl_ssi driver on i.MX series
has the ability to derive LRCLK and BCLK from baud clock source so as to
support some audio Codecs which can only be used in slave mode.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
sound/soc/fsl/fsl_ssi.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++-
sound/soc/fsl/fsl_ssi.h | 2 +
2 files changed, 278 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f9f4569..b2ebaf8 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -38,6 +38,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
@@ -139,7 +140,10 @@ struct fsl_ssi_private {
bool ssi_on_imx;
bool imx_ac97;
bool use_dma;
+ bool baudclk_locked;
u8 i2s_mode;
+ spinlock_t baudclk_lock;
+ struct clk *baudclk;
struct clk *clk;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -434,13 +438,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi_private *ssi_private =
snd_soc_dai_get_drvdata(rtd->cpu_dai);
+ unsigned long flags;
/* First, we only do fsl_ssi_setup() when SSI is going to be active.
* Second, fsl_ssi_setup was already called by ac97_init earlier if
* the driver is in ac97 mode.
*/
- if (!dai->active && !ssi_private->imx_ac97)
+ if (!dai->active && !ssi_private->imx_ac97) {
fsl_ssi_setup(ssi_private);
+ spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
+ ssi_private->baudclk_locked = false;
+ spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+ }
return 0;
}
@@ -502,6 +511,243 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
}
/**
+ * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format.
+ */
+static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+ struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
+ struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+ u32 strcr = 0, stcr, srcr, scr, mask;
+
+ scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
+ scr |= CCSR_SSI_SCR_NET;
+
+ mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
+ CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
+ CCSR_SSI_STCR_TEFS;
+ stcr = read_ssi(&ssi->stcr) & ~mask;
+ srcr = read_ssi(&ssi->srcr) & ~mask;
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ scr |= ssi_private->i2s_mode;
+
+ /* Data on rising edge of bclk, frame low, 1clk before data */
+ strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP |
+ CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ /* Data on rising edge of bclk, frame high */
+ strcr |= CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TSCKP;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ /* Data on rising edge of bclk, frame high, 1clk before data */
+ strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
+ CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ /* Data on rising edge of bclk, frame high */
+ strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
+ CCSR_SSI_STCR_TXBIT0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* DAI clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ /* Nothing to do for both normal cases */
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ /* Invert bit clock */
+ strcr ^= CCSR_SSI_STCR_TSCKP;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ /* Invert frame clock */
+ strcr ^= CCSR_SSI_STCR_TFSI;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ /* Invert both clocks */
+ strcr ^= CCSR_SSI_STCR_TSCKP;
+ strcr ^= CCSR_SSI_STCR_TFSI;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* DAI clock master masks */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ strcr |= CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR;
+ scr |= CCSR_SSI_SCR_SYS_CLK_EN;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ scr &= ~CCSR_SSI_SCR_SYS_CLK_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ stcr |= strcr;
+ srcr |= strcr;
+
+ if (ssi_private->cpu_dai_drv.symmetric_rates) {
+ /* Need to clear RXDIR when using SYNC mode */
+ srcr &= ~CCSR_SSI_SRCR_RXDIR;
+ scr |= CCSR_SSI_SCR_SYN;
+ }
+
+ write_ssi(stcr, &ssi->stcr);
+ write_ssi(srcr, &ssi->srcr);
+ write_ssi(scr, &ssi->scr);
+
+ return 0;
+}
+
+/**
+ * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock
+ *
+ * Note: This function can be only called when using SSI as DAI master
+ *
+ * Quick instruction for parameters:
+ * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels
+ * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK.
+ */
+static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
+ struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+ int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret;
+ u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
+ unsigned long flags, clkrate, baudrate, tmprate;
+ u64 sub, savesub = 100000;
+
+ /* Don't apply it to any non-baudclk circumstance */
+ if (IS_ERR(ssi_private->baudclk))
+ return -EINVAL;
+
+ /* It should be already enough to divide clock by setting pm alone */
+ psr = 0;
+ div2 = 0;
+
+ factor = (div2 + 1) * (7 * psr + 1) * 2;
+
+ for (i = 0; i < 255; i++) {
+ /* The bclk rate must be smaller than 1/5 sysclk rate */
+ if (factor * (i + 1) < 5)
+ continue;
+
+ tmprate = freq * factor * (i + 2);
+ clkrate = clk_round_rate(ssi_private->baudclk, tmprate);
+
+ do_div(clkrate, factor);
+ afreq = (u32)clkrate / (i + 1);
+
+ if (freq == afreq)
+ sub = 0;
+ else if (freq / afreq == 1)
+ sub = freq - afreq;
+ else if (afreq / freq == 1)
+ sub = afreq - freq;
+ else
+ continue;
+
+ /* Calculate the fraction */
+ sub *= 100000;
+ do_div(sub, freq);
+
+ if (sub < savesub) {
+ baudrate = tmprate;
+ savesub = sub;
+ pm = i;
+ }
+
+ /* We are lucky */
+ if (savesub == 0)
+ break;
+ }
+
+ /* No proper pm found if it is still remaining the initial value */
+ if (pm == 999) {
+ dev_err(cpu_dai->dev, "failed to handle the required sysclk\n");
+ return -EINVAL;
+ }
+
+ stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) |
+ (psr ? CCSR_SSI_SxCCR_PSR : 0);
+ mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR;
+
+ if (dir == SND_SOC_CLOCK_OUT || synchronous)
+ write_ssi_mask(&ssi->stccr, mask, stccr);
+ else
+ write_ssi_mask(&ssi->srccr, mask, stccr);
+
+ spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
+ if (!ssi_private->baudclk_locked) {
+ ret = clk_set_rate(ssi_private->baudclk, baudrate);
+ if (ret) {
+ spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+ dev_err(cpu_dai->dev, "failed to set baudclk rate\n");
+ return -EINVAL;
+ }
+ ssi_private->baudclk_locked = true;
+ }
+ spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+
+ return 0;
+}
+
+/**
+ * fsl_ssi_set_dai_tdm_slot - set TDM slot number
+ *
+ * Note: This function can be only called when using SSI as DAI master
+ */
+static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
+ u32 rx_mask, int slots, int slot_width)
+{
+ struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
+ struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+ u32 val;
+
+ /* The slot number should be >= 2 if using Network mode or I2S mode */
+ val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET);
+ if (val && slots < 2) {
+ dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n");
+ return -EINVAL;
+ }
+
+ write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
+ CCSR_SSI_SxCCR_DC(slots));
+ write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
+ CCSR_SSI_SxCCR_DC(slots));
+
+ /* The register SxMSKs needs SSI to provide essential clock due to
+ * hardware design. So we here temporarily enable SSI to set them.
+ */
+ val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
+ write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
+
+ write_ssi(tx_mask, &ssi->stmsk);
+ write_ssi(rx_mask, &ssi->srmsk);
+
+ write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val);
+
+ return 0;
+}
+
+/**
* fsl_ssi_trigger: start and stop the DMA transfer.
*
* This function is called by ALSA to start, stop, pause, and resume the DMA
@@ -517,6 +763,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
unsigned int sier_bits;
+ unsigned long flags;
/*
* Enable only the interrupts and DMA requests
@@ -557,8 +804,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
- (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
+ (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
+ spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
+ ssi_private->baudclk_locked = false;
+ spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
+ }
break;
default:
@@ -585,6 +836,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
.startup = fsl_ssi_startup,
.hw_params = fsl_ssi_hw_params,
+ .set_fmt = fsl_ssi_set_dai_fmt,
+ .set_sysclk = fsl_ssi_set_dai_sysclk,
+ .set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
.trigger = fsl_ssi_trigger,
};
@@ -897,6 +1151,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
/* Older 8610 DTs didn't have the fifo-depth property */
ssi_private->fifo_depth = 8;
+ ssi_private->baudclk_locked = false;
+ spin_lock_init(&ssi_private->baudclk_lock);
+
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
u32 dma_events[2];
ssi_private->ssi_on_imx = true;
@@ -914,6 +1171,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
goto error_irqmap;
}
+ /* For those SLAVE implementations, we ingore non-baudclk cases
+ * and, instead, abandon MASTER mode that needs baud clock.
+ */
+ ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
+ if (IS_ERR(ssi_private->baudclk))
+ dev_warn(&pdev->dev, "could not get baud clock: %d\n", ret);
+ else
+ clk_prepare_enable(ssi_private->baudclk);
+
/*
* We have burstsize be "fifo_depth - 2" to match the SSI
* watermark setting in fsl_ssi_startup().
@@ -1059,8 +1325,11 @@ error_dev:
device_remove_file(&pdev->dev, dev_attr);
error_clk:
- if (ssi_private->ssi_on_imx)
+ if (ssi_private->ssi_on_imx) {
+ if (!IS_ERR(ssi_private->baudclk))
+ clk_disable_unprepare(ssi_private->baudclk);
clk_disable_unprepare(ssi_private->clk);
+ }
error_irqmap:
irq_dispose_mapping(ssi_private->irq);
@@ -1076,8 +1345,11 @@ static int fsl_ssi_remove(struct platform_device *pdev)
platform_device_unregister(ssi_private->pdev);
snd_soc_unregister_component(&pdev->dev);
device_remove_file(&pdev->dev, &ssi_private->dev_attr);
- if (ssi_private->ssi_on_imx)
+ if (ssi_private->ssi_on_imx) {
+ if (!IS_ERR(ssi_private->baudclk))
+ clk_disable_unprepare(ssi_private->baudclk);
clk_disable_unprepare(ssi_private->clk);
+ }
irq_dispose_mapping(ssi_private->irq);
return 0;
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index e6b9a69..e6b6324 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -125,7 +125,9 @@ struct ccsr_ssi {
#define CCSR_SSI_SRCR_REFS 0x00000001
/* STCCR and SRCCR */
+#define CCSR_SSI_SxCCR_DIV2_SHIFT 18
#define CCSR_SSI_SxCCR_DIV2 0x00040000
+#define CCSR_SSI_SxCCR_PSR_SHIFT 17
#define CCSR_SSI_SxCCR_PSR 0x00020000
#define CCSR_SSI_SxCCR_WL_SHIFT 13
#define CCSR_SSI_SxCCR_WL_MASK 0x0001E000
--
1.8.4
^ permalink raw reply related
* Re: [PATCH 1/5] powerpc/85xx/dts: add third elo3 dma component
From: Hongbo Zhang @ 2013-12-12 9:57 UTC (permalink / raw)
To: Shengzhou Liu, linuxppc-dev, scottwood
In-Reply-To: <1386760774-14743-1-git-send-email-Shengzhou.Liu@freescale.com>
Shengzhou,
I canceled my patch http://patchwork.ozlabs.org/patch/295157/ because
the original wrong elo3-dma-2.dtsi hadn't been merged.
But please pay attention to comments from Scott about my changes of
adding 208 for some interrupts, and take some actions if needed, or
further discussions.
Below comments form Scott:
"The FSL MPIC binding should be updated to point out how this works.
Technically it's not a change to the binding itself, since it's defined
in terms of register offset, but the explanatory text says "So interrupt
0 is at offset 0x0, interrupt 1 is at offset 0x20, and so on." which is
not accurate for these new high interrupt numbers."
On 12/11/2013 07:19 PM, Shengzhou Liu wrote:
> Add elo3-dma-2.dtsi to support the third DMA controller.
> This is used on T2080, T4240, etc.
>
> MPIC registers for internal interrupts is non-continous in address, any
> internal interrupt number greater than 159 should be added (16+208) to work,
> adding 16 is due to external interrupts as usual, adding 208 is due to
> non-continous MPIC register space.
>
> Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
> Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
> ---
> arch/powerpc/boot/dts/fsl/elo3-dma-2.dtsi | 82 +++++++++++++++++++++++++++++++
> 1 file changed, 82 insertions(+)
> create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-2.dtsi
>
> diff --git a/arch/powerpc/boot/dts/fsl/elo3-dma-2.dtsi b/arch/powerpc/boot/dts/fsl/elo3-dma-2.dtsi
> new file mode 100644
> index 0000000..d3cc8d0
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/fsl/elo3-dma-2.dtsi
> @@ -0,0 +1,82 @@
> +/*
> + * QorIQ Elo3 DMA device tree stub [ controller @ offset 0x102300 ]
> + *
> + * Copyright 2013 Freescale Semiconductor Inc.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are met:
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the distribution.
> + * * Neither the name of Freescale Semiconductor nor the
> + * names of its contributors may be used to endorse or promote products
> + * derived from this software without specific prior written permission.
> + *
> + *
> + * ALTERNATIVELY, this software may be distributed under the terms of the
> + * GNU General Public License ("GPL") as published by the Free Software
> + * Foundation, either version 2 of that License or (at your option) any
> + * later version.
> + *
> + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +dma2: dma@102300 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "fsl,elo3-dma";
> + reg = <0x102300 0x4>,
> + <0x102600 0x4>;
> + ranges = <0x0 0x102100 0x500>;
> + dma-channel@0 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x0 0x80>;
> + interrupts = <464 2 0 0>;
> + };
> + dma-channel@80 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x80 0x80>;
> + interrupts = <465 2 0 0>;
> + };
> + dma-channel@100 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x100 0x80>;
> + interrupts = <466 2 0 0>;
> + };
> + dma-channel@180 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x180 0x80>;
> + interrupts = <467 2 0 0>;
> + };
> + dma-channel@300 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x300 0x80>;
> + interrupts = <468 2 0 0>;
> + };
> + dma-channel@380 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x380 0x80>;
> + interrupts = <469 2 0 0>;
> + };
> + dma-channel@400 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x400 0x80>;
> + interrupts = <470 2 0 0>;
> + };
> + dma-channel@480 {
> + compatible = "fsl,eloplus-dma-channel";
> + reg = <0x480 0x80>;
> + interrupts = <471 2 0 0>;
> + };
> +};
^ permalink raw reply
* Re: [PATCH] DTS: DMA: Fix DMA3 interrupts
From: Hongbo Zhang @ 2013-12-12 9:46 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1386700403.10013.109.camel@snotra.buserror.net>
On 12/11/2013 02:33 AM, Scott Wood wrote:
> On Tue, 2013-12-10 at 18:33 +0800, Hongbo Zhang wrote:
>> Scott,
>> This issue is due to the non-continuous MPIC register, I think there is
>> two ways to fix it.
>>
>> The first one is as what we are discussing, in fact the Bman/Qman DT
>> author had introduced this way, and I had to follow it, it is a trick,
>> adding 208 is a bit ugly I think, and even difficult to explain it to
>> customers etc, but this way changes less codes.
>>
>> The second one is editing MPIC related codes without adding 208 to high
>> interrupts. The point of translate interrupt number to MPIC register
>> address is a so called 'isu' mechanism, we can do like the following
>> example codes, then the tricky adding 208 isn't needed any more.
>>
>> Which one do you prefer?
>> In fact I myself prefer the second, if the idea is acceptable, I will
>> send a patch instead of this one. (and also alone with the internal
>> patch decreasing 208 for the Bman/Qman)
>>
>> void __init corenet_ds_pic_init(void)
>> {
>> ......
>>
>> mpic = mpic_alloc(NULL, 0, flags, 0, 512, "OpenPIC");
>> BUG_ON(mpic == NULL);
>>
>> // Add this start
>> for (i = 0; i < 17; i++) {
>> if (i < 11)
>> addr_off = 0x10000 + 0x20 * 16 * i;
>> else
>> addr_off = 0x13000 + 0x20 * 16 * (i - 11); /* scape the
>> address not for interrupts */
>> mpic_assign_isu(mpic, i, mpic->paddr + addr_off);
>> }
>> // Add this end
>>
>> mpic_init(mpic);
>> }
> NACK
>
> We already have a binding that states that the interrupt number is based
> on the register offset, rather than whatever arbitrary numbers hardware
> documenters decide to use next week.
>
> While I'm not terribly happy with the usability of this, especially now
> that it's not a simple "add 16", redefining the existing binding is not
> OK (and in any case the code above seems obfuscatory). If we decide to
> do something other than continue with register offset divided by 32,
> then we need to define a new interrupt type (similar to current defined
> types of error interrupt, timer, and IPI) for the new numberspace -- and
> it should be handled when decoding that type of interrupt specifier,
> rather than with the isu mechanism.
>
> -Scott
>
>
Scott,
Thanks for your comments. Since the second way isn't so good, let's
choose the original one.
But we meet a small accident now.
My patch is based on the http://patchwork.ozlabs.org/patch/291553/,
which had been superseded, so this thread can be closed now.
And Shenzhou has already sent a complete dma3 dtsi patch including
correct interrupt numbers, http://patchwork.ozlabs.org/patch/300026/, so
let's focus on this patch, and I will forward your first comments of my
patch there.
Thanks.
^ permalink raw reply
* Re: [PATCH V4 08/10] powerpc, perf: Enable SW filtering in branch stack sampling framework
From: Anshuman Khandual @ 2013-12-12 8:45 UTC (permalink / raw)
To: Michael Ellerman
Cc: mikey, ak, linux-kernel, eranian, linuxppc-dev, acme, sukadev,
mingo
In-Reply-To: <52A6AD61.4050408@linux.vnet.ibm.com>
On 12/10/2013 11:27 AM, Anshuman Khandual wrote:
> On 12/09/2013 11:51 AM, Michael Ellerman wrote:
>> This code was already in need of some unindentation, and now it's just
>> ridiculous.
>>
>> To start with at the beginning of this routine we have:
>>
>> while (..) {
>> if (!val)
>> break;
>> else {
>> // Bulk of the logic
>> ...
>> }
>> }
>>
>> That should almost always become:
>>
>> while (..) {
>> if (!val)
>> break;
>>
>> // Bulk of the logic
>> ...
>> }
>>
>>
>> But in this case that's not enough. Please send a precursor patch which moves
>> this logic out into a helper function.
>
> Hey Michael,
>
> I believe this patch should be able to take care of this.
>
> commit d66d729715cabe0cfd8e34861a6afa8ad639ddf3
> Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> Date: Tue Dec 10 11:10:06 2013 +0530
>
> power, perf: Clean up BHRB processing
>
> This patch cleans up some indentation problem and re-organizes the
> BHRB processing code with an additional helper function.
>
> Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
>
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index 29b89e8..9ae96c5 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -400,11 +400,20 @@ static __u64 power_pmu_bhrb_to(u64 addr)
> return target - (unsigned long)&instr + addr;
> }
>
> +void update_branch_entry(struct cpu_hw_events *cpuhw, int u_index, u64 from, u64 to, int pred)
> +{
> + cpuhw->bhrb_entries[u_index].from = from;
> + cpuhw->bhrb_entries[u_index].to = to;
> + cpuhw->bhrb_entries[u_index].mispred = pred;
> + cpuhw->bhrb_entries[u_index].predicted = ~pred;
> + return;
> +}
> +
> /* Processing BHRB entries */
> void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
> {
> u64 val;
> - u64 addr;
> + u64 addr, tmp;
> int r_index, u_index, pred;
>
> r_index = 0;
> @@ -415,62 +424,54 @@ void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
> if (!val)
> /* Terminal marker: End of valid BHRB entries */
> break;
> - else {
> - addr = val & BHRB_EA;
> - pred = val & BHRB_PREDICTION;
>
> - if (!addr)
> - /* invalid entry */
> - continue;
> + addr = val & BHRB_EA;
> + pred = val & BHRB_PREDICTION;
>
> - /* Branches are read most recent first (ie. mfbhrb 0 is
> - * the most recent branch).
> - * There are two types of valid entries:
> - * 1) a target entry which is the to address of a
> - * computed goto like a blr,bctr,btar. The next
> - * entry read from the bhrb will be branch
> - * corresponding to this target (ie. the actual
> - * blr/bctr/btar instruction).
> - * 2) a from address which is an actual branch. If a
> - * target entry proceeds this, then this is the
> - * matching branch for that target. If this is not
> - * following a target entry, then this is a branch
> - * where the target is given as an immediate field
> - * in the instruction (ie. an i or b form branch).
> - * In this case we need to read the instruction from
> - * memory to determine the target/to address.
> + if (!addr)
> + /* invalid entry */
> + continue;
> +
> + /* Branches are read most recent first (ie. mfbhrb 0 is
> + * the most recent branch).
> + * There are two types of valid entries:
> + * 1) a target entry which is the to address of a
> + * computed goto like a blr,bctr,btar. The next
> + * entry read from the bhrb will be branch
> + * corresponding to this target (ie. the actual
> + * blr/bctr/btar instruction).
> + * 2) a from address which is an actual branch. If a
> + * target entry proceeds this, then this is the
> + * matching branch for that target. If this is not
> + * following a target entry, then this is a branch
> + * where the target is given as an immediate field
> + * in the instruction (ie. an i or b form branch).
> + * In this case we need to read the instruction from
> + * memory to determine the target/to address.
> + */
> + if (val & BHRB_TARGET) {
> + /* Target branches use two entries
> + * (ie. computed gotos/XL form)
> */
> + tmp = addr;
>
> + /* Get from address in next entry */
> + val = read_bhrb(r_index++);
> + addr = val & BHRB_EA;
> if (val & BHRB_TARGET) {
> - /* Target branches use two entries
> - * (ie. computed gotos/XL form)
> - */
> - cpuhw->bhrb_entries[u_index].to = addr;
> - cpuhw->bhrb_entries[u_index].mispred = pred;
> - cpuhw->bhrb_entries[u_index].predicted = ~pred;
> -
> - /* Get from address in next entry */
> - val = read_bhrb(r_index++);
> - addr = val & BHRB_EA;
> - if (val & BHRB_TARGET) {
> - /* Shouldn't have two targets in a
> - row.. Reset index and try again */
> - r_index--;
> - addr = 0;
> - }
> - cpuhw->bhrb_entries[u_index].from = addr;
> - } else {
> - /* Branches to immediate field
> - (ie I or B form) */
> - cpuhw->bhrb_entries[u_index].from = addr;
> - cpuhw->bhrb_entries[u_index].to =
> - power_pmu_bhrb_to(addr);
> - cpuhw->bhrb_entries[u_index].mispred = pred;
> - cpuhw->bhrb_entries[u_index].predicted = ~pred;
> + /* Shouldn't have two targets in a
> + row.. Reset index and try again */
> + r_index--;
> + addr = 0;
> }
> - u_index++;
> -
> + update_branch_entry(cpuhw, u_index, addr, tmp, pred);
> + } else {
> + /* Branches to immediate field
> + (ie I or B form) */
> + tmp = power_pmu_bhrb_to(addr);
> + update_branch_entry(cpuhw, u_index, addr, tmp, pred);
> }
> + u_index++;
> }
> cpuhw->bhrb_stack.nr = u_index;
> return;
Hey Michael,
Does the patch looks okay ? In which case will send it out separately. Do let
me know. Thank you.
Regards
Anshuman
^ permalink raw reply
* [PATCH v11] PPC: POWERNV: move iommu_add_device earlier
From: Alexey Kardashevskiy @ 2013-12-12 7:54 UTC (permalink / raw)
To: linuxppc-dev
Cc: Alexey Kardashevskiy, Alex Graf, Bharat Bhushan, linux-kernel
The current implementation of IOMMU on sPAPR does not use iommu_ops
and therefore does not call IOMMU API's bus_set_iommu() which
1) sets iommu_ops for a bus
2) registers a bus notifier
Instead, PCI devices are added to IOMMU groups from
subsys_initcall_sync(tce_iommu_init) which does basically the same
thing without using iommu_ops callbacks.
However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158)
implements iommu_ops and when tce_iommu_init is called, every PCI device
is already added to some group so there is a conflict.
This patch does 2 things:
1. removes the loop in which PCI devices were added to groups and
adds explicit iommu_add_device() calls to add devices as soon as they get
the iommu_table pointer assigned to them.
2. moves a bus notifier to powernv code in order to avoid conflict with
the notifier from Freescale driver.
iommu_add_device() and iommu_del_device() are public now.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v11:
* rebased on upstream
v10:
* fixed linker error when IOMMU_API is not enabled
v9:
* removed "KVM" from the subject as it is not really a KVM patch so
PPC mainainter (hi Ben!) can review/include it into his tree
v8:
* added the check for iommu_group!=NULL before removing device from a group
as suggested by Wei Yang <weiyang@linux.vnet.ibm.com>
v2:
* added a helper - set_iommu_table_base_and_group - which does
set_iommu_table_base() and iommu_add_device()
---
arch/powerpc/include/asm/iommu.h | 26 ++++++++++++++++++++++++
arch/powerpc/kernel/iommu.c | 11 ++++------
arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++----
arch/powerpc/platforms/powernv/pci-p5ioc2.c | 2 +-
arch/powerpc/platforms/powernv/pci.c | 31 ++++++++++++++++++++++++++++-
arch/powerpc/platforms/pseries/iommu.c | 8 +++++---
6 files changed, 70 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index c34656a..774fa27 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -101,8 +101,34 @@ extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
*/
extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
int nid);
+#ifdef CONFIG_IOMMU_API
extern void iommu_register_group(struct iommu_table *tbl,
int pci_domain_number, unsigned long pe_num);
+extern int iommu_add_device(struct device *dev);
+extern void iommu_del_device(struct device *dev);
+#else
+static inline void iommu_register_group(struct iommu_table *tbl,
+ int pci_domain_number,
+ unsigned long pe_num)
+{
+}
+
+static inline int iommu_add_device(struct device *dev)
+{
+ return 0;
+}
+
+static inline void iommu_del_device(struct device *dev)
+{
+}
+#endif /* !CONFIG_IOMMU_API */
+
+static inline void set_iommu_table_base_and_group(struct device *dev,
+ void *base)
+{
+ set_iommu_table_base(dev, base);
+ iommu_add_device(dev);
+}
extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
struct scatterlist *sglist, int nelems,
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 572bb5b..818a092 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1105,7 +1105,7 @@ void iommu_release_ownership(struct iommu_table *tbl)
}
EXPORT_SYMBOL_GPL(iommu_release_ownership);
-static int iommu_add_device(struct device *dev)
+int iommu_add_device(struct device *dev)
{
struct iommu_table *tbl;
int ret = 0;
@@ -1134,11 +1134,13 @@ static int iommu_add_device(struct device *dev)
return ret;
}
+EXPORT_SYMBOL_GPL(iommu_add_device);
-static void iommu_del_device(struct device *dev)
+void iommu_del_device(struct device *dev)
{
iommu_group_remove_device(dev);
}
+EXPORT_SYMBOL_GPL(iommu_del_device);
static int iommu_bus_notifier(struct notifier_block *nb,
unsigned long action, void *data)
@@ -1162,13 +1164,8 @@ static struct notifier_block tce_iommu_bus_nb = {
static int __init tce_iommu_init(void)
{
- struct pci_dev *pdev = NULL;
-
BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
- for_each_pci_dev(pdev)
- iommu_add_device(&pdev->dev);
-
bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
return 0;
}
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2c6d173..f0e6871 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -460,7 +460,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
return;
pe = &phb->ioda.pe_array[pdn->pe_number];
- set_iommu_table_base(&pdev->dev, &pe->tce32_table);
+ set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table);
}
static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
@@ -468,7 +468,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
- set_iommu_table_base(&dev->dev, &pe->tce32_table);
+ set_iommu_table_base_and_group(&dev->dev, &pe->tce32_table);
if (dev->subordinate)
pnv_ioda_setup_bus_dma(pe, dev->subordinate);
}
@@ -644,7 +644,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number);
if (pe->pdev)
- set_iommu_table_base(&pe->pdev->dev, tbl);
+ set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
else
pnv_ioda_setup_bus_dma(pe, pe->pbus);
@@ -723,7 +723,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number);
if (pe->pdev)
- set_iommu_table_base(&pe->pdev->dev, tbl);
+ set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
else
pnv_ioda_setup_bus_dma(pe, pe->pbus);
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index f8b4bd8..e3807d6 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -92,7 +92,7 @@ static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
pci_domain_nr(phb->hose->bus), phb->opal_id);
}
- set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table);
+ set_iommu_table_base_and_group(&pdev->dev, &phb->p5ioc2.iommu_table);
}
static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 4eb33a9..a78abad 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -536,7 +536,7 @@ static void pnv_pci_dma_fallback_setup(struct pci_controller *hose,
pdn->iommu_table = pnv_pci_setup_bml_iommu(hose);
if (!pdn->iommu_table)
return;
- set_iommu_table_base(&pdev->dev, pdn->iommu_table);
+ set_iommu_table_base_and_group(&pdev->dev, pdn->iommu_table);
}
static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
@@ -657,3 +657,32 @@ void __init pnv_pci_init(void)
ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
#endif
}
+
+static int tce_iommu_bus_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ return iommu_add_device(dev);
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (dev->iommu_group)
+ iommu_del_device(dev);
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static struct notifier_block tce_iommu_bus_nb = {
+ .notifier_call = tce_iommu_bus_notifier,
+};
+
+static int __init tce_iommu_bus_notifier_init(void)
+{
+ bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
+ return 0;
+}
+
+subsys_initcall_sync(tce_iommu_bus_notifier_init);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index f253361..a80af6c 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -687,7 +687,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
iommu_table_setparms(phb, dn, tbl);
PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
iommu_register_group(tbl, pci_domain_nr(phb->bus), 0);
- set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
+ set_iommu_table_base_and_group(&dev->dev,
+ PCI_DN(dn)->iommu_table);
return;
}
@@ -699,7 +700,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
dn = dn->parent;
if (dn && PCI_DN(dn))
- set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
+ set_iommu_table_base_and_group(&dev->dev,
+ PCI_DN(dn)->iommu_table);
else
printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
pci_name(dev));
@@ -1193,7 +1195,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
pr_debug(" found DMA window, table: %p\n", pci->iommu_table);
}
- set_iommu_table_base(&dev->dev, pci->iommu_table);
+ set_iommu_table_base_and_group(&dev->dev, pci->iommu_table);
}
static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
--
1.8.4.rc4
^ permalink raw reply related
* Re: [PATCH] powerpc: set default kernel thread priority to medium-low
From: Philippe Bergheaud @ 2013-12-12 7:11 UTC (permalink / raw)
To: Michael Ellerman; +Cc: Linuxppc-dev
In-Reply-To: <1386811338.12662.3.camel@concordia>
Michael Ellerman wrote:
> On Wed, 2013-12-11 at 11:30 +0100, Philippe Bergheaud wrote:
>
>>Benjamin Herrenschmidt wrote:
>>
>>>On Wed, 2013-12-11 at 17:29 +1100, Michael Ellerman wrote:
>>>
>>>
>>>
>>>>It would be nice if you could make an assertion about what the state of HMT
>>>>handling should be once your patch is applied.
>>>>
>>>>I think it's:
>>>>
>>>>* The kernel should use HMT_MEDIUM_LOW as it's "default" priority
>>>>* The kernel should use HMT_LOW as it's "low" priority
>>>>
>>>>Which would imply:
>>>>
>>>>* The kernel should not use HMT_MEDIUM anywhere ..
>>>>* Nor should it use any of the other higher HMT modes.
>>>>
>>>>Do you agree?
>
>
>>Not entirely. HT_MEDIUM might still be used by the kernel, in places where a
>>priority higher than the default is required.
>
>
> Right. But any code that currently uses HMT_MEDIUM is at the default level,
> whereas once your patch is applied any code still using HMT_MEDIUM will be
> boosted vs the default.
>
> So any code that still uses HMT_MEDIUM after your patch seems like a bug to me.
>
>
>>>>The reason I ask is I still see HMT_MEDIUM used in a few places, and it's not
>>>>clear to me if that is correct.
>>>
>>>
>>>HMT_MEDIUM used to be our default no ?
>
>
>>Yes, but I am not sure that all references to HMT_MEDIUM were references to
>>the default kernel priority.
>
>
> What were they references to? Regardless they will now have the effect of
> boosting the priority in those code sections. It would be good to understand,
> and document, any places where we still use HMT_MEDIUM and why.
Yes. This needs to be documented.
>
>>>Also there's an open question... when doing things with interrupts off
>>>(or worse, in real mode) such as some KVM hcalls etc... should we on the
>>>contrary boost up to limit interrupt latency ?
>
>
>>Yes. I think that there are cases when one should consider using HT_MEDIUM.
>
>
> Or HIGH?
Correct, I had not thought of that option.
> But let's not get side-tracked on that until we've got the default sorted.
>
>
>>Shouldn't we define a new macro HMT_DEFAULT, to identify explicitely where
>>the default priority is required?
>
>
> That might help clarify things yes.
>
> cheers
>
Thank you for the help. I will rework this.
Philippe
^ permalink raw reply
* [PATCH v2] mtd: m25p80: Add Power Management support
From: Hou Zhiqiang @ 2013-12-12 5:38 UTC (permalink / raw)
To: linux-mtd, linuxppc-dev; +Cc: scottwood, Mingkai.Hu, Hou Zhiqiang, dwmw2
Add PM support using callback function suspend and resume in
.driver.pm of spi_driver.
Signed-off-by: Hou Zhiqiang <b48286@freescale.com>
---
v2:
- Replace .driver.suspend and .driver.resume with .driver.pm
- Use CONFIG_PM_SLEEP instead of CONFIG_PM
drivers/mtd/devices/m25p80.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7eda71d..eb558e8 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -66,6 +66,8 @@
/* Used for Spansion flashes only. */
#define OPCODE_BRWR 0x17 /* Bank register write */
+#define OPCODE_DP 0xb9 /* Enter deep power down mode */
+#define OPCODE_RES 0xab /* Exit deep power down mode */
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
@@ -1128,11 +1130,46 @@ static int m25p_remove(struct spi_device *spi)
return mtd_device_unregister(&flash->mtd);
}
+#ifdef CONFIG_PM_SLEEP
+static int m25p_suspend(struct device *dev)
+{
+ struct m25p *flash = dev_get_drvdata(dev);
+ int ret;
+
+ flash->command[0] = OPCODE_DP;
+ mutex_lock(&flash->lock);
+ /* Wait until finished previous write/erase command. */
+ ret = wait_till_ready(flash);
+ if (ret) {
+ mutex_unlock(&flash->lock);
+ return ret;
+ }
+ ret = spi_write(flash->spi, flash->command, 1);
+ mutex_unlock(&flash->lock);
+
+ return ret;
+}
+
+static int m25p_resume(struct device *dev)
+{
+ struct m25p *flash = dev_get_drvdata(dev);
+ int ret;
+
+ flash->command[0] = OPCODE_RES;
+
+ return spi_write(flash->spi, flash->command, 1);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops m25p_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(m25p_suspend, m25p_resume)
+};
static struct spi_driver m25p80_driver = {
.driver = {
.name = "m25p80",
.owner = THIS_MODULE,
+ .pm = &m25p_pm,
},
.id_table = m25p_ids,
.probe = m25p_probe,
--
1.8.4.1
^ permalink raw reply related
* [PATCH v2] spi/fsl-espi: Add Power Management support for eSPI controller
From: Hou Zhiqiang @ 2013-12-12 4:53 UTC (permalink / raw)
To: linux-spi, linuxppc-dev; +Cc: scottwood, Mingkai.Hu, broonie, Hou Zhiqiang
Add PM support for eSPI controller using callback function suspend
and resume in .driver.pm of platform_driver.
Signed-off-by: Hou Zhiqiang <b48286@freescale.com>
---
v2:
- Replace .driver.suspend and .driver.resume with .driver.pm
- Use CONFIG_PM_SLEEP instead of CONFIG_PM
- Add spi_master_suspend and spi_master_resume
drivers/spi/spi-fsl-espi.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 8106006..428dc7a 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -727,6 +727,66 @@ static int of_fsl_espi_remove(struct platform_device *dev)
return mpc8xxx_spi_remove(&dev->dev);
}
+#ifdef CONFIG_PM_SLEEP
+static int of_fsl_espi_suspend(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct mpc8xxx_spi *mpc8xxx_spi;
+ struct fsl_espi_reg *reg_base;
+ u32 regval;
+ int ret;
+
+ mpc8xxx_spi = spi_master_get_devdata(master);
+ reg_base = mpc8xxx_spi->reg_base;
+
+ ret = spi_master_suspend(master);
+ if (ret) {
+ dev_warn(dev, "cannot suspend master\n");
+ return ret;
+ }
+
+ regval = mpc8xxx_spi_read_reg(®_base->mode);
+ regval &= ~SPMODE_ENABLE;
+ mpc8xxx_spi_write_reg(®_base->mode, regval);
+
+ return 0;
+}
+
+static int of_fsl_espi_resume(struct device *dev)
+{
+ struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct mpc8xxx_spi *mpc8xxx_spi;
+ struct fsl_espi_reg *reg_base;
+ u32 regval;
+ int i;
+
+ mpc8xxx_spi = spi_master_get_devdata(master);
+ reg_base = mpc8xxx_spi->reg_base;
+
+ /* SPI controller initializations */
+ mpc8xxx_spi_write_reg(®_base->mode, 0);
+ mpc8xxx_spi_write_reg(®_base->mask, 0);
+ mpc8xxx_spi_write_reg(®_base->command, 0);
+ mpc8xxx_spi_write_reg(®_base->event, 0xffffffff);
+
+ /* Init eSPI CS mode register */
+ for (i = 0; i < pdata->max_chipselect; i++)
+ mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL);
+
+ /* Enable SPI interface */
+ regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
+
+ mpc8xxx_spi_write_reg(®_base->mode, regval);
+
+ return spi_master_resume(master);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops espi_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(of_fsl_espi_suspend, of_fsl_espi_resume)
+};
+
static const struct of_device_id of_fsl_espi_match[] = {
{ .compatible = "fsl,mpc8536-espi" },
{}
@@ -738,6 +798,7 @@ static struct platform_driver fsl_espi_driver = {
.name = "fsl_espi",
.owner = THIS_MODULE,
.of_match_table = of_fsl_espi_match,
+ .pm = &espi_pm,
},
.probe = of_fsl_espi_probe,
.remove = of_fsl_espi_remove,
--
1.8.4.1
^ permalink raw reply related
* Re: [PATCH 0/4] Minor fixes and improvements for kexec
From: Simon Horman @ 2013-12-12 5:11 UTC (permalink / raw)
To: Geoff Levand
Cc: linux-sh, kexec, Paul Mundt, Paul Mackerras, Eric Biederman,
linuxppc-dev
In-Reply-To: <cover.1386807069.git.geoff@infradead.org>
On Thu, Dec 12, 2013 at 12:18:56AM +0000, Geoff Levand wrote:
> Hi Eric,
>
> Here are a few minor fixes and improvements for kexec. Please consider.
FWIW,
Reviewed-by: Simon Horman <horms@verge.net.au>
>
> -Geoff
>
> The following changes since commit 374b105797c3d4f29c685f3be535c35f5689b30e:
>
> Linux 3.13-rc3 (2013-12-06 09:34:04 -0800)
>
> are available in the git repository at:
>
> git://git.linaro.org/people/geoff.levand/linux-kexec.git for-kexec
>
> for you to fetch changes up to 594a3d26aac66e9668edc81d7bfb4e801575514f:
>
> sh/kexec: Fix kexec build warning (2013-12-11 16:03:27 -0800)
>
> ----------------------------------------------------------------
> Geoff Levand (4):
> kexec: Simplify conditional
> kexec: Add IND_FLAGS macro
> powerpc/kexec: Use global IND_FLAGS macro
> sh/kexec: Fix kexec build warning
>
> arch/powerpc/kernel/machine_kexec_64.c | 2 --
> arch/sh/kernel/machine_kexec.c | 2 +-
> include/linux/kexec.h | 1 +
> kernel/kexec.c | 17 ++++++++++-------
> 4 files changed, 12 insertions(+), 10 deletions(-)
>
> --
> 1.8.1.2
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
>
^ permalink raw reply
* [PATCH 8/8] powerpc: Fix endian issues in crash dump code
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
A couple more device tree properties that need byte swapping.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/crash_dump.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 779a78c..11c1d06 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -124,15 +124,15 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
{
unsigned long addr;
- const u32 *basep, *sizep;
+ const __be32 *basep, *sizep;
unsigned int rtas_start = 0, rtas_end = 0;
basep = of_get_property(rtas.dev, "linux,rtas-base", NULL);
sizep = of_get_property(rtas.dev, "rtas-size", NULL);
if (basep && sizep) {
- rtas_start = *basep;
- rtas_end = *basep + *sizep;
+ rtas_start = be32_to_cpup(basep);
+ rtas_end = rtas_start + be32_to_cpup(sizep);
}
for (addr = begin; addr < end; addr += PAGE_SIZE) {
--
1.8.3.2
^ permalink raw reply related
* [PATCH 7/8] powerpc/pseries: Fix endian issues in MSI code
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
The MSI code is miscalculating quotas in little endian mode.
Add required byteswaps to fix this.
Before we claimed a quota of 65536, after the patch we
see the correct value of 256.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/platforms/pseries/msi.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 6d2f0ab..0c882e8 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -130,7 +130,8 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
{
struct device_node *dn;
struct pci_dn *pdn;
- const u32 *req_msi;
+ const __be32 *p;
+ u32 req_msi;
pdn = pci_get_pdn(pdev);
if (!pdn)
@@ -138,19 +139,20 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
dn = pdn->node;
- req_msi = of_get_property(dn, prop_name, NULL);
- if (!req_msi) {
+ p = of_get_property(dn, prop_name, NULL);
+ if (!p) {
pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name);
return -ENOENT;
}
- if (*req_msi < nvec) {
+ req_msi = be32_to_cpup(p);
+ if (req_msi < nvec) {
pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
- if (*req_msi == 0) /* Be paranoid */
+ if (req_msi == 0) /* Be paranoid */
return -ENOSPC;
- return *req_msi;
+ return req_msi;
}
return 0;
@@ -171,7 +173,7 @@ static int check_req_msix(struct pci_dev *pdev, int nvec)
static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
{
struct device_node *dn;
- const u32 *p;
+ const __be32 *p;
dn = of_node_get(pci_device_to_OF_node(dev));
while (dn) {
@@ -179,7 +181,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
if (p) {
pr_debug("rtas_msi: found prop on dn %s\n",
dn->full_name);
- *total = *p;
+ *total = be32_to_cpup(p);
return dn;
}
@@ -232,13 +234,13 @@ struct msi_counts {
static void *count_non_bridge_devices(struct device_node *dn, void *data)
{
struct msi_counts *counts = data;
- const u32 *p;
+ const __be32 *p;
u32 class;
pr_debug("rtas_msi: counting %s\n", dn->full_name);
p = of_get_property(dn, "class-code", NULL);
- class = p ? *p : 0;
+ class = p ? be32_to_cpup(p) : 0;
if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
counts->num_devices++;
@@ -249,7 +251,7 @@ static void *count_non_bridge_devices(struct device_node *dn, void *data)
static void *count_spare_msis(struct device_node *dn, void *data)
{
struct msi_counts *counts = data;
- const u32 *p;
+ const __be32 *p;
int req;
if (dn == counts->requestor)
@@ -260,11 +262,11 @@ static void *count_spare_msis(struct device_node *dn, void *data)
req = 0;
p = of_get_property(dn, "ibm,req#msi", NULL);
if (p)
- req = *p;
+ req = be32_to_cpup(p);
p = of_get_property(dn, "ibm,req#msi-x", NULL);
if (p)
- req = max(req, (int)*p);
+ req = max(req, (int)be32_to_cpup(p));
}
if (req < counts->quota)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 6/8] powerpc/pseries: Fix PCIE link speed endian issue
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
We need to byteswap ibm,pcie-link-speed-stats.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/platforms/pseries/pci.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 5f93856..70670a2 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -113,7 +113,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
{
struct device_node *dn, *pdn;
struct pci_bus *bus;
- const uint32_t *pcie_link_speed_stats;
+ const __be32 *pcie_link_speed_stats;
bus = bridge->bus;
@@ -122,7 +122,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
return 0;
for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) {
- pcie_link_speed_stats = (const uint32_t *) of_get_property(pdn,
+ pcie_link_speed_stats = of_get_property(pdn,
"ibm,pcie-link-speed-stats", NULL);
if (pcie_link_speed_stats)
break;
@@ -135,7 +135,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
return 0;
}
- switch (pcie_link_speed_stats[0]) {
+ switch (be32_to_cpup(pcie_link_speed_stats)) {
case 0x01:
bus->max_bus_speed = PCIE_SPEED_2_5GT;
break;
@@ -147,7 +147,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
break;
}
- switch (pcie_link_speed_stats[1]) {
+ switch (be32_to_cpup(pcie_link_speed_stats)) {
case 0x01:
bus->cur_bus_speed = PCIE_SPEED_2_5GT;
break;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 5/8] powerpc/pseries: Fix endian issues in nvram code
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
The NVRAM code has a number of endian issues. I noticed a very
confused error log count:
RTAS: 100663330 -------- RTAS event begin --------
100663330 == 0x06000022. 0x6 LE error logs and 0x22 BE error logs.
The pstore code has similar issues - if we write an oops in one
endian and attempt to read it in another we get junk.
Make both of these formats big endian, and byteswap as required.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/platforms/pseries/nvram.c | 46 +++++++++++++++++-----------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 7bfaf58..d7096f2 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -43,8 +43,8 @@ static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
static DEFINE_SPINLOCK(nvram_lock);
struct err_log_info {
- int error_type;
- unsigned int seq_num;
+ __be32 error_type;
+ __be32 seq_num;
};
struct nvram_os_partition {
@@ -79,9 +79,9 @@ static const char *pseries_nvram_os_partitions[] = {
};
struct oops_log_info {
- u16 version;
- u16 report_length;
- u64 timestamp;
+ __be16 version;
+ __be16 report_length;
+ __be64 timestamp;
} __attribute__((packed));
static void oops_to_nvram(struct kmsg_dumper *dumper,
@@ -291,8 +291,8 @@ int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
length = part->size;
}
- info.error_type = err_type;
- info.seq_num = error_log_cnt;
+ info.error_type = cpu_to_be32(err_type);
+ info.seq_num = cpu_to_be32(error_log_cnt);
tmp_index = part->index;
@@ -364,8 +364,8 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff,
}
if (part->os_partition) {
- *error_log_cnt = info.seq_num;
- *err_type = info.error_type;
+ *error_log_cnt = be32_to_cpu(info.seq_num);
+ *err_type = be32_to_cpu(info.error_type);
}
return 0;
@@ -529,9 +529,9 @@ static int zip_oops(size_t text_len)
pr_err("nvram: logging uncompressed oops/panic report\n");
return -1;
}
- oops_hdr->version = OOPS_HDR_VERSION;
- oops_hdr->report_length = (u16) zipped_len;
- oops_hdr->timestamp = get_seconds();
+ oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+ oops_hdr->report_length = cpu_to_be16(zipped_len);
+ oops_hdr->timestamp = cpu_to_be64(get_seconds());
return 0;
}
@@ -574,9 +574,9 @@ static int nvram_pstore_write(enum pstore_type_id type,
clobbering_unread_rtas_event())
return -1;
- oops_hdr->version = OOPS_HDR_VERSION;
- oops_hdr->report_length = (u16) size;
- oops_hdr->timestamp = get_seconds();
+ oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+ oops_hdr->report_length = cpu_to_be16(size);
+ oops_hdr->timestamp = cpu_to_be64(get_seconds());
if (compressed)
err_type = ERR_TYPE_KERNEL_PANIC_GZ;
@@ -670,16 +670,16 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
size_t length, hdr_size;
oops_hdr = (struct oops_log_info *)buff;
- if (oops_hdr->version < OOPS_HDR_VERSION) {
+ if (be16_to_cpu(oops_hdr->version) < OOPS_HDR_VERSION) {
/* Old format oops header had 2-byte record size */
hdr_size = sizeof(u16);
- length = oops_hdr->version;
+ length = be16_to_cpu(oops_hdr->version);
time->tv_sec = 0;
time->tv_nsec = 0;
} else {
hdr_size = sizeof(*oops_hdr);
- length = oops_hdr->report_length;
- time->tv_sec = oops_hdr->timestamp;
+ length = be16_to_cpu(oops_hdr->report_length);
+ time->tv_sec = be64_to_cpu(oops_hdr->timestamp);
time->tv_nsec = 0;
}
*buf = kmalloc(length, GFP_KERNEL);
@@ -889,13 +889,13 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
kmsg_dump_get_buffer(dumper, false,
oops_data, oops_data_sz, &text_len);
err_type = ERR_TYPE_KERNEL_PANIC;
- oops_hdr->version = OOPS_HDR_VERSION;
- oops_hdr->report_length = (u16) text_len;
- oops_hdr->timestamp = get_seconds();
+ oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+ oops_hdr->report_length = cpu_to_be16(text_len);
+ oops_hdr->timestamp = cpu_to_be64(get_seconds());
}
(void) nvram_write_os_partition(&oops_log_partition, oops_buf,
- (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
+ (int) (sizeof(*oops_hdr) + text_len), err_type,
++oops_count);
spin_unlock_irqrestore(&lock, flags);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 4/8] powerpc/pseries: Fix endian issues in /proc/ppc64/lparcfg
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
Some obvious issues:
cat /proc/ppc64/lparcfg
...
partition_id=16777216
...
partition_potential_processors=268435456
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/platforms/pseries/lparcfg.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index e738007..c9fecf0 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -157,7 +157,7 @@ static void parse_ppp_data(struct seq_file *m)
{
struct hvcall_ppp_data ppp_data;
struct device_node *root;
- const int *perf_level;
+ const __be32 *perf_level;
int rc;
rc = h_get_ppp(&ppp_data);
@@ -201,7 +201,7 @@ static void parse_ppp_data(struct seq_file *m)
perf_level = of_get_property(root,
"ibm,partition-performance-parameters-level",
NULL);
- if (perf_level && (*perf_level >= 1)) {
+ if (perf_level && (be32_to_cpup(perf_level) >= 1)) {
seq_printf(m,
"physical_procs_allocated_to_virtualization=%d\n",
ppp_data.phys_platform_procs);
@@ -435,7 +435,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
int partition_potential_processors;
int partition_active_processors;
struct device_node *rtas_node;
- const int *lrdrp = NULL;
+ const __be32 *lrdrp = NULL;
rtas_node = of_find_node_by_path("/rtas");
if (rtas_node)
@@ -444,7 +444,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
if (lrdrp == NULL) {
partition_potential_processors = vdso_data->processorCount;
} else {
- partition_potential_processors = *(lrdrp + 4);
+ partition_potential_processors = be32_to_cpup(lrdrp + 4);
}
of_node_put(rtas_node);
@@ -654,7 +654,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
const char *model = "";
const char *system_id = "";
const char *tmp;
- const unsigned int *lp_index_ptr;
+ const __be32 *lp_index_ptr;
unsigned int lp_index = 0;
seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);
@@ -670,7 +670,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
lp_index_ptr = of_get_property(rootdn, "ibm,partition-no",
NULL);
if (lp_index_ptr)
- lp_index = *lp_index_ptr;
+ lp_index = be32_to_cpup(lp_index_ptr);
of_node_put(rootdn);
}
seq_printf(m, "serial_number=%s\n", system_id);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/8] powerpc: Fix topology core_id endian issue on LE builds
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
cpu_to_core_id() is missing a byteswap:
cat /sys/devices/system/cpu/cpu63/topology/core_id
201326592
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/smp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 19d654b..ac2621a 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -575,7 +575,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
int cpu_to_core_id(int cpu)
{
struct device_node *np;
- const int *reg;
+ const __be32 *reg;
int id = -1;
np = of_get_cpu_node(cpu, NULL);
@@ -586,7 +586,7 @@ int cpu_to_core_id(int cpu)
if (!reg)
goto out;
- id = *reg;
+ id = be32_to_cpup(reg);
out:
of_node_put(np);
return id;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/8] powerpc: Fix endian issue in setup-common.c
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
During on LE boot we see:
Partition configured for 1073741824 cpus, operating system maximum is 2048.
Clearly missing a byteswap here.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/setup-common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index febc804..bc76cc6 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -479,7 +479,7 @@ void __init smp_setup_cpu_maps(void)
if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
(dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus;
- const unsigned int *ireg;
+ const __be32 *ireg;
num_addr_cell = of_n_addr_cells(dn);
num_size_cell = of_n_size_cells(dn);
@@ -489,7 +489,7 @@ void __init smp_setup_cpu_maps(void)
if (!ireg)
goto out;
- maxcpus = ireg[num_addr_cell + num_size_cell];
+ maxcpus = be32_to_cpup(ireg + num_addr_cell + num_size_cell);
/* Double maxcpus for processors which have SMT capability */
if (cpu_has_feature(CPU_FTR_SMT))
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/8] powerpc: PTRACE_PEEKUSR always returns FPR0
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
In-Reply-To: <1386824381-14032-1-git-send-email-anton@samba.org>
From: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
There is a bug in using ptrace to access FPRs via PTRACE_PEEKUSR /
PTRACE_POKEUSR. In effect, trying to access any of the FPRs always
really accesses FPR0, which does seriously break debugging :-)
The problem seems to have been introduced by commit 3ad26e5c4459d
(Merge branch 'for-kvm' into next).
[ It is indeed a merge conflict between Paul's FPU/VSX state rework
and my LE patches - Anton ]
Signed-off-by: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/ptrace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 75fb404..2e3d2bf 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1555,7 +1555,7 @@ long arch_ptrace(struct task_struct *child, long request,
flush_fp_to_thread(child);
if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&tmp, &child->thread.fp_state.fpr,
+ memcpy(&tmp, &child->thread.TS_FPR(fpidx),
sizeof(long));
else
tmp = child->thread.fp_state.fpscr;
@@ -1588,7 +1588,7 @@ long arch_ptrace(struct task_struct *child, long request,
flush_fp_to_thread(child);
if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&child->thread.fp_state.fpr, &data,
+ memcpy(&child->thread.TS_FPR(fpidx), &data,
sizeof(long));
else
child->thread.fp_state.fpscr = data;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 0/8] ppc64 little endian bug fixes
From: Anton Blanchard @ 2013-12-12 4:59 UTC (permalink / raw)
To: benh, paulus, Ulrich.Weigand; +Cc: linuxppc-dev
Here are a number of little endian fixes found during testing of
2.6.13-*. Some of the interesting things:
A patch from Uli that fixes a nasty bug in PTRACE_PEEKUSR, basically
we always get FPR0 no matter which one we ask for.
Also included is a fix for the pseries NVRAM code, without it we
corrupt NVRAM and end up with particular hard to fix issues, since
we don't have easy ways to edit the contents of NVRAM.
Fixed other endian issues in crash dump, lparcfg and MSI code.
Anton Blanchard (7):
powerpc: Fix endian issue in setup-common.c
powerpc: Fix topology core_id endian issue on LE builds
powerpc/pseries: Fix endian issues in /proc/ppc64/lparcfg
powerpc/pseries: Fix endian issues in nvram code
powerpc/pseries: Fix PCIE link speed endian issue
powerpc/pseries: Fix endian issues in MSI code
powerpc: Fix endian issues in crash dump code
Ulrich Weigand (1):
powerpc: PTRACE_PEEKUSR always returns FPR0
arch/powerpc/kernel/crash_dump.c | 6 ++---
arch/powerpc/kernel/ptrace.c | 4 +--
arch/powerpc/kernel/setup-common.c | 4 +--
arch/powerpc/kernel/smp.c | 4 +--
arch/powerpc/platforms/pseries/lparcfg.c | 12 ++++-----
arch/powerpc/platforms/pseries/msi.c | 28 ++++++++++---------
arch/powerpc/platforms/pseries/nvram.c | 46 ++++++++++++++++----------------
arch/powerpc/platforms/pseries/pci.c | 8 +++---
8 files changed, 57 insertions(+), 55 deletions(-)
--
1.8.3.2
^ permalink raw reply
* Re: [PATCH 1/3] powerpc: mm: make _PAGE_NUMA take effect
From: Liu ping fan @ 2013-12-12 2:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras, Aneesh Kumar K.V
In-Reply-To: <1386755416.15730.12.camel@pasglop>
On Wed, Dec 11, 2013 at 5:50 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Wed, 2013-12-11 at 16:50 +0800, Liu ping fan wrote:
>> > why ? , All the hash routines do check for _PAGE_PRESENT via access
>> > variable.
>> >
>> Going through __hash_page_4K(4k on 4k HW), I do not find such check.
>> Am I wrong? Or I will send out a patch to fix that.
>
> We pass a bitmask of flags to check which are tested by doing an "andc"
> of the PTE on that mask and checking if anything is left...
>
Oh, see it, thank you very much
Regards,
Pingfan
^ permalink raw reply
* Re: [PATCH 2/4] kexec: Add IND_FLAGS macro
From: Zhang Yanfei @ 2013-12-12 1:35 UTC (permalink / raw)
To: Geoff Levand; +Cc: linuxppc-dev, kexec, Eric Biederman, Paul Mackerras
In-Reply-To: <3d9d024551c3c0e560d77f81926cb5774dda7067.1386807069.git.geoff@infradead.org>
Hello
On 12/12/2013 08:18 AM, 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 prosessing of the
> kexec kimage_entry items.
Where? I didn't see any place you use this macro to help simplification.
Thanks
Zhang
>
> Signed-off-by: Geoff Levand <geoff@infradead.org> for Huawei, Linaro
> ---
> include/linux/kexec.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index d78d28a..f755ec3 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -67,6 +67,7 @@ typedef unsigned long kimage_entry_t;
> #define IND_INDIRECTION 0x2
> #define IND_DONE 0x4
> #define IND_SOURCE 0x8
> +#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
>
> struct kexec_segment {
> void __user *buf;
>
--
Thanks.
Zhang Yanfei
^ permalink raw reply
* Re: [PATCH] powerpc: set default kernel thread priority to medium-low
From: Michael Ellerman @ 2013-12-12 1:22 UTC (permalink / raw)
To: Philippe Bergheaud; +Cc: Linuxppc-dev
In-Reply-To: <52A83EBE.4060305@linux.vnet.ibm.com>
On Wed, 2013-12-11 at 11:30 +0100, Philippe Bergheaud wrote:
> Benjamin Herrenschmidt wrote:
> > On Wed, 2013-12-11 at 17:29 +1100, Michael Ellerman wrote:
> >
> >
> >>It would be nice if you could make an assertion about what the state of HMT
> >>handling should be once your patch is applied.
> >>
> >>I think it's:
> >>
> >> * The kernel should use HMT_MEDIUM_LOW as it's "default" priority
> >> * The kernel should use HMT_LOW as it's "low" priority
> >>
> >>Which would imply:
> >>
> >> * The kernel should not use HMT_MEDIUM anywhere ..
> >> * Nor should it use any of the other higher HMT modes.
> >>
> >>Do you agree?
> Not entirely. HT_MEDIUM might still be used by the kernel, in places where a
> priority higher than the default is required.
Right. But any code that currently uses HMT_MEDIUM is at the default level,
whereas once your patch is applied any code still using HMT_MEDIUM will be
boosted vs the default.
So any code that still uses HMT_MEDIUM after your patch seems like a bug to me.
> >>The reason I ask is I still see HMT_MEDIUM used in a few places, and it's not
> >>clear to me if that is correct.
> >
> >
> > HMT_MEDIUM used to be our default no ?
> Yes, but I am not sure that all references to HMT_MEDIUM were references to
> the default kernel priority.
What were they references to? Regardless they will now have the effect of
boosting the priority in those code sections. It would be good to understand,
and document, any places where we still use HMT_MEDIUM and why.
> > Also there's an open question... when doing things with interrupts off
> > (or worse, in real mode) such as some KVM hcalls etc... should we on the
> > contrary boost up to limit interrupt latency ?
> Yes. I think that there are cases when one should consider using HT_MEDIUM.
Or HIGH?
But let's not get side-tracked on that until we've got the default sorted.
> Shouldn't we define a new macro HMT_DEFAULT, to identify explicitely where
> the default priority is required?
That might help clarify things yes.
cheers
^ permalink raw reply
* [PATCH 2/4] kexec: Add IND_FLAGS macro
From: Geoff Levand @ 2013-12-12 0:18 UTC (permalink / raw)
To: Eric Biederman; +Cc: kexec, linuxppc-dev, Paul Mackerras
In-Reply-To: <cover.1386807069.git.geoff@infradead.org>
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 prosessing of the
kexec kimage_entry items.
Signed-off-by: Geoff Levand <geoff@infradead.org> for Huawei, Linaro
---
include/linux/kexec.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index d78d28a..f755ec3 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -67,6 +67,7 @@ typedef unsigned long kimage_entry_t;
#define IND_INDIRECTION 0x2
#define IND_DONE 0x4
#define IND_SOURCE 0x8
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
struct kexec_segment {
void __user *buf;
--
1.8.1.2
^ permalink raw reply related
* [PATCH 0/4] Minor fixes and improvements for kexec
From: Geoff Levand @ 2013-12-12 0:18 UTC (permalink / raw)
To: Eric Biederman; +Cc: linux-sh, kexec, Paul Mundt, Paul Mackerras, linuxppc-dev
Hi Eric,
Here are a few minor fixes and improvements for kexec. Please consider.
-Geoff
The following changes since commit 374b105797c3d4f29c685f3be535c35f5689b30e:
Linux 3.13-rc3 (2013-12-06 09:34:04 -0800)
are available in the git repository at:
git://git.linaro.org/people/geoff.levand/linux-kexec.git for-kexec
for you to fetch changes up to 594a3d26aac66e9668edc81d7bfb4e801575514f:
sh/kexec: Fix kexec build warning (2013-12-11 16:03:27 -0800)
----------------------------------------------------------------
Geoff Levand (4):
kexec: Simplify conditional
kexec: Add IND_FLAGS macro
powerpc/kexec: Use global IND_FLAGS macro
sh/kexec: Fix kexec build warning
arch/powerpc/kernel/machine_kexec_64.c | 2 --
arch/sh/kernel/machine_kexec.c | 2 +-
include/linux/kexec.h | 1 +
kernel/kexec.c | 17 ++++++++++-------
4 files changed, 12 insertions(+), 10 deletions(-)
--
1.8.1.2
^ permalink raw reply
* [PATCH 3/4] powerpc/kexec: Use global IND_FLAGS macro
From: Geoff Levand @ 2013-12-12 0:18 UTC (permalink / raw)
To: Eric Biederman; +Cc: kexec, linuxppc-dev, Paul Mackerras
In-Reply-To: <cover.1386807069.git.geoff@infradead.org>
linux/kexec.h now defines an IND_FLAGS macro. Remove the local powerpc
definition and use the generic one.
Signed-off-by: Geoff Levand <geoff@infradead.org> for Huawei, Linaro
---
arch/powerpc/kernel/machine_kexec_64.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index be4e6d6..1fab1f0 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;
--
1.8.1.2
^ 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